[FFmpeg-devel] [PATCH 1/2] lavc/mpegvideo_parser: export additional properties

Rodger Combs rodger.combs at gmail.com
Wed Apr 13 10:26:03 CEST 2016


---
 libavcodec/mpegvideo_parser.c | 67 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c
index 1f74bfb..92ba24a 100644
--- a/libavcodec/mpegvideo_parser.c
+++ b/libavcodec/mpegvideo_parser.c
@@ -29,6 +29,8 @@ struct MpvParseContext {
     AVRational frame_rate;
     int progressive_sequence;
     int width, height;
+    int aspect_ratio_info;
+    int cwidth, cheight; // crop
 };
 
 
@@ -66,6 +68,7 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
             break;
         case SEQ_START_CODE:
             if (bytes_left >= 7) {
+                pc->aspect_ratio_info = buf[3] >> 4;
                 pc->width  = (buf[0] << 4) | (buf[1] >> 4);
                 pc->height = ((buf[1] & 0x0f) << 8) | buf[2];
                 if(!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height){
@@ -86,6 +89,8 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
                 switch(ext_type) {
                 case 0x1: /* sequence extension */
                     if (bytes_left >= 6) {
+                        avctx->profile = (buf[0] & 7);
+                        avctx->level = (buf[1] >> 4);
                         horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7);
                         vert_size_ext = (buf[2] >> 5) & 3;
                         bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1);
@@ -112,6 +117,20 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
                         avctx->ticks_per_frame = 2;
                     }
                     break;
+                case 0x2:
+                    if (bytes_left >= 4) {
+                        int offset = 0;
+                        if (buf[0] & 1) {
+                            avctx->color_primaries = buf[1];
+                            avctx->color_trc       = buf[2];
+                            avctx->colorspace      = buf[3];
+                            offset = 3;
+                        }
+                        if (bytes_left >= 5 + offset) {
+                            pc->cwidth  = 16 * (buf[1 + offset] << 6) | (buf[2 + offset] >> 2);
+                            pc->cheight = 16 * ((buf[2 + offset] & 1) << 13) | (buf[3 + offset] << 5) | (buf[4 + offset] >> 3);
+                        }
+                    }
                 case 0x8: /* picture coding extension */
                     if (bytes_left >= 5) {
                         top_field_first = buf[3] & (1 << 7);
@@ -172,6 +191,54 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
         s->height = s->coded_height = pc->height;
     }
 
+    if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
+        // MPEG-1 aspect
+        avctx->sample_aspect_ratio = av_d2q(1.0 / ff_mpeg1_aspect[pc->aspect_ratio_info], 255);
+        avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
+    } else { // MPEG-2
+        // MPEG-2 aspect
+        if (pc->aspect_ratio_info > 1) {
+            AVRational dar =
+                av_mul_q(av_div_q(ff_mpeg2_aspect[pc->aspect_ratio_info],
+                                  (AVRational) { pc->cwidth,
+                                                 pc->cheight }),
+                         (AVRational) { pc->width, pc->height });
+
+            /* We ignore the spec here and guess a bit as reality does not
+             * match the spec, see for example res_change_ffmpeg_aspect.ts
+             * and sequence-display-aspect.mpg.
+             * issue1613, 621, 562 */
+            if ((pc->cwidth == 0) || (pc->cheight == 0) ||
+                (av_cmp_q(dar, (AVRational) { 4, 3 }) &&
+                 av_cmp_q(dar, (AVRational) { 16, 9 }))) {
+                avctx->sample_aspect_ratio =
+                    av_div_q(ff_mpeg2_aspect[pc->aspect_ratio_info],
+                             (AVRational) { pc->width, pc->height });
+            } else {
+                avctx->sample_aspect_ratio =
+                    av_div_q(ff_mpeg2_aspect[pc->aspect_ratio_info],
+                             (AVRational) { pc->cwidth, pc->cheight });
+// issue1613 4/3 16/9 -> 16/9
+// res_change_ffmpeg_aspect.ts 4/3 225/44 ->4/3
+// widescreen-issue562.mpg 4/3 16/9 -> 16/9
+//                s->avctx->sample_aspect_ratio = av_mul_q(s->avctx->sample_aspect_ratio, (AVRational) {s->width, s->height});
+                ff_dlog(avctx, "aspect A %d/%d\n",
+                        ff_mpeg2_aspect[pc->aspect_ratio_info].num,
+                        ff_mpeg2_aspect[pc->aspect_ratio_info].den);
+                ff_dlog(avctx, "aspect B %d/%d\n", avctx->sample_aspect_ratio.num,
+                        avctx->sample_aspect_ratio.den);
+            }
+        } else {
+            avctx->sample_aspect_ratio = ff_mpeg2_aspect[pc->aspect_ratio_info];
+        }
+        switch (pix_fmt) {
+            case AV_PIX_FMT_YUV420P: avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; break;
+            case AV_PIX_FMT_YUV422P:
+            case AV_PIX_FMT_YUV444P: avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; break;
+            default: break;
+        }
+    } // MPEG-2
+
 #if FF_API_AVCTX_TIMEBASE
     if (avctx->framerate.num)
         avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));
-- 
2.7.3



More information about the ffmpeg-devel mailing list