diff --git a/avconv.c b/avconv.c index cfb231907b..a02d36bb30 100644 --- a/avconv.c +++ b/avconv.c @@ -105,7 +105,6 @@ static int frame_width = 0; static int frame_height = 0; static float frame_aspect_ratio = 0; static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE; -static enum AVSampleFormat audio_sample_fmt = AV_SAMPLE_FMT_NONE; static AVRational frame_rate; static float video_qscale = 0; static uint16_t *intra_matrix = NULL; @@ -320,6 +319,8 @@ typedef struct OptionsContext { int nb_bitstream_filters; SpecifierOpt *codec_tags; int nb_codec_tags; + SpecifierOpt *sample_fmts; + int nb_sample_fmts; } OptionsContext; #define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\ @@ -2572,24 +2573,6 @@ static int opt_top_field_first(const char *opt, const char *arg) return 0; } -static int opt_audio_sample_fmt(const char *opt, const char *arg) -{ - if (strcmp(arg, "list")) { - audio_sample_fmt = av_get_sample_fmt(arg); - if (audio_sample_fmt == AV_SAMPLE_FMT_NONE) { - av_log(NULL, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg); - return AVERROR(EINVAL); - } - } else { - int i; - char fmt_str[128]; - for (i = -1; i < AV_SAMPLE_FMT_NB; i++) - printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i)); - exit_program(0); - } - return 0; -} - static int opt_audio_rate(const char *opt, const char *arg) { audio_sample_rate = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX); @@ -2994,7 +2977,6 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena frame_height = 0; frame_width = 0; audio_sample_rate = 0; - audio_sample_fmt = AV_SAMPLE_FMT_NONE; for (i = 0; i < orig_nb_streams; i++) av_dict_free(&opts[i]); @@ -3204,14 +3186,21 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc) audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; } if (!st->stream_copy) { + char *sample_fmt = NULL; + if (audio_qscale > QSCALE_NONE) { audio_enc->flags |= CODEC_FLAG_QSCALE; audio_enc->global_quality = FF_QP2LAMBDA * audio_qscale; } MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st); - if (audio_sample_fmt != AV_SAMPLE_FMT_NONE) - audio_enc->sample_fmt = audio_sample_fmt; + MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st); + if (sample_fmt && + (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) { + av_log(NULL, AV_LOG_ERROR, "Invalid sample format '%s'\n", sample_fmt); + exit_program(1); + } + if (audio_sample_rate) audio_enc->sample_rate = audio_sample_rate; } @@ -3642,7 +3631,6 @@ static void opt_output_file(void *optctx, const char *filename) frame_width = 0; frame_height = 0; audio_sample_rate = 0; - audio_sample_fmt = AV_SAMPLE_FMT_NONE; av_freep(&streamid_map); nb_streamid_map = 0; @@ -4079,7 +4067,7 @@ static const OptionDef options[] = { { "acodec", HAS_ARG | OPT_AUDIO | OPT_FUNC2, {(void*)opt_audio_codec}, "force audio codec ('copy' to copy stream)", "codec" }, { "atag", HAS_ARG | OPT_EXPERT | OPT_AUDIO | OPT_FUNC2, {(void*)opt_audio_tag}, "force audio tag/fourcc", "fourcc/tag" }, { "vol", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&audio_volume}, "change audio volume (256=normal)" , "volume" }, // - { "sample_fmt", HAS_ARG | OPT_EXPERT | OPT_AUDIO, {(void*)opt_audio_sample_fmt}, "set sample format, 'list' as argument shows all the sample formats supported", "format" }, + { "sample_fmt", HAS_ARG | OPT_EXPERT | OPT_AUDIO | OPT_SPEC | OPT_STRING, {.off = OFFSET(sample_fmts)}, "set sample format", "format" }, /* subtitle options */ { "sn", OPT_BOOL | OPT_SUBTITLE | OPT_OFFSET, {.off = OFFSET(subtitle_disable)}, "disable subtitle" }, diff --git a/cmdutils.c b/cmdutils.c index 52ec96f951..2aab395a96 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -717,6 +717,15 @@ void show_pix_fmts(void) } } +int show_sample_fmts(const char *opt, const char *arg) +{ + int i; + char fmt_str[128]; + for (i = -1; i < AV_SAMPLE_FMT_NB; i++) + printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i)); + return 0; +} + int read_yesno(void) { int c = getchar(); diff --git a/cmdutils.h b/cmdutils.h index 989d769dfe..dc19486834 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -277,6 +277,12 @@ void show_protocols(void); */ void show_pix_fmts(void); +/** + * Print a listing containing all the sample formats supported by the + * program. + */ +int show_sample_fmts(const char *opt, const char *arg); + /** * Return a positive value if a line read from standard input * starts with [yY], otherwise return 0. diff --git a/cmdutils_common_opts.h b/cmdutils_common_opts.h index 9b5e5d22cd..36b2e322e5 100644 --- a/cmdutils_common_opts.h +++ b/cmdutils_common_opts.h @@ -10,4 +10,5 @@ { "protocols", OPT_EXIT, {(void*)show_protocols}, "show available protocols" }, { "filters", OPT_EXIT, {(void*)show_filters }, "show available filters" }, { "pix_fmts" , OPT_EXIT, {(void*)show_pix_fmts }, "show available pixel formats" }, + { "sample_fmts", OPT_EXIT, {.func_arg = show_sample_fmts }, "show available audio sample formats" }, { "loglevel", HAS_ARG, {(void*)opt_loglevel}, "set libav* logging level", "loglevel" }, diff --git a/doc/avconv.texi b/doc/avconv.texi index 827e0f94e5..d9c1461674 100644 --- a/doc/avconv.texi +++ b/doc/avconv.texi @@ -590,6 +590,9 @@ and is mapped to the corresponding demuxer options. Disable audio recording. @item -acodec @var{codec} Set the audio codec. This is an alias for @code{-codec:a}. +@item -sample_fmt[:@var{stream_specifier}] @var{sample_fmt} +Set the audio sample format. Use @code{-help sample_fmts} to get a list +of supported sample formats. @end table @section Advanced Audio options: diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi index 8ffc3299ce..91e1ed7969 100644 --- a/doc/fftools-common-opts.texi +++ b/doc/fftools-common-opts.texi @@ -68,6 +68,9 @@ Show available libavfilter filters. @item -pix_fmts Show available pixel formats. +@item -sample_fmts +Show available sample formats. + @item -loglevel @var{loglevel} Set the logging level used by the library. @var{loglevel} is a number or a string containing one of the following values: