summaryrefslogtreecommitdiff
path: root/libavcodec/ac3dec.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/ac3dec.c')
-rw-r--r--libavcodec/ac3dec.c57
1 files changed, 37 insertions, 20 deletions
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index ae00373dcb..70b35c170f 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -32,6 +32,7 @@
#include "libavutil/channel_layout.h"
#include "libavutil/crc.h"
#include "libavutil/downmix_info.h"
+#include "libavutil/intmath.h"
#include "libavutil/opt.h"
#include "libavutil/thread.h"
#include "bswapdsp.h"
@@ -186,6 +187,8 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx)
{
static AVOnce init_static_once = AV_ONCE_INIT;
AC3DecodeContext *s = avctx->priv_data;
+ const AVChannelLayout mono = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
+ const AVChannelLayout stereo = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
int i, ret;
s->avctx = avctx;
@@ -214,12 +217,23 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx)
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
/* allow downmixing to stereo or mono */
- if (avctx->channels > 1 &&
- avctx->request_channel_layout == AV_CH_LAYOUT_MONO)
- avctx->channels = 1;
- else if (avctx->channels > 2 &&
- avctx->request_channel_layout == AV_CH_LAYOUT_STEREO)
- avctx->channels = 2;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->request_channel_layout) {
+ av_channel_layout_uninit(&s->downmix_layout);
+ av_channel_layout_from_mask(&s->downmix_layout, avctx->request_channel_layout);
+ }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ if (avctx->ch_layout.nb_channels > 1 &&
+ !av_channel_layout_compare(&s->downmix_layout, &mono)) {
+ av_channel_layout_uninit(&avctx->ch_layout);
+ avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
+ } else if (avctx->ch_layout.nb_channels > 2 &&
+ !av_channel_layout_compare(&s->downmix_layout, &stereo)) {
+ av_channel_layout_uninit(&avctx->ch_layout);
+ avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
+ }
s->downmixed = 1;
for (i = 0; i < AC3_MAX_CHANNELS; i++) {
@@ -1480,6 +1494,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
const SHORTFLOAT *output[AC3_MAX_CHANNELS];
enum AVMatrixEncoding matrix_encoding;
AVDownmixInfo *downmix_info;
+ uint64_t mask;
s->superframe_size = 0;
@@ -1590,11 +1605,11 @@ dependent_frame:
if (s->lfe_on)
s->output_mode |= AC3_OUTPUT_LFEON;
if (s->channels > 1 &&
- avctx->request_channel_layout == AV_CH_LAYOUT_MONO) {
+ !av_channel_layout_compare(&s->downmix_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO)) {
s->out_channels = 1;
s->output_mode = AC3_CHMODE_MONO;
} else if (s->channels > 2 &&
- avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
+ !av_channel_layout_compare(&s->downmix_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO)) {
s->out_channels = 2;
s->output_mode = AC3_CHMODE_STEREO;
}
@@ -1615,10 +1630,13 @@ dependent_frame:
av_log(avctx, AV_LOG_ERROR, "unable to determine channel mode\n");
return AVERROR_INVALIDDATA;
}
- avctx->channels = s->out_channels;
- avctx->channel_layout = ff_ac3_channel_layout_tab[s->output_mode & ~AC3_OUTPUT_LFEON];
+
+ mask = ff_ac3_channel_layout_tab[s->output_mode & ~AC3_OUTPUT_LFEON];
if (s->output_mode & AC3_OUTPUT_LFEON)
- avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
+ mask |= AV_CH_LOW_FREQUENCY;
+
+ av_channel_layout_uninit(&avctx->ch_layout);
+ av_channel_layout_from_mask(&avctx->ch_layout, mask);
/* set audio service type based on bitstream mode for AC-3 */
avctx->audio_service_type = s->bitstream_mode;
@@ -1714,20 +1732,20 @@ skip:
channel_layout |= ff_eac3_custom_channel_map_locations[ch][1];
}
}
- if (av_get_channel_layout_nb_channels(channel_layout) > EAC3_MAX_CHANNELS) {
+ if (av_popcount64(channel_layout) > EAC3_MAX_CHANNELS) {
av_log(avctx, AV_LOG_ERROR, "Too many channels (%d) coded\n",
- av_get_channel_layout_nb_channels(channel_layout));
+ av_popcount64(channel_layout));
return AVERROR_INVALIDDATA;
}
- avctx->channel_layout = channel_layout;
- avctx->channels = av_get_channel_layout_nb_channels(channel_layout);
+ av_channel_layout_uninit(&avctx->ch_layout);
+ av_channel_layout_from_mask(&avctx->ch_layout, channel_layout);
for (ch = 0; ch < EAC3_MAX_CHANNELS; ch++) {
if (s->channel_map & (1 << (EAC3_MAX_CHANNELS - ch - 1))) {
if (ff_eac3_custom_channel_map_locations[ch][0]) {
- int index = av_get_channel_layout_channel_index(channel_layout,
- ff_eac3_custom_channel_map_locations[ch][1]);
+ int index = av_channel_layout_index_from_channel(&avctx->ch_layout,
+ ff_ctzll(ff_eac3_custom_channel_map_locations[ch][1]));
if (index < 0)
return AVERROR_INVALIDDATA;
if (extend >= channel_map_size)
@@ -1739,8 +1757,7 @@ skip:
for (i = 0; i < 64; i++) {
if ((1ULL << i) & ff_eac3_custom_channel_map_locations[ch][1]) {
- int index = av_get_channel_layout_channel_index(channel_layout,
- 1ULL << i);
+ int index = av_channel_layout_index_from_channel(&avctx->ch_layout, i);
if (index < 0)
return AVERROR_INVALIDDATA;
if (extend >= channel_map_size)
@@ -1759,7 +1776,7 @@ skip:
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
- for (ch = 0; ch < avctx->channels; ch++) {
+ for (ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
int map = extended_channel_map[ch];
av_assert0(ch>=AV_NUM_DATA_POINTERS || frame->extended_data[ch] == frame->data[ch]);
memcpy((SHORTFLOAT *)frame->extended_data[ch],