Signed-off-by: Vittorio Giovara <vittorio.giov...@gmail.com> --- libavcodec/aac.h | 7 +++-- libavcodec/aac_ac3_parser.c | 9 ++++-- libavcodec/aaccoder.c | 2 +- libavcodec/aacdec.c | 76 ++++++++++++++++++++++++++++++++++++++------- libavcodec/aacdectab.h | 16 ++++++++++ libavcodec/aacenc.c | 2 +- libavcodec/aacpsy.c | 10 +++--- 7 files changed, 99 insertions(+), 23 deletions(-)
diff --git a/libavcodec/aac.h b/libavcodec/aac.h index fed6bf4214..b72af09ca0 100644 --- a/libavcodec/aac.h +++ b/libavcodec/aac.h @@ -30,6 +30,7 @@ #ifndef AVCODEC_AAC_H #define AVCODEC_AAC_H +#include "libavutil/channel_layout.h" #include "libavutil/float_dsp.h" #include "avcodec.h" #include "imdct15.h" @@ -116,8 +117,7 @@ typedef struct OutputConfiguration { MPEG4AudioConfig m4ac; uint8_t layout_map[MAX_ELEM_ID*4][3]; int layout_map_tags; - int channels; - uint64_t channel_layout; + AVChannelLayout ch_layout; enum OCStatus status; } OutputConfiguration; @@ -260,6 +260,7 @@ typedef struct ChannelElement { * main AAC context */ typedef struct AACContext { + const AVClass *class; AVCodecContext *avctx; AVFrame *frame; @@ -306,6 +307,8 @@ typedef struct AACContext { DECLARE_ALIGNED(32, float, temp)[128]; OutputConfiguration oc[2]; + + AVChannelLayout downmix_layout; } AACContext; #endif /* AVCODEC_AAC_H */ diff --git a/libavcodec/aac_ac3_parser.c b/libavcodec/aac_ac3_parser.c index a754f4a957..17e88435f8 100644 --- a/libavcodec/aac_ac3_parser.c +++ b/libavcodec/aac_ac3_parser.c @@ -82,8 +82,13 @@ get_next: seconds is still correct (as is the number of bits in the frame). */ if (avctx->codec_id != AV_CODEC_ID_AAC) { avctx->sample_rate = s->sample_rate; - avctx->channels = s->channels; - avctx->channel_layout = s->channel_layout; + + av_channel_layout_uninit(&avctx->ch_layout); + if (s->channel_layout) + av_channel_layout_from_mask(&avctx->ch_layout, s->channel_layout); + else + av_channel_layout_default(&avctx->ch_layout, s->channels); + s1->duration = s->samples; avctx->audio_service_type = s->service_type; } diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c index a654844cd0..ec936d89ad 100644 --- a/libavcodec/aaccoder.c +++ b/libavcodec/aaccoder.c @@ -710,7 +710,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, const float lambda) { int start = 0, i, w, w2, g; - int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels * (lambda / 120.f); + int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->ch_layout.nb_channels * (lambda / 120.f); float dists[128] = { 0 }, uplims[128]; float maxvals[128]; int fflag, minscaler; diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index e436b4f2f7..ab184b8634 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -81,6 +81,7 @@ */ #include "libavutil/float_dsp.h" +#include "libavutil/opt.h" #include "avcodec.h" #include "internal.h" #include "get_bits.h" @@ -193,7 +194,7 @@ static int frame_configure_elements(AVCodecContext *avctx) } /* map output channel pointers to AVFrame data */ - for (ch = 0; ch < avctx->channels; ch++) { + for (ch = 0; ch < avctx->ch_layout.nb_channels; ch++) { if (ac->output_element[ch]) ac->output_element[ch]->ret = (float *)ac->frame->extended_data[ch]; } @@ -432,8 +433,7 @@ static void push_output_configuration(AACContext *ac) { static void pop_output_configuration(AACContext *ac) { if (ac->oc[1].status != OC_LOCKED && ac->oc[0].status != OC_NONE) { ac->oc[1] = ac->oc[0]; - ac->avctx->channels = ac->oc[1].channels; - ac->avctx->channel_layout = ac->oc[1].channel_layout; + av_channel_layout_copy(&ac->avctx->ch_layout, &ac->oc[1].ch_layout); } } @@ -464,7 +464,15 @@ static int output_configure(AACContext *ac, } // Try to sniff a reasonable channel order, otherwise output the // channels in the order the PCE declared them. - if (avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE) +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->request_channel_layout) { + av_channel_layout_uninit(&ac->downmix_layout); + av_channel_layout_from_mask(&ac->downmix_layout, avctx->request_channel_layout); + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (ac->downmix_layout.order == AV_CHANNEL_ORDER_NATIVE) layout = sniff_channel_order(layout_map, tags); for (i = 0; i < tags; i++) { int type = layout_map[i][0]; @@ -486,8 +494,18 @@ static int output_configure(AACContext *ac, } } - avctx->channel_layout = ac->oc[1].channel_layout = layout; - avctx->channels = ac->oc[1].channels = channels; + av_channel_layout_uninit(&ac->oc[1].ch_layout); + av_channel_layout_from_mask(&ac->oc[1].ch_layout, layout); + ret = av_channel_layout_copy(&avctx->ch_layout, &ac->oc[1].ch_layout); + if (ret < 0) + return ret; +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + avctx->channels = avctx->ch_layout.nb_channels; + avctx->channel_layout = layout; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + ac->oc[1].status = oc_type; if (get_new_frame) { @@ -1073,12 +1091,12 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) sr = sample_rate_idx(avctx->sample_rate); ac->oc[1].m4ac.sampling_index = sr; - ac->oc[1].m4ac.channels = avctx->channels; + ac->oc[1].m4ac.channels = avctx->ch_layout.nb_channels; ac->oc[1].m4ac.sbr = -1; ac->oc[1].m4ac.ps = -1; for (i = 0; i < FF_ARRAY_ELEMS(ff_mpeg4audio_channels); i++) - if (ff_mpeg4audio_channels[i] == avctx->channels) + if (ff_mpeg4audio_channels[i] == avctx->ch_layout.nb_channels) break; if (i == FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) { i = 0; @@ -2226,7 +2244,8 @@ static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt, av_log(ac->avctx, AV_LOG_ERROR, "Implicit SBR was found with a first occurrence after the first frame.\n"); skip_bits_long(gb, 8 * cnt - 4); return res; - } else if (ac->oc[1].m4ac.ps == -1 && ac->oc[1].status < OC_LOCKED && ac->avctx->channels == 1) { + } else if (ac->oc[1].m4ac.ps == -1 && ac->oc[1].status < OC_LOCKED && + ac->avctx->ch_layout.nb_channels == 1) { ac->oc[1].m4ac.sbr = 1; ac->oc[1].m4ac.ps = 1; ac->avctx->profile = FF_PROFILE_AAC_HE_V2; @@ -2832,7 +2851,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, } } - if (avctx->channels) + if (avctx->ch_layout.nb_channels) if ((err = frame_configure_elements(avctx)) < 0) goto fail; @@ -2845,7 +2864,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, while ((elem_type = get_bits(gb, 3)) != TYPE_END) { elem_id = get_bits(gb, 4); - if (!avctx->channels && elem_type != TYPE_PCE) { + if (!avctx->ch_layout.nb_channels && elem_type != TYPE_PCE) { err = AVERROR_INVALIDDATA; goto fail; } @@ -2936,7 +2955,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, } } - if (!avctx->channels) { + if (!avctx->ch_layout.nb_channels) { *got_frame_ptr = 0; return 0; } @@ -3318,6 +3337,20 @@ static av_cold int latm_decode_init(AVCodecContext *avctx) return ret; } +#define OFFSET(x) offsetof(AACContext, x) +#define A AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM +static const AVOption options[] = { + { "downmix", "Request a specific channel layout from the decoder", + OFFSET(downmix_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.str = NULL}, .flags = A }, + { NULL }, +}; + +static const AVClass aacdec_class = { + .class_name = "AAC decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; AVCodec ff_aac_decoder = { .name = "aac", @@ -3325,6 +3358,7 @@ AVCodec ff_aac_decoder = { .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AAC, .priv_data_size = sizeof(AACContext), + .priv_class = &aacdec_class, .init = aac_decode_init, .close = aac_decode_close, .decode = aac_decode_frame, @@ -3333,7 +3367,19 @@ AVCodec ff_aac_decoder = { }, .capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS .channel_layouts = aac_channel_layout, +FF_ENABLE_DEPRECATION_WARNINGS +#endif + .ch_layouts = aac_ch_layouts, +}; + +static const AVClass aaclatmdec_class = { + .class_name = "AAC-LATM decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, }; /* @@ -3347,6 +3393,7 @@ AVCodec ff_aac_latm_decoder = { .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AAC_LATM, .priv_data_size = sizeof(struct LATMContext), + .priv_class = &aaclatmdec_class, .init = latm_decode_init, .close = aac_decode_close, .decode = latm_decode_frame, @@ -3355,5 +3402,10 @@ AVCodec ff_aac_latm_decoder = { }, .capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS .channel_layouts = aac_channel_layout, +FF_ENABLE_DEPRECATION_WARNINGS +#endif + .ch_layouts = aac_ch_layouts, }; diff --git a/libavcodec/aacdectab.h b/libavcodec/aacdectab.h index b7c5f7e719..35773f36d4 100644 --- a/libavcodec/aacdectab.h +++ b/libavcodec/aacdectab.h @@ -114,4 +114,20 @@ static const uint64_t aac_channel_layout[16] = { /* AV_CH_LAYOUT_7POINT1_TOP, */ }; +static const AVChannelLayout aac_ch_layouts[16] = { + AV_CHANNEL_LAYOUT_MONO, + AV_CHANNEL_LAYOUT_STEREO, + AV_CHANNEL_LAYOUT_SURROUND, + AV_CHANNEL_LAYOUT_4POINT0, + AV_CHANNEL_LAYOUT_5POINT0_BACK, + AV_CHANNEL_LAYOUT_5POINT1_BACK, + AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK, + { 0 }, + { 0 }, + { 0 }, + AV_CHANNEL_LAYOUT_6POINT1, + AV_CHANNEL_LAYOUT_7POINT1, + { 0 }, +}; + #endif /* AVCODEC_AACDECTAB_H */ diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index b7f60fb872..ad14007011 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -739,7 +739,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[i]) break; - s->channels = avctx->channels; + s->channels = avctx->ch_layout.nb_channels; ERROR_IF(i == 16, "Unsupported sample rate %d\n", avctx->sample_rate); diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c index 272be9f137..886728cf30 100644 --- a/libavcodec/aacpsy.c +++ b/libavcodec/aacpsy.c @@ -253,13 +253,13 @@ static av_cold void lame_window_init(AacPsyContext *ctx, AVCodecContext *avctx) { int i, j; - for (i = 0; i < avctx->channels; i++) { + for (i = 0; i < avctx->ch_layout.nb_channels; i++) { AacPsyChannel *pch = &ctx->ch[i]; if (avctx->flags & AV_CODEC_FLAG_QSCALE) pch->attack_threshold = psy_vbr_map[avctx->global_quality / FF_QP2LAMBDA].st_lrm; else - pch->attack_threshold = lame_calc_attack_threshold(avctx->bit_rate / avctx->channels / 1000); + pch->attack_threshold = lame_calc_attack_threshold(avctx->bit_rate / avctx->ch_layout.nb_channels / 1000); for (j = 0; j < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; j++) pch->prev_energy_subshort[j] = 10.0f; @@ -293,7 +293,7 @@ static av_cold int psy_3gpp_init(FFPsyContext *ctx) { float bark; int i, j, g, start; float prev, minscale, minath, minsnr, pe_min; - const int chan_bitrate = ctx->avctx->bit_rate / ctx->avctx->channels; + const int chan_bitrate = ctx->avctx->bit_rate / ctx->avctx->ch_layout.nb_channels; const int bandwidth = ctx->avctx->cutoff ? ctx->avctx->cutoff : ctx->avctx->sample_rate / 2; const float num_bark = calc_bark((float)bandwidth); @@ -350,7 +350,7 @@ static av_cold int psy_3gpp_init(FFPsyContext *ctx) { } } - pctx->ch = av_mallocz(sizeof(AacPsyChannel) * ctx->avctx->channels); + pctx->ch = av_mallocz(sizeof(AacPsyChannel) * ctx->avctx->ch_layout.nb_channels); if (!pctx->ch) { av_freep(&pctx); return AVERROR(ENOMEM); @@ -391,7 +391,7 @@ static av_unused FFPsyWindowInfo psy_3gpp_window(FFPsyContext *ctx, int channel, int prev_type) { int i, j; - int br = ctx->avctx->bit_rate / ctx->avctx->channels; + int br = ctx->avctx->bit_rate / ctx->avctx->ch_layout.nb_channels; int attack_ratio = br <= 16000 ? 18 : 10; AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data; AacPsyChannel *pch = &pctx->ch[channel]; -- 2.13.1 _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel