summaryrefslogtreecommitdiff
path: root/libavfilter
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-11-03 13:57:01 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-11-03 13:57:05 +0100
commit2ed562d5fa05ae624c417210b71f6b8fdd46524d (patch)
tree73882dc00a2a484f760cd4c86dcf97030e5b9bf6 /libavfilter
parent91a697576169a19e01202035f0fb6e0d320edff3 (diff)
parent7b0a587393e03dab552d66450d43ab82bda0a5a1 (diff)
Merge remote-tracking branch 'cigaes/master'
* cigaes/master: lavfi/af_pan: support unknown layouts on input. lavfi/af_pan: support unknown layouts on output. lswr: fix assert failure on unknown layouts. lavfi: parsing helper for unknown channel layouts. lavfi/avfiltergraph: do not reduce incompatible lists. lavfi/avfiltergraph: suggest a solution when format selection fails. lavd/lavfi: support unknown channel layouts. lavf/wavenc: check for a single stream. lavd/alsa: add stream validation lavd/alsa: fix timestamp calculation Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavfilter')
-rw-r--r--libavfilter/af_aconvert.c2
-rw-r--r--libavfilter/af_pan.c26
-rw-r--r--libavfilter/asrc_aevalsrc.c2
-rw-r--r--libavfilter/asrc_anullsrc.c2
-rw-r--r--libavfilter/avfiltergraph.c7
-rw-r--r--libavfilter/formats.c17
-rw-r--r--libavfilter/internal.h5
7 files changed, 43 insertions, 18 deletions
diff --git a/libavfilter/af_aconvert.c b/libavfilter/af_aconvert.c
index 10497aa787..19095cb7e6 100644
--- a/libavfilter/af_aconvert.c
+++ b/libavfilter/af_aconvert.c
@@ -66,7 +66,7 @@ static av_cold int init(AVFilterContext *ctx)
(ret = ff_parse_sample_format(&aconvert->out_sample_fmt, aconvert->format_str, ctx)) < 0)
return ret;
if (aconvert->channel_layout_str && strcmp(aconvert->channel_layout_str, "auto"))
- return ff_parse_channel_layout(&aconvert->out_chlayout, aconvert->channel_layout_str, ctx);
+ return ff_parse_channel_layout(&aconvert->out_chlayout, NULL, aconvert->channel_layout_str, ctx);
return ret;
}
diff --git a/libavfilter/af_pan.c b/libavfilter/af_pan.c
index 1a01664675..d28f382482 100644
--- a/libavfilter/af_pan.c
+++ b/libavfilter/af_pan.c
@@ -46,7 +46,6 @@ typedef struct PanContext {
double gain[MAX_CHANNELS][MAX_CHANNELS];
int64_t need_renorm;
int need_renumber;
- int nb_input_channels;
int nb_output_channels;
int pure_gains;
@@ -116,10 +115,10 @@ static av_cold int init(AVFilterContext *ctx)
if (!args)
return AVERROR(ENOMEM);
arg = av_strtok(args, "|", &tokenizer);
- ret = ff_parse_channel_layout(&pan->out_channel_layout, arg, ctx);
+ ret = ff_parse_channel_layout(&pan->out_channel_layout,
+ &pan->nb_output_channels, arg, ctx);
if (ret < 0)
goto fail;
- pan->nb_output_channels = av_get_channel_layout_nb_channels(pan->out_channel_layout);
/* parse channel specifications */
while ((arg = arg0 = av_strtok(NULL, "|", &tokenizer))) {
@@ -239,12 +238,14 @@ static int query_formats(AVFilterContext *ctx)
ff_set_common_samplerates(ctx, formats);
// inlink supports any channel layout
- layouts = ff_all_channel_layouts();
+ layouts = ff_all_channel_counts();
ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts);
// outlink supports only requested output channel layout
layouts = NULL;
- ff_add_channel_layout(&layouts, pan->out_channel_layout);
+ ff_add_channel_layout(&layouts,
+ pan->out_channel_layout ? pan->out_channel_layout :
+ FF_COUNT2LAYOUT(pan->nb_output_channels));
ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
return 0;
}
@@ -257,7 +258,6 @@ static int config_props(AVFilterLink *link)
int i, j, k, r;
double t;
- pan->nb_input_channels = av_get_channel_layout_nb_channels(link->channel_layout);
if (pan->need_renumber) {
// input channels were given by their name: renumber them
for (i = j = 0; i < MAX_CHANNELS; i++) {
@@ -271,7 +271,7 @@ static int config_props(AVFilterLink *link)
// sanity check; can't be done in query_formats since the inlink
// channel layout is unknown at that time
- if (pan->nb_input_channels > SWR_CH_MAX ||
+ if (link->channels > SWR_CH_MAX ||
pan->nb_output_channels > SWR_CH_MAX) {
av_log(ctx, AV_LOG_ERROR,
"libswresample support a maximum of %d channels. "
@@ -286,6 +286,10 @@ static int config_props(AVFilterLink *link)
0, ctx);
if (!pan->swr)
return AVERROR(ENOMEM);
+ if (!link->channel_layout)
+ av_opt_set_int(pan->swr, "ich", link->channels, 0);
+ if (!pan->out_channel_layout)
+ av_opt_set_int(pan->swr, "och", pan->nb_output_channels, 0);
// gains are pure, init the channel mapping
if (pan->pure_gains) {
@@ -293,7 +297,7 @@ static int config_props(AVFilterLink *link)
// get channel map from the pure gains
for (i = 0; i < pan->nb_output_channels; i++) {
int ch_id = -1;
- for (j = 0; j < pan->nb_input_channels; j++) {
+ for (j = 0; j < link->channels; j++) {
if (pan->gain[i][j]) {
ch_id = j;
break;
@@ -311,7 +315,7 @@ static int config_props(AVFilterLink *link)
if (!((pan->need_renorm >> i) & 1))
continue;
t = 0;
- for (j = 0; j < pan->nb_input_channels; j++)
+ for (j = 0; j < link->channels; j++)
t += pan->gain[i][j];
if (t > -1E-5 && t < 1E-5) {
// t is almost 0 but not exactly, this is probably a mistake
@@ -320,7 +324,7 @@ static int config_props(AVFilterLink *link)
"Degenerate coefficients while renormalizing\n");
continue;
}
- for (j = 0; j < pan->nb_input_channels; j++)
+ for (j = 0; j < link->channels; j++)
pan->gain[i][j] /= t;
}
av_opt_set_int(pan->swr, "icl", link->channel_layout, 0);
@@ -335,7 +339,7 @@ static int config_props(AVFilterLink *link)
// summary
for (i = 0; i < pan->nb_output_channels; i++) {
cur = buf;
- for (j = 0; j < pan->nb_input_channels; j++) {
+ for (j = 0; j < link->channels; j++) {
r = snprintf(cur, buf + sizeof(buf) - cur, "%s%.3g i%d",
j ? " + " : "", pan->gain[i][j], j);
cur += FFMIN(buf + sizeof(buf) - cur, r);
diff --git a/libavfilter/asrc_aevalsrc.c b/libavfilter/asrc_aevalsrc.c
index ded533d568..4c1bbdf1f8 100644
--- a/libavfilter/asrc_aevalsrc.c
+++ b/libavfilter/asrc_aevalsrc.c
@@ -109,7 +109,7 @@ static av_cold int init(AVFilterContext *ctx)
if (eval->chlayout_str) {
int n;
- ret = ff_parse_channel_layout(&eval->chlayout, eval->chlayout_str, ctx);
+ ret = ff_parse_channel_layout(&eval->chlayout, NULL, eval->chlayout_str, ctx);
if (ret < 0)
goto end;
diff --git a/libavfilter/asrc_anullsrc.c b/libavfilter/asrc_anullsrc.c
index 26b32e1647..28d4500a25 100644
--- a/libavfilter/asrc_anullsrc.c
+++ b/libavfilter/asrc_anullsrc.c
@@ -68,7 +68,7 @@ static av_cold int init(AVFilterContext *ctx)
null->sample_rate_str, ctx)) < 0)
return ret;
- if ((ret = ff_parse_channel_layout(&null->channel_layout,
+ if ((ret = ff_parse_channel_layout(&null->channel_layout, NULL,
null->channel_layout_str, ctx)) < 0)
return ret;
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 506d79ec71..1fb83c4877 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -654,6 +654,10 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref)
av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
" the link between filters %s and %s.\n", link->src->name,
link->dst->name);
+ if (!link->in_channel_layouts->all_counts)
+ av_log(link->src, AV_LOG_ERROR, "Unknown channel layouts not "
+ "supported, try specifying a channel layout using "
+ "'aformat=channel_layouts=something'.\n");
return AVERROR(EINVAL);
}
link->in_channel_layouts->nb_channel_layouts = 1;
@@ -737,7 +741,8 @@ static int reduce_formats_on_filter(AVFilterContext *filter)
if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
continue;
- if (fmts->all_layouts) {
+ if (fmts->all_layouts &&
+ (!FF_LAYOUT2COUNT(fmt) || fmts->all_counts)) {
/* Turn the infinite list into a singleton */
fmts->all_layouts = fmts->all_counts = 0;
ff_add_channel_layout(&outlink->in_channel_layouts, fmt);
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index d51bf3c51d..5816032746 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -615,10 +615,21 @@ int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
return 0;
}
-int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
+int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
+ void *log_ctx)
{
char *tail;
- int64_t chlayout = av_get_channel_layout(arg);
+ int64_t chlayout, count;
+
+ if (nret) {
+ count = strtol(arg, &tail, 10);
+ if (*tail == 'c' && !tail[1] && count > 0 && count < 63) {
+ *nret = count;
+ *ret = 0;
+ return 0;
+ }
+ }
+ chlayout = av_get_channel_layout(arg);
if (chlayout == 0) {
chlayout = strtol(arg, &tail, 10);
if (*tail || chlayout == 0) {
@@ -627,6 +638,8 @@ int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
}
}
*ret = chlayout;
+ if (nret)
+ *nret = av_get_channel_layout_nb_channels(chlayout);
return 0;
}
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index f8d0cce638..5e19698d07 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -207,11 +207,14 @@ int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx);
* Parse a channel layout or a corresponding integer representation.
*
* @param ret 64bit integer pointer to where the value should be written.
+ * @param nret integer pointer to the number of channels;
+ * if not NULL, then unknown channel layouts are accepted
* @param arg string to parse
* @param log_ctx log context
* @return >= 0 in case of success, a negative AVERROR code on error
*/
-int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx);
+int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
+ void *log_ctx);
void ff_update_link_current_pts(AVFilterLink *link, int64_t pts);