summaryrefslogtreecommitdiff
path: root/fftools
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2022-03-18 16:55:58 -0300
committerJames Almer <jamrial@gmail.com>2022-03-22 08:45:38 -0300
commitbc99e3a9d693d46b1aa3a6149255ad4885eeb9ce (patch)
tree538a5012a70e172cd3293cd5f94baeaafb29fa8a /fftools
parente6e86a3907379a08d0015d76da7ea6b682def815 (diff)
ffmpeg: replace custom channel_layout code with an SpecifierOpt based one
This is cleaner and allows fine tuning which stream the option is applied to. Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'fftools')
-rw-r--r--fftools/ffmpeg.h2
-rw-r--r--fftools/ffmpeg_opt.c83
2 files changed, 35 insertions, 50 deletions
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 6a19dc9c7c..1e14bf9fa9 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -96,6 +96,8 @@ typedef struct OptionsContext {
SpecifierOpt *codec_names;
int nb_codec_names;
+ SpecifierOpt *audio_ch_layouts;
+ int nb_audio_ch_layouts;
SpecifierOpt *audio_channels;
int nb_audio_channels;
SpecifierOpt *audio_sample_rate;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 70e6502f22..431ef25af4 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -55,6 +55,7 @@
static const char *const opt_name_codec_names[] = {"c", "codec", "acodec", "vcodec", "scodec", "dcodec", NULL};
static const char *const opt_name_audio_channels[] = {"ac", NULL};
+static const char *const opt_name_audio_ch_layouts[] = {"channel_layout", NULL};
static const char *const opt_name_audio_sample_rate[] = {"ar", NULL};
static const char *const opt_name_frame_rates[] = {"r", NULL};
static const char *const opt_name_max_frame_rates[] = {"fpsmax", NULL};
@@ -1124,6 +1125,14 @@ static int open_input_file(OptionsContext *o, const char *filename)
av_dict_set_int(&o->g->format_opts, "channels", o->audio_channels[o->nb_audio_channels - 1].u.i, 0);
}
}
+ if (o->nb_audio_ch_layouts) {
+ const AVClass *priv_class;
+ if (file_iformat && (priv_class = file_iformat->priv_class) &&
+ av_opt_find(&priv_class, "ch_layout", NULL, 0,
+ AV_OPT_SEARCH_FAKE_OBJ)) {
+ av_dict_set(&o->g->format_opts, "ch_layout", o->audio_ch_layouts[o->nb_audio_ch_layouts - 1].u.str, 0);
+ }
+ }
if (o->nb_frame_rates) {
const AVClass *priv_class;
/* set the format-level framerate option;
@@ -1946,6 +1955,7 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, in
if (!ost->stream_copy) {
int channels = 0;
+ char *layout = NULL;
char *sample_fmt = NULL;
MATCH_PER_STREAM_OPT(audio_channels, i, channels, oc, st);
@@ -1954,6 +1964,27 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, in
audio_enc->ch_layout.nb_channels = channels;
}
+ MATCH_PER_STREAM_OPT(audio_ch_layouts, str, layout, oc, st);
+ if (layout) {
+ if (av_channel_layout_from_string(&audio_enc->ch_layout, layout) < 0) {
+#if FF_API_OLD_CHANNEL_LAYOUT
+ uint64_t mask;
+ AV_NOWARN_DEPRECATED({
+ mask = av_get_channel_layout(layout);
+ })
+ if (!mask) {
+#endif
+ av_log(NULL, AV_LOG_FATAL, "Unknown channel layout: %s\n", layout);
+ exit_program(1);
+#if FF_API_OLD_CHANNEL_LAYOUT
+ }
+ av_log(NULL, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n",
+ layout);
+ av_channel_layout_from_mask(&audio_enc->ch_layout, mask);
+#endif
+ }
+ }
+
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) {
@@ -3235,54 +3266,6 @@ static int opt_timecode(void *optctx, const char *opt, const char *arg)
return ret;
}
-static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
-{
- OptionsContext *o = optctx;
- char layout_str[32];
- char *stream_str;
- char *ac_str;
- int ret, ac_str_size;
- AVChannelLayout layout = { 0 };
-
- ret = av_channel_layout_from_string(&layout, arg);
- if (ret < 0) {
-#if FF_API_OLD_CHANNEL_LAYOUT
- uint64_t mask;
- AV_NOWARN_DEPRECATED({
- mask = av_get_channel_layout(arg);
- })
- if (!mask) {
-#endif
- av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg);
- return AVERROR(EINVAL);
-#if FF_API_OLD_CHANNEL_LAYOUT
- }
- av_log(NULL, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n",
- arg);
- av_channel_layout_from_mask(&layout, mask);
-#endif
- }
-
- ret = opt_default_new(o, opt, arg);
- if (ret < 0)
- return ret;
-
- /* set 'ac' option based on channel layout */
- snprintf(layout_str, sizeof(layout_str), "%d", layout.nb_channels);
- stream_str = strchr(opt, ':');
- ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0);
- ac_str = av_mallocz(ac_str_size);
- if (!ac_str)
- return AVERROR(ENOMEM);
- av_strlcpy(ac_str, "ac", 3);
- if (stream_str)
- av_strlcat(ac_str, stream_str, ac_str_size);
- ret = parse_option(o, ac_str, layout_str, options);
- av_free(ac_str);
-
- return ret;
-}
-
static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
{
OptionsContext *o = optctx;
@@ -3827,8 +3810,8 @@ const OptionDef options[] = {
{ "sample_fmt", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_SPEC |
OPT_STRING | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(sample_fmts) },
"set sample format", "format" },
- { "channel_layout", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
- OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_channel_layout },
+ { "channel_layout", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_SPEC |
+ OPT_STRING | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(audio_ch_layouts) },
"set channel layout", "layout" },
{ "af", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_filters },
"set audio filters", "filter_graph" },