Originally committed as revision 222 to svn://svn.ffmpeg.org/ffmpeg/trunk
Juanjo authored on 2001/11/19 11:13:14... | ... |
@@ -5,6 +5,14 @@ version 0.4.6: |
5 | 5 |
- recoded dct and motion vector search with gcc (no longer depends on |
6 | 6 |
nasm). |
7 | 7 |
- fix quantization bug in AC3 encoder. |
8 |
+- added GOB header parsing on H.263/H.263+ decoder. (Juanjo) |
|
9 |
+- bug fix on MCBPC tables of H.263. (Juanjo) |
|
10 |
+- added Advanced Prediction Mode on H.263/H.263+ decoder. (Juanjo) |
|
11 |
+- now we can decode H.263 streams found on QuickTime files. (Juanjo) |
|
12 |
+- now we can decode H.263 streams found on VIVO v1 files.(Juanjo) |
|
13 |
+- preliminary RTP "friendly" mode for H.263/H.263+ coding. (Juanjo) |
|
14 |
+- added GOB header for H.263/H.263+ coding on RTP mode. (Juanjo) |
|
15 |
+- now H.263 picture size is returned on the first decoded frame. (Juanjo) |
|
8 | 16 |
|
9 | 17 |
version 0.4.5: |
10 | 18 |
|
... | ... |
@@ -103,6 +103,19 @@ typedef struct AVCodecContext { |
103 | 103 |
struct AVCodec *codec; |
104 | 104 |
void *priv_data; |
105 | 105 |
|
106 |
+ /* The following data is for RTP friendly coding */ |
|
107 |
+ /* By now only H.263/H.263+ coder honours this */ |
|
108 |
+ int rtp_mode; /* 1 for activate RTP friendly-mode */ |
|
109 |
+ /* highers numbers represent more error-prone */ |
|
110 |
+ /* enviroments, by now just "1" exist */ |
|
111 |
+ |
|
112 |
+ int rtp_payload_size; /* The size of the RTP payload, the coder will */ |
|
113 |
+ /* do it's best to deliver a chunk with size */ |
|
114 |
+ /* below rtp_payload_size, the chunk will start */ |
|
115 |
+ /* with a start code on some codecs like H.263 */ |
|
116 |
+ /* This doesn't take account of any particular */ |
|
117 |
+ /* headers inside the transmited RTP payload */ |
|
118 |
+ |
|
106 | 119 |
/* the following fields are ignored */ |
107 | 120 |
void *opaque; /* can be used to carry app specific stuff */ |
108 | 121 |
char codec_name[32]; |
... | ... |
@@ -239,8 +252,8 @@ void avcodec_register_all(void); |
239 | 239 |
|
240 | 240 |
#ifdef FF_POSTPROCESS |
241 | 241 |
#ifndef MBC |
242 |
-#define MBC 120 |
|
243 |
-#define MBR 72 |
|
242 |
+#define MBC 48 |
|
243 |
+#define MBR 36 |
|
244 | 244 |
#endif |
245 | 245 |
extern int quant_store[MBR+1][MBC+1]; // [Review] |
246 | 246 |
#endif |
... | ... |
@@ -140,12 +140,45 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) |
140 | 140 |
put_bits(&s->pb, 1, 0); /* no PEI */ |
141 | 141 |
} |
142 | 142 |
|
143 |
+int h263_encode_gob_header(MpegEncContext * s, int mb_line) |
|
144 |
+{ |
|
145 |
+ int pdif=0; |
|
146 |
+ |
|
147 |
+ /* Check to see if we need to put a new GBSC */ |
|
148 |
+ /* for RTP packetization */ |
|
149 |
+ if (s->rtp_mode) { |
|
150 |
+ pdif = s->pb.buf_ptr - s->ptr_lastgob; |
|
151 |
+ if (pdif >= s->rtp_payload_size) { |
|
152 |
+ /* Bad luck, packet must be cut before */ |
|
153 |
+ align_put_bits(&s->pb); |
|
154 |
+ s->ptr_lastgob = s->pb.buf_ptr; |
|
155 |
+ put_bits(&s->pb, 17, 1); /* GBSC */ |
|
156 |
+ s->gob_number = mb_line; |
|
157 |
+ put_bits(&s->pb, 5, s->gob_number); /* GN */ |
|
158 |
+ put_bits(&s->pb, 2, 1); /* GFID */ |
|
159 |
+ put_bits(&s->pb, 5, s->qscale); /* GQUANT */ |
|
160 |
+ return pdif; |
|
161 |
+ } else if (pdif + s->mb_line_avgsize >= s->rtp_payload_size) { |
|
162 |
+ /* Cut the packet before we can't */ |
|
163 |
+ align_put_bits(&s->pb); |
|
164 |
+ s->ptr_lastgob = s->pb.buf_ptr; |
|
165 |
+ put_bits(&s->pb, 17, 1); /* GBSC */ |
|
166 |
+ s->gob_number = mb_line; |
|
167 |
+ put_bits(&s->pb, 5, s->gob_number); /* GN */ |
|
168 |
+ put_bits(&s->pb, 2, 1); /* GFID */ |
|
169 |
+ put_bits(&s->pb, 5, s->qscale); /* GQUANT */ |
|
170 |
+ return pdif; |
|
171 |
+ } |
|
172 |
+ } |
|
173 |
+ return 0; |
|
174 |
+} |
|
175 |
+ |
|
143 | 176 |
void h263_encode_mb(MpegEncContext * s, |
144 | 177 |
DCTELEM block[6][64], |
145 | 178 |
int motion_x, int motion_y) |
146 | 179 |
{ |
147 | 180 |
int cbpc, cbpy, i, cbp, pred_x, pred_y; |
148 |
- |
|
181 |
+ |
|
149 | 182 |
// printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); |
150 | 183 |
if (!s->mb_intra) { |
151 | 184 |
/* compute cbp */ |
... | ... |
@@ -772,42 +805,38 @@ void h263_decode_init_vlc(MpegEncContext *s) |
772 | 772 |
} |
773 | 773 |
} |
774 | 774 |
|
775 |
-int h263_decode_mb(MpegEncContext *s, |
|
776 |
- DCTELEM block[6][64]) |
|
775 |
+int h263_decode_gob_header(MpegEncContext *s) |
|
777 | 776 |
{ |
778 |
- int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant; |
|
779 |
- unsigned int val; |
|
780 |
- INT16 *mot_val; |
|
781 |
- static INT8 quant_tab[4] = { -1, -2, 1, 2 }; |
|
782 |
- unsigned int gfid; |
|
777 |
+ unsigned int val, gfid; |
|
783 | 778 |
|
784 | 779 |
/* Check for GOB Start Code */ |
785 |
- if (s->mb_x == 0) { |
|
786 |
- val = show_bits(&s->gb, 16); |
|
787 |
- if (val == 0) { |
|
788 |
- /* We have a GBSC probably with GSTUFF */ |
|
789 |
- skip_bits(&s->gb, 16); /* Drop the zeros */ |
|
790 |
- while (get_bits1(&s->gb) == 0); /* Seek the '1' bit */ |
|
780 |
+ val = show_bits(&s->gb, 16); |
|
781 |
+ if (val == 0) { |
|
782 |
+ /* We have a GBSC probably with GSTUFF */ |
|
783 |
+ skip_bits(&s->gb, 16); /* Drop the zeros */ |
|
784 |
+ while (get_bits1(&s->gb) == 0); /* Seek the '1' bit */ |
|
791 | 785 |
#ifdef DEBUG |
792 |
- fprintf(stderr,"\nGOB Start Code at MB %d\n", |
|
793 |
- (s->mb_y * s->mb_width) + s->mb_x); |
|
786 |
+ fprintf(stderr,"\nGOB Start Code at MB %d\n", (s->mb_y * s->mb_width) + s->mb_x); |
|
794 | 787 |
#endif |
795 |
- s->gob_number = get_bits(&s->gb, 5); /* GN */ |
|
796 |
- gfid = get_bits(&s->gb, 2); /* GFID */ |
|
797 |
- s->qscale = get_bits(&s->gb, 5); /* GQUANT */ |
|
788 |
+ s->gob_number = get_bits(&s->gb, 5); /* GN */ |
|
789 |
+ gfid = get_bits(&s->gb, 2); /* GFID */ |
|
790 |
+ s->qscale = get_bits(&s->gb, 5); /* GQUANT */ |
|
798 | 791 |
#ifdef DEBUG |
799 |
- fprintf(stderr, "\nGN: %u GFID: %u Quant: %u\n", gn, gfid, s->qscale); |
|
792 |
+ fprintf(stderr, "\nGN: %u GFID: %u Quant: %u\n", gn, gfid, s->qscale); |
|
800 | 793 |
#endif |
801 |
- } |
|
794 |
+ return 1; |
|
802 | 795 |
} |
803 |
- /* FIXME: In the future H.263+ will have intra prediction */ |
|
804 |
- /* and we are gonna need another way to detect MPEG4 */ |
|
805 |
- if (!s->h263_pred) { |
|
806 |
- if (s->mb_y == s->gob_number) |
|
807 |
- s->first_gob_line = 1; |
|
808 |
- else |
|
809 |
- s->first_gob_line = 0; |
|
810 |
- } |
|
796 |
+ return 0; |
|
797 |
+ |
|
798 |
+} |
|
799 |
+ |
|
800 |
+int h263_decode_mb(MpegEncContext *s, |
|
801 |
+ DCTELEM block[6][64]) |
|
802 |
+{ |
|
803 |
+ int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant; |
|
804 |
+ INT16 *mot_val; |
|
805 |
+ static INT8 quant_tab[4] = { -1, -2, 1, 2 }; |
|
806 |
+ |
|
811 | 807 |
if (s->pict_type == P_TYPE) { |
812 | 808 |
if (get_bits1(&s->gb)) { |
813 | 809 |
/* skip mb */ |
... | ... |
@@ -140,6 +140,12 @@ static int h263_decode_frame(AVCodecContext *avctx, |
140 | 140 |
|
141 | 141 |
/* decode each macroblock */ |
142 | 142 |
for(s->mb_y=0; s->mb_y < s->mb_height; s->mb_y++) { |
143 |
+ /* Check for GOB headers on H.263 */ |
|
144 |
+ /* FIXME: In the future H.263+ will have intra prediction */ |
|
145 |
+ /* and we are gonna need another way to detect MPEG4 */ |
|
146 |
+ if (s->mb_y && !s->h263_pred) { |
|
147 |
+ s->first_gob_line = h263_decode_gob_header(s); |
|
148 |
+ } |
|
143 | 149 |
for(s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) { |
144 | 150 |
#ifdef DEBUG |
145 | 151 |
printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); |
... | ... |
@@ -249,6 +249,9 @@ int MPV_encode_init(AVCodecContext *avctx) |
249 | 249 |
s->width = avctx->width; |
250 | 250 |
s->height = avctx->height; |
251 | 251 |
s->gop_size = avctx->gop_size; |
252 |
+ s->rtp_mode = avctx->rtp_mode; |
|
253 |
+ s->rtp_payload_size = avctx->rtp_payload_size; |
|
254 |
+ |
|
252 | 255 |
if (s->gop_size <= 1) { |
253 | 256 |
s->intra_only = 1; |
254 | 257 |
s->gop_size = 12; |
... | ... |
@@ -276,6 +279,8 @@ int MPV_encode_init(AVCodecContext *avctx) |
276 | 276 |
break; |
277 | 277 |
case CODEC_ID_H263P: |
278 | 278 |
s->out_format = FMT_H263; |
279 |
+ s->rtp_mode = 1; |
|
280 |
+ s->rtp_payload_size = 1200; |
|
279 | 281 |
s->h263_plus = 1; |
280 | 282 |
s->unrestricted_mv = 1; |
281 | 283 |
|
... | ... |
@@ -819,7 +824,7 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) |
819 | 819 |
|
820 | 820 |
static void encode_picture(MpegEncContext *s, int picture_number) |
821 | 821 |
{ |
822 |
- int mb_x, mb_y, wrap; |
|
822 |
+ int mb_x, mb_y, wrap, last_gob; |
|
823 | 823 |
UINT8 *ptr; |
824 | 824 |
int i, motion_x, motion_y; |
825 | 825 |
|
... | ... |
@@ -869,7 +874,29 @@ static void encode_picture(MpegEncContext *s, int picture_number) |
869 | 869 |
s->mv_type = MV_TYPE_16X16; |
870 | 870 |
s->mv_dir = MV_DIR_FORWARD; |
871 | 871 |
|
872 |
+ /* Get the GOB height based on picture height */ |
|
873 |
+ if (s->out_format == FMT_H263 && s->h263_plus) { |
|
874 |
+ if (s->height <= 400) |
|
875 |
+ s->gob_index = 1; |
|
876 |
+ else if (s->height <= 800) |
|
877 |
+ s->gob_index = 2; |
|
878 |
+ else |
|
879 |
+ s->gob_index = 4; |
|
880 |
+ } |
|
881 |
+ |
|
872 | 882 |
for(mb_y=0; mb_y < s->mb_height; mb_y++) { |
883 |
+ /* Put GOB header based on RTP MTU */ |
|
884 |
+ if (!mb_y) { |
|
885 |
+ s->ptr_lastgob = s->pb.buf_ptr; |
|
886 |
+ s->ptr_last_mb_line = s->pb.buf_ptr; |
|
887 |
+ } else if (s->out_format == FMT_H263 && s->h263_plus) { |
|
888 |
+ last_gob = h263_encode_gob_header(s, mb_y); |
|
889 |
+ if (last_gob) { |
|
890 |
+ //fprintf(stderr,"\nLast GOB size: %d", last_gob); |
|
891 |
+ s->first_gob_line = 1; |
|
892 |
+ } else |
|
893 |
+ s->first_gob_line = 0; |
|
894 |
+ } |
|
873 | 895 |
for(mb_x=0; mb_x < s->mb_width; mb_x++) { |
874 | 896 |
|
875 | 897 |
s->mb_x = mb_x; |
... | ... |
@@ -981,7 +1008,17 @@ static void encode_picture(MpegEncContext *s, int picture_number) |
981 | 981 |
|
982 | 982 |
MPV_decode_mb(s, s->block); |
983 | 983 |
} |
984 |
+ /* Obtain average MB line size for RTP */ |
|
985 |
+ if (!mb_y) |
|
986 |
+ s->mb_line_avgsize = s->pb.buf_ptr - s->ptr_last_mb_line; |
|
987 |
+ else |
|
988 |
+ s->mb_line_avgsize = (s->mb_line_avgsize + s->pb.buf_ptr - s->ptr_last_mb_line) >> 1; |
|
989 |
+ //fprintf(stderr, "\nMB line: %d\tSize: %u\tAvg. Size: %u", s->mb_y, |
|
990 |
+ // (s->pb.buf_ptr - s->ptr_last_mb_line), s->mb_line_avgsize); |
|
991 |
+ s->ptr_last_mb_line = s->pb.buf_ptr; |
|
984 | 992 |
} |
993 |
+ //if (s->gob_number) |
|
994 |
+ // fprintf(stderr,"\nNumber of GOB: %d", s->gob_number); |
|
985 | 995 |
} |
986 | 996 |
|
987 | 997 |
static int dct_quantize(MpegEncContext *s, |
... | ... |
@@ -131,6 +131,7 @@ typedef struct MpegEncContext { |
131 | 131 |
|
132 | 132 |
/* H.263 specific */ |
133 | 133 |
int gob_number; |
134 |
+ int gob_index; |
|
134 | 135 |
int first_gob_line; |
135 | 136 |
|
136 | 137 |
/* H.263+ specific */ |
... | ... |
@@ -185,7 +186,14 @@ typedef struct MpegEncContext { |
185 | 185 |
int interlaced_dct; |
186 | 186 |
int last_qscale; |
187 | 187 |
int first_slice; |
188 |
- |
|
188 |
+ |
|
189 |
+ /* RTP specific */ |
|
190 |
+ int rtp_mode; |
|
191 |
+ int rtp_payload_size; |
|
192 |
+ UINT8 *ptr_lastgob; |
|
193 |
+ UINT8 *ptr_last_mb_line; |
|
194 |
+ UINT32 mb_line_avgsize; |
|
195 |
+ |
|
189 | 196 |
DCTELEM block[6][64] __align8; |
190 | 197 |
void (*dct_unquantize)(struct MpegEncContext *s, |
191 | 198 |
DCTELEM *block, int n, int qscale); |
... | ... |
@@ -236,7 +244,7 @@ typedef struct RLTable { |
236 | 236 |
void init_rl(RLTable *rl); |
237 | 237 |
void init_vlc_rl(RLTable *rl); |
238 | 238 |
|
239 |
-static inline int get_rl_index(const RLTable *rl, int last, int run, int level) |
|
239 |
+extern inline int get_rl_index(const RLTable *rl, int last, int run, int level) |
|
240 | 240 |
{ |
241 | 241 |
int index; |
242 | 242 |
index = rl->index_run[last][run]; |
... | ... |
@@ -251,6 +259,7 @@ void h263_encode_mb(MpegEncContext *s, |
251 | 251 |
DCTELEM block[6][64], |
252 | 252 |
int motion_x, int motion_y); |
253 | 253 |
void h263_encode_picture_header(MpegEncContext *s, int picture_number); |
254 |
+int h263_encode_gob_header(MpegEncContext * s, int mb_line); |
|
254 | 255 |
void h263_dc_scale(MpegEncContext *s); |
255 | 256 |
INT16 *h263_pred_motion(MpegEncContext * s, int block, |
256 | 257 |
int *px, int *py); |
... | ... |
@@ -261,6 +270,7 @@ void h263_encode_init_vlc(MpegEncContext *s); |
261 | 261 |
|
262 | 262 |
void h263_decode_init_vlc(MpegEncContext *s); |
263 | 263 |
int h263_decode_picture_header(MpegEncContext *s); |
264 |
+int h263_decode_gob_header(MpegEncContext *s); |
|
264 | 265 |
int mpeg4_decode_picture_header(MpegEncContext * s); |
265 | 266 |
int intel_h263_decode_picture_header(MpegEncContext *s); |
266 | 267 |
int h263_decode_mb(MpegEncContext *s, |