/* * Copyright (C) 2016 foo86 * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define BITSTREAM_READER_LE #include "libavutil/channel_layout.h"#include "libavutil/mem.h"#include "libavutil/mem_internal.h" #include "dcadec.h"#include "dcadata.h"#include "dcahuff.h"#include "dca_syncwords.h"#include "bytestream.h"#include "decode.h" #define AMP_MAX 56 enum LBRFlags { LBR_FLAG_24_BIT = 0x01, LBR_FLAG_LFE_PRESENT = 0x02, LBR_FLAG_BAND_LIMIT_2_3 = 0x04, LBR_FLAG_BAND_LIMIT_1_2 = 0x08, LBR_FLAG_BAND_LIMIT_1_3 = 0x0c, LBR_FLAG_BAND_LIMIT_1_4 = 0x10, LBR_FLAG_BAND_LIMIT_1_8 = 0x18, LBR_FLAG_BAND_LIMIT_NONE = 0x14, LBR_FLAG_BAND_LIMIT_MASK = 0x1c, LBR_FLAG_DMIX_STEREO = 0x20, LBR_FLAG_DMIX_MULTI_CH = 0x40}; enum LBRChunkTypes { LBR_CHUNK_NULL = 0x00, LBR_CHUNK_PAD = 0x01, LBR_CHUNK_FRAME = 0x04, LBR_CHUNK_FRAME_NO_CSUM = 0x06, LBR_CHUNK_LFE = 0x0a, LBR_CHUNK_ECS = 0x0b, LBR_CHUNK_RESERVED_1 = 0x0c, LBR_CHUNK_RESERVED_2 = 0x0d, LBR_CHUNK_SCF = 0x0e, LBR_CHUNK_TONAL = 0x10, LBR_CHUNK_TONAL_GRP_1 = 0x11, LBR_CHUNK_TONAL_GRP_2 = 0x12, LBR_CHUNK_TONAL_GRP_3 = 0x13, LBR_CHUNK_TONAL_GRP_4 = 0x14, LBR_CHUNK_TONAL_GRP_5 = 0x15, LBR_CHUNK_TONAL_SCF = 0x16, LBR_CHUNK_TONAL_SCF_GRP_1 = 0x17, LBR_CHUNK_TONAL_SCF_GRP_2 = 0x18, LBR_CHUNK_TONAL_SCF_GRP_3 = 0x19, LBR_CHUNK_TONAL_SCF_GRP_4 = 0x1a, LBR_CHUNK_TONAL_SCF_GRP_5 = 0x1b, LBR_CHUNK_RES_GRID_LR = 0x30, LBR_CHUNK_RES_GRID_LR_LAST = 0x3f, LBR_CHUNK_RES_GRID_HR = 0x40, LBR_CHUNK_RES_GRID_HR_LAST = 0x4f, LBR_CHUNK_RES_TS_1 = 0x50, LBR_CHUNK_RES_TS_1_LAST = 0x5f, LBR_CHUNK_RES_TS_2 = 0x60, LBR_CHUNK_RES_TS_2_LAST = 0x6f, LBR_CHUNK_EXTENSION = 0x7f}; typedef struct LBRChunk { int id, len; const uint8_t *data;} LBRChunk; static const int8_t channel_reorder_nolfe[7][5] = { { 0, -1, -1, -1, -1 }, // C { 0, 1, -1, -1, -1 }, // LR { 0, 1, 2, -1, -1 }, // LR C { 0, 1, -1, -1, -1 }, // LsRs { 1, 2, 0, -1, -1 }, // LsRs C { 0, 1, 2, 3, -1 }, // LR LsRs { 0, 1, 3, 4, 2 }, // LR LsRs C}; static const int8_t channel_reorder_lfe[7][5] = { { 0, -1, -1, -1, -1 }, // C { 0, 1, -1, -1, -1 }, // LR { 0, 1, 2, -1, -1 }, // LR C { 1, 2, -1, -1, -1 }, // LsRs { 2, 3, 0, -1, -1 }, // LsRs C { 0, 1, 3, 4, -1 }, // LR LsRs { 0, 1, 4, 5, 2 }, // LR LsRs C}; static const uint8_t lfe_index[7] = { 1, 2, 3, 0, 1, 2, 3}; static const uint16_t channel_layouts[7] = { AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_SURROUND, AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, AV_CH_FRONT_CENTER | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, AV_CH_LAYOUT_2_2, AV_CH_LAYOUT_5POINT0}; static float cos_tab[256];static const float lpc_tab[16] = { /* lpc_tab[i] = sin((i - 8) * (M_PI / ((i < 8) ? 17 : 15))) */ -0.995734176295034521871191178905, -0.961825643172819070408796290732, -0.895163291355062322067016499754, -0.798017227280239503332805112796, -0.673695643646557211712691912426, -0.526432162877355800244607799141, -0.361241666187152948744714596184, -0.183749517816570331574408839621, 0.0, 0.207911690817759337101742284405, 0.406736643075800207753985990341, 0.587785252292473129168705954639, 0.743144825477394235014697048974, 0.866025403784438646763723170753, 0.951056516295153572116439333379, 0.994521895368273336922691944981}; av_cold void ff_dca_lbr_init_tables(void){ int i; for (i = 0; i < 256; i++) cos_tab[i] = cos(M_PI * i / 128);} static int parse_lfe_24(DCALbrDecoder *s){ int step_max = FF_ARRAY_ELEMS(ff_dca_lfe_step_size_24) - 1; int i, ps, si, code, step_i; float step, value, delta; ps = get_bits(&s->gb, 24); si = ps >> 23; value = (((ps & 0x7fffff) ^ -si) + si) * (1.0f / 0x7fffff); step_i = get_bits(&s->gb, 8); if (step_i > step_max) { av_log(s->avctx, AV_LOG_ERROR, "Invalid LFE step size index\n"); return AVERROR_INVALIDDATA; } step = ff_dca_lfe_step_size_24[step_i]; for (i = 0; i < 64; i++) { code = get_bits(&s->gb, 6); delta = step * 0.03125f; if (code & 16) delta += step; if (code & 8) delta += step * 0.5f; if (code & 4) delta += step * 0.25f; if (code & 2) delta += step * 0.125f; if (code & 1) delta += step * 0.0625f; if (code & 32) { value -= delta; if (value < -3.0f) value = -3.0f; } else { value += delta; if (value > 3.0f) value = 3.0f; } step_i += ff_dca_lfe_delta_index_24[code & 31]; step_i = av_clip(step_i, 0, step_max); step = ff_dca_lfe_step_size_24[step_i]; s->lfe_data[i] = value * s->lfe_scale; } return 0;} static int parse_lfe_16(DCALbrDecoder *s){ int step_max = FF_ARRAY_ELEMS(ff_dca_lfe_step_size_16) - 1; int i, ps, si, code, step_i; float step, value, delta; ps = get_bits(&s->gb, 16); si = ps >> 15; value = (((ps & 0x7fff) ^ -si) + si) * (1.0f / 0x7fff); step_i = get_bits(&s->gb, 8); if (step_i > step_max) { av_log(s->avctx, AV_LOG_ERROR, "Invalid LFE step size index\n"); return AVERROR_INVALIDDATA; } step = ff_dca_lfe_step_size_16[step_i]; for (i = 0; i < 64; i++) { code = get_bits(&s->gb, 4); delta = step * 0.125f; if (code & 4) delta += step; if (code & 2) delta += step * 0.5f; if (code & 1) delta += step * 0.25f; if (code & 8) { value -= delta; if (value < -3.0f) value = -3.0f; } else { value += delta; if (value > 3.0f) value = 3.0f; } step_i += ff_dca_lfe_delta_index_16[code & 7]; step_i = av_clip(step_i, 0, step_max); step = ff_dca_lfe_step_size_16[step_i]; s->lfe_data[i] = value * s->lfe_scale; } return 0;} static int parse_lfe_chunk(DCALbrDecoder *s, LBRChunk *chunk){ int ret; if (!(s->flags & LBR_FLAG_LFE_PRESENT)) return 0; if (!chunk->len) return 0; ret = init_get_bits8(&s->gb, chunk->data, chunk->len); if (ret < 0) return ret; // Determine bit depth from chunk size if (chunk->len >= 52) return parse_lfe_24(s); if (chunk->len >= 35) return parse_lfe_16(s); av_log(s->avctx, AV_LOG_ERROR, "LFE chunk too short\n"); return AVERROR_INVALIDDATA;} static inline int parse_vlc(GetBitContext *s, const VLC *vlc, int nb_bits, int max_depth){ int v = get_vlc2(s, vlc->table, nb_bits, max_depth); if (v >= 0) return v; // Rare value return get_bits(s, get_bits(s, 3) + 1);} static int parse_tonal(DCALbrDecoder *s, int group){ unsigned int amp[DCA_LBR_CHANNELS_TOTAL]; unsigned int phs[DCA_LBR_CHANNELS_TOTAL]; unsigned int diff, main_amp, shift; int sf, sf_idx, ch, main_ch, freq; int ch_nbits = av_ceil_log2(s->nchannels_total); // Parse subframes for this group for (sf = 0; sf < 1 << group; sf += diff ? 8 : 1) { sf_idx = ((s->framenum << group) + sf) & 31; s->tonal_bounds[group][sf_idx][0] = s->ntones; // Parse tones for this subframe for (freq = 1;; freq++) { if (get_bits_left(&s->gb) < 1) { av_log(s->avctx, AV_LOG_ERROR, "Tonal group chunk too short\n"); return AVERROR_INVALIDDATA; } diff = parse_vlc(&s->gb, &ff_dca_vlc_tnl_grp[group], DCA_TNL_GRP_VLC_BITS, 2); if (diff >= FF_ARRAY_ELEMS(ff_dca_fst_amp)) { av_log(s->avctx, AV_LOG_ERROR, "Invalid tonal frequency diff\n"); return AVERROR_INVALIDDATA; } diff = get_bitsz(&s->gb, diff >> 2) + ff_dca_fst_amp[diff]; if (diff <= 1) break; // End of subframe freq += diff - 2; if (freq >> (5 - group) > s->nsubbands * 4 - 6) { av_log(s->avctx, AV_LOG_ERROR, "Invalid spectral line offset\n"); return AVERROR_INVALIDDATA; } // Main channel main_ch = get_bitsz(&s->gb, ch_nbits); main_amp = parse_vlc(&s->gb, &ff_dca_vlc_tnl_scf, DCA_TNL_SCF_VLC_BITS, 2) + s->tonal_scf[ff_dca_freq_to_sb[freq >> (7 - group)]] + s->limited_range - 2; amp[main_ch] = main_amp < AMP_MAX ? main_amp : 0; phs[main_ch] = get_bits(&s->gb, 3); // Secondary channels for (ch = 0; ch < s->nchannels_total; ch++) { if (ch == main_ch) continue; if (get_bits1(&s->gb)) { amp[ch] = amp[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_damp, DCA_DAMP_VLC_BITS, 1); phs[ch] = phs[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_dph, DCA_DPH_VLC_BITS, 1); } else { amp[ch] = 0; phs[ch] = 0; } } if (amp[main_ch]) { // Allocate new tone DCALbrTone *t = &s->tones[s->ntones]; s->ntones = (s->ntones + 1) & (DCA_LBR_TONES - 1); t->x_freq = freq >> (5 - group); t->f_delt = (freq & ((1 << (5 - group)) - 1)) << group; t->ph_rot = 256 - (t->x_freq & 1) * 128 - t->f_delt * 4; shift = ff_dca_ph0_shift[(t->x_freq & 3) * 2 + (freq & 1)] - ((t->ph_rot << (5 - group)) - t->ph_rot); for (ch = 0; ch < s->nchannels; ch++) { t->amp[ch] = amp[ch] < AMP_MAX ? amp[ch] : 0; t->phs[ch] = 128 - phs[ch] * 32 + shift; } } } s->tonal_bounds[group][sf_idx][1] = s->ntones; } return 0;} static int parse_tonal_chunk(DCALbrDecoder *s, LBRChunk *chunk){ int sb, group, ret; if (!chunk->len) return 0; ret = init_get_bits8(&s->gb, chunk->data, chunk->len); if (ret < 0) return ret; // Scale factors if (chunk->id == LBR_CHUNK_SCF || chunk->id == LBR_CHUNK_TONAL_SCF) { if (get_bits_left(&s->gb) < 36) { av_log(s->avctx, AV_LOG_ERROR, "Tonal scale factor chunk too short\n"); return AVERROR_INVALIDDATA; } for (sb = 0; sb < 6; sb++) s->tonal_scf[sb] = get_bits(&s->gb, 6); } // Tonal groups if (chunk->id == LBR_CHUNK_TONAL || chunk->id == LBR_CHUNK_TONAL_SCF) for (group = 0; group < 5; group++) { ret = parse_tonal(s, group); if (ret < 0) return ret; } return 0;} static int parse_tonal_group(DCALbrDecoder *s, LBRChunk *chunk){ int ret; if (!chunk->len) return 0; ret = init_get_bits8(&s->gb, chunk->data, chunk->len); if (ret < 0) return ret; return parse_tonal(s, chunk->id);} /** * Check point to ensure that enough bits are left. Aborts decoding * by skipping to the end of chunk otherwise. */static int ensure_bits(GetBitContext *s, int n){ int left = get_bits_left(s); if (left < 0) return AVERROR_INVALIDDATA; if (left < n) { skip_bits_long(s, left); return 1; } return 0;} static int parse_scale_factors(DCALbrDecoder *s, uint8_t *scf){ int i, sf, prev, next, dist; // Truncated scale factors remain zero if (ensure_bits(&s->gb, 20)) return 0; // Initial scale factor prev = parse_vlc(&s->gb, &ff_dca_vlc_fst_rsd_amp, DCA_FST_RSD_VLC_BITS, 2); for (sf = 0; sf < 7; sf += dist) { scf[sf] = prev; // Store previous value if (ensure_bits(&s->gb, 20)) return 0; // Interpolation distance dist = parse_vlc(&s->gb, &ff_dca_vlc_rsd_apprx, DCA_RSD_APPRX_VLC_BITS, 1) + 1; if (dist > 7 - sf) { av_log(s->avctx, AV_LOG_ERROR, "Invalid scale factor distance\n"); return AVERROR_INVALIDDATA; } if (ensure_bits(&s->gb, 20)) return 0; // Final interpolation point next = parse_vlc(&s->gb, &ff_dca_vlc_rsd_amp, DCA_RSD_AMP_VLC_BITS, 2); if (next & 1) next = prev + ((next + 1) >> 1); else next = prev - ( next >> 1); // Interpolate switch (dist) { case 2: if (next > prev) scf[sf + 1] = prev + ((next - prev) >> 1); else scf[sf + 1] = prev - ((prev - next) >> 1); break; case 4: if (next > prev) { scf[sf + 1] = prev + ( (next - prev) >> 2); scf[sf + 2] = prev + ( (next - prev) >> 1); scf[sf + 3] = prev + (((next - prev) * 3) >> 2); } else { scf[sf + 1] = prev - ( (prev - next) >> 2); scf[sf + 2] = prev - ( (prev - next) >> 1); scf[sf + 3] = prev - (((prev - next) * 3) >> 2); } break; default: for (i = 1; i < dist; i++) scf[sf + i] = prev + (next - prev) * i / dist; break; } prev = next; } scf[sf] = next; // Store final value return 0;} static int parse_st_code(GetBitContext *s, int min_v){ unsigned int v = parse_vlc(s, &ff_dca_vlc_st_grid, DCA_ST_GRID_VLC_BITS, 2) + min_v; if (v & 1)Lines 1–500 of 1841. Load more
/* * Copyright (C) 2016 foo86 * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define BITSTREAM_READER_LE #include "libavutil/channel_layout.h" #include "libavutil/mem.h" #include "libavutil/mem_internal.h" #include "dcadec.h" #include "dcadata.h" #include "dcahuff.h" #include "dca_syncwords.h" #include "bytestream.h" #include "decode.h" #define AMP_MAX 56 enum LBRFlags { LBR_FLAG_24_BIT = 0x01, LBR_FLAG_LFE_PRESENT = 0x02, LBR_FLAG_BAND_LIMIT_2_3 = 0x04, LBR_FLAG_BAND_LIMIT_1_2 = 0x08, LBR_FLAG_BAND_LIMIT_1_3 = 0x0c, LBR_FLAG_BAND_LIMIT_1_4 = 0x10, LBR_FLAG_BAND_LIMIT_1_8 = 0x18, LBR_FLAG_BAND_LIMIT_NONE = 0x14, LBR_FLAG_BAND_LIMIT_MASK = 0x1c, LBR_FLAG_DMIX_STEREO = 0x20, LBR_FLAG_DMIX_MULTI_CH = 0x40 }; enum LBRChunkTypes { LBR_CHUNK_NULL = 0x00, LBR_CHUNK_PAD = 0x01, LBR_CHUNK_FRAME = 0x04, LBR_CHUNK_FRAME_NO_CSUM = 0x06, LBR_CHUNK_LFE = 0x0a, LBR_CHUNK_ECS = 0x0b, LBR_CHUNK_RESERVED_1 = 0x0c, LBR_CHUNK_RESERVED_2 = 0x0d, LBR_CHUNK_SCF = 0x0e, LBR_CHUNK_TONAL = 0x10, LBR_CHUNK_TONAL_GRP_1 = 0x11, LBR_CHUNK_TONAL_GRP_2 = 0x12, LBR_CHUNK_TONAL_GRP_3 = 0x13, LBR_CHUNK_TONAL_GRP_4 = 0x14, LBR_CHUNK_TONAL_GRP_5 = 0x15, LBR_CHUNK_TONAL_SCF = 0x16, LBR_CHUNK_TONAL_SCF_GRP_1 = 0x17, LBR_CHUNK_TONAL_SCF_GRP_2 = 0x18, LBR_CHUNK_TONAL_SCF_GRP_3 = 0x19, LBR_CHUNK_TONAL_SCF_GRP_4 = 0x1a, LBR_CHUNK_TONAL_SCF_GRP_5 = 0x1b, LBR_CHUNK_RES_GRID_LR = 0x30, LBR_CHUNK_RES_GRID_LR_LAST = 0x3f, LBR_CHUNK_RES_GRID_HR = 0x40, LBR_CHUNK_RES_GRID_HR_LAST = 0x4f, LBR_CHUNK_RES_TS_1 = 0x50, LBR_CHUNK_RES_TS_1_LAST = 0x5f, LBR_CHUNK_RES_TS_2 = 0x60, LBR_CHUNK_RES_TS_2_LAST = 0x6f, LBR_CHUNK_EXTENSION = 0x7f }; typedef struct LBRChunk { int id, len; const uint8_t *data; } LBRChunk; static const int8_t channel_reorder_nolfe[7][5] = { { 0, -1, -1, -1, -1 }, // C { 0, 1, -1, -1, -1 }, // LR { 0, 1, 2, -1, -1 }, // LR C { 0, 1, -1, -1, -1 }, // LsRs { 1, 2, 0, -1, -1 }, // LsRs C { 0, 1, 2, 3, -1 }, // LR LsRs { 0, 1, 3, 4, 2 }, // LR LsRs C }; static const int8_t channel_reorder_lfe[7][5] = { { 0, -1, -1, -1, -1 }, // C { 0, 1, -1, -1, -1 }, // LR { 0, 1, 2, -1, -1 }, // LR C { 1, 2, -1, -1, -1 }, // LsRs { 2, 3, 0, -1, -1 }, // LsRs C { 0, 1, 3, 4, -1 }, // LR LsRs { 0, 1, 4, 5, 2 }, // LR LsRs C }; static const uint8_t lfe_index[7] = { 1, 2, 3, 0, 1, 2, 3 }; static const uint16_t channel_layouts[7] = { AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_SURROUND, AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, AV_CH_FRONT_CENTER | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, AV_CH_LAYOUT_2_2, AV_CH_LAYOUT_5POINT0 }; static float cos_tab[256]; static const float lpc_tab[16] = { /* lpc_tab[i] = sin((i - 8) * (M_PI / ((i < 8) ? 17 : 15))) */ -0.995734176295034521871191178905, -0.961825643172819070408796290732, -0.895163291355062322067016499754, -0.798017227280239503332805112796, -0.673695643646557211712691912426, -0.526432162877355800244607799141, -0.361241666187152948744714596184, -0.183749517816570331574408839621, 0.0, 0.207911690817759337101742284405, 0.406736643075800207753985990341, 0.587785252292473129168705954639, 0.743144825477394235014697048974, 0.866025403784438646763723170753, 0.951056516295153572116439333379, 0.994521895368273336922691944981 }; av_cold void ff_dca_lbr_init_tables(void) { int i; for (i = 0; i < 256; i++) cos_tab[i] = cos(M_PI * i / 128); } static int parse_lfe_24(DCALbrDecoder *s) { int step_max = FF_ARRAY_ELEMS(ff_dca_lfe_step_size_24) - 1; int i, ps, si, code, step_i; float step, value, delta; ps = get_bits(&s->gb, 24); si = ps >> 23; value = (((ps & 0x7fffff) ^ -si) + si) * (1.0f / 0x7fffff); step_i = get_bits(&s->gb, 8); if (step_i > step_max) { av_log(s->avctx, AV_LOG_ERROR, "Invalid LFE step size index\n"); return AVERROR_INVALIDDATA; } step = ff_dca_lfe_step_size_24[step_i]; for (i = 0; i < 64; i++) { code = get_bits(&s->gb, 6); delta = step * 0.03125f; if (code & 16) delta += step; if (code & 8) delta += step * 0.5f; if (code & 4) delta += step * 0.25f; if (code & 2) delta += step * 0.125f; if (code & 1) delta += step * 0.0625f; if (code & 32) { value -= delta; if (value < -3.0f) value = -3.0f; } else { value += delta; if (value > 3.0f) value = 3.0f; } step_i += ff_dca_lfe_delta_index_24[code & 31]; step_i = av_clip(step_i, 0, step_max); step = ff_dca_lfe_step_size_24[step_i]; s->lfe_data[i] = value * s->lfe_scale; } return 0; } static int parse_lfe_16(DCALbrDecoder *s) { int step_max = FF_ARRAY_ELEMS(ff_dca_lfe_step_size_16) - 1; int i, ps, si, code, step_i; float step, value, delta; ps = get_bits(&s->gb, 16); si = ps >> 15; value = (((ps & 0x7fff) ^ -si) + si) * (1.0f / 0x7fff); step_i = get_bits(&s->gb, 8); if (step_i > step_max) { av_log(s->avctx, AV_LOG_ERROR, "Invalid LFE step size index\n"); return AVERROR_INVALIDDATA; } step = ff_dca_lfe_step_size_16[step_i]; for (i = 0; i < 64; i++) { code = get_bits(&s->gb, 4); delta = step * 0.125f; if (code & 4) delta += step; if (code & 2) delta += step * 0.5f; if (code & 1) delta += step * 0.25f; if (code & 8) { value -= delta; if (value < -3.0f) value = -3.0f; } else { value += delta; if (value > 3.0f) value = 3.0f; } step_i += ff_dca_lfe_delta_index_16[code & 7]; step_i = av_clip(step_i, 0, step_max); step = ff_dca_lfe_step_size_16[step_i]; s->lfe_data[i] = value * s->lfe_scale; } return 0; } static int parse_lfe_chunk(DCALbrDecoder *s, LBRChunk *chunk) { int ret; if (!(s->flags & LBR_FLAG_LFE_PRESENT)) return 0; if (!chunk->len) return 0; ret = init_get_bits8(&s->gb, chunk->data, chunk->len); if (ret < 0) return ret; // Determine bit depth from chunk size if (chunk->len >= 52) return parse_lfe_24(s); if (chunk->len >= 35) return parse_lfe_16(s); av_log(s->avctx, AV_LOG_ERROR, "LFE chunk too short\n"); return AVERROR_INVALIDDATA; } static inline int parse_vlc(GetBitContext *s, const VLC *vlc, int nb_bits, int max_depth) { int v = get_vlc2(s, vlc->table, nb_bits, max_depth); if (v >= 0) return v; // Rare value return get_bits(s, get_bits(s, 3) + 1); } static int parse_tonal(DCALbrDecoder *s, int group) { unsigned int amp[DCA_LBR_CHANNELS_TOTAL]; unsigned int phs[DCA_LBR_CHANNELS_TOTAL]; unsigned int diff, main_amp, shift; int sf, sf_idx, ch, main_ch, freq; int ch_nbits = av_ceil_log2(s->nchannels_total); // Parse subframes for this group for (sf = 0; sf < 1 << group; sf += diff ? 8 : 1) { sf_idx = ((s->framenum << group) + sf) & 31; s->tonal_bounds[group][sf_idx][0] = s->ntones; // Parse tones for this subframe for (freq = 1;; freq++) { if (get_bits_left(&s->gb) < 1) { av_log(s->avctx, AV_LOG_ERROR, "Tonal group chunk too short\n"); return AVERROR_INVALIDDATA; } diff = parse_vlc(&s->gb, &ff_dca_vlc_tnl_grp[group], DCA_TNL_GRP_VLC_BITS, 2); if (diff >= FF_ARRAY_ELEMS(ff_dca_fst_amp)) { av_log(s->avctx, AV_LOG_ERROR, "Invalid tonal frequency diff\n"); return AVERROR_INVALIDDATA; } diff = get_bitsz(&s->gb, diff >> 2) + ff_dca_fst_amp[diff]; if (diff <= 1) break; // End of subframe freq += diff - 2; if (freq >> (5 - group) > s->nsubbands * 4 - 6) { av_log(s->avctx, AV_LOG_ERROR, "Invalid spectral line offset\n"); return AVERROR_INVALIDDATA; } // Main channel main_ch = get_bitsz(&s->gb, ch_nbits); main_amp = parse_vlc(&s->gb, &ff_dca_vlc_tnl_scf, DCA_TNL_SCF_VLC_BITS, 2) + s->tonal_scf[ff_dca_freq_to_sb[freq >> (7 - group)]] + s->limited_range - 2; amp[main_ch] = main_amp < AMP_MAX ? main_amp : 0; phs[main_ch] = get_bits(&s->gb, 3); // Secondary channels for (ch = 0; ch < s->nchannels_total; ch++) { if (ch == main_ch) continue; if (get_bits1(&s->gb)) { amp[ch] = amp[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_damp, DCA_DAMP_VLC_BITS, 1); phs[ch] = phs[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_dph, DCA_DPH_VLC_BITS, 1); } else { amp[ch] = 0; phs[ch] = 0; } } if (amp[main_ch]) { // Allocate new tone DCALbrTone *t = &s->tones[s->ntones]; s->ntones = (s->ntones + 1) & (DCA_LBR_TONES - 1); t->x_freq = freq >> (5 - group); t->f_delt = (freq & ((1 << (5 - group)) - 1)) << group; t->ph_rot = 256 - (t->x_freq & 1) * 128 - t->f_delt * 4; shift = ff_dca_ph0_shift[(t->x_freq & 3) * 2 + (freq & 1)] - ((t->ph_rot << (5 - group)) - t->ph_rot); for (ch = 0; ch < s->nchannels; ch++) { t->amp[ch] = amp[ch] < AMP_MAX ? amp[ch] : 0; t->phs[ch] = 128 - phs[ch] * 32 + shift; } } } s->tonal_bounds[group][sf_idx][1] = s->ntones; } return 0; } static int parse_tonal_chunk(DCALbrDecoder *s, LBRChunk *chunk) { int sb, group, ret; if (!chunk->len) return 0; ret = init_get_bits8(&s->gb, chunk->data, chunk->len); if (ret < 0) return ret; // Scale factors if (chunk->id == LBR_CHUNK_SCF || chunk->id == LBR_CHUNK_TONAL_SCF) { if (get_bits_left(&s->gb) < 36) { av_log(s->avctx, AV_LOG_ERROR, "Tonal scale factor chunk too short\n"); return AVERROR_INVALIDDATA; } for (sb = 0; sb < 6; sb++) s->tonal_scf[sb] = get_bits(&s->gb, 6); } // Tonal groups if (chunk->id == LBR_CHUNK_TONAL || chunk->id == LBR_CHUNK_TONAL_SCF) for (group = 0; group < 5; group++) { ret = parse_tonal(s, group); if (ret < 0) return ret; } return 0; } static int parse_tonal_group(DCALbrDecoder *s, LBRChunk *chunk) { int ret; if (!chunk->len) return 0; ret = init_get_bits8(&s->gb, chunk->data, chunk->len); if (ret < 0) return ret; return parse_tonal(s, chunk->id); } /** * Check point to ensure that enough bits are left. Aborts decoding * by skipping to the end of chunk otherwise. */ static int ensure_bits(GetBitContext *s, int n) { int left = get_bits_left(s); if (left < 0) return AVERROR_INVALIDDATA; if (left < n) { skip_bits_long(s, left); return 1; } return 0; } static int parse_scale_factors(DCALbrDecoder *s, uint8_t *scf) { int i, sf, prev, next, dist; // Truncated scale factors remain zero if (ensure_bits(&s->gb, 20)) return 0; // Initial scale factor prev = parse_vlc(&s->gb, &ff_dca_vlc_fst_rsd_amp, DCA_FST_RSD_VLC_BITS, 2); for (sf = 0; sf < 7; sf += dist) { scf[sf] = prev; // Store previous value if (ensure_bits(&s->gb, 20)) return 0; // Interpolation distance dist = parse_vlc(&s->gb, &ff_dca_vlc_rsd_apprx, DCA_RSD_APPRX_VLC_BITS, 1) + 1; if (dist > 7 - sf) { av_log(s->avctx, AV_LOG_ERROR, "Invalid scale factor distance\n"); return AVERROR_INVALIDDATA; } if (ensure_bits(&s->gb, 20)) return 0; // Final interpolation point next = parse_vlc(&s->gb, &ff_dca_vlc_rsd_amp, DCA_RSD_AMP_VLC_BITS, 2); if (next & 1) next = prev + ((next + 1) >> 1); else next = prev - ( next >> 1); // Interpolate switch (dist) { case 2: if (next > prev) scf[sf + 1] = prev + ((next - prev) >> 1); else scf[sf + 1] = prev - ((prev - next) >> 1); break; case 4: if (next > prev) { scf[sf + 1] = prev + ( (next - prev) >> 2); scf[sf + 2] = prev + ( (next - prev) >> 1); scf[sf + 3] = prev + (((next - prev) * 3) >> 2); } else { scf[sf + 1] = prev - ( (prev - next) >> 2); scf[sf + 2] = prev - ( (prev - next) >> 1); scf[sf + 3] = prev - (((prev - next) * 3) >> 2); } break; default: for (i = 1; i < dist; i++) scf[sf + i] = prev + (next - prev) * i / dist; break; } prev = next; } scf[sf] = next; // Store final value return 0; } static int parse_st_code(GetBitContext *s, int min_v) { unsigned int v = parse_vlc(s, &ff_dca_vlc_st_grid, DCA_ST_GRID_VLC_BITS, 2) + min_v; if (v & 1)