Browse code

- Preliminary RTP friendly mode for H.263. - GOB headers for H.263 coding on RTP mode. - Improved GOB header detection for H.263 decoder.

Originally committed as revision 222 to svn://svn.ffmpeg.org/ffmpeg/trunk

Juanjo authored on 2001/11/19 11:13:14
Showing 6 changed files
... ...
@@ -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,