static int query_formats(AVFilterContext *ctx) { LADSPAContext *s = ctx->priv; AVFilterFormats *formats; AVFilterChannelLayouts *layouts; static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }; formats = ff_make_format_list(sample_fmts); if (!formats) return AVERROR(ENOMEM); ff_set_common_formats(ctx, formats); if (s->nb_inputs) { formats = ff_all_samplerates(); if (!formats) return AVERROR(ENOMEM); ff_set_common_samplerates(ctx, formats); } else { int sample_rates[] = { s->sample_rate, -1 }; ff_set_common_samplerates(ctx, ff_make_format_list(sample_rates)); } if (s->nb_inputs == 1 && s->nb_outputs == 1) { // We will instantiate multiple LADSPA_Handle, one over each channel layouts = ff_all_channel_layouts(); if (!layouts) return AVERROR(ENOMEM); ff_set_common_channel_layouts(ctx, layouts); } else { AVFilterLink *outlink = ctx->outputs[0]; if (s->nb_inputs >= 1) { AVFilterLink *inlink = ctx->inputs[0]; int64_t inlayout = FF_COUNT2LAYOUT(s->nb_inputs); layouts = NULL; ff_add_channel_layout(&layouts, inlayout); ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts); if (!s->nb_outputs) ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts); } if (s->nb_outputs >= 1) { int64_t outlayout = FF_COUNT2LAYOUT(s->nb_outputs); layouts = NULL; ff_add_channel_layout(&layouts, outlayout); ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts); } } return 0; }
static int query_formats(AVFilterContext *ctx) { BufferSourceContext *c = ctx->priv; AVFilterChannelLayouts *channel_layouts = NULL; AVFilterFormats *formats = NULL; AVFilterFormats *samplerates = NULL; int ret; switch (ctx->outputs[0]->type) { case AVMEDIA_TYPE_VIDEO: if ((ret = ff_add_format (&formats, c->pix_fmt)) < 0 || (ret = ff_set_common_formats (ctx , formats )) < 0) return ret; break; case AVMEDIA_TYPE_AUDIO: if ((ret = ff_add_format (&formats , c->sample_fmt )) < 0 || (ret = ff_set_common_formats (ctx , formats )) < 0 || (ret = ff_add_format (&samplerates, c->sample_rate)) < 0 || (ret = ff_set_common_samplerates (ctx , samplerates )) < 0) return ret; if ((ret = ff_add_channel_layout(&channel_layouts, c->channel_layout ? c->channel_layout : FF_COUNT2LAYOUT(c->channels))) < 0) return ret; if ((ret = ff_set_common_channel_layouts(ctx, channel_layouts)) < 0) return ret; break; default: return AVERROR(EINVAL); } return 0; }
static int64_t *concat_channels_lists(const int64_t *layouts, const int *counts) { int nb_layouts = 0, nb_counts = 0, i; int64_t *list; if (layouts) for (; layouts[nb_layouts] != -1; nb_layouts++); if (counts) for (; counts[nb_counts] != -1; nb_counts++); if (nb_counts > INT_MAX - 1 - nb_layouts) return NULL; if (!(list = av_calloc(nb_layouts + nb_counts + 1, sizeof(*list)))) return NULL; for (i = 0; i < nb_layouts; i++) list[i] = layouts[i]; for (i = 0; i < nb_counts; i++) list[nb_layouts + i] = FF_COUNT2LAYOUT(counts[i]); list[nb_layouts + nb_counts] = -1; return list; }
static int query_formats(AVFilterContext *ctx) { SpectrumSynthContext *s = ctx->priv; AVFilterFormats *formats = NULL; AVFilterChannelLayouts *layout = NULL; AVFilterLink *magnitude = ctx->inputs[0]; AVFilterLink *phase = ctx->inputs[1]; AVFilterLink *outlink = ctx->outputs[0]; static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }; static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_NONE }; int ret, sample_rates[] = { 48000, -1 }; formats = ff_make_format_list(sample_fmts); if ((ret = ff_formats_ref (formats, &outlink->in_formats )) < 0 || (ret = ff_add_channel_layout (&layout, FF_COUNT2LAYOUT(s->channels))) < 0 || (ret = ff_channel_layouts_ref (layout , &outlink->in_channel_layouts)) < 0) return ret; sample_rates[0] = s->sample_rate; formats = ff_make_format_list(sample_rates); if (!formats) return AVERROR(ENOMEM); if ((ret = ff_formats_ref(formats, &outlink->in_samplerates)) < 0) return ret; formats = ff_make_format_list(pix_fmts); if (!formats) return AVERROR(ENOMEM); if ((ret = ff_formats_ref(formats, &magnitude->out_formats)) < 0) return ret; formats = ff_make_format_list(pix_fmts); if (!formats) return AVERROR(ENOMEM); if ((ret = ff_formats_ref(formats, &phase->out_formats)) < 0) return ret; return 0; }
AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a, AVFilterChannelLayouts *b) { AVFilterChannelLayouts *ret = NULL; unsigned a_all = a->all_layouts + a->all_counts; unsigned b_all = b->all_layouts + b->all_counts; int ret_max, ret_nb = 0, i, j, round; if (a == b) return a; /* Put the most generic set in a, to avoid doing everything twice */ if (a_all < b_all) { FFSWAP(AVFilterChannelLayouts *, a, b); FFSWAP(unsigned, a_all, b_all); } if (a_all) { if (a_all == 1 && !b_all) { /* keep only known layouts in b; works also for b_all = 1 */ for (i = j = 0; i < b->nb_channel_layouts; i++) if (KNOWN(b->channel_layouts[i])) b->channel_layouts[j++] = b->channel_layouts[i]; /* Not optimal: the unknown layouts of b may become known after another merge. */ if (!j) return NULL; b->nb_channel_layouts = j; } MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail); return b; } ret_max = a->nb_channel_layouts + b->nb_channel_layouts; if (!(ret = av_mallocz(sizeof(*ret))) || !(ret->channel_layouts = av_malloc(sizeof(*ret->channel_layouts) * ret_max))) goto fail; /* a[known] intersect b[known] */ for (i = 0; i < a->nb_channel_layouts; i++) { if (!KNOWN(a->channel_layouts[i])) continue; for (j = 0; j < b->nb_channel_layouts; j++) { if (a->channel_layouts[i] == b->channel_layouts[j]) { ret->channel_layouts[ret_nb++] = a->channel_layouts[i]; a->channel_layouts[i] = b->channel_layouts[j] = 0; } } } /* 1st round: a[known] intersect b[generic] 2nd round: a[generic] intersect b[known] */ for (round = 0; round < 2; round++) { for (i = 0; i < a->nb_channel_layouts; i++) { uint64_t fmt = a->channel_layouts[i], bfmt; if (!fmt || !KNOWN(fmt)) continue; bfmt = FF_COUNT2LAYOUT(av_get_channel_layout_nb_channels(fmt)); for (j = 0; j < b->nb_channel_layouts; j++) if (b->channel_layouts[j] == bfmt) ret->channel_layouts[ret_nb++] = a->channel_layouts[i]; } /* 1st round: swap to prepare 2nd round; 2nd round: put it back */ FFSWAP(AVFilterChannelLayouts *, a, b); } /* a[generic] intersect b[generic] */ for (i = 0; i < a->nb_channel_layouts; i++) { if (KNOWN(a->channel_layouts[i])) continue; for (j = 0; j < b->nb_channel_layouts; j++) if (a->channel_layouts[i] == b->channel_layouts[j]) ret->channel_layouts[ret_nb++] = a->channel_layouts[i]; } ret->nb_channel_layouts = ret_nb; if (!ret->nb_channel_layouts) goto fail; MERGE_REF(ret, a, channel_layouts, AVFilterChannelLayouts, fail); MERGE_REF(ret, b, channel_layouts, AVFilterChannelLayouts, fail); return ret; fail: if (ret) { av_freep(&ret->refs); av_freep(&ret->channel_layouts); } av_freep(&ret); return NULL; }