[FFmpeg-devel] [PATCH] Fix issue2359: ffmpeg -aspect 16:9 doesn't work

Mike Scheutzow mjs973
Wed Feb 2 17:41:12 CET 2011


This patch fixes the -aspect option for me. ffmpeg now correctly
overrides the image aspect ratio at the input to the encoder.

This patch is has been tested with "-vcodec mpeg4", "-vcodec copy"
and "-vf scale=w:h".

When testing, make sure you encode with a codec that implements
arbitrary aspect ratio (mpeg4 does, mpeg2 does not.)

Also, do not be confused by an unrelated bug. The ffmpeg status msg
for the output file SAR & DAR shows the wrong values if the input file
SAR is not exactly equal to the output file SAR.

However, 'ffmpeg -i infile' seems to accurately report the SAR and DAR,
so you can use this to check how a file was encoded.

Signed-off-by: Mike Scheutzow <mjs973 at optonline.net>
---
 ffmpeg.c |   46 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index df89018..eb1ad28 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -148,7 +148,10 @@ static int nb_streamid_map = 0;
 
 static int frame_width  = 0;
 static int frame_height = 0;
-static float frame_aspect_ratio = 0;
+
+/** set non-zero to force encoder display aspect ratio */
+static float enc_frame_aspect_ratio = 0;
+static float dec_frame_aspect_ratio = 0;
 static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE;
 static enum AVSampleFormat audio_sample_fmt = AV_SAMPLE_FMT_NONE;
 static int max_frames[4] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX};
@@ -1679,8 +1682,22 @@ static int output_packet(AVInputStream *ist, int 
ist_index,
                             break;
                         case AVMEDIA_TYPE_VIDEO:
 #if CONFIG_AVFILTER
-                            if (ist->picref->video)
-                                ost->st->codec->sample_aspect_ratio = 
ist->picref->video->pixel_aspect;
+                            if (ist->picref->video) {
+                                /* filter might change sample aspect 
ratio */
+                                AVRational sar;
+                                if (enc_frame_aspect_ratio == 0) {
+                                    /* result from filter chain */
+                                    sar = ist->picref->video->pixel_aspect;
+                                } else {
+                                    /* value forced by user */
+                                    sar = av_d2q(enc_frame_aspect_ratio *
+                                        ost->st->codec->height /
+                                        ost->st->codec->width,
+                                        255);
+                                }
+                                ost->st->codec->sample_aspect_ratio =  sar;
+                                ost->st->sample_aspect_ratio = sar;
+                            }
 #endif
                             do_video_out(os, ost, ist, &picture, 
&frame_size);
                             if (vstats_filename && frame_size)
@@ -2844,7 +2861,7 @@ static void opt_frame_aspect_ratio(const char *arg)
         fprintf(stderr, "Incorrect aspect ratio specification.\n");
         ffmpeg_exit(1);
     }
-    frame_aspect_ratio = ar;
+    enc_frame_aspect_ratio = ar;
 }
 
 static int opt_metadata(const char *opt, const char *arg)
@@ -3271,10 +3288,10 @@ static void opt_input_file(const char *filename)
             frame_height = dec->height;
             frame_width  = dec->width;
             if(ic->streams[i]->sample_aspect_ratio.num)
-                
frame_aspect_ratio=av_q2d(ic->streams[i]->sample_aspect_ratio);
+                
dec_frame_aspect_ratio=av_q2d(ic->streams[i]->sample_aspect_ratio);
             else
-                frame_aspect_ratio=av_q2d(dec->sample_aspect_ratio);
-            frame_aspect_ratio *= (float) dec->width / dec->height;
+                dec_frame_aspect_ratio=av_q2d(dec->sample_aspect_ratio);
+            dec_frame_aspect_ratio *= (float) dec->width / dec->height;
             frame_pix_fmt = dec->pix_fmt;
             rfps      = ic->streams[i]->r_frame_rate.num;
             rfps_base = ic->streams[i]->r_frame_rate.den;
@@ -3425,10 +3442,11 @@ static void new_video_stream(AVFormatContext 
*oc, int file_idx)
         st->stream_copy = 1;
         video_enc->codec_type = AVMEDIA_TYPE_VIDEO;
         video_enc->sample_aspect_ratio =
-        st->sample_aspect_ratio = 
av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
+        st->sample_aspect_ratio = 
av_d2q(dec_frame_aspect_ratio*frame_height/frame_width, 255);
     } else {
         const char *p;
         int i;
+        float frame_aspect;
         AVRational fps= frame_rate.num ? frame_rate : (AVRational){25,1};
 
         video_enc->codec_id = codec_id;
@@ -3439,9 +3457,17 @@ static void new_video_stream(AVFormatContext *oc, 
int file_idx)
         video_enc->time_base.den = fps.num;
         video_enc->time_base.num = fps.den;
 
+        /* assume that the decoder width, height and pixel aspect are 
correct
+         * for encoder. if a video filter is used, these fields are
+         * rewritten later. */
         video_enc->width = frame_width;
         video_enc->height = frame_height;
-        video_enc->sample_aspect_ratio = 
av_d2q(frame_aspect_ratio*video_enc->height/video_enc->width, 255);
+        if (enc_frame_aspect_ratio == 0) {
+            frame_aspect = dec_frame_aspect_ratio;
+        } else {
+            frame_aspect = enc_frame_aspect_ratio;  /* ratio forced by 
user */
+        }
+        video_enc->sample_aspect_ratio = 
av_d2q(frame_aspect*video_enc->height/video_enc->width, 255);
         video_enc->pix_fmt = frame_pix_fmt;
         st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
 
@@ -4238,7 +4264,7 @@ static const OptionDef options[] = {
     { "vframes", OPT_INT | HAS_ARG | OPT_VIDEO, 
{(void*)&max_frames[AVMEDIA_TYPE_VIDEO]}, "set the number of video 
frames to record", "number" },
     { "r", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, {(void*)opt_frame_rate}, 
"set frame rate (Hz value, fraction or abbreviation)", "rate" },
     { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame 
size (WxH or abbreviation)", "size" },
-    { "aspect", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_aspect_ratio}, 
"set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
+    { "aspect", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_aspect_ratio}, 
"set encoder aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
     { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, 
{(void*)opt_frame_pix_fmt}, "set pixel format, 'list' as argument shows 
all the pixel formats supported", "format" },
     { "croptop", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, 
{(void*)opt_frame_crop}, "Removed, use the crop filter instead", "size" },
     { "cropbottom", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, 
{(void*)opt_frame_crop}, "Removed, use the crop filter instead", "size" },
-- 
1.7.3.5





More information about the ffmpeg-devel mailing list