You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	avfilter: convert to new channel layout API
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
		| @@ -57,7 +57,7 @@ typedef struct EvalContext { | ||||
|     const AVClass *class; | ||||
|     char *sample_rate_str; | ||||
|     int sample_rate; | ||||
|     int64_t chlayout; | ||||
|     AVChannelLayout chlayout; | ||||
|     char *chlayout_str; | ||||
|     int nb_channels;            ///< number of output channels | ||||
|     int nb_in_channels;         ///< number of input channels | ||||
| @@ -70,7 +70,6 @@ typedef struct EvalContext { | ||||
|     uint64_t n; | ||||
|     double var_values[VAR_VARS_NB]; | ||||
|     double *channel_values; | ||||
|     int64_t out_channel_layout; | ||||
| } EvalContext; | ||||
|  | ||||
| static double val(void *priv, double ch) | ||||
| @@ -181,7 +180,7 @@ static av_cold int init(AVFilterContext *ctx) | ||||
|             if (ret < 0) | ||||
|                 return ret; | ||||
|  | ||||
|             ret = parse_channel_expressions(ctx, av_get_channel_layout_nb_channels(eval->chlayout)); | ||||
|             ret = parse_channel_expressions(ctx, eval->chlayout.nb_channels); | ||||
|             if (ret < 0) | ||||
|                 return ret; | ||||
|         } | ||||
| @@ -190,8 +189,8 @@ static av_cold int init(AVFilterContext *ctx) | ||||
|         if ((ret = parse_channel_expressions(ctx, -1)) < 0) | ||||
|             return ret; | ||||
|  | ||||
|         eval->chlayout = av_get_default_channel_layout(eval->nb_channels); | ||||
|         if (!eval->chlayout && eval->nb_channels <= 0) { | ||||
|         av_channel_layout_default(&eval->chlayout, eval->nb_channels); | ||||
|         if (eval->nb_channels <= 0) { | ||||
|             av_log(ctx, AV_LOG_ERROR, "Invalid number of channels '%d' provided\n", | ||||
|                    eval->nb_channels); | ||||
|             return AVERROR(EINVAL); | ||||
| @@ -217,6 +216,7 @@ static av_cold void uninit(AVFilterContext *ctx) | ||||
|     } | ||||
|     av_freep(&eval->expr); | ||||
|     av_freep(&eval->channel_values); | ||||
|     av_channel_layout_uninit(&eval->chlayout); | ||||
| } | ||||
|  | ||||
| static int config_props(AVFilterLink *outlink) | ||||
| @@ -229,9 +229,9 @@ static int config_props(AVFilterLink *outlink) | ||||
|  | ||||
|     eval->var_values[VAR_S] = eval->sample_rate; | ||||
|     eval->var_values[VAR_NB_IN_CHANNELS] = NAN; | ||||
|     eval->var_values[VAR_NB_OUT_CHANNELS] = outlink->channels; | ||||
|     eval->var_values[VAR_NB_OUT_CHANNELS] = outlink->ch_layout.nb_channels; | ||||
|  | ||||
|     av_get_channel_layout_string(buf, sizeof(buf), 0, eval->chlayout); | ||||
|     av_channel_layout_describe(&eval->chlayout, buf, sizeof(buf)); | ||||
|  | ||||
|     av_log(outlink->src, AV_LOG_VERBOSE, | ||||
|            "sample_rate:%d chlayout:%s duration:%"PRId64"\n", | ||||
| @@ -244,7 +244,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
| { | ||||
|     EvalContext *eval = ctx->priv; | ||||
|     static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_DBLP, AV_SAMPLE_FMT_NONE }; | ||||
|     int64_t chlayouts[] = { eval->chlayout ? eval->chlayout : FF_COUNT2LAYOUT(eval->nb_channels) , -1 }; | ||||
|     AVChannelLayout chlayouts[] = { eval->chlayout.nb_channels ? eval->chlayout : FF_COUNT2LAYOUT(eval->nb_channels), { 0 } }; | ||||
|     int sample_rates[] = { eval->sample_rate, -1 }; | ||||
|     int ret; | ||||
|  | ||||
| @@ -365,9 +365,7 @@ static int aeval_query_formats(AVFilterContext *ctx) | ||||
|     } else { | ||||
|         // outlink supports only requested output channel layout | ||||
|         layouts = NULL; | ||||
|         if ((ret = ff_add_channel_layout(&layouts, | ||||
|                               eval->out_channel_layout ? eval->out_channel_layout : | ||||
|                               FF_COUNT2LAYOUT(eval->nb_channels))) < 0) | ||||
|         if ((ret = ff_add_channel_layout(&layouts, &FF_COUNT2LAYOUT(eval->nb_channels))) < 0) | ||||
|             return ret; | ||||
|         if ((ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts)) < 0) | ||||
|             return ret; | ||||
| @@ -387,20 +385,21 @@ static int aeval_config_output(AVFilterLink *outlink) | ||||
|     int ret; | ||||
|  | ||||
|     if (eval->same_chlayout) { | ||||
|         eval->chlayout = inlink->channel_layout; | ||||
|         if ((ret = av_channel_layout_copy(&eval->chlayout, &inlink->ch_layout)) < 0) | ||||
|             return ret; | ||||
|  | ||||
|         if ((ret = parse_channel_expressions(ctx, inlink->channels)) < 0) | ||||
|         if ((ret = parse_channel_expressions(ctx, inlink->ch_layout.nb_channels)) < 0) | ||||
|             return ret; | ||||
|     } | ||||
|  | ||||
|     eval->n = 0; | ||||
|     eval->nb_in_channels = eval->var_values[VAR_NB_IN_CHANNELS] = inlink->channels; | ||||
|     eval->var_values[VAR_NB_OUT_CHANNELS] = outlink->channels; | ||||
|     eval->nb_in_channels = eval->var_values[VAR_NB_IN_CHANNELS] = inlink->ch_layout.nb_channels; | ||||
|     eval->var_values[VAR_NB_OUT_CHANNELS] = outlink->ch_layout.nb_channels; | ||||
|     eval->var_values[VAR_S] = inlink->sample_rate; | ||||
|     eval->var_values[VAR_T] = NAN; | ||||
|  | ||||
|     eval->channel_values = av_realloc_f(eval->channel_values, | ||||
|                                         inlink->channels, sizeof(*eval->channel_values)); | ||||
|                                         inlink->ch_layout.nb_channels, sizeof(*eval->channel_values)); | ||||
|     if (!eval->channel_values) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
| @@ -430,10 +429,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         eval->var_values[VAR_N] = eval->n; | ||||
|         eval->var_values[VAR_T] = t0 + i * (double)1/inlink->sample_rate; | ||||
|  | ||||
|         for (j = 0; j < inlink->channels; j++) | ||||
|         for (j = 0; j < inlink->ch_layout.nb_channels; j++) | ||||
|             eval->channel_values[j] = *((double *) in->extended_data[j] + i); | ||||
|  | ||||
|         for (j = 0; j < outlink->channels; j++) { | ||||
|         for (j = 0; j < outlink->ch_layout.nb_channels; j++) { | ||||
|             eval->var_values[VAR_CH] = j; | ||||
|             *((double *) out->extended_data[j] + i) = | ||||
|                 av_expr_eval(eval->expr[j], eval->var_values, eval); | ||||
|   | ||||
| @@ -152,7 +152,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     } | ||||
|  | ||||
|     s->filter((void **)out->extended_data, (const void **)in->extended_data, | ||||
|               in->nb_samples, in->channels, s->contrast / 750); | ||||
|               in->nb_samples, in->ch_layout.nb_channels, s->contrast / 750); | ||||
|  | ||||
|     if (out != in) | ||||
|         av_frame_free(&in); | ||||
|   | ||||
| @@ -356,8 +356,8 @@ static int filter_channels_## name(AVFilterContext *ctx, void *arg, int jobnr, i | ||||
|     AudioCrossoverContext *s = ctx->priv;                                                   \ | ||||
|     AVFrame *in = arg;                                                           \ | ||||
|     AVFrame **frames = s->frames;                                                           \ | ||||
|     const int start = (in->channels * jobnr) / nb_jobs;                                     \ | ||||
|     const int end = (in->channels * (jobnr+1)) / nb_jobs;                                   \ | ||||
|     const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs;                        \ | ||||
|     const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;                      \ | ||||
|     const int nb_samples = in->nb_samples;                                                  \ | ||||
|     const int nb_outs = ctx->nb_outputs;                                                    \ | ||||
|     const int first_order = s->first_order;                                                 \ | ||||
| @@ -496,7 +496,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         goto fail; | ||||
|  | ||||
|     ff_filter_execute(ctx, s->filter_channels, in, NULL, | ||||
|                       FFMIN(inlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(inlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     for (int i = 0; i < ctx->nb_outputs; i++) { | ||||
|         if (ff_outlink_get_status(ctx->outputs[i])) { | ||||
|   | ||||
| @@ -244,7 +244,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|             s->round = round(s->samples); | ||||
|         } | ||||
|  | ||||
|         for (c = 0; c < inlink->channels; c++) { | ||||
|         for (c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|             double sample = src[c] * level_in; | ||||
|  | ||||
|             sample = mix * samplereduction(s, &s->sr[c], sample) + src[c] * (1. - mix) * level_in; | ||||
| @@ -296,7 +296,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|     s->lfo.amount = .5; | ||||
|  | ||||
|     if (!s->sr) | ||||
|         s->sr = av_calloc(inlink->channels, sizeof(*s->sr)); | ||||
|         s->sr = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->sr)); | ||||
|     if (!s->sr) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|   | ||||
| @@ -151,7 +151,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|     s->efifo = av_audio_fifo_alloc(inlink->format, 1, s->window_size); | ||||
|     if (!s->efifo) | ||||
|         return AVERROR(ENOMEM); | ||||
|     s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->window_size); | ||||
|     s->fifo = av_audio_fifo_alloc(inlink->format, inlink->ch_layout.nb_channels, s->window_size); | ||||
|     if (!s->fifo) | ||||
|         return AVERROR(ENOMEM); | ||||
|     s->overlap_skip = s->method ? (s->window_size - s->hop_size) / 2 : 0; | ||||
| @@ -160,12 +160,12 @@ static int config_input(AVFilterLink *inlink) | ||||
|                             s->overlap_skip); | ||||
|     } | ||||
|  | ||||
|     s->nb_channels = inlink->channels; | ||||
|     s->chan = av_calloc(inlink->channels, sizeof(*s->chan)); | ||||
|     s->nb_channels = inlink->ch_layout.nb_channels; | ||||
|     s->chan = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->chan)); | ||||
|     if (!s->chan) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (i = 0; i < inlink->channels; i++) { | ||||
|     for (i = 0; i < inlink->ch_layout.nb_channels; i++) { | ||||
|         DeclickChannel *c = &s->chan[i]; | ||||
|  | ||||
|         c->detection = av_calloc(s->window_size, sizeof(*c->detection)); | ||||
| @@ -557,11 +557,11 @@ static int filter_frame(AVFilterLink *inlink) | ||||
|         goto fail; | ||||
|  | ||||
|     td.out = out; | ||||
|     ret = ff_filter_execute(ctx, filter_channel, &td, NULL, inlink->channels); | ||||
|     ret = ff_filter_execute(ctx, filter_channel, &td, NULL, inlink->ch_layout.nb_channels); | ||||
|     if (ret < 0) | ||||
|         goto fail; | ||||
|  | ||||
|     for (ch = 0; ch < s->in->channels; ch++) { | ||||
|     for (ch = 0; ch < s->in->ch_layout.nb_channels; ch++) { | ||||
|         double *is = (double *)s->is->extended_data[ch]; | ||||
|  | ||||
|         for (j = 0; j < s->hop_size; j++) { | ||||
| @@ -580,7 +580,7 @@ static int filter_frame(AVFilterLink *inlink) | ||||
|     s->pts += av_rescale_q(s->hop_size, (AVRational){1, outlink->sample_rate}, outlink->time_base); | ||||
|  | ||||
|     s->detected_errors += detected_errors; | ||||
|     s->nb_samples += out->nb_samples * inlink->channels; | ||||
|     s->nb_samples += out->nb_samples * inlink->ch_layout.nb_channels; | ||||
|  | ||||
|     ret = ff_filter_frame(outlink, out); | ||||
|     if (ret < 0) | ||||
|   | ||||
| @@ -131,12 +131,12 @@ static int config_input(AVFilterLink *inlink) | ||||
|         s->seed = av_get_random_seed(); | ||||
|     av_lfg_init(&s->c, s->seed); | ||||
|  | ||||
|     s->nb_channels = inlink->channels; | ||||
|     s->ap = av_calloc(inlink->channels, sizeof(*s->ap)); | ||||
|     s->nb_channels = inlink->ch_layout.nb_channels; | ||||
|     s->ap = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->ap)); | ||||
|     if (!s->ap) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (int i = 0; i < inlink->channels; i++) { | ||||
|     for (int i = 0; i < inlink->ch_layout.nb_channels; i++) { | ||||
|         for (int j = 0; j < s->stages; j++) { | ||||
|             ret = ap_init(&s->ap[i][j], inlink->sample_rate, | ||||
|                           (double)av_lfg_get(&s->c) / 0xffffffff * 2.2917e-3 + 0.83333e-3); | ||||
| @@ -160,8 +160,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo | ||||
|     ThreadData *td = arg; | ||||
|     AVFrame *out = td->out; | ||||
|     AVFrame *in = td->in; | ||||
|     const int start = (in->channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|  | ||||
|     for (int ch = start; ch < end; ch++) | ||||
|         s->filter_channel(ctx, ch, in, out); | ||||
| @@ -189,7 +189,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|  | ||||
|     td.in = in; td.out = out; | ||||
|     ff_filter_execute(ctx, filter_channels, &td, NULL, | ||||
|                       FFMIN(inlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(inlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     if (out != in) | ||||
|         av_frame_free(&in); | ||||
|   | ||||
| @@ -187,10 +187,10 @@ static int config_input(AVFilterLink *inlink) | ||||
|     char *p, *saveptr = NULL; | ||||
|     int i; | ||||
|  | ||||
|     s->chandelay = av_calloc(inlink->channels, sizeof(*s->chandelay)); | ||||
|     s->chandelay = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->chandelay)); | ||||
|     if (!s->chandelay) | ||||
|         return AVERROR(ENOMEM); | ||||
|     s->nb_delays = inlink->channels; | ||||
|     s->nb_delays = inlink->ch_layout.nb_channels; | ||||
|     s->block_align = av_get_bytes_per_sample(inlink->format); | ||||
|  | ||||
|     p = s->delays; | ||||
| @@ -371,7 +371,7 @@ static int activate(AVFilterContext *ctx) | ||||
|  | ||||
|         av_samples_set_silence(frame->extended_data, 0, | ||||
|                                frame->nb_samples, | ||||
|                                outlink->channels, | ||||
|                                outlink->ch_layout.nb_channels, | ||||
|                                frame->format); | ||||
|  | ||||
|         frame->pts = s->next_pts; | ||||
| @@ -403,7 +403,7 @@ static int activate(AVFilterContext *ctx) | ||||
|  | ||||
|         av_samples_set_silence(frame->extended_data, 0, | ||||
|                                frame->nb_samples, | ||||
|                                outlink->channels, | ||||
|                                outlink->ch_layout.nb_channels, | ||||
|                                frame->format); | ||||
|  | ||||
|         frame->pts = s->next_pts; | ||||
|   | ||||
| @@ -200,8 +200,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo | ||||
|     ThreadData *td = arg; | ||||
|     AVFrame *out = td->out; | ||||
|     AVFrame *in = td->in; | ||||
|     const int start = (in->channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|  | ||||
|     for (int ch = start; ch < end; ch++) { | ||||
|         s->filter(ctx, out->extended_data[ch], | ||||
| @@ -234,7 +234,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     s->level = exp(s->level_db / 20. * M_LN10); | ||||
|     td.in = in; td.out = out; | ||||
|     ff_filter_execute(ctx, filter_channels, &td, NULL, | ||||
|                       FFMIN(inlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(inlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     s->in_samples += in->nb_samples; | ||||
|  | ||||
|   | ||||
| @@ -109,7 +109,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     if (ctx->is_disabled) { | ||||
|         if (s->prev) | ||||
|             av_samples_set_silence(s->prev->extended_data, 0, 1, | ||||
|                                    s->prev->channels, | ||||
|                                    s->prev->ch_layout.nb_channels, | ||||
|                                    s->prev->format); | ||||
|  | ||||
|         return ff_filter_frame(outlink, in); | ||||
| @@ -131,7 +131,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     } | ||||
|  | ||||
|     s->filter((void **)out->extended_data, (void **)s->prev->extended_data, (const void **)in->extended_data, | ||||
|               in->nb_samples, in->channels); | ||||
|               in->nb_samples, in->ch_layout.nb_channels); | ||||
|  | ||||
|     av_frame_free(&in); | ||||
|     return ff_filter_frame(outlink, out); | ||||
|   | ||||
| @@ -157,8 +157,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo | ||||
|     const double tqfactor = s->tqfactor; | ||||
|     const double fg = tan(M_PI * tfrequency / sample_rate); | ||||
|     const double dg = tan(M_PI * dfrequency / sample_rate); | ||||
|     const int start = (in->channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|     const int mode = s->mode; | ||||
|     const double knee = s->knee; | ||||
|     const double slew = s->slew; | ||||
| @@ -245,7 +245,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     td.in = in; | ||||
|     td.out = out; | ||||
|     ff_filter_execute(ctx, filter_channels, &td, NULL, | ||||
|                      FFMIN(outlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                      FFMIN(outlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     if (out != in) | ||||
|         av_frame_free(&in); | ||||
|   | ||||
| @@ -63,7 +63,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         av_frame_copy_props(out, in); | ||||
|     } | ||||
|  | ||||
|     for (int ch = 0; ch < out->channels; ch++) { | ||||
|     for (int ch = 0; ch < out->ch_layout.nb_channels; ch++) { | ||||
|         const double *src = (const double *)in->extended_data[ch]; | ||||
|         double *dst = (double *)out->extended_data[ch]; | ||||
|         double *coeffs = (double *)s->coeffs->extended_data[ch]; | ||||
|   | ||||
| @@ -236,7 +236,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|     av_freep(&s->delayptrs); | ||||
|  | ||||
|     return av_samples_alloc_array_and_samples(&s->delayptrs, NULL, | ||||
|                                               outlink->channels, | ||||
|                                               outlink->ch_layout.nb_channels, | ||||
|                                               s->max_samples, | ||||
|                                               outlink->format, 0); | ||||
| } | ||||
| @@ -259,7 +259,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) | ||||
|     } | ||||
|  | ||||
|     s->echo_samples(s, s->delayptrs, frame->extended_data, out_frame->extended_data, | ||||
|                     frame->nb_samples, inlink->channels); | ||||
|                     frame->nb_samples, inlink->ch_layout.nb_channels); | ||||
|  | ||||
|     s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base); | ||||
|  | ||||
| @@ -282,11 +282,11 @@ static int request_frame(AVFilterLink *outlink) | ||||
|  | ||||
|     av_samples_set_silence(frame->extended_data, 0, | ||||
|                            frame->nb_samples, | ||||
|                            outlink->channels, | ||||
|                            outlink->ch_layout.nb_channels, | ||||
|                            frame->format); | ||||
|  | ||||
|     s->echo_samples(s, s->delayptrs, frame->extended_data, frame->extended_data, | ||||
|                     frame->nb_samples, outlink->channels); | ||||
|                     frame->nb_samples, outlink->ch_layout.nb_channels); | ||||
|  | ||||
|     frame->pts = s->next_pts; | ||||
|     if (s->next_pts != AV_NOPTS_VALUE) | ||||
|   | ||||
| @@ -105,8 +105,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo | ||||
|     ThreadData *td = arg; | ||||
|     AVFrame *out = td->out; | ||||
|     AVFrame *in = td->in; | ||||
|     const int start = (in->channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|  | ||||
|     for (int ch = start; ch < end; ch++) { | ||||
|         const double *src = (const double *)in->extended_data[ch]; | ||||
| @@ -144,7 +144,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|  | ||||
|     td.in = in; td.out = out; | ||||
|     ff_filter_execute(ctx, filter_channels, &td, NULL, | ||||
|                       FFMIN(inlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(inlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     if (in != out) | ||||
|         av_frame_free(&in); | ||||
|   | ||||
| @@ -195,7 +195,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|  | ||||
|     dst = (double *)out->data[0]; | ||||
|     for (int n = 0; n < in->nb_samples; n++) { | ||||
|         for (int c = 0; c < inlink->channels; c++) { | ||||
|         for (int c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|             double sample = src[c] * level_in; | ||||
|  | ||||
|             sample = distortion_process(s, &s->cp[c], sample); | ||||
| @@ -208,8 +208,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|                 dst[c] = sample; | ||||
|         } | ||||
|  | ||||
|         src += inlink->channels; | ||||
|         dst += inlink->channels; | ||||
|         src += inlink->ch_layout.nb_channels; | ||||
|         dst += inlink->ch_layout.nb_channels; | ||||
|     } | ||||
|  | ||||
|     if (in != out) | ||||
| @@ -231,11 +231,11 @@ static int config_input(AVFilterLink *inlink) | ||||
|     AExciterContext *s = ctx->priv; | ||||
|  | ||||
|     if (!s->cp) | ||||
|         s->cp = av_calloc(inlink->channels, sizeof(*s->cp)); | ||||
|         s->cp = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->cp)); | ||||
|     if (!s->cp) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (int i = 0; i < inlink->channels; i++) | ||||
|     for (int i = 0; i < inlink->ch_layout.nb_channels; i++) | ||||
|         set_params(&s->cp[i], s->blend, s->drive, inlink->sample_rate, | ||||
|                    s->freq, s->ceil); | ||||
|  | ||||
|   | ||||
| @@ -289,7 +289,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) | ||||
|     if ((!s->type && (cur_sample + nb_samples < s->start_sample)) || | ||||
|         ( s->type && (s->start_sample + s->nb_samples < cur_sample))) { | ||||
|         av_samples_set_silence(out_buf->extended_data, 0, nb_samples, | ||||
|                                out_buf->channels, out_buf->format); | ||||
|                                out_buf->ch_layout.nb_channels, out_buf->format); | ||||
|     } else { | ||||
|         int64_t start; | ||||
|  | ||||
| @@ -299,7 +299,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) | ||||
|             start = s->start_sample + s->nb_samples - cur_sample; | ||||
|  | ||||
|         s->fade_samples(out_buf->extended_data, buf->extended_data, | ||||
|                         nb_samples, buf->channels, | ||||
|                         nb_samples, buf->ch_layout.nb_channels, | ||||
|                         s->type ? -1 : 1, start, | ||||
|                         s->nb_samples, s->curve); | ||||
|     } | ||||
| @@ -502,7 +502,7 @@ static int activate(AVFilterContext *ctx) | ||||
|  | ||||
|             s->crossfade_samples(out->extended_data, cf[0]->extended_data, | ||||
|                                  cf[1]->extended_data, | ||||
|                                  s->nb_samples, out->channels, | ||||
|                                  s->nb_samples, out->ch_layout.nb_channels, | ||||
|                                  s->curve, s->curve2); | ||||
|             out->pts = s->pts; | ||||
|             s->pts += av_rescale_q(s->nb_samples, | ||||
| @@ -523,7 +523,7 @@ static int activate(AVFilterContext *ctx) | ||||
|             } | ||||
|  | ||||
|             s->fade_samples(out->extended_data, cf[0]->extended_data, s->nb_samples, | ||||
|                             outlink->channels, -1, s->nb_samples - 1, s->nb_samples, s->curve); | ||||
|                             outlink->ch_layout.nb_channels, -1, s->nb_samples - 1, s->nb_samples, s->curve); | ||||
|             out->pts = s->pts; | ||||
|             s->pts += av_rescale_q(s->nb_samples, | ||||
|                 (AVRational){ 1, outlink->sample_rate }, outlink->time_base); | ||||
| @@ -543,7 +543,7 @@ static int activate(AVFilterContext *ctx) | ||||
|             } | ||||
|  | ||||
|             s->fade_samples(out->extended_data, cf[1]->extended_data, s->nb_samples, | ||||
|                             outlink->channels, 1, 0, s->nb_samples, s->curve2); | ||||
|                             outlink->ch_layout.nb_channels, 1, 0, s->nb_samples, s->curve2); | ||||
|             out->pts = s->pts; | ||||
|             s->pts += av_rescale_q(s->nb_samples, | ||||
|                 (AVRational){ 1, outlink->sample_rate }, outlink->time_base); | ||||
|   | ||||
| @@ -641,11 +641,11 @@ static int config_input(AVFilterLink *inlink) | ||||
|     double wscale, sar, sum, sdiv; | ||||
|     int i, j, k, m, n, ret; | ||||
|  | ||||
|     s->dnch = av_calloc(inlink->channels, sizeof(*s->dnch)); | ||||
|     s->dnch = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->dnch)); | ||||
|     if (!s->dnch) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     s->channels = inlink->channels; | ||||
|     s->channels = inlink->ch_layout.nb_channels; | ||||
|     s->sample_rate = inlink->sample_rate; | ||||
|     s->sample_advance = s->sample_rate / 80; | ||||
|     s->window_length = 3 * s->sample_advance; | ||||
| @@ -704,7 +704,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|     if (!s->band_alpha || !s->band_beta) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (int ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         DeNoiseChannel *dnch = &s->dnch[ch]; | ||||
|         float scale = 1.f; | ||||
|  | ||||
| @@ -786,7 +786,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|             return AVERROR(ENOMEM); | ||||
|     } | ||||
|  | ||||
|     for (int ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         DeNoiseChannel *dnch = &s->dnch[ch]; | ||||
|         double *prior_band_excit = dnch->prior_band_excit; | ||||
|         double min, max; | ||||
| @@ -871,7 +871,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|     s->sample_floor = s->floor * exp(4.144600506562284); | ||||
|     s->auto_floor = s->floor * exp(6.907667510937141); | ||||
|  | ||||
|     for (int ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         DeNoiseChannel *dnch = &s->dnch[ch]; | ||||
|  | ||||
|         dnch->noise_reduction = s->noise_reduction; | ||||
| @@ -1040,8 +1040,8 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job | ||||
| { | ||||
|     AudioFFTDeNoiseContext *s = ctx->priv; | ||||
|     AVFrame *in = arg; | ||||
|     const int start = (in->channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|     const int window_length = s->window_length; | ||||
|     const double *window = s->window; | ||||
|  | ||||
| @@ -1122,7 +1122,7 @@ static int output_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     if (s->track_noise) { | ||||
|         double average = 0.0, min = DBL_MAX, max = -DBL_MAX; | ||||
|  | ||||
|         for (int ch = 0; ch < inlink->channels; ch++) { | ||||
|         for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|             DeNoiseChannel *dnch = &s->dnch[ch]; | ||||
|             double levels[NB_PROFILE_BANDS]; | ||||
|  | ||||
| @@ -1133,9 +1133,9 @@ static int output_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|             min = fmin(min, dnch->noise_floor); | ||||
|         } | ||||
|  | ||||
|         average /= inlink->channels; | ||||
|         average /= inlink->ch_layout.nb_channels; | ||||
|  | ||||
|         for (int ch = 0; ch < inlink->channels; ch++) { | ||||
|         for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|             DeNoiseChannel *dnch = &s->dnch[ch]; | ||||
|  | ||||
|             switch (s->noise_floor_link) { | ||||
| @@ -1153,7 +1153,7 @@ static int output_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     } | ||||
|  | ||||
|     if (s->sample_noise_start) { | ||||
|         for (int ch = 0; ch < inlink->channels; ch++) { | ||||
|         for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|             DeNoiseChannel *dnch = &s->dnch[ch]; | ||||
|  | ||||
|             init_sample_noise(dnch); | ||||
| @@ -1163,7 +1163,7 @@ static int output_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     } | ||||
|  | ||||
|     if (s->sample_noise) { | ||||
|         for (int ch = 0; ch < inlink->channels; ch++) { | ||||
|         for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|             DeNoiseChannel *dnch = &s->dnch[ch]; | ||||
|  | ||||
|             sample_noise_block(s, dnch, s->winframe, ch); | ||||
| @@ -1171,7 +1171,7 @@ static int output_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     } | ||||
|  | ||||
|     if (s->sample_noise_end) { | ||||
|         for (int ch = 0; ch < inlink->channels; ch++) { | ||||
|         for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|             DeNoiseChannel *dnch = &s->dnch[ch]; | ||||
|             double sample_noise[NB_PROFILE_BANDS]; | ||||
|  | ||||
| @@ -1185,7 +1185,7 @@ static int output_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|  | ||||
|     s->block_count++; | ||||
|     ff_filter_execute(ctx, filter_channel, s->winframe, NULL, | ||||
|                       FFMIN(outlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(outlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     if (av_frame_is_writable(in)) { | ||||
|         out = in; | ||||
| @@ -1199,7 +1199,7 @@ static int output_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         out->pts = in->pts; | ||||
|     } | ||||
|  | ||||
|     for (int ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         DeNoiseChannel *dnch = &s->dnch[ch]; | ||||
|         double *src = dnch->out_samples; | ||||
|         const float *orig = (const float *)s->winframe->extended_data[ch]; | ||||
|   | ||||
| @@ -109,7 +109,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|     const char *last_expr = "1"; | ||||
|     int buf_size; | ||||
|  | ||||
|     s->channels = inlink->channels; | ||||
|     s->channels = inlink->ch_layout.nb_channels; | ||||
|     ret = av_tx_init(&s->fft, &s->tx_fn, AV_TX_FLOAT_FFT, 0, s->fft_size, &scale, 0); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
| @@ -121,19 +121,19 @@ static int config_input(AVFilterLink *inlink) | ||||
|     s->window_size = s->fft_size; | ||||
|     buf_size = FFALIGN(s->window_size, av_cpu_max_align()); | ||||
|  | ||||
|     s->fft_in = av_calloc(inlink->channels, sizeof(*s->fft_in)); | ||||
|     s->fft_in = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->fft_in)); | ||||
|     if (!s->fft_in) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     s->fft_out = av_calloc(inlink->channels, sizeof(*s->fft_out)); | ||||
|     s->fft_out = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->fft_out)); | ||||
|     if (!s->fft_out) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     s->fft_temp = av_calloc(inlink->channels, sizeof(*s->fft_temp)); | ||||
|     s->fft_temp = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->fft_temp)); | ||||
|     if (!s->fft_temp) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         s->fft_in[ch] = av_calloc(buf_size, sizeof(**s->fft_in)); | ||||
|         if (!s->fft_in[ch]) | ||||
|             return AVERROR(ENOMEM); | ||||
| @@ -147,11 +147,11 @@ static int config_input(AVFilterLink *inlink) | ||||
|             return AVERROR(ENOMEM); | ||||
|     } | ||||
|  | ||||
|     s->real = av_calloc(inlink->channels, sizeof(*s->real)); | ||||
|     s->real = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->real)); | ||||
|     if (!s->real) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     s->imag = av_calloc(inlink->channels, sizeof(*s->imag)); | ||||
|     s->imag = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->imag)); | ||||
|     if (!s->imag) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
| @@ -159,7 +159,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|     if (!args) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr); | ||||
|  | ||||
|         ret = av_expr_parse(&s->real[ch], arg ? arg : last_expr, var_names, | ||||
| @@ -179,7 +179,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|  | ||||
|     saveptr = NULL; | ||||
|     last_expr = "1"; | ||||
|     for (ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr); | ||||
|  | ||||
|         ret = av_expr_parse(&s->imag[ch], arg ? arg : last_expr, var_names, | ||||
| @@ -232,7 +232,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     int ch, n, ret, i; | ||||
|     AVFrame *out; | ||||
|  | ||||
|     for (ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         const int offset = s->window_size - s->hop_size; | ||||
|         float *src = (float *)s->window->extended_data[ch]; | ||||
|         AVComplexFloat *fft_in = s->fft_in[ch]; | ||||
| @@ -250,16 +250,16 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     values[VAR_PTS]         = in->pts; | ||||
|     values[VAR_SAMPLE_RATE] = inlink->sample_rate; | ||||
|     values[VAR_NBBINS]      = window_size / 2; | ||||
|     values[VAR_CHANNELS]    = inlink->channels; | ||||
|     values[VAR_CHANNELS]    = inlink->ch_layout.nb_channels; | ||||
|  | ||||
|     for (ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         AVComplexFloat *fft_in = s->fft_in[ch]; | ||||
|         AVComplexFloat *fft_out = s->fft_out[ch]; | ||||
|  | ||||
|         s->tx_fn(s->fft, fft_out, fft_in, sizeof(float)); | ||||
|     } | ||||
|  | ||||
|     for (ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         AVComplexFloat *fft_out = s->fft_out[ch]; | ||||
|         AVComplexFloat *fft_temp = s->fft_temp[ch]; | ||||
|         float *buf = (float *)s->buffer->extended_data[ch]; | ||||
| @@ -309,7 +309,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     out->pts = in->pts; | ||||
|     out->nb_samples = in->nb_samples; | ||||
|  | ||||
|     for (ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         float *dst = (float *)out->extended_data[ch]; | ||||
|         float *buf = (float *)s->buffer->extended_data[ch]; | ||||
|  | ||||
|   | ||||
| @@ -200,8 +200,8 @@ static int fir_channel(AVFilterContext *ctx, AVFrame *out, int ch) | ||||
| static int fir_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) | ||||
| { | ||||
|     AVFrame *out = arg; | ||||
|     const int start = (out->channels * jobnr) / nb_jobs; | ||||
|     const int end = (out->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|  | ||||
|     for (int ch = start; ch < end; ch++) { | ||||
|         fir_channel(ctx, out, ch); | ||||
| @@ -224,7 +224,7 @@ static int fir_frame(AudioFIRContext *s, AVFrame *in, AVFilterLink *outlink) | ||||
|  | ||||
|     s->in = in; | ||||
|     ff_filter_execute(ctx, fir_channels, out, NULL, | ||||
|                       FFMIN(outlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(outlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     av_frame_free(&in); | ||||
|     s->in = NULL; | ||||
| @@ -298,7 +298,7 @@ static void draw_response(AVFilterContext *ctx, AVFrame *out) | ||||
|     if (!mag || !phase || !delay) | ||||
|         goto end; | ||||
|  | ||||
|     channel = av_clip(s->ir_channel, 0, s->ir[s->selir]->channels - 1); | ||||
|     channel = av_clip(s->ir_channel, 0, s->ir[s->selir]->ch_layout.nb_channels - 1); | ||||
|     for (i = 0; i < s->w; i++) { | ||||
|         const float *src = (const float *)s->ir[s->selir]->extended_data[channel]; | ||||
|         double w = i * M_PI / (s->w - 1); | ||||
| @@ -375,8 +375,8 @@ static int init_segment(AVFilterContext *ctx, AudioFIRSegment *seg, | ||||
| { | ||||
|     AudioFIRContext *s = ctx->priv; | ||||
|  | ||||
|     seg->tx  = av_calloc(ctx->inputs[0]->channels, sizeof(*seg->tx)); | ||||
|     seg->itx = av_calloc(ctx->inputs[0]->channels, sizeof(*seg->itx)); | ||||
|     seg->tx  = av_calloc(ctx->inputs[0]->ch_layout.nb_channels, sizeof(*seg->tx)); | ||||
|     seg->itx = av_calloc(ctx->inputs[0]->ch_layout.nb_channels, sizeof(*seg->itx)); | ||||
|     if (!seg->tx || !seg->itx) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
| @@ -388,12 +388,12 @@ static int init_segment(AVFilterContext *ctx, AudioFIRSegment *seg, | ||||
|     seg->input_size    = offset + s->min_part_size; | ||||
|     seg->input_offset  = offset; | ||||
|  | ||||
|     seg->part_index    = av_calloc(ctx->inputs[0]->channels, sizeof(*seg->part_index)); | ||||
|     seg->output_offset = av_calloc(ctx->inputs[0]->channels, sizeof(*seg->output_offset)); | ||||
|     seg->part_index    = av_calloc(ctx->inputs[0]->ch_layout.nb_channels, sizeof(*seg->part_index)); | ||||
|     seg->output_offset = av_calloc(ctx->inputs[0]->ch_layout.nb_channels, sizeof(*seg->output_offset)); | ||||
|     if (!seg->part_index || !seg->output_offset) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (int ch = 0; ch < ctx->inputs[0]->channels && part_size >= 8; ch++) { | ||||
|     for (int ch = 0; ch < ctx->inputs[0]->ch_layout.nb_channels && part_size >= 8; ch++) { | ||||
|         float scale = 1.f, iscale = 1.f / part_size; | ||||
|         av_tx_init(&seg->tx[ch],  &seg->tx_fn,  AV_TX_FLOAT_RDFT, 0, 2 * part_size, &scale,  0); | ||||
|         av_tx_init(&seg->itx[ch], &seg->itx_fn, AV_TX_FLOAT_RDFT, 1, 2 * part_size, &iscale, 0); | ||||
| @@ -505,25 +505,25 @@ static int convert_coeffs(AVFilterContext *ctx) | ||||
|         /* nothing to do */ | ||||
|         break; | ||||
|     case 0: | ||||
|         for (ch = 0; ch < ctx->inputs[1 + s->selir]->channels; ch++) { | ||||
|         for (ch = 0; ch < ctx->inputs[1 + s->selir]->ch_layout.nb_channels; ch++) { | ||||
|             float *time = (float *)s->ir[s->selir]->extended_data[!s->one2many * ch]; | ||||
|  | ||||
|             for (i = 0; i < cur_nb_taps; i++) | ||||
|                 power += FFABS(time[i]); | ||||
|         } | ||||
|         s->gain = ctx->inputs[1 + s->selir]->channels / power; | ||||
|         s->gain = ctx->inputs[1 + s->selir]->ch_layout.nb_channels / power; | ||||
|         break; | ||||
|     case 1: | ||||
|         for (ch = 0; ch < ctx->inputs[1 + s->selir]->channels; ch++) { | ||||
|         for (ch = 0; ch < ctx->inputs[1 + s->selir]->ch_layout.nb_channels; ch++) { | ||||
|             float *time = (float *)s->ir[s->selir]->extended_data[!s->one2many * ch]; | ||||
|  | ||||
|             for (i = 0; i < cur_nb_taps; i++) | ||||
|                 power += time[i]; | ||||
|         } | ||||
|         s->gain = ctx->inputs[1 + s->selir]->channels / power; | ||||
|         s->gain = ctx->inputs[1 + s->selir]->ch_layout.nb_channels / power; | ||||
|         break; | ||||
|     case 2: | ||||
|         for (ch = 0; ch < ctx->inputs[1 + s->selir]->channels; ch++) { | ||||
|         for (ch = 0; ch < ctx->inputs[1 + s->selir]->ch_layout.nb_channels; ch++) { | ||||
|             float *time = (float *)s->ir[s->selir]->extended_data[!s->one2many * ch]; | ||||
|  | ||||
|             for (i = 0; i < cur_nb_taps; i++) | ||||
| @@ -537,7 +537,7 @@ static int convert_coeffs(AVFilterContext *ctx) | ||||
|  | ||||
|     s->gain = FFMIN(s->gain * s->ir_gain, 1.f); | ||||
|     av_log(ctx, AV_LOG_DEBUG, "power %f, gain %f\n", power, s->gain); | ||||
|     for (ch = 0; ch < ctx->inputs[1 + s->selir]->channels; ch++) { | ||||
|     for (ch = 0; ch < ctx->inputs[1 + s->selir]->ch_layout.nb_channels; ch++) { | ||||
|         float *time = (float *)s->ir[s->selir]->extended_data[!s->one2many * ch]; | ||||
|  | ||||
|         s->fdsp->vector_fmul_scalar(time, time, s->gain, FFALIGN(cur_nb_taps, 4)); | ||||
| @@ -546,7 +546,7 @@ static int convert_coeffs(AVFilterContext *ctx) | ||||
|     av_log(ctx, AV_LOG_DEBUG, "nb_taps: %d\n", cur_nb_taps); | ||||
|     av_log(ctx, AV_LOG_DEBUG, "nb_segments: %d\n", s->nb_segments); | ||||
|  | ||||
|     for (ch = 0; ch < ctx->inputs[1 + s->selir]->channels; ch++) { | ||||
|     for (ch = 0; ch < ctx->inputs[1 + s->selir]->ch_layout.nb_channels; ch++) { | ||||
|         float *time = (float *)s->ir[s->selir]->extended_data[!s->one2many * ch]; | ||||
|         int toffset = 0; | ||||
|  | ||||
| @@ -740,7 +740,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|         if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0) | ||||
|             return ret; | ||||
|  | ||||
|         ret = ff_add_channel_layout(&mono, AV_CH_LAYOUT_MONO); | ||||
|         ret = ff_add_channel_layout(&mono, &(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO); | ||||
|         if (ret) | ||||
|             return ret; | ||||
|         for (int i = 1; i < ctx->nb_inputs; i++) { | ||||
| @@ -759,15 +759,22 @@ static int config_output(AVFilterLink *outlink) | ||||
| { | ||||
|     AVFilterContext *ctx = outlink->src; | ||||
|     AudioFIRContext *s = ctx->priv; | ||||
|     int ret; | ||||
|  | ||||
|     s->one2many = ctx->inputs[1 + s->selir]->channels == 1; | ||||
|     s->one2many = ctx->inputs[1 + s->selir]->ch_layout.nb_channels == 1; | ||||
|     outlink->sample_rate = ctx->inputs[0]->sample_rate; | ||||
|     outlink->time_base   = ctx->inputs[0]->time_base; | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     outlink->channel_layout = ctx->inputs[0]->channel_layout; | ||||
|     outlink->channels = ctx->inputs[0]->channels; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|     if ((ret = av_channel_layout_copy(&outlink->ch_layout, &ctx->inputs[0]->ch_layout)) < 0) | ||||
|         return ret; | ||||
|     outlink->ch_layout.nb_channels = ctx->inputs[0]->ch_layout.nb_channels; | ||||
|  | ||||
|     s->nb_channels = outlink->channels; | ||||
|     s->nb_coef_channels = ctx->inputs[1 + s->selir]->channels; | ||||
|     s->nb_channels = outlink->ch_layout.nb_channels; | ||||
|     s->nb_coef_channels = ctx->inputs[1 + s->selir]->ch_layout.nb_channels; | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -89,17 +89,59 @@ static int get_sample_rate(const char *samplerate) | ||||
|     return FFMAX(ret, 0); | ||||
| } | ||||
|  | ||||
| static int parse_channel_layouts(AVFilterContext *ctx) | ||||
| { | ||||
|     AFormatContext *s = ctx->priv; | ||||
|     char *next, *cur = s->channel_layouts_str; | ||||
|     AVChannelLayout fmt = { 0 }; | ||||
|     int ret; | ||||
|  | ||||
|     while (cur) { | ||||
|         next = strchr(cur, '|'); | ||||
|         if (next) | ||||
|             *next++ = 0; | ||||
|  | ||||
|         ret = av_channel_layout_from_string(&fmt, cur); | ||||
|         if (ret < 0) { | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
|             uint64_t mask; | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|             mask = av_get_channel_layout(cur); | ||||
|             if (!mask) { | ||||
| #endif | ||||
|             av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout: %s.\n", cur); | ||||
|             return AVERROR(EINVAL); | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
|             } | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
|             av_log(ctx, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n", | ||||
|                    cur); | ||||
|             av_channel_layout_from_mask(&fmt, mask); | ||||
| #endif | ||||
|         } | ||||
|         ret = ff_add_channel_layout(&s->channel_layouts, &fmt); | ||||
|         av_channel_layout_uninit(&fmt); | ||||
|         if (ret < 0) | ||||
|             return ret; | ||||
|  | ||||
|         cur = next; | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static av_cold int init(AVFilterContext *ctx) | ||||
| { | ||||
|     AFormatContext *s = ctx->priv; | ||||
|     int ret; | ||||
|  | ||||
|     PARSE_FORMATS(s->formats_str, enum AVSampleFormat, s->formats, | ||||
|                   ff_add_format, av_get_sample_fmt, AV_SAMPLE_FMT_NONE, "sample format"); | ||||
|     PARSE_FORMATS(s->sample_rates_str, int, s->sample_rates, ff_add_format, | ||||
|                   get_sample_rate, 0, "sample rate"); | ||||
|     PARSE_FORMATS(s->channel_layouts_str, uint64_t, s->channel_layouts, | ||||
|                   ff_add_channel_layout, av_get_channel_layout, 0, | ||||
|                   "channel layout"); | ||||
|     ret = parse_channel_layouts(ctx); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -290,8 +290,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo | ||||
|     ThreadData *td = arg; | ||||
|     AVFrame *out = td->out; | ||||
|     AVFrame *in = td->in; | ||||
|     const int start = (in->channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|  | ||||
|     for (int ch = start; ch < end; ch++) | ||||
|         s->filter_channel(ctx, ch, in, out); | ||||
| @@ -324,7 +324,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|  | ||||
|     td.in = in; td.out = out; | ||||
|     ff_filter_execute(ctx, filter_channels, &td, NULL, | ||||
|                       FFMIN(inlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(inlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     s->in_samples += in->nb_samples; | ||||
|  | ||||
|   | ||||
| @@ -1037,14 +1037,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         s->padd_samples -= s->nb_samples - (in ? in->nb_samples: 0); | ||||
|         if (in) | ||||
|             av_samples_copy(new_in->extended_data, in->extended_data, 0, 0, | ||||
|                             in->nb_samples, in->channels, in->format); | ||||
|                             in->nb_samples, in->ch_layout.nb_channels, in->format); | ||||
|         av_frame_free(&in); | ||||
|         in = new_in; | ||||
|     } | ||||
|  | ||||
|     td.in  = in; | ||||
|     td.out = out; | ||||
|     ff_filter_execute(ctx, s->filter_channel, &td, NULL, inlink->channels); | ||||
|     ff_filter_execute(ctx, s->filter_channel, &td, NULL, inlink->ch_layout.nb_channels); | ||||
|     if (s->need_profile) | ||||
|         s->got_profile = 1; | ||||
|  | ||||
| @@ -1059,7 +1059,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         FF_FILTER_FORWARD_WANTED(outlink, inlink); | ||||
|         return 0; | ||||
|     } else if (s->drop_samples > 0) { | ||||
|         for (int ch = 0; ch < out->channels; ch++) { | ||||
|         for (int ch = 0; ch < out->ch_layout.nb_channels; ch++) { | ||||
|             memmove(out->extended_data[ch], | ||||
|                     out->extended_data[ch] + s->drop_samples * sizeof(double), | ||||
|                     (in->nb_samples - s->drop_samples) * sizeof(double)); | ||||
| @@ -1164,7 +1164,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|         !s->new_stddev || !s->new_absmean) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     s->channels = outlink->channels; | ||||
|     s->channels = outlink->ch_layout.nb_channels; | ||||
|     s->overlap_length = max_left_ext(s->wavelet_length, s->levels); | ||||
|     s->prev_length = s->overlap_length; | ||||
|     s->drop_samples = s->overlap_length; | ||||
|   | ||||
| @@ -150,19 +150,19 @@ static void gate(AudioGateContext *s, | ||||
|     const double release_coeff = s->release_coeff; | ||||
|     int n, c; | ||||
|  | ||||
|     for (n = 0; n < nb_samples; n++, src += inlink->channels, dst += inlink->channels, scsrc += sclink->channels) { | ||||
|     for (n = 0; n < nb_samples; n++, src += inlink->ch_layout.nb_channels, dst += inlink->ch_layout.nb_channels, scsrc += sclink->ch_layout.nb_channels) { | ||||
|         double abs_sample = fabs(scsrc[0] * level_sc), gain = 1.0; | ||||
|         double factor; | ||||
|         int detected; | ||||
|  | ||||
|         if (s->link == 1) { | ||||
|             for (c = 1; c < sclink->channels; c++) | ||||
|             for (c = 1; c < sclink->ch_layout.nb_channels; c++) | ||||
|                 abs_sample = FFMAX(fabs(scsrc[c] * level_sc), abs_sample); | ||||
|         } else { | ||||
|             for (c = 1; c < sclink->channels; c++) | ||||
|             for (c = 1; c < sclink->ch_layout.nb_channels; c++) | ||||
|                 abs_sample += fabs(scsrc[c] * level_sc); | ||||
|  | ||||
|             abs_sample /= sclink->channels; | ||||
|             abs_sample /= sclink->ch_layout.nb_channels; | ||||
|         } | ||||
|  | ||||
|         if (s->detection) | ||||
| @@ -181,7 +181,7 @@ static void gate(AudioGateContext *s, | ||||
|                                s->range, s->mode); | ||||
|  | ||||
|         factor = ctx->is_disabled ? 1.f : level_in * gain * makeup; | ||||
|         for (c = 0; c < inlink->channels; c++) | ||||
|         for (c = 0; c < inlink->ch_layout.nb_channels; c++) | ||||
|             dst[c] = src[c] * factor; | ||||
|     } | ||||
| } | ||||
| @@ -344,8 +344,8 @@ static int scconfig_output(AVFilterLink *outlink) | ||||
|  | ||||
|     outlink->time_base   = ctx->inputs[0]->time_base; | ||||
|  | ||||
|     s->fifo[0] = av_audio_fifo_alloc(ctx->inputs[0]->format, ctx->inputs[0]->channels, 1024); | ||||
|     s->fifo[1] = av_audio_fifo_alloc(ctx->inputs[1]->format, ctx->inputs[1]->channels, 1024); | ||||
|     s->fifo[0] = av_audio_fifo_alloc(ctx->inputs[0]->format, ctx->inputs[0]->ch_layout.nb_channels, 1024); | ||||
|     s->fifo[1] = av_audio_fifo_alloc(ctx->inputs[1]->format, ctx->inputs[1]->ch_layout.nb_channels, 1024); | ||||
|     if (!s->fifo[0] || !s->fifo[1]) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|   | ||||
| @@ -1263,35 +1263,35 @@ static int config_output(AVFilterLink *outlink) | ||||
|     AVFilterLink *inlink = ctx->inputs[0]; | ||||
|     int ch, ret, i; | ||||
|  | ||||
|     s->channels = inlink->channels; | ||||
|     s->channels = inlink->ch_layout.nb_channels; | ||||
|     s->iir = av_calloc(s->channels, sizeof(*s->iir)); | ||||
|     if (!s->iir) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     ret = read_gains(ctx, s->g_str, inlink->channels); | ||||
|     ret = read_gains(ctx, s->g_str, inlink->ch_layout.nb_channels); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|  | ||||
|     ret = read_channels(ctx, inlink->channels, s->a_str, 0); | ||||
|     ret = read_channels(ctx, inlink->ch_layout.nb_channels, s->a_str, 0); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|  | ||||
|     ret = read_channels(ctx, inlink->channels, s->b_str, 1); | ||||
|     ret = read_channels(ctx, inlink->ch_layout.nb_channels, s->b_str, 1); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|  | ||||
|     if (s->format == -1) { | ||||
|         convert_sf2tf(ctx, inlink->channels); | ||||
|         convert_sf2tf(ctx, inlink->ch_layout.nb_channels); | ||||
|         s->format = 0; | ||||
|     } else if (s->format == 2) { | ||||
|         convert_pr2zp(ctx, inlink->channels); | ||||
|         convert_pr2zp(ctx, inlink->ch_layout.nb_channels); | ||||
|     } else if (s->format == 3) { | ||||
|         convert_pd2zp(ctx, inlink->channels); | ||||
|         convert_pd2zp(ctx, inlink->ch_layout.nb_channels); | ||||
|     } else if (s->format == 4) { | ||||
|         convert_sp2zp(ctx, inlink->channels); | ||||
|         convert_sp2zp(ctx, inlink->ch_layout.nb_channels); | ||||
|     } | ||||
|     if (s->format > 0) { | ||||
|         check_stability(ctx, inlink->channels); | ||||
|         check_stability(ctx, inlink->ch_layout.nb_channels); | ||||
|     } | ||||
|  | ||||
|     av_frame_free(&s->video); | ||||
| @@ -1309,7 +1309,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|     if (s->format > 0 && s->process == 0) { | ||||
|         av_log(ctx, AV_LOG_WARNING, "Direct processsing is not recommended for zp coefficients format.\n"); | ||||
|  | ||||
|         ret = convert_zp2tf(ctx, inlink->channels); | ||||
|         ret = convert_zp2tf(ctx, inlink->ch_layout.nb_channels); | ||||
|         if (ret < 0) | ||||
|             return ret; | ||||
|     } else if (s->format == -2 && s->process > 0) { | ||||
| @@ -1322,21 +1322,21 @@ static int config_output(AVFilterLink *outlink) | ||||
|         av_log(ctx, AV_LOG_ERROR, "Parallel processing is not implemented for transfer function.\n"); | ||||
|         return AVERROR_PATCHWELCOME; | ||||
|     } else if (s->format > 0 && s->process == 1) { | ||||
|         ret = decompose_zp2biquads(ctx, inlink->channels); | ||||
|         ret = decompose_zp2biquads(ctx, inlink->ch_layout.nb_channels); | ||||
|         if (ret < 0) | ||||
|             return ret; | ||||
|     } else if (s->format > 0 && s->process == 2) { | ||||
|         if (s->precision > 1) | ||||
|             av_log(ctx, AV_LOG_WARNING, "Parallel processing is not recommended for fixed-point precisions.\n"); | ||||
|         ret = decompose_zp2biquads(ctx, inlink->channels); | ||||
|         ret = decompose_zp2biquads(ctx, inlink->ch_layout.nb_channels); | ||||
|         if (ret < 0) | ||||
|             return ret; | ||||
|         ret = convert_serial2parallel(ctx, inlink->channels); | ||||
|         ret = convert_serial2parallel(ctx, inlink->ch_layout.nb_channels); | ||||
|         if (ret < 0) | ||||
|             return ret; | ||||
|     } | ||||
|  | ||||
|     for (ch = 0; s->format == -2 && ch < inlink->channels; ch++) { | ||||
|     for (ch = 0; s->format == -2 && ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         IIRChannel *iir = &s->iir[ch]; | ||||
|  | ||||
|         if (iir->nb_ab[0] != iir->nb_ab[1] + 1) { | ||||
| @@ -1345,7 +1345,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     for (ch = 0; s->format == 0 && ch < inlink->channels; ch++) { | ||||
|     for (ch = 0; s->format == 0 && ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         IIRChannel *iir = &s->iir[ch]; | ||||
|  | ||||
|         for (i = 1; i < iir->nb_ab[0]; i++) { | ||||
| @@ -1401,9 +1401,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|  | ||||
|     td.in  = in; | ||||
|     td.out = out; | ||||
|     ff_filter_execute(ctx, s->iir_channel, &td, NULL, outlink->channels); | ||||
|     ff_filter_execute(ctx, s->iir_channel, &td, NULL, outlink->ch_layout.nb_channels); | ||||
|  | ||||
|     for (ch = 0; ch < outlink->channels; ch++) { | ||||
|     for (ch = 0; ch < outlink->ch_layout.nb_channels; ch++) { | ||||
|         if (s->iir[ch].clippings > 0) | ||||
|             av_log(ctx, AV_LOG_WARNING, "Channel %d clipping %d times. Please reduce gain.\n", | ||||
|                    ch, s->iir[ch].clippings); | ||||
|   | ||||
| @@ -116,7 +116,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     AudioLimiterContext *s = ctx->priv; | ||||
|     AVFilterLink *outlink = ctx->outputs[0]; | ||||
|     const double *src = (const double *)in->data[0]; | ||||
|     const int channels = inlink->channels; | ||||
|     const int channels = inlink->ch_layout.nb_channels; | ||||
|     const int buffer_size = s->buffer_size; | ||||
|     double *dst, *buffer = s->buffer; | ||||
|     const double release = s->release; | ||||
| @@ -281,8 +281,8 @@ static int config_input(AVFilterLink *inlink) | ||||
|     AudioLimiterContext *s = ctx->priv; | ||||
|     int obuffer_size; | ||||
|  | ||||
|     obuffer_size = inlink->sample_rate * inlink->channels * 100 / 1000. + inlink->channels; | ||||
|     if (obuffer_size < inlink->channels) | ||||
|     obuffer_size = inlink->sample_rate * inlink->ch_layout.nb_channels * 100 / 1000. + inlink->ch_layout.nb_channels; | ||||
|     if (obuffer_size < inlink->ch_layout.nb_channels) | ||||
|         return AVERROR(EINVAL); | ||||
|  | ||||
|     s->buffer = av_calloc(obuffer_size, sizeof(*s->buffer)); | ||||
| @@ -292,8 +292,8 @@ static int config_input(AVFilterLink *inlink) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     memset(s->nextpos, -1, obuffer_size * sizeof(*s->nextpos)); | ||||
|     s->buffer_size = inlink->sample_rate * s->attack * inlink->channels; | ||||
|     s->buffer_size -= s->buffer_size % inlink->channels; | ||||
|     s->buffer_size = inlink->sample_rate * s->attack * inlink->ch_layout.nb_channels; | ||||
|     s->buffer_size -= s->buffer_size % inlink->ch_layout.nb_channels; | ||||
|  | ||||
|     if (s->buffer_size <= 0) { | ||||
|         av_log(ctx, AV_LOG_ERROR, "Attack is too small.\n"); | ||||
|   | ||||
| @@ -73,7 +73,8 @@ static int query_formats(AVFilterContext *ctx) | ||||
|         AV_SAMPLE_FMT_NONE | ||||
|     }; | ||||
|     AMergeContext *s = ctx->priv; | ||||
|     int64_t inlayout[SWR_CH_MAX], outlayout = 0; | ||||
|     AVChannelLayout *inlayout[SWR_CH_MAX] = { NULL }, outlayout = { 0 }; | ||||
|     uint64_t outmask = 0; | ||||
|     AVFilterChannelLayouts *layouts; | ||||
|     int i, ret, overlap = 0, nb_ch = 0; | ||||
|  | ||||
| @@ -84,20 +85,21 @@ static int query_formats(AVFilterContext *ctx) | ||||
|                    "No channel layout for input %d\n", i + 1); | ||||
|             return AVERROR(EAGAIN); | ||||
|         } | ||||
|         inlayout[i] = ctx->inputs[i]->incfg.channel_layouts->channel_layouts[0]; | ||||
|         inlayout[i] = &ctx->inputs[i]->incfg.channel_layouts->channel_layouts[0]; | ||||
|         if (ctx->inputs[i]->incfg.channel_layouts->nb_channel_layouts > 1) { | ||||
|             char buf[256]; | ||||
|             av_get_channel_layout_string(buf, sizeof(buf), 0, inlayout[i]); | ||||
|             av_channel_layout_describe(inlayout[i], buf, sizeof(buf)); | ||||
|             av_log(ctx, AV_LOG_INFO, "Using \"%s\" for input %d\n", buf, i + 1); | ||||
|         } | ||||
|         s->in[i].nb_ch = FF_LAYOUT2COUNT(inlayout[i]); | ||||
|         if (s->in[i].nb_ch) { | ||||
|             overlap++; | ||||
|         } else { | ||||
|             s->in[i].nb_ch = av_get_channel_layout_nb_channels(inlayout[i]); | ||||
|             if (outlayout & inlayout[i]) | ||||
|             s->in[i].nb_ch = inlayout[i]->nb_channels; | ||||
|             if (av_channel_layout_subset(inlayout[i], outmask)) | ||||
|                 overlap++; | ||||
|             outlayout |= inlayout[i]; | ||||
|             outmask |= inlayout[i]->order == AV_CHANNEL_ORDER_NATIVE ? | ||||
|                        inlayout[i]->u.mask : 0; | ||||
|         } | ||||
|         nb_ch += s->in[i].nb_ch; | ||||
|     } | ||||
| @@ -111,19 +113,20 @@ static int query_formats(AVFilterContext *ctx) | ||||
|                "output layout will be determined by the number of distinct input channels\n"); | ||||
|         for (i = 0; i < nb_ch; i++) | ||||
|             s->route[i] = i; | ||||
|         outlayout = av_get_default_channel_layout(nb_ch); | ||||
|         if (!outlayout && nb_ch) | ||||
|             outlayout = 0xFFFFFFFFFFFFFFFFULL >> (64 - nb_ch); | ||||
|         av_channel_layout_default(&outlayout, nb_ch); | ||||
|         if (!KNOWN(&outlayout) && nb_ch) | ||||
|             av_channel_layout_from_mask(&outlayout, 0xFFFFFFFFFFFFFFFFULL >> (64 - nb_ch)); | ||||
|     } else { | ||||
|         int *route[SWR_CH_MAX]; | ||||
|         int c, out_ch_number = 0; | ||||
|  | ||||
|         av_channel_layout_from_mask(&outlayout, outmask); | ||||
|         route[0] = s->route; | ||||
|         for (i = 1; i < s->nb_inputs; i++) | ||||
|             route[i] = route[i - 1] + s->in[i - 1].nb_ch; | ||||
|         for (c = 0; c < 64; c++) | ||||
|             for (i = 0; i < s->nb_inputs; i++) | ||||
|                 if ((inlayout[i] >> c) & 1) | ||||
|                 if (av_channel_layout_index_from_channel(inlayout[i], c) >= 0) | ||||
|                     *(route[i]++) = out_ch_number++; | ||||
|     } | ||||
|     if ((ret = ff_set_common_formats_from_list(ctx, packed_sample_fmts)) < 0) | ||||
| @@ -136,7 +139,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|             return ret; | ||||
|     } | ||||
|     layouts = NULL; | ||||
|     if ((ret = ff_add_channel_layout(&layouts, outlayout)) < 0) | ||||
|     if ((ret = ff_add_channel_layout(&layouts, &outlayout)) < 0) | ||||
|         return ret; | ||||
|     if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0) | ||||
|         return ret; | ||||
| @@ -149,6 +152,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|     AVFilterContext *ctx = outlink->src; | ||||
|     AMergeContext *s = ctx->priv; | ||||
|     AVBPrint bp; | ||||
|     char buf[128]; | ||||
|     int i; | ||||
|  | ||||
|     s->bps = av_get_bytes_per_sample(ctx->outputs[0]->format); | ||||
| @@ -157,10 +161,12 @@ static int config_output(AVFilterLink *outlink) | ||||
|     av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); | ||||
|     for (i = 0; i < s->nb_inputs; i++) { | ||||
|         av_bprintf(&bp, "%sin%d:", i ? " + " : "", i); | ||||
|         av_bprint_channel_layout(&bp, -1, ctx->inputs[i]->channel_layout); | ||||
|         av_channel_layout_describe(&ctx->inputs[i]->ch_layout, buf, sizeof(buf)); | ||||
|         av_bprintf(&bp, "%s", buf); | ||||
|     } | ||||
|     av_bprintf(&bp, " -> out:"); | ||||
|     av_bprint_channel_layout(&bp, -1, ctx->outputs[0]->channel_layout); | ||||
|     av_channel_layout_describe(&ctx->outputs[0]->ch_layout, buf, sizeof(buf)); | ||||
|     av_bprintf(&bp, "%s", buf); | ||||
|     av_log(ctx, AV_LOG_VERBOSE, "%s\n", bp.str); | ||||
|  | ||||
|     return 0; | ||||
| @@ -237,8 +243,14 @@ static int try_push_frame(AVFilterContext *ctx, int nb_samples) | ||||
|     outbuf->pts = inbuf[0]->pts; | ||||
|  | ||||
|     outbuf->nb_samples     = nb_samples; | ||||
|     if ((ret = av_channel_layout_copy(&outbuf->ch_layout, &outlink->ch_layout)) < 0) | ||||
|         return ret; | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     outbuf->channel_layout = outlink->channel_layout; | ||||
|     outbuf->channels       = outlink->channels; | ||||
|     outbuf->channels       = outlink->ch_layout.nb_channels; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|  | ||||
|     while (nb_samples) { | ||||
|         /* Unroll the most common sample formats: speed +~350% for the loop, | ||||
|   | ||||
| @@ -261,7 +261,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|     if (!s->fifos) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     s->nb_channels = outlink->channels; | ||||
|     s->nb_channels = outlink->ch_layout.nb_channels; | ||||
|     for (i = 0; i < s->nb_inputs; i++) { | ||||
|         s->fifos[i] = av_audio_fifo_alloc(outlink->format, s->nb_channels, 1024); | ||||
|         if (!s->fifos[i]) | ||||
| @@ -282,7 +282,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|         s->scale_norm[i] = s->weight_sum / FFABS(s->weights[i]); | ||||
|     calculate_scales(s, 0); | ||||
|  | ||||
|     av_get_channel_layout_string(buf, sizeof(buf), -1, outlink->channel_layout); | ||||
|     av_channel_layout_describe(&outlink->ch_layout, buf, sizeof(buf)); | ||||
|  | ||||
|     av_log(ctx, AV_LOG_VERBOSE, | ||||
|            "inputs:%d fmt:%s srate:%d cl:%s\n", s->nb_inputs, | ||||
|   | ||||
| @@ -128,8 +128,8 @@ static int config_output(AVFilterLink *outlink) | ||||
|     AudioMultiplyContext *s = ctx->priv; | ||||
|     AVFilterLink *inlink = ctx->inputs[0]; | ||||
|  | ||||
|     s->channels = inlink->channels; | ||||
|     s->planes = av_sample_fmt_is_planar(inlink->format) ? inlink->channels : 1; | ||||
|     s->channels = inlink->ch_layout.nb_channels; | ||||
|     s->planes = av_sample_fmt_is_planar(inlink->format) ? inlink->ch_layout.nb_channels : 1; | ||||
|     s->samples_align = 16; | ||||
|  | ||||
|     return 0; | ||||
|   | ||||
| @@ -103,7 +103,7 @@ static void draw_curves(AVFilterContext *ctx, AVFilterLink *inlink, AVFrame *out | ||||
|  | ||||
|     memset(out->data[0], 0, s->h * out->linesize[0]); | ||||
|  | ||||
|     for (ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         uint8_t fg[4] = { 0xff, 0xff, 0xff, 0xff }; | ||||
|         int prev_v = -1; | ||||
|         double f; | ||||
| @@ -577,8 +577,8 @@ static int config_input(AVFilterLink *inlink) | ||||
|     if (!args) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     s->nb_allocated = 32 * inlink->channels; | ||||
|     s->filters = av_calloc(inlink->channels, 32 * sizeof(*s->filters)); | ||||
|     s->nb_allocated = 32 * inlink->ch_layout.nb_channels; | ||||
|     s->filters = av_calloc(inlink->ch_layout.nb_channels, 32 * sizeof(*s->filters)); | ||||
|     if (!s->filters) { | ||||
|         s->nb_allocated = 0; | ||||
|         av_free(args); | ||||
| @@ -610,7 +610,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|             s->filters[s->nb_filters].ignore = 1; | ||||
|  | ||||
|         if (s->filters[s->nb_filters].channel < 0 || | ||||
|             s->filters[s->nb_filters].channel >= inlink->channels) | ||||
|             s->filters[s->nb_filters].channel >= inlink->ch_layout.nb_channels) | ||||
|             s->filters[s->nb_filters].ignore = 1; | ||||
|  | ||||
|         s->filters[s->nb_filters].type = av_clip(s->filters[s->nb_filters].type, 0, NB_TYPES - 1); | ||||
| @@ -698,8 +698,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, | ||||
| { | ||||
|     AudioNEqualizerContext *s = ctx->priv; | ||||
|     AVFrame *buf = arg; | ||||
|     const int start = (buf->channels * jobnr) / nb_jobs; | ||||
|     const int end = (buf->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (buf->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (buf->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|  | ||||
|     for (int i = 0; i < s->nb_filters; i++) { | ||||
|         EqualizatorFilter *f = &s->filters[i]; | ||||
| @@ -731,7 +731,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) | ||||
|  | ||||
|     if (!ctx->is_disabled) | ||||
|         ff_filter_execute(ctx, filter_channels, buf, NULL, | ||||
|                           FFMIN(inlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                           FFMIN(inlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     if (s->draw_curves) { | ||||
|         AVFrame *clone; | ||||
|   | ||||
| @@ -141,7 +141,7 @@ static int config_filter(AVFilterContext *ctx) | ||||
|         if (new_cache) { | ||||
|             if (s->cache) | ||||
|                 av_samples_copy(new_cache->extended_data, s->cache->extended_data, 0, 0, | ||||
|                                 s->cache->nb_samples, new_cache->channels, new_cache->format); | ||||
|                                 s->cache->nb_samples, new_cache->ch_layout.nb_channels, new_cache->format); | ||||
|             av_frame_free(&s->cache); | ||||
|             s->cache = new_cache; | ||||
|         } else { | ||||
| @@ -156,7 +156,7 @@ static int config_filter(AVFilterContext *ctx) | ||||
|         if (new_window) { | ||||
|             if (s->window) | ||||
|                 av_samples_copy(new_window->extended_data, s->window->extended_data, 0, 0, | ||||
|                                 s->window->nb_samples, new_window->channels, new_window->format); | ||||
|                                 s->window->nb_samples, new_window->ch_layout.nb_channels, new_window->format); | ||||
|             av_frame_free(&s->window); | ||||
|             s->window = new_window; | ||||
|         } else { | ||||
| @@ -285,7 +285,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     } | ||||
|  | ||||
|     s->in = in; | ||||
|     ff_filter_execute(ctx, filter_channel, out, NULL, inlink->channels); | ||||
|     ff_filter_execute(ctx, filter_channel, out, NULL, inlink->ch_layout.nb_channels); | ||||
|  | ||||
|     if (out != in) | ||||
|         av_frame_free(&in); | ||||
|   | ||||
| @@ -156,8 +156,8 @@ static int process_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_j | ||||
| { | ||||
|     AudioNLMSContext *s = ctx->priv; | ||||
|     AVFrame *out = arg; | ||||
|     const int start = (out->channels * jobnr) / nb_jobs; | ||||
|     const int end = (out->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|  | ||||
|     for (int c = start; c < end; c++) { | ||||
|         const float *input = (const float *)s->frame[0]->extended_data[c]; | ||||
| @@ -208,7 +208,7 @@ static int activate(AVFilterContext *ctx) | ||||
|         } | ||||
|  | ||||
|         ff_filter_execute(ctx, process_channels, out, NULL, | ||||
|                           FFMIN(ctx->outputs[0]->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                           FFMIN(ctx->outputs[0]->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|         out->pts = s->frame[0]->pts; | ||||
|  | ||||
|   | ||||
| @@ -121,7 +121,7 @@ static int request_frame(AVFilterLink *outlink) | ||||
|  | ||||
|         av_samples_set_silence(outsamplesref->extended_data, 0, | ||||
|                                n_out, | ||||
|                                outsamplesref->channels, | ||||
|                                outsamplesref->ch_layout.nb_channels, | ||||
|                                outsamplesref->format); | ||||
|  | ||||
|         outsamplesref->pts = s->next_pts; | ||||
|   | ||||
| @@ -177,7 +177,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|         av_log(outlink->src, AV_LOG_ERROR, "delay is too small\n"); | ||||
|         return AVERROR(EINVAL); | ||||
|     } | ||||
|     s->delay_buffer = av_calloc(s->delay_buffer_length, sizeof(*s->delay_buffer) * inlink->channels); | ||||
|     s->delay_buffer = av_calloc(s->delay_buffer_length, sizeof(*s->delay_buffer) * inlink->ch_layout.nb_channels); | ||||
|     s->modulation_buffer_length = inlink->sample_rate / s->speed + 0.5; | ||||
|     s->modulation_buffer = av_malloc_array(s->modulation_buffer_length, sizeof(*s->modulation_buffer)); | ||||
|  | ||||
| @@ -223,7 +223,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inbuf) | ||||
|     } | ||||
|  | ||||
|     s->phaser(s, inbuf->extended_data, outbuf->extended_data, | ||||
|               outbuf->nb_samples, outbuf->channels); | ||||
|               outbuf->nb_samples, outbuf->ch_layout.nb_channels); | ||||
|  | ||||
|     if (inbuf != outbuf) | ||||
|         av_frame_free(&inbuf); | ||||
|   | ||||
| @@ -244,7 +244,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|  | ||||
|     generate_spread_table(s); | ||||
|  | ||||
|     s->channels = inlink->channels; | ||||
|     s->channels = inlink->ch_layout.nb_channels; | ||||
|  | ||||
|     s->tx_ctx = av_calloc(s->channels, sizeof(*s->tx_ctx)); | ||||
|     s->itx_ctx = av_calloc(s->channels, sizeof(*s->itx_ctx)); | ||||
| @@ -532,8 +532,8 @@ static int psy_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) | ||||
| { | ||||
|     AudioPsyClipContext *s = ctx->priv; | ||||
|     AVFrame *out = arg; | ||||
|     const int start = (out->channels * jobnr) / nb_jobs; | ||||
|     const int end = (out->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|  | ||||
|     for (int ch = start; ch < end; ch++) | ||||
|         psy_channel(ctx, s->in, out, ch); | ||||
| @@ -557,7 +557,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|  | ||||
|     s->in = in; | ||||
|     ff_filter_execute(ctx, psy_channels, out, NULL, | ||||
|                       FFMIN(outlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(outlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     out->pts = in->pts; | ||||
|     out->nb_samples = in->nb_samples; | ||||
|   | ||||
| @@ -192,7 +192,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|     if ((ret = ff_add_format                 (&formats, AV_SAMPLE_FMT_DBL  )) < 0 || | ||||
|         (ret = ff_set_common_formats         (ctx     , formats            )) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , AV_CH_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_set_common_channel_layouts (ctx     , layout             )) < 0) | ||||
|         return ret; | ||||
|  | ||||
|   | ||||
| @@ -65,7 +65,8 @@ static int query_formats(AVFilterContext *ctx) | ||||
| { | ||||
|     AResampleContext *aresample = ctx->priv; | ||||
|     enum AVSampleFormat out_format; | ||||
|     int64_t out_rate, out_layout; | ||||
|     AVChannelLayout out_layout = { 0 }; | ||||
|     int64_t out_rate; | ||||
|  | ||||
|     AVFilterLink *inlink  = ctx->inputs[0]; | ||||
|     AVFilterLink *outlink = ctx->outputs[0]; | ||||
| @@ -79,7 +80,6 @@ static int query_formats(AVFilterContext *ctx) | ||||
|         av_opt_set_int(aresample->swr, "osr", aresample->sample_rate_arg, 0); | ||||
|     av_opt_get_sample_fmt(aresample->swr, "osf", 0, &out_format); | ||||
|     av_opt_get_int(aresample->swr, "osr", 0, &out_rate); | ||||
|     av_opt_get_int(aresample->swr, "ocl", 0, &out_layout); | ||||
|  | ||||
|     in_formats      = ff_all_formats(AVMEDIA_TYPE_AUDIO); | ||||
|     if ((ret = ff_formats_ref(in_formats, &inlink->outcfg.formats)) < 0) | ||||
| @@ -111,11 +111,13 @@ static int query_formats(AVFilterContext *ctx) | ||||
|     if ((ret = ff_formats_ref(out_formats, &outlink->incfg.formats)) < 0) | ||||
|         return ret; | ||||
|  | ||||
|     if(out_layout) { | ||||
|         int64_t layout_list[] = { out_layout, -1 }; | ||||
|         out_layouts = ff_make_format64_list(layout_list); | ||||
|     av_opt_get_chlayout(aresample->swr, "ochl", 0, &out_layout); | ||||
|     if (av_channel_layout_check(&out_layout)) { | ||||
|         const AVChannelLayout layout_list[] = { out_layout, { 0 } }; | ||||
|         out_layouts = ff_make_channel_layout_list(layout_list); | ||||
|     } else | ||||
|         out_layouts = ff_all_channel_counts(); | ||||
|     av_channel_layout_uninit(&out_layout); | ||||
|  | ||||
|     return ff_channel_layouts_ref(out_layouts, &outlink->incfg.channel_layouts); | ||||
| } | ||||
| @@ -127,42 +129,41 @@ static int config_output(AVFilterLink *outlink) | ||||
|     AVFilterContext *ctx = outlink->src; | ||||
|     AVFilterLink *inlink = ctx->inputs[0]; | ||||
|     AResampleContext *aresample = ctx->priv; | ||||
|     int64_t out_rate, out_layout; | ||||
|     AVChannelLayout out_layout = { 0 }; | ||||
|     int64_t out_rate; | ||||
|     enum AVSampleFormat out_format; | ||||
|     char inchl_buf[128], outchl_buf[128]; | ||||
|  | ||||
|     aresample->swr = swr_alloc_set_opts(aresample->swr, | ||||
|                                         outlink->channel_layout, outlink->format, outlink->sample_rate, | ||||
|                                         inlink->channel_layout, inlink->format, inlink->sample_rate, | ||||
|                                         0, ctx); | ||||
|     if (!aresample->swr) | ||||
|         return AVERROR(ENOMEM); | ||||
|     if (!inlink->channel_layout) | ||||
|         av_opt_set_int(aresample->swr, "ich", inlink->channels, 0); | ||||
|     if (!outlink->channel_layout) | ||||
|         av_opt_set_int(aresample->swr, "och", outlink->channels, 0); | ||||
|     ret = swr_alloc_set_opts2(&aresample->swr, | ||||
|                               &outlink->ch_layout, outlink->format, outlink->sample_rate, | ||||
|                               &inlink->ch_layout, inlink->format, inlink->sample_rate, | ||||
|                                          0, ctx); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|  | ||||
|     ret = swr_init(aresample->swr); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|  | ||||
|     av_opt_get_int(aresample->swr, "osr", 0, &out_rate); | ||||
|     av_opt_get_int(aresample->swr, "ocl", 0, &out_layout); | ||||
|     av_opt_get_chlayout(aresample->swr, "ochl", 0, &out_layout); | ||||
|     av_opt_get_sample_fmt(aresample->swr, "osf", 0, &out_format); | ||||
|     outlink->time_base = (AVRational) {1, out_rate}; | ||||
|  | ||||
|     av_assert0(outlink->sample_rate == out_rate); | ||||
|     av_assert0(outlink->channel_layout == out_layout || !outlink->channel_layout); | ||||
|     av_assert0(!av_channel_layout_compare(&outlink->ch_layout, &out_layout)); | ||||
|     av_assert0(outlink->format == out_format); | ||||
|  | ||||
|     av_channel_layout_uninit(&out_layout); | ||||
|  | ||||
|     aresample->ratio = (double)outlink->sample_rate / inlink->sample_rate; | ||||
|  | ||||
|     av_get_channel_layout_string(inchl_buf,  sizeof(inchl_buf),  inlink ->channels, inlink ->channel_layout); | ||||
|     av_get_channel_layout_string(outchl_buf, sizeof(outchl_buf), outlink->channels, outlink->channel_layout); | ||||
|     av_channel_layout_describe(&inlink ->ch_layout, inchl_buf,  sizeof(inchl_buf)); | ||||
|     av_channel_layout_describe(&outlink->ch_layout, outchl_buf, sizeof(outchl_buf)); | ||||
|  | ||||
|     av_log(ctx, AV_LOG_VERBOSE, "ch:%d chl:%s fmt:%s r:%dHz -> ch:%d chl:%s fmt:%s r:%dHz\n", | ||||
|            inlink ->channels, inchl_buf,  av_get_sample_fmt_name(inlink->format),  inlink->sample_rate, | ||||
|            outlink->channels, outchl_buf, av_get_sample_fmt_name(outlink->format), outlink->sample_rate); | ||||
|            inlink ->ch_layout.nb_channels, inchl_buf,  av_get_sample_fmt_name(inlink->format),  inlink->sample_rate, | ||||
|            outlink->ch_layout.nb_channels, outchl_buf, av_get_sample_fmt_name(outlink->format), outlink->sample_rate); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| @@ -189,8 +190,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref) | ||||
|  | ||||
|     av_frame_copy_props(outsamplesref, insamplesref); | ||||
|     outsamplesref->format                = outlink->format; | ||||
|     outsamplesref->channels              = outlink->channels; | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     outsamplesref->channels              = outlink->ch_layout.nb_channels; | ||||
|     outsamplesref->channel_layout        = outlink->channel_layout; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|     ret = av_channel_layout_copy(&outsamplesref->ch_layout, &outlink->ch_layout); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|     outsamplesref->sample_rate           = outlink->sample_rate; | ||||
|  | ||||
|     if(insamplesref->pts != AV_NOPTS_VALUE) { | ||||
|   | ||||
| @@ -353,7 +353,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|     AudioRNNContext *s = ctx->priv; | ||||
|     int ret = 0; | ||||
|  | ||||
|     s->channels = inlink->channels; | ||||
|     s->channels = inlink->ch_layout.nb_channels; | ||||
|  | ||||
|     if (!s->st) | ||||
|         s->st = av_calloc(s->channels, sizeof(DenoiseState)); | ||||
| @@ -1413,8 +1413,8 @@ static int rnnoise_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_j | ||||
|     ThreadData *td = arg; | ||||
|     AVFrame *in = td->in; | ||||
|     AVFrame *out = td->out; | ||||
|     const int start = (out->channels * jobnr) / nb_jobs; | ||||
|     const int end = (out->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|  | ||||
|     for (int ch = start; ch < end; ch++) { | ||||
|         rnnoise_channel(s, &s->st[ch], | ||||
| @@ -1442,7 +1442,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|  | ||||
|     td.in = in; td.out = out; | ||||
|     ff_filter_execute(ctx, rnnoise_channels, &td, NULL, | ||||
|                       FFMIN(outlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(outlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     av_frame_free(&in); | ||||
|     return ff_filter_frame(outlink, out); | ||||
|   | ||||
| @@ -41,7 +41,7 @@ static void sdr(AVFilterContext *ctx, const AVFrame *u, const AVFrame *v) | ||||
| { | ||||
|     AudioSDRContext *s = ctx->priv; | ||||
|  | ||||
|     for (int ch = 0; ch < u->channels; ch++) { | ||||
|     for (int ch = 0; ch < u->ch_layout.nb_channels; ch++) { | ||||
|         const double *const us = (double *)u->extended_data[ch]; | ||||
|         const double *const vs = (double *)v->extended_data[ch]; | ||||
|         double sum_uv = s->sum_uv[ch]; | ||||
| @@ -117,10 +117,10 @@ static int config_output(AVFilterLink *outlink) | ||||
|  | ||||
|     s->pts = AV_NOPTS_VALUE; | ||||
|  | ||||
|     s->channels = inlink->channels; | ||||
|     s->channels = inlink->ch_layout.nb_channels; | ||||
|  | ||||
|     s->sum_u  = av_calloc(outlink->channels, sizeof(*s->sum_u)); | ||||
|     s->sum_uv = av_calloc(outlink->channels, sizeof(*s->sum_uv)); | ||||
|     s->sum_u  = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_u)); | ||||
|     s->sum_uv = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->sum_uv)); | ||||
|     if (!s->sum_u || !s->sum_uv) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|   | ||||
| @@ -87,9 +87,9 @@ static int activate(AVFilterContext *ctx) | ||||
|         } | ||||
|  | ||||
|         av_samples_copy(pad_frame->extended_data, frame->extended_data, | ||||
|                         0, 0, frame->nb_samples, frame->channels, frame->format); | ||||
|                         0, 0, frame->nb_samples, frame->ch_layout.nb_channels, frame->format); | ||||
|         av_samples_set_silence(pad_frame->extended_data, frame->nb_samples, | ||||
|                                s->nb_out_samples - frame->nb_samples, frame->channels, | ||||
|                                s->nb_out_samples - frame->nb_samples, frame->ch_layout.nb_channels, | ||||
|                                frame->format); | ||||
|         av_frame_free(&frame); | ||||
|         return ff_filter_frame(outlink, pad_frame); | ||||
|   | ||||
| @@ -178,9 +178,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) | ||||
| { | ||||
|     AVFilterContext *ctx = inlink->dst; | ||||
|     AShowInfoContext *s  = ctx->priv; | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
|     AVChannelLayout layout = { 0 }; | ||||
| #endif | ||||
|     char chlayout_str[128]; | ||||
|     uint32_t checksum = 0; | ||||
|     int channels    = inlink->channels; | ||||
|     int channels    = inlink->ch_layout.nb_channels; | ||||
|     int planar      = av_sample_fmt_is_planar(buf->format); | ||||
|     int block_align = av_get_bytes_per_sample(buf->format) * (planar ? 1 : channels); | ||||
|     int data_size   = buf->nb_samples * block_align; | ||||
| @@ -200,8 +203,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) | ||||
|                        s->plane_checksums[0]; | ||||
|     } | ||||
|  | ||||
|     av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str), buf->channels, | ||||
|                                  buf->channel_layout); | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     if (av_channel_layout_from_mask(&layout, buf->channel_layout)) { | ||||
|         av_channel_layout_describe(&layout, chlayout_str, sizeof(chlayout_str)); | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
|     } else if (buf->ch_layout.nb_channels) | ||||
| #endif | ||||
|     av_channel_layout_describe(&buf->ch_layout, chlayout_str, sizeof(chlayout_str)); | ||||
|  | ||||
|     av_log(ctx, AV_LOG_INFO, | ||||
|            "n:%"PRId64" pts:%s pts_time:%s pos:%"PRId64" " | ||||
| @@ -210,7 +219,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) | ||||
|            inlink->frame_count_out, | ||||
|            av_ts2str(buf->pts), av_ts2timestr(buf->pts, &inlink->time_base), | ||||
|            buf->pkt_pos, | ||||
|            av_get_sample_fmt_name(buf->format), buf->channels, chlayout_str, | ||||
|            av_get_sample_fmt_name(buf->format), buf->ch_layout.nb_channels, chlayout_str, | ||||
|            buf->sample_rate, buf->nb_samples, | ||||
|            checksum); | ||||
|  | ||||
|   | ||||
| @@ -440,7 +440,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     } | ||||
|  | ||||
|     nb_samples = in->nb_samples; | ||||
|     channels = in->channels; | ||||
|     channels = in->ch_layout.nb_channels; | ||||
|  | ||||
|     td.in = in; | ||||
|     td.out = out; | ||||
|   | ||||
| @@ -81,7 +81,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|     float overlap, scale; | ||||
|     int ret; | ||||
|  | ||||
|     s->nb_channels = outlink->channels; | ||||
|     s->nb_channels = outlink->ch_layout.nb_channels; | ||||
|     s->window_func_lut = av_realloc_f(s->window_func_lut, s->win_size, | ||||
|                                       sizeof(*s->window_func_lut)); | ||||
|     if (!s->window_func_lut) | ||||
| @@ -471,7 +471,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|  | ||||
|     metadata = &out->metadata; | ||||
|     ff_filter_execute(ctx, filter_channel, in, NULL, | ||||
|                       FFMIN(inlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(inlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     set_metadata(s, metadata); | ||||
|  | ||||
|   | ||||
| @@ -131,7 +131,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|     if ((ret = ff_add_format                 (&formats, AV_SAMPLE_FMT_S16                 )) < 0 || | ||||
|         (ret = ff_set_common_formats         (ctx     , formats                           )) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , AV_CH_LAYOUT_MONO                 )) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , &(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO )) < 0 || | ||||
|         (ret = ff_set_common_channel_layouts (ctx     , layout                            )) < 0 || | ||||
|         (ret = ff_set_common_samplerates_from_list(ctx, sample_rates     )) < 0) | ||||
|         return ret; | ||||
|   | ||||
| @@ -194,12 +194,12 @@ static int config_output(AVFilterLink *outlink) | ||||
| { | ||||
|     AudioStatsContext *s = outlink->src->priv; | ||||
|  | ||||
|     s->chstats = av_calloc(sizeof(*s->chstats), outlink->channels); | ||||
|     s->chstats = av_calloc(sizeof(*s->chstats), outlink->ch_layout.nb_channels); | ||||
|     if (!s->chstats) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     s->tc_samples = FFMAX(s->time_constant * outlink->sample_rate + .5, 1); | ||||
|     s->nb_channels = outlink->channels; | ||||
|     s->nb_channels = outlink->ch_layout.nb_channels; | ||||
|  | ||||
|     for (int i = 0; i < s->nb_channels; i++) { | ||||
|         ChannelStats *p = &s->chstats[i]; | ||||
| @@ -584,8 +584,8 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job | ||||
|     const uint8_t * const * const data = (const uint8_t * const *)buf->extended_data; | ||||
|     const int channels = s->nb_channels; | ||||
|     const int samples = buf->nb_samples; | ||||
|     const int start = (buf->channels * jobnr) / nb_jobs; | ||||
|     const int end = (buf->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (buf->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (buf->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|  | ||||
|     switch (inlink->format) { | ||||
|     case AV_SAMPLE_FMT_DBLP: | ||||
| @@ -638,7 +638,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) | ||||
|     } | ||||
|  | ||||
|     ff_filter_execute(ctx, filter_channel, buf, NULL, | ||||
|                       FFMIN(inlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(inlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     if (s->metadata) | ||||
|         set_metadata(s, metadata); | ||||
|   | ||||
| @@ -76,7 +76,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|  | ||||
|     s->buffer = ff_get_audio_buffer(inlink, inlink->sample_rate / 10); | ||||
|     s->w = ff_get_audio_buffer(inlink, 2); | ||||
|     s->write_pos = av_calloc(inlink->channels, sizeof(*s->write_pos)); | ||||
|     s->write_pos = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->write_pos)); | ||||
|     if (!s->buffer || !s->w || !s->write_pos) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
| @@ -102,8 +102,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo | ||||
|     const double b2 = s->b2; | ||||
|     const double a1 = -s->a1; | ||||
|     const double a2 = -s->a2; | ||||
|     const int start = (in->channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|     const int buffer_samples = s->buffer_samples; | ||||
|  | ||||
|     for (int ch = start; ch < end; ch++) { | ||||
| @@ -153,7 +153,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|  | ||||
|     td.in = in; td.out = out; | ||||
|     ff_filter_execute(ctx, filter_channels, &td, NULL, | ||||
|                       FFMIN(inlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(inlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     if (out != in) | ||||
|         av_frame_free(&in); | ||||
|   | ||||
| @@ -210,8 +210,8 @@ static int filter_channels_## name(AVFilterContext *ctx, void *arg, \ | ||||
|     ThreadData *td = arg;                                           \ | ||||
|     AVFrame *out = td->out;                                         \ | ||||
|     AVFrame *in = td->in;                                           \ | ||||
|     const int start = (in->channels * jobnr) / nb_jobs;             \ | ||||
|     const int end = (in->channels * (jobnr+1)) / nb_jobs;           \ | ||||
|     const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; \ | ||||
|     const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; \ | ||||
|     const double level = s->level;                                  \ | ||||
|                                                                     \ | ||||
|     for (int ch = start; ch < end; ch++) {                          \ | ||||
| @@ -286,7 +286,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|  | ||||
|     td.in = in; td.out = out; | ||||
|     ff_filter_execute(ctx, s->filter_channels, &td, NULL, | ||||
|                       FFMIN(inlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(inlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     if (out != in) | ||||
|         av_frame_free(&in); | ||||
|   | ||||
| @@ -1018,7 +1018,7 @@ static int config_props(AVFilterLink *inlink) | ||||
|     enum AVSampleFormat format = inlink->format; | ||||
|     int sample_rate = (int)inlink->sample_rate; | ||||
|  | ||||
|     return yae_reset(atempo, format, sample_rate, inlink->channels); | ||||
|     return yae_reset(atempo, format, sample_rate, inlink->ch_layout.nb_channels); | ||||
| } | ||||
|  | ||||
| static int push_samples(ATempoContext *atempo, | ||||
|   | ||||
| @@ -125,8 +125,8 @@ static int filter_channels_## name(AVFilterContext *ctx, void *arg, \ | ||||
|     ThreadData *td = arg;                                           \ | ||||
|     AVFrame *out = td->out;                                         \ | ||||
|     AVFrame *in = td->in;                                           \ | ||||
|     const int start = (in->channels * jobnr) / nb_jobs;             \ | ||||
|     const int end = (in->channels * (jobnr+1)) / nb_jobs;           \ | ||||
|     const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; \ | ||||
|     const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; \ | ||||
|     const type level = s->level;                                    \ | ||||
|                                                                     \ | ||||
|     for (int ch = start; ch < end; ch++) {                          \ | ||||
| @@ -196,7 +196,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     } | ||||
|  | ||||
|     td.in = in; td.out = out; | ||||
|     ff_filter_execute(ctx, s->filter_channels, &td, NULL, FFMIN(inlink->channels, | ||||
|     ff_filter_execute(ctx, s->filter_channels, &td, NULL, FFMIN(inlink->ch_layout.nb_channels, | ||||
|                                                                ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     if (out != in) | ||||
|   | ||||
| @@ -113,7 +113,7 @@ static int xcorrelate_slow_##suffix(AVFilterContext *ctx, \ | ||||
|     const int size = FFMIN(available, s->size);           \ | ||||
|     int used;                                             \ | ||||
|                                                           \ | ||||
|     for (int ch = 0; ch < out->channels; ch++) {          \ | ||||
|     for (int ch = 0; ch < out->ch_layout.nb_channels; ch++) {         \ | ||||
|         const type *x = (const type *)s->cache[0]->extended_data[ch]; \ | ||||
|         const type *y = (const type *)s->cache[1]->extended_data[ch]; \ | ||||
|         type *sumx = (type *)s->mean_sum[0]->extended_data[ch];       \ | ||||
| @@ -155,7 +155,7 @@ static int xcorrelate_fast_##suffix(AVFilterContext *ctx, AVFrame *out,        \ | ||||
|     const int size = FFMIN(available, s->size);                                \ | ||||
|     int used;                                                                  \ | ||||
|                                                                                \ | ||||
|     for (int ch = 0; ch < out->channels; ch++) {                               \ | ||||
|     for (int ch = 0; ch < out->ch_layout.nb_channels; ch++) {                  \ | ||||
|         const type *x = (const type *)s->cache[0]->extended_data[ch];          \ | ||||
|         const type *y = (const type *)s->cache[1]->extended_data[ch];          \ | ||||
|         type *num_sum = (type *)s->num_sum->extended_data[ch];                 \ | ||||
| @@ -299,8 +299,8 @@ static int config_output(AVFilterLink *outlink) | ||||
|  | ||||
|     s->pts = AV_NOPTS_VALUE; | ||||
|  | ||||
|     s->fifo[0] = av_audio_fifo_alloc(outlink->format, outlink->channels, s->size); | ||||
|     s->fifo[1] = av_audio_fifo_alloc(outlink->format, outlink->channels, s->size); | ||||
|     s->fifo[0] = av_audio_fifo_alloc(outlink->format, outlink->ch_layout.nb_channels, s->size); | ||||
|     s->fifo[1] = av_audio_fifo_alloc(outlink->format, outlink->ch_layout.nb_channels, s->size); | ||||
|     if (!s->fifo[0] || !s->fifo[1]) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|   | ||||
| @@ -125,7 +125,8 @@ typedef struct BiquadsContext { | ||||
|     double frequency; | ||||
|     double width; | ||||
|     double mix; | ||||
|     uint64_t channels; | ||||
|     char *ch_layout_str; | ||||
|     AVChannelLayout ch_layout; | ||||
|     int normalize; | ||||
|     int order; | ||||
|  | ||||
| @@ -716,11 +717,11 @@ static int config_filter(AVFilterLink *outlink, int reset) | ||||
|         s->b2 *= factor; | ||||
|     } | ||||
|  | ||||
|     s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels); | ||||
|     s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->ch_layout.nb_channels); | ||||
|     if (!s->cache) | ||||
|         return AVERROR(ENOMEM); | ||||
|     if (reset) | ||||
|         memset(s->cache, 0, sizeof(ChanCache) * inlink->channels); | ||||
|         memset(s->cache, 0, sizeof(ChanCache) * inlink->ch_layout.nb_channels); | ||||
|  | ||||
|     switch (s->transform_type) { | ||||
|     case DI: | ||||
| @@ -838,12 +839,15 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job | ||||
|     AVFrame *buf = td->in; | ||||
|     AVFrame *out_buf = td->out; | ||||
|     BiquadsContext *s = ctx->priv; | ||||
|     const int start = (buf->channels * jobnr) / nb_jobs; | ||||
|     const int end = (buf->channels * (jobnr+1)) / nb_jobs; | ||||
|     const int start = (buf->ch_layout.nb_channels * jobnr) / nb_jobs; | ||||
|     const int end = (buf->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; | ||||
|     int ch; | ||||
|  | ||||
|     for (ch = start; ch < end; ch++) { | ||||
|         if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) { | ||||
|         enum AVChannel channel = av_channel_layout_channel_from_index(&inlink->ch_layout, ch); | ||||
|  | ||||
|         if (av_channel_layout_index_from_channel(&s->ch_layout, channel) < 0) { | ||||
|  | ||||
|             if (buf != out_buf) | ||||
|                 memcpy(out_buf->extended_data[ch], buf->extended_data[ch], | ||||
|                        buf->nb_samples * s->block_align); | ||||
| @@ -884,9 +888,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) | ||||
|     td.in = buf; | ||||
|     td.out = out_buf; | ||||
|     ff_filter_execute(ctx, filter_channel, &td, NULL, | ||||
|                       FFMIN(outlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(outlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     for (ch = 0; ch < outlink->channels; ch++) { | ||||
|     for (ch = 0; ch < outlink->ch_layout.nb_channels; ch++) { | ||||
|         if (s->cache[ch].clippings > 0) | ||||
|             av_log(ctx, AV_LOG_WARNING, "Channel %d clipping %d times. Please reduce gain.\n", | ||||
|                    ch, s->cache[ch].clippings); | ||||
| @@ -917,6 +921,7 @@ static av_cold void uninit(AVFilterContext *ctx) | ||||
|     BiquadsContext *s = ctx->priv; | ||||
|  | ||||
|     av_freep(&s->cache); | ||||
|     av_channel_layout_uninit(&s->ch_layout); | ||||
| } | ||||
|  | ||||
| static const AVFilterPad inputs[] = { | ||||
| @@ -943,8 +948,12 @@ static const AVFilterPad outputs[] = { | ||||
| static av_cold int name_##_init(AVFilterContext *ctx)                   \ | ||||
| {                                                                       \ | ||||
|     BiquadsContext *s = ctx->priv;                                      \ | ||||
|     int ret;                                                            \ | ||||
|     s->filter_type = name_;                                             \ | ||||
|     return 0;                                                           \ | ||||
|     if (strcmp(s->ch_layout_str, "all"))                                \ | ||||
|         ret = av_channel_layout_from_string(&s->ch_layout,              \ | ||||
|                                             s->ch_layout_str);          \ | ||||
|     return ret;                                                         \ | ||||
| }                                                                       \ | ||||
|                                                          \ | ||||
| const AVFilter ff_af_##name_ = {                               \ | ||||
| @@ -982,8 +991,8 @@ static const AVOption equalizer_options[] = { | ||||
|     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, | ||||
|     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, | ||||
| @@ -1024,8 +1033,8 @@ static const AVOption bass_lowshelf_options[] = { | ||||
|     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF}, | ||||
|     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, | ||||
| @@ -1073,8 +1082,8 @@ static const AVOption treble_highshelf_options[] = { | ||||
|     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF}, | ||||
|     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, | ||||
| @@ -1121,8 +1130,8 @@ static const AVOption bandpass_options[] = { | ||||
|     {"csg",   "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, | ||||
| @@ -1159,8 +1168,8 @@ static const AVOption bandreject_options[] = { | ||||
|     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, | ||||
|     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, | ||||
| @@ -1199,8 +1208,8 @@ static const AVOption lowpass_options[] = { | ||||
|     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF}, | ||||
|     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, | ||||
| @@ -1239,8 +1248,8 @@ static const AVOption highpass_options[] = { | ||||
|     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF}, | ||||
|     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, | ||||
| @@ -1277,8 +1286,8 @@ static const AVOption allpass_options[] = { | ||||
|     {"w",     "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS}, | ||||
|     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"order", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS}, | ||||
| @@ -1312,8 +1321,8 @@ static const AVOption biquad_options[] = { | ||||
|     {"b2", NULL, OFFSET(ob2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS}, | ||||
|     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"channels", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"c",        "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS}, | ||||
|     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, | ||||
|     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, | ||||
|   | ||||
| @@ -104,7 +104,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|     }; | ||||
|     int ret; | ||||
|  | ||||
|     if (ff_add_channel_layout(&layouts, AV_CH_LAYOUT_STEREO) != 0) | ||||
|     if (ff_add_channel_layout(&layouts, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO) != 0) | ||||
|         return AVERROR(ENOMEM); | ||||
|     ret = ff_set_common_channel_layouts(ctx, layouts); | ||||
|     if (ret < 0) | ||||
|   | ||||
| @@ -38,8 +38,8 @@ | ||||
| #include "internal.h" | ||||
|  | ||||
| struct ChannelMap { | ||||
|     uint64_t in_channel; | ||||
|     uint64_t out_channel; | ||||
|     int in_channel; | ||||
|     int out_channel; | ||||
|     int in_channel_idx; | ||||
|     int out_channel_idx; | ||||
| }; | ||||
| @@ -59,7 +59,7 @@ typedef struct ChannelMapContext { | ||||
|     const AVClass *class; | ||||
|     char *mapping_str; | ||||
|     char *channel_layout_str; | ||||
|     uint64_t output_layout; | ||||
|     AVChannelLayout output_layout; | ||||
|     struct ChannelMap map[MAX_CH]; | ||||
|     int nch; | ||||
|     enum MappingMode mode; | ||||
| @@ -105,13 +105,13 @@ static int get_channel_idx(char **map, int *ch, char delim, int max_ch) | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int get_channel(char **map, uint64_t *ch, char delim) | ||||
| static int get_channel(char **map, int *ch, char delim) | ||||
| { | ||||
|     char *next = split(*map, delim); | ||||
|     if (!next && delim == '-') | ||||
|         return AVERROR(EINVAL); | ||||
|     *ch = av_get_channel_layout(*map); | ||||
|     if (av_get_channel_layout_nb_channels(*ch) != 1) | ||||
|     *ch = av_channel_from_string(*map); | ||||
|     if (*ch < 0) | ||||
|         return AVERROR(EINVAL); | ||||
|     *map = next; | ||||
|     return 0; | ||||
| @@ -167,7 +167,7 @@ static av_cold int channelmap_init(AVFilterContext *ctx) | ||||
|  | ||||
|     for (i = 0; i < map_entries; i++) { | ||||
|         int in_ch_idx = -1, out_ch_idx = -1; | ||||
|         uint64_t in_ch = 0, out_ch = 0; | ||||
|         int in_ch = 0, out_ch = 0; | ||||
|         static const char err[] = "Failed to parse channel map\n"; | ||||
|         switch (mode) { | ||||
|         case MAP_ONE_INT: | ||||
| @@ -198,13 +198,13 @@ static av_cold int channelmap_init(AVFilterContext *ctx) | ||||
|         case MAP_PAIR_INT_STR: | ||||
|             if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 || | ||||
|                 get_channel(&mapping, &out_ch, separator) < 0 || | ||||
|                 out_ch & out_ch_mask) { | ||||
|                 (1ULL << out_ch) & out_ch_mask) { | ||||
|                 av_log(ctx, AV_LOG_ERROR, err); | ||||
|                 return AVERROR(EINVAL); | ||||
|             } | ||||
|             s->map[i].in_channel_idx  = in_ch_idx; | ||||
|             s->map[i].out_channel     = out_ch; | ||||
|             out_ch_mask |= out_ch; | ||||
|             out_ch_mask |= 1ULL << out_ch; | ||||
|             break; | ||||
|         case MAP_PAIR_STR_INT: | ||||
|             if (get_channel(&mapping, &in_ch, '-') < 0 || | ||||
| @@ -218,42 +218,57 @@ static av_cold int channelmap_init(AVFilterContext *ctx) | ||||
|         case MAP_PAIR_STR_STR: | ||||
|             if (get_channel(&mapping, &in_ch, '-') < 0 || | ||||
|                 get_channel(&mapping, &out_ch, separator) < 0 || | ||||
|                 out_ch & out_ch_mask) { | ||||
|                 (1ULL << out_ch) & out_ch_mask) { | ||||
|                 av_log(ctx, AV_LOG_ERROR, err); | ||||
|                 return AVERROR(EINVAL); | ||||
|             } | ||||
|             s->map[i].in_channel = in_ch; | ||||
|             s->map[i].out_channel = out_ch; | ||||
|             out_ch_mask |= out_ch; | ||||
|             out_ch_mask |= 1ULL << out_ch; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     s->mode          = mode; | ||||
|     s->nch           = map_entries; | ||||
|     s->output_layout = out_ch_mask ? out_ch_mask : | ||||
|                        av_get_default_channel_layout(map_entries); | ||||
|     if (out_ch_mask) | ||||
|         av_channel_layout_from_mask(&s->output_layout, out_ch_mask); | ||||
|     else | ||||
|         av_channel_layout_default(&s->output_layout, map_entries); | ||||
|  | ||||
|     if (s->channel_layout_str) { | ||||
|         uint64_t fmt; | ||||
|         if ((fmt = av_get_channel_layout(s->channel_layout_str)) == 0) { | ||||
|             av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout: '%s'.\n", | ||||
|         AVChannelLayout fmt = { 0 }; | ||||
|         int ret; | ||||
|         if ((ret = av_channel_layout_from_string(&fmt, s->channel_layout_str)) < 0) { | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
|             uint64_t mask; | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|             if ((mask = av_get_channel_layout(s->channel_layout_str)) == 0) { | ||||
| #endif | ||||
|                 av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout: '%s'.\n", | ||||
|                        s->channel_layout_str); | ||||
|                 return AVERROR(EINVAL); | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
|             } | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
|             av_log(ctx, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n", | ||||
|                    s->channel_layout_str); | ||||
|             return AVERROR(EINVAL); | ||||
|             av_channel_layout_from_mask(&fmt, mask); | ||||
| #endif | ||||
|         } | ||||
|         if (mode == MAP_NONE) { | ||||
|             int i; | ||||
|             s->nch = av_get_channel_layout_nb_channels(fmt); | ||||
|             s->nch = fmt.nb_channels; | ||||
|             for (i = 0; i < s->nch; i++) { | ||||
|                 s->map[i].in_channel_idx  = i; | ||||
|                 s->map[i].out_channel_idx = i; | ||||
|             } | ||||
|         } else if (out_ch_mask && out_ch_mask != fmt) { | ||||
|             av_get_channel_layout_string(buf, sizeof(buf), 0, out_ch_mask); | ||||
|         } else if (out_ch_mask && av_channel_layout_compare(&s->output_layout, &fmt)) { | ||||
|             av_channel_layout_describe(&s->output_layout, buf, sizeof(buf)); | ||||
|             av_log(ctx, AV_LOG_ERROR, | ||||
|                    "Output channel layout '%s' does not match the list of channel mapped: '%s'.\n", | ||||
|                    s->channel_layout_str, buf); | ||||
|             return AVERROR(EINVAL); | ||||
|         } else if (s->nch != av_get_channel_layout_nb_channels(fmt)) { | ||||
|         } else if (s->nch != fmt.nb_channels) { | ||||
|             av_log(ctx, AV_LOG_ERROR, | ||||
|                    "Output channel layout %s does not match the number of channels mapped %d.\n", | ||||
|                    s->channel_layout_str, s->nch); | ||||
| @@ -261,7 +276,7 @@ static av_cold int channelmap_init(AVFilterContext *ctx) | ||||
|         } | ||||
|         s->output_layout = fmt; | ||||
|     } | ||||
|     if (!s->output_layout) { | ||||
|     if (!s->output_layout.nb_channels) { | ||||
|         av_log(ctx, AV_LOG_ERROR, "Output channel layout is not set and " | ||||
|                "cannot be guessed from the maps.\n"); | ||||
|         return AVERROR(EINVAL); | ||||
| @@ -269,8 +284,8 @@ static av_cold int channelmap_init(AVFilterContext *ctx) | ||||
|  | ||||
|     if (mode == MAP_PAIR_INT_STR || mode == MAP_PAIR_STR_STR) { | ||||
|         for (i = 0; i < s->nch; i++) { | ||||
|             s->map[i].out_channel_idx = av_get_channel_layout_channel_index( | ||||
|                 s->output_layout, s->map[i].out_channel); | ||||
|             s->map[i].out_channel_idx = av_channel_layout_index_from_channel( | ||||
|                 &s->output_layout, s->map[i].out_channel); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -285,7 +300,7 @@ static int channelmap_query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|     if ((ret = ff_set_common_formats    (ctx,  ff_planar_sample_fmts()))  < 0 || | ||||
|         (ret = ff_set_common_all_samplerates(ctx                              )) < 0 || | ||||
|         (ret = ff_add_channel_layout(&channel_layouts, s->output_layout)) < 0 || | ||||
|         (ret = ff_add_channel_layout(&channel_layouts, &s->output_layout)) < 0 || | ||||
|         (ret = ff_channel_layouts_ref(channel_layouts, | ||||
|                                       &ctx->outputs[0]->incfg.channel_layouts)) < 0) | ||||
|         return ret; | ||||
| @@ -299,9 +314,9 @@ static int channelmap_filter_frame(AVFilterLink *inlink, AVFrame *buf) | ||||
|     AVFilterContext  *ctx = inlink->dst; | ||||
|     AVFilterLink *outlink = ctx->outputs[0]; | ||||
|     const ChannelMapContext *s = ctx->priv; | ||||
|     const int nch_in = inlink->channels; | ||||
|     const int nch_in = inlink->ch_layout.nb_channels; | ||||
|     const int nch_out = s->nch; | ||||
|     int ch; | ||||
|     int ch, ret; | ||||
|     uint8_t *source_planes[MAX_CH]; | ||||
|  | ||||
|     memcpy(source_planes, buf->extended_data, | ||||
| @@ -336,8 +351,14 @@ static int channelmap_filter_frame(AVFilterLink *inlink, AVFrame *buf) | ||||
|         memcpy(buf->data, buf->extended_data, | ||||
|            FFMIN(FF_ARRAY_ELEMS(buf->data), nch_out) * sizeof(buf->data[0])); | ||||
|  | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     buf->channels = outlink->ch_layout.nb_channels; | ||||
|     buf->channel_layout = outlink->channel_layout; | ||||
|     buf->channels       = outlink->channels; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|     if ((ret = av_channel_layout_copy(&buf->ch_layout, &outlink->ch_layout)) < 0) | ||||
|         return ret; | ||||
|  | ||||
|     return ff_filter_frame(outlink, buf); | ||||
| } | ||||
| @@ -346,24 +367,23 @@ static int channelmap_config_input(AVFilterLink *inlink) | ||||
| { | ||||
|     AVFilterContext *ctx = inlink->dst; | ||||
|     ChannelMapContext *s = ctx->priv; | ||||
|     int nb_channels = inlink->channels; | ||||
|     int nb_channels = inlink->ch_layout.nb_channels; | ||||
|     int i, err = 0; | ||||
|     const char *channel_name; | ||||
|     char channel_name[64]; | ||||
|     char layout_name[256]; | ||||
|  | ||||
|     for (i = 0; i < s->nch; i++) { | ||||
|         struct ChannelMap *m = &s->map[i]; | ||||
|  | ||||
|         if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR) { | ||||
|             m->in_channel_idx = av_get_channel_layout_channel_index( | ||||
|                 inlink->channel_layout, m->in_channel); | ||||
|             m->in_channel_idx = av_channel_layout_index_from_channel( | ||||
|                 &inlink->ch_layout, m->in_channel); | ||||
|         } | ||||
|  | ||||
|         if (m->in_channel_idx < 0 || m->in_channel_idx >= nb_channels) { | ||||
|             av_get_channel_layout_string(layout_name, sizeof(layout_name), | ||||
|                                          nb_channels, inlink->channel_layout); | ||||
|             av_channel_layout_describe(&inlink->ch_layout, layout_name, sizeof(layout_name)); | ||||
|             if (m->in_channel) { | ||||
|                 channel_name = av_get_channel_name(m->in_channel); | ||||
|                 av_channel_name(channel_name, sizeof(channel_name), m->in_channel); | ||||
|                 av_log(ctx, AV_LOG_ERROR, | ||||
|                        "input channel '%s' not available from input layout '%s'\n", | ||||
|                        channel_name, layout_name); | ||||
|   | ||||
| @@ -34,10 +34,12 @@ | ||||
| #include "formats.h" | ||||
| #include "internal.h" | ||||
|  | ||||
| #define MAX_CH 64 | ||||
|  | ||||
| typedef struct ChannelSplitContext { | ||||
|     const AVClass *class; | ||||
|  | ||||
|     uint64_t channel_layout; | ||||
|     AVChannelLayout channel_layout; | ||||
|     char    *channel_layout_str; | ||||
|     char    *channels_str; | ||||
|  | ||||
| @@ -58,54 +60,72 @@ AVFILTER_DEFINE_CLASS(channelsplit); | ||||
| static av_cold int init(AVFilterContext *ctx) | ||||
| { | ||||
|     ChannelSplitContext *s = ctx->priv; | ||||
|     uint64_t channel_layout; | ||||
|     int nb_channels; | ||||
|     AVChannelLayout channel_layout = { 0 }; | ||||
|     int all = 0, ret = 0, i; | ||||
|  | ||||
|     if (!(s->channel_layout = av_get_channel_layout(s->channel_layout_str))) { | ||||
|     if ((ret = av_channel_layout_from_string(&s->channel_layout, s->channel_layout_str)) < 0) { | ||||
|         av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n", | ||||
|                s->channel_layout_str); | ||||
|         ret = AVERROR(EINVAL); | ||||
|         goto fail; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     if (!strcmp(s->channels_str, "all")) { | ||||
|         nb_channels = av_get_channel_layout_nb_channels(s->channel_layout); | ||||
|         channel_layout = s->channel_layout; | ||||
|         if ((ret = av_channel_layout_copy(&channel_layout, &s->channel_layout)) < 0) | ||||
|             goto fail; | ||||
|         all = 1; | ||||
|     } else { | ||||
|         if ((ret = av_get_extended_channel_layout(s->channels_str, &channel_layout, &nb_channels)) < 0) | ||||
|             return ret; | ||||
|         if ((ret = av_channel_layout_from_string(&channel_layout, s->channels_str)) < 0) | ||||
|             goto fail; | ||||
|     } | ||||
|  | ||||
|     for (i = 0; i < nb_channels; i++) { | ||||
|         uint64_t channel = av_channel_layout_extract_channel(channel_layout, i); | ||||
|         AVFilterPad pad  = { 0 }; | ||||
|     if (channel_layout.nb_channels > MAX_CH) { | ||||
|         av_log(ctx, AV_LOG_ERROR, "Too many channels\n"); | ||||
|         goto fail; | ||||
|     } | ||||
|  | ||||
|     for (i = 0; i < channel_layout.nb_channels; i++) { | ||||
|         enum AVChannel channel = av_channel_layout_channel_from_index(&channel_layout, i); | ||||
|         char buf[64]; | ||||
|         AVFilterPad pad = { .flags = AVFILTERPAD_FLAG_FREE_NAME }; | ||||
|  | ||||
|         av_channel_name(buf, sizeof(buf), channel); | ||||
|         pad.type = AVMEDIA_TYPE_AUDIO; | ||||
|         pad.name = av_get_channel_name(channel); | ||||
|         pad.name = av_strdup(buf); | ||||
|         if (!pad.name) { | ||||
|             ret = AVERROR(ENOMEM); | ||||
|             goto fail; | ||||
|         } | ||||
|  | ||||
|         if (all) { | ||||
|             s->map[i] = i; | ||||
|         } else { | ||||
|             if ((ret = av_get_channel_layout_channel_index(s->channel_layout, channel)) < 0) { | ||||
|             if ((ret = av_channel_layout_index_from_channel(&s->channel_layout, channel)) < 0) { | ||||
|                 av_log(ctx, AV_LOG_ERROR, "Channel name '%s' not present in channel layout '%s'.\n", | ||||
|                        av_get_channel_name(channel), s->channel_layout_str); | ||||
|                 return ret; | ||||
|                        pad.name, s->channel_layout_str); | ||||
|                 av_freep(&pad.name); | ||||
|                 goto fail; | ||||
|             } | ||||
|  | ||||
|             s->map[i] = ret; | ||||
|         } | ||||
|  | ||||
|         if ((ret = ff_append_outpad(ctx, &pad)) < 0) | ||||
|             return ret; | ||||
|             goto fail; | ||||
|     } | ||||
|  | ||||
| fail: | ||||
|     av_channel_layout_uninit(&channel_layout); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| static av_cold void uninit(AVFilterContext *ctx) | ||||
| { | ||||
|     ChannelSplitContext *s = ctx->priv; | ||||
|  | ||||
|     av_channel_layout_uninit(&s->channel_layout); | ||||
| } | ||||
|  | ||||
| static int query_formats(AVFilterContext *ctx) | ||||
| { | ||||
|     ChannelSplitContext *s = ctx->priv; | ||||
| @@ -116,15 +136,17 @@ static int query_formats(AVFilterContext *ctx) | ||||
|         (ret = ff_set_common_all_samplerates(ctx)) < 0) | ||||
|         return ret; | ||||
|  | ||||
|     if ((ret = ff_add_channel_layout(&in_layouts, s->channel_layout)) < 0 || | ||||
|     if ((ret = ff_add_channel_layout(&in_layouts, &s->channel_layout)) < 0 || | ||||
|         (ret = ff_channel_layouts_ref(in_layouts, &ctx->inputs[0]->outcfg.channel_layouts)) < 0) | ||||
|         return ret; | ||||
|  | ||||
|     for (i = 0; i < ctx->nb_outputs; i++) { | ||||
|         AVChannelLayout channel_layout = { 0 }; | ||||
|         AVFilterChannelLayouts *out_layouts = NULL; | ||||
|         uint64_t channel = av_channel_layout_extract_channel(s->channel_layout, s->map[i]); | ||||
|         enum AVChannel channel = av_channel_layout_channel_from_index(&s->channel_layout, s->map[i]); | ||||
|  | ||||
|         if ((ret = ff_add_channel_layout(&out_layouts, channel)) < 0 || | ||||
|         if ((ret = av_channel_layout_from_mask(&channel_layout, 1ULL << channel)) < 0 || | ||||
|             (ret = ff_add_channel_layout(&out_layouts, &channel_layout)) < 0 || | ||||
|             (ret = ff_channel_layouts_ref(out_layouts, &ctx->outputs[i]->incfg.channel_layouts)) < 0) | ||||
|             return ret; | ||||
|     } | ||||
| @@ -137,15 +159,24 @@ static int filter_frame(AVFilterLink *outlink, AVFrame *buf) | ||||
|     AVFilterContext *ctx = outlink->src; | ||||
|     ChannelSplitContext *s = ctx->priv; | ||||
|     const int i = FF_OUTLINK_IDX(outlink); | ||||
|     enum AVChannel channel = av_channel_layout_channel_from_index(&buf->ch_layout, s->map[i]); | ||||
|     int ret; | ||||
|  | ||||
|     AVFrame *buf_out = av_frame_clone(buf); | ||||
|     if (!buf_out) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     buf_out->data[0] = buf_out->extended_data[0] = buf_out->extended_data[s->map[i]]; | ||||
|     ret = av_channel_layout_from_mask(&buf_out->ch_layout, 1ULL << channel); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     buf_out->channel_layout = | ||||
|         av_channel_layout_extract_channel(buf->channel_layout, s->map[i]); | ||||
|     buf_out->channels = 1; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|  | ||||
|     return ff_filter_frame(ctx->outputs[i], buf_out); | ||||
| } | ||||
| @@ -215,6 +246,7 @@ const AVFilter ff_af_channelsplit = { | ||||
|     .priv_class     = &channelsplit_class, | ||||
|     .init           = init, | ||||
|     .activate       = activate, | ||||
|     .uninit         = uninit, | ||||
|     FILTER_INPUTS(avfilter_af_channelsplit_inputs), | ||||
|     .outputs        = NULL, | ||||
|     FILTER_QUERY_FUNC(query_formats), | ||||
|   | ||||
| @@ -161,7 +161,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|     float sum_in_volume = 1.0; | ||||
|     int n; | ||||
|  | ||||
|     s->channels = outlink->channels; | ||||
|     s->channels = outlink->ch_layout.nb_channels; | ||||
|  | ||||
|     for (n = 0; n < s->num_chorus; n++) { | ||||
|         int samples = (int) ((s->delays[n] + s->depths[n]) * outlink->sample_rate / 1000.0); | ||||
| @@ -184,15 +184,15 @@ static int config_output(AVFilterLink *outlink) | ||||
|     if (s->in_gain * (sum_in_volume) > 1.0 / s->out_gain) | ||||
|         av_log(ctx, AV_LOG_WARNING, "output gain can cause saturation or clipping of output\n"); | ||||
|  | ||||
|     s->counter = av_calloc(outlink->channels, sizeof(*s->counter)); | ||||
|     s->counter = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->counter)); | ||||
|     if (!s->counter) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     s->phase = av_calloc(outlink->channels, sizeof(*s->phase)); | ||||
|     s->phase = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->phase)); | ||||
|     if (!s->phase) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (n = 0; n < outlink->channels; n++) { | ||||
|     for (n = 0; n < outlink->ch_layout.nb_channels; n++) { | ||||
|         s->phase[n] = av_calloc(s->num_chorus, sizeof(int)); | ||||
|         if (!s->phase[n]) | ||||
|             return AVERROR(ENOMEM); | ||||
| @@ -201,7 +201,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|     s->fade_out = s->max_samples; | ||||
|  | ||||
|     return av_samples_alloc_array_and_samples(&s->chorusbuf, NULL, | ||||
|                                               outlink->channels, | ||||
|                                               outlink->ch_layout.nb_channels, | ||||
|                                               s->max_samples, | ||||
|                                               outlink->format, 0); | ||||
| } | ||||
| @@ -226,7 +226,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) | ||||
|         av_frame_copy_props(out_frame, frame); | ||||
|     } | ||||
|  | ||||
|     for (c = 0; c < inlink->channels; c++) { | ||||
|     for (c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|         const float *src = (const float *)frame->extended_data[c]; | ||||
|         float *dst = (float *)out_frame->extended_data[c]; | ||||
|         float *chorusbuf = (float *)s->chorusbuf[c]; | ||||
| @@ -280,7 +280,7 @@ static int request_frame(AVFilterLink *outlink) | ||||
|  | ||||
|         av_samples_set_silence(frame->extended_data, 0, | ||||
|                                frame->nb_samples, | ||||
|                                outlink->channels, | ||||
|                                outlink->ch_layout.nb_channels, | ||||
|                                frame->format); | ||||
|  | ||||
|         frame->pts = s->next_pts; | ||||
|   | ||||
| @@ -146,7 +146,7 @@ static int compand_nodelay(AVFilterContext *ctx, AVFrame *frame) | ||||
| { | ||||
|     CompandContext *s    = ctx->priv; | ||||
|     AVFilterLink *inlink = ctx->inputs[0]; | ||||
|     const int channels   = inlink->channels; | ||||
|     const int channels   = inlink->ch_layout.nb_channels; | ||||
|     const int nb_samples = frame->nb_samples; | ||||
|     AVFrame *out_frame; | ||||
|     int chan, i; | ||||
| @@ -192,7 +192,7 @@ static int compand_delay(AVFilterContext *ctx, AVFrame *frame) | ||||
| { | ||||
|     CompandContext *s    = ctx->priv; | ||||
|     AVFilterLink *inlink = ctx->inputs[0]; | ||||
|     const int channels = inlink->channels; | ||||
|     const int channels = inlink->ch_layout.nb_channels; | ||||
|     const int nb_samples = frame->nb_samples; | ||||
|     int chan, i, av_uninit(dindex), oindex, av_uninit(count); | ||||
|     AVFrame *out_frame   = NULL; | ||||
| @@ -264,7 +264,7 @@ static int compand_drain(AVFilterLink *outlink) | ||||
| { | ||||
|     AVFilterContext *ctx = outlink->src; | ||||
|     CompandContext *s    = ctx->priv; | ||||
|     const int channels   = outlink->channels; | ||||
|     const int channels   = outlink->ch_layout.nb_channels; | ||||
|     AVFrame *frame       = NULL; | ||||
|     int chan, i, dindex; | ||||
|  | ||||
| @@ -302,7 +302,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|     const int sample_rate = outlink->sample_rate; | ||||
|     double radius         = s->curve_dB * M_LN10 / 20.0; | ||||
|     char *p, *saveptr     = NULL; | ||||
|     const int channels    = outlink->channels; | ||||
|     const int channels    = outlink->ch_layout.nb_channels; | ||||
|     int nb_attacks, nb_decays, nb_points; | ||||
|     int new_nb_items, num; | ||||
|     int i; | ||||
| @@ -503,7 +503,13 @@ static int config_output(AVFilterLink *outlink) | ||||
|  | ||||
|     s->delay_frame->format         = outlink->format; | ||||
|     s->delay_frame->nb_samples     = s->delay_samples; | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     s->delay_frame->channel_layout = outlink->channel_layout; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|     if ((err = av_channel_layout_copy(&s->delay_frame->ch_layout, &outlink->ch_layout)) < 0) | ||||
|         return err; | ||||
|  | ||||
|     err = av_frame_get_buffer(s->delay_frame, 0); | ||||
|     if (err) | ||||
|   | ||||
| @@ -68,6 +68,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|     AVFilterContext *ctx = inlink->dst; | ||||
|     CompensationDelayContext *s = ctx->priv; | ||||
|     unsigned min_size, new_size = 1; | ||||
|     int ret; | ||||
|  | ||||
|     s->delay = (s->distance_m * 100. + s->distance_cm * 1. + s->distance_mm * .1) * | ||||
|                COMP_DELAY_SOUND_FRONT_DELAY(s->temp) * inlink->sample_rate; | ||||
| @@ -83,8 +84,14 @@ static int config_input(AVFilterLink *inlink) | ||||
|     s->buf_size                    = new_size; | ||||
|     s->delay_frame->format         = inlink->format; | ||||
|     s->delay_frame->nb_samples     = new_size; | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     s->delay_frame->channel_layout = inlink->channel_layout; | ||||
|     s->delay_frame->channels       = inlink->channels; | ||||
|     s->delay_frame->channels       = inlink->ch_layout.nb_channels; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|     if ((ret = av_channel_layout_copy(&s->delay_frame->ch_layout, &inlink->ch_layout)) < 0) | ||||
|         return ret; | ||||
|  | ||||
|     return av_frame_get_buffer(s->delay_frame, 0); | ||||
| } | ||||
| @@ -110,7 +117,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     } | ||||
|     av_frame_copy_props(out, in); | ||||
|  | ||||
|     for (ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         const double *src = (const double *)in->extended_data[ch]; | ||||
|         double *dst = (double *)out->extended_data[ch]; | ||||
|         double *buffer = (double *)s->delay_frame->extended_data[ch]; | ||||
|   | ||||
| @@ -46,7 +46,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|     if ((ret = ff_add_format                 (&formats, AV_SAMPLE_FMT_DBL  )) < 0 || | ||||
|         (ret = ff_set_common_formats         (ctx     , formats            )) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , AV_CH_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_set_common_channel_layouts (ctx     , layout             )) < 0 || | ||||
|         (ret = ff_set_common_all_samplerates (ctx                          )) < 0) | ||||
|         return ret; | ||||
|   | ||||
| @@ -206,10 +206,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     td.s = (const void **)in->extended_data; | ||||
|     td.p = (void **)s->prev->extended_data; | ||||
|     td.nb_samples = in->nb_samples; | ||||
|     td.channels = in->channels; | ||||
|     td.channels = in->ch_layout.nb_channels; | ||||
|     td.mult = ctx->is_disabled ? 0.f : s->mult; | ||||
|     ff_filter_execute(ctx, s->filter[td.mult >= 0.f][s->clip], &td, NULL, | ||||
|                       FFMIN(inlink->channels, ff_filter_get_nb_threads(ctx))); | ||||
|                       FFMIN(inlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx))); | ||||
|  | ||||
|     if (out != in) | ||||
|         av_frame_free(&in); | ||||
|   | ||||
| @@ -73,7 +73,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     } | ||||
|  | ||||
|     if (s->limitergain > 0) { | ||||
|         for (i = 0; i < inlink->channels; i++) { | ||||
|         for (i = 0; i < inlink->ch_layout.nb_channels; i++) { | ||||
|             const int32_t *src = (int32_t *)in->extended_data[i]; | ||||
|             int32_t *dst = (int32_t *)out->extended_data[i]; | ||||
|  | ||||
| @@ -98,7 +98,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|         for (i = 0; i < inlink->channels; i++) { | ||||
|         for (i = 0; i < inlink->ch_layout.nb_channels; i++) { | ||||
|             const int32_t *src = (int32_t *)in->extended_data[i]; | ||||
|             int32_t *dst = (int32_t *)out->extended_data[i]; | ||||
|  | ||||
|   | ||||
| @@ -73,11 +73,11 @@ static int config_input(AVFilterLink *inlink) | ||||
|     AVFilterContext *ctx = inlink->dst; | ||||
|     DeesserContext *s = ctx->priv; | ||||
|  | ||||
|     s->chan = av_calloc(inlink->channels, sizeof(*s->chan)); | ||||
|     s->chan = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->chan)); | ||||
|     if (!s->chan) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (int i = 0; i < inlink->channels; i++) { | ||||
|     for (int i = 0; i < inlink->ch_layout.nb_channels; i++) { | ||||
|         DeesserChannel *chan = &s->chan[i]; | ||||
|  | ||||
|         chan->ratioA = chan->ratioB = 1.0; | ||||
| @@ -104,7 +104,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         av_frame_copy_props(out, in); | ||||
|     } | ||||
|  | ||||
|     for (int ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         DeesserChannel *dec = &s->chan[ch]; | ||||
|         double *src = (double *)in->extended_data[ch]; | ||||
|         double *dst = (double *)out->extended_data[ch]; | ||||
|   | ||||
| @@ -72,9 +72,9 @@ static int query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|     if ((ret = ff_add_format                 (&formats, AV_SAMPLE_FMT_FLTP )) < 0 || | ||||
|         (ret = ff_set_common_formats         (ctx     , formats            )) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&in_layout , AV_CH_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&in_layout , &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_channel_layouts_ref(in_layout, &ctx->inputs[0]->outcfg.channel_layouts)) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&out_layout , AV_CH_LAYOUT_SURROUND)) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&out_layout , &(AVChannelLayout)AV_CHANNEL_LAYOUT_SURROUND)) < 0 || | ||||
|         (ret = ff_channel_layouts_ref(out_layout, &ctx->outputs[0]->incfg.channel_layouts)) < 0) | ||||
|         return ret; | ||||
|  | ||||
|   | ||||
| @@ -59,10 +59,10 @@ static int config_output(AVFilterLink *outlink) | ||||
| { | ||||
|     DRMeterContext *s = outlink->src->priv; | ||||
|  | ||||
|     s->chstats = av_calloc(sizeof(*s->chstats), outlink->channels); | ||||
|     s->chstats = av_calloc(sizeof(*s->chstats), outlink->ch_layout.nb_channels); | ||||
|     if (!s->chstats) | ||||
|         return AVERROR(ENOMEM); | ||||
|     s->nb_channels = outlink->channels; | ||||
|     s->nb_channels = outlink->ch_layout.nb_channels; | ||||
|     s->tc_samples = s->time_constant * outlink->sample_rate + .5; | ||||
|  | ||||
|     return 0; | ||||
|   | ||||
| @@ -79,7 +79,8 @@ typedef struct DynamicAudioNormalizerContext { | ||||
|     int channels; | ||||
|     int sample_advance; | ||||
|     int eof; | ||||
|     uint64_t channels_to_filter; | ||||
|     char *channels_to_filter; | ||||
|     AVChannelLayout ch_layout; | ||||
|     int64_t pts; | ||||
|  | ||||
|     cqueue **gain_history_original; | ||||
| @@ -116,8 +117,8 @@ static const AVOption dynaudnorm_options[] = { | ||||
|     { "s",           "set the compress factor",          OFFSET(compress_factor),   AV_OPT_TYPE_DOUBLE, {.dbl = 0.0},  0.0,  30.0, FLAGS }, | ||||
|     { "threshold",   "set the threshold value",          OFFSET(threshold),         AV_OPT_TYPE_DOUBLE, {.dbl = 0.0},  0.0,   1.0, FLAGS }, | ||||
|     { "t",           "set the threshold value",          OFFSET(threshold),         AV_OPT_TYPE_DOUBLE, {.dbl = 0.0},  0.0,   1.0, FLAGS }, | ||||
|     { "channels",    "set channels to filter",           OFFSET(channels_to_filter),AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS }, | ||||
|     { "h",           "set channels to filter",           OFFSET(channels_to_filter),AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS }, | ||||
|     { "channels",    "set channels to filter",           OFFSET(channels_to_filter),AV_OPT_TYPE_STRING, {.str="all"}, 0, 0, FLAGS }, | ||||
|     { "h",           "set channels to filter",           OFFSET(channels_to_filter),AV_OPT_TYPE_STRING, {.str="all"}, 0, 0, FLAGS }, | ||||
|     { "overlap",     "set the frame overlap",            OFFSET(overlap),           AV_OPT_TYPE_DOUBLE, {.dbl=.0},     0.0,   1.0, FLAGS }, | ||||
|     { "o",           "set the frame overlap",            OFFSET(overlap),           AV_OPT_TYPE_DOUBLE, {.dbl=.0},     0.0,   1.0, FLAGS }, | ||||
|     { NULL } | ||||
| @@ -128,13 +129,17 @@ AVFILTER_DEFINE_CLASS(dynaudnorm); | ||||
| static av_cold int init(AVFilterContext *ctx) | ||||
| { | ||||
|     DynamicAudioNormalizerContext *s = ctx->priv; | ||||
|     int ret = 0; | ||||
|  | ||||
|     if (!(s->filter_size & 1)) { | ||||
|         av_log(ctx, AV_LOG_WARNING, "filter size %d is invalid. Changing to an odd value.\n", s->filter_size); | ||||
|         s->filter_size |= 1; | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
|     if (strcmp(s->channels_to_filter, "all")) | ||||
|         ret = av_channel_layout_from_string(&s->ch_layout, s->channels_to_filter); | ||||
|  | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| static inline int frame_size(int sample_rate, int frame_len_msec) | ||||
| @@ -298,6 +303,8 @@ static av_cold void uninit(AVFilterContext *ctx) | ||||
|  | ||||
|     av_freep(&s->weights); | ||||
|  | ||||
|     av_channel_layout_uninit(&s->ch_layout); | ||||
|  | ||||
|     ff_bufqueue_discard_all(&s->queue); | ||||
|  | ||||
|     av_frame_free(&s->window); | ||||
| @@ -310,17 +317,17 @@ static int config_input(AVFilterLink *inlink) | ||||
|  | ||||
|     uninit(ctx); | ||||
|  | ||||
|     s->channels = inlink->channels; | ||||
|     s->channels = inlink->ch_layout.nb_channels; | ||||
|     s->frame_len = frame_size(inlink->sample_rate, s->frame_len_msec); | ||||
|     av_log(ctx, AV_LOG_DEBUG, "frame len %d\n", s->frame_len); | ||||
|  | ||||
|     s->prev_amplification_factor = av_malloc_array(inlink->channels, sizeof(*s->prev_amplification_factor)); | ||||
|     s->dc_correction_value = av_calloc(inlink->channels, sizeof(*s->dc_correction_value)); | ||||
|     s->compress_threshold = av_calloc(inlink->channels, sizeof(*s->compress_threshold)); | ||||
|     s->gain_history_original = av_calloc(inlink->channels, sizeof(*s->gain_history_original)); | ||||
|     s->gain_history_minimum = av_calloc(inlink->channels, sizeof(*s->gain_history_minimum)); | ||||
|     s->gain_history_smoothed = av_calloc(inlink->channels, sizeof(*s->gain_history_smoothed)); | ||||
|     s->threshold_history = av_calloc(inlink->channels, sizeof(*s->threshold_history)); | ||||
|     s->prev_amplification_factor = av_malloc_array(inlink->ch_layout.nb_channels, sizeof(*s->prev_amplification_factor)); | ||||
|     s->dc_correction_value = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->dc_correction_value)); | ||||
|     s->compress_threshold = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->compress_threshold)); | ||||
|     s->gain_history_original = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->gain_history_original)); | ||||
|     s->gain_history_minimum = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->gain_history_minimum)); | ||||
|     s->gain_history_smoothed = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->gain_history_smoothed)); | ||||
|     s->threshold_history = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->threshold_history)); | ||||
|     s->weights = av_malloc_array(MAX_FILTER_SIZE, sizeof(*s->weights)); | ||||
|     s->is_enabled = cqueue_create(s->filter_size, MAX_FILTER_SIZE); | ||||
|     if (!s->prev_amplification_factor || !s->dc_correction_value || | ||||
| @@ -330,7 +337,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|         !s->is_enabled || !s->weights) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (int c = 0; c < inlink->channels; c++) { | ||||
|     for (int c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|         s->prev_amplification_factor[c] = 1.0; | ||||
|  | ||||
|         s->gain_history_original[c] = cqueue_create(s->filter_size, MAX_FILTER_SIZE); | ||||
| @@ -377,7 +384,7 @@ static double find_peak_magnitude(AVFrame *frame, int channel) | ||||
|     double max = DBL_EPSILON; | ||||
|  | ||||
|     if (channel == -1) { | ||||
|         for (int c = 0; c < frame->channels; c++) { | ||||
|         for (int c = 0; c < frame->ch_layout.nb_channels; c++) { | ||||
|             double *data_ptr = (double *)frame->extended_data[c]; | ||||
|  | ||||
|             for (int i = 0; i < frame->nb_samples; i++) | ||||
| @@ -398,7 +405,7 @@ static double compute_frame_rms(AVFrame *frame, int channel) | ||||
|     double rms_value = 0.0; | ||||
|  | ||||
|     if (channel == -1) { | ||||
|         for (int c = 0; c < frame->channels; c++) { | ||||
|         for (int c = 0; c < frame->ch_layout.nb_channels; c++) { | ||||
|             const double *data_ptr = (double *)frame->extended_data[c]; | ||||
|  | ||||
|             for (int i = 0; i < frame->nb_samples; i++) { | ||||
| @@ -406,7 +413,7 @@ static double compute_frame_rms(AVFrame *frame, int channel) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         rms_value /= frame->nb_samples * frame->channels; | ||||
|         rms_value /= frame->nb_samples * frame->ch_layout.nb_channels; | ||||
|     } else { | ||||
|         const double *data_ptr = (double *)frame->extended_data[channel]; | ||||
|         for (int i = 0; i < frame->nb_samples; i++) { | ||||
| @@ -526,7 +533,9 @@ static inline double update_value(double new, double old, double aggressiveness) | ||||
|  | ||||
| static inline int bypass_channel(DynamicAudioNormalizerContext *s, AVFrame *frame, int ch) | ||||
| { | ||||
|     return !(av_channel_layout_extract_channel(frame->channel_layout, ch) & s->channels_to_filter); | ||||
|     enum AVChannel channel = av_channel_layout_channel_from_index(&frame->ch_layout, ch); | ||||
|  | ||||
|     return av_channel_layout_index_from_channel(&s->ch_layout, channel) < 0; | ||||
| } | ||||
|  | ||||
| static void perform_dc_correction(DynamicAudioNormalizerContext *s, AVFrame *frame) | ||||
| @@ -702,7 +711,7 @@ static int analyze_frame(DynamicAudioNormalizerContext *s, AVFilterLink *outlink | ||||
|         analyze_frame = s->window; | ||||
|     } else { | ||||
|         av_samples_copy(s->window->extended_data, (*frame)->extended_data, 0, 0, | ||||
|                         s->frame_len, (*frame)->channels, (*frame)->format); | ||||
|                         s->frame_len, (*frame)->ch_layout.nb_channels, (*frame)->format); | ||||
|         analyze_frame = *frame; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -88,7 +88,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|     if ((ret = ff_add_format                 (&formats, AV_SAMPLE_FMT_S16P                )) < 0 || | ||||
|         (ret = ff_set_common_formats         (ctx     , formats                           )) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , AV_CH_LAYOUT_STEREO               )) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_set_common_channel_layouts (ctx     , layout                            )) < 0 || | ||||
|         (ret = ff_set_common_samplerates_from_list(ctx, sample_rates)) < 0) | ||||
|         return ret; | ||||
|   | ||||
| @@ -49,7 +49,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|     if ((ret = ff_add_format                 (&formats, AV_SAMPLE_FMT_FLT  )) < 0 || | ||||
|         (ret = ff_set_common_formats         (ctx     , formats            )) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , AV_CH_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_set_common_channel_layouts (ctx     , layout             )) < 0) | ||||
|         return ret; | ||||
|  | ||||
|   | ||||
| @@ -607,14 +607,15 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g | ||||
|     if (s->dumpfile && (!s->dump_buf || !s->analysis_rdft || !(dump_fp = fopen(s->dumpfile, "w")))) | ||||
|         av_log(ctx, AV_LOG_WARNING, "dumping failed.\n"); | ||||
|  | ||||
|     vars[VAR_CHS] = inlink->channels; | ||||
|     vars[VAR_CHLAYOUT] = inlink->channel_layout; | ||||
|     vars[VAR_CHS] = inlink->ch_layout.nb_channels; | ||||
|     vars[VAR_CHLAYOUT] = inlink->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ? | ||||
|                          inlink->ch_layout.u.mask : 0; | ||||
|     vars[VAR_SR] = inlink->sample_rate; | ||||
|     for (ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         float *rdft_buf = s->kernel_tmp_buf + ch * s->rdft_len; | ||||
|         double result; | ||||
|         vars[VAR_CH] = ch; | ||||
|         vars[VAR_CHID] = av_channel_layout_extract_channel(inlink->channel_layout, ch); | ||||
|         vars[VAR_CHID] = av_channel_layout_channel_from_index(&inlink->ch_layout, ch); | ||||
|         vars[VAR_F] = 0.0; | ||||
|         if (xlog) | ||||
|             vars[VAR_F] = log2(0.05 * vars[VAR_F]); | ||||
| @@ -715,7 +716,7 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g | ||||
|             break; | ||||
|     } | ||||
|  | ||||
|     memcpy(s->kernel_buf, s->kernel_tmp_buf, (s->multi ? inlink->channels : 1) * s->rdft_len * sizeof(*s->kernel_buf)); | ||||
|     memcpy(s->kernel_buf, s->kernel_tmp_buf, (s->multi ? inlink->ch_layout.nb_channels : 1) * s->rdft_len * sizeof(*s->kernel_buf)); | ||||
|     av_expr_free(gain_expr); | ||||
|     if (dump_fp) | ||||
|         fclose(dump_fp); | ||||
| @@ -754,7 +755,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|     if (!(s->rdft = av_rdft_init(rdft_bits, DFT_R2C)) || !(s->irdft = av_rdft_init(rdft_bits, IDFT_C2R))) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     if (s->fft2 && !s->multi && inlink->channels > 1 && !(s->fft_ctx = av_fft_init(rdft_bits, 0))) | ||||
|     if (s->fft2 && !s->multi && inlink->ch_layout.nb_channels > 1 && !(s->fft_ctx = av_fft_init(rdft_bits, 0))) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     if (s->min_phase) { | ||||
| @@ -796,15 +797,15 @@ static int config_input(AVFilterLink *inlink) | ||||
|     } | ||||
|  | ||||
|     s->analysis_buf = av_malloc_array(s->analysis_rdft_len, sizeof(*s->analysis_buf)); | ||||
|     s->kernel_tmp_buf = av_malloc_array(s->rdft_len * (s->multi ? inlink->channels : 1), sizeof(*s->kernel_tmp_buf)); | ||||
|     s->kernel_buf = av_malloc_array(s->rdft_len * (s->multi ? inlink->channels : 1), sizeof(*s->kernel_buf)); | ||||
|     s->conv_buf   = av_calloc(2 * s->rdft_len * inlink->channels, sizeof(*s->conv_buf)); | ||||
|     s->conv_idx   = av_calloc(inlink->channels, sizeof(*s->conv_idx)); | ||||
|     s->kernel_tmp_buf = av_malloc_array(s->rdft_len * (s->multi ? inlink->ch_layout.nb_channels : 1), sizeof(*s->kernel_tmp_buf)); | ||||
|     s->kernel_buf = av_malloc_array(s->rdft_len * (s->multi ? inlink->ch_layout.nb_channels : 1), sizeof(*s->kernel_buf)); | ||||
|     s->conv_buf   = av_calloc(2 * s->rdft_len * inlink->ch_layout.nb_channels, sizeof(*s->conv_buf)); | ||||
|     s->conv_idx   = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->conv_idx)); | ||||
|     if (!s->analysis_buf || !s->kernel_tmp_buf || !s->kernel_buf || !s->conv_buf || !s->conv_idx) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     av_log(ctx, AV_LOG_DEBUG, "sample_rate = %d, channels = %d, analysis_rdft_len = %d, rdft_len = %d, fir_len = %d, nsamples_max = %d.\n", | ||||
|            inlink->sample_rate, inlink->channels, s->analysis_rdft_len, s->rdft_len, s->fir_len, s->nsamples_max); | ||||
|            inlink->sample_rate, inlink->ch_layout.nb_channels, s->analysis_rdft_len, s->rdft_len, s->fir_len, s->nsamples_max); | ||||
|  | ||||
|     if (s->fixed) | ||||
|         inlink->min_samples = inlink->max_samples = s->nsamples_max; | ||||
| @@ -819,19 +820,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) | ||||
|     int ch; | ||||
|  | ||||
|     if (!s->min_phase) { | ||||
|         for (ch = 0; ch + 1 < inlink->channels && s->fft_ctx; ch += 2) { | ||||
|         for (ch = 0; ch + 1 < inlink->ch_layout.nb_channels && s->fft_ctx; ch += 2) { | ||||
|             fast_convolute2(s, s->kernel_buf, (FFTComplex *)(s->conv_buf + 2 * ch * s->rdft_len), | ||||
|                             s->conv_idx + ch, (float *) frame->extended_data[ch], | ||||
|                             (float *) frame->extended_data[ch+1], frame->nb_samples); | ||||
|         } | ||||
|  | ||||
|         for ( ; ch < inlink->channels; ch++) { | ||||
|         for ( ; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|             fast_convolute(s, s->kernel_buf + (s->multi ? ch * s->rdft_len : 0), | ||||
|                         s->conv_buf + 2 * ch * s->rdft_len, s->conv_idx + ch, | ||||
|                         (float *) frame->extended_data[ch], frame->nb_samples); | ||||
|         } | ||||
|     } else { | ||||
|         for (ch = 0; ch < inlink->channels; ch++) { | ||||
|         for (ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|             fast_convolute_nonlinear(s, s->kernel_buf + (s->multi ? ch * s->rdft_len : 0), | ||||
|                                      s->conv_buf + 2 * ch * s->rdft_len, s->conv_idx + ch, | ||||
|                                      (float *) frame->extended_data[ch], frame->nb_samples); | ||||
| @@ -861,7 +862,7 @@ static int request_frame(AVFilterLink *outlink) | ||||
|         if (!frame) | ||||
|             return AVERROR(ENOMEM); | ||||
|  | ||||
|         av_samples_set_silence(frame->extended_data, 0, frame->nb_samples, outlink->channels, frame->format); | ||||
|         av_samples_set_silence(frame->extended_data, 0, frame->nb_samples, outlink->ch_layout.nb_channels, frame->format); | ||||
|         frame->pts = s->next_pts; | ||||
|         s->remaining -= frame->nb_samples; | ||||
|         ret = filter_frame(ctx->inputs[0], frame); | ||||
|   | ||||
| @@ -95,7 +95,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|  | ||||
|     s->max_samples = (s->delay_min + s->delay_depth) * inlink->sample_rate + 2.5; | ||||
|     s->lfo_length  = inlink->sample_rate / s->speed; | ||||
|     s->delay_last  = av_calloc(inlink->channels, sizeof(*s->delay_last)); | ||||
|     s->delay_last  = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->delay_last)); | ||||
|     s->lfo         = av_calloc(s->lfo_length, sizeof(*s->lfo)); | ||||
|     if (!s->lfo || !s->delay_last) | ||||
|         return AVERROR(ENOMEM); | ||||
| @@ -105,7 +105,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|                            s->max_samples - 2., 3 * M_PI_2); | ||||
|  | ||||
|     return av_samples_alloc_array_and_samples(&s->delay_buffer, NULL, | ||||
|                                               inlink->channels, s->max_samples, | ||||
|                                               inlink->ch_layout.nb_channels, s->max_samples, | ||||
|                                               inlink->format, 0); | ||||
| } | ||||
|  | ||||
| @@ -131,7 +131,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) | ||||
|  | ||||
|         s->delay_buf_pos = (s->delay_buf_pos + s->max_samples - 1) % s->max_samples; | ||||
|  | ||||
|         for (chan = 0; chan < inlink->channels; chan++) { | ||||
|         for (chan = 0; chan < inlink->ch_layout.nb_channels; chan++) { | ||||
|             double *src = (double *)frame->extended_data[chan]; | ||||
|             double *dst = (double *)out_frame->extended_data[chan]; | ||||
|             double delayed_0, delayed_1; | ||||
|   | ||||
| @@ -87,7 +87,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|     if ((ret = ff_add_format                 (&formats, AV_SAMPLE_FMT_DBL  )) < 0 || | ||||
|         (ret = ff_set_common_formats         (ctx     , formats            )) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , AV_CH_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_set_common_channel_layouts (ctx     , layout             )) < 0) | ||||
|         return ret; | ||||
|  | ||||
|   | ||||
| @@ -1554,27 +1554,27 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     switch (inlink->format) { | ||||
|         case AV_SAMPLE_FMT_S16P: | ||||
|             for (n = 0; n < in->nb_samples; n++) | ||||
|                 for (c = 0; c < in->channels; c++) { | ||||
|                 for (c = 0; c < in->ch_layout.nb_channels; c++) { | ||||
|                     in_data = (int16_t*)in->extended_data[c]; | ||||
|                     out_data[(n * in->channels) + c] = in_data[n]; | ||||
|                     out_data[(n * in->ch_layout.nb_channels) + c] = in_data[n]; | ||||
|                 } | ||||
|             break; | ||||
|         case AV_SAMPLE_FMT_S16: | ||||
|             in_data  = (int16_t*)in->data[0]; | ||||
|             for (n = 0; n < in->nb_samples * in->channels; n++) | ||||
|             for (n = 0; n < in->nb_samples * in->ch_layout.nb_channels; n++) | ||||
|                 out_data[n] = in_data[n]; | ||||
|             break; | ||||
|  | ||||
|         case AV_SAMPLE_FMT_S32P: | ||||
|             for (n = 0; n < in->nb_samples; n++) | ||||
|                 for (c = 0; c < in->channels; c++) { | ||||
|                 for (c = 0; c < in->ch_layout.nb_channels; c++) { | ||||
|                     in_data32 = (int32_t*)in->extended_data[c]; | ||||
|                     out_data[(n * in->channels) + c] = in_data32[n] >> a; | ||||
|                     out_data[(n * in->ch_layout.nb_channels) + c] = in_data32[n] >> a; | ||||
|                 } | ||||
|             break; | ||||
|         case AV_SAMPLE_FMT_S32: | ||||
|             in_data32  = (int32_t*)in->data[0]; | ||||
|             for (n = 0; n < in->nb_samples * in->channels; n++) | ||||
|             for (n = 0; n < in->nb_samples * in->ch_layout.nb_channels; n++) | ||||
|                 out_data[n] = in_data32[n] >> a; | ||||
|             break; | ||||
|     } | ||||
| @@ -1587,14 +1587,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         hdcd_detect_end(&s->detect, 2); | ||||
|     } else { | ||||
|         hdcd_detect_start(&s->detect); | ||||
|         for (c = 0; c < in->channels; c++) { | ||||
|             hdcd_process(s, &s->state[c], out_data + c, in->nb_samples, in->channels); | ||||
|         for (c = 0; c < in->ch_layout.nb_channels; c++) { | ||||
|             hdcd_process(s, &s->state[c], out_data + c, in->nb_samples, in->ch_layout.nb_channels); | ||||
|             hdcd_detect_onech(&s->state[c], &s->detect); | ||||
|         } | ||||
|         hdcd_detect_end(&s->detect, in->channels); | ||||
|         hdcd_detect_end(&s->detect, in->ch_layout.nb_channels); | ||||
|     } | ||||
|  | ||||
|     s->sample_count += in->nb_samples * in->channels; | ||||
|     s->sample_count += in->nb_samples * in->ch_layout.nb_channels; | ||||
|  | ||||
|     av_frame_free(&in); | ||||
|     return ff_filter_frame(outlink, out); | ||||
| @@ -1627,10 +1627,10 @@ static int query_formats(AVFilterContext *ctx) | ||||
|     }; | ||||
|     int ret; | ||||
|  | ||||
|     ret = ff_add_channel_layout(&layouts, AV_CH_LAYOUT_MONO); | ||||
|     ret = ff_add_channel_layout(&layouts, &(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|     ret = ff_add_channel_layout(&layouts, AV_CH_LAYOUT_STEREO); | ||||
|     ret = ff_add_channel_layout(&layouts, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|  | ||||
| @@ -1739,8 +1739,8 @@ static int config_input(AVFilterLink *inlink) { | ||||
|     av_log(ctx, AV_LOG_VERBOSE, "CDT period: %dms (%u samples @44100Hz)\n", | ||||
|         s->cdt_ms, s->state[0].sustain_reset ); | ||||
|  | ||||
|     if (inlink->channels != 2 && s->process_stereo) { | ||||
|         av_log(ctx, AV_LOG_WARNING, "process_stereo disabled (channels = %d)\n", inlink->channels); | ||||
|     if (inlink->ch_layout.nb_channels != 2 && s->process_stereo) { | ||||
|         av_log(ctx, AV_LOG_WARNING, "process_stereo disabled (channels = %d)\n", inlink->ch_layout.nb_channels); | ||||
|         s->process_stereo = 0; | ||||
|     } | ||||
|     av_log(ctx, AV_LOG_VERBOSE, "Process mode: %s\n", | ||||
|   | ||||
| @@ -82,18 +82,18 @@ typedef struct HeadphoneContext { | ||||
|         int          ir_len; | ||||
|         int          eof; | ||||
|     } hrir_in[64]; | ||||
|     uint64_t map_channel_layout; | ||||
|     uint64_t mapping[64]; | ||||
|     AVChannelLayout map_channel_layout; | ||||
|     enum AVChannel mapping[64]; | ||||
|     uint8_t  hrir_map[64]; | ||||
| } HeadphoneContext; | ||||
|  | ||||
| static int parse_channel_name(const char *arg, uint64_t *rchannel) | ||||
| static int parse_channel_name(const char *arg, enum AVChannel *rchannel) | ||||
| { | ||||
|     uint64_t layout = av_get_channel_layout(arg); | ||||
|     int channel = av_channel_from_string(arg); | ||||
|  | ||||
|     if (av_get_channel_layout_nb_channels(layout) != 1) | ||||
|     if (channel < 0 || channel >= 64) | ||||
|         return AVERROR(EINVAL); | ||||
|     *rchannel = layout; | ||||
|     *rchannel = channel; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| @@ -105,22 +105,22 @@ static void parse_map(AVFilterContext *ctx) | ||||
|  | ||||
|     p = s->map; | ||||
|     while ((arg = av_strtok(p, "|", &tokenizer))) { | ||||
|         uint64_t out_channel; | ||||
|         enum AVChannel out_channel; | ||||
|  | ||||
|         p = NULL; | ||||
|         if (parse_channel_name(arg, &out_channel)) { | ||||
|             av_log(ctx, AV_LOG_WARNING, "Failed to parse \'%s\' as channel name.\n", arg); | ||||
|             continue; | ||||
|         } | ||||
|         if (used_channels & out_channel) { | ||||
|         if (used_channels & (1ULL << out_channel)) { | ||||
|             av_log(ctx, AV_LOG_WARNING, "Ignoring duplicate channel '%s'.\n", arg); | ||||
|             continue; | ||||
|         } | ||||
|         used_channels        |= out_channel; | ||||
|         used_channels        |= (1ULL << out_channel); | ||||
|         s->mapping[s->nb_irs] = out_channel; | ||||
|         s->nb_irs++; | ||||
|     } | ||||
|     s->map_channel_layout = used_channels; | ||||
|     av_channel_layout_from_mask(&s->map_channel_layout, used_channels); | ||||
|  | ||||
|     if (s->hrir_fmt == HRIR_MULTI) | ||||
|         s->nb_hrir_inputs = 1; | ||||
| @@ -155,7 +155,7 @@ static int headphone_convolute(AVFilterContext *ctx, void *arg, int jobnr, int n | ||||
|     const int air_len = s->air_len; | ||||
|     const float *src = (const float *)in->data[0]; | ||||
|     float *dst = (float *)out->data[0]; | ||||
|     const int in_channels = in->channels; | ||||
|     const int in_channels = in->ch_layout.nb_channels; | ||||
|     const int buffer_length = s->buffer_length; | ||||
|     const uint32_t modulo = (uint32_t)buffer_length - 1; | ||||
|     float *buffer[64]; | ||||
| @@ -224,7 +224,7 @@ static int headphone_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr, | ||||
|     const int ir_len = s->ir_len; | ||||
|     const float *src = (const float *)in->data[0]; | ||||
|     float *dst = (float *)out->data[0]; | ||||
|     const int in_channels = in->channels; | ||||
|     const int in_channels = in->ch_layout.nb_channels; | ||||
|     const int buffer_length = s->buffer_length; | ||||
|     const uint32_t modulo = (uint32_t)buffer_length - 1; | ||||
|     AVComplexFloat *fft_out = s->out_fft[jobnr]; | ||||
| @@ -363,8 +363,8 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink) | ||||
| { | ||||
|     struct HeadphoneContext *s = ctx->priv; | ||||
|     const int ir_len = s->ir_len; | ||||
|     int nb_input_channels = ctx->inputs[0]->channels; | ||||
|     const int nb_hrir_channels = s->nb_hrir_inputs == 1 ? ctx->inputs[1]->channels : s->nb_hrir_inputs * 2; | ||||
|     int nb_input_channels = ctx->inputs[0]->ch_layout.nb_channels; | ||||
|     const int nb_hrir_channels = s->nb_hrir_inputs == 1 ? ctx->inputs[1]->ch_layout.nb_channels : s->nb_hrir_inputs * 2; | ||||
|     float gain_lin = expf((s->gain - 3 * nb_input_channels) / 20 * M_LN10); | ||||
|     AVFrame *frame; | ||||
|     int ret = 0; | ||||
| @@ -455,7 +455,7 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink) | ||||
|         ptr = (float *)frame->extended_data[0]; | ||||
|  | ||||
|         if (s->hrir_fmt == HRIR_STEREO) { | ||||
|             int idx = av_get_channel_layout_channel_index(s->map_channel_layout, | ||||
|             int idx = av_channel_layout_index_from_channel(&s->map_channel_layout, | ||||
|                                                           s->mapping[i]); | ||||
|             if (idx < 0) | ||||
|                 continue; | ||||
| @@ -484,10 +484,10 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink) | ||||
|                 s->tx_fn[0](s->fft[0], fft_out_r, fft_in_r, sizeof(float)); | ||||
|             } | ||||
|         } else { | ||||
|             int I, N = ctx->inputs[1]->channels; | ||||
|             int I, N = ctx->inputs[1]->ch_layout.nb_channels; | ||||
|  | ||||
|             for (k = 0; k < N / 2; k++) { | ||||
|                 int idx = av_get_channel_layout_channel_index(inlink->channel_layout, | ||||
|                 int idx = av_channel_layout_index_from_channel(&inlink->ch_layout, | ||||
|                                                               s->mapping[k]); | ||||
|                 if (idx < 0) | ||||
|                     continue; | ||||
| @@ -609,7 +609,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|     if (ret) | ||||
|         return ret; | ||||
|  | ||||
|     ret = ff_add_channel_layout(&stereo_layout, AV_CH_LAYOUT_STEREO); | ||||
|     ret = ff_add_channel_layout(&stereo_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO); | ||||
|     if (ret) | ||||
|         return ret; | ||||
|     ret = ff_channel_layouts_ref(stereo_layout, &ctx->outputs[0]->incfg.channel_layouts); | ||||
| @@ -639,13 +639,13 @@ static int config_input(AVFilterLink *inlink) | ||||
|     AVFilterContext *ctx = inlink->dst; | ||||
|     HeadphoneContext *s = ctx->priv; | ||||
|  | ||||
|     if (s->nb_irs < inlink->channels) { | ||||
|         av_log(ctx, AV_LOG_ERROR, "Number of HRIRs must be >= %d.\n", inlink->channels); | ||||
|     if (s->nb_irs < inlink->ch_layout.nb_channels) { | ||||
|         av_log(ctx, AV_LOG_ERROR, "Number of HRIRs must be >= %d.\n", inlink->ch_layout.nb_channels); | ||||
|         return AVERROR(EINVAL); | ||||
|     } | ||||
|  | ||||
|     s->lfe_channel = av_get_channel_layout_channel_index(inlink->channel_layout, | ||||
|                                                          AV_CH_LOW_FREQUENCY); | ||||
|     s->lfe_channel = av_channel_layout_index_from_channel(&inlink->ch_layout, | ||||
|                                                           AV_CHAN_LOW_FREQUENCY); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| @@ -701,13 +701,13 @@ static int config_output(AVFilterLink *outlink) | ||||
|     if (s->hrir_fmt == HRIR_MULTI) { | ||||
|         AVFilterLink *hrir_link = ctx->inputs[1]; | ||||
|  | ||||
|         if (hrir_link->channels < inlink->channels * 2) { | ||||
|             av_log(ctx, AV_LOG_ERROR, "Number of channels in HRIR stream must be >= %d.\n", inlink->channels * 2); | ||||
|         if (hrir_link->ch_layout.nb_channels < inlink->ch_layout.nb_channels * 2) { | ||||
|             av_log(ctx, AV_LOG_ERROR, "Number of channels in HRIR stream must be >= %d.\n", inlink->ch_layout.nb_channels * 2); | ||||
|             return AVERROR(EINVAL); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     s->gain_lfe = expf((s->gain - 3 * inlink->channels + s->lfe_gain) / 20 * M_LN10); | ||||
|     s->gain_lfe = expf((s->gain - 3 * inlink->ch_layout.nb_channels + s->lfe_gain) / 20 * M_LN10); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -24,6 +24,7 @@ | ||||
|  * a single output | ||||
|  */ | ||||
|  | ||||
| #include "libavutil/avassert.h" | ||||
| #include "libavutil/avstring.h" | ||||
| #include "libavutil/channel_layout.h" | ||||
| #include "libavutil/common.h" | ||||
| @@ -36,10 +37,10 @@ | ||||
| #include "internal.h" | ||||
|  | ||||
| typedef struct ChannelMap { | ||||
|     int input;                ///< input stream index | ||||
|     int       in_channel_idx; ///< index of in_channel in the input stream data | ||||
|     uint64_t  in_channel;     ///< layout describing the input channel | ||||
|     uint64_t out_channel;     ///< layout describing the output channel | ||||
|     int input;                     ///< input stream index | ||||
|     int            in_channel_idx; ///< index of in_channel in the input stream data | ||||
|     enum AVChannel in_channel; | ||||
|     enum AVChannel out_channel; | ||||
| } ChannelMap; | ||||
|  | ||||
| typedef struct JoinContext { | ||||
| @@ -48,11 +49,10 @@ typedef struct JoinContext { | ||||
|     int inputs; | ||||
|     char *map; | ||||
|     char    *channel_layout_str; | ||||
|     uint64_t channel_layout; | ||||
|     AVChannelLayout ch_layout; | ||||
|  | ||||
|     int64_t  eof_pts; | ||||
|  | ||||
|     int      nb_channels; | ||||
|     ChannelMap *channels; | ||||
|  | ||||
|     /** | ||||
| @@ -79,20 +79,21 @@ static const AVOption join_options[] = { | ||||
|     { NULL } | ||||
| }; | ||||
|  | ||||
| #define MAP_SEPARATOR '|' | ||||
|  | ||||
| AVFILTER_DEFINE_CLASS(join); | ||||
|  | ||||
| static int parse_maps(AVFilterContext *ctx) | ||||
| { | ||||
|     JoinContext *s = ctx->priv; | ||||
|     char separator = '|'; | ||||
|     char *cur      = s->map; | ||||
|  | ||||
|     while (cur && *cur) { | ||||
|         ChannelMap *map; | ||||
|         char *sep, *next, *p; | ||||
|         uint64_t in_channel = 0, out_channel = 0; | ||||
|         int input_idx, out_ch_idx, in_ch_idx; | ||||
|         int input_idx, out_ch_idx; | ||||
|  | ||||
|         next = strchr(cur, separator); | ||||
|         next = strchr(cur, MAP_SEPARATOR); | ||||
|         if (next) | ||||
|             *next++ = 0; | ||||
|  | ||||
| @@ -104,28 +105,16 @@ static int parse_maps(AVFilterContext *ctx) | ||||
|         } | ||||
|         *sep++ = 0; | ||||
|  | ||||
| #define PARSE_CHANNEL(str, var, inout)                                         \ | ||||
|         if (!(var = av_get_channel_layout(str))) {                             \ | ||||
|             av_log(ctx, AV_LOG_ERROR, "Invalid " inout " channel: %s.\n", str);\ | ||||
|             return AVERROR(EINVAL);                                            \ | ||||
|         }                                                                      \ | ||||
|         if (av_get_channel_layout_nb_channels(var) != 1) {                     \ | ||||
|             av_log(ctx, AV_LOG_ERROR, "Channel map describes more than one "   \ | ||||
|                    inout " channel.\n");                                       \ | ||||
|             return AVERROR(EINVAL);                                            \ | ||||
|         } | ||||
|  | ||||
|         /* parse output channel */ | ||||
|         PARSE_CHANNEL(sep, out_channel, "output"); | ||||
|         if (!(out_channel & s->channel_layout)) { | ||||
|             av_log(ctx, AV_LOG_ERROR, "Output channel '%s' is not present in " | ||||
|                    "requested channel layout.\n", sep); | ||||
|         out_ch_idx = av_channel_layout_index_from_string(&s->ch_layout, sep); | ||||
|         if (out_ch_idx < 0) { | ||||
|             av_log(ctx, AV_LOG_ERROR, "Invalid output channel: %s.\n", sep); | ||||
|             return AVERROR(EINVAL); | ||||
|         } | ||||
|  | ||||
|         out_ch_idx = av_get_channel_layout_channel_index(s->channel_layout, | ||||
|                                                          out_channel); | ||||
|         if (s->channels[out_ch_idx].input >= 0) { | ||||
|         map = &s->channels[out_ch_idx]; | ||||
|  | ||||
|         if (map->input >= 0) { | ||||
|             av_log(ctx, AV_LOG_ERROR, "Multiple maps for output channel " | ||||
|                    "'%s'.\n", sep); | ||||
|             return AVERROR(EINVAL); | ||||
| @@ -142,19 +131,21 @@ static int parse_maps(AVFilterContext *ctx) | ||||
|         if (*cur) | ||||
|             cur++; | ||||
|  | ||||
|         in_ch_idx = strtol(cur, &p, 0); | ||||
|         map->input          = input_idx; | ||||
|         map->in_channel     = AV_CHAN_NONE; | ||||
|         map->in_channel_idx = strtol(cur, &p, 0); | ||||
|         if (p == cur) { | ||||
|             /* channel specifier is not a number, | ||||
|              * try to parse as channel name */ | ||||
|             PARSE_CHANNEL(cur, in_channel, "input"); | ||||
|             /* channel specifier is not a number, handle as channel name */ | ||||
|             map->in_channel = av_channel_from_string(cur); | ||||
|             if (map->in_channel < 0) { | ||||
|                 av_log(ctx, AV_LOG_ERROR, "Invalid input channel: %s.\n", cur); | ||||
|                 return AVERROR(EINVAL); | ||||
|             } | ||||
|         } else if (map->in_channel_idx < 0) { | ||||
|             av_log(ctx, AV_LOG_ERROR, "Invalid input channel index: %d\n", map->in_channel_idx); | ||||
|             return AVERROR(EINVAL); | ||||
|         } | ||||
|  | ||||
|         s->channels[out_ch_idx].input      = input_idx; | ||||
|         if (in_channel) | ||||
|             s->channels[out_ch_idx].in_channel = in_channel; | ||||
|         else | ||||
|             s->channels[out_ch_idx].in_channel_idx = in_ch_idx; | ||||
|  | ||||
|         cur = next; | ||||
|     } | ||||
|     return 0; | ||||
| @@ -165,22 +156,37 @@ static av_cold int join_init(AVFilterContext *ctx) | ||||
|     JoinContext *s = ctx->priv; | ||||
|     int ret, i; | ||||
|  | ||||
|     if (!(s->channel_layout = av_get_channel_layout(s->channel_layout_str))) { | ||||
|         av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n", | ||||
|     ret = av_channel_layout_from_string(&s->ch_layout, s->channel_layout_str); | ||||
|     if (ret < 0) { | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
|         uint64_t mask; | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|         mask = av_get_channel_layout(s->channel_layout_str); | ||||
|         if (!mask) { | ||||
| #endif | ||||
|             av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n", | ||||
|                    s->channel_layout_str); | ||||
|             return AVERROR(EINVAL); | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
|         } | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
|         av_log(ctx, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n", | ||||
|                s->channel_layout_str); | ||||
|         return AVERROR(EINVAL); | ||||
|         av_channel_layout_from_mask(&s->ch_layout, mask); | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     s->nb_channels  = av_get_channel_layout_nb_channels(s->channel_layout); | ||||
|     s->channels     = av_calloc(s->nb_channels, sizeof(*s->channels)); | ||||
|     s->buffers      = av_calloc(s->nb_channels, sizeof(*s->buffers)); | ||||
|     s->channels     = av_calloc(s->ch_layout.nb_channels, sizeof(*s->channels)); | ||||
|     s->buffers      = av_calloc(s->ch_layout.nb_channels, sizeof(*s->buffers)); | ||||
|     s->input_frames = av_calloc(s->inputs, sizeof(*s->input_frames)); | ||||
|     if (!s->channels || !s->buffers|| !s->input_frames) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (i = 0; i < s->nb_channels; i++) { | ||||
|         s->channels[i].out_channel = av_channel_layout_extract_channel(s->channel_layout, i); | ||||
|         s->channels[i].input       = -1; | ||||
|     for (i = 0; i < s->ch_layout.nb_channels; i++) { | ||||
|         s->channels[i].out_channel    = av_channel_layout_channel_from_index(&s->ch_layout, i); | ||||
|         s->channels[i].input          = -1; | ||||
|         s->channels[i].in_channel_idx = -1; | ||||
|         s->channels[i].in_channel     = AV_CHAN_NONE; | ||||
|     } | ||||
|  | ||||
|     if ((ret = parse_maps(ctx)) < 0) | ||||
| @@ -221,7 +227,7 @@ static int join_query_formats(AVFilterContext *ctx) | ||||
|     AVFilterChannelLayouts *layouts = NULL; | ||||
|     int i, ret; | ||||
|  | ||||
|     if ((ret = ff_add_channel_layout(&layouts, s->channel_layout)) < 0 || | ||||
|     if ((ret = ff_add_channel_layout(&layouts, &s->ch_layout)) < 0 || | ||||
|         (ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts)) < 0) | ||||
|         return ret; | ||||
|  | ||||
| @@ -238,38 +244,55 @@ static int join_query_formats(AVFilterContext *ctx) | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| typedef struct ChannelList { | ||||
|     enum AVChannel *ch; | ||||
|     int          nb_ch; | ||||
| } ChannelList; | ||||
|  | ||||
| static enum AVChannel channel_list_pop(ChannelList *chl, int idx) | ||||
| { | ||||
|     enum AVChannel ret = chl->ch[idx]; | ||||
|     memcpy(chl->ch + idx, chl->ch + idx + 1, | ||||
|            (chl->nb_ch - idx - 1) * sizeof(*chl->ch)); | ||||
|     chl->nb_ch--; | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * If ch is present in chl, remove it from the list and return it. | ||||
|  * Otherwise return AV_CHAN_NONE. | ||||
|  */ | ||||
| static enum AVChannel channel_list_pop_ch(ChannelList *chl, enum AVChannel ch) | ||||
| { | ||||
|     for (int i = 0; i < chl->nb_ch; i++) | ||||
|         if (chl->ch[i] == ch) | ||||
|             return channel_list_pop(chl, i); | ||||
|     return AV_CHAN_NONE; | ||||
| } | ||||
|  | ||||
| static void guess_map_matching(AVFilterContext *ctx, ChannelMap *ch, | ||||
|                                uint64_t *inputs) | ||||
|                                ChannelList *inputs) | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     for (i = 0; i < ctx->nb_inputs; i++) { | ||||
|         AVFilterLink *link = ctx->inputs[i]; | ||||
|  | ||||
|         if (ch->out_channel & link->channel_layout && | ||||
|             !(ch->out_channel & inputs[i])) { | ||||
|         if (channel_list_pop_ch(&inputs[i], ch->out_channel) != AV_CHAN_NONE) { | ||||
|             ch->input      = i; | ||||
|             ch->in_channel = ch->out_channel; | ||||
|             inputs[i]     |= ch->out_channel; | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void guess_map_any(AVFilterContext *ctx, ChannelMap *ch, | ||||
|                           uint64_t *inputs) | ||||
|                           ChannelList *inputs) | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     for (i = 0; i < ctx->nb_inputs; i++) { | ||||
|         AVFilterLink *link = ctx->inputs[i]; | ||||
|  | ||||
|         if ((inputs[i] & link->channel_layout) != link->channel_layout) { | ||||
|             uint64_t unused = link->channel_layout & ~inputs[i]; | ||||
|  | ||||
|         if (inputs[i].nb_ch) { | ||||
|             ch->input      = i; | ||||
|             ch->in_channel = av_channel_layout_extract_channel(unused, 0); | ||||
|             inputs[i]     |= ch->in_channel; | ||||
|             ch->in_channel = channel_list_pop(&inputs[i], 0); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| @@ -279,81 +302,136 @@ static int join_config_output(AVFilterLink *outlink) | ||||
| { | ||||
|     AVFilterContext *ctx = outlink->src; | ||||
|     JoinContext       *s = ctx->priv; | ||||
|     uint64_t *inputs;   // nth element tracks which channels are used from nth input | ||||
|     // unused channels from each input | ||||
|     ChannelList *inputs_unused; | ||||
|     char inbuf[64], outbuf[64]; | ||||
|     int i, ret = 0; | ||||
|  | ||||
|     /* initialize inputs to user-specified mappings */ | ||||
|     if (!(inputs = av_calloc(ctx->nb_inputs, sizeof(*inputs)))) | ||||
|     /* initialize unused channel list for each input */ | ||||
|     inputs_unused = av_calloc(ctx->nb_inputs, sizeof(*inputs_unused)); | ||||
|     if (!inputs_unused) | ||||
|         return AVERROR(ENOMEM); | ||||
|     for (i = 0; i < s->nb_channels; i++) { | ||||
|     for (i = 0; i < ctx->nb_inputs; i++) { | ||||
|         AVFilterLink *inlink = ctx->inputs[i]; | ||||
|         AVChannelLayout *chl = &inlink->ch_layout; | ||||
|         ChannelList      *iu = &inputs_unused[i]; | ||||
|  | ||||
|         iu->nb_ch = chl->nb_channels; | ||||
|         iu->ch    = av_malloc_array(iu->nb_ch, sizeof(*iu->ch)); | ||||
|         if (!iu->ch) { | ||||
|             ret = AVERROR(ENOMEM); | ||||
|             goto fail; | ||||
|         } | ||||
|  | ||||
|         for (int ch_idx = 0; ch_idx < iu->nb_ch; ch_idx++) { | ||||
|             iu->ch[ch_idx] = av_channel_layout_channel_from_index(chl, ch_idx); | ||||
|             if (iu->ch[ch_idx] < 0) { | ||||
|                 /* no channel ordering information in this input, | ||||
|                  * so don't auto-map from it */ | ||||
|                 iu->nb_ch = 0; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* process user-specified maps */ | ||||
|     for (i = 0; i < s->ch_layout.nb_channels; i++) { | ||||
|         ChannelMap *ch = &s->channels[i]; | ||||
|         AVFilterLink *inlink; | ||||
|         AVChannelLayout *ichl; | ||||
|         ChannelList     *iu; | ||||
|  | ||||
|         if (ch->input < 0) | ||||
|             continue; | ||||
|  | ||||
|         inlink = ctx->inputs[ch->input]; | ||||
|         ichl   = &inlink->ch_layout; | ||||
|         iu     = &inputs_unused[ch->input]; | ||||
|  | ||||
|         if (!ch->in_channel) | ||||
|             ch->in_channel = av_channel_layout_extract_channel(inlink->channel_layout, | ||||
|                                                                ch->in_channel_idx); | ||||
|         /* get the index for the channels defined by name */ | ||||
|         if (ch->in_channel != AV_CHAN_NONE) { | ||||
|             ch->in_channel_idx = av_channel_layout_index_from_channel(ichl, ch->in_channel); | ||||
|             if (ch->in_channel_idx < 0) { | ||||
|                 av_channel_name(inbuf, sizeof(inbuf), ch->in_channel); | ||||
|                 av_log(ctx, AV_LOG_ERROR, "Requested channel %s is not present in " | ||||
|                        "input stream #%d.\n", inbuf, | ||||
|                        ch->input); | ||||
|                 ret = AVERROR(EINVAL); | ||||
|                 goto fail; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!(ch->in_channel & inlink->channel_layout)) { | ||||
|             av_log(ctx, AV_LOG_ERROR, "Requested channel %s is not present in " | ||||
|                    "input stream #%d.\n", av_get_channel_name(ch->in_channel), | ||||
|                    ch->input); | ||||
|         /* make sure channels specified by index actually exist */ | ||||
|         if (ch->in_channel_idx >= ichl->nb_channels) { | ||||
|             av_log(ctx, AV_LOG_ERROR, "Requested channel with index %d is not " | ||||
|                    "present in input stream #%d.\n", ch->in_channel_idx, ch->input); | ||||
|             ret = AVERROR(EINVAL); | ||||
|             goto fail; | ||||
|         } | ||||
|  | ||||
|         inputs[ch->input] |= ch->in_channel; | ||||
|         channel_list_pop_ch(iu, av_channel_layout_channel_from_index(ichl, ch->in_channel_idx)); | ||||
|     } | ||||
|  | ||||
|     /* guess channel maps when not explicitly defined */ | ||||
|     /* first try unused matching channels */ | ||||
|     for (i = 0; i < s->nb_channels; i++) { | ||||
|     for (i = 0; i < s->ch_layout.nb_channels; i++) { | ||||
|         ChannelMap *ch = &s->channels[i]; | ||||
|  | ||||
|         if (ch->input < 0) | ||||
|             guess_map_matching(ctx, ch, inputs); | ||||
|             guess_map_matching(ctx, ch, inputs_unused); | ||||
|     } | ||||
|  | ||||
|     /* if the above failed, try to find _any_ unused input channel */ | ||||
|     for (i = 0; i < s->nb_channels; i++) { | ||||
|     for (i = 0; i < s->ch_layout.nb_channels; i++) { | ||||
|         ChannelMap *ch = &s->channels[i]; | ||||
|  | ||||
|         if (ch->input < 0) | ||||
|             guess_map_any(ctx, ch, inputs); | ||||
|             guess_map_any(ctx, ch, inputs_unused); | ||||
|  | ||||
|         if (ch->input < 0) { | ||||
|             av_channel_name(outbuf, sizeof(outbuf), ch->out_channel); | ||||
|             av_log(ctx, AV_LOG_ERROR, "Could not find input channel for " | ||||
|                    "output channel '%s'.\n", | ||||
|                    av_get_channel_name(ch->out_channel)); | ||||
|                    outbuf); | ||||
|             ret = AVERROR(EINVAL); | ||||
|             goto fail; | ||||
|         } | ||||
|  | ||||
|         ch->in_channel_idx = av_get_channel_layout_channel_index(ctx->inputs[ch->input]->channel_layout, | ||||
|                                                                  ch->in_channel); | ||||
|         if (ch->in_channel != AV_CHAN_NONE) { | ||||
|             ch->in_channel_idx = av_channel_layout_index_from_channel( | ||||
|                 &ctx->inputs[ch->input]->ch_layout, ch->in_channel); | ||||
|         } | ||||
|  | ||||
|         av_assert0(ch->in_channel_idx >= 0); | ||||
|     } | ||||
|  | ||||
|     /* print mappings */ | ||||
|     av_log(ctx, AV_LOG_VERBOSE, "mappings: "); | ||||
|     for (i = 0; i < s->nb_channels; i++) { | ||||
|     for (i = 0; i < s->ch_layout.nb_channels; i++) { | ||||
|         ChannelMap *ch = &s->channels[i]; | ||||
|         av_log(ctx, AV_LOG_VERBOSE, "%d.%s => %s ", ch->input, | ||||
|                av_get_channel_name(ch->in_channel), | ||||
|                av_get_channel_name(ch->out_channel)); | ||||
|         AVFilterLink  *inlink = ctx->inputs[ch->input]; | ||||
|         AVChannelLayout *ichl = &inlink->ch_layout; | ||||
|         enum AVChannel  in_ch = av_channel_layout_channel_from_index( | ||||
|                                     ichl, ch->in_channel_idx); | ||||
|  | ||||
|         av_channel_name(inbuf, sizeof(inbuf), in_ch); | ||||
|         av_channel_name(outbuf, sizeof(outbuf), ch->out_channel); | ||||
|         av_log(ctx, AV_LOG_VERBOSE, "%d.%s(%d) => %s(%d) ", ch->input, | ||||
|                inbuf, ch->in_channel_idx, | ||||
|                outbuf, i); | ||||
|     } | ||||
|     av_log(ctx, AV_LOG_VERBOSE, "\n"); | ||||
|  | ||||
|     for (i = 0; i < ctx->nb_inputs; i++) { | ||||
|         if (!inputs[i]) | ||||
|         if (inputs_unused[i].nb_ch == ctx->inputs[i]->ch_layout.nb_channels) | ||||
|             av_log(ctx, AV_LOG_WARNING, "No channels are used from input " | ||||
|                    "stream %d.\n", i); | ||||
|     } | ||||
|  | ||||
| fail: | ||||
|     av_freep(&inputs); | ||||
|     for (i = 0; i < ctx->nb_inputs; i++) | ||||
|         av_freep(&inputs_unused[i].ch); | ||||
|     av_freep(&inputs_unused); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| @@ -382,8 +460,8 @@ static int try_push_frame(AVFilterContext *ctx) | ||||
|     frame = av_frame_alloc(); | ||||
|     if (!frame) | ||||
|         return AVERROR(ENOMEM); | ||||
|     if (s->nb_channels > FF_ARRAY_ELEMS(frame->data)) { | ||||
|         frame->extended_data = av_calloc(s->nb_channels, | ||||
|     if (s->ch_layout.nb_channels > FF_ARRAY_ELEMS(frame->data)) { | ||||
|         frame->extended_data = av_calloc(s->ch_layout.nb_channels, | ||||
|                                           sizeof(*frame->extended_data)); | ||||
|         if (!frame->extended_data) { | ||||
|             ret = AVERROR(ENOMEM); | ||||
| @@ -392,7 +470,7 @@ static int try_push_frame(AVFilterContext *ctx) | ||||
|     } | ||||
|  | ||||
|     /* copy the data pointers */ | ||||
|     for (i = 0; i < s->nb_channels; i++) { | ||||
|     for (i = 0; i < s->ch_layout.nb_channels; i++) { | ||||
|         ChannelMap *ch = &s->channels[i]; | ||||
|         AVFrame *cur   = s->input_frames[ch->input]; | ||||
|         AVBufferRef *buf; | ||||
| @@ -442,15 +520,21 @@ static int try_push_frame(AVFilterContext *ctx) | ||||
|     } | ||||
|  | ||||
|     frame->nb_samples     = nb_samples; | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     frame->channel_layout = outlink->channel_layout; | ||||
|     frame->channels       = outlink->channels; | ||||
|     frame->channels       = outlink->ch_layout.nb_channels; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|     if ((ret = av_channel_layout_copy(&frame->ch_layout, &outlink->ch_layout)) < 0) | ||||
|         return ret; | ||||
|     frame->sample_rate    = outlink->sample_rate; | ||||
|     frame->format         = outlink->format; | ||||
|     frame->pts            = s->input_frames[0]->pts; | ||||
|     frame->linesize[0]    = linesize; | ||||
|     if (frame->data != frame->extended_data) { | ||||
|         memcpy(frame->data, frame->extended_data, sizeof(*frame->data) * | ||||
|                FFMIN(FF_ARRAY_ELEMS(frame->data), s->nb_channels)); | ||||
|                FFMIN(FF_ARRAY_ELEMS(frame->data), s->ch_layout.nb_channels)); | ||||
|     } | ||||
|  | ||||
|     s->eof_pts = frame->pts + av_rescale_q(frame->nb_samples, | ||||
|   | ||||
| @@ -165,7 +165,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     AVFrame *out; | ||||
|     int i, h, p, new_out_samples; | ||||
|  | ||||
|     av_assert0(in->channels == (s->nb_inputs * s->nb_handles)); | ||||
|     av_assert0(in->ch_layout.nb_channels == (s->nb_inputs * s->nb_handles)); | ||||
|  | ||||
|     if (!s->nb_outputs || | ||||
|         (av_frame_is_writable(in) && s->nb_inputs == s->nb_outputs && | ||||
| @@ -181,7 +181,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         av_frame_copy_props(out, in); | ||||
|     } | ||||
|  | ||||
|     av_assert0(!s->nb_outputs || out->channels == (s->nb_outputs * s->nb_handles)); | ||||
|     av_assert0(!s->nb_outputs || out->ch_layout.nb_channels == (s->nb_outputs * s->nb_handles)); | ||||
|  | ||||
|     for (h = 0; h < s->nb_handles; h++) { | ||||
|         for (i = 0; i < s->nb_inputs; i++) { | ||||
| @@ -221,7 +221,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         return 0; | ||||
|     } else if (new_out_samples < out->nb_samples) { | ||||
|         int offset = out->nb_samples - new_out_samples; | ||||
|         for (int ch = 0; ch < out->channels; ch++) | ||||
|         for (int ch = 0; ch < out->ch_layout.nb_channels; ch++) | ||||
|             memmove(out->extended_data[ch], out->extended_data[ch] + sizeof(float) * offset, | ||||
|                     sizeof(float) * new_out_samples); | ||||
|         out->nb_samples = new_out_samples; | ||||
| @@ -318,7 +318,7 @@ static int connect_ports(AVFilterContext *ctx, AVFilterLink *link) | ||||
|     LADSPAContext *s = ctx->priv; | ||||
|     int i, j; | ||||
|  | ||||
|     s->nb_handles = s->nb_inputs == 1 && s->nb_outputs == 1 ? link->channels : 1; | ||||
|     s->nb_handles = s->nb_inputs == 1 && s->nb_outputs == 1 ? link->ch_layout.nb_channels : 1; | ||||
|     s->handles    = av_calloc(s->nb_handles, sizeof(*s->handles)); | ||||
|     if (!s->handles) | ||||
|         return AVERROR(ENOMEM); | ||||
| @@ -366,8 +366,13 @@ static int config_output(AVFilterLink *outlink) | ||||
|         outlink->format      = inlink->format; | ||||
|         outlink->sample_rate = inlink->sample_rate; | ||||
|         if (s->nb_inputs == s->nb_outputs) { | ||||
|             if ((ret = av_channel_layout_copy(&outlink->ch_layout, &inlink->ch_layout)) < 0) | ||||
|                 return ret; | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|             outlink->channel_layout = inlink->channel_layout; | ||||
|             outlink->channels = inlink->channels; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|         } | ||||
|  | ||||
|         ret = 0; | ||||
| @@ -681,7 +686,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|             return ret; | ||||
|     } else if (s->nb_inputs == 2 && s->nb_outputs == 2) { | ||||
|         layouts = NULL; | ||||
|         ret = ff_add_channel_layout(&layouts, AV_CH_LAYOUT_STEREO); | ||||
|         ret = ff_add_channel_layout(&layouts, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO); | ||||
|         if (ret < 0) | ||||
|             return ret; | ||||
|         ret = ff_set_common_channel_layouts(ctx, layouts); | ||||
| @@ -692,10 +697,10 @@ static int query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|         if (s->nb_inputs >= 1) { | ||||
|             AVFilterLink *inlink = ctx->inputs[0]; | ||||
|             uint64_t inlayout = FF_COUNT2LAYOUT(s->nb_inputs); | ||||
|             AVChannelLayout inlayout = FF_COUNT2LAYOUT(s->nb_inputs); | ||||
|  | ||||
|             layouts = NULL; | ||||
|             ret = ff_add_channel_layout(&layouts, inlayout); | ||||
|             ret = ff_add_channel_layout(&layouts, &inlayout); | ||||
|             if (ret < 0) | ||||
|                 return ret; | ||||
|             ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts); | ||||
| @@ -710,10 +715,10 @@ static int query_formats(AVFilterContext *ctx) | ||||
|         } | ||||
|  | ||||
|         if (s->nb_outputs >= 1) { | ||||
|             uint64_t outlayout = FF_COUNT2LAYOUT(s->nb_outputs); | ||||
|             AVChannelLayout outlayout = FF_COUNT2LAYOUT(s->nb_outputs); | ||||
|  | ||||
|             layouts = NULL; | ||||
|             ret = ff_add_channel_layout(&layouts, outlayout); | ||||
|             ret = ff_add_channel_layout(&layouts, &outlayout); | ||||
|             if (ret < 0) | ||||
|                 return ret; | ||||
|             ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts); | ||||
|   | ||||
| @@ -446,7 +446,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         double offset, offset_tp, true_peak; | ||||
|  | ||||
|         ff_ebur128_loudness_global(s->r128_in, &global); | ||||
|         for (c = 0; c < inlink->channels; c++) { | ||||
|         for (c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|             double tmp; | ||||
|             ff_ebur128_sample_peak(s->r128_in, c, &tmp); | ||||
|             if (c == 0 || tmp > true_peak) | ||||
| @@ -462,11 +462,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     switch (s->frame_type) { | ||||
|     case FIRST_FRAME: | ||||
|         for (n = 0; n < in->nb_samples; n++) { | ||||
|             for (c = 0; c < inlink->channels; c++) { | ||||
|             for (c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|                 buf[s->buf_index + c] = src[c]; | ||||
|             } | ||||
|             src += inlink->channels; | ||||
|             s->buf_index += inlink->channels; | ||||
|             src += inlink->ch_layout.nb_channels; | ||||
|             s->buf_index += inlink->ch_layout.nb_channels; | ||||
|         } | ||||
|  | ||||
|         ff_ebur128_loudness_shortterm(s->r128_in, &shortterm); | ||||
| @@ -486,19 +486,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         s->buf_index = | ||||
|         s->limiter_buf_index = 0; | ||||
|  | ||||
|         for (n = 0; n < (s->limiter_buf_size / inlink->channels); n++) { | ||||
|             for (c = 0; c < inlink->channels; c++) { | ||||
|         for (n = 0; n < (s->limiter_buf_size / inlink->ch_layout.nb_channels); n++) { | ||||
|             for (c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|                 limiter_buf[s->limiter_buf_index + c] = buf[s->buf_index + c] * s->delta[s->index] * s->offset; | ||||
|             } | ||||
|             s->limiter_buf_index += inlink->channels; | ||||
|             s->limiter_buf_index += inlink->ch_layout.nb_channels; | ||||
|             if (s->limiter_buf_index >= s->limiter_buf_size) | ||||
|                 s->limiter_buf_index -= s->limiter_buf_size; | ||||
|  | ||||
|             s->buf_index += inlink->channels; | ||||
|             s->buf_index += inlink->ch_layout.nb_channels; | ||||
|         } | ||||
|  | ||||
|         subframe_length = frame_size(inlink->sample_rate, 100); | ||||
|         true_peak_limiter(s, dst, subframe_length, inlink->channels); | ||||
|         true_peak_limiter(s, dst, subframe_length, inlink->ch_layout.nb_channels); | ||||
|         ff_ebur128_add_frames_double(s->r128_out, dst, subframe_length); | ||||
|  | ||||
|         s->pts += | ||||
| @@ -514,29 +514,29 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         gain_next = gaussian_filter(s, s->index + 11 < 30 ? s->index + 11 : s->index + 11 - 30); | ||||
|  | ||||
|         for (n = 0; n < in->nb_samples; n++) { | ||||
|             for (c = 0; c < inlink->channels; c++) { | ||||
|             for (c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|                 buf[s->prev_buf_index + c] = src[c]; | ||||
|                 limiter_buf[s->limiter_buf_index + c] = buf[s->buf_index + c] * (gain + (((double) n / in->nb_samples) * (gain_next - gain))) * s->offset; | ||||
|             } | ||||
|             src += inlink->channels; | ||||
|             src += inlink->ch_layout.nb_channels; | ||||
|  | ||||
|             s->limiter_buf_index += inlink->channels; | ||||
|             s->limiter_buf_index += inlink->ch_layout.nb_channels; | ||||
|             if (s->limiter_buf_index >= s->limiter_buf_size) | ||||
|                 s->limiter_buf_index -= s->limiter_buf_size; | ||||
|  | ||||
|             s->prev_buf_index += inlink->channels; | ||||
|             s->prev_buf_index += inlink->ch_layout.nb_channels; | ||||
|             if (s->prev_buf_index >= s->buf_size) | ||||
|                 s->prev_buf_index -= s->buf_size; | ||||
|  | ||||
|             s->buf_index += inlink->channels; | ||||
|             s->buf_index += inlink->ch_layout.nb_channels; | ||||
|             if (s->buf_index >= s->buf_size) | ||||
|                 s->buf_index -= s->buf_size; | ||||
|         } | ||||
|  | ||||
|         subframe_length = (frame_size(inlink->sample_rate, 100) - in->nb_samples) * inlink->channels; | ||||
|         subframe_length = (frame_size(inlink->sample_rate, 100) - in->nb_samples) * inlink->ch_layout.nb_channels; | ||||
|         s->limiter_buf_index = s->limiter_buf_index + subframe_length < s->limiter_buf_size ? s->limiter_buf_index + subframe_length : s->limiter_buf_index + subframe_length - s->limiter_buf_size; | ||||
|  | ||||
|         true_peak_limiter(s, dst, in->nb_samples, inlink->channels); | ||||
|         true_peak_limiter(s, dst, in->nb_samples, inlink->ch_layout.nb_channels); | ||||
|         ff_ebur128_add_frames_double(s->r128_out, dst, in->nb_samples); | ||||
|  | ||||
|         ff_ebur128_loudness_range(s->r128_in, &lra); | ||||
| @@ -576,39 +576,39 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         s->limiter_buf_index = 0; | ||||
|         src_index = 0; | ||||
|  | ||||
|         for (n = 0; n < s->limiter_buf_size / inlink->channels; n++) { | ||||
|             for (c = 0; c < inlink->channels; c++) { | ||||
|         for (n = 0; n < s->limiter_buf_size / inlink->ch_layout.nb_channels; n++) { | ||||
|             for (c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|                 s->limiter_buf[s->limiter_buf_index + c] = src[src_index + c] * gain * s->offset; | ||||
|             } | ||||
|             src_index += inlink->channels; | ||||
|             src_index += inlink->ch_layout.nb_channels; | ||||
|  | ||||
|             s->limiter_buf_index += inlink->channels; | ||||
|             s->limiter_buf_index += inlink->ch_layout.nb_channels; | ||||
|             if (s->limiter_buf_index >= s->limiter_buf_size) | ||||
|                 s->limiter_buf_index -= s->limiter_buf_size; | ||||
|         } | ||||
|  | ||||
|         subframe_length = frame_size(inlink->sample_rate, 100); | ||||
|         for (i = 0; i < in->nb_samples / subframe_length; i++) { | ||||
|             true_peak_limiter(s, dst, subframe_length, inlink->channels); | ||||
|             true_peak_limiter(s, dst, subframe_length, inlink->ch_layout.nb_channels); | ||||
|  | ||||
|             for (n = 0; n < subframe_length; n++) { | ||||
|                 for (c = 0; c < inlink->channels; c++) { | ||||
|                     if (src_index < (in->nb_samples * inlink->channels)) { | ||||
|                 for (c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|                     if (src_index < (in->nb_samples * inlink->ch_layout.nb_channels)) { | ||||
|                         limiter_buf[s->limiter_buf_index + c] = src[src_index + c] * gain * s->offset; | ||||
|                     } else { | ||||
|                         limiter_buf[s->limiter_buf_index + c] = 0.; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if (src_index < (in->nb_samples * inlink->channels)) | ||||
|                     src_index += inlink->channels; | ||||
|                 if (src_index < (in->nb_samples * inlink->ch_layout.nb_channels)) | ||||
|                     src_index += inlink->ch_layout.nb_channels; | ||||
|  | ||||
|                 s->limiter_buf_index += inlink->channels; | ||||
|                 s->limiter_buf_index += inlink->ch_layout.nb_channels; | ||||
|                 if (s->limiter_buf_index >= s->limiter_buf_size) | ||||
|                     s->limiter_buf_index -= s->limiter_buf_size; | ||||
|             } | ||||
|  | ||||
|             dst += (subframe_length * inlink->channels); | ||||
|             dst += (subframe_length * inlink->ch_layout.nb_channels); | ||||
|         } | ||||
|  | ||||
|         dst = (double *)out->data[0]; | ||||
| @@ -617,11 +617,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|  | ||||
|     case LINEAR_MODE: | ||||
|         for (n = 0; n < in->nb_samples; n++) { | ||||
|             for (c = 0; c < inlink->channels; c++) { | ||||
|             for (c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|                 dst[c] = src[c] * s->offset; | ||||
|             } | ||||
|             src += inlink->channels; | ||||
|             dst += inlink->channels; | ||||
|             src += inlink->ch_layout.nb_channels; | ||||
|             dst += inlink->ch_layout.nb_channels; | ||||
|         } | ||||
|  | ||||
|         dst = (double *)out->data[0]; | ||||
| @@ -650,7 +650,7 @@ static int request_frame(AVFilterLink *outlink) | ||||
|         int nb_samples, n, c, offset; | ||||
|         AVFrame *frame; | ||||
|  | ||||
|         nb_samples  = (s->buf_size / inlink->channels) - s->prev_nb_samples; | ||||
|         nb_samples  = (s->buf_size / inlink->ch_layout.nb_channels) - s->prev_nb_samples; | ||||
|         nb_samples -= (frame_size(inlink->sample_rate, 100) - s->prev_nb_samples); | ||||
|  | ||||
|         frame = ff_get_audio_buffer(outlink, nb_samples); | ||||
| @@ -661,16 +661,16 @@ static int request_frame(AVFilterLink *outlink) | ||||
|         buf = s->buf; | ||||
|         src = (double *)frame->data[0]; | ||||
|  | ||||
|         offset  = ((s->limiter_buf_size / inlink->channels) - s->prev_nb_samples) * inlink->channels; | ||||
|         offset -= (frame_size(inlink->sample_rate, 100) - s->prev_nb_samples) * inlink->channels; | ||||
|         offset  = ((s->limiter_buf_size / inlink->ch_layout.nb_channels) - s->prev_nb_samples) * inlink->ch_layout.nb_channels; | ||||
|         offset -= (frame_size(inlink->sample_rate, 100) - s->prev_nb_samples) * inlink->ch_layout.nb_channels; | ||||
|         s->buf_index = s->buf_index - offset < 0 ? s->buf_index - offset + s->buf_size : s->buf_index - offset; | ||||
|  | ||||
|         for (n = 0; n < nb_samples; n++) { | ||||
|             for (c = 0; c < inlink->channels; c++) { | ||||
|             for (c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|                 src[c] = buf[s->buf_index + c]; | ||||
|             } | ||||
|             src += inlink->channels; | ||||
|             s->buf_index += inlink->channels; | ||||
|             src += inlink->ch_layout.nb_channels; | ||||
|             s->buf_index += inlink->ch_layout.nb_channels; | ||||
|             if (s->buf_index >= s->buf_size) | ||||
|                 s->buf_index -= s->buf_size; | ||||
|         } | ||||
| @@ -720,30 +720,30 @@ static int config_input(AVFilterLink *inlink) | ||||
|     AVFilterContext *ctx = inlink->dst; | ||||
|     LoudNormContext *s = ctx->priv; | ||||
|  | ||||
|     s->r128_in = ff_ebur128_init(inlink->channels, inlink->sample_rate, 0, FF_EBUR128_MODE_I | FF_EBUR128_MODE_S | FF_EBUR128_MODE_LRA | FF_EBUR128_MODE_SAMPLE_PEAK); | ||||
|     s->r128_in = ff_ebur128_init(inlink->ch_layout.nb_channels, inlink->sample_rate, 0, FF_EBUR128_MODE_I | FF_EBUR128_MODE_S | FF_EBUR128_MODE_LRA | FF_EBUR128_MODE_SAMPLE_PEAK); | ||||
|     if (!s->r128_in) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     s->r128_out = ff_ebur128_init(inlink->channels, inlink->sample_rate, 0, FF_EBUR128_MODE_I | FF_EBUR128_MODE_S | FF_EBUR128_MODE_LRA | FF_EBUR128_MODE_SAMPLE_PEAK); | ||||
|     s->r128_out = ff_ebur128_init(inlink->ch_layout.nb_channels, inlink->sample_rate, 0, FF_EBUR128_MODE_I | FF_EBUR128_MODE_S | FF_EBUR128_MODE_LRA | FF_EBUR128_MODE_SAMPLE_PEAK); | ||||
|     if (!s->r128_out) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     if (inlink->channels == 1 && s->dual_mono) { | ||||
|     if (inlink->ch_layout.nb_channels == 1 && s->dual_mono) { | ||||
|         ff_ebur128_set_channel(s->r128_in,  0, FF_EBUR128_DUAL_MONO); | ||||
|         ff_ebur128_set_channel(s->r128_out, 0, FF_EBUR128_DUAL_MONO); | ||||
|     } | ||||
|  | ||||
|     s->buf_size = frame_size(inlink->sample_rate, 3000) * inlink->channels; | ||||
|     s->buf_size = frame_size(inlink->sample_rate, 3000) * inlink->ch_layout.nb_channels; | ||||
|     s->buf = av_malloc_array(s->buf_size, sizeof(*s->buf)); | ||||
|     if (!s->buf) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     s->limiter_buf_size = frame_size(inlink->sample_rate, 210) * inlink->channels; | ||||
|     s->limiter_buf_size = frame_size(inlink->sample_rate, 210) * inlink->ch_layout.nb_channels; | ||||
|     s->limiter_buf = av_malloc_array(s->buf_size, sizeof(*s->limiter_buf)); | ||||
|     if (!s->limiter_buf) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     s->prev_smp = av_malloc_array(inlink->channels, sizeof(*s->prev_smp)); | ||||
|     s->prev_smp = av_malloc_array(inlink->ch_layout.nb_channels, sizeof(*s->prev_smp)); | ||||
|     if (!s->prev_smp) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
| @@ -758,7 +758,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|     s->buf_index = | ||||
|     s->prev_buf_index = | ||||
|     s->limiter_buf_index = 0; | ||||
|     s->channels = inlink->channels; | ||||
|     s->channels = inlink->ch_layout.nb_channels; | ||||
|     s->index = 1; | ||||
|     s->limiter_state = OUT; | ||||
|     s->offset = pow(10., s->offset / 20.); | ||||
|   | ||||
| @@ -288,8 +288,14 @@ static int config_output(AVFilterLink *outlink) | ||||
|         outlink->format      = inlink->format; | ||||
|         outlink->sample_rate = sample_rate = inlink->sample_rate; | ||||
|         if (s->nb_inputs == s->nb_outputs) { | ||||
|             int ret; | ||||
|             if ((ret = av_channel_layout_copy(&outlink->ch_layout, &inlink->ch_layout)) < 0) | ||||
|                 return ret; | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|             outlink->channel_layout = inlink->channel_layout; | ||||
|             outlink->channels = inlink->channels; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|         } | ||||
|  | ||||
|     } else { | ||||
| @@ -496,7 +502,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|     if (s->nb_inputs == 2 && s->nb_outputs == 2) { | ||||
|         layouts = NULL; | ||||
|         ret = ff_add_channel_layout(&layouts, AV_CH_LAYOUT_STEREO); | ||||
|         ret = ff_add_channel_layout(&layouts, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO); | ||||
|         if (ret < 0) | ||||
|             return ret; | ||||
|         ret = ff_set_common_channel_layouts(ctx, layouts); | ||||
| @@ -505,10 +511,10 @@ static int query_formats(AVFilterContext *ctx) | ||||
|     } else { | ||||
|         if (s->nb_inputs >= 1) { | ||||
|             AVFilterLink *inlink = ctx->inputs[0]; | ||||
|             uint64_t inlayout = FF_COUNT2LAYOUT(s->nb_inputs); | ||||
|             AVChannelLayout inlayout = FF_COUNT2LAYOUT(s->nb_inputs); | ||||
|  | ||||
|             layouts = NULL; | ||||
|             ret = ff_add_channel_layout(&layouts, inlayout); | ||||
|             ret = ff_add_channel_layout(&layouts, &inlayout); | ||||
|             if (ret < 0) | ||||
|                 return ret; | ||||
|             ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts); | ||||
| @@ -523,10 +529,10 @@ static int query_formats(AVFilterContext *ctx) | ||||
|         } | ||||
|  | ||||
|         if (s->nb_outputs >= 1) { | ||||
|             uint64_t outlayout = FF_COUNT2LAYOUT(s->nb_outputs); | ||||
|             AVChannelLayout outlayout = FF_COUNT2LAYOUT(s->nb_outputs); | ||||
|  | ||||
|             layouts = NULL; | ||||
|             ret = ff_add_channel_layout(&layouts, outlayout); | ||||
|             ret = ff_add_channel_layout(&layouts, &outlayout); | ||||
|             if (ret < 0) | ||||
|                 return ret; | ||||
|             ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts); | ||||
|   | ||||
| @@ -302,7 +302,7 @@ static int crossover_setup(AVFilterLink *outlink, Crossover *p, double frequency | ||||
|     square_quadratic(x + 3, p->coefs + 5); | ||||
|     square_quadratic(x + 6, p->coefs + 10); | ||||
|  | ||||
|     p->previous = av_calloc(outlink->channels, sizeof(*p->previous)); | ||||
|     p->previous = av_calloc(outlink->ch_layout.nb_channels, sizeof(*p->previous)); | ||||
|     if (!p->previous) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
| @@ -350,13 +350,13 @@ static int config_output(AVFilterLink *outlink) | ||||
|             return AVERROR(EINVAL); | ||||
|         } | ||||
|  | ||||
|         s->bands[i].attack_rate = av_calloc(outlink->channels, sizeof(double)); | ||||
|         s->bands[i].decay_rate = av_calloc(outlink->channels, sizeof(double)); | ||||
|         s->bands[i].volume = av_calloc(outlink->channels, sizeof(double)); | ||||
|         s->bands[i].attack_rate = av_calloc(outlink->ch_layout.nb_channels, sizeof(double)); | ||||
|         s->bands[i].decay_rate = av_calloc(outlink->ch_layout.nb_channels, sizeof(double)); | ||||
|         s->bands[i].volume = av_calloc(outlink->ch_layout.nb_channels, sizeof(double)); | ||||
|         if (!s->bands[i].attack_rate || !s->bands[i].decay_rate || !s->bands[i].volume) | ||||
|             return AVERROR(ENOMEM); | ||||
|  | ||||
|         for (k = 0; k < FFMIN(nb_attacks / 2, outlink->channels); k++) { | ||||
|         for (k = 0; k < FFMIN(nb_attacks / 2, outlink->ch_layout.nb_channels); k++) { | ||||
|             char *tstr3 = av_strtok(p3, ",", &saveptr3); | ||||
|  | ||||
|             p3 = NULL; | ||||
| @@ -377,7 +377,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         for (ch = k; ch < outlink->channels; ch++) { | ||||
|         for (ch = k; ch < outlink->ch_layout.nb_channels; ch++) { | ||||
|             s->bands[i].attack_rate[ch] = s->bands[i].attack_rate[k - 1]; | ||||
|             s->bands[i].decay_rate[ch]  = s->bands[i].decay_rate[k - 1]; | ||||
|         } | ||||
| @@ -440,7 +440,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|                 sscanf(tstr2, "%lf", &initial_volume); | ||||
|                 initial_volume = pow(10.0, initial_volume / 20); | ||||
|  | ||||
|                 for (k = 0; k < outlink->channels; k++) { | ||||
|                 for (k = 0; k < outlink->ch_layout.nb_channels; k++) { | ||||
|                     s->bands[i].volume[k] = initial_volume; | ||||
|                 } | ||||
|  | ||||
| @@ -574,7 +574,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         s->band_samples = in->nb_samples; | ||||
|     } | ||||
|  | ||||
|     for (ch = 0; ch < outlink->channels; ch++) { | ||||
|     for (ch = 0; ch < outlink->ch_layout.nb_channels; ch++) { | ||||
|         double *a, *dst = (double *)out->extended_data[ch]; | ||||
|  | ||||
|         for (band = 0, abuf = in, bbuf = s->band_buf2, cbuf = s->band_buf1; band < s->nb_bands; band++) { | ||||
|   | ||||
| @@ -42,7 +42,7 @@ | ||||
| typedef struct PanContext { | ||||
|     const AVClass *class; | ||||
|     char *args; | ||||
|     int64_t out_channel_layout; | ||||
|     AVChannelLayout out_channel_layout; | ||||
|     double gain[MAX_CHANNELS][MAX_CHANNELS]; | ||||
|     int64_t need_renorm; | ||||
|     int need_renumber; | ||||
| @@ -65,23 +65,15 @@ static void skip_spaces(char **arg) | ||||
| static int parse_channel_name(char **arg, int *rchannel, int *rnamed) | ||||
| { | ||||
|     char buf[8]; | ||||
|     int len, i, channel_id = 0; | ||||
|     int64_t layout, layout0; | ||||
|     int len, channel_id = 0; | ||||
|  | ||||
|     skip_spaces(arg); | ||||
|     /* try to parse a channel name, e.g. "FL" */ | ||||
|     if (sscanf(*arg, "%7[A-Z]%n", buf, &len)) { | ||||
|         layout0 = layout = av_get_channel_layout(buf); | ||||
|         /* channel_id <- first set bit in layout */ | ||||
|         for (i = 32; i > 0; i >>= 1) { | ||||
|             if (layout >= (int64_t)1 << i) { | ||||
|                 channel_id += i; | ||||
|                 layout >>= i; | ||||
|             } | ||||
|         } | ||||
|         /* reject layouts that are not a single channel */ | ||||
|         if (channel_id >= MAX_CHANNELS || layout0 != (int64_t)1 << channel_id) | ||||
|             return AVERROR(EINVAL); | ||||
|         channel_id = av_channel_from_string(buf); | ||||
|         if (channel_id < 0) | ||||
|             return channel_id; | ||||
|  | ||||
|         *rchannel = channel_id; | ||||
|         *rnamed = 1; | ||||
|         *arg += len; | ||||
| @@ -137,17 +129,12 @@ static av_cold int init(AVFilterContext *ctx) | ||||
|             goto fail; | ||||
|         } | ||||
|         if (named) { | ||||
|             if (!((pan->out_channel_layout >> out_ch_id) & 1)) { | ||||
|             if ((out_ch_id = av_channel_layout_index_from_channel(&pan->out_channel_layout, out_ch_id)) < 0) { | ||||
|                 av_log(ctx, AV_LOG_ERROR, | ||||
|                        "Channel \"%.8s\" does not exist in the chosen layout\n", arg0); | ||||
|                 ret = AVERROR(EINVAL); | ||||
|                 goto fail; | ||||
|             } | ||||
|             /* get the channel number in the output channel layout: | ||||
|              * out_channel_layout & ((1 << out_ch_id) - 1) are all the | ||||
|              * channels that come before out_ch_id, | ||||
|              * so their count is the index of out_ch_id */ | ||||
|             out_ch_id = av_get_channel_layout_nb_channels(pan->out_channel_layout & (((int64_t)1 << out_ch_id) - 1)); | ||||
|         } | ||||
|         if (out_ch_id < 0 || out_ch_id >= pan->nb_output_channels) { | ||||
|             av_log(ctx, AV_LOG_ERROR, | ||||
| @@ -269,9 +256,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|     // outlink supports only requested output channel layout | ||||
|     layouts = NULL; | ||||
|     if ((ret = ff_add_channel_layout(&layouts, | ||||
|                           pan->out_channel_layout ? pan->out_channel_layout : | ||||
|                           FF_COUNT2LAYOUT(pan->nb_output_channels))) < 0) | ||||
|     if ((ret = ff_add_channel_layout(&layouts, &pan->out_channel_layout)) < 0) | ||||
|         return ret; | ||||
|     return ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts); | ||||
| } | ||||
| @@ -281,13 +266,13 @@ static int config_props(AVFilterLink *link) | ||||
|     AVFilterContext *ctx = link->dst; | ||||
|     PanContext *pan = ctx->priv; | ||||
|     char buf[1024], *cur; | ||||
|     int i, j, k, r; | ||||
|     int i, j, k, r, ret; | ||||
|     double t; | ||||
|  | ||||
|     if (pan->need_renumber) { | ||||
|         // input channels were given by their name: renumber them | ||||
|         for (i = j = 0; i < MAX_CHANNELS; i++) { | ||||
|             if ((link->channel_layout >> i) & 1) { | ||||
|             if (av_channel_layout_index_from_channel(&link->ch_layout, i) >= 0) { | ||||
|                 for (k = 0; k < pan->nb_output_channels; k++) | ||||
|                     pan->gain[k][j] = pan->gain[k][i]; | ||||
|                 j++; | ||||
| @@ -297,7 +282,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 (link->channels > MAX_CHANNELS || | ||||
|     if (link->ch_layout.nb_channels > MAX_CHANNELS || | ||||
|         pan->nb_output_channels > MAX_CHANNELS) { | ||||
|         av_log(ctx, AV_LOG_ERROR, | ||||
|                "af_pan supports a maximum of %d channels. " | ||||
| @@ -306,20 +291,12 @@ static int config_props(AVFilterLink *link) | ||||
|     } | ||||
|  | ||||
|     // init libswresample context | ||||
|     pan->swr = swr_alloc_set_opts(pan->swr, | ||||
|                                   pan->out_channel_layout, link->format, link->sample_rate, | ||||
|                                   link->channel_layout,    link->format, link->sample_rate, | ||||
|                                   0, ctx); | ||||
|     if (!pan->swr) | ||||
|     ret = swr_alloc_set_opts2(&pan->swr, | ||||
|                               &pan->out_channel_layout, link->format, link->sample_rate, | ||||
|                               &link->ch_layout, link->format, link->sample_rate, | ||||
|                               0, ctx); | ||||
|     if (ret < 0) | ||||
|         return AVERROR(ENOMEM); | ||||
|     if (!link->channel_layout) { | ||||
|         if (av_opt_set_int(pan->swr, "ich", link->channels, 0) < 0) | ||||
|             return AVERROR(EINVAL); | ||||
|     } | ||||
|     if (!pan->out_channel_layout) { | ||||
|         if (av_opt_set_int(pan->swr, "och", pan->nb_output_channels, 0) < 0) | ||||
|             return AVERROR(EINVAL); | ||||
|     } | ||||
|  | ||||
|     // gains are pure, init the channel mapping | ||||
|     if (pan->pure_gains) { | ||||
| @@ -327,7 +304,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 < link->channels; j++) { | ||||
|             for (j = 0; j < link->ch_layout.nb_channels; j++) { | ||||
|                 if (pan->gain[i][j]) { | ||||
|                     ch_id = j; | ||||
|                     break; | ||||
| @@ -336,7 +313,6 @@ static int config_props(AVFilterLink *link) | ||||
|             pan->channel_map[i] = ch_id; | ||||
|         } | ||||
|  | ||||
|         av_opt_set_int(pan->swr, "icl", pan->out_channel_layout, 0); | ||||
|         av_opt_set_int(pan->swr, "uch", pan->nb_output_channels, 0); | ||||
|         swr_set_channel_mapping(pan->swr, pan->channel_map); | ||||
|     } else { | ||||
| @@ -345,7 +321,7 @@ static int config_props(AVFilterLink *link) | ||||
|             if (!((pan->need_renorm >> i) & 1)) | ||||
|                 continue; | ||||
|             t = 0; | ||||
|             for (j = 0; j < link->channels; j++) | ||||
|             for (j = 0; j < link->ch_layout.nb_channels; j++) | ||||
|                 t += fabs(pan->gain[i][j]); | ||||
|             if (t > -1E-5 && t < 1E-5) { | ||||
|                 // t is almost 0 but not exactly, this is probably a mistake | ||||
| @@ -354,11 +330,9 @@ static int config_props(AVFilterLink *link) | ||||
|                            "Degenerate coefficients while renormalizing\n"); | ||||
|                 continue; | ||||
|             } | ||||
|             for (j = 0; j < link->channels; j++) | ||||
|             for (j = 0; j < link->ch_layout.nb_channels; j++) | ||||
|                 pan->gain[i][j] /= t; | ||||
|         } | ||||
|         av_opt_set_int(pan->swr, "icl", link->channel_layout, 0); | ||||
|         av_opt_set_int(pan->swr, "ocl", pan->out_channel_layout, 0); | ||||
|         swr_set_matrix(pan->swr, pan->gain[0], pan->gain[1] - pan->gain[0]); | ||||
|     } | ||||
|  | ||||
| @@ -369,7 +343,7 @@ static int config_props(AVFilterLink *link) | ||||
|     // summary | ||||
|     for (i = 0; i < pan->nb_output_channels; i++) { | ||||
|         cur = buf; | ||||
|         for (j = 0; j < link->channels; j++) { | ||||
|         for (j = 0; j < link->ch_layout.nb_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); | ||||
| @@ -405,8 +379,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) | ||||
|     swr_convert(pan->swr, outsamples->extended_data, n, | ||||
|                 (void *)insamples->extended_data, n); | ||||
|     av_frame_copy_props(outsamples, insamples); | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     outsamples->channel_layout = outlink->channel_layout; | ||||
|     outsamples->channels = outlink->channels; | ||||
|     outsamples->channels = outlink->ch_layout.nb_channels; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|     if ((ret = av_channel_layout_copy(&outsamples->ch_layout, &outlink->ch_layout)) < 0) | ||||
|         return ret; | ||||
|  | ||||
|     ret = ff_filter_frame(outlink, outsamples); | ||||
|     av_frame_free(&insamples); | ||||
|   | ||||
| @@ -327,7 +327,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|     if ((ret = ff_add_format                 (&formats, AV_SAMPLE_FMT_FLT  )) < 0 || | ||||
|         (ret = ff_set_common_formats         (ctx     , formats            )) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , AV_CH_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_set_common_channel_layouts (ctx     , layout             )) < 0) | ||||
|         return ret; | ||||
|  | ||||
|   | ||||
| @@ -135,7 +135,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|  | ||||
|     if (s->rbs) | ||||
|         rubberband_delete(s->rbs); | ||||
|     s->rbs = rubberband_new(inlink->sample_rate, inlink->channels, opts, 1. / s->tempo, s->pitch); | ||||
|     s->rbs = rubberband_new(inlink->sample_rate, inlink->ch_layout.nb_channels, opts, 1. / s->tempo, s->pitch); | ||||
|     if (!s->rbs) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|   | ||||
| @@ -177,13 +177,13 @@ static void compressor(SidechainCompressContext *s, | ||||
|         abs_sample = fabs(scsrc[0] * level_sc); | ||||
|  | ||||
|         if (s->link == 1) { | ||||
|             for (c = 1; c < sclink->channels; c++) | ||||
|             for (c = 1; c < sclink->ch_layout.nb_channels; c++) | ||||
|                 abs_sample = FFMAX(fabs(scsrc[c] * level_sc), abs_sample); | ||||
|         } else { | ||||
|             for (c = 1; c < sclink->channels; c++) | ||||
|             for (c = 1; c < sclink->ch_layout.nb_channels; c++) | ||||
|                 abs_sample += fabs(scsrc[c] * level_sc); | ||||
|  | ||||
|             abs_sample /= sclink->channels; | ||||
|             abs_sample /= sclink->ch_layout.nb_channels; | ||||
|         } | ||||
|  | ||||
|         if (s->detection) | ||||
| @@ -206,12 +206,12 @@ static void compressor(SidechainCompressContext *s, | ||||
|                                s->compressed_knee_stop, | ||||
|                                s->detection, s->mode); | ||||
|  | ||||
|         for (c = 0; c < inlink->channels; c++) | ||||
|         for (c = 0; c < inlink->ch_layout.nb_channels; c++) | ||||
|             dst[c] = src[c] * level_in * (gain * makeup * mix + (1. - mix)); | ||||
|  | ||||
|         src += inlink->channels; | ||||
|         dst += inlink->channels; | ||||
|         scsrc += sclink->channels; | ||||
|         src += inlink->ch_layout.nb_channels; | ||||
|         dst += inlink->ch_layout.nb_channels; | ||||
|         scsrc += sclink->ch_layout.nb_channels; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -325,8 +325,8 @@ static int config_output(AVFilterLink *outlink) | ||||
|  | ||||
|     outlink->time_base   = ctx->inputs[0]->time_base; | ||||
|  | ||||
|     s->fifo[0] = av_audio_fifo_alloc(ctx->inputs[0]->format, ctx->inputs[0]->channels, 1024); | ||||
|     s->fifo[1] = av_audio_fifo_alloc(ctx->inputs[1]->format, ctx->inputs[1]->channels, 1024); | ||||
|     s->fifo[0] = av_audio_fifo_alloc(ctx->inputs[0]->format, ctx->inputs[0]->ch_layout.nb_channels, 1024); | ||||
|     s->fifo[1] = av_audio_fifo_alloc(ctx->inputs[1]->format, ctx->inputs[1]->ch_layout.nb_channels, 1024); | ||||
|     if (!s->fifo[0] || !s->fifo[1]) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|   | ||||
| @@ -136,12 +136,12 @@ static void silencedetect_##name(SilenceDetectContext *s, AVFrame *insamples, | ||||
|                                  int nb_samples, int64_t nb_samples_notify,      \ | ||||
|                                  AVRational time_base)                           \ | ||||
| {                                                                                \ | ||||
|     const int channels = insamples->channels;                                    \ | ||||
|     const int channels = insamples->ch_layout.nb_channels;                       \ | ||||
|     const type noise = s->noise;                                                 \ | ||||
|                                                                                  \ | ||||
|     nb_samples /= channels;                                                      \ | ||||
|     for (int i = 0; i < nb_samples; i++) {                                       \ | ||||
|         for (int ch = 0; ch < insamples->channels; ch++) {                       \ | ||||
|         for (int ch = 0; ch < insamples->ch_layout.nb_channels; ch++) {          \ | ||||
|             const type *p = (const type *)insamples->extended_data[ch];          \ | ||||
|             update(s, insamples, p[i] < noise && p[i] > -noise,                  \ | ||||
|                    channels * i + ch,                                            \ | ||||
| @@ -166,7 +166,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|     SilenceDetectContext *s = ctx->priv; | ||||
|     int c; | ||||
|  | ||||
|     s->channels = inlink->channels; | ||||
|     s->channels = inlink->ch_layout.nb_channels; | ||||
|     s->duration = av_rescale(s->duration, inlink->sample_rate, AV_TIME_BASE); | ||||
|     s->independent_channels = s->mono ? s->channels : 1; | ||||
|     s->nb_null_samples = av_calloc(s->independent_channels, | ||||
| @@ -210,7 +210,7 @@ static int config_input(AVFilterLink *inlink) | ||||
| static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) | ||||
| { | ||||
|     SilenceDetectContext *s         = inlink->dst->priv; | ||||
|     const int nb_channels           = inlink->channels; | ||||
|     const int nb_channels           = inlink->ch_layout.nb_channels; | ||||
|     const int srate                 = inlink->sample_rate; | ||||
|     const int nb_samples            = insamples->nb_samples     * nb_channels; | ||||
|     const int64_t nb_samples_notify = s->duration * (s->mono ? 1 : nb_channels); | ||||
|   | ||||
| @@ -136,10 +136,10 @@ static void copy_double(SilenceRemoveContext *s, AVFrame *out, AVFrame *in, | ||||
|                         int ch, int out_offset, int in_offset) | ||||
| { | ||||
|     const double *srcp = (const double *)in->data[0]; | ||||
|     const double src = srcp[in->channels * in_offset + ch]; | ||||
|     const double src = srcp[in->ch_layout.nb_channels * in_offset + ch]; | ||||
|     double *dstp = (double *)out->data[0]; | ||||
|  | ||||
|     dstp[out->channels * out_offset + ch] = src; | ||||
|     dstp[out->ch_layout.nb_channels * out_offset + ch] = src; | ||||
| } | ||||
|  | ||||
| static void copy_doublep(SilenceRemoveContext *s, AVFrame *out, AVFrame *in, | ||||
| @@ -156,10 +156,10 @@ static void copy_float(SilenceRemoveContext *s, AVFrame *out, AVFrame *in, | ||||
|                        int ch, int out_offset, int in_offset) | ||||
| { | ||||
|     const float *srcp = (const float *)in->data[0]; | ||||
|     const float src = srcp[in->channels * in_offset + ch]; | ||||
|     const float src = srcp[in->ch_layout.nb_channels * in_offset + ch]; | ||||
|     float *dstp = (float *)out->data[0]; | ||||
|  | ||||
|     dstp[out->channels * out_offset + ch] = src; | ||||
|     dstp[out->ch_layout.nb_channels * out_offset + ch] = src; | ||||
| } | ||||
|  | ||||
| static void copy_floatp(SilenceRemoveContext *s, AVFrame *out, AVFrame *in, | ||||
| @@ -176,8 +176,8 @@ static double compute_peak_double(SilenceRemoveContext *s, AVFrame *frame, int c | ||||
| { | ||||
|     const double *samples = (const double *)frame->data[0]; | ||||
|     const double *wsamples = (const double *)s->window->data[0]; | ||||
|     double sample = samples[frame->channels * offset + ch]; | ||||
|     double wsample = wsamples[frame->channels * s->window_offset + ch]; | ||||
|     double sample = samples[frame->ch_layout.nb_channels * offset + ch]; | ||||
|     double wsample = wsamples[frame->ch_layout.nb_channels * s->window_offset + ch]; | ||||
|     double new_sum; | ||||
|  | ||||
|     new_sum  = s->sum; | ||||
| @@ -192,8 +192,8 @@ static void update_peak_double(SilenceRemoveContext *s, AVFrame *frame, int ch, | ||||
| { | ||||
|     const double *samples = (const double *)frame->data[0]; | ||||
|     double *wsamples = (double *)s->window->data[0]; | ||||
|     double sample = samples[frame->channels * offset + ch]; | ||||
|     double *wsample = &wsamples[frame->channels * s->window_offset + ch]; | ||||
|     double sample = samples[frame->ch_layout.nb_channels * offset + ch]; | ||||
|     double *wsample = &wsamples[frame->ch_layout.nb_channels * s->window_offset + ch]; | ||||
|  | ||||
|     s->sum -= *wsample; | ||||
|     s->sum  = fmax(s->sum, 0.); | ||||
| @@ -205,8 +205,8 @@ static double compute_peak_float(SilenceRemoveContext *s, AVFrame *frame, int ch | ||||
| { | ||||
|     const float *samples = (const float *)frame->data[0]; | ||||
|     const float *wsamples = (const float *)s->window->data[0]; | ||||
|     float sample = samples[frame->channels * offset + ch]; | ||||
|     float wsample = wsamples[frame->channels * s->window_offset + ch]; | ||||
|     float sample = samples[frame->ch_layout.nb_channels * offset + ch]; | ||||
|     float wsample = wsamples[frame->ch_layout.nb_channels * s->window_offset + ch]; | ||||
|     float new_sum; | ||||
|  | ||||
|     new_sum  = s->sum; | ||||
| @@ -221,8 +221,8 @@ static void update_peak_float(SilenceRemoveContext *s, AVFrame *frame, int ch, i | ||||
| { | ||||
|     const float *samples = (const float *)frame->data[0]; | ||||
|     float *wsamples = (float *)s->window->data[0]; | ||||
|     float sample = samples[frame->channels * offset + ch]; | ||||
|     float *wsample = &wsamples[frame->channels * s->window_offset + ch]; | ||||
|     float sample = samples[frame->ch_layout.nb_channels * offset + ch]; | ||||
|     float *wsample = &wsamples[frame->ch_layout.nb_channels * s->window_offset + ch]; | ||||
|  | ||||
|     s->sum -= *wsample; | ||||
|     s->sum  = fmaxf(s->sum, 0.f); | ||||
| @@ -234,8 +234,8 @@ static double compute_rms_double(SilenceRemoveContext *s, AVFrame *frame, int ch | ||||
| { | ||||
|     const double *samples = (const double *)frame->data[0]; | ||||
|     const double *wsamples = (const double *)s->window->data[0]; | ||||
|     double sample = samples[frame->channels * offset + ch]; | ||||
|     double wsample = wsamples[frame->channels * s->window_offset + ch]; | ||||
|     double sample = samples[frame->ch_layout.nb_channels * offset + ch]; | ||||
|     double wsample = wsamples[frame->ch_layout.nb_channels * s->window_offset + ch]; | ||||
|     double new_sum; | ||||
|  | ||||
|     new_sum  = s->sum; | ||||
| @@ -251,8 +251,8 @@ static void update_rms_double(SilenceRemoveContext *s, AVFrame *frame, int ch, i | ||||
| { | ||||
|     const double *samples = (const double *)frame->data[0]; | ||||
|     double *wsamples = (double *)s->window->data[0]; | ||||
|     double sample = samples[frame->channels * offset + ch]; | ||||
|     double *wsample = &wsamples[frame->channels * s->window_offset + ch]; | ||||
|     double sample = samples[frame->ch_layout.nb_channels * offset + ch]; | ||||
|     double *wsample = &wsamples[frame->ch_layout.nb_channels * s->window_offset + ch]; | ||||
|  | ||||
|     s->sum -= *wsample; | ||||
|     s->sum  = fmax(s->sum, 0.); | ||||
| @@ -264,8 +264,8 @@ static double compute_rms_float(SilenceRemoveContext *s, AVFrame *frame, int ch, | ||||
| { | ||||
|     const float *samples = (const float *)frame->data[0]; | ||||
|     const float *wsamples = (const float *)s->window->data[0]; | ||||
|     float sample = samples[frame->channels * offset + ch]; | ||||
|     float wsample = wsamples[frame->channels * s->window_offset + ch]; | ||||
|     float sample = samples[frame->ch_layout.nb_channels * offset + ch]; | ||||
|     float wsample = wsamples[frame->ch_layout.nb_channels * s->window_offset + ch]; | ||||
|     float new_sum; | ||||
|  | ||||
|     new_sum  = s->sum; | ||||
| @@ -280,9 +280,9 @@ static double compute_rms_float(SilenceRemoveContext *s, AVFrame *frame, int ch, | ||||
| static void update_rms_float(SilenceRemoveContext *s, AVFrame *frame, int ch, int offset) | ||||
| { | ||||
|     const float *samples = (const float *)frame->data[0]; | ||||
|     float sample = samples[frame->channels * offset + ch]; | ||||
|     float sample = samples[frame->ch_layout.nb_channels * offset + ch]; | ||||
|     float *wsamples = (float *)s->window->data[0]; | ||||
|     float *wsample = &wsamples[frame->channels * s->window_offset + ch]; | ||||
|     float *wsample = &wsamples[frame->ch_layout.nb_channels * s->window_offset + ch]; | ||||
|  | ||||
|     s->sum -= *wsample; | ||||
|     s->sum  = fmaxf(s->sum, 0.f); | ||||
| @@ -423,7 +423,7 @@ static av_cold int init(AVFilterContext *ctx) | ||||
| static void clear_window(SilenceRemoveContext *s) | ||||
| { | ||||
|     av_samples_set_silence(s->window->extended_data, 0, s->window_duration, | ||||
|                            s->window->channels, s->window->format); | ||||
|                            s->window->ch_layout.nb_channels, s->window->format); | ||||
|  | ||||
|     s->window_offset = 0; | ||||
|     s->sum = 0; | ||||
| @@ -543,7 +543,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|         return AVERROR_BUG; | ||||
|     } | ||||
|  | ||||
|     s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, 1024); | ||||
|     s->fifo = av_audio_fifo_alloc(inlink->format, inlink->ch_layout.nb_channels, 1024); | ||||
|     if (!s->fifo) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
| @@ -576,14 +576,14 @@ static void flush(SilenceRemoveContext *s, | ||||
|         av_samples_copy(silence->extended_data, s->stop_silence_hold->extended_data, 0, | ||||
|                         s->stop_silence_offset, | ||||
|                         s->stop_silence_end - s->stop_silence_offset, | ||||
|                         outlink->channels, outlink->format); | ||||
|                         outlink->ch_layout.nb_channels, outlink->format); | ||||
|     } | ||||
|  | ||||
|     if (s->stop_silence_offset > 0) { | ||||
|         av_samples_copy(silence->extended_data, s->stop_silence_hold->extended_data, | ||||
|                         s->stop_silence_end - s->stop_silence_offset, | ||||
|                         0, s->stop_silence_offset, | ||||
|                         outlink->channels, outlink->format); | ||||
|                         outlink->ch_layout.nb_channels, outlink->format); | ||||
|     } | ||||
|  | ||||
|     s->stop_silence_offset = 0; | ||||
| @@ -617,18 +617,18 @@ silence_trim: | ||||
|         for (i = 0; i < nbs; i++) { | ||||
|             if (s->start_mode == T_ANY) { | ||||
|                 threshold = 0; | ||||
|                 for (j = 0; j < outlink->channels; j++) { | ||||
|                 for (j = 0; j < outlink->ch_layout.nb_channels; j++) { | ||||
|                     threshold |= s->compute(s, in, j, nb_samples_read) > s->start_threshold; | ||||
|                 } | ||||
|             } else { | ||||
|                 threshold = 1; | ||||
|                 for (j = 0; j < outlink->channels; j++) { | ||||
|                 for (j = 0; j < outlink->ch_layout.nb_channels; j++) { | ||||
|                     threshold &= s->compute(s, in, j, nb_samples_read) > s->start_threshold; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (threshold) { | ||||
|                 for (j = 0; j < outlink->channels; j++) { | ||||
|                 for (j = 0; j < outlink->ch_layout.nb_channels; j++) { | ||||
|                     s->update(s, in, j, nb_samples_read); | ||||
|                     s->copy(s, s->start_holdoff, in, j, s->start_holdoff_end, nb_samples_read); | ||||
|                 } | ||||
| @@ -656,7 +656,7 @@ silence_trim: | ||||
|                 s->start_holdoff_end = 0; | ||||
|                 s->one_period++; | ||||
|  | ||||
|                 for (j = 0; j < outlink->channels; j++) { | ||||
|                 for (j = 0; j < outlink->ch_layout.nb_channels; j++) { | ||||
|                     s->update(s, in, j, nb_samples_read); | ||||
|                     if (s->start_silence) | ||||
|                         s->copy(s, s->start_silence_hold, in, j, s->start_silence_offset, nb_samples_read); | ||||
| @@ -694,21 +694,21 @@ silence_trim_flush: | ||||
|                 av_samples_copy(out->extended_data, s->start_silence_hold->extended_data, 0, | ||||
|                                 s->start_silence_offset, | ||||
|                                 s->start_silence_end - s->start_silence_offset, | ||||
|                                 outlink->channels, outlink->format); | ||||
|                                 outlink->ch_layout.nb_channels, outlink->format); | ||||
|             } | ||||
|  | ||||
|             if (s->start_silence_offset > 0) { | ||||
|                 av_samples_copy(out->extended_data, s->start_silence_hold->extended_data, | ||||
|                                 s->start_silence_end - s->start_silence_offset, | ||||
|                                 0, s->start_silence_offset, | ||||
|                                 outlink->channels, outlink->format); | ||||
|                                 outlink->ch_layout.nb_channels, outlink->format); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         av_samples_copy(out->extended_data, s->start_holdoff->extended_data, | ||||
|                         s->start_silence_end, | ||||
|                         s->start_holdoff_offset, nbs, | ||||
|                         outlink->channels, outlink->format); | ||||
|                         outlink->ch_layout.nb_channels, outlink->format); | ||||
|  | ||||
|         s->start_holdoff_offset += nbs; | ||||
|  | ||||
| @@ -741,12 +741,12 @@ silence_copy: | ||||
|             for (i = 0; i < nbs; i++) { | ||||
|                 if (s->stop_mode == T_ANY) { | ||||
|                     threshold = 0; | ||||
|                     for (j = 0; j < outlink->channels; j++) { | ||||
|                     for (j = 0; j < outlink->ch_layout.nb_channels; j++) { | ||||
|                         threshold |= s->compute(s, in, j, nb_samples_read) > s->stop_threshold; | ||||
|                     } | ||||
|                 } else { | ||||
|                     threshold = 1; | ||||
|                     for (j = 0; j < outlink->channels; j++) { | ||||
|                     for (j = 0; j < outlink->ch_layout.nb_channels; j++) { | ||||
|                         threshold &= s->compute(s, in, j, nb_samples_read) > s->stop_threshold; | ||||
|                     } | ||||
|                 } | ||||
| @@ -757,7 +757,7 @@ silence_copy: | ||||
|                     s->one_period++; | ||||
|                     goto silence_copy_flush; | ||||
|                 } else if (threshold) { | ||||
|                     for (j = 0; j < outlink->channels; j++) { | ||||
|                     for (j = 0; j < outlink->ch_layout.nb_channels; j++) { | ||||
|                         s->update(s, in, j, nb_samples_read); | ||||
|                         s->copy(s, out, in, j, nb_samples_written, nb_samples_read); | ||||
|                     } | ||||
| @@ -769,7 +769,7 @@ silence_copy: | ||||
|                     nb_samples_written++; | ||||
|                     s->one_period++; | ||||
|                 } else if (!threshold) { | ||||
|                     for (j = 0; j < outlink->channels; j++) { | ||||
|                     for (j = 0; j < outlink->ch_layout.nb_channels; j++) { | ||||
|                         s->update(s, in, j, nb_samples_read); | ||||
|                         if (s->stop_silence) | ||||
|                             s->copy(s, s->stop_silence_hold, in, j, s->stop_silence_offset, nb_samples_read); | ||||
| @@ -827,7 +827,7 @@ silence_copy: | ||||
|             av_samples_copy(out->extended_data, in->extended_data, | ||||
|                             nb_samples_written, | ||||
|                             nb_samples_read, nbs, | ||||
|                             outlink->channels, outlink->format); | ||||
|                             outlink->ch_layout.nb_channels, outlink->format); | ||||
|  | ||||
|             av_audio_fifo_write(s->fifo, (void **)out->extended_data, out->nb_samples); | ||||
|             av_frame_free(&out); | ||||
| @@ -848,7 +848,7 @@ silence_copy_flush: | ||||
|  | ||||
|         av_samples_copy(out->extended_data, s->stop_holdoff->extended_data, 0, | ||||
|                         s->stop_holdoff_offset, nbs, | ||||
|                         outlink->channels, outlink->format); | ||||
|                         outlink->ch_layout.nb_channels, outlink->format); | ||||
|  | ||||
|         s->stop_holdoff_offset += nbs; | ||||
|  | ||||
| @@ -909,7 +909,7 @@ static int request_frame(AVFilterLink *outlink) | ||||
|  | ||||
|             av_samples_copy(frame->extended_data, s->stop_holdoff->extended_data, 0, | ||||
|                             s->stop_holdoff_offset, nbs, | ||||
|                             outlink->channels, outlink->format); | ||||
|                             outlink->ch_layout.nb_channels, outlink->format); | ||||
|  | ||||
|             frame->pts = s->next_pts; | ||||
|             s->next_pts += av_rescale_q(frame->nb_samples, | ||||
|   | ||||
| @@ -187,25 +187,18 @@ static int preload_sofa(AVFilterContext *ctx, char *filename, int *samplingrate) | ||||
|  | ||||
| static int parse_channel_name(AVFilterContext *ctx, char **arg, int *rchannel) | ||||
| { | ||||
|     int len, i, channel_id = 0; | ||||
|     int64_t layout, layout0; | ||||
|     int len; | ||||
|     enum AVChannel channel_id = 0; | ||||
|     char buf[8] = {0}; | ||||
|  | ||||
|     /* try to parse a channel name, e.g. "FL" */ | ||||
|     if (av_sscanf(*arg, "%7[A-Z]%n", buf, &len)) { | ||||
|         layout0 = layout = av_get_channel_layout(buf); | ||||
|         /* channel_id <- first set bit in layout */ | ||||
|         for (i = 32; i > 0; i >>= 1) { | ||||
|             if (layout >= 1LL << i) { | ||||
|                 channel_id += i; | ||||
|                 layout >>= i; | ||||
|             } | ||||
|         } | ||||
|         /* reject layouts that are not a single channel */ | ||||
|         if (channel_id >= 64 || layout0 != 1LL << channel_id) { | ||||
|         channel_id = av_channel_from_string(buf); | ||||
|         if (channel_id < 0 || channel_id >= 64) { | ||||
|             av_log(ctx, AV_LOG_WARNING, "Failed to parse \'%s\' as channel name.\n", buf); | ||||
|             return AVERROR(EINVAL); | ||||
|         } | ||||
|  | ||||
|         *rchannel = channel_id; | ||||
|         *arg += len; | ||||
|         return 0; | ||||
| @@ -221,7 +214,7 @@ static int parse_channel_name(AVFilterContext *ctx, char **arg, int *rchannel) | ||||
|     return AVERROR(EINVAL); | ||||
| } | ||||
|  | ||||
| static void parse_speaker_pos(AVFilterContext *ctx, int64_t in_channel_layout) | ||||
| static void parse_speaker_pos(AVFilterContext *ctx) | ||||
| { | ||||
|     SOFAlizerContext *s = ctx->priv; | ||||
|     char *arg, *tokenizer, *p, *args = av_strdup(s->speakers_pos); | ||||
| @@ -256,10 +249,10 @@ static int get_speaker_pos(AVFilterContext *ctx, | ||||
|                            float *speaker_azim, float *speaker_elev) | ||||
| { | ||||
|     struct SOFAlizerContext *s = ctx->priv; | ||||
|     uint64_t channels_layout = ctx->inputs[0]->channel_layout; | ||||
|     AVChannelLayout *channel_layout = &ctx->inputs[0]->ch_layout; | ||||
|     float azim[64] = { 0 }; | ||||
|     float elev[64] = { 0 }; | ||||
|     int m, ch, n_conv = ctx->inputs[0]->channels; /* get no. input channels */ | ||||
|     int m, ch, n_conv = ctx->inputs[0]->ch_layout.nb_channels; /* get no. input channels */ | ||||
|  | ||||
|     if (n_conv < 0 || n_conv > 64) | ||||
|         return AVERROR(EINVAL); | ||||
| @@ -267,46 +260,45 @@ static int get_speaker_pos(AVFilterContext *ctx, | ||||
|     s->lfe_channel = -1; | ||||
|  | ||||
|     if (s->speakers_pos) | ||||
|         parse_speaker_pos(ctx, channels_layout); | ||||
|         parse_speaker_pos(ctx); | ||||
|  | ||||
|     /* set speaker positions according to input channel configuration: */ | ||||
|     for (m = 0, ch = 0; ch < n_conv && m < 64; m++) { | ||||
|         uint64_t mask = channels_layout & (1ULL << m); | ||||
|         int chan = av_channel_layout_channel_from_index(channel_layout, m); | ||||
|  | ||||
|         switch (mask) { | ||||
|         case AV_CH_FRONT_LEFT:            azim[ch] =  30;      break; | ||||
|         case AV_CH_FRONT_RIGHT:           azim[ch] = 330;      break; | ||||
|         case AV_CH_FRONT_CENTER:          azim[ch] =   0;      break; | ||||
|         case AV_CH_LOW_FREQUENCY: | ||||
|         case AV_CH_LOW_FREQUENCY_2:       s->lfe_channel = ch; break; | ||||
|         case AV_CH_BACK_LEFT:             azim[ch] = 150;      break; | ||||
|         case AV_CH_BACK_RIGHT:            azim[ch] = 210;      break; | ||||
|         case AV_CH_BACK_CENTER:           azim[ch] = 180;      break; | ||||
|         case AV_CH_SIDE_LEFT:             azim[ch] =  90;      break; | ||||
|         case AV_CH_SIDE_RIGHT:            azim[ch] = 270;      break; | ||||
|         case AV_CH_FRONT_LEFT_OF_CENTER:  azim[ch] =  15;      break; | ||||
|         case AV_CH_FRONT_RIGHT_OF_CENTER: azim[ch] = 345;      break; | ||||
|         case AV_CH_TOP_CENTER:            azim[ch] =   0; | ||||
|         switch (chan) { | ||||
|         case AV_CHAN_FRONT_LEFT:          azim[ch] =  30;      break; | ||||
|         case AV_CHAN_FRONT_RIGHT:         azim[ch] = 330;      break; | ||||
|         case AV_CHAN_FRONT_CENTER:        azim[ch] =   0;      break; | ||||
|         case AV_CHAN_LOW_FREQUENCY: | ||||
|         case AV_CHAN_LOW_FREQUENCY_2:     s->lfe_channel = ch; break; | ||||
|         case AV_CHAN_BACK_LEFT:           azim[ch] = 150;      break; | ||||
|         case AV_CHAN_BACK_RIGHT:          azim[ch] = 210;      break; | ||||
|         case AV_CHAN_BACK_CENTER:         azim[ch] = 180;      break; | ||||
|         case AV_CHAN_SIDE_LEFT:           azim[ch] =  90;      break; | ||||
|         case AV_CHAN_SIDE_RIGHT:          azim[ch] = 270;      break; | ||||
|         case AV_CHAN_FRONT_LEFT_OF_CENTER:  azim[ch] =  15;    break; | ||||
|         case AV_CHAN_FRONT_RIGHT_OF_CENTER: azim[ch] = 345;    break; | ||||
|         case AV_CHAN_TOP_CENTER:          azim[ch] =   0; | ||||
|                                           elev[ch] =  90;      break; | ||||
|         case AV_CH_TOP_FRONT_LEFT:        azim[ch] =  30; | ||||
|         case AV_CHAN_TOP_FRONT_LEFT:      azim[ch] =  30; | ||||
|                                           elev[ch] =  45;      break; | ||||
|         case AV_CH_TOP_FRONT_CENTER:      azim[ch] =   0; | ||||
|         case AV_CHAN_TOP_FRONT_CENTER:    azim[ch] =   0; | ||||
|                                           elev[ch] =  45;      break; | ||||
|         case AV_CH_TOP_FRONT_RIGHT:       azim[ch] = 330; | ||||
|         case AV_CHAN_TOP_FRONT_RIGHT:     azim[ch] = 330; | ||||
|                                           elev[ch] =  45;      break; | ||||
|         case AV_CH_TOP_BACK_LEFT:         azim[ch] = 150; | ||||
|         case AV_CHAN_TOP_BACK_LEFT:       azim[ch] = 150; | ||||
|                                           elev[ch] =  45;      break; | ||||
|         case AV_CH_TOP_BACK_RIGHT:        azim[ch] = 210; | ||||
|         case AV_CHAN_TOP_BACK_RIGHT:      azim[ch] = 210; | ||||
|                                           elev[ch] =  45;      break; | ||||
|         case AV_CH_TOP_BACK_CENTER:       azim[ch] = 180; | ||||
|         case AV_CHAN_TOP_BACK_CENTER:     azim[ch] = 180; | ||||
|                                           elev[ch] =  45;      break; | ||||
|         case AV_CH_WIDE_LEFT:             azim[ch] =  90;      break; | ||||
|         case AV_CH_WIDE_RIGHT:            azim[ch] = 270;      break; | ||||
|         case AV_CH_SURROUND_DIRECT_LEFT:  azim[ch] =  90;      break; | ||||
|         case AV_CH_SURROUND_DIRECT_RIGHT: azim[ch] = 270;      break; | ||||
|         case AV_CH_STEREO_LEFT:           azim[ch] =  90;      break; | ||||
|         case AV_CH_STEREO_RIGHT:          azim[ch] = 270;      break; | ||||
|         case 0:                                                break; | ||||
|         case AV_CHAN_WIDE_LEFT:           azim[ch] =  90;      break; | ||||
|         case AV_CHAN_WIDE_RIGHT:          azim[ch] = 270;      break; | ||||
|         case AV_CHAN_SURROUND_DIRECT_LEFT:  azim[ch] =  90;    break; | ||||
|         case AV_CHAN_SURROUND_DIRECT_RIGHT: azim[ch] = 270;    break; | ||||
|         case AV_CHAN_STEREO_LEFT:         azim[ch] =  90;      break; | ||||
|         case AV_CHAN_STEREO_RIGHT:        azim[ch] = 270;      break; | ||||
|         default: | ||||
|             return AVERROR(EINVAL); | ||||
|         } | ||||
| @@ -315,9 +307,6 @@ static int get_speaker_pos(AVFilterContext *ctx, | ||||
|             azim[ch] = s->vspkrpos[m].azim; | ||||
|             elev[ch] = s->vspkrpos[m].elev; | ||||
|         } | ||||
|  | ||||
|         if (mask) | ||||
|             ch++; | ||||
|     } | ||||
|  | ||||
|     memcpy(speaker_azim, azim, n_conv * sizeof(float)); | ||||
| @@ -668,7 +657,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|         return ret; | ||||
|  | ||||
|     layouts = NULL; | ||||
|     ret = ff_add_channel_layout(&layouts, AV_CH_LAYOUT_STEREO); | ||||
|     ret = ff_add_channel_layout(&layouts, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO); | ||||
|     if (ret) | ||||
|         return ret; | ||||
|  | ||||
| @@ -733,7 +722,7 @@ static int load_data(AVFilterContext *ctx, int azim, int elev, float radius, int | ||||
|     int n_fft; | ||||
|     float delay_l; /* broadband delay for each IR */ | ||||
|     float delay_r; | ||||
|     int nb_input_channels = ctx->inputs[0]->channels; /* no. input channels */ | ||||
|     int nb_input_channels = ctx->inputs[0]->ch_layout.nb_channels; /* no. input channels */ | ||||
|     float gain_lin = expf((s->gain - 3 * nb_input_channels) / 20 * M_LN10); /* gain - 3dB/channel */ | ||||
|     AVComplexFloat *data_hrtf_l = NULL; | ||||
|     AVComplexFloat *data_hrtf_r = NULL; | ||||
| @@ -1016,16 +1005,16 @@ static int config_input(AVFilterLink *inlink) | ||||
|         s->nb_samples = s->framesize; | ||||
|  | ||||
|     /* gain -3 dB per channel */ | ||||
|     s->gain_lfe = expf((s->gain - 3 * inlink->channels + s->lfe_gain) / 20 * M_LN10); | ||||
|     s->gain_lfe = expf((s->gain - 3 * inlink->ch_layout.nb_channels + s->lfe_gain) / 20 * M_LN10); | ||||
|  | ||||
|     s->n_conv = inlink->channels; | ||||
|     s->n_conv = inlink->ch_layout.nb_channels; | ||||
|  | ||||
|     /* load IRs to data_ir[0] and data_ir[1] for required directions */ | ||||
|     if ((ret = load_data(ctx, s->rotation, s->elevation, s->radius, inlink->sample_rate)) < 0) | ||||
|         return ret; | ||||
|  | ||||
|     av_log(ctx, AV_LOG_DEBUG, "Samplerate: %d Channels to convolute: %d, Length of ringbuffer: %d x %d\n", | ||||
|         inlink->sample_rate, s->n_conv, inlink->channels, s->buffer_length); | ||||
|         inlink->sample_rate, s->n_conv, inlink->ch_layout.nb_channels, s->buffer_length); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -68,7 +68,8 @@ typedef struct SpeechNormalizerContext { | ||||
|     double threshold_value; | ||||
|     double raise_amount; | ||||
|     double fall_amount; | ||||
|     uint64_t channels; | ||||
|     char *ch_layout_str; | ||||
|     AVChannelLayout ch_layout; | ||||
|     int invert; | ||||
|     int link; | ||||
|  | ||||
| @@ -103,8 +104,8 @@ static const AVOption speechnorm_options[] = { | ||||
|     { "r",     "set the expansion raising amount", OFFSET(raise_amount), AV_OPT_TYPE_DOUBLE, {.dbl=0.001}, 0.0, 1.0, FLAGS }, | ||||
|     { "fall", "set the compression raising amount", OFFSET(fall_amount), AV_OPT_TYPE_DOUBLE, {.dbl=0.001}, 0.0, 1.0, FLAGS }, | ||||
|     { "f",    "set the compression raising amount", OFFSET(fall_amount), AV_OPT_TYPE_DOUBLE, {.dbl=0.001}, 0.0, 1.0, FLAGS }, | ||||
|     { "channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS }, | ||||
|     { "h",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS }, | ||||
|     { "channels", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS }, | ||||
|     { "h",        "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str="all"}, INT64_MIN, INT64_MAX, FLAGS }, | ||||
|     { "invert", "set inverted filtering", OFFSET(invert), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, | ||||
|     { "i",      "set inverted filtering", OFFSET(invert), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, | ||||
|     { "link", "set linked channels filtering", OFFSET(link), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, | ||||
| @@ -142,7 +143,7 @@ static int available_samples(AVFilterContext *ctx) | ||||
|     int min_pi_nb_samples; | ||||
|  | ||||
|     min_pi_nb_samples = get_pi_samples(s->cc[0].pi, s->cc[0].pi_start, s->cc[0].pi_end, s->cc[0].pi_size); | ||||
|     for (int ch = 1; ch < inlink->channels && min_pi_nb_samples > 0; ch++) { | ||||
|     for (int ch = 1; ch < inlink->ch_layout.nb_channels && min_pi_nb_samples > 0; ch++) { | ||||
|         ChannelContext *cc = &s->cc[ch]; | ||||
|  | ||||
|         min_pi_nb_samples = FFMIN(min_pi_nb_samples, get_pi_samples(cc->pi, cc->pi_start, cc->pi_end, cc->pi_size)); | ||||
| @@ -296,11 +297,12 @@ static void filter_channels_## name (AVFilterContext *ctx, | ||||
|     SpeechNormalizerContext *s = ctx->priv;                                     \ | ||||
|     AVFilterLink *inlink = ctx->inputs[0];                                      \ | ||||
|                                                                                 \ | ||||
|     for (int ch = 0; ch < inlink->channels; ch++) {                             \ | ||||
|     for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) {                \ | ||||
|         ChannelContext *cc = &s->cc[ch];                                        \ | ||||
|         const ptype *src = (const ptype *)in->extended_data[ch];                \ | ||||
|         ptype *dst = (ptype *)out->extended_data[ch];                           \ | ||||
|         const int bypass = !(av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels); \ | ||||
|         enum AVChannel channel = av_channel_layout_channel_from_index(&inlink->ch_layout, ch); \ | ||||
|         const int bypass = av_channel_layout_index_from_channel(&s->ch_layout, channel) < 0; \ | ||||
|         int n = 0;                                                              \ | ||||
|                                                                                 \ | ||||
|         while (n < nb_samples) {                                                \ | ||||
| @@ -346,10 +348,11 @@ static void filter_link_channels_## name (AVFilterContext *ctx, | ||||
|         int max_size = 1;                                                       \ | ||||
|         ptype gain = s->max_expansion;                                          \ | ||||
|                                                                                 \ | ||||
|         for (int ch = 0; ch < inlink->channels; ch++) {                         \ | ||||
|         for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) {            \ | ||||
|             ChannelContext *cc = &s->cc[ch];                                    \ | ||||
|                                                                                 \ | ||||
|             cc->bypass = !(av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels); \ | ||||
|             enum AVChannel channel = av_channel_layout_channel_from_index(&inlink->ch_layout, ch); \ | ||||
|             cc->bypass = av_channel_layout_index_from_channel(&s->ch_layout, channel) < 0; \ | ||||
|                                                                                 \ | ||||
|             next_pi(ctx, cc, cc->bypass);                                       \ | ||||
|             min_size = FFMIN(min_size, cc->pi_size);                            \ | ||||
| @@ -357,7 +360,7 @@ static void filter_link_channels_## name (AVFilterContext *ctx, | ||||
|         }                                                                       \ | ||||
|                                                                                 \ | ||||
|         av_assert1(min_size > 0);                                               \ | ||||
|         for (int ch = 0; ch < inlink->channels; ch++) {                         \ | ||||
|         for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) {            \ | ||||
|             ChannelContext *cc = &s->cc[ch];                                    \ | ||||
|                                                                                 \ | ||||
|             if (cc->bypass)                                                     \ | ||||
| @@ -365,7 +368,7 @@ static void filter_link_channels_## name (AVFilterContext *ctx, | ||||
|             gain = FFMIN(gain, min_gain(ctx, cc, max_size));                    \ | ||||
|         }                                                                       \ | ||||
|                                                                                 \ | ||||
|         for (int ch = 0; ch < inlink->channels; ch++) {                         \ | ||||
|         for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) {            \ | ||||
|             ChannelContext *cc = &s->cc[ch];                                    \ | ||||
|             const ptype *src = (const ptype *)in->extended_data[ch];            \ | ||||
|             ptype *dst = (ptype *)out->extended_data[ch];                       \ | ||||
| @@ -441,7 +444,7 @@ static int filter_frame(AVFilterContext *ctx) | ||||
|  | ||||
|         ff_bufqueue_add(ctx, &s->queue, in); | ||||
|  | ||||
|         for (int ch = 0; ch < inlink->channels; ch++) { | ||||
|         for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|             ChannelContext *cc = &s->cc[ch]; | ||||
|  | ||||
|             s->analyze_channel(ctx, cc, in->extended_data[ch], in->nb_samples); | ||||
| @@ -499,11 +502,11 @@ static int config_input(AVFilterLink *inlink) | ||||
|     s->max_period = inlink->sample_rate / 10; | ||||
|  | ||||
|     s->prev_gain = 1.; | ||||
|     s->cc = av_calloc(inlink->channels, sizeof(*s->cc)); | ||||
|     s->cc = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->cc)); | ||||
|     if (!s->cc) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     for (int ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         ChannelContext *cc = &s->cc[ch]; | ||||
|  | ||||
|         cc->state = -1; | ||||
| @@ -544,11 +547,24 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static av_cold int init(AVFilterContext *ctx) | ||||
| { | ||||
|     SpeechNormalizerContext *s = ctx->priv; | ||||
|     int ret; | ||||
|  | ||||
|     if (strcmp(s->ch_layout_str, "all")) | ||||
|         ret = av_channel_layout_from_string(&s->ch_layout, | ||||
|                                             s->ch_layout_str); | ||||
|  | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| static av_cold void uninit(AVFilterContext *ctx) | ||||
| { | ||||
|     SpeechNormalizerContext *s = ctx->priv; | ||||
|  | ||||
|     ff_bufqueue_discard_all(&s->queue); | ||||
|     av_channel_layout_uninit(&s->ch_layout); | ||||
|     av_freep(&s->cc); | ||||
| } | ||||
|  | ||||
| @@ -573,6 +589,7 @@ const AVFilter ff_af_speechnorm = { | ||||
|     .priv_size       = sizeof(SpeechNormalizerContext), | ||||
|     .priv_class      = &speechnorm_class, | ||||
|     .activate        = activate, | ||||
|     .init            = init, | ||||
|     .uninit          = uninit, | ||||
|     FILTER_INPUTS(inputs), | ||||
|     FILTER_OUTPUTS(outputs), | ||||
|   | ||||
| @@ -107,7 +107,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|     if ((ret = ff_add_format                 (&formats, AV_SAMPLE_FMT_DBL  )) < 0 || | ||||
|         (ret = ff_set_common_formats         (ctx     , formats            )) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , AV_CH_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_set_common_channel_layouts (ctx     , layout             )) < 0) | ||||
|         return ret; | ||||
|  | ||||
|   | ||||
| @@ -60,7 +60,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|  | ||||
|     if ((ret = ff_add_format                 (&formats, AV_SAMPLE_FMT_FLT  )) < 0 || | ||||
|         (ret = ff_set_common_formats         (ctx     , formats            )) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , AV_CH_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_add_channel_layout         (&layout , &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO)) < 0 || | ||||
|         (ret = ff_set_common_channel_layouts (ctx     , layout             )) < 0) | ||||
|         return ret; | ||||
|  | ||||
|   | ||||
| @@ -203,7 +203,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         return AVERROR(ENOMEM); | ||||
|     } | ||||
|  | ||||
|     for (ch = 0; ch < in->channels; ch++) { | ||||
|     for (ch = 0; ch < in->ch_layout.nb_channels; ch++) { | ||||
|         ptr = (float *)out->extended_data[ch]; | ||||
|         dst = (float *)s->out->extended_data[ch]; | ||||
|         src = (float *)in->extended_data[ch]; | ||||
|   | ||||
| @@ -91,8 +91,8 @@ typedef struct AudioSurroundContext { | ||||
|     float lowcut; | ||||
|     float highcut; | ||||
|  | ||||
|     uint64_t out_channel_layout; | ||||
|     uint64_t in_channel_layout; | ||||
|     AVChannelLayout out_channel_layout; | ||||
|     AVChannelLayout in_channel_layout; | ||||
|     int nb_in_channels; | ||||
|     int nb_out_channels; | ||||
|  | ||||
| @@ -170,7 +170,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|         return ret; | ||||
|  | ||||
|     layouts = NULL; | ||||
|     ret = ff_add_channel_layout(&layouts, s->out_channel_layout); | ||||
|     ret = ff_add_channel_layout(&layouts, &s->out_channel_layout); | ||||
|     if (ret) | ||||
|         return ret; | ||||
|  | ||||
| @@ -179,7 +179,7 @@ static int query_formats(AVFilterContext *ctx) | ||||
|         return ret; | ||||
|  | ||||
|     layouts = NULL; | ||||
|     ret = ff_add_channel_layout(&layouts, s->in_channel_layout); | ||||
|     ret = ff_add_channel_layout(&layouts, &s->in_channel_layout); | ||||
|     if (ret) | ||||
|         return ret; | ||||
|  | ||||
| @@ -196,12 +196,12 @@ static int config_input(AVFilterLink *inlink) | ||||
|     AudioSurroundContext *s = ctx->priv; | ||||
|     int ch; | ||||
|  | ||||
|     s->rdft = av_calloc(inlink->channels, sizeof(*s->rdft)); | ||||
|     s->rdft = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->rdft)); | ||||
|     if (!s->rdft) | ||||
|         return AVERROR(ENOMEM); | ||||
|     s->nb_in_channels = inlink->channels; | ||||
|     s->nb_in_channels = inlink->ch_layout.nb_channels; | ||||
|  | ||||
|     for (ch = 0; ch < inlink->channels; ch++) { | ||||
|     for (ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { | ||||
|         float scale = 1.f; | ||||
|  | ||||
|         av_tx_init(&s->rdft[ch], &s->tx_fn, AV_TX_FLOAT_RDFT, 0, s->buf_size, &scale, 0); | ||||
| @@ -213,31 +213,31 @@ static int config_input(AVFilterLink *inlink) | ||||
|         return AVERROR(ENOMEM); | ||||
|     for (ch = 0;  ch < s->nb_in_channels; ch++) | ||||
|         s->input_levels[ch] = s->level_in; | ||||
|     ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_FRONT_CENTER); | ||||
|     ch = av_channel_layout_index_from_channel(&inlink->ch_layout, AV_CHAN_FRONT_CENTER); | ||||
|     if (ch >= 0) | ||||
|         s->input_levels[ch] *= s->fc_in; | ||||
|     ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_FRONT_LEFT); | ||||
|     ch = av_channel_layout_index_from_channel(&inlink->ch_layout, AV_CHAN_FRONT_LEFT); | ||||
|     if (ch >= 0) | ||||
|         s->input_levels[ch] *= s->fl_in; | ||||
|     ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_FRONT_RIGHT); | ||||
|     ch = av_channel_layout_index_from_channel(&inlink->ch_layout, AV_CHAN_FRONT_RIGHT); | ||||
|     if (ch >= 0) | ||||
|         s->input_levels[ch] *= s->fr_in; | ||||
|     ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_SIDE_LEFT); | ||||
|     ch = av_channel_layout_index_from_channel(&inlink->ch_layout, AV_CHAN_SIDE_LEFT); | ||||
|     if (ch >= 0) | ||||
|         s->input_levels[ch] *= s->sl_in; | ||||
|     ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_SIDE_RIGHT); | ||||
|     ch = av_channel_layout_index_from_channel(&inlink->ch_layout, AV_CHAN_SIDE_RIGHT); | ||||
|     if (ch >= 0) | ||||
|         s->input_levels[ch] *= s->sr_in; | ||||
|     ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_BACK_LEFT); | ||||
|     ch = av_channel_layout_index_from_channel(&inlink->ch_layout, AV_CHAN_BACK_LEFT); | ||||
|     if (ch >= 0) | ||||
|         s->input_levels[ch] *= s->bl_in; | ||||
|     ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_BACK_RIGHT); | ||||
|     ch = av_channel_layout_index_from_channel(&inlink->ch_layout, AV_CHAN_BACK_RIGHT); | ||||
|     if (ch >= 0) | ||||
|         s->input_levels[ch] *= s->br_in; | ||||
|     ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_BACK_CENTER); | ||||
|     ch = av_channel_layout_index_from_channel(&inlink->ch_layout, AV_CHAN_BACK_CENTER); | ||||
|     if (ch >= 0) | ||||
|         s->input_levels[ch] *= s->bc_in; | ||||
|     ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_LOW_FREQUENCY); | ||||
|     ch = av_channel_layout_index_from_channel(&inlink->ch_layout, AV_CHAN_LOW_FREQUENCY); | ||||
|     if (ch >= 0) | ||||
|         s->input_levels[ch] *= s->lfe_in; | ||||
|  | ||||
| @@ -265,12 +265,12 @@ static int config_output(AVFilterLink *outlink) | ||||
|     AudioSurroundContext *s = ctx->priv; | ||||
|     int ch; | ||||
|  | ||||
|     s->irdft = av_calloc(outlink->channels, sizeof(*s->irdft)); | ||||
|     s->irdft = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->irdft)); | ||||
|     if (!s->irdft) | ||||
|         return AVERROR(ENOMEM); | ||||
|     s->nb_out_channels = outlink->channels; | ||||
|     s->nb_out_channels = outlink->ch_layout.nb_channels; | ||||
|  | ||||
|     for (ch = 0; ch < outlink->channels; ch++) { | ||||
|     for (ch = 0; ch < outlink->ch_layout.nb_channels; ch++) { | ||||
|         float iscale = 1.f; | ||||
|  | ||||
|         av_tx_init(&s->irdft[ch], &s->itx_fn, AV_TX_FLOAT_RDFT, 1, s->buf_size, &iscale, 0); | ||||
| @@ -282,31 +282,31 @@ static int config_output(AVFilterLink *outlink) | ||||
|         return AVERROR(ENOMEM); | ||||
|     for (ch = 0;  ch < s->nb_out_channels; ch++) | ||||
|         s->output_levels[ch] = s->level_out; | ||||
|     ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_FRONT_CENTER); | ||||
|     ch = av_channel_layout_index_from_channel(&outlink->ch_layout, AV_CHAN_FRONT_CENTER); | ||||
|     if (ch >= 0) | ||||
|         s->output_levels[ch] *= s->fc_out; | ||||
|     ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_FRONT_LEFT); | ||||
|     ch = av_channel_layout_index_from_channel(&outlink->ch_layout, AV_CHAN_FRONT_LEFT); | ||||
|     if (ch >= 0) | ||||
|         s->output_levels[ch] *= s->fl_out; | ||||
|     ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_FRONT_RIGHT); | ||||
|     ch = av_channel_layout_index_from_channel(&outlink->ch_layout, AV_CHAN_FRONT_RIGHT); | ||||
|     if (ch >= 0) | ||||
|         s->output_levels[ch] *= s->fr_out; | ||||
|     ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_SIDE_LEFT); | ||||
|     ch = av_channel_layout_index_from_channel(&outlink->ch_layout, AV_CHAN_SIDE_LEFT); | ||||
|     if (ch >= 0) | ||||
|         s->output_levels[ch] *= s->sl_out; | ||||
|     ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_SIDE_RIGHT); | ||||
|     ch = av_channel_layout_index_from_channel(&outlink->ch_layout, AV_CHAN_SIDE_RIGHT); | ||||
|     if (ch >= 0) | ||||
|         s->output_levels[ch] *= s->sr_out; | ||||
|     ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_BACK_LEFT); | ||||
|     ch = av_channel_layout_index_from_channel(&outlink->ch_layout, AV_CHAN_BACK_LEFT); | ||||
|     if (ch >= 0) | ||||
|         s->output_levels[ch] *= s->bl_out; | ||||
|     ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_BACK_RIGHT); | ||||
|     ch = av_channel_layout_index_from_channel(&outlink->ch_layout, AV_CHAN_BACK_RIGHT); | ||||
|     if (ch >= 0) | ||||
|         s->output_levels[ch] *= s->br_out; | ||||
|     ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_BACK_CENTER); | ||||
|     ch = av_channel_layout_index_from_channel(&outlink->ch_layout, AV_CHAN_BACK_CENTER); | ||||
|     if (ch >= 0) | ||||
|         s->output_levels[ch] *= s->bc_out; | ||||
|     ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_LOW_FREQUENCY); | ||||
|     ch = av_channel_layout_index_from_channel(&outlink->ch_layout, AV_CHAN_LOW_FREQUENCY); | ||||
|     if (ch >= 0) | ||||
|         s->output_levels[ch] *= s->lfe_out; | ||||
|  | ||||
| @@ -1381,15 +1381,16 @@ static av_cold int init(AVFilterContext *ctx) | ||||
| { | ||||
|     AudioSurroundContext *s = ctx->priv; | ||||
|     float overlap; | ||||
|     int i; | ||||
|     int64_t in_channel_layout, out_channel_layout; | ||||
|     int i, ret; | ||||
|  | ||||
|     if (!(s->out_channel_layout = av_get_channel_layout(s->out_channel_layout_str))) { | ||||
|     if ((ret = av_channel_layout_from_string(&s->out_channel_layout, s->out_channel_layout_str)) < 0) { | ||||
|         av_log(ctx, AV_LOG_ERROR, "Error parsing output channel layout '%s'.\n", | ||||
|                s->out_channel_layout_str); | ||||
|         return AVERROR(EINVAL); | ||||
|         return ret; | ||||
|     } | ||||
|  | ||||
|     if (!(s->in_channel_layout = av_get_channel_layout(s->in_channel_layout_str))) { | ||||
|     if ((ret = av_channel_layout_from_string(&s->in_channel_layout, s->in_channel_layout_str)) < 0) { | ||||
|         av_log(ctx, AV_LOG_ERROR, "Error parsing input channel layout '%s'.\n", | ||||
|                s->in_channel_layout_str); | ||||
|         return AVERROR(EINVAL); | ||||
| @@ -1401,10 +1402,15 @@ static av_cold int init(AVFilterContext *ctx) | ||||
|         return AVERROR(EINVAL); | ||||
|     } | ||||
|  | ||||
|     switch (s->in_channel_layout) { | ||||
|     in_channel_layout  = s->in_channel_layout.order == AV_CHANNEL_ORDER_NATIVE ? | ||||
|                          s->in_channel_layout.u.mask : 0; | ||||
|     out_channel_layout = s->out_channel_layout.order == AV_CHANNEL_ORDER_NATIVE ? | ||||
|                          s->out_channel_layout.u.mask : 0; | ||||
|  | ||||
|     switch (in_channel_layout) { | ||||
|     case AV_CH_LAYOUT_STEREO: | ||||
|         s->filter = filter_stereo; | ||||
|         switch (s->out_channel_layout) { | ||||
|         switch (out_channel_layout) { | ||||
|         case AV_CH_LAYOUT_MONO: | ||||
|             s->upmix_stereo = upmix_1_0; | ||||
|             break; | ||||
| @@ -1450,7 +1456,7 @@ static av_cold int init(AVFilterContext *ctx) | ||||
|         break; | ||||
|     case AV_CH_LAYOUT_2POINT1: | ||||
|         s->filter = filter_2_1; | ||||
|         switch (s->out_channel_layout) { | ||||
|         switch (out_channel_layout) { | ||||
|         case AV_CH_LAYOUT_5POINT1_BACK: | ||||
|             s->upmix_2_1 = upmix_5_1_back_2_1; | ||||
|             break; | ||||
| @@ -1460,7 +1466,7 @@ static av_cold int init(AVFilterContext *ctx) | ||||
|         break; | ||||
|     case AV_CH_LAYOUT_SURROUND: | ||||
|         s->filter = filter_surround; | ||||
|         switch (s->out_channel_layout) { | ||||
|         switch (out_channel_layout) { | ||||
|         case AV_CH_LAYOUT_3POINT1: | ||||
|             s->upmix_3_0 = upmix_3_1_surround; | ||||
|             break; | ||||
| @@ -1473,7 +1479,7 @@ static av_cold int init(AVFilterContext *ctx) | ||||
|         break; | ||||
|     case AV_CH_LAYOUT_5POINT0: | ||||
|         s->filter = filter_5_0_side; | ||||
|         switch (s->out_channel_layout) { | ||||
|         switch (out_channel_layout) { | ||||
|         case AV_CH_LAYOUT_7POINT1: | ||||
|             s->upmix_5_0 = upmix_7_1_5_0_side; | ||||
|             break; | ||||
| @@ -1483,7 +1489,7 @@ static av_cold int init(AVFilterContext *ctx) | ||||
|         break; | ||||
|     case AV_CH_LAYOUT_5POINT1: | ||||
|         s->filter = filter_5_1_side; | ||||
|         switch (s->out_channel_layout) { | ||||
|         switch (out_channel_layout) { | ||||
|         case AV_CH_LAYOUT_7POINT1: | ||||
|             s->upmix_5_1 = upmix_7_1_5_1; | ||||
|             break; | ||||
| @@ -1493,7 +1499,7 @@ static av_cold int init(AVFilterContext *ctx) | ||||
|         break; | ||||
|     case AV_CH_LAYOUT_5POINT1_BACK: | ||||
|         s->filter = filter_5_1_back; | ||||
|         switch (s->out_channel_layout) { | ||||
|         switch (out_channel_layout) { | ||||
|         case AV_CH_LAYOUT_7POINT1: | ||||
|             s->upmix_5_1 = upmix_7_1_5_1; | ||||
|             break; | ||||
| @@ -1590,7 +1596,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     AudioSurroundContext *s = ctx->priv; | ||||
|     AVFrame *out; | ||||
|  | ||||
|     ff_filter_execute(ctx, fft_channel, in, NULL, inlink->channels); | ||||
|     ff_filter_execute(ctx, fft_channel, in, NULL, inlink->ch_layout.nb_channels); | ||||
|  | ||||
|     s->filter(ctx); | ||||
|  | ||||
| @@ -1598,7 +1604,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     if (!out) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     ff_filter_execute(ctx, ifft_channel, out, NULL, outlink->channels); | ||||
|     ff_filter_execute(ctx, ifft_channel, out, NULL, outlink->ch_layout.nb_channels); | ||||
|  | ||||
|     out->pts = in->pts; | ||||
|     out->nb_samples = in->nb_samples; | ||||
|   | ||||
| @@ -49,7 +49,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|     AVFilterLink *outlink = ctx->outputs[0]; | ||||
|     TremoloContext *s = ctx->priv; | ||||
|     const double *src = (const double *)in->data[0]; | ||||
|     const int channels = inlink->channels; | ||||
|     const int channels = inlink->ch_layout.nb_channels; | ||||
|     const int nb_samples = in->nb_samples; | ||||
|     AVFrame *out; | ||||
|     double *dst; | ||||
|   | ||||
| @@ -79,7 +79,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         if (s->wave_table_index >= s->wave_table_size) | ||||
|             s->wave_table_index -= s->wave_table_size; | ||||
|  | ||||
|         for (c = 0; c < inlink->channels; c++) { | ||||
|         for (c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|             int samp1_index, samp2_index; | ||||
|             double *buf; | ||||
|             double this_samp; | ||||
| @@ -127,10 +127,10 @@ static int config_input(AVFilterLink *inlink) | ||||
|     AVFilterContext *ctx = inlink->dst; | ||||
|     VibratoContext *s = ctx->priv; | ||||
|  | ||||
|     s->buf = av_calloc(inlink->channels, sizeof(*s->buf)); | ||||
|     s->buf = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->buf)); | ||||
|     if (!s->buf) | ||||
|         return AVERROR(ENOMEM); | ||||
|     s->channels = inlink->channels; | ||||
|     s->channels = inlink->ch_layout.nb_channels; | ||||
|     s->buf_size = lrint(inlink->sample_rate * 0.005 + 0.5); | ||||
|     for (c = 0; c < s->channels; c++) { | ||||
|         s->buf[c] = av_malloc_array(s->buf_size, sizeof(*s->buf[c])); | ||||
|   | ||||
| @@ -281,7 +281,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|     AVFilterLink *inlink = ctx->inputs[0]; | ||||
|  | ||||
|     vol->sample_fmt = inlink->format; | ||||
|     vol->channels   = inlink->channels; | ||||
|     vol->channels   = inlink->ch_layout.nb_channels; | ||||
|     vol->planes     = av_sample_fmt_is_planar(inlink->format) ? vol->channels : 1; | ||||
|  | ||||
|     vol->var_values[VAR_N] = | ||||
| @@ -294,7 +294,7 @@ static int config_output(AVFilterLink *outlink) | ||||
|     vol->var_values[VAR_T] = | ||||
|     vol->var_values[VAR_VOLUME] = NAN; | ||||
|  | ||||
|     vol->var_values[VAR_NB_CHANNELS] = inlink->channels; | ||||
|     vol->var_values[VAR_NB_CHANNELS] = inlink->ch_layout.nb_channels; | ||||
|     vol->var_values[VAR_TB]          = av_q2d(inlink->time_base); | ||||
|     vol->var_values[VAR_SAMPLE_RATE] = inlink->sample_rate; | ||||
|  | ||||
|   | ||||
| @@ -38,7 +38,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *samples) | ||||
|     AVFilterContext *ctx = inlink->dst; | ||||
|     VolDetectContext *vd = ctx->priv; | ||||
|     int nb_samples  = samples->nb_samples; | ||||
|     int nb_channels = samples->channels; | ||||
|     int nb_channels = samples->ch_layout.nb_channels; | ||||
|     int nb_planes   = nb_channels; | ||||
|     int plane, i; | ||||
|     int16_t *pcm; | ||||
|   | ||||
| @@ -109,7 +109,7 @@ static av_cold void uninit(AVFilterContext *ctx) | ||||
| static av_cold int query_formats(AVFilterContext *ctx) | ||||
| { | ||||
|     AudioFIRSourceContext *s = ctx->priv; | ||||
|     static const int64_t chlayouts[] = { AV_CH_LAYOUT_MONO, -1 }; | ||||
|     static const AVChannelLayout chlayouts[] = { AV_CHANNEL_LAYOUT_MONO, { 0 } }; | ||||
|     int sample_rates[] = { s->sample_rate, -1 }; | ||||
|     static const enum AVSampleFormat sample_fmts[] = { | ||||
|         AV_SAMPLE_FMT_FLT, | ||||
|   | ||||
| @@ -84,7 +84,7 @@ AVFILTER_DEFINE_CLASS(anoisesrc); | ||||
| static av_cold int query_formats(AVFilterContext *ctx) | ||||
| { | ||||
|     ANoiseSrcContext *s = ctx->priv; | ||||
|     static const int64_t chlayouts[] = { AV_CH_LAYOUT_MONO, -1 }; | ||||
|     static const AVChannelLayout chlayouts[] = { AV_CHANNEL_LAYOUT_MONO, { 0 } }; | ||||
|     int sample_rates[] = { s->sample_rate, -1 }; | ||||
|     static const enum AVSampleFormat sample_fmts[] = { | ||||
|         AV_SAMPLE_FMT_DBL, | ||||
|   | ||||
| @@ -38,7 +38,7 @@ | ||||
| typedef struct ANullContext { | ||||
|     const AVClass *class; | ||||
|     char   *channel_layout_str; | ||||
|     uint64_t channel_layout; | ||||
|     AVChannelLayout ch_layout; | ||||
|     char   *sample_rate_str; | ||||
|     int     sample_rate; | ||||
|     int64_t duration; | ||||
| @@ -72,7 +72,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, NULL, | ||||
|     if ((ret = ff_parse_channel_layout(&null->ch_layout, NULL, | ||||
|                                         null->channel_layout_str, ctx)) < 0) | ||||
|         return ret; | ||||
|  | ||||
| @@ -82,7 +82,7 @@ static av_cold int init(AVFilterContext *ctx) | ||||
| static int query_formats(AVFilterContext *ctx) | ||||
| { | ||||
|     ANullContext *null = ctx->priv; | ||||
|     int64_t chlayouts[] = { null->channel_layout, -1 }; | ||||
|     const AVChannelLayout chlayouts[] = { null->ch_layout, { 0 } }; | ||||
|     int sample_rates[] = { null->sample_rate, -1 }; | ||||
|     int ret; | ||||
|  | ||||
| @@ -128,6 +128,12 @@ static int activate(AVFilterContext *ctx) | ||||
|     return FFERROR_NOT_READY; | ||||
| } | ||||
|  | ||||
| static av_cold void uninit(AVFilterContext *ctx) | ||||
| { | ||||
|     ANullContext *s = ctx->priv; | ||||
|     av_channel_layout_uninit(&s->ch_layout); | ||||
| } | ||||
|  | ||||
| static const AVFilterPad avfilter_asrc_anullsrc_outputs[] = { | ||||
|     { | ||||
|         .name          = "default", | ||||
| @@ -140,6 +146,7 @@ const AVFilter ff_asrc_anullsrc = { | ||||
|     .name          = "anullsrc", | ||||
|     .description   = NULL_IF_CONFIG_SMALL("Null audio source, return empty audio frames."), | ||||
|     .init          = init, | ||||
|     .uninit        = uninit, | ||||
|     .priv_size     = sizeof(ANullContext), | ||||
|     .inputs        = NULL, | ||||
|     FILTER_OUTPUTS(avfilter_asrc_anullsrc_outputs), | ||||
|   | ||||
| @@ -225,11 +225,13 @@ static int query_formats(AVFilterContext *ctx) | ||||
|     int ret; | ||||
|  | ||||
|     AVFilterChannelLayouts *chlayouts = NULL; | ||||
|     int64_t chlayout = av_get_default_channel_layout(flite->wave->num_channels); | ||||
|     AVFilterFormats *sample_formats = NULL; | ||||
|     AVFilterFormats *sample_rates = NULL; | ||||
|     AVChannelLayout chlayout = { 0 }; | ||||
|  | ||||
|     if ((ret = ff_add_channel_layout         (&chlayouts     , chlayout                )) < 0 || | ||||
|     av_channel_layout_default(&chlayout, flite->wave->num_channels); | ||||
|  | ||||
|     if ((ret = ff_add_channel_layout         (&chlayouts     , &chlayout               )) < 0 || | ||||
|         (ret = ff_set_common_channel_layouts (ctx            , chlayouts               )) < 0 || | ||||
|         (ret = ff_add_format                 (&sample_formats, AV_SAMPLE_FMT_S16       )) < 0 || | ||||
|         (ret = ff_set_common_formats         (ctx            , sample_formats          )) < 0 || | ||||
|   | ||||
| @@ -77,7 +77,7 @@ static av_cold void uninit(AVFilterContext *ctx) | ||||
| static av_cold int query_formats(AVFilterContext *ctx) | ||||
| { | ||||
|     HilbertContext *s = ctx->priv; | ||||
|     static const int64_t chlayouts[] = { AV_CH_LAYOUT_MONO, -1 }; | ||||
|     static const AVChannelLayout chlayouts[] = { AV_CHANNEL_LAYOUT_MONO, { 0 } }; | ||||
|     int sample_rates[] = { s->sample_rate, -1 }; | ||||
|     static const enum AVSampleFormat sample_fmts[] = { | ||||
|         AV_SAMPLE_FMT_FLT, | ||||
|   | ||||
| @@ -76,7 +76,7 @@ static int activate(AVFilterContext *ctx) | ||||
| static int query_formats(AVFilterContext *ctx) | ||||
| { | ||||
|     SincContext *s = ctx->priv; | ||||
|     static const int64_t chlayouts[] = { AV_CH_LAYOUT_MONO, -1 }; | ||||
|     static const AVChannelLayout chlayouts[] = { AV_CHANNEL_LAYOUT_MONO, { 0 } }; | ||||
|     int sample_rates[] = { s->sample_rate, -1 }; | ||||
|     static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_FLT, | ||||
|                                                        AV_SAMPLE_FMT_NONE }; | ||||
|   | ||||
| @@ -180,7 +180,7 @@ static av_cold void uninit(AVFilterContext *ctx) | ||||
| static av_cold int query_formats(AVFilterContext *ctx) | ||||
| { | ||||
|     SineContext *sine = ctx->priv; | ||||
|     static const int64_t chlayouts[] = { AV_CH_LAYOUT_MONO, -1 }; | ||||
|     static const AVChannelLayout chlayouts[] = { AV_CHANNEL_LAYOUT_MONO, { 0 } }; | ||||
|     int sample_rates[] = { sine->sample_rate, -1 }; | ||||
|     static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, | ||||
|                                                        AV_SAMPLE_FMT_NONE }; | ||||
|   | ||||
| @@ -37,11 +37,15 @@ AVFrame *ff_null_get_audio_buffer(AVFilterLink *link, int nb_samples) | ||||
| AVFrame *ff_default_get_audio_buffer(AVFilterLink *link, int nb_samples) | ||||
| { | ||||
|     AVFrame *frame = NULL; | ||||
|     int channels = link->channels; | ||||
|     int channels = link->ch_layout.nb_channels; | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     int channel_layout_nb_channels = av_get_channel_layout_nb_channels(link->channel_layout); | ||||
|     int align = av_cpu_max_align(); | ||||
|  | ||||
|     av_assert0(channels == channel_layout_nb_channels || !channel_layout_nb_channels); | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|  | ||||
|     if (!link->frame_pool) { | ||||
|         link->frame_pool = ff_frame_pool_audio_init(av_buffer_allocz, channels, | ||||
| @@ -76,7 +80,16 @@ AVFrame *ff_default_get_audio_buffer(AVFilterLink *link, int nb_samples) | ||||
|         return NULL; | ||||
|  | ||||
|     frame->nb_samples = nb_samples; | ||||
| #if FF_API_OLD_CHANNEL_LAYOUT | ||||
| FF_DISABLE_DEPRECATION_WARNINGS | ||||
|     frame->channel_layout = link->channel_layout; | ||||
| FF_ENABLE_DEPRECATION_WARNINGS | ||||
| #endif | ||||
|     if (link->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC && | ||||
|         av_channel_layout_copy(&frame->ch_layout, &link->ch_layout) < 0) { | ||||
|         av_frame_free(&frame); | ||||
|         return NULL; | ||||
|     } | ||||
|     frame->sample_rate = link->sample_rate; | ||||
|  | ||||
|     av_samples_set_silence(frame->extended_data, 0, nb_samples, channels, link->format); | ||||
|   | ||||
| @@ -107,7 +107,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|     char *colors, *saveptr = NULL; | ||||
|  | ||||
|     s->nb_samples = FFMAX(1, av_rescale(inlink->sample_rate, s->frame_rate.den, s->frame_rate.num)); | ||||
|     s->nb_channels = inlink->channels; | ||||
|     s->nb_channels = inlink->ch_layout.nb_channels; | ||||
|     s->depth = inlink->format == AV_SAMPLE_FMT_S16P ? 16 : 32; | ||||
|  | ||||
|     s->fg = av_malloc_array(s->nb_channels, 4 * sizeof(*s->fg)); | ||||
| @@ -148,9 +148,9 @@ static int config_output(AVFilterLink *outlink) | ||||
| } | ||||
|  | ||||
| #define BARS(type, depth, one)                                              \ | ||||
|     for (int ch = 0; ch < inlink->channels; ch++) {                         \ | ||||
|     for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) {            \ | ||||
|         const type *in = (const type *)insamples->extended_data[ch];        \ | ||||
|         const int w = outpicref->width / inlink->channels;                  \ | ||||
|         const int w = outpicref->width / inlink->ch_layout.nb_channels;     \ | ||||
|         const int h = outpicref->height / depth;                            \ | ||||
|         const uint32_t color = AV_RN32(&s->fg[4 * ch]);                     \ | ||||
|                                                                             \ | ||||
| @@ -175,8 +175,8 @@ static int config_output(AVFilterLink *outlink) | ||||
|     } | ||||
|  | ||||
| #define DO_TRACE(type, depth, one)                                          \ | ||||
|     for (int ch = 0; ch < inlink->channels; ch++) {                         \ | ||||
|         const int w = outpicref->width / inlink->channels;                  \ | ||||
|     for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) {            \ | ||||
|         const int w = outpicref->width / inlink->ch_layout.nb_channels;     \ | ||||
|         const type *in = (const type *)insamples->extended_data[ch];        \ | ||||
|         const int wb = w / depth;                                           \ | ||||
|         int wv;                                                             \ | ||||
|   | ||||
| @@ -127,7 +127,7 @@ static int config_input(AVFilterLink *inlink) | ||||
|     AudioHistogramContext *s = ctx->priv; | ||||
|  | ||||
|     s->nb_samples = FFMAX(1, av_rescale(inlink->sample_rate, s->frame_rate.den, s->frame_rate.num)); | ||||
|     s->dchannels = s->dmode == SINGLE ? 1 : inlink->channels; | ||||
|     s->dchannels = s->dmode == SINGLE ? 1 : inlink->ch_layout.nb_channels; | ||||
|     s->shistogram = av_calloc(s->w, s->dchannels * sizeof(*s->shistogram)); | ||||
|     if (!s->shistogram) | ||||
|         return AVERROR(ENOMEM); | ||||
| @@ -249,7 +249,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|  | ||||
|     switch (s->ascale) { | ||||
|     case ALINEAR: | ||||
|         for (c = 0; c < inlink->channels; c++) { | ||||
|         for (c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|             const float *src = (const float *)in->extended_data[c]; | ||||
|             uint64_t *achistogram = &s->achistogram[(s->dmode == SINGLE ? 0: c) * w]; | ||||
|  | ||||
| @@ -272,7 +272,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | ||||
|         } | ||||
|         break; | ||||
|     case ALOG: | ||||
|         for (c = 0; c < inlink->channels; c++) { | ||||
|         for (c = 0; c < inlink->ch_layout.nb_channels; c++) { | ||||
|             const float *src = (const float *)in->extended_data[c]; | ||||
|             uint64_t *achistogram = &s->achistogram[(s->dmode == SINGLE ? 0: c) * w]; | ||||
|  | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user