diff options
author | Rostislav Pehlivanov <atomnuker@gmail.com> | 2018-08-27 23:15:08 +0100 |
---|---|---|
committer | Rostislav Pehlivanov <atomnuker@gmail.com> | 2018-08-27 23:18:03 +0100 |
commit | ea82ff81e4ae0c03a3471ff5e94cb95196dd0789 (patch) | |
tree | 80084f1f40871f3f2d79796656aac2347760ebab /libavcodec | |
parent | 6213cf73945db1dd488ec51d6c4214b496833d7b (diff) | |
download | ffmpeg-ea82ff81e4ae0c03a3471ff5e94cb95196dd0789.tar.gz |
atrac9dec: implement LFE channel decoding
Much simpler than regular decoding, does allow for 5.1 and 7.1
streams to be decoded without desync.
Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/atrac9dec.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/libavcodec/atrac9dec.c b/libavcodec/atrac9dec.c index 28f8fef174..3cae2ff1d1 100644 --- a/libavcodec/atrac9dec.c +++ b/libavcodec/atrac9dec.c @@ -634,6 +634,34 @@ static int atrac9_decode_block(ATRAC9Context *s, GetBitContext *gb, const int reuse_params = get_bits1(gb); const int stereo = s->block_config->type[block_idx] == ATRAC9_BLOCK_TYPE_CPE; + if (s->block_config->type[block_idx] == ATRAC9_BLOCK_TYPE_LFE) { + ATRAC9ChannelData *c = &b->channel[0]; + const int precision = reuse_params ? 8 : 4; + c->q_unit_cnt = b->q_unit_cnt = 2; + + memset(c->scalefactors, 0, sizeof(c->scalefactors)); + memset(c->q_coeffs_fine, 0, sizeof(c->q_coeffs_fine)); + memset(c->q_coeffs_coarse, 0, sizeof(c->q_coeffs_coarse)); + + for (int i = 0; i < b->q_unit_cnt; i++) { + c->scalefactors[i] = get_bits(gb, 5); + c->precision_coarse[i] = precision; + c->precision_fine[i] = 0; + } + + for (int i = 0; i < c->q_unit_cnt; i++) { + const int start = at9_q_unit_to_coeff_idx[i + 0]; + const int end = at9_q_unit_to_coeff_idx[i + 1]; + for (int j = start; j < end; j++) + c->q_coeffs_coarse[j] = get_bits(gb, c->precision_coarse[i] + 1); + } + + dequantize (s, b, c); + apply_scalefactors(s, b, 0); + + goto imdct; + } + if (first_in_pkt && reuse_params) { av_log(s->avctx, AV_LOG_ERROR, "Invalid block flags!\n"); return AVERROR_INVALIDDATA; @@ -718,7 +746,7 @@ static int atrac9_decode_block(ATRAC9Context *s, GetBitContext *gb, apply_scalefactors (s, b, stereo); apply_band_extension (s, b, stereo); - /* iMDCT */ +imdct: for (int i = 0; i <= stereo; i++) { ATRAC9ChannelData *c = &b->channel[i]; const int dst_idx = s->block_config->plane_map[block_idx][i]; |