[PATCH] Add sample_aspect_ratio fields to vsrc_buffer arguments. This fixes aspect handling in ffmpeg.
Stefano Sabatini
stefano.sabatini-lala
Wed Feb 2 20:39:57 CET 2011
Also clarify documentation for -aspect ffmpeg option and its
interaction with -vf.
This is based on a patch by Michael, which was based on a patch by
Baptiste.
Fix issues 2359 and 2378.
---
cmdutils.c | 23 +++++++++++++++++++++++
cmdutils.h | 1 +
doc/APIchanges | 5 ++++-
doc/ffmpeg.texi | 6 ++++++
doc/filters.texi | 11 ++++++++---
ffmpeg.c | 16 +++++++++++++---
libavfilter/avfilter.h | 2 +-
libavfilter/vsrc_buffer.c | 7 +++++--
8 files changed, 61 insertions(+), 10 deletions(-)
diff --git a/cmdutils.c b/cmdutils.c
index 58fe85c..e97e8ef 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -809,6 +809,28 @@ static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque)
return 0;
}
+static int ffsink_config_props(AVFilterLink *inlink)
+{
+ FFSinkContext *priv = inlink->dst->priv;
+ AVRational dar = av_d2q(priv->display_aspect_ratio, 100);
+ AVRational sar;
+
+ if (dar.num <= 0)
+ return 0;
+
+ av_reduce(&sar.num, &sar.den,
+ dar.num * inlink->h,
+ dar.den * inlink->w, 100);
+
+ av_log(inlink->dst, AV_LOG_INFO, "w:%d h:%d dar:%f -> dar:%d/%d sar:%d/%d\n",
+ inlink->w, inlink->h, priv->display_aspect_ratio,
+ dar.num, dar.den, sar.num, sar.den);
+
+ inlink->sample_aspect_ratio = sar;
+
+ return 0;
+}
+
static void null_end_frame(AVFilterLink *inlink) { }
static int ffsink_query_formats(AVFilterContext *ctx)
@@ -829,6 +851,7 @@ AVFilter ffsink = {
.inputs = (AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO,
+ .config_props = ffsink_config_props,
.end_frame = null_end_frame,
.min_perms = AV_PERM_READ, },
{ .name = NULL }},
diff --git a/cmdutils.h b/cmdutils.h
index c3d8a42..604feeb 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -284,6 +284,7 @@ FILE *get_preset_file(char *filename, size_t filename_size,
typedef struct {
enum PixelFormat pix_fmt;
+ float display_aspect_ratio;
} FFSinkContext;
extern AVFilter ffsink;
diff --git a/doc/APIchanges b/doc/APIchanges
index b14ae7f..14ac7af 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,7 +13,10 @@ libavutil: 2009-03-08
API changes, most recent first:
-2011-02-XX - XXXXXXX - lavfi 1.75.0 - AVFilterLink sample_aspect_ratio
+2011-02-XX - X - lavfi 1.76.0 - vsrc_buffer
+ Add sample_aspect_ratio fields to vsrc_buffer arguments.
+
+2011-02-XX - X - lavfi 1.75.0 - AVFilterLink sample_aspect_ratio
Add sample_aspect_ratio field to AVFilterLink.
2011-02-04 - f124b08 - lavf 52.96.0 - avformat_free_context()
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 8b8e42f..7b3a9fd 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -233,6 +233,12 @@ The following abbreviations are recognized:
@item -aspect @var{aspect}
Set aspect ratio (4:3, 16:9 or 1.3333, 1.7777).
+
+For output streams, this value overrides the value eventually set by a
+setdar filter at the end of the filtering chain.
+If not set the aspect ratio is assumed to be the same of the
+corresponding input stream.
+
@item -croptop @var{size}
@item -cropbottom @var{size}
@item -cropleft @var{size}
diff --git a/doc/filters.texi b/doc/filters.texi
index 3842886..ccddc33 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -1014,7 +1014,7 @@ This source is mainly intended for a programmatic use, in particular
through the interface defined in @file{libavfilter/vsrc_buffer.h}.
It accepts the following parameters:
- at var{width}:@var{height}:@var{pix_fmt_string}:@var{timebase_num}:@var{timebase_den}
+ at var{width}:@var{height}:@var{pix_fmt_string}:@var{timebase_num}:@var{timebase_den}:@var{sample_aspect_ratio_num}:@var{sample_aspect_ratio.den}
All the parameters need to be explicitely defined.
@@ -1033,15 +1033,20 @@ name.
@item timebase_num, timebase_den
Specify numerator and denomitor of the timebase assumed by the
timestamps of the buffered frames.
+
+ at item sample_aspect_ratio.num, sample_aspect_ratio.den
+Specify numerator and denominator of the sample aspect ratio assumed
+by the video frames.
@end table
For example:
@example
-buffer=320:240:yuv410p:1:24
+buffer=320:240:yuv410p:1:24:1:1
@end example
will instruct the source to accept video frames with size 320x240 and
-with format "yuv410p" and assuming 1/24 as the timestamps timebase.
+with format "yuv410p", assuming 1/24 as the timestamps timebase and
+square pixels (1:1 sample aspect ratio).
Since the pixel format with name "yuv410p" corresponds to the number 6
(check the enum PixelFormat definition in @file{libavutil/pixfmt.h}),
this example corresponds to:
diff --git a/ffmpeg.c b/ffmpeg.c
index b0d3320..ad82b8d 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -354,14 +354,22 @@ static int configure_filters(AVInputStream *ist, AVOutputStream *ost)
/** filter graph containing all filters including input & output */
AVCodecContext *codec = ost->st->codec;
AVCodecContext *icodec = ist->st->codec;
- FFSinkContext ffsink_ctx = { .pix_fmt = codec->pix_fmt };
+ FFSinkContext ffsink_ctx = { .pix_fmt = codec->pix_fmt, .display_aspect_ratio = frame_aspect_ratio };
+ AVRational sample_aspect_ratio;
char args[255];
int ret;
graph = avfilter_graph_alloc();
- snprintf(args, 255, "%d:%d:%d:%d:%d", ist->st->codec->width,
- ist->st->codec->height, ist->st->codec->pix_fmt, 1, AV_TIME_BASE);
+ if (ist->st->sample_aspect_ratio.num){
+ sample_aspect_ratio = ist->st->sample_aspect_ratio;
+ }else
+ sample_aspect_ratio = ist->st->codec->sample_aspect_ratio;
+
+ snprintf(args, 255, "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width,
+ ist->st->codec->height, ist->st->codec->pix_fmt, 1, AV_TIME_BASE,
+ sample_aspect_ratio.num, sample_aspect_ratio.den);
+
ret = avfilter_graph_create_filter(&ist->input_video_filter, avfilter_get_by_name("buffer"),
"src", args, NULL, graph);
if (ret < 0)
@@ -415,6 +423,8 @@ static int configure_filters(AVInputStream *ist, AVOutputStream *ost)
codec->width = ist->output_video_filter->inputs[0]->w;
codec->height = ist->output_video_filter->inputs[0]->h;
+ codec->sample_aspect_ratio = ost->st->sample_aspect_ratio =
+ ist->output_video_filter->inputs[0]->sample_aspect_ratio;
return 0;
}
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 48555fd..451d0be 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -27,7 +27,7 @@
#include "libavcore/samplefmt.h"
#define LIBAVFILTER_VERSION_MAJOR 1
-#define LIBAVFILTER_VERSION_MINOR 75
+#define LIBAVFILTER_VERSION_MINOR 76
#define LIBAVFILTER_VERSION_MICRO 0
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
diff --git a/libavfilter/vsrc_buffer.c b/libavfilter/vsrc_buffer.c
index 74d9bf6..6845c74 100644
--- a/libavfilter/vsrc_buffer.c
+++ b/libavfilter/vsrc_buffer.c
@@ -68,8 +68,10 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
int n = 0;
if (!args ||
- (n = sscanf(args, "%d:%d:%127[^:]:%d:%d", &c->w, &c->h, pix_fmt_str, &c->time_base.num, &c->time_base.den)) != 5) {
- av_log(ctx, AV_LOG_ERROR, "Expected 5 arguments, but only %d found in '%s'\n", n, args);
+ (n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d", &c->w, &c->h, pix_fmt_str,
+ &c->time_base.num, &c->time_base.den,
+ &c->pixel_aspect.num, &c->pixel_aspect.den)) != 7) {
+ av_log(ctx, AV_LOG_ERROR, "Expected 7 arguments, but only %d found in '%s'\n", n, args);
return AVERROR(EINVAL);
}
if ((c->pix_fmt = av_get_pix_fmt(pix_fmt_str)) == PIX_FMT_NONE) {
@@ -100,6 +102,7 @@ static int config_props(AVFilterLink *link)
link->w = c->w;
link->h = c->h;
+ link->sample_aspect_ratio = c->pixel_aspect;
link->time_base = c->time_base;
return 0;
--
1.7.2.3
--6c2NcOVqGQ03X4Wi--
More information about the ffmpeg-devel
mailing list