* @return 0 on success, <0 on error.
*/
static av_cold int decode_vbmtree(GetBitContext *gb, int8_t vbm_tree[25])
+{
+ int cntr[8] = { 0 }, n, res;
+
+ memset(vbm_tree, 0xff, sizeof(vbm_tree[0]) * 25);
+ for (n = 0; n < 17; n++) {
+ res = get_bits(gb, 3);
+ if (cntr[res] > 3) // should be >= 3 + (res == 7))
+ return -1;
+ vbm_tree[res * 3 + cntr[res]++] = n;
+ }
+ return 0;
+}
+
+static av_cold void wmavoice_init_static_data(AVCodec *codec)
{
static const uint8_t bits[] = {
2, 2, 2, 4, 4, 4,
0x0ffc, 0x0ffd, 0x0ffe, // 1111111111+00/01/10
0x3ffc, 0x3ffd, 0x3ffe, 0x3fff // 111111111111+xx
};
- int cntr[8] = { 0 }, n, res;
- memset(vbm_tree, 0xff, sizeof(vbm_tree[0]) * 25);
- for (n = 0; n < 17; n++) {
- res = get_bits(gb, 3);
- if (cntr[res] > 3) // should be >= 3 + (res == 7))
- return -1;
- vbm_tree[res * 3 + cntr[res]++] = n;
- }
INIT_VLC_STATIC(&frame_type_vlc, VLC_NBITS, sizeof(bits),
bits, 1, 1, codes, 2, 2, 132);
- return 0;
}
/**
* @param gb bit I/O context
* @param block_idx block index in frame [0, 1]
* @param fcb structure containing fixed codebook vector info
+ * @return -1 on error, 0 otherwise
*/
-static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb,
- int block_idx, AMRFixed *fcb)
+static int aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb,
+ int block_idx, AMRFixed *fcb)
{
uint16_t use_mask_mem[9]; // only 5 are used, rest is padding
uint16_t *use_mask = use_mask_mem + 2;
else if (use_mask[2]) idx = 0x2F;
else if (use_mask[3]) idx = 0x3F;
else if (use_mask[4]) idx = 0x4F;
- else return;
+ else return -1;
idx -= av_log2_16bit(use_mask[idx >> 4]);
}
if (use_mask[idx >> 4] & (0x8000 >> (idx & 15))) {
/* set offset for next block, relative to start of that block */
n = (MAX_FRAMESIZE / 2 - start_off) % fcb->pitch_lag;
s->aw_next_pulse_off_cache = n ? fcb->pitch_lag - n : 0;
+ return 0;
}
/**
* (fixed) codebook pulses of the speech signal. */
if (frame_desc->fcb_type == FCB_TYPE_AW_PULSES) {
aw_pulse_set1(s, gb, block_idx, &fcb);
- aw_pulse_set2(s, gb, block_idx, &fcb);
+ if (aw_pulse_set2(s, gb, block_idx, &fcb)) {
+ /* Conceal the block with silence and return.
+ * Skip the correct amount of bits to read the next
+ * block from the correct offset. */
+ int r_idx = pRNG(s->frame_cntr, block_idx, size);
+
+ for (n = 0; n < size; n++)
+ excitation[n] =
+ wmavoice_std_codebook[r_idx + n] * s->silence_gain;
+ skip_bits(gb, 7 + 1);
+ return;
+ }
} else /* FCB_TYPE_EXC_PULSES */ {
int offset_nbits = 5 - frame_desc->log_n_blocks;
}
AVCodec ff_wmavoice_decoder = {
- .name = "wmavoice",
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_WMAVOICE,
- .priv_data_size = sizeof(WMAVoiceContext),
- .init = wmavoice_decode_init,
- .close = wmavoice_decode_end,
- .decode = wmavoice_decode_packet,
- .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
- .flush = wmavoice_flush,
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"),
+ .name = "wmavoice",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_WMAVOICE,
+ .priv_data_size = sizeof(WMAVoiceContext),
+ .init = wmavoice_decode_init,
+ .init_static_data = wmavoice_init_static_data,
+ .close = wmavoice_decode_end,
+ .decode = wmavoice_decode_packet,
+ .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
+ .flush = wmavoice_flush,
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"),
};