Additionally, support Japanese DTV version which uses the different coefficiency from the AAC standard. (ref. ARIB STD-B21 6.2.1)
Signed-off-by: Akihiro Tsukada <[email protected]> --- libavcodec/aacdec.c | 75 +++++++++++++++++++++++++++++++++++++++++++++- libavcodec/mpeg4audio.h | 3 ++ 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index 24b3702..3a01cc7 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -588,8 +588,13 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, if (get_bits1(gb)) skip_bits(gb, 4); // stereo_mixdown_tag - if (get_bits1(gb)) - skip_bits(gb, 3); // mixdown_coeff_index and pseudo_surround + if (get_bits1(gb)) { // mixdown_coeff_index and pseudo_surround + m4ac->dmatrix_idx = get_bits(gb, 2); + m4ac->p_surround = get_bits1(gb); + } else { + m4ac->dmatrix_idx = -1; + m4ac->p_surround = 0; + } decode_channel_map(layout_map , AAC_CHANNEL_FRONT, gb, num_front); tags = num_front; @@ -2371,6 +2376,67 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb) return size; } +/** + * Matrix mixdown of 5ch/5.1ch audio into mono/stereo. reference: 8.5.3 + * (Japanse DTV reference: ARIB STD-B21 table 6-DM1, 6-DM2) + */ +static void aac_downmix5ch(AVCodecContext *avctx, AACContext *ac) +{ + static const float coef[4] = {M_SQRT1_2, 0.5, 0.5 * M_SQRT1_2, 0.0}; + float a, k; + float *l, *r, *c, *ls, *rs; + int i; + int have_lfe; + + avctx->channels = avctx->request_channels; + have_lfe = !!(ac->oc[1].channel_layout & AV_CH_LOW_FREQUENCY); + + k = (ac->oc[1].m4ac.dmatrix_idx >= 0) ? + coef[ac->oc[1].m4ac.dmatrix_idx] : coef[0]; + + l = ac->output_data[0]; + r = ac->output_data[1]; + c = ac->output_data[2]; + ls = ac->output_data[3 + have_lfe]; + rs = ac->output_data[4 + have_lfe]; + + /* 5[.1]ch -> mono */ + if (avctx->request_channels == 1) { + a = 1.0 / (3.0 + 2.0 * k); + for (i = 0; i < 1024; i++) + ac->output_data[0][i] = a * (*(l++) + *(c++) + *(r++) + + k * (*(ls++) + *(rs++))); + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + return; + } + + /* 5[.1]ch -> stereo */ + + if (ac->jp_dtv_mode) + a = M_SQRT1_2; + else if (ac->oc[1].m4ac.p_surround) + a = 1.0 / (1.0 + M_SQRT1_2 + 2.0 * k); + else + a = 1.0 / (1.0 + M_SQRT1_2 + k); + + if (!ac->oc[1].m4ac.p_surround) { + for (i = 0; i < 1024; i++) { + ac->output_data[0][i] = a * (*l + M_SQRT1_2 * *c + k * *ls); + ac->output_data[1][i] = a * (*r + M_SQRT1_2 * *c + k * *rs); + l++; r++; c++; ls++; rs++; + } + } else { + for (i = 0; i < 1024; i++) { + ac->output_data[0][i] = a * (*l + M_SQRT1_2 * *c - k * (*ls + *rs)); + ac->output_data[1][i] = a * (*r + M_SQRT1_2 * *c + k * (*ls + *rs)); + l++; r++; c++; ls++; rs++; + } + } + avctx->channels = 2; + avctx->channel_layout = AV_CH_LAYOUT_STEREO; +} + static int aac_decode_frame_int(AVCodecContext *avctx, void *data, int *got_frame_ptr, GetBitContext *gb) { @@ -2492,6 +2558,11 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, multiplier = (ac->oc[1].m4ac.sbr == 1) ? ac->oc[1].m4ac.ext_sample_rate > ac->oc[1].m4ac.sample_rate : 0; samples <<= multiplier; + if (avctx->request_channels <= 2 && + (ac->oc[1].channel_layout == AV_CH_LAYOUT_5POINT0 || + ac->oc[1].channel_layout == AV_CH_LAYOUT_5POINT1)) + aac_downmix5ch(avctx, ac); + /* for dual-mono audio (SCE + SCE) */ is_dmono = ac->jp_dtv_mode && sce_count == 2 && ac->oc[1].channel_layout == (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT); diff --git a/libavcodec/mpeg4audio.h b/libavcodec/mpeg4audio.h index 7560f3f..f89fc3f 100644 --- a/libavcodec/mpeg4audio.h +++ b/libavcodec/mpeg4audio.h @@ -38,6 +38,9 @@ typedef struct { int ext_chan_config; int channels; int ps; ///< -1 implicit, 1 presence + + int dmatrix_idx; ///< index of the coef. of matrix downmix, or -1 for none + int p_surround; ///< pseudo surround enabled. 1: enabled } MPEG4AudioConfig; extern const int avpriv_mpeg4audio_sample_rates[16]; -- 1.7.7.6 _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
