00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include "libavutil/audioconvert.h"
00027 #include "libavutil/avstring.h"
00028 #include "libavutil/common.h"
00029 #include "libavutil/opt.h"
00030
00031 #include "audio.h"
00032 #include "avfilter.h"
00033 #include "formats.h"
00034 #include "internal.h"
00035
00036 typedef struct AFormatContext {
00037 const AVClass *class;
00038
00039 AVFilterFormats *formats;
00040 AVFilterFormats *sample_rates;
00041 AVFilterChannelLayouts *channel_layouts;
00042
00043 char *formats_str;
00044 char *sample_rates_str;
00045 char *channel_layouts_str;
00046 } AFormatContext;
00047
00048 #define OFFSET(x) offsetof(AFormatContext, x)
00049 #define A AV_OPT_FLAG_AUDIO_PARAM
00050 #define F AV_OPT_FLAG_FILTERING_PARAM
00051 static const AVOption aformat_options[] = {
00052 { "sample_fmts", "A comma-separated list of sample formats.", OFFSET(formats_str), AV_OPT_TYPE_STRING, .flags = A|F },
00053 { "sample_rates", "A comma-separated list of sample rates.", OFFSET(sample_rates_str), AV_OPT_TYPE_STRING, .flags = A|F },
00054 { "channel_layouts", "A comma-separated list of channel layouts.", OFFSET(channel_layouts_str), AV_OPT_TYPE_STRING, .flags = A|F },
00055 { NULL },
00056 };
00057
00058 AVFILTER_DEFINE_CLASS(aformat);
00059
00060 #define PARSE_FORMATS(str, type, list, add_to_list, get_fmt, none, desc) \
00061 do { \
00062 char *next, *cur = str; \
00063 while (cur) { \
00064 type fmt; \
00065 next = strchr(cur, ','); \
00066 if (next) \
00067 *next++ = 0; \
00068 \
00069 if ((fmt = get_fmt(cur)) == none) { \
00070 av_log(ctx, AV_LOG_ERROR, "Error parsing " desc ": %s.\n", cur);\
00071 ret = AVERROR(EINVAL); \
00072 goto fail; \
00073 } \
00074 add_to_list(&list, fmt); \
00075 \
00076 cur = next; \
00077 } \
00078 } while (0)
00079
00080 static int get_sample_rate(const char *samplerate)
00081 {
00082 int ret = strtol(samplerate, NULL, 0);
00083 return FFMAX(ret, 0);
00084 }
00085
00086 static av_cold int init(AVFilterContext *ctx, const char *args)
00087 {
00088 AFormatContext *s = ctx->priv;
00089 int ret;
00090
00091 if (!args) {
00092 av_log(ctx, AV_LOG_ERROR, "No parameters supplied.\n");
00093 return AVERROR(EINVAL);
00094 }
00095
00096 s->class = &aformat_class;
00097 av_opt_set_defaults(s);
00098
00099 if ((ret = av_set_options_string(s, args, "=", ":")) < 0)
00100 return ret;
00101
00102 PARSE_FORMATS(s->formats_str, enum AVSampleFormat, s->formats,
00103 ff_add_format, av_get_sample_fmt, AV_SAMPLE_FMT_NONE, "sample format");
00104 PARSE_FORMATS(s->sample_rates_str, int, s->sample_rates, ff_add_format,
00105 get_sample_rate, 0, "sample rate");
00106 PARSE_FORMATS(s->channel_layouts_str, uint64_t, s->channel_layouts,
00107 ff_add_channel_layout, av_get_channel_layout, 0,
00108 "channel layout");
00109
00110 fail:
00111 av_opt_free(s);
00112 return ret;
00113 }
00114
00115 static int query_formats(AVFilterContext *ctx)
00116 {
00117 AFormatContext *s = ctx->priv;
00118
00119 ff_set_common_formats(ctx, s->formats ? s->formats :
00120 ff_all_formats(AVMEDIA_TYPE_AUDIO));
00121 ff_set_common_samplerates(ctx, s->sample_rates ? s->sample_rates :
00122 ff_all_samplerates());
00123 ff_set_common_channel_layouts(ctx, s->channel_layouts ? s->channel_layouts :
00124 ff_all_channel_layouts());
00125
00126 return 0;
00127 }
00128
00129 AVFilter avfilter_af_aformat = {
00130 .name = "aformat",
00131 .description = NULL_IF_CONFIG_SMALL("Convert the input audio to one of the specified formats."),
00132 .init = init,
00133 .query_formats = query_formats,
00134 .priv_size = sizeof(AFormatContext),
00135
00136 .inputs = (const AVFilterPad[]) {{ .name = "default",
00137 .type = AVMEDIA_TYPE_AUDIO, },
00138 { .name = NULL}},
00139 .outputs = (const AVFilterPad[]) {{ .name = "default",
00140 .type = AVMEDIA_TYPE_AUDIO},
00141 { .name = NULL}},
00142 .priv_class = &aformat_class,
00143 };