History

lavfi: support unknown channel layouts.

Nicolas George committed 13 years ago

Commit b6afb2d1 parent fccd8c25 files · +184 −19Browse files

Showing the changes to libavfilter/avfiltergraph.c (1 of 5 files). Show all

Unified · Split

libavfilter/avfiltergraph.c+79−6
@@ -185,9 +185,24 @@ AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name) · 184 unmodified lines
185185 return NULL;
186186 }
187187
188+static void sanitize_channel_layouts(void *log, AVFilterChannelLayouts *l)
189+{
190+ if (!l)
191+ return;
192+ if (l->nb_channel_layouts) {
193+ if (l->all_layouts || l->all_counts)
194+ av_log(log, AV_LOG_WARNING, "All layouts set on non-empty list\n");
195+ l->all_layouts = l->all_counts = 0;
196+ } else {
197+ if (l->all_counts && !l->all_layouts)
198+ av_log(log, AV_LOG_WARNING, "All counts without all layouts\n");
199+ l->all_layouts = 1;
200+ }
201+}
202+
188203 static int filter_query_formats(AVFilterContext *ctx)
189204 {
190− int ret;
205+ int ret, i;
191206 AVFilterFormats *formats;
192207 AVFilterChannelLayouts *chlayouts;
193208 AVFilterFormats *samplerates;
@@ -201,6 +216,11 @@ static int filter_query_formats(AVFilterContext *ctx) · 7 unmodified lines
201216 return ret;
202217 }
203218
219+ for (i = 0; i < ctx->nb_inputs; i++)
220+ sanitize_channel_layouts(ctx, ctx->inputs[i]->out_channel_layouts);
221+ for (i = 0; i < ctx->nb_outputs; i++)
222+ sanitize_channel_layouts(ctx, ctx->outputs[i]->in_channel_layouts);
223+
204224 formats = ff_all_formats(type);
205225 if (!formats)
206226 return AVERROR(ENOMEM);
@@ -470,7 +490,7 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 263 unmodified lines
470490 link->in_samplerates->format_count = 1;
471491 link->sample_rate = link->in_samplerates->formats[0];
472492
473− if (!link->in_channel_layouts->nb_channel_layouts) {
493+ if (link->in_channel_layouts->all_layouts) {
474494 av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
475495 "the link between filters %s and %s.\n", link->src->name,
476496 link->dst->name);
@@ -478,7 +498,10 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 1 unmodified line
478498 }
479499 link->in_channel_layouts->nb_channel_layouts = 1;
480500 link->channel_layout = link->in_channel_layouts->channel_layouts[0];
481− link->channels = av_get_channel_layout_nb_channels(link->channel_layout);
501+ if ((link->channels = FF_LAYOUT2COUNT(link->channel_layout)))
502+ link->channel_layout = 0;
503+ else
504+ link->channels = av_get_channel_layout_nb_channels(link->channel_layout);
482505 }
483506
484507 ff_formats_unref(&link->in_formats);
@@ -534,8 +557,42 @@ static int reduce_formats_on_filter(AVFilterContext *filter) · 49 unmodified lines
534557 format_count, ff_add_format);
535558 REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats,
536559 format_count, ff_add_format);
537− REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts,
538− channel_layouts, nb_channel_layouts, ff_add_channel_layout);
560+
561+ /* reduce channel layouts */
562+ for (i = 0; i < filter->nb_inputs; i++) {
563+ AVFilterLink *inlink = filter->inputs[i];
564+ uint64_t fmt;
565+
566+ if (!inlink->out_channel_layouts ||
567+ inlink->out_channel_layouts->nb_channel_layouts != 1)
568+ continue;
569+ fmt = inlink->out_channel_layouts->channel_layouts[0];
570+
571+ for (j = 0; j < filter->nb_outputs; j++) {
572+ AVFilterLink *outlink = filter->outputs[j];
573+ AVFilterChannelLayouts *fmts;
574+
575+ fmts = outlink->in_channel_layouts;
576+ if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
577+ continue;
578+
579+ if (fmts->all_layouts) {
580+ /* Turn the infinite list into a singleton */
581+ fmts->all_layouts = fmts->all_counts = 0;
582+ ff_add_channel_layout(&outlink->in_channel_layouts, fmt);
583+ break;
584+ }
585+
586+ for (k = 0; k < outlink->in_channel_layouts->nb_channel_layouts; k++) {
587+ if (fmts->channel_layouts[k] == fmt) {
588+ fmts->channel_layouts[0] = fmt;
589+ fmts->nb_channel_layouts = 1;
590+ ret = 1;
591+ break;
592+ }
593+ }
594+ }
595+ }
539596
540597 return ret;
541598 }
@@ -663,7 +720,23 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter) · 121 unmodified lines
663720 int out_channels = av_get_channel_layout_nb_channels(out_chlayout);
664721 int count_diff = out_channels - in_channels;
665722 int matched_channels, extra_channels;
666− int score = 0;
723+ int score = 100000;
724+
725+ if (FF_LAYOUT2COUNT(in_chlayout) || FF_LAYOUT2COUNT(out_chlayout)) {
726+ /* Compute score in case the input or output layout encodes
727+ a channel count; in this case the score is not altered by
728+ the computation afterwards, as in_chlayout and
729+ out_chlayout have both been set to 0 */
730+ if (FF_LAYOUT2COUNT(in_chlayout))
731+ in_channels = FF_LAYOUT2COUNT(in_chlayout);
732+ if (FF_LAYOUT2COUNT(out_chlayout))
733+ out_channels = FF_LAYOUT2COUNT(out_chlayout);
734+ score -= 10000 + FFABS(out_channels - in_channels) +
735+ (in_channels > out_channels ? 10000 : 0);
736+ in_chlayout = out_chlayout = 0;
737+ /* Let the remaining computation run, even if the score
738+ value is not altered */
739+ }
667740
668741 /* channel substitution */
669742 for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t