diff options
author | Claudio Freire <klaussfreire@gmail.com> | 2016-01-10 03:04:21 -0300 |
---|---|---|
committer | Claudio Freire <klaussfreire@gmail.com> | 2016-01-13 05:28:34 -0300 |
commit | 699c2ee560532a5111a944d2653e9a3e484efc34 (patch) | |
tree | 9cfaf3565a9dbf2f5c2a7c7b0300c858c91ce8d3 | |
parent | aa64a483575be65eedb336ab949e865e441d1f85 (diff) | |
download | ffmpeg-699c2ee560532a5111a944d2653e9a3e484efc34.tar.gz |
AAC encoder: encode out-of-phase I/S efficiently
Use the ability to invert phase with ms_mask instead of changing
the codebook when possible, to avoid having to switch codebooks
if some bands are INTENSTY_BT and others are INTENSITY_BT2, since
usually a set ms_mask uses less bits that a codebook change. While
it may not always be a win (ie: if it causes an ms_mask bitmap
to be sent when it wouldn't have been otherwise), it's unlikely
since the ms_mask bitmap will almost always be there already for
M/S itself.
-rw-r--r-- | libavcodec/aacenc_is.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/libavcodec/aacenc_is.c b/libavcodec/aacenc_is.c index d77fcb5a98..405f178556 100644 --- a/libavcodec/aacenc_is.c +++ b/libavcodec/aacenc_is.c @@ -99,7 +99,7 @@ void ff_aac_search_for_is(AACEncContext *s, AVCodecContext *avctx, ChannelElemen { SingleChannelElement *sce0 = &cpe->ch[0]; SingleChannelElement *sce1 = &cpe->ch[1]; - int start = 0, count = 0, w, w2, g, i, prev_sf1 = -1; + int start = 0, count = 0, w, w2, g, i, prev_sf1 = -1, prev_bt = -1, prev_is = 0; const float freq_mult = avctx->sample_rate/(1024.0f/sce0->ics.num_windows)/2.0f; uint8_t nextband1[128]; @@ -139,11 +139,18 @@ void ff_aac_search_for_is(AACEncContext *s, AVCodecContext *avctx, ChannelElemen cpe->ch[0].is_ener[w*16+g] = sqrt(ener0 / best->ener01); cpe->ch[1].is_ener[w*16+g] = ener0/ener1; cpe->ch[1].band_type[w*16+g] = (best->phase > 0) ? INTENSITY_BT : INTENSITY_BT2; + if (prev_is && prev_bt != cpe->ch[1].band_type[w*16+g]) { + /** Flip M/S mask and pick the other CB, since it encodes more efficiently */ + cpe->ms_mask[w*16+g] = 1; + cpe->ch[1].band_type[w*16+g] = (best->phase > 0) ? INTENSITY_BT2 : INTENSITY_BT; + } + prev_bt = cpe->ch[1].band_type[w*16+g]; count++; } } if (!sce1->zeroes[w*16+g] && sce1->band_type[w*16+g] < RESERVED_BT) prev_sf1 = sce1->sf_idx[w*16+g]; + prev_is = cpe->is_mask[w*16+g]; start += sce0->ics.swb_sizes[g]; } } |