[FFmpeg-devel] [PATCH] af_aresample: add 'sample_rate_list' option

Takayuki 'January June' Suwa jjsuwa.sys3175 at gmail.com
Sun Mar 5 01:21:48 EET 2017


From: Takayuki 'January June' Suwa <jjsuwa at users.noreply.github.com>

This adds '|'-separated list of desired sample rates.

examples:

 -i 44.1k_from_cd_da_source -af "aresample=sample_rate_list=44100|48000|192000" ...
 -i 48k_from_dat_source -af "aresample=sample_rate_list=44100|48000|192000" ...
 -i 192k_hires_source -af "aresample=sample_rate_list=44100|48000|192000" ...

    Each above will retain its source sample rate, and

 -i 352.8k_from_dsd64_source -af "aresample=sample_rate_list=44100|48000|192000" ...
 -i 96k_hires_source -af "aresample=sample_rate_list=44100|48000|192000" ...

    will produce 192k and 48k resampled-to-nearest outputs.
---
 libavfilter/af_aresample.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/libavfilter/af_aresample.c b/libavfilter/af_aresample.c
index 028e105..3a0c4e4 100644
--- a/libavfilter/af_aresample.c
+++ b/libavfilter/af_aresample.c
@@ -37,6 +37,7 @@
 typedef struct {
     const AVClass *class;
     int sample_rate_arg;
+    char *sample_rate_list;
     double ratio;
     struct SwrContext *swr;
     int64_t next_pts;
@@ -74,6 +75,7 @@ static av_cold void uninit(AVFilterContext *ctx)
 {
     AResampleContext *aresample = ctx->priv;
     swr_free(&aresample->swr);
+    av_freep(&aresample->sample_rate_list);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -109,6 +111,30 @@ static int query_formats(AVFilterContext *ctx)
     if(out_rate > 0) {
         int ratelist[] = { out_rate, -1 };
         out_samplerates = ff_make_format_list(ratelist);
+    } else if (aresample->sample_rate_list) {
+        int cnt = 0, *lst = NULL;
+        const char *srl;
+        for (srl = aresample->sample_rate_list; *srl; cnt++) {
+            char *tok;
+            if (!(tok = av_get_token(&srl, "|"))) {
+                av_log(ctx, AV_LOG_FATAL, "Could not get token from '-sample_rate_list'.\n");
+                av_freep(&lst);
+                return AVERROR(ENOMEM);
+            }
+            if (*srl)
+                srl++;
+            if ((ret = av_reallocp_array(&lst, cnt + 1, sizeof(*lst))) < 0)
+                return ret;
+            if ((ret = ff_parse_sample_rate(&lst[cnt], tok, ctx)) < 0) {
+                av_freep(&lst);
+                return ret;
+            }
+        }
+        if ((ret = av_reallocp_array(&lst, cnt + 1, sizeof(*lst))) < 0)
+            return ret;
+        lst[cnt] = -1;
+        out_samplerates = ff_make_format_list(lst);
+        av_freep(&lst);
     } else {
         out_samplerates = ff_all_samplerates();
     }
@@ -306,7 +332,8 @@ static void *resample_child_next(void *obj, void *prev)
 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 
 static const AVOption options[] = {
-    {"sample_rate", NULL, OFFSET(sample_rate_arg), AV_OPT_TYPE_INT, {.i64=0},  0,        INT_MAX, FLAGS },
+    {"sample_rate",      "set sample rate",                            OFFSET(sample_rate_arg),  AV_OPT_TYPE_INT,    {.i64=0},    0, INT_MAX, FLAGS },
+    {"sample_rate_list", "set the '|'-separated list of sample rates", OFFSET(sample_rate_list), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0,       FLAGS },
     {NULL}
 };
 


More information about the ffmpeg-devel mailing list