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
185 return NULL;185 return NULL;
186}186}
187 187
188static 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
188static int filter_query_formats(AVFilterContext *ctx)203static int filter_query_formats(AVFilterContext *ctx)
189{204{
190 int ret;205 int ret, i;
191 AVFilterFormats *formats;206 AVFilterFormats *formats;
192 AVFilterChannelLayouts *chlayouts;207 AVFilterChannelLayouts *chlayouts;
193 AVFilterFormats *samplerates;208 AVFilterFormats *samplerates;
@@ -201,6 +216,11 @@ static int filter_query_formats(AVFilterContext *ctx) · 7 unmodified lines
201 return ret;216 return ret;
202 }217 }
203 218
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
204 formats = ff_all_formats(type);224 formats = ff_all_formats(type);
205 if (!formats)225 if (!formats)
206 return AVERROR(ENOMEM);226 return AVERROR(ENOMEM);
@@ -470,7 +490,7 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 263 unmodified lines
470 link->in_samplerates->format_count = 1;490 link->in_samplerates->format_count = 1;
471 link->sample_rate = link->in_samplerates->formats[0];491 link->sample_rate = link->in_samplerates->formats[0];
472 492
473 if (!link->in_channel_layouts->nb_channel_layouts) {493 if (link->in_channel_layouts->all_layouts) {
474 av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"494 av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for"
475 "the link between filters %s and %s.\n", link->src->name,495 "the link between filters %s and %s.\n", link->src->name,
476 link->dst->name);496 link->dst->name);
@@ -478,7 +498,10 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) · 1 unmodified line
478 }498 }
479 link->in_channel_layouts->nb_channel_layouts = 1;499 link->in_channel_layouts->nb_channel_layouts = 1;
480 link->channel_layout = link->in_channel_layouts->channel_layouts[0];500 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);
482 }505 }
483 506
484 ff_formats_unref(&link->in_formats);507 ff_formats_unref(&link->in_formats);
@@ -534,8 +557,42 @@ static int reduce_formats_on_filter(AVFilterContext *filter) · 49 unmodified lines
534 format_count, ff_add_format);557 format_count, ff_add_format);
535 REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats,558 REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats,
536 format_count, ff_add_format);559 format_count, ff_add_format);
537 REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts,560
538 channel_layouts, nb_channel_layouts, ff_add_channel_layout);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 }
539 596
540 return ret;597 return ret;
541}598}
@@ -663,7 +720,23 @@ static void swap_channel_layouts_on_filter(AVFilterContext *filter) · 121 unmodified lines
663 int out_channels = av_get_channel_layout_nb_channels(out_chlayout);720 int out_channels = av_get_channel_layout_nb_channels(out_chlayout);
664 int count_diff = out_channels - in_channels;721 int count_diff = out_channels - in_channels;
665 int matched_channels, extra_channels;722 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 }
667 740
668 /* channel substitution */741 /* channel substitution */
669 for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {742 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