[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