From: Michael Niedermayer Date: Fri, 29 Nov 2013 03:00:59 +0000 (+0100) Subject: Merge commit 'aaa44d0299338e3bc90128816c21dbfab06cdb48' X-Git-Tag: android-x86-6.0-r1~8675 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=97468463a239a6767a9c7ad0ed2f9f03e61f5d1a;p=android-x86%2Fexternal-ffmpeg.git Merge commit 'aaa44d0299338e3bc90128816c21dbfab06cdb48' * commit 'aaa44d0299338e3bc90128816c21dbfab06cdb48': dca: support mixing LFE in dca_downmix. Conflicts: libavcodec/dcadec.c Merged-by: Michael Niedermayer --- 97468463a239a6767a9c7ad0ed2f9f03e61f5d1a diff --cc libavcodec/dcadec.c index 3301a1a15d,cd4f18825b..3e3a562d7c --- a/libavcodec/dcadec.c +++ b/libavcodec/dcadec.c @@@ -2145,55 -1733,6 +2154,54 @@@ static int dca_decode_frame(AVCodecCont /* record number of core channels incase less than max channels are requested */ num_core_channels = s->prim_channels; - if (s->prim_channels > 2 && ++ if (s->prim_channels + !!s->lfe > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { - /* Stereo downmix coefficients - * - * The decoder can only downmix to 2-channel, so we need to ensure - * embedded downmix coefficients are actually targeting 2-channel. - * - * Coefficients for the LFE channel are ignored (not supported) */ - if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO || - s->core_downmix_amode == DCA_STEREO_TOTAL)) { - int sign, code; - for (i = 0; i < s->prim_channels; i++) { - sign = s->core_downmix_codes[i][0] & 0x100 ? 1 : -1; - code = s->core_downmix_codes[i][0] & 0x0FF; - s->downmix_coef[i][0] = (!code ? 0.0f : - sign * dca_dmixtable[code - 1]); - sign = s->core_downmix_codes[i][1] & 0x100 ? 1 : -1; - code = s->core_downmix_codes[i][1] & 0x0FF; - s->downmix_coef[i][1] = (!code ? 0.0f : - sign * dca_dmixtable[code - 1]); - } - } else { - int am = s->amode & DCA_CHANNEL_MASK; - if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) { - av_log(s->avctx, AV_LOG_ERROR, - "Invalid channel mode %d\n", am); - return AVERROR_INVALIDDATA; - } - - if (s->prim_channels > FF_ARRAY_ELEMS(dca_default_coeffs[0])) { - avpriv_request_sample(s->avctx, "Downmixing %d channels", - s->prim_channels); - return AVERROR_PATCHWELCOME; ++ /* Stereo downmix coefficients ++ * ++ * The decoder can only downmix to 2-channel, so we need to ensure ++ * embedded downmix coefficients are actually targeting 2-channel. ++ */ ++ if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO || ++ s->core_downmix_amode == DCA_STEREO_TOTAL)) { ++ int sign, code; ++ for (i = 0; i < s->prim_channels + !!s->lfe; i++) { ++ sign = s->core_downmix_codes[i][0] & 0x100 ? 1 : -1; ++ code = s->core_downmix_codes[i][0] & 0x0FF; ++ s->downmix_coef[i][0] = (!code ? 0.0f : ++ sign * dca_dmixtable[code - 1]); ++ sign = s->core_downmix_codes[i][1] & 0x100 ? 1 : -1; ++ code = s->core_downmix_codes[i][1] & 0x0FF; ++ s->downmix_coef[i][1] = (!code ? 0.0f : ++ sign * dca_dmixtable[code - 1]); ++ } ++ } else { ++ int am = s->amode & DCA_CHANNEL_MASK; ++ if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) { ++ av_log(s->avctx, AV_LOG_ERROR, ++ "Invalid channel mode %d\n", am); ++ return AVERROR_INVALIDDATA; ++ } ++ if (s->prim_channels + !!s->lfe > ++ FF_ARRAY_ELEMS(dca_default_coeffs[0])) { ++ avpriv_request_sample(s->avctx, "Downmixing %d channels", ++ s->prim_channels + !!s->lfe); ++ return AVERROR_PATCHWELCOME; ++ } ++ for (i = 0; i < s->prim_channels + !!s->lfe; i++) { ++ s->downmix_coef[i][0] = dca_default_coeffs[am][i][0]; ++ s->downmix_coef[i][1] = dca_default_coeffs[am][i][1]; ++ } + } - for (i = 0; i < s->prim_channels; i++) { - s->downmix_coef[i][0] = dca_default_coeffs[am][i][0]; - s->downmix_coef[i][1] = dca_default_coeffs[am][i][1]; ++ av_dlog(s->avctx, "Stereo downmix coeffs:\n"); ++ for (i = 0; i < s->prim_channels + !!s->lfe; i++) { ++ av_dlog(s->avctx, "L, input channel %d = %f\n", i, ++ s->downmix_coef[i][0]); ++ av_dlog(s->avctx, "R, input channel %d = %f\n", i, ++ s->downmix_coef[i][1]); + } - } - av_dlog(s->avctx, "Stereo downmix coeffs:\n"); - for (i = 0; i < s->prim_channels; i++) { - av_dlog(s->avctx, "L, input channel %d = %f\n", i, - s->downmix_coef[i][0]); - av_dlog(s->avctx, "R, input channel %d = %f\n", i, - s->downmix_coef[i][1]); - } - av_dlog(s->avctx, "\n"); ++ av_dlog(s->avctx, "\n"); + } + if (s->ext_coding) s->core_ext_mask = dca_ext_audio_descr_mask[s->ext_descr]; else @@@ -2302,137 -1835,94 +2310,137 @@@ full_channels = channels = s->prim_channels + !!s->lfe; - if (s->amode < 16) { - avctx->channel_layout = dca_core_channel_layout[s->amode]; - + /* If we have XXCH then the channel layout is managed differently */ + /* note that XLL will also have another way to do things */ + if (!(s->core_ext_mask & DCA_EXT_XXCH) + || (s->core_ext_mask & DCA_EXT_XXCH && avctx->request_channels > 0 + && avctx->request_channels + < num_core_channels + !!s->lfe + s->xxch_chset_nch[0])) + { /* xxx should also do MA extensions */ + if (s->amode < 16) { + avctx->channel_layout = dca_core_channel_layout[s->amode]; #if FF_API_REQUEST_CHANNELS FF_DISABLE_DEPRECATION_WARNINGS - if (s->xch_present && (!avctx->request_channels || - avctx->request_channels > num_core_channels + !!s->lfe)) { + if (s->xch_present && (!avctx->request_channels || + avctx->request_channels + > num_core_channels + !!s->lfe)) { FF_ENABLE_DEPRECATION_WARNINGS #else - if (s->xch_present) { + if (s->xch_present) { #endif - avctx->channel_layout |= AV_CH_BACK_CENTER; - if (s->lfe) { - avctx->channel_layout |= AV_CH_LOW_FREQUENCY; - s->channel_order_tab = dca_channel_reorder_lfe_xch[s->amode]; + avctx->channel_layout |= AV_CH_BACK_CENTER; + if (s->lfe) { + avctx->channel_layout |= AV_CH_LOW_FREQUENCY; + s->channel_order_tab = dca_channel_reorder_lfe_xch[s->amode]; + } else { + s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode]; + } + if (s->channel_order_tab[s->xch_base_channel] < 0) + return AVERROR_INVALIDDATA; } else { - s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode]; + channels = num_core_channels + !!s->lfe; + s->xch_present = 0; /* disable further xch processing */ + if (s->lfe) { + avctx->channel_layout |= AV_CH_LOW_FREQUENCY; + s->channel_order_tab = dca_channel_reorder_lfe[s->amode]; + } else + s->channel_order_tab = dca_channel_reorder_nolfe[s->amode]; + } + + if (channels > !!s->lfe && + s->channel_order_tab[channels - 1 - !!s->lfe] < 0) + return AVERROR_INVALIDDATA; + + if (av_get_channel_layout_nb_channels(avctx->channel_layout) != channels) { + av_log(avctx, AV_LOG_ERROR, "Number of channels %d mismatches layout %d\n", channels, av_get_channel_layout_nb_channels(avctx->channel_layout)); + return AVERROR_INVALIDDATA; + } + - if (s->prim_channels > 2 && ++ if (s->prim_channels + !!s->lfe > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { + channels = 2; + s->output = DCA_STEREO; + avctx->channel_layout = AV_CH_LAYOUT_STEREO; + } + else if (avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE) { + static const int8_t dca_channel_order_native[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; + s->channel_order_tab = dca_channel_order_native; } + s->lfe_index = dca_lfe_index[s->amode]; } else { + av_log(avctx, AV_LOG_ERROR, + "Non standard configuration %d !\n", s->amode); + return AVERROR_INVALIDDATA; + } + + s->xxch_dmix_embedded = 0; + } else { + /* we only get here if an XXCH channel set can be added to the mix */ + channel_mask = s->xxch_core_spkmask; + + if (avctx->request_channels > 0 + && avctx->request_channels < s->prim_channels) { channels = num_core_channels + !!s->lfe; - s->xch_present = 0; /* disable further xch processing */ - if (s->lfe) { - avctx->channel_layout |= AV_CH_LOW_FREQUENCY; - s->channel_order_tab = dca_channel_reorder_lfe[s->amode]; - } else - s->channel_order_tab = dca_channel_reorder_nolfe[s->amode]; + for (i = 0; i < s->xxch_chset && channels + s->xxch_chset_nch[i] + <= avctx->request_channels; i++) { + channels += s->xxch_chset_nch[i]; + channel_mask |= s->xxch_spk_masks[i]; + } + } else { + channels = s->prim_channels + !!s->lfe; + for (i = 0; i < s->xxch_chset; i++) { + channel_mask |= s->xxch_spk_masks[i]; + } } - if (channels > !!s->lfe && - s->channel_order_tab[channels - 1 - !!s->lfe] < 0) - return AVERROR_INVALIDDATA; + /* Given the DTS spec'ed channel mask, generate an avcodec version */ + channel_layout = 0; + for (i = 0; i < s->xxch_nbits_spk_mask; ++i) { + if (channel_mask & (1 << i)) { + channel_layout |= map_xxch_to_native[i]; + } + } - if (s->prim_channels + !!s->lfe > 2 && - avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { - channels = 2; - s->output = DCA_STEREO; - avctx->channel_layout = AV_CH_LAYOUT_STEREO; + /* make sure that we have managed to get equivelant dts/avcodec channel + * masks in some sense -- unfortunately some channels could overlap */ + if (av_popcount(channel_mask) != av_popcount(channel_layout)) { + av_log(avctx, AV_LOG_DEBUG, + "DTS-XXCH: Inconsistant avcodec/dts channel layouts\n"); + return AVERROR_INVALIDDATA; + } - /* Stereo downmix coefficients - * - * The decoder can only downmix to 2-channel, so we need to ensure - * embedded downmix coefficients are actually targeting 2-channel. - */ - if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO || - s->core_downmix_amode == DCA_STEREO_TOTAL)) { - int sign, code; - for (i = 0; i < s->prim_channels + !!s->lfe; i++) { - sign = s->core_downmix_codes[i][0] & 0x100 ? 1 : -1; - code = s->core_downmix_codes[i][0] & 0x0FF; - s->downmix_coef[i][0] = (!code ? 0.0f : - sign * dca_dmixtable[code - 1]); - sign = s->core_downmix_codes[i][1] & 0x100 ? 1 : -1; - code = s->core_downmix_codes[i][1] & 0x0FF; - s->downmix_coef[i][1] = (!code ? 0.0f : - sign * dca_dmixtable[code - 1]); - } - } else { - int am = s->amode & DCA_CHANNEL_MASK; - if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) { - av_log(s->avctx, AV_LOG_ERROR, - "Invalid channel mode %d\n", am); - return AVERROR_INVALIDDATA; - } - if (s->prim_channels + !!s->lfe > - FF_ARRAY_ELEMS(dca_default_coeffs[0])) { - avpriv_request_sample(s->avctx, "Downmixing %d channels", - s->prim_channels + !!s->lfe); - return AVERROR_PATCHWELCOME; - } - for (i = 0; i < s->prim_channels + !!s->lfe; i++) { - s->downmix_coef[i][0] = dca_default_coeffs[am][i][0]; - s->downmix_coef[i][1] = dca_default_coeffs[am][i][1]; + avctx->channel_layout = channel_layout; + + if (!(avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE)) { + /* Estimate DTS --> avcodec ordering table */ + for (chset = -1, j = 0; chset < s->xxch_chset; ++chset) { + mask = chset >= 0 ? s->xxch_spk_masks[chset] + : s->xxch_core_spkmask; + for (i = 0; i < s->xxch_nbits_spk_mask; i++) { + if (mask & ~(DCA_XXCH_LFE1 | DCA_XXCH_LFE2) & (1 << i)) { + lavc = map_xxch_to_native[i]; + posn = av_popcount(channel_layout & (lavc - 1)); + s->xxch_order_tab[j++] = posn; + } } } - av_dlog(s->avctx, "Stereo downmix coeffs:\n"); - for (i = 0; i < s->prim_channels + !!s->lfe; i++) { - av_dlog(s->avctx, "L, input channel %d = %f\n", i, - s->downmix_coef[i][0]); - av_dlog(s->avctx, "R, input channel %d = %f\n", i, - s->downmix_coef[i][1]); - } - av_dlog(s->avctx, "\n"); + + s->lfe_index = av_popcount(channel_layout & (AV_CH_LOW_FREQUENCY-1)); + } else { /* native ordering */ + for (i = 0; i < channels; i++) + s->xxch_order_tab[i] = i; + + s->lfe_index = channels - 1; } - } else { - av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode); - return AVERROR_INVALIDDATA; + + s->channel_order_tab = s->xxch_order_tab; + } + + if (avctx->channels != channels) { + if (avctx->channels) + av_log(avctx, AV_LOG_INFO, "Number of channels changed in DCA decoder (%d -> %d)\n", avctx->channels, channels); + avctx->channels = channels; } - avctx->channels = channels; /* get output buffer */ frame->nb_samples = 256 * (s->sample_blocks / 8);