| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -234,18 +234,29 @@ static int config_props(AVFilterLink *link) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    // gains are pure, init the channel mapping | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (pan->pure_gains) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        /* TODO reindent */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // sanity check; can't be done in query_formats since the inlink | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // channel layout is unknown at that time | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (pan->nb_input_channels > SWR_CH_MAX) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (pan->nb_input_channels > SWR_CH_MAX || | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            pan->nb_output_channels > SWR_CH_MAX) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            av_log(ctx, AV_LOG_ERROR, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                   "libswresample support a maximum of %d channels. " | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                   "Feel free to ask for a higher limit.\n", SWR_CH_MAX); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return AVERROR_PATCHWELCOME; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // 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) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return AVERROR(ENOMEM); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    // gains are pure, init the channel mapping | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (pan->pure_gains) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // get channel map from the pure gains | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        for (i = 0; i < pan->nb_output_channels; i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            int ch_id = -1; | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -258,19 +269,9 @@ static int config_props(AVFilterLink *link) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            pan->channel_map[i] = ch_id; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // 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) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return AVERROR(ENOMEM); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        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); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        r = swr_init(pan->swr); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (r < 0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return r; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // renormalize | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        for (i = 0; i < pan->nb_output_channels; i++) { | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -289,7 +290,16 @@ static int config_props(AVFilterLink *link) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            for (j = 0; j < pan->nb_input_channels; j++) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                pan->gain.d[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.d[0], | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                       pan->gain.d[1] - pan->gain.d[0]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    r = swr_init(pan->swr); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (r < 0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        return r; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    // summary | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    for (i = 0; i < pan->nb_output_channels; i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        cur = buf; | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -331,30 +341,6 @@ static void filter_samples_channel_mapping(PanContext *pan, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    swr_convert(pan->swr, outsamples->data, n, (void *)insamples->data, n); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static void filter_samples_panning(PanContext *pan, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                                   AVFilterBufferRef *outsamples, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                                   AVFilterBufferRef *insamples, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                                   int n) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int i, o; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* input */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    const int16_t *in     = (int16_t *)insamples->data[0]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    const int16_t *in_end = in + n * pan->nb_input_channels; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* output */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int16_t *out = (int16_t *)outsamples->data[0]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    for (; in < in_end; in += pan->nb_input_channels) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        for (o = 0; o < pan->nb_output_channels; o++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            int v = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            for (i = 0; i < pan->nb_input_channels; i++) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                v += pan->gain.i[o][i] * in[i]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            *(out++) = v >> 8; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int n = insamples->audio->nb_samples; | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -379,21 +365,12 @@ static int query_formats(AVFilterContext *ctx) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    AVFilterLink *outlink = ctx->outputs[0]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    AVFilterFormats *formats; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (pan->nb_output_channels <= SWR_CH_MAX) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        /* TODO reindent */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        pan->pure_gains = are_gains_pure(pan); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (pan->pure_gains) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        /* libswr supports any sample and packing formats */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        avfilter_set_common_sample_formats(ctx, avfilter_make_all_formats(AVMEDIA_TYPE_AUDIO)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        avfilter_set_common_packing_formats(ctx, avfilter_make_all_packing_formats()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        pan->filter_samples = filter_samples_channel_mapping; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        const enum AVSampleFormat sample_fmts[] = {AV_SAMPLE_FMT_S16, -1}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        const int                packing_fmts[] = {AVFILTER_PACKED,   -1}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        avfilter_set_common_sample_formats (ctx, avfilter_make_format_list(sample_fmts)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        avfilter_set_common_packing_formats(ctx, avfilter_make_format_list(packing_fmts)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        pan->filter_samples = filter_samples_panning; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    // inlink supports any channel layout | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    formats = avfilter_make_all_channel_layouts(); | 
		
		
	
	
		
			
				| 
				
					
				
				
				
				 | 
			
			 | 
			
  |