summaryrefslogtreecommitdiff
path: root/avconv_filter.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2016-05-23 14:09:08 +0200
committerAnton Khirnov <anton@khirnov.net>2016-06-25 12:04:32 +0200
commit50722b4f0cbc5940e9e6e21d113888436cc89ff5 (patch)
tree6e056d850cdfd6c3c91d75e97f4c6af2cbade392 /avconv_filter.c
parentba7397baef796ca3991fe1c921bc91054407c48b (diff)
avconv: decouple configuring filtergraphs and setting output parameters
Currently, a filtergraph will pull in the output constraints from its corresponding decoder context, which breaks proper layering. Instead, explicitly send the constaints on the output parameters to the filtergraph. This is similar to what is done for filtergraph inputs in 30ab4c51a180610d9f1720c75518d763515c0d9f
Diffstat (limited to 'avconv_filter.c')
-rw-r--r--avconv_filter.c50
1 files changed, 32 insertions, 18 deletions
diff --git a/avconv_filter.c b/avconv_filter.c
index 2332f99707..44f3d07eaf 100644
--- a/avconv_filter.c
+++ b/avconv_filter.c
@@ -38,13 +38,13 @@
/* Define a function for building a string containing a list of
* allowed formats. */
-#define DEF_CHOOSE_FORMAT(type, var, supported_list, none, get_name) \
-static char *choose_ ## var ## s(OutputStream *ost) \
+#define DEF_CHOOSE_FORMAT(suffix, type, var, supported_list, none, get_name) \
+static char *choose_ ## suffix (OutputFilter *ofilter) \
{ \
- if (ost->enc_ctx->var != none) { \
- get_name(ost->enc_ctx->var); \
+ if (ofilter->var != none) { \
+ get_name(ofilter->var); \
return av_strdup(name); \
- } else if (ost->enc && ost->enc->supported_list) { \
+ } else if (ofilter->supported_list) { \
const type *p; \
AVIOContext *s = NULL; \
uint8_t *ret; \
@@ -53,7 +53,7 @@ static char *choose_ ## var ## s(OutputStream *ost) \
if (avio_open_dyn_buf(&s) < 0) \
exit(1); \
\
- for (p = ost->enc->supported_list; *p != none; p++) { \
+ for (p = ofilter->supported_list; *p != none; p++) { \
get_name(*p); \
avio_printf(s, "%s|", name); \
} \
@@ -64,16 +64,16 @@ static char *choose_ ## var ## s(OutputStream *ost) \
return NULL; \
}
-DEF_CHOOSE_FORMAT(enum AVPixelFormat, pix_fmt, pix_fmts, AV_PIX_FMT_NONE,
+DEF_CHOOSE_FORMAT(pix_fmts, enum AVPixelFormat, format, formats, AV_PIX_FMT_NONE,
GET_PIX_FMT_NAME)
-DEF_CHOOSE_FORMAT(enum AVSampleFormat, sample_fmt, sample_fmts,
+DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME)
-DEF_CHOOSE_FORMAT(int, sample_rate, supported_samplerates, 0,
+DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
GET_SAMPLE_RATE_NAME)
-DEF_CHOOSE_FORMAT(uint64_t, channel_layout, channel_layouts, 0,
+DEF_CHOOSE_FORMAT(channel_layouts, uint64_t, channel_layout, channel_layouts, 0,
GET_CH_LAYOUT_NAME)
int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
@@ -89,6 +89,7 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
exit(1);
fg->outputs[0]->ost = ost;
fg->outputs[0]->graph = fg;
+ fg->outputs[0]->format = -1;
ost->filter = fg->outputs[0];
@@ -296,7 +297,6 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
char *pix_fmts;
OutputStream *ost = ofilter->ost;
OutputFile *of = output_files[ost->file_index];
- AVCodecContext *codec = ost->enc_ctx;
AVFilterContext *last_filter = out->filter_ctx;
int pad_idx = out->pad_idx;
int ret;
@@ -309,13 +309,12 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
if (ret < 0)
return ret;
- if (!hw_device_ctx && (codec->width || codec->height)) {
+ if (!hw_device_ctx && (ofilter->width || ofilter->height)) {
char args[255];
AVFilterContext *filter;
snprintf(args, sizeof(args), "%d:%d:0x%X",
- codec->width,
- codec->height,
+ ofilter->width, ofilter->height,
(unsigned)ost->sws_flags);
snprintf(name, sizeof(name), "scaler for output stream %d:%d",
ost->file_index, ost->index);
@@ -329,7 +328,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
pad_idx = 0;
}
- if ((pix_fmts = choose_pix_fmts(ost))) {
+ if ((pix_fmts = choose_pix_fmts(ofilter))) {
AVFilterContext *filter;
snprintf(name, sizeof(name), "pixel format for output stream %d:%d",
ost->file_index, ost->index);
@@ -402,9 +401,9 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
if (codec->channels && !codec->channel_layout)
codec->channel_layout = av_get_default_channel_layout(codec->channels);
- sample_fmts = choose_sample_fmts(ost);
- sample_rates = choose_sample_rates(ost);
- channel_layouts = choose_channel_layouts(ost);
+ sample_fmts = choose_sample_fmts(ofilter);
+ sample_rates = choose_sample_rates(ofilter);
+ channel_layouts = choose_channel_layouts(ofilter);
if (sample_fmts || sample_rates || channel_layouts) {
AVFilterContext *format;
char args[256];
@@ -747,6 +746,21 @@ int configure_filtergraph(FilterGraph *fg)
if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
return ret;
+ /* limit the lists of allowed formats to the ones selected, to
+ * make sure they stay the same if the filtergraph is reconfigured later */
+ for (i = 0; i < fg->nb_outputs; i++) {
+ OutputFilter *ofilter = fg->outputs[i];
+ AVFilterLink *link = ofilter->filter->inputs[0];
+
+ ofilter->format = link->format;
+
+ ofilter->width = link->w;
+ ofilter->height = link->h;
+
+ ofilter->sample_rate = link->sample_rate;
+ ofilter->channel_layout = link->channel_layout;
+ }
+
return 0;
}