forked from len0rd/rockbox
wmapro: Backport multiple fixes
upstream commits: 780d454 b28c678 9166f48 97a5add b21ba20 f734671 b86dd1 b4027d9 50f0a6b 4c0080b c7a7605 5dcb990 7ad698e Change-Id: I8e6d74316e1eaf22217a57ddb54c1ea8303e6788
This commit is contained in:
parent
a5a19a3370
commit
bcbf8bbf0a
1 changed files with 91 additions and 39 deletions
|
|
@ -141,6 +141,7 @@
|
||||||
#define MAX_BANDS 29 ///< max number of scale factor bands
|
#define MAX_BANDS 29 ///< max number of scale factor bands
|
||||||
#define MAX_FRAMESIZE 32768 ///< maximum compressed frame size
|
#define MAX_FRAMESIZE 32768 ///< maximum compressed frame size
|
||||||
|
|
||||||
|
#define WMAPRO_BLOCK_MIN_BITS 6 ///< log2 of min block size
|
||||||
#define WMAPRO_BLOCK_MAX_BITS 12 ///< log2 of max block size
|
#define WMAPRO_BLOCK_MAX_BITS 12 ///< log2 of max block size
|
||||||
#define WMAPRO_BLOCK_MAX_SIZE (1 << WMAPRO_BLOCK_MAX_BITS) ///< maximum block size
|
#define WMAPRO_BLOCK_MAX_SIZE (1 << WMAPRO_BLOCK_MAX_BITS) ///< maximum block size
|
||||||
#define WMAPRO_BLOCK_SIZES (WMAPRO_BLOCK_MAX_BITS - BLOCK_MIN_BITS + 1) ///< possible block sizes
|
#define WMAPRO_BLOCK_SIZES (WMAPRO_BLOCK_MAX_BITS - BLOCK_MIN_BITS + 1) ///< possible block sizes
|
||||||
|
|
@ -306,7 +307,7 @@ int decode_init(asf_waveformatex_t *wfx)
|
||||||
WMAProDecodeCtx *s = &globWMAProDecCtx;
|
WMAProDecodeCtx *s = &globWMAProDecCtx;
|
||||||
uint8_t *edata_ptr = wfx->data;
|
uint8_t *edata_ptr = wfx->data;
|
||||||
unsigned int channel_mask;
|
unsigned int channel_mask;
|
||||||
int i;
|
int i, bits;
|
||||||
int log2_max_num_subframes;
|
int log2_max_num_subframes;
|
||||||
int num_possible_block_sizes;
|
int num_possible_block_sizes;
|
||||||
|
|
||||||
|
|
@ -355,8 +356,12 @@ int decode_init(asf_waveformatex_t *wfx)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** get frame len */
|
/** get frame len */
|
||||||
s->samples_per_frame = 1 << ff_wma_get_frame_len_bits(wfx->rate,
|
bits = ff_wma_get_frame_len_bits(wfx->rate, 3, s->decode_flags);
|
||||||
3, s->decode_flags);
|
if (bits > WMAPRO_BLOCK_MAX_BITS) {
|
||||||
|
DEBUGF("14-bits block sizes\n");
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
s->samples_per_frame = 1 << bits;
|
||||||
|
|
||||||
/** init previous block len */
|
/** init previous block len */
|
||||||
for (i = 0; i < wfx->channels; i++)
|
for (i = 0; i < wfx->channels; i++)
|
||||||
|
|
@ -365,7 +370,7 @@ int decode_init(asf_waveformatex_t *wfx)
|
||||||
/** subframe info */
|
/** subframe info */
|
||||||
log2_max_num_subframes = ((s->decode_flags & 0x38) >> 3);
|
log2_max_num_subframes = ((s->decode_flags & 0x38) >> 3);
|
||||||
s->max_num_subframes = 1 << log2_max_num_subframes;
|
s->max_num_subframes = 1 << log2_max_num_subframes;
|
||||||
if (s->max_num_subframes == 16)
|
if (s->max_num_subframes == 16 || s->max_num_subframes == 4)
|
||||||
s->max_subframe_len_bit = 1;
|
s->max_subframe_len_bit = 1;
|
||||||
s->subframe_len_bits = av_log2(log2_max_num_subframes) + 1;
|
s->subframe_len_bits = av_log2(log2_max_num_subframes) + 1;
|
||||||
|
|
||||||
|
|
@ -379,6 +384,12 @@ int decode_init(asf_waveformatex_t *wfx)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->min_samples_per_subframe < (1<<WMAPRO_BLOCK_MIN_BITS)) {
|
||||||
|
av_log(avctx, AV_LOG_ERROR, "min_samples_per_subframe of %d too small\n",
|
||||||
|
s->min_samples_per_subframe);
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
s->num_channels = wfx->channels;
|
s->num_channels = wfx->channels;
|
||||||
|
|
||||||
/** extract lfe channel position */
|
/** extract lfe channel position */
|
||||||
|
|
@ -443,9 +454,15 @@ int decode_init(asf_waveformatex_t *wfx)
|
||||||
offset &= ~3;
|
offset &= ~3;
|
||||||
if (offset > s->sfb_offsets[i][band - 1])
|
if (offset > s->sfb_offsets[i][band - 1])
|
||||||
s->sfb_offsets[i][band++] = offset;
|
s->sfb_offsets[i][band++] = offset;
|
||||||
|
if (offset >= subframe_len)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
s->sfb_offsets[i][band - 1] = subframe_len;
|
s->sfb_offsets[i][band - 1] = subframe_len;
|
||||||
s->num_sfb[i] = band - 1;
|
s->num_sfb[i] = band - 1;
|
||||||
|
if (s->num_sfb[i] <= 0) {
|
||||||
|
av_log(avctx, AV_LOG_ERROR, "num_sfb invalid\n");
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1182,7 +1199,7 @@ static int decode_subframe(WMAProDecodeCtx *s)
|
||||||
int num_fill_bits;
|
int num_fill_bits;
|
||||||
if (!(num_fill_bits = get_bits(&s->gb, 2))) {
|
if (!(num_fill_bits = get_bits(&s->gb, 2))) {
|
||||||
int len = get_bits(&s->gb, 4);
|
int len = get_bits(&s->gb, 4);
|
||||||
num_fill_bits = get_bits(&s->gb, len) + 1;
|
num_fill_bits = (len ? get_bits(&s->gb, len) : 0) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_fill_bits >= 0) {
|
if (num_fill_bits >= 0) {
|
||||||
|
|
@ -1219,7 +1236,12 @@ static int decode_subframe(WMAProDecodeCtx *s)
|
||||||
int num_bits = av_log2((s->subframe_len + 3)/4) + 1;
|
int num_bits = av_log2((s->subframe_len + 3)/4) + 1;
|
||||||
for (i = 0; i < s->channels_for_cur_subframe; i++) {
|
for (i = 0; i < s->channels_for_cur_subframe; i++) {
|
||||||
int c = s->channel_indexes_for_cur_subframe[i];
|
int c = s->channel_indexes_for_cur_subframe[i];
|
||||||
s->channel[c].num_vec_coeffs = get_bits(&s->gb, num_bits) << 2;
|
int num_vec_coeffs = get_bits(&s->gb, num_bits) << 2;
|
||||||
|
if (num_vec_coeffs > s->subframe_len) {
|
||||||
|
av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs);
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
s->channel[c].num_vec_coeffs = num_vec_coeffs;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < s->channels_for_cur_subframe; i++) {
|
for (i = 0; i < s->channels_for_cur_subframe; i++) {
|
||||||
|
|
@ -1481,7 +1503,7 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len,
|
||||||
init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
|
init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
buflen = (s->num_saved_bits + len + 8) >> 3;
|
buflen = (put_bits_count(&s->pb) + len + 8) >> 3;
|
||||||
|
|
||||||
if (len <= 0 || buflen > MAX_FRAMESIZE) {
|
if (len <= 0 || buflen > MAX_FRAMESIZE) {
|
||||||
DEBUGF("input buffer too small\n");
|
DEBUGF("input buffer too small\n");
|
||||||
|
|
@ -1489,6 +1511,16 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (len > put_bits_left(&s->pb)) {
|
||||||
|
av_log(s->avctx, AV_LOG_ERROR,
|
||||||
|
"Cannot append %d bits, only %d bits available.\n",
|
||||||
|
len, put_bits_left(&s->pb));
|
||||||
|
s->packet_loss = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
s->num_saved_bits += len;
|
s->num_saved_bits += len;
|
||||||
if (!append) {
|
if (!append) {
|
||||||
ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3),
|
ff_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3),
|
||||||
|
|
@ -1546,8 +1578,11 @@ int decode_packet(asf_waveformatex_t *wfx, int32_t *dec[2], int *data_size,
|
||||||
s->buf_bit_size = buf_size << 3;
|
s->buf_bit_size = buf_size << 3;
|
||||||
|
|
||||||
/** sanity check for the buffer length */
|
/** sanity check for the buffer length */
|
||||||
if (buf_size < wfx->blockalign)
|
if (buf_size < wfx->blockalign) {
|
||||||
return 0;
|
av_log(wfx, AV_LOG_ERROR, "Input packet too small (%d < %d)\n",
|
||||||
|
buf_size, wfx->block_align);
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
buf_size = wfx->blockalign;
|
buf_size = wfx->blockalign;
|
||||||
|
|
||||||
|
|
@ -1568,9 +1603,15 @@ int decode_packet(asf_waveformatex_t *wfx, int32_t *dec[2], int *data_size,
|
||||||
DEBUGF("Packet loss detected! seq %x vs %x\n",
|
DEBUGF("Packet loss detected! seq %x vs %x\n",
|
||||||
s->packet_sequence_number, packet_sequence_number);
|
s->packet_sequence_number, packet_sequence_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
s->packet_sequence_number = packet_sequence_number;
|
s->packet_sequence_number = packet_sequence_number;
|
||||||
|
|
||||||
if (num_bits_prev_frame > 0) {
|
if (num_bits_prev_frame > 0) {
|
||||||
|
int remaining_packet_bits = s->buf_bit_size - get_bits_count(gb);
|
||||||
|
if (num_bits_prev_frame >= remaining_packet_bits) {
|
||||||
|
num_bits_prev_frame = remaining_packet_bits;
|
||||||
|
s->packet_done = 1;
|
||||||
|
}
|
||||||
/** append the previous frame data to the remaining data from the
|
/** append the previous frame data to the remaining data from the
|
||||||
previous packet to create a full frame */
|
previous packet to create a full frame */
|
||||||
save_bits(s, gb, num_bits_prev_frame, 1);
|
save_bits(s, gb, num_bits_prev_frame, 1);
|
||||||
|
|
@ -1585,8 +1626,13 @@ int decode_packet(asf_waveformatex_t *wfx, int32_t *dec[2], int *data_size,
|
||||||
s->num_saved_bits - s->frame_offset);
|
s->num_saved_bits - s->frame_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->packet_loss) {
|
||||||
|
/** reset number of saved bits so that the decoder
|
||||||
|
does not start to decode incomplete frames in the
|
||||||
|
s->len_prefix == 0 case */
|
||||||
|
s->num_saved_bits = 0;
|
||||||
s->packet_loss = 0;
|
s->packet_loss = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int frame_size;
|
int frame_size;
|
||||||
s->buf_bit_size = size << 3;
|
s->buf_bit_size = size << 3;
|
||||||
|
|
@ -1596,11 +1642,17 @@ int decode_packet(asf_waveformatex_t *wfx, int32_t *dec[2], int *data_size,
|
||||||
(frame_size = show_bits(gb, s->log2_frame_size)) &&
|
(frame_size = show_bits(gb, s->log2_frame_size)) &&
|
||||||
frame_size <= remaining_bits(s, gb)) {
|
frame_size <= remaining_bits(s, gb)) {
|
||||||
save_bits(s, gb, frame_size, 0);
|
save_bits(s, gb, frame_size, 0);
|
||||||
|
if (!s->packet_loss)
|
||||||
s->packet_done = !decode_frame(s);
|
s->packet_done = !decode_frame(s);
|
||||||
} else
|
} else
|
||||||
s->packet_done = 1;
|
s->packet_done = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (remaining_bits(s, gb) < 0) {
|
||||||
|
av_log(wctx, AV_LOG_ERROR, "Overread %d\n", -remaining_bits(s, gb));
|
||||||
|
s->packet_loss = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (s->packet_done && !s->packet_loss &&
|
if (s->packet_done && !s->packet_loss &&
|
||||||
remaining_bits(s, gb) > 0) {
|
remaining_bits(s, gb) > 0) {
|
||||||
/** save the rest of the data so that it can be decoded
|
/** save the rest of the data so that it can be decoded
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue