From 7189a0341784fe84c5213dd974a81045cf9a562e Mon Sep 17 00:00:00 2001 From: ddennedy Date: Thu, 15 May 2008 02:47:37 +0000 Subject: [PATCH] profiles/dv_*, consumer_avformat.c, producer_avformat.c: bugfix (1912796) to override FFmpeg notion of sample aspect for DV. The values it uses might be more proper in certain contexts, but not in the way MLT currently operates. This change improves performance and quality when outputting to one of the "dv" profiles when using DV or other ITU-R 601-based video sources such as MPEG-2 for DVD Video and broadcast. git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@1126 d19143bc-622f-0410-bfdd-b5b2a6649095 --- profiles/dv_ntsc | 4 +-- profiles/dv_ntsc_wide | 4 +-- profiles/dv_pal | 4 +-- profiles/dv_pal_wide | 4 +-- src/modules/avformat/consumer_avformat.c | 37 ++++++++++++++++++++++-- src/modules/avformat/producer_avformat.c | 26 +++++++++++++++-- 6 files changed, 66 insertions(+), 13 deletions(-) diff --git a/profiles/dv_ntsc b/profiles/dv_ntsc index c5462ddd..ff1f24e6 100644 --- a/profiles/dv_ntsc +++ b/profiles/dv_ntsc @@ -4,7 +4,7 @@ frame_rate_den=1001 width=720 height=480 progressive=0 -sample_aspect_num=10 -sample_aspect_den=11 +sample_aspect_num=8 +sample_aspect_den=9 display_aspect_num=4 display_aspect_den=3 diff --git a/profiles/dv_ntsc_wide b/profiles/dv_ntsc_wide index 6c98e4f8..d512d6ce 100644 --- a/profiles/dv_ntsc_wide +++ b/profiles/dv_ntsc_wide @@ -4,7 +4,7 @@ frame_rate_den=1001 width=720 height=480 progressive=0 -sample_aspect_num=40 -sample_aspect_den=33 +sample_aspect_num=32 +sample_aspect_den=27 display_aspect_num=16 display_aspect_den=9 diff --git a/profiles/dv_pal b/profiles/dv_pal index 33e82bc2..d5691400 100644 --- a/profiles/dv_pal +++ b/profiles/dv_pal @@ -4,7 +4,7 @@ frame_rate_den=1 width=720 height=576 progressive=0 -sample_aspect_num=59 -sample_aspect_den=54 +sample_aspect_num=16 +sample_aspect_den=15 display_aspect_num=4 display_aspect_den=3 diff --git a/profiles/dv_pal_wide b/profiles/dv_pal_wide index a4b669c5..a52b9cff 100644 --- a/profiles/dv_pal_wide +++ b/profiles/dv_pal_wide @@ -4,7 +4,7 @@ frame_rate_den=1 width=720 height=576 progressive=0 -sample_aspect_num=118 -sample_aspect_den=81 +sample_aspect_num=64 +sample_aspect_den=45 display_aspect_num=16 display_aspect_den=9 diff --git a/src/modules/avformat/consumer_avformat.c b/src/modules/avformat/consumer_avformat.c index d2c6fe13..93b8652b 100644 --- a/src/modules/avformat/consumer_avformat.c +++ b/src/modules/avformat/consumer_avformat.c @@ -429,7 +429,7 @@ static AVStream *add_video_stream( mlt_consumer this, AVFormatContext *oc, int c if ( st != NULL ) { char *pix_fmt = mlt_properties_get( properties, "pix_fmt" ); - double ar = mlt_properties_get_double( properties, "display_ratio" ); + double ar = mlt_properties_get_double( properties, "aspect_ratio" ); AVCodecContext *c = st->codec; // Establish defaults from AVOptions @@ -451,11 +451,44 @@ static AVStream *add_video_stream( mlt_consumer this, AVFormatContext *oc, int c // Set options controlled by MLT c->width = mlt_properties_get_int( properties, "width" ); c->height = mlt_properties_get_int( properties, "height" ); - c->sample_aspect_ratio = av_d2q( ar * c->height / c->width , 255); c->time_base.num = mlt_properties_get_int( properties, "frame_rate_den" ); c->time_base.den = mlt_properties_get_int( properties, "frame_rate_num" ); c->pix_fmt = pix_fmt ? avcodec_get_pix_fmt( pix_fmt ) : PIX_FMT_YUV420P; + if ( codec_id == CODEC_ID_DVVIDEO ) + { + // Compensate for FFmpeg's notion of DV aspect ratios, which are + // based upon a width of 704. Since we do not have a normaliser + // that crops (nor is cropping 720 wide ITU-R 601 video always desirable) + // we just coerce the values to facilitate a passive behaviour through + // the rescale normaliser when using equivalent producers and consumers. + // = display_aspect / (width * height) + if ( ar == 8.0/9.0 ) // 4:3 NTSC + { + c->sample_aspect_ratio.num = 10; + c->sample_aspect_ratio.den = 11; + } + else if ( ar == 16.0/15.0 ) // 4:3 PAL + { + c->sample_aspect_ratio.num = 159; + c->sample_aspect_ratio.den = 54; + } + else if ( ar == 32.0/27.0 ) // 16:9 NTSC + { + c->sample_aspect_ratio.num = 40; + c->sample_aspect_ratio.den = 33; + } + else // 16:9 PAL + { + c->sample_aspect_ratio.num = 118; + c->sample_aspect_ratio.den = 81; + } + } + else + { + c->sample_aspect_ratio = av_d2q( ar * c->height / c->width , 255); + } + if ( mlt_properties_get_double( properties, "qscale" ) > 0 ) { c->flags |= CODEC_FLAG_QSCALE; diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index d42a307e..51037981 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -640,7 +640,6 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form if ( got_picture ) { mlt_properties_set_int( frame_properties, "progressive", !av_frame->interlaced_frame ); - mlt_properties_set_int( frame_properties, "top_field_first", av_frame->top_field_first ); mlt_properties_set_int( properties, "top_field_first", av_frame->top_field_first ); convert_image( av_frame, *buffer, codec_context->pix_fmt, *format, *width, *height ); mlt_properties_set_data( frame_properties, "image", *buffer, size, (mlt_destructor)mlt_pool_release, NULL ); @@ -729,6 +728,28 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame ) double force_aspect_ratio = mlt_properties_get_double( properties, "force_aspect_ratio" ); double aspect_ratio; + if ( strcmp( codec_context->codec->name, "dvvideo" ) == 0 ) + { + // Override FFmpeg's notion of DV aspect ratios, which are + // based upon a width of 704. Since we do not have a normaliser + // that crops (nor is cropping 720 wide ITU-R 601 video always desirable) + // we just coerce the values to facilitate a passive behaviour through + // the rescale normaliser when using equivalent producers and consumers. + // = display_aspect / (width * height) + if ( codec_context->sample_aspect_ratio.num == 10 && + codec_context->sample_aspect_ratio.den == 11 ) + force_aspect_ratio = 8.0/9.0; // 4:3 NTSC + else if ( codec_context->sample_aspect_ratio.num == 59 && + codec_context->sample_aspect_ratio.den == 54 ) + force_aspect_ratio = 16.0/15.0; // 4:3 PAL + else if ( codec_context->sample_aspect_ratio.num == 40 && + codec_context->sample_aspect_ratio.den == 33 ) + force_aspect_ratio = 32.0/27.0; // 16:9 NTSC + else if ( codec_context->sample_aspect_ratio.num == 118 && + codec_context->sample_aspect_ratio.den == 81 ) + force_aspect_ratio = 64.0/45.0; // 16:9 PAL + } + // XXX: We won't know the real aspect ratio until an image is decoded // but we do need it now (to satisfy filter_resize) - take a guess based // on pal/ntsc @@ -742,8 +763,7 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame ) } else { - int is_pal = mlt_producer_get_fps( this ) == 25.0; - aspect_ratio = is_pal ? 59.0/54.0 : 10.0/11.0; + aspect_ratio = 1.0; } // Determine the fps -- 2.39.2