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 };