summaryrefslogtreecommitdiff
path: root/fftools
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2021-09-02 21:04:30 -0300
committerJames Almer <jamrial@gmail.com>2022-03-15 09:42:46 -0300
commit987763ac35d3db8beb77e7c5e8426e1b265b2f95 (patch)
treec9b4a68ff26bc4d8c7c9177e4e0662842079825c /fftools
parent53d60aafaf2649660bea6f1558dd54d50f6cf636 (diff)
ffmpeg: convert to new channel layout-API
Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'fftools')
-rw-r--r--fftools/cmdutils.c42
-rw-r--r--fftools/cmdutils.h8
-rw-r--r--fftools/ffmpeg.c47
-rw-r--r--fftools/ffmpeg.h7
-rw-r--r--fftools/ffmpeg_filter.c52
-rw-r--r--fftools/ffmpeg_opt.c47
6 files changed, 129 insertions, 74 deletions
diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 4b50e15eef..55cdbfb7a7 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -1470,8 +1470,19 @@ static void print_codec(const AVCodec *c)
GET_SAMPLE_RATE_NAME);
PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample formats",
AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME);
- PRINT_CODEC_SUPPORTED(c, channel_layouts, uint64_t, "channel layouts",
- 0, GET_CH_LAYOUT_DESC);
+
+ if (c->ch_layouts) {
+ const AVChannelLayout *p = c->ch_layouts;
+
+ printf(" Supported channel layouts:");
+ while (p->nb_channels) {
+ char name[128];
+ av_channel_layout_describe(p, name, sizeof(name));
+ printf(" %s", name);
+ p++;
+ }
+ printf("\n");
+ }
if (c->priv_class) {
show_help_children(c->priv_class,
@@ -1784,29 +1795,30 @@ int show_pix_fmts(void *optctx, const char *opt, const char *arg)
int show_layouts(void *optctx, const char *opt, const char *arg)
{
+ const AVChannelLayout *ch_layout;
+ void *iter = NULL;
+ char buf[128], buf2[128];
int i = 0;
- uint64_t layout, j;
- const char *name, *descr;
printf("Individual channels:\n"
"NAME DESCRIPTION\n");
for (i = 0; i < 63; i++) {
- name = av_get_channel_name((uint64_t)1 << i);
- if (!name)
+ av_channel_name(buf, sizeof(buf), i);
+ if (!strcmp(buf, "?"))
continue;
- descr = av_get_channel_description((uint64_t)1 << i);
- printf("%-14s %s\n", name, descr);
+ av_channel_description(buf2, sizeof(buf2), i);
+ printf("%-14s %s\n", buf, buf2);
}
printf("\nStandard channel layouts:\n"
"NAME DECOMPOSITION\n");
- for (i = 0; !av_get_standard_channel_layout(i, &layout, &name); i++) {
- if (name) {
- printf("%-14s ", name);
- for (j = 1; j; j <<= 1)
- if ((layout & j))
- printf("%s%s", (layout & (j - 1)) ? "+" : "", av_get_channel_name(j));
+ while (ch_layout = av_channel_layout_standard(&iter)) {
+ av_channel_layout_describe(ch_layout, buf, sizeof(buf));
+ av_channel_name(buf2, sizeof(buf2), i);
+ printf("%-14s ", buf);
+ for (i = 0; i < 63; i++)
+ if (av_channel_layout_index_from_channel(ch_layout, i) >= 0)
+ printf("%s%s", i ? "+" : "", buf2);
printf("\n");
- }
}
return 0;
}
diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h
index 50eed9b13a..274d2e5b14 100644
--- a/fftools/cmdutils.h
+++ b/fftools/cmdutils.h
@@ -663,14 +663,6 @@ void *allocate_array_elem(void *array, size_t elem_size, int *nb_elems);
char name[16];\
snprintf(name, sizeof(name), "%d", rate);
-#define GET_CH_LAYOUT_NAME(ch_layout)\
- char name[16];\
- snprintf(name, sizeof(name), "0x%"PRIx64, ch_layout);
-
-#define GET_CH_LAYOUT_DESC(ch_layout)\
- char name[128];\
- av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
-
double get_rotation(int32_t *displaymatrix);
#endif /* FFTOOLS_CMDUTILS_H */
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 9a3fdc636d..a98e49b775 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -551,6 +551,7 @@ static void ffmpeg_cleanup(int ret)
avfilter_inout_free(&ofilter->out_tmp);
av_freep(&ofilter->name);
+ av_channel_layout_uninit(&ofilter->ch_layout);
av_freep(&fg->outputs[j]);
}
av_freep(&fg->outputs);
@@ -1532,7 +1533,7 @@ static int reap_filters(int flush)
break;
case AVMEDIA_TYPE_AUDIO:
if (!(enc->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE) &&
- enc->channels != filtered_frame->channels) {
+ enc->ch_layout.nb_channels != filtered_frame->ch_layout.nb_channels) {
av_log(NULL, AV_LOG_ERROR,
"Audio filter graph output is not normalized and encoder does not support parameter changes\n");
break;
@@ -1878,17 +1879,22 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
print_final_stats(total_size);
}
-static void ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par)
+static int ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par)
{
+ int ret;
+
// We never got any input. Set a fake format, which will
// come from libavformat.
ifilter->format = par->format;
ifilter->sample_rate = par->sample_rate;
- ifilter->channels = par->channels;
- ifilter->channel_layout = par->channel_layout;
ifilter->width = par->width;
ifilter->height = par->height;
ifilter->sample_aspect_ratio = par->sample_aspect_ratio;
+ ret = av_channel_layout_copy(&ifilter->ch_layout, &par->ch_layout);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
static void flush_encoders(void)
@@ -1916,8 +1922,11 @@ static void flush_encoders(void)
int x;
for (x = 0; x < fg->nb_inputs; x++) {
InputFilter *ifilter = fg->inputs[x];
- if (ifilter->format < 0)
- ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar);
+ if (ifilter->format < 0 &&
+ ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar) < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error copying paramerets from input stream\n");
+ exit_program(1);
+ }
}
if (!ifilter_has_all_input_formats(fg))
@@ -2093,16 +2102,15 @@ int guess_input_channel_layout(InputStream *ist)
{
AVCodecContext *dec = ist->dec_ctx;
- if (!dec->channel_layout) {
+ if (dec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
char layout_name[256];
- if (dec->channels > ist->guess_layout_max)
+ if (dec->ch_layout.nb_channels > ist->guess_layout_max)
return 0;
- dec->channel_layout = av_get_default_channel_layout(dec->channels);
- if (!dec->channel_layout)
+ av_channel_layout_default(&dec->ch_layout, dec->ch_layout.nb_channels);
+ if (dec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
return 0;
- av_get_channel_layout_string(layout_name, sizeof(layout_name),
- dec->channels, dec->channel_layout);
+ av_channel_layout_describe(&dec->ch_layout, layout_name, sizeof(layout_name));
av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Input Stream "
"#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);
}
@@ -2155,8 +2163,7 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_ref
switch (ifilter->ist->st->codecpar->codec_type) {
case AVMEDIA_TYPE_AUDIO:
need_reinit |= ifilter->sample_rate != frame->sample_rate ||
- ifilter->channels != frame->channels ||
- ifilter->channel_layout != frame->channel_layout;
+ av_channel_layout_compare(&ifilter->ch_layout, &frame->ch_layout);
break;
case AVMEDIA_TYPE_VIDEO:
need_reinit |= ifilter->width != frame->width ||
@@ -2232,8 +2239,11 @@ static int ifilter_send_eof(InputFilter *ifilter, int64_t pts)
return ret;
} else {
// the filtergraph was never configured
- if (ifilter->format < 0)
- ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar);
+ if (ifilter->format < 0) {
+ ret = ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar);
+ if (ret < 0)
+ return ret;
+ }
if (ifilter->format < 0 && (ifilter->type == AVMEDIA_TYPE_AUDIO || ifilter->type == AVMEDIA_TYPE_VIDEO)) {
av_log(NULL, AV_LOG_ERROR, "Cannot determine format of input stream %d:%d after EOF\n", ifilter->ist->file_index, ifilter->ist->st->index);
return AVERROR_INVALIDDATA;
@@ -3306,8 +3316,9 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame)
case AVMEDIA_TYPE_AUDIO:
enc_ctx->sample_fmt = av_buffersink_get_format(ost->filter->filter);
enc_ctx->sample_rate = av_buffersink_get_sample_rate(ost->filter->filter);
- enc_ctx->channel_layout = av_buffersink_get_channel_layout(ost->filter->filter);
- enc_ctx->channels = av_buffersink_get_channels(ost->filter->filter);
+ ret = av_buffersink_get_ch_layout(ost->filter->filter, &enc_ctx->ch_layout);
+ if (ret < 0)
+ return ret;
if (ost->bits_per_raw_sample)
enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample;
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index cc8f767e5d..6a19dc9c7c 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -250,8 +250,7 @@ typedef struct InputFilter {
AVRational sample_aspect_ratio;
int sample_rate;
- int channels;
- uint64_t channel_layout;
+ AVChannelLayout ch_layout;
AVBufferRef *hw_frames_ctx;
int32_t *displaymatrix;
@@ -274,12 +273,12 @@ typedef struct OutputFilter {
AVRational frame_rate;
int format;
int sample_rate;
- uint64_t channel_layout;
+ AVChannelLayout ch_layout;
// those are only set if no format is specified and the encoder gives us multiple options
// They point directly to the relevant lists of the encoder.
const int *formats;
- const uint64_t *channel_layouts;
+ const AVChannelLayout *ch_layouts;
const int *sample_rates;
} OutputFilter;
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index b80d7189db..0845c631a5 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -153,8 +153,25 @@ DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
"%d", )
-DEF_CHOOSE_FORMAT(channel_layouts, uint64_t, channel_layout, channel_layouts, 0,
- "0x%"PRIx64, )
+static void choose_channel_layouts(OutputFilter *ofilter, AVBPrint *bprint)
+{
+ if (av_channel_layout_check(&ofilter->ch_layout)) {
+ av_bprintf(bprint, "channel_layouts=");
+ av_channel_layout_describe_bprint(&ofilter->ch_layout, bprint);
+ } else if (ofilter->ch_layouts) {
+ const AVChannelLayout *p;
+
+ av_bprintf(bprint, "channel_layouts=");
+ for (p = ofilter->ch_layouts; p->nb_channels; p++) {
+ av_channel_layout_describe_bprint(p, bprint);
+ av_bprintf(bprint, "|");
+ }
+ if (bprint->len > 0)
+ bprint->str[--bprint->len] = '\0';
+ } else
+ return;
+ av_bprint_chars(bprint, ':', 1);
+}
int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
{
@@ -542,9 +559,10 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
} while (0)
av_bprint_init(&args, 0, AV_BPRINT_SIZE_UNLIMITED);
if (ost->audio_channels_mapped) {
+ AVChannelLayout mapped_layout = { 0 };
int i;
- av_bprintf(&args, "0x%"PRIx64,
- av_get_default_channel_layout(ost->audio_channels_mapped));
+ av_channel_layout_default(&mapped_layout, ost->audio_channels_mapped);
+ av_channel_layout_describe_bprint(&mapped_layout, &args);
for (i = 0; i < ost->audio_channels_mapped; i++)
if (ost->audio_channels_map[i] != -1)
av_bprintf(&args, "|c%d=c%d", i, ost->audio_channels_map[i]);
@@ -553,8 +571,8 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
av_bprint_clear(&args);
}
- if (codec->channels && !codec->channel_layout)
- codec->channel_layout = av_get_default_channel_layout(codec->channels);
+ if (codec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
+ av_channel_layout_default(&codec->ch_layout, codec->ch_layout.nb_channels);
choose_sample_fmts(ofilter, &args);
choose_sample_rates(ofilter, &args);
@@ -833,11 +851,12 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
1, ifilter->sample_rate,
ifilter->sample_rate,
av_get_sample_fmt_name(ifilter->format));
- if (ifilter->channel_layout)
- av_bprintf(&args, ":channel_layout=0x%"PRIx64,
- ifilter->channel_layout);
- else
- av_bprintf(&args, ":channels=%d", ifilter->channels);
+ if (av_channel_layout_check(&ifilter->ch_layout) &&
+ ifilter->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
+ av_bprintf(&args, ":channel_layout=");
+ av_channel_layout_describe_bprint(&ifilter->ch_layout, &args);
+ } else
+ av_bprintf(&args, ":channels=%d", ifilter->ch_layout.nb_channels);
snprintf(name, sizeof(name), "graph_%d_in_%d_%d", fg->index,
ist->file_index, ist->st->index);
@@ -1085,7 +1104,10 @@ int configure_filtergraph(FilterGraph *fg)
ofilter->height = av_buffersink_get_h(sink);
ofilter->sample_rate = av_buffersink_get_sample_rate(sink);
- ofilter->channel_layout = av_buffersink_get_channel_layout(sink);
+ av_channel_layout_uninit(&ofilter->ch_layout);
+ ret = av_buffersink_get_ch_layout(sink, &ofilter->ch_layout);
+ if (ret < 0)
+ goto fail;
}
fg->reconfiguration = 1;
@@ -1147,6 +1169,7 @@ fail:
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
{
AVFrameSideData *sd;
+ int ret;
av_buffer_unref(&ifilter->hw_frames_ctx);
@@ -1157,8 +1180,9 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
ifilter->sample_aspect_ratio = frame->sample_aspect_ratio;
ifilter->sample_rate = frame->sample_rate;
- ifilter->channels = frame->channels;
- ifilter->channel_layout = frame->channel_layout;
+ ret = av_channel_layout_copy(&ifilter->ch_layout, &frame->ch_layout);
+ if (ret < 0)
+ return ret;
av_freep(&ifilter->displaymatrix);
sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index f983c74a66..70e6502f22 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -507,7 +507,7 @@ static int opt_map_channel(void *optctx, const char *opt, const char *arg)
/* allow trailing ? to map_channel */
if (allow_unused = strchr(mapchan, '?'))
*allow_unused = 0;
- if (m->channel_idx < 0 || m->channel_idx >= st->codecpar->channels ||
+ if (m->channel_idx < 0 || m->channel_idx >= st->codecpar->ch_layout.nb_channels ||
input_streams[input_files[m->file_idx]->ist_index + m->stream_idx]->user_set_discard == AVDISCARD_ALL) {
if (allow_unused) {
av_log(NULL, AV_LOG_VERBOSE, "mapchan: invalid audio channel #%d.%d.%d\n",
@@ -1945,9 +1945,14 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, in
MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
if (!ost->stream_copy) {
+ int channels = 0;
char *sample_fmt = NULL;
- MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
+ MATCH_PER_STREAM_OPT(audio_channels, i, channels, oc, st);
+ if (channels) {
+ audio_enc->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
+ audio_enc->ch_layout.nb_channels = channels;
+ }
MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
if (sample_fmt &&
@@ -2367,7 +2372,7 @@ static int open_output_file(OptionsContext *o, const char *filename)
for (i = 0; i < ifile->nb_streams; i++) {
int score;
ist = input_streams[ifile->ist_index + i];
- score = ist->st->codecpar->channels
+ score = ist->st->codecpar->ch_layout.nb_channels
+ 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
+ 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
if (ist->user_set_discard == AVDISCARD_ALL)
@@ -2644,10 +2649,10 @@ loop_end:
} else {
f->sample_rates = ost->enc->supported_samplerates;
}
- if (ost->enc_ctx->channels) {
- f->channel_layout = av_get_default_channel_layout(ost->enc_ctx->channels);
- } else {
- f->channel_layouts = ost->enc->channel_layouts;
+ if (ost->enc_ctx->ch_layout.nb_channels) {
+ av_channel_layout_default(&f->ch_layout, ost->enc_ctx->ch_layout.nb_channels);
+ } else if (ost->enc->ch_layouts) {
+ f->ch_layouts = ost->enc->ch_layouts;
}
break;
}
@@ -3236,22 +3241,34 @@ static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
char layout_str[32];
char *stream_str;
char *ac_str;
- int ret, channels, ac_str_size;
- uint64_t layout;
+ int ret, ac_str_size;
+ AVChannelLayout layout = { 0 };
- layout = av_get_channel_layout(arg);
- if (!layout) {
+ 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
}
- snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout);
- ret = opt_default_new(o, opt, layout_str);
+
+ ret = opt_default_new(o, opt, arg);
if (ret < 0)
return ret;
/* set 'ac' option based on channel layout */
- channels = av_get_channel_layout_nb_channels(layout);
- snprintf(layout_str, sizeof(layout_str), "%d", channels);
+ 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);