Since the request_channel_layout is used only by a handful of codecs,
move the option to codec private contexts.
---
libavcodec/avcodec.h | 31 +++++++++
libavcodec/decode.c | 49 +++++++++-----
libavcodec/encode.c | 9 ++-
libavcodec/internal.h | 2 +
libavcodec/options_table.h | 5 ++
libavcodec/utils.c | 162 +++++++++++++++++++++++++++++++++------------
libavformat/utils.c | 26 +++++++-
7 files changed, 220 insertions(+), 64 deletions(-)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index bc7097c7bd..b0eac85f72 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1834,7 +1834,13 @@ typedef struct AVCodecContext {
/* audio only */
int sample_rate; ///< samples per second
+#if FF_API_OLD_CHANNEL_LAYOUT
+ /**
+ * @deprecated use ch_layout.nb_channels
+ */
+ attribute_deprecated
int channels; ///< number of audio channels
+#endif
/**
* audio sample format
@@ -1879,19 +1885,25 @@ typedef struct AVCodecContext {
*/
int cutoff;
+#if FF_API_OLD_CHANNEL_LAYOUT
/**
* Audio channel layout.
* - encoding: set by user.
* - decoding: set by libavcodec.
+ * @deprecated use ch_layout
*/
+ attribute_deprecated
uint64_t channel_layout;
/**
* Request decoder to use this channel layout if it can (0 for default)
* - encoding: unused
* - decoding: Set by user.
+ * @deprecated use "downmix" codec private option
*/
+ attribute_deprecated
uint64_t request_channel_layout;
+#endif
/**
* Type of service that the audio stream conveys.
@@ -2730,6 +2742,14 @@ typedef struct AVCodecContext {
* AVCodecContext.get_format callback)
*/
int hwaccel_flags;
+
+ /**
+ * Audio channel layout.
+ * - encoding: must be set by the caller, to one of AVCodec.ch_layouts.
+ * - decoding: may be set by the caller if known e.g. from the container.
+ * The decoder can then override during decoding as needed.
+ */
+ AVChannelLayout ch_layout;
} AVCodecContext;
/**
@@ -2771,10 +2791,21 @@ typedef struct AVCodec {
const enum AVPixelFormat *pix_fmts; ///< array of supported pixel
formats, or NULL if unknown, array is terminated by -1
const int *supported_samplerates; ///< array of supported audio
samplerates, or NULL if unknown, array is terminated by 0
const enum AVSampleFormat *sample_fmts; ///< array of supported sample
formats, or NULL if unknown, array is terminated by -1
+#if FF_API_OLD_CHANNEL_LAYOUT
+ /**
+ * @deprecated use ch_layouts instead
+ */
+ attribute_deprecated
const uint64_t *channel_layouts; ///< array of support channel
layouts, or NULL if unknown. array is terminated by 0
+#endif
const AVClass *priv_class; ///< AVClass for the private
context
const AVProfile *profiles; ///< array of recognized profiles,
or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN}
+ /**
+ * Array of supported channel layouts, terminated with a zeroed layout.
+ */
+ const AVChannelLayout *ch_layouts;
+
/*****************************************************************
* No fields below this line are part of the public API. They
* may not be used outside of libavcodec and can be changed and
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index b0d6b9fb33..c4bcfb95df 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -1131,27 +1131,42 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame
*frame, int flags)
frame->sample_rate = avctx->sample_rate;
if (frame->format < 0)
frame->format = avctx->sample_fmt;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ||
+ avctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
+ if (!frame->ch_layout.nb_channels && (avctx->channel_layout ||
avctx->channels)) {
+ if (avctx->channel_layout)
+ av_channel_layout_from_mask(&frame->ch_layout,
avctx->channel_layout);
+ else
+ av_channel_layout_default(&frame->ch_layout,
avctx->channels);
+ }
+ }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
if (!frame->ch_layout.nb_channels) {
- if (avctx->channel_layout)
- av_channel_layout_from_mask(&frame->ch_layout,
avctx->channel_layout);
- else
- av_channel_layout_default(&frame->ch_layout, avctx->channels);
+ ret = av_channel_layout_copy(&frame->ch_layout, &avctx->ch_layout);
+ if (ret < 0)
+ return ret;
}
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGS
- /* set the deprecated channel_layout field for callers
- * that didn't update to the new API yet */
- if (frame->ch_layout.nb_channels > FF_SANE_NB_CHANNELS) {
- av_log(avctx, AV_LOG_ERROR, "Too many channels.\n");
- return AVERROR(EINVAL);
- }
- if (!frame->channel_layout) {
- if (frame->ch_layout.order == AV_CHANNEL_ORDER_NATIVE)
- frame->channel_layout = frame->ch_layout.u.mask;
- else {
- frame->channel_layout =
av_get_default_channel_layout(frame->ch_layout.nb_channels);
- if (!frame->channel_layout)
- frame->channel_layout = (1ULL <<
frame->ch_layout.nb_channels) - 1;
+ if (avctx->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ||
+ avctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
+ /* set the deprecated channel_layout field for callers
+ * that didn't update to the new API yet */
+ if (frame->ch_layout.nb_channels > FF_SANE_NB_CHANNELS) {
+ av_log(avctx, AV_LOG_ERROR, "Too many channels.\n");
+ return AVERROR(EINVAL);
+ }
+ if (!frame->channel_layout) {
+ if (frame->ch_layout.order == AV_CHANNEL_ORDER_NATIVE)
+ frame->channel_layout = frame->ch_layout.u.mask;
+ else {
+ frame->channel_layout =
av_get_default_channel_layout(frame->ch_layout.nb_channels);
+ if (!frame->channel_layout)
+ frame->channel_layout = (1ULL <<
frame->ch_layout.nb_channels) - 1;
+ }
}
}
FF_ENABLE_DEPRECATION_WARNINGS
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index cf77fa7cff..d315e218ab 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -54,6 +54,7 @@ int ff_alloc_packet(AVPacket *avpkt, int size)
static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src)
{
AVFrame *frame = NULL;
+ int ch = s->ch_layout.nb_channels;
int ret;
if (!(frame = av_frame_alloc()))
@@ -63,6 +64,8 @@ static int pad_last_frame(AVCodecContext *s, AVFrame **dst,
const AVFrame *src)
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGS
frame->channel_layout = src->channel_layout;
+ if (!ch)
+ ch = s->channels;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
frame->nb_samples = s->frame_size;
@@ -80,11 +83,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
goto fail;
if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0,
- src->nb_samples, s->channels, s->sample_fmt)) <
0)
+ src->nb_samples, ch, s->sample_fmt)) < 0)
goto fail;
if ((ret = av_samples_set_silence(frame->extended_data, src->nb_samples,
frame->nb_samples - src->nb_samples,
- s->channels, s->sample_fmt)) < 0)
+ ch, s->sample_fmt)) < 0)
goto fail;
*dst = frame;
@@ -122,7 +125,7 @@ int attribute_align_arg
avcodec_encode_audio2(AVCodecContext *avctx,
/* ensure that extended_data is properly set */
if (frame && !frame->extended_data) {
if (av_sample_fmt_is_planar(avctx->sample_fmt) &&
- avctx->channels > AV_NUM_DATA_POINTERS) {
+ avctx->ch_layout.nb_channels > AV_NUM_DATA_POINTERS) {
av_log(avctx, AV_LOG_ERROR, "Encoding to a planar sample format, "
"with more than %d channels, but
extended_data is not set.\n",
AV_NUM_DATA_POINTERS);
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 403fb4a090..2d695fafc2 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -75,7 +75,9 @@
#define FF_DEFAULT_QUANT_BIAS 999999
+#if FF_API_OLD_CHANNEL_LAYOUT
#define FF_SANE_NB_CHANNELS 63U
+#endif
#define FF_SIGNBIT(x) (x >> CHAR_BIT * sizeof(x) - 1)
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index 925ef376f3..b07f3fbbcf 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -71,7 +71,9 @@ static const AVOption avcodec_options[] = {
{"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0},
INT_MIN, INT_MAX},
{"g", "set the group of picture (GOP) size", OFFSET(gop_size),
AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E},
{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate),
AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|D|E},
+#if FF_API_OLD_CHANNEL_LAYOUT
{"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT,
{.i64 = DEFAULT }, INT_MIN, INT_MAX, A|D|E},
+#endif
{"cutoff", "set cutoff bandwidth", OFFSET(cutoff), AV_OPT_TYPE_INT, {.i64 =
DEFAULT }, INT_MIN, INT_MAX, A|E},
{"frame_size", NULL, OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT },
INT_MIN, INT_MAX, A|E},
{"frame_number", NULL, OFFSET(frame_number), AV_OPT_TYPE_INT, {.i64 = DEFAULT
}, INT_MIN, INT_MAX},
@@ -308,8 +310,11 @@ static const AVOption avcodec_options[] = {
{"timecode_frame_start", "GOP timecode frame start number, in non-drop-frame
format", OFFSET(timecode_frame_start), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0,
INT64_MAX, V|E},
#endif
{"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), AV_OPT_TYPE_INT,
{.i64 = DEFAULT }, INT_MIN, INT_MAX},
+#if FF_API_OLD_CHANNEL_LAYOUT
{"channel_layout", NULL, OFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 =
DEFAULT }, 0, INT64_MAX, A|E|D, "channel_layout"},
{"request_channel_layout", NULL, OFFSET(request_channel_layout),
AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT64_MAX, A|D,
"request_channel_layout"},
+#endif
+{"ch_layout", NULL, OFFSET(ch_layout),
AV_OPT_TYPE_CHANNEL_LAYOUT, { .str = NULL }, .flags = A|E|D},
{"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT,
{.dbl = 1.0/3 }, 0.0, FLT_MAX, V|E},
{"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use), AV_OPT_TYPE_FLOAT,
{.dbl = 3 }, 0.0, FLT_MAX, V|E},
{"ticks_per_frame", NULL, OFFSET(ticks_per_frame), AV_OPT_TYPE_INT, {.i64 = 1
}, 1, INT_MAX, A|V|E|D},
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index f8ae415d52..5290477b31 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -480,10 +480,25 @@ int attribute_align_arg avcodec_open2(AVCodecContext
*avctx, const AVCodec *code
if (av_codec_is_decoder(codec))
av_freep(&avctx->subtitle_header);
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ /* if the caller set the deprecated channels/channel_layout fields,
+ * convert them to the new channel layout */
if (avctx->channels > FF_SANE_NB_CHANNELS) {
ret = AVERROR(EINVAL);
goto free_and_end;
}
+ if (!avctx->ch_layout.nb_channels) {
+ if (avctx->channel_layout)
+ av_channel_layout_from_mask(&avctx->ch_layout,
avctx->channel_layout);
+ else
+ avctx->ch_layout = (AVChannelLayout){
+ .nb_channels = avctx->channels,
+ .order = AV_CHANNEL_ORDER_UNSPEC,
+ };
+ }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
avctx->codec = codec;
if ((avctx->codec_type == AVMEDIA_TYPE_UNKNOWN || avctx->codec_type ==
codec->type) &&
@@ -542,7 +557,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
for (i = 0; avctx->codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE;
i++) {
if (avctx->sample_fmt == avctx->codec->sample_fmts[i])
break;
- if (avctx->channels == 1 &&
+ if (avctx->ch_layout.nb_channels == 1 &&
av_get_planar_sample_fmt(avctx->sample_fmt) ==
av_get_planar_sample_fmt(avctx->codec->sample_fmts[i])) {
avctx->sample_fmt = avctx->codec->sample_fmts[i];
@@ -580,7 +595,50 @@ FF_ENABLE_DEPRECATION_WARNINGS
goto free_and_end;
}
}
- if (avctx->codec->channel_layouts) {
+
+ if (avctx->codec->ch_layouts) {
+ if (avctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
+ /* if the layout is unspecified, select a supported native one
+ * with provided number of channels */
+ for (i = 0; avctx->codec->ch_layouts[i].nb_channels; i++) {
+ if (avctx->codec->ch_layouts[i].nb_channels ==
avctx->ch_layout.nb_channels) {
+ ret = av_channel_layout_copy(&avctx->ch_layout,
+
&avctx->codec->ch_layouts[i]);
+ if (ret < 0)
+ goto free_and_end;
+ break;
+ }
+ }
+ if (avctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
+ av_log(avctx, AV_LOG_ERROR, "This encoder does not "
+ "support any channel layout with %d channels.\n",
+ avctx->ch_layout.nb_channels);
+ ret = AVERROR(EINVAL);
+ goto free_and_end;
+ }
+ } else {
+ /* check that the selected channel layout is supported */
+ for (i = 0; avctx->codec->ch_layouts[i].nb_channels; i++) {
+ if
(!av_channel_layout_compare(&avctx->codec->ch_layouts[i],
+ &avctx->ch_layout))
+ break;
+ }
+ if (!avctx->codec->ch_layouts[i].nb_channels) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Specified channel_layout is not supported\n");
+ ret = AVERROR(EINVAL);
+ goto free_and_end;
+ }
+ }
+
+ if (!av_channel_layout_check(&avctx->ch_layout)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid channel layout
provided.\n");
+ ret = AVERROR_INVALIDDATA;
+ goto free_and_end;
+ }
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ } else if (avctx->codec->channel_layouts) {
if (!avctx->channel_layout) {
av_log(avctx, AV_LOG_WARNING, "channel_layout not
specified\n");
} else {
@@ -593,15 +651,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
goto free_and_end;
}
}
- }
- if (avctx->channel_layout && avctx->channels) {
- if (av_get_channel_layout_nb_channels(avctx->channel_layout) !=
avctx->channels) {
- av_log(avctx, AV_LOG_ERROR, "channel layout does not match
number of channels\n");
- ret = AVERROR(EINVAL);
- goto free_and_end;
- }
- } else if (avctx->channel_layout) {
- avctx->channels =
av_get_channel_layout_nb_channels(avctx->channel_layout);
+ av_channel_layout_from_mask(&avctx->ch_layout,
avctx->channel_layout);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
}
if (!avctx->rc_initial_buffer_occupancy)
@@ -646,24 +698,22 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
}
- if (av_codec_is_decoder(avctx->codec)) {
- /* validate channel layout from the decoder */
- if (avctx->channel_layout) {
- int channels =
av_get_channel_layout_nb_channels(avctx->channel_layout);
- if (!avctx->channels)
- avctx->channels = channels;
- else if (channels != avctx->channels) {
- av_log(avctx, AV_LOG_WARNING,
- "channel layout does not match number of channels\n");
- avctx->channel_layout = 0;
- }
- }
- if (avctx->channels && avctx->channels < 0 ||
- avctx->channels > FF_SANE_NB_CHANNELS) {
- ret = AVERROR(EINVAL);
- goto free_and_end;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ||
+ avctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
+ if (avctx->channel_layout && avctx->channel_layout !=
avctx->ch_layout.u.mask)
+ av_channel_layout_from_mask(&avctx->ch_layout,
avctx->channel_layout);
+ else if (avctx->channels && avctx->channels !=
avctx->ch_layout.nb_channels)
+ av_channel_layout_default(&avctx->ch_layout, avctx->channels);
+ if (avctx->ch_layout.nb_channels) {
+ avctx->channel_layout = avctx->ch_layout.u.mask;
+ avctx->channels = avctx->ch_layout.nb_channels;
}
}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
end:
if (!(codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE) && codec->init)
{
entangled_thread_counter--;
@@ -764,6 +814,8 @@ av_cold int avcodec_close(AVCodecContext *avctx)
av_freep(&avctx->internal);
}
+ av_channel_layout_uninit(&avctx->ch_layout);
+
for (i = 0; i < avctx->nb_coded_side_data; i++)
av_freep(&avctx->coded_side_data[i].data);
av_freep(&avctx->coded_side_data);
@@ -859,7 +911,7 @@ static int get_bit_rate(AVCodecContext *ctx)
break;
case AVMEDIA_TYPE_AUDIO:
bits_per_sample = av_get_bits_per_sample(ctx->codec_id);
- bit_rate = bits_per_sample ? ctx->sample_rate * ctx->channels *
bits_per_sample : ctx->bit_rate;
+ bit_rate = bits_per_sample ? ctx->sample_rate *
ctx->ch_layout.nb_channels * bits_per_sample : ctx->bit_rate;
break;
default:
bit_rate = 0;
@@ -1004,7 +1056,13 @@ void avcodec_string(char *buf, int buf_size,
AVCodecContext *enc, int encode)
snprintf(buf + strlen(buf), buf_size - strlen(buf),
"%d Hz, ", enc->sample_rate);
}
- av_get_channel_layout_string(buf + strlen(buf), buf_size -
strlen(buf), enc->channels, enc->channel_layout);
+
+ if (av_channel_layout_check(&enc->ch_layout)) {
+ char *chlstr = av_channel_layout_describe(&enc->ch_layout);
+ av_strlcat(buf, chlstr, buf_size);
+ av_free(chlstr);
+ }
+
if (enc->sample_fmt != AV_SAMPLE_FMT_NONE) {
snprintf(buf + strlen(buf), buf_size - strlen(buf),
", %s", av_get_sample_fmt_name(enc->sample_fmt));
@@ -1292,8 +1350,15 @@ static int get_audio_frame_duration(enum AVCodecID id,
int sr, int ch, int ba,
int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes)
{
+ int channels = avctx->ch_layout.nb_channels;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (!channels)
+ channels = avctx->channels;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
return get_audio_frame_duration(avctx->codec_id, avctx->sample_rate,
- avctx->channels, avctx->block_align,
+ channels, avctx->block_align,
avctx->codec_tag,
avctx->bits_per_coded_sample,
frame_bytes);
}
@@ -1601,6 +1666,8 @@ int avcodec_parameters_copy(AVCodecParameters *dst, const
AVCodecParameters *src
int avcodec_parameters_from_context(AVCodecParameters *par,
const AVCodecContext *codec)
{
+ int ret;
+
codec_parameters_reset(par);
par->codec_type = codec->codec_type;
@@ -1627,16 +1694,23 @@ int avcodec_parameters_from_context(AVCodecParameters
*par,
break;
case AVMEDIA_TYPE_AUDIO:
par->format = codec->sample_fmt;
+ ret = av_channel_layout_copy(&par->ch_layout, &codec->ch_layout);
+ if (ret < 0)
+ return ret;
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGS
- par->channel_layout = codec->channel_layout;
- par->channels = codec->channels;
+ if (!av_channel_layout_check(&codec->ch_layout))
+ if (codec->channel_layout)
+ av_channel_layout_from_mask(&par->ch_layout,
codec->channel_layout);
+ else
+ av_channel_layout_default(&par->ch_layout, codec->channels);
+ if (codec->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ||
+ codec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
+ par->channel_layout = codec->channel_layout;
+ par->channels = codec->channels;
+ }
FF_ENABLE_DEPRECATION_WARNINGS
#endif
- if (codec->channel_layout)
- av_channel_layout_from_mask(&par->ch_layout,
codec->channel_layout);
- else
- av_channel_layout_default(&par->ch_layout, codec->channels);
par->sample_rate = codec->sample_rate;
par->block_align = codec->block_align;
par->initial_padding = codec->initial_padding;
@@ -1657,6 +1731,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
int avcodec_parameters_to_context(AVCodecContext *codec,
const AVCodecParameters *par)
{
+ int ret;
+
codec->codec_type = par->codec_type;
codec->codec_id = par->codec_id;
codec->codec_tag = par->codec_tag;
@@ -1681,16 +1757,18 @@ int avcodec_parameters_to_context(AVCodecContext *codec,
break;
case AVMEDIA_TYPE_AUDIO:
codec->sample_fmt = par->format;
+ ret = av_channel_layout_copy(&codec->ch_layout, &par->ch_layout);
+ if (ret < 0)
+ return ret;
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGS
- codec->channel_layout = par->channel_layout;
- codec->channels = par->channels;
+ if (par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ||
+ par->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
+ codec->channel_layout = par->ch_layout.u.mask;
+ codec->channels = par->ch_layout.nb_channels;
+ }
FF_ENABLE_DEPRECATION_WARNINGS
#endif
- if (par->ch_layout.u.mask)
- codec->channel_layout = par->ch_layout.u.mask;
- if (par->ch_layout.nb_channels)
- codec->channels = par->ch_layout.nb_channels;
codec->sample_rate = par->sample_rate;
codec->block_align = par->block_align;
codec->initial_padding = par->initial_padding;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index c8bb04aa70..b12e91f78b 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1862,11 +1862,18 @@ static void estimate_timings(AVFormatContext *ic,
int64_t old_offset)
static int has_codec_parameters(AVStream *st)
{
AVCodecContext *avctx = st->internal->avctx;
- int val;
+ int val, ch;
switch (avctx->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- val = avctx->sample_rate && avctx->channels;
+ ch = avctx->ch_layout.nb_channels;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (!ch)
+ ch = avctx->channels;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ val = avctx->sample_rate && ch;
if (st->info->found_decoder >= 0 &&
avctx->sample_fmt == AV_SAMPLE_FMT_NONE)
return 0;
@@ -1965,6 +1972,21 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
}
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ /* temporary compatibility layer */
+ if (!avctx->ch_layout.nb_channels) {
+ av_channel_layout_uninit(&avctx->ch_layout);
+ if (avctx->channel_layout)
+ av_channel_layout_from_mask(&avctx->ch_layout,
avctx->channel_layout);
+ else {
+ avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
+ avctx->ch_layout.nb_channels = avctx->channels;
+ }
+ }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
fail:
av_frame_free(&frame);
return ret;
--
2.13.1
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel