diff --git a/libavfilter/formats.c b/libavfilter/formats.c index 214718b779..d121b3b4bf 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/eval.h" #include "libavutil/pixdesc.h" #include "libavutil/audioconvert.h" #include "avfilter.h" @@ -233,3 +234,61 @@ void avfilter_formats_changeref(AVFilterFormats **oldref, } } +/* internal functions for parsing audio format arguments */ + +int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx) +{ + char *tail; + int sfmt = av_get_sample_fmt(arg); + if (sfmt == AV_SAMPLE_FMT_NONE) { + sfmt = strtol(arg, &tail, 0); + if (*tail || (unsigned)sfmt >= AV_SAMPLE_FMT_NB) { + av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg); + return AVERROR(EINVAL); + } + } + *ret = sfmt; + return 0; +} + +int ff_parse_sample_rate(unsigned *ret, const char *arg, void *log_ctx) +{ + char *tail; + double srate = av_strtod(arg, &tail); + if (*tail || srate < 1 || (int)srate != srate) { + av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg); + return AVERROR(EINVAL); + } + *ret = srate; + return 0; +} + +int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx) +{ + char *tail; + int64_t chlayout = av_get_channel_layout(arg); + if (chlayout == 0) { + chlayout = strtol(arg, &tail, 10); + if (*tail || chlayout == 0) { + av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg); + return AVERROR(EINVAL); + } + } + *ret = chlayout; + return 0; +} + +int ff_parse_packing_format(int *ret, const char *arg, void *log_ctx) +{ + char *tail; + int planar = strtol(arg, &tail, 10); + if (*tail) { + planar = (strcmp(arg, "packed") != 0); + } else if (planar != 0 && planar != 1) { + av_log(log_ctx, AV_LOG_ERROR, "Invalid packing format '%s'\n", arg); + return AVERROR(EINVAL); + } + *ret = planar; + return 0; +} + diff --git a/libavfilter/internal.h b/libavfilter/internal.h index 7537565768..d03b8b8455 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -61,4 +61,46 @@ void ff_avfilter_default_free_buffer(AVFilterBuffer *buf); /** Tell is a format is contained in the provided list terminated by -1. */ int ff_fmt_is_in(int fmt, const int *fmts); +/* Functions to parse audio format arguments */ + +/** + * Parse a sample rate. + * + * @param ret unsigned integer pointer to where the value should be written + * @param arg string to parse + * @param log_ctx log context + * @return 0 in case of success, a negative AVERROR code on error + */ +int ff_parse_sample_rate(unsigned *ret, const char *arg, void *log_ctx); + +/** + * Parse a sample format name or a corresponding integer representation. + * + * @param ret integer pointer to where the value should be written + * @param arg string to parse + * @param log_ctx log context + * @return 0 in case of success, a negative AVERROR code on error + */ +int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx); + +/** + * Parse a channel layout or a corresponding integer representation. + * + * @param ret 64bit integer pointer to where the value should be written. + * @param arg string to parse + * @param log_ctx log context + * @return 0 in case of success, a negative AVERROR code on error + */ +int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx); + +/** + * Parse a packing format or a corresponding integer representation. + * + * @param ret integer pointer to where the value should be written + * @param arg string to parse + * @param log_ctx log context + * @return 0 in case of success, a negative AVERROR code on error + */ +int ff_parse_packing_format(int *ret, const char *arg, void *log_ctx); + #endif /* AVFILTER_INTERNAL_H */