[FFmpeg-devel] [PATCH 2/2] lavfi: add layout negotiation fields and helper functions.
Mina Nagy Zaki
mnzaki at gmail.com
Thu Jun 9 12:27:50 CEST 2011
---
libavfilter/avfilter.c | 3 ++
libavfilter/avfilter.h | 30 +++++++++++++++++-------
libavfilter/avfiltergraph.c | 10 +++++++-
libavfilter/defaults.c | 52 +++++++++++++++++++++++++++---------------
libavfilter/formats.c | 22 ++++++++++++++++++
5 files changed, 88 insertions(+), 29 deletions(-)
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index acab816..815a5f5 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -217,6 +217,9 @@ int avfilter_insert_filter(AVFilterLink *link,
AVFilterContext *filt,
if (link->out_formats)
avfilter_formats_changeref(&link->out_formats,
&filt->outputs[filt_dstpad_idx]-
>out_formats);
+ if (link->out_chlayouts)
+ avfilter_formats_changeref(&link->out_chlayouts,
+ &filt->outputs[filt_dstpad_idx]-
>out_chlayouts);
return 0;
}
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 3a71fb4..483758a 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -255,6 +255,11 @@ int avfilter_add_format(AVFilterFormats **avff, int64_t
fmt);
AVFilterFormats *avfilter_all_formats(enum AVMediaType type);
/**
+ * Return a list of all channel layouts supported by FFmpeg.
+ */
+AVFilterFormats *avfilter_all_chlayouts(void);
+
+/**
* Return a format list which contains the intersection of the formats of
* a and b. Also, all the references of a, all the references of b, and
* a and b themselves will be deallocated.
@@ -465,11 +470,12 @@ AVFilterBufferRef
*avfilter_default_get_audio_buffer(AVFilterLink *link, int per
int64_t channel_layout,
int planar);
/**
- * A helper for query_formats() which sets all links to the same list of
- * formats. If there are no links hooked to this filter, the list of formats
is
- * freed.
+ * Helpers for query_formats() which set all links to the same list of
+ * formats/layouts. If there are no links hooked to this filter, the list
+ * of formats is freed.
*/
void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats
*formats);
+void avfilter_set_common_chlayouts(AVFilterContext *ctx, AVFilterFormats
*formats);
/** Default handler for query_formats() */
int avfilter_default_query_formats(AVFilterContext *ctx);
@@ -520,9 +526,9 @@ typedef struct AVFilter {
void (*uninit)(AVFilterContext *ctx);
/**
- * Queries formats supported by the filter and its pads, and sets the
- * in_formats for links connected to its output pads, and out_formats
- * for links connected to its input pads.
+ * Queries formats/layouts supported by the filter and its pads, and sets
+ * the in_formats/in_chlayouts for links connected to its output pads,
+ * and out_formats/out_chlayouts for links connected to its input pads.
*
* @return zero on success, a negative value corresponding to an
* AVERROR code otherwise
@@ -592,13 +598,19 @@ struct AVFilterLink {
int format; ///< agreed upon media format
/**
- * Lists of formats supported by the input and output filters
respectively.
- * These lists are used for negotiating the format to actually be used,
- * which will be loaded into the format member, above, when chosen.
+ * Lists of formats and channel layouts supported by the input and output
+ * filters respectively. These lists are used for negotiating the format
+ * to actually be used, which will be loaded into the format and
+ * channel_layout members, above, when chosen.
+ *
+ * An empty list indicates that all formats are supported.
*/
AVFilterFormats *in_formats;
AVFilterFormats *out_formats;
+ AVFilterFormats *in_chlayouts;
+ AVFilterFormats *out_chlayouts;
+
/**
* The buffer reference currently being sent across the link by the source
* filter. This is used internally by the filter system to allow
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index bdf22b3..080f29f 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -195,9 +195,17 @@ static void pick_format(AVFilterLink *link)
link->in_formats->format_count = 1;
link->format = link->in_formats->formats[0];
-
avfilter_formats_unref(&link->in_formats);
avfilter_formats_unref(&link->out_formats);
+
+ if (link->type == AVMEDIA_TYPE_AUDIO) {
+ link->in_chlayouts->format_count = 1;
+ link->channel_layout = link->in_chlayouts->formats[0];
+ avfilter_formats_unref(&link->in_chlayouts);
+ avfilter_formats_unref(&link->out_chlayouts);
+
+ }
+
}
static void pick_formats(AVFilterGraph *graph)
diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c
index c98dfa9..505a24f 100644
--- a/libavfilter/defaults.c
+++ b/libavfilter/defaults.c
@@ -204,28 +204,38 @@ int avfilter_default_config_output_link(AVFilterLink
*link)
* FIXME: this will need changed for filters with a mix of pad types
* (video + audio, etc)
*/
+
+#define SET_COMMON_ELEMS(type) do { \
+ int count = 0, i; \
+ \
+ for (i = 0; i < ctx->input_count; i++) { \
+ if (ctx->inputs[i]) { \
+ avfilter_formats_ref(formats, &ctx->inputs[i]->out_##type); \
+ count++; \
+ } \
+ } \
+ for (i = 0; i < ctx->output_count; i++) { \
+ if (ctx->outputs[i]) { \
+ avfilter_formats_ref(formats, &ctx->outputs[i]->in_##type); \
+ count++; \
+ } \
+ } \
+ \
+ if (!count) { \
+ av_free(formats->formats); \
+ av_free(formats->refs); \
+ av_free(formats); \
+ } \
+} while(0)
+
void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats
*formats)
{
- int count = 0, i;
-
- for (i = 0; i < ctx->input_count; i++) {
- if (ctx->inputs[i]) {
- avfilter_formats_ref(formats, &ctx->inputs[i]->out_formats);
- count++;
- }
- }
- for (i = 0; i < ctx->output_count; i++) {
- if (ctx->outputs[i]) {
- avfilter_formats_ref(formats, &ctx->outputs[i]->in_formats);
- count++;
- }
- }
+ SET_COMMON_ELEMS(formats);
+}
- if (!count) {
- av_free(formats->formats);
- av_free(formats->refs);
- av_free(formats);
- }
+void avfilter_set_common_chlayouts(AVFilterContext *ctx, AVFilterFormats
*formats)
+{
+ SET_COMMON_ELEMS(chlayouts);
}
int avfilter_default_query_formats(AVFilterContext *ctx)
@@ -235,6 +245,10 @@ int avfilter_default_query_formats(AVFilterContext *ctx)
AVMEDIA_TYPE_VIDEO;
avfilter_set_common_formats(ctx, avfilter_all_formats(type));
+
+ if (type == AVMEDIA_TYPE_AUDIO)
+ avfilter_set_common_chlayouts(ctx, avfilter_all_chlayouts());
+
return 0;
}
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index 962a915..181a671 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -20,6 +20,7 @@
*/
#include "libavutil/pixdesc.h"
+#include "libavutil/audioconvert.h"
#include "avfilter.h"
/**
@@ -123,6 +124,27 @@ AVFilterFormats *avfilter_all_formats(enum AVMediaType
type)
return ret;
}
+AVFilterFormats *avfilter_all_chlayouts(void)
+{
+ int64_t chlayouts[] = {
+ AV_CH_LAYOUT_MONO,
+ AV_CH_LAYOUT_STEREO,
+ AV_CH_LAYOUT_4POINT0,
+ AV_CH_LAYOUT_QUAD,
+ AV_CH_LAYOUT_5POINT0,
+ AV_CH_LAYOUT_5POINT0_BACK,
+ AV_CH_LAYOUT_5POINT1,
+ AV_CH_LAYOUT_5POINT1_BACK,
+ AV_CH_LAYOUT_5POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX,
+ AV_CH_LAYOUT_7POINT1,
+ AV_CH_LAYOUT_7POINT1_WIDE,
+ AV_CH_LAYOUT_7POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX,
+ -1,
+ };
+
+ return avfilter_make_format_list(chlayouts);
+}
+
void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
{
*ref = f;
--
1.7.4.4
More information about the ffmpeg-devel
mailing list