You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	av_aresample: Allow changing sample format and channel layout as well
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		| @@ -26,13 +26,14 @@ | ||||
|  | ||||
| #include "libavutil/avstring.h" | ||||
| #include "libavutil/opt.h" | ||||
| #include "libavutil/samplefmt.h" | ||||
| #include "libavutil/avassert.h" | ||||
| #include "libswresample/swresample.h" | ||||
| #include "avfilter.h" | ||||
| #include "audio.h" | ||||
| #include "internal.h" | ||||
|  | ||||
| typedef struct { | ||||
|     int out_rate; | ||||
|     double ratio; | ||||
|     struct SwrContext *swr; | ||||
| } AResampleContext; | ||||
| @@ -57,12 +58,14 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) | ||||
|             if(value) { | ||||
|                 if((ret=av_opt_set(aresample->swr, token, value, 0)) < 0) | ||||
|                     goto end; | ||||
|             } else if ((ret = ff_parse_sample_rate(&aresample->out_rate, token, ctx)) < 0) | ||||
|             } else { | ||||
|                 int out_rate; | ||||
|                 if ((ret = ff_parse_sample_rate(&out_rate, token, ctx)) < 0) | ||||
|                     goto end; | ||||
|                 if((ret = av_opt_set_int(aresample->swr, "osr", out_rate, 0)) < 0) | ||||
|                     goto end; | ||||
|             } | ||||
|  | ||||
|     } else { | ||||
|         aresample->out_rate = -1; | ||||
|         } | ||||
|     } | ||||
| end: | ||||
|     av_free(argd); | ||||
| @@ -78,34 +81,42 @@ static av_cold void uninit(AVFilterContext *ctx) | ||||
| static int query_formats(AVFilterContext *ctx) | ||||
| { | ||||
|     AResampleContext *aresample = ctx->priv; | ||||
|     int out_rate                   = av_get_int(aresample->swr, "osr", NULL); | ||||
|     uint64_t out_layout            = av_get_int(aresample->swr, "ocl", NULL); | ||||
|     enum AVSampleFormat out_format = av_get_int(aresample->swr, "osf", NULL); | ||||
|  | ||||
|     AVFilterLink *inlink  = ctx->inputs[0]; | ||||
|     AVFilterLink *outlink = ctx->outputs[0]; | ||||
|  | ||||
|     AVFilterFormats        *in_formats      = avfilter_all_formats(AVMEDIA_TYPE_AUDIO); | ||||
|     AVFilterFormats        *out_formats     = avfilter_all_formats(AVMEDIA_TYPE_AUDIO); | ||||
|     AVFilterFormats        *out_formats; | ||||
|     AVFilterFormats        *in_samplerates  = ff_all_samplerates(); | ||||
|     AVFilterFormats        *out_samplerates; | ||||
|  | ||||
|  | ||||
|     AVFilterChannelLayouts *in_layouts      = ff_all_channel_layouts(); | ||||
|     AVFilterChannelLayouts *out_layouts     = ff_all_channel_layouts(); | ||||
|  | ||||
|     avfilter_formats_ref(in_formats,  &inlink->out_formats); | ||||
|     avfilter_formats_ref(out_formats, &outlink->in_formats); | ||||
|  | ||||
|     avfilter_formats_ref(in_samplerates,  &inlink->out_samplerates); | ||||
|     AVFilterChannelLayouts *out_layouts; | ||||
|  | ||||
|     avfilter_formats_ref  (in_formats,      &inlink->out_formats); | ||||
|     avfilter_formats_ref  (in_samplerates,  &inlink->out_samplerates); | ||||
|     ff_channel_layouts_ref(in_layouts,      &inlink->out_channel_layouts); | ||||
|     ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts); | ||||
|  | ||||
|     if(aresample->out_rate > 0) { | ||||
|         int sample_rates[] = { aresample->out_rate, -1 }; | ||||
|         avfilter_formats_ref(avfilter_make_format_list(sample_rates), &outlink->in_samplerates); | ||||
|     if(out_rate > 0) { | ||||
|         out_samplerates = avfilter_make_format_list((int[]){ out_rate, -1 }); | ||||
|     } else { | ||||
|         out_samplerates = ff_all_samplerates(); | ||||
|         avfilter_formats_ref(out_samplerates, &outlink->in_samplerates); | ||||
|     } | ||||
|     avfilter_formats_ref(out_samplerates, &outlink->in_samplerates); | ||||
|  | ||||
|     if(out_format != AV_SAMPLE_FMT_NONE) { | ||||
|         out_formats = avfilter_make_format_list((int[]){ out_format, -1 }); | ||||
|     } else | ||||
|         out_formats = avfilter_make_all_formats(AVMEDIA_TYPE_AUDIO); | ||||
|     avfilter_formats_ref(out_formats, &outlink->in_formats); | ||||
|  | ||||
|     if(out_layout) { | ||||
|         out_layouts = avfilter_make_format64_list((int64_t[]){ out_layout, -1 }); | ||||
|     } else | ||||
|         out_layouts = ff_all_channel_layouts(); | ||||
|     ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
| @@ -117,12 +128,9 @@ static int config_output(AVFilterLink *outlink) | ||||
|     AVFilterContext *ctx = outlink->src; | ||||
|     AVFilterLink *inlink = ctx->inputs[0]; | ||||
|     AResampleContext *aresample = ctx->priv; | ||||
|  | ||||
|     if (aresample->out_rate == -1) | ||||
|         aresample->out_rate = outlink->sample_rate; | ||||
|     else | ||||
|         outlink->sample_rate = aresample->out_rate; | ||||
|     outlink->time_base = (AVRational) {1, aresample->out_rate}; | ||||
|     int out_rate; | ||||
|     uint64_t out_layout; | ||||
|     enum AVSampleFormat out_format; | ||||
|  | ||||
|     aresample->swr = swr_alloc_set_opts(aresample->swr, | ||||
|                                         outlink->channel_layout, outlink->format, outlink->sample_rate, | ||||
| @@ -130,10 +138,20 @@ static int config_output(AVFilterLink *outlink) | ||||
|                                         0, ctx); | ||||
|     if (!aresample->swr) | ||||
|         return AVERROR(ENOMEM); | ||||
|  | ||||
|     ret = swr_init(aresample->swr); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|  | ||||
|     out_rate   = av_get_int(aresample->swr, "osr", NULL); | ||||
|     out_layout = av_get_int(aresample->swr, "ocl", NULL); | ||||
|     out_format = av_get_int(aresample->swr, "osf", NULL); | ||||
|     outlink->time_base = (AVRational) {1, out_rate}; | ||||
|  | ||||
|     av_assert0(outlink->sample_rate == out_rate); | ||||
|     av_assert0(outlink->channel_layout == out_layout); | ||||
|     av_assert0(outlink->format == out_format); | ||||
|  | ||||
|     aresample->ratio = (double)outlink->sample_rate / inlink->sample_rate; | ||||
|  | ||||
|     av_log(ctx, AV_LOG_INFO, "r:%"PRId64"Hz -> r:%"PRId64"Hz\n", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user