]> git.sesse.net Git - ffmpeg/commitdiff
export mpeg2 active display area / pan scan
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 20 Oct 2003 09:52:02 +0000 (09:52 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 20 Oct 2003 09:52:02 +0000 (09:52 +0000)
fix mpeg2 aspect_ratio for the rare case that active display area != AVCodecContext.width/height
decode sequence display extension & picture display extension

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

libavcodec/avcodec.h
libavcodec/mpeg12.c
libavcodec/mpegvideo.c

index 271561c79f360c7e2920a709ce1698eafbd6e890..542200f7a1beaea16ea7e92ffd5ade168208f573 100644 (file)
@@ -15,7 +15,7 @@ extern "C" {
 
 #define FFMPEG_VERSION_INT     0x000408
 #define FFMPEG_VERSION         "0.4.8"
-#define LIBAVCODEC_BUILD       4684
+#define LIBAVCODEC_BUILD       4685
 
 #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT
 #define LIBAVCODEC_VERSION     FFMPEG_VERSION
@@ -271,6 +271,34 @@ static const __attribute__((unused)) int Motion_Est_QTab[] =
 #define CODEC_CAP_PARSE_ONLY      0x0004
 #define CODEC_CAP_TRUNCATED       0x0008
 
+/**
+ * Pan Scan area.
+ * this specifies the area which should be displayed. Note there may be multiple such areas for one frame
+ */
+typedef struct AVPanScan{
+    /**
+     * id.
+     * - encoding: set by user.
+     * - decoding: set by lavc
+     */
+    int id;
+
+    /**
+     * width and height in 1/16 pel
+     * - encoding: set by user.
+     * - decoding: set by lavc
+     */
+    int width;
+    int height;
+
+    /**
+     * position of the top left corner in 1/16 pel for up to 3 fields/frames.
+     * - encoding: set by user.
+     * - decoding: set by lavc
+     */
+    int16_t position[3][2];
+}AVPanScan;
+
 #define FF_COMMON_FRAME \
     /**\
      * pointer to the picture planes.\
@@ -413,6 +441,14 @@ static const __attribute__((unused)) int Motion_Est_QTab[] =
      * - decoding: set by lavc (default 0)\
      */\
     int bottom_field_first;\
+    \
+    /**\
+     * Pan scan.\
+     * - encoding: set by user\
+     * - decoding: set by lavc\
+     */\
+    AVPanScan *pan_scan;\
+    
 
 #define FF_QSCALE_TYPE_MPEG1   0
 #define FF_QSCALE_TYPE_MPEG2   1
@@ -1303,6 +1339,7 @@ typedef struct AVCodecContext {
      * - decoding: unused
      */
     int lmax;
+    
 } AVCodecContext;
 
 
index a5e646d29f42f741f04904643dd29c6559393405..015033bf36f766aa5e211b73df2aacc9e3a631f7 100644 (file)
@@ -1655,6 +1655,7 @@ typedef struct Mpeg1Context {
     MpegEncContext mpeg_enc_ctx;
     int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
     int repeat_field; /* true if we must repeat the field */
+    AVPanScan pan_scan; /** some temporary storage for the panscan */
 } Mpeg1Context;
 
 static int mpeg_decode_init(AVCodecContext *avctx)
@@ -1781,6 +1782,53 @@ static void mpeg_decode_sequence_extension(MpegEncContext *s)
         printf("profile: %d, level: %d \n", profile, level);
 }
 
+static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1)
+{
+    MpegEncContext *s= &s1->mpeg_enc_ctx;
+    int color_description, w, h;
+
+    skip_bits(&s->gb, 3); /* video format */
+    color_description= get_bits1(&s->gb);
+    if(color_description){
+        skip_bits(&s->gb, 8); /* color primaries */
+        skip_bits(&s->gb, 8); /* transfer_characteristics */
+        skip_bits(&s->gb, 8); /* matrix_coefficients */
+    }
+    w= get_bits(&s->gb, 14);
+    skip_bits(&s->gb, 1); //marker
+    h= get_bits(&s->gb, 14);
+    skip_bits(&s->gb, 1); //marker
+    
+    s1->pan_scan.width= 16*w;
+    s1->pan_scan.height=16*h;
+
+    if(mpeg2_aspect[s->aspect_ratio_info] < 0.0)
+        s->avctx->aspect_ratio*= (s->width * h)/(float)(s->height * w);
+    
+    if(s->avctx->debug & FF_DEBUG_PICT_INFO)
+        printf("sde w:%d, h:%d\n", w, h);
+}
+
+static void mpeg_decode_picture_display_extension(Mpeg1Context *s1)
+{
+    MpegEncContext *s= &s1->mpeg_enc_ctx;
+    int i;
+
+    for(i=0; i<1; i++){ //FIXME count
+        s1->pan_scan.position[i][0]= get_sbits(&s->gb, 16);
+        skip_bits(&s->gb, 1); //marker
+        s1->pan_scan.position[i][1]= get_sbits(&s->gb, 16);
+        skip_bits(&s->gb, 1); //marker
+    }
+   
+    if(s->avctx->debug & FF_DEBUG_PICT_INFO)
+        printf("pde (%d,%d) (%d,%d) (%d,%d)\n", 
+            s1->pan_scan.position[0][0], s1->pan_scan.position[0][1], 
+            s1->pan_scan.position[1][0], s1->pan_scan.position[1][1], 
+            s1->pan_scan.position[2][0], s1->pan_scan.position[2][1]
+        );
+}
+
 static void mpeg_decode_quant_matrix_extension(MpegEncContext *s)
 {
     int i, v, j;
@@ -1881,15 +1929,18 @@ static void mpeg_decode_extension(AVCodecContext *avctx,
     ext_type = get_bits(&s->gb, 4);
     switch(ext_type) {
     case 0x1:
-        /* sequence ext */
         mpeg_decode_sequence_extension(s);
         break;
+    case 0x2:
+        mpeg_decode_sequence_display_extension(s1);
+        break;
     case 0x3:
-        /* quant matrix extension */
         mpeg_decode_quant_matrix_extension(s);
         break;
+    case 0x7:
+        mpeg_decode_picture_display_extension(s1);
+        break;
     case 0x8:
-        /* picture extension */
         mpeg_decode_picture_coding_extension(s);
         break;
     }
@@ -1953,6 +2004,9 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
                 s->current_picture_ptr->repeat_pict = 1;
             }
         }         
+
+        *s->current_picture_ptr->pan_scan= s1->pan_scan;
+
         //printf("%d\n", s->current_picture_ptr->repeat_pict);
 
         if(s->avctx->debug&FF_DEBUG_PICT_INFO){
index d7474084f18686e8888b2b0e2f3c373eb581c92c..2f60055721a81d32ab160627ec406ea52372b594 100644 (file)
@@ -302,6 +302,7 @@ static int alloc_picture(MpegEncContext *s, Picture *pic, int shared){
             }
         }
         pic->qstride= s->mb_stride;
+        CHECKED_ALLOCZ(pic->pan_scan , 1 * sizeof(AVPanScan))
     }
 
     //it might be nicer if the application would keep track of these but it would require a API change
@@ -332,6 +333,7 @@ static void free_picture(MpegEncContext *s, Picture *pic){
     av_freep(&pic->mbskip_table);
     av_freep(&pic->qscale_table);
     av_freep(&pic->mb_type_base);
+    av_freep(&pic->pan_scan);
     pic->mb_type= NULL;
     for(i=0; i<2; i++){
         av_freep(&pic->motion_val[i]);