export delay info
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 22 Apr 2002 19:04:28 +0000 (19:04 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 22 Apr 2002 19:04:28 +0000 (19:04 +0000)
fixed low_delay & vo_type on mpeg4 header writer & parser

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

libavcodec/avcodec.h
libavcodec/h263.c
libavcodec/h263dec.c
libavcodec/mpeg4data.h
libavcodec/mpegvideo.c
libavcodec/mpegvideo.h

index 10ebcae..26e1b19 100644 (file)
@@ -5,8 +5,8 @@
 
 #define LIBAVCODEC_VERSION_INT 0x000406
 #define LIBAVCODEC_VERSION     "0.4.6"
-#define LIBAVCODEC_BUILD       4601
-#define LIBAVCODEC_BUILD_STR   "4601"
+#define LIBAVCODEC_BUILD       4602
+#define LIBAVCODEC_BUILD_STR   "4602"
 
 enum CodecID {
     CODEC_ID_NONE, 
@@ -140,6 +140,9 @@ typedef struct AVCodecContext {
     int frame_number; /* audio or video frame number */
     int key_frame;    /* true if the previous compressed frame was 
                          a key frame (intra, or seekable) */
+    int delay;        /* number of frames the decoded output will be delayed relative to the encoded input */
+    
+    /* encoding parameters */
     int quality;      /* quality of the previous encoded frame 
                          (between 1 (good) and 31 (bad)) 
                          this is allso used to set the quality in vbr mode
index 305e80d..7e3fec5 100644 (file)
@@ -1008,7 +1008,9 @@ static void mpeg4_encode_vol_header(MpegEncContext * s)
 {
     int vo_ver_id=1; //must be 2 if we want GMC or q-pel
     char buf[255];
-    
+
+    s->vo_type= s->has_b_frames ? CORE_VO_TYPE : SIMPLE_VO_TYPE;
+
     if(get_bit_count(&s->pb)!=0) mpeg4_stuffing(&s->pb);
     put_bits(&s->pb, 16, 0);
     put_bits(&s->pb, 16, 0x100);        /* video obj */
@@ -1016,7 +1018,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s)
     put_bits(&s->pb, 16, 0x120);        /* video obj layer */
 
     put_bits(&s->pb, 1, 0);            /* random access vol */
-    put_bits(&s->pb, 8, 1);            /* video obj type indication= simple obj */
+    put_bits(&s->pb, 8, s->vo_type);   /* video obj type indication */
     put_bits(&s->pb, 1, 1);            /* is obj layer id= yes */
       put_bits(&s->pb, 4, vo_ver_id);  /* is obj layer ver id */
       put_bits(&s->pb, 3, 1);          /* is obj layer priority */
@@ -1024,7 +1026,16 @@ static void mpeg4_encode_vol_header(MpegEncContext * s)
         put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */
     else
         put_bits(&s->pb, 4, 1);                /* aspect ratio info= sqare pixel */
-    put_bits(&s->pb, 1, 0);            /* vol control parameters= no */
+
+    if(s->low_delay){
+        put_bits(&s->pb, 1, 1);                /* vol control parameters= yes */
+        put_bits(&s->pb, 2, 1);                /* chroma format 422 */
+        put_bits(&s->pb, 1, s->low_delay);
+        put_bits(&s->pb, 1, 0);                /* vbv parameters= no */
+    }else{
+        put_bits(&s->pb, 1, 0);                /* vol control parameters= no */
+    }
+
     put_bits(&s->pb, 2, RECT_SHAPE);   /* vol shape= rectangle */
     put_bits(&s->pb, 1, 1);            /* marker bit */
     
@@ -2579,7 +2590,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
 
         /* vol header */
         skip_bits(&s->gb, 1); /* random access */
-        skip_bits(&s->gb, 8); /* vo_type */
+        s->vo_type= get_bits(&s->gb, 8);
         if (get_bits1(&s->gb) != 0) { /* is_ol_id */
             vo_ver_id = get_bits(&s->gb, 4); /* vo_ver_id */
             skip_bits(&s->gb, 3); /* vo_priority */
@@ -2594,9 +2605,19 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
         }
 
         if(get_bits1(&s->gb)){ /* vol control parameter */
-            printf("vol control parameter not supported\n");
-            return -1;   
+            int chroma_format= get_bits(&s->gb, 2);
+            if(chroma_format!=1){
+                printf("illegal chroma format\n");
+            }
+            s->low_delay= get_bits1(&s->gb);
+            if(get_bits1(&s->gb)){ /* vbv parameters */
+                printf("vbv parameters not supported\n");
+                return -1;
+            }
+        }else{
+            s->low_delay=0;
         }
+
         s->shape = get_bits(&s->gb, 2); /* vol shape */
         if(s->shape != RECT_SHAPE) printf("only rectangular vol supported\n");
         if(s->shape == GRAY_SHAPE && vo_ver_id != 1){
index b3e11b9..9b8606d 100644 (file)
@@ -45,7 +45,7 @@ static int h263_decode_init(AVCodecContext *avctx)
     case CODEC_ID_MPEG4:
         s->time_increment_bits = 4; /* default value for broken headers */
         s->h263_pred = 1;
-        s->has_b_frames = 1;
+        s->has_b_frames = 1; //default, might be overriden in the vol header during header parsing
         break;
     case CODEC_ID_MSMPEG4V1:
         s->h263_msmpeg4 = 1;
@@ -129,6 +129,7 @@ static int h263_decode_frame(AVCodecContext *avctx,
         ret = msmpeg4_decode_picture_header(s);
     } else if (s->h263_pred) {
         ret = mpeg4_decode_picture_header(s);
+        s->has_b_frames= !s->low_delay;
     } else if (s->h263_intel) {
         ret = intel_h263_decode_picture_header(s);
     } else {
index d94b1d9..831cf4b 100644 (file)
@@ -4,6 +4,9 @@
 #define BIN_ONLY_SHAPE   2
 #define GRAY_SHAPE       3
 
+#define SIMPLE_VO_TYPE 1
+#define CORE_VO_TYPE   3
+
 // aspect_ratio_info
 #define EXTENDET_PAR 15
 
index 5885fd7..ec1c0f9 100644 (file)
@@ -409,6 +409,7 @@ int MPV_encode_init(AVCodecContext *avctx)
     switch(avctx->codec->id) {
     case CODEC_ID_MPEG1VIDEO:
         s->out_format = FMT_MPEG1;
+        avctx->delay=0; //FIXME not sure, should check the spec
         break;
     case CODEC_ID_MJPEG:
         s->out_format = FMT_MJPEG;
@@ -422,6 +423,7 @@ int MPV_encode_init(AVCodecContext *avctx)
         s->mjpeg_hsample[2] = 1; 
         if (mjpeg_init(s) < 0)
             return -1;
+        avctx->delay=0;
         break;
     case CODEC_ID_H263:
         if (h263_get_picture_format(s->width, s->height) == 7) {
@@ -429,6 +431,7 @@ int MPV_encode_init(AVCodecContext *avctx)
             return -1;
         }
         s->out_format = FMT_H263;
+        avctx->delay=0;
         break;
     case CODEC_ID_H263P:
         s->out_format = FMT_H263;
@@ -440,16 +443,20 @@ int MPV_encode_init(AVCodecContext *avctx)
         /* These are just to be sure */
         s->umvplus = 0;
         s->umvplus_dec = 0;
+        avctx->delay=0;
         break;
     case CODEC_ID_RV10:
         s->out_format = FMT_H263;
         s->h263_rv10 = 1;
+        avctx->delay=0;
         break;
     case CODEC_ID_MPEG4:
         s->out_format = FMT_H263;
         s->h263_pred = 1;
         s->unrestricted_mv = 1;
         s->has_b_frames= s->max_b_frames ? 1 : 0;
+        s->low_delay=0;
+        avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); 
         break;
     case CODEC_ID_MSMPEG4V1:
         s->out_format = FMT_H263;
@@ -457,6 +464,7 @@ int MPV_encode_init(AVCodecContext *avctx)
         s->h263_pred = 1;
         s->unrestricted_mv = 1;
         s->msmpeg4_version= 1;
+        avctx->delay=0;
         break;
     case CODEC_ID_MSMPEG4V2:
         s->out_format = FMT_H263;
@@ -464,6 +472,7 @@ int MPV_encode_init(AVCodecContext *avctx)
         s->h263_pred = 1;
         s->unrestricted_mv = 1;
         s->msmpeg4_version= 2;
+        avctx->delay=0;
         break;
     case CODEC_ID_MSMPEG4V3:
         s->out_format = FMT_H263;
@@ -471,6 +480,7 @@ int MPV_encode_init(AVCodecContext *avctx)
         s->h263_pred = 1;
         s->unrestricted_mv = 1;
         s->msmpeg4_version= 3;
+        avctx->delay=0;
         break;
     default:
         return -1;
index c5335ab..6b67823 100644 (file)
@@ -296,6 +296,8 @@ typedef struct MpegEncContext {
     int data_partioning;
     int resync_marker;
     int resync_x_pos;
+    int low_delay;                   /* no reordering needed / has no b-frames */
+    int vo_type;
 
     /* divx specific, used to workaround (many) bugs in divx5 */
     int divx_version;