#include "libavutil/channel_layout.h"
#include "libavutil/lfg.h"
+#include "libavutil/thread.h"
#include "avcodec.h"
#include "get_bits.h"
#include "internal.h"
static VLC band_vlc, scfi_vlc[2], dscf_vlc[2], res_vlc[2];
static VLC q1_vlc, q2_vlc[2], q3_vlc[2], quant_vlc[4][2], q9up_vlc;
-static const int q3_offsets[2] = { MPC8_Q3_OFFSET, MPC8_Q4_OFFSET };
-static const int quant_offsets[6] = { MPC8_Q5_OFFSET, MPC8_Q6_OFFSET, MPC8_Q7_OFFSET, MPC8_Q8_OFFSET };
-
static inline int mpc8_dec_base(GetBitContext *gb, int k, int n)
{
int len = mpc8_cnk_len[k-1][n-1] - 1;
do {
n--;
if (code >= C[n]) {
- bits |= 1 << n;
+ bits |= 1U << n;
code -= C[n];
C -= 32;
k--;
return mask;
}
-static const uint16_t vlc_offsets[13] = {
- 0, 640, 1184, 1748, 2298, 2426, 2554, 3066, 3578, 4106, 4618, 5196, 5708
-};
+static av_cold void build_vlc(VLC *vlc, unsigned *buf_offset,
+ const uint8_t codes_counts[16],
+ const uint8_t **syms, int offset)
+{
+ static VLC_TYPE vlc_buf[9296][2];
+ uint8_t len[MPC8_MAX_VLC_SIZE];
+ unsigned num = 0;
+
+ vlc->table = &vlc_buf[*buf_offset];
+ vlc->table_allocated = FF_ARRAY_ELEMS(vlc_buf) - *buf_offset;
+
+ for (int i = 16; i > 0; i--)
+ for (unsigned tmp = num + codes_counts[i - 1]; num < tmp; num++)
+ len[num] = i;
+
+ ff_init_vlc_from_lengths(vlc, FFMIN(len[0], 9), num, len, 1,
+ *syms, 1, 1, offset, INIT_VLC_STATIC_OVERLONG, NULL);
+ *buf_offset += vlc->table_size;
+ *syms += num;
+}
+
+static av_cold void mpc8_init_static(void)
+{
+ const uint8_t *q_syms = mpc8_q_syms, *bands_syms = mpc8_bands_syms;
+ const uint8_t *res_syms = mpc8_res_syms, *scfi_syms = mpc8_scfi_syms;
+ const uint8_t *dscf_syms = mpc8_dscf_syms;
+ unsigned offset = 0;
+
+ build_vlc(&band_vlc, &offset, mpc8_bands_len_counts, &bands_syms, 0);
+
+ build_vlc(&q1_vlc, &offset, mpc8_q1_len_counts, &q_syms, 0);
+ build_vlc(&q9up_vlc, &offset, mpc8_q9up_len_counts, &q_syms, 0);
+
+ for (int i = 0; i < 2; i++){
+ build_vlc(&scfi_vlc[i], &offset, mpc8_scfi_len_counts[i], &scfi_syms, 0);
+
+ build_vlc(&dscf_vlc[i], &offset, mpc8_dscf_len_counts[i], &dscf_syms, 0);
+
+ build_vlc(&res_vlc[i], &offset, mpc8_res_len_counts[i], &res_syms, 0);
+
+ build_vlc(&q2_vlc[i], &offset, mpc8_q2_len_counts[i], &q_syms, 0);
+ build_vlc(&q3_vlc[i], &offset, mpc8_q34_len_counts[i],
+ &q_syms, -48 - 16 * i);
+ for (int j = 0; j < 4; j++)
+ build_vlc(&quant_vlc[j][i], &offset, mpc8_q5_8_len_counts[i][j],
+ &q_syms, -((8 << j) - 1));
+ }
+ ff_mpa_synth_init_fixed();
+}
static av_cold int mpc8_decode_init(AVCodecContext * avctx)
{
- int i;
+ static AVOnce init_static_once = AV_ONCE_INIT;
MPCContext *c = avctx->priv_data;
GetBitContext gb;
- static int vlc_initialized = 0;
int channels;
- static VLC_TYPE band_table[542][2];
- static VLC_TYPE q1_table[520][2];
- static VLC_TYPE q9up_table[524][2];
- static VLC_TYPE scfi0_table[1 << MPC8_SCFI0_BITS][2];
- static VLC_TYPE scfi1_table[1 << MPC8_SCFI1_BITS][2];
- static VLC_TYPE dscf0_table[560][2];
- static VLC_TYPE dscf1_table[598][2];
- static VLC_TYPE q3_0_table[512][2];
- static VLC_TYPE q3_1_table[516][2];
- static VLC_TYPE codes_table[5708][2];
-
if(avctx->extradata_size < 2){
av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size);
return -1;
av_lfg_init(&c->rnd, 0xDEADBEEF);
ff_mpadsp_init(&c->mpadsp);
- ff_mpc_init();
-
init_get_bits(&gb, avctx->extradata, 16);
skip_bits(&gb, 3);//sample rate
avctx->channel_layout = (channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
avctx->channels = channels;
- if(vlc_initialized) return 0;
- av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n");
-
- band_vlc.table = band_table;
- band_vlc.table_allocated = 542;
- init_vlc(&band_vlc, MPC8_BANDS_BITS, MPC8_BANDS_SIZE,
- mpc8_bands_bits, 1, 1,
- mpc8_bands_codes, 1, 1, INIT_VLC_USE_NEW_STATIC);
-
- q1_vlc.table = q1_table;
- q1_vlc.table_allocated = 520;
- init_vlc(&q1_vlc, MPC8_Q1_BITS, MPC8_Q1_SIZE,
- mpc8_q1_bits, 1, 1,
- mpc8_q1_codes, 1, 1, INIT_VLC_USE_NEW_STATIC);
- q9up_vlc.table = q9up_table;
- q9up_vlc.table_allocated = 524;
- init_vlc(&q9up_vlc, MPC8_Q9UP_BITS, MPC8_Q9UP_SIZE,
- mpc8_q9up_bits, 1, 1,
- mpc8_q9up_codes, 1, 1, INIT_VLC_USE_NEW_STATIC);
-
- scfi_vlc[0].table = scfi0_table;
- scfi_vlc[0].table_allocated = 1 << MPC8_SCFI0_BITS;
- init_vlc(&scfi_vlc[0], MPC8_SCFI0_BITS, MPC8_SCFI0_SIZE,
- mpc8_scfi0_bits, 1, 1,
- mpc8_scfi0_codes, 1, 1, INIT_VLC_USE_NEW_STATIC);
- scfi_vlc[1].table = scfi1_table;
- scfi_vlc[1].table_allocated = 1 << MPC8_SCFI1_BITS;
- init_vlc(&scfi_vlc[1], MPC8_SCFI1_BITS, MPC8_SCFI1_SIZE,
- mpc8_scfi1_bits, 1, 1,
- mpc8_scfi1_codes, 1, 1, INIT_VLC_USE_NEW_STATIC);
-
- dscf_vlc[0].table = dscf0_table;
- dscf_vlc[0].table_allocated = 560;
- init_vlc(&dscf_vlc[0], MPC8_DSCF0_BITS, MPC8_DSCF0_SIZE,
- mpc8_dscf0_bits, 1, 1,
- mpc8_dscf0_codes, 1, 1, INIT_VLC_USE_NEW_STATIC);
- dscf_vlc[1].table = dscf1_table;
- dscf_vlc[1].table_allocated = 598;
- init_vlc(&dscf_vlc[1], MPC8_DSCF1_BITS, MPC8_DSCF1_SIZE,
- mpc8_dscf1_bits, 1, 1,
- mpc8_dscf1_codes, 1, 1, INIT_VLC_USE_NEW_STATIC);
-
- q3_vlc[0].table = q3_0_table;
- q3_vlc[0].table_allocated = 512;
- ff_init_vlc_sparse(&q3_vlc[0], MPC8_Q3_BITS, MPC8_Q3_SIZE,
- mpc8_q3_bits, 1, 1,
- mpc8_q3_codes, 1, 1,
- mpc8_q3_syms, 1, 1, INIT_VLC_USE_NEW_STATIC);
- q3_vlc[1].table = q3_1_table;
- q3_vlc[1].table_allocated = 516;
- ff_init_vlc_sparse(&q3_vlc[1], MPC8_Q4_BITS, MPC8_Q4_SIZE,
- mpc8_q4_bits, 1, 1,
- mpc8_q4_codes, 1, 1,
- mpc8_q4_syms, 1, 1, INIT_VLC_USE_NEW_STATIC);
-
- for(i = 0; i < 2; i++){
- res_vlc[i].table = &codes_table[vlc_offsets[0+i]];
- res_vlc[i].table_allocated = vlc_offsets[1+i] - vlc_offsets[0+i];
- init_vlc(&res_vlc[i], MPC8_RES_BITS, MPC8_RES_SIZE,
- &mpc8_res_bits[i], 1, 1,
- &mpc8_res_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
-
- q2_vlc[i].table = &codes_table[vlc_offsets[2+i]];
- q2_vlc[i].table_allocated = vlc_offsets[3+i] - vlc_offsets[2+i];
- init_vlc(&q2_vlc[i], MPC8_Q2_BITS, MPC8_Q2_SIZE,
- &mpc8_q2_bits[i], 1, 1,
- &mpc8_q2_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
-
- quant_vlc[0][i].table = &codes_table[vlc_offsets[4+i]];
- quant_vlc[0][i].table_allocated = vlc_offsets[5+i] - vlc_offsets[4+i];
- init_vlc(&quant_vlc[0][i], MPC8_Q5_BITS, MPC8_Q5_SIZE,
- &mpc8_q5_bits[i], 1, 1,
- &mpc8_q5_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
- quant_vlc[1][i].table = &codes_table[vlc_offsets[6+i]];
- quant_vlc[1][i].table_allocated = vlc_offsets[7+i] - vlc_offsets[6+i];
- init_vlc(&quant_vlc[1][i], MPC8_Q6_BITS, MPC8_Q6_SIZE,
- &mpc8_q6_bits[i], 1, 1,
- &mpc8_q6_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
- quant_vlc[2][i].table = &codes_table[vlc_offsets[8+i]];
- quant_vlc[2][i].table_allocated = vlc_offsets[9+i] - vlc_offsets[8+i];
- init_vlc(&quant_vlc[2][i], MPC8_Q7_BITS, MPC8_Q7_SIZE,
- &mpc8_q7_bits[i], 1, 1,
- &mpc8_q7_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
- quant_vlc[3][i].table = &codes_table[vlc_offsets[10+i]];
- quant_vlc[3][i].table_allocated = vlc_offsets[11+i] - vlc_offsets[10+i];
- init_vlc(&quant_vlc[3][i], MPC8_Q8_BITS, MPC8_Q8_SIZE,
- &mpc8_q8_bits[i], 1, 1,
- &mpc8_q8_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
- }
- vlc_initialized = 1;
+ ff_thread_once(&init_static_once, mpc8_init_static);
return 0;
}
for(j = 0; j < SAMPLES_PER_BAND; j += SAMPLES_PER_BAND / 2){
cnt = get_vlc2(gb, q1_vlc.table, MPC8_Q1_BITS, 2);
t = mpc8_get_mask(gb, 18, cnt);
- for(k = 0; k < SAMPLES_PER_BAND / 2; k++, t <<= 1)
- c->Q[ch][off + j + k] = (t & 0x20000) ? (get_bits1(gb) << 1) - 1 : 0;
+ for(k = 0; k < SAMPLES_PER_BAND / 2; k++)
+ c->Q[ch][off + j + k] = t & (1 << (SAMPLES_PER_BAND / 2 - k - 1))
+ ? (get_bits1(gb) << 1) - 1 : 0;
}
break;
case 2:
case 3:
case 4:
for(j = 0; j < SAMPLES_PER_BAND; j += 2){
- t = get_vlc2(gb, q3_vlc[res - 3].table, MPC8_Q3_BITS, 2) + q3_offsets[res - 3];
+ t = get_vlc2(gb, q3_vlc[res - 3].table, MPC8_Q3_BITS, 2);
c->Q[ch][off + j + 1] = t >> 4;
- c->Q[ch][off + j + 0] = (t & 8) ? (t & 0xF) - 16 : (t & 0xF);
+ c->Q[ch][off + j + 0] = sign_extend(t, 4);
}
break;
case 5:
case 8:
cnt = 2 * mpc8_thres[res];
for(j = 0; j < SAMPLES_PER_BAND; j++){
- t = get_vlc2(gb, quant_vlc[res - 5][cnt > mpc8_thres[res]].table, quant_vlc[res - 5][cnt > mpc8_thres[res]].bits, 2) + quant_offsets[res - 5];
- c->Q[ch][off + j] = t;
+ const VLC *vlc = &quant_vlc[res - 5][cnt > mpc8_thres[res]];
+ c->Q[ch][off + j] = get_vlc2(gb, vlc->table, vlc->bits, 2);
cnt = (cnt >> 1) + FFABS(c->Q[ch][off + j]);
}
break;
.init = mpc8_decode_init,
.decode = mpc8_decode_frame,
.flush = mpc8_decode_flush,
- .capabilities = AV_CODEC_CAP_DR1,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
AV_SAMPLE_FMT_NONE },
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
};