mpegaudiodec: fix seeking.

The safe bitstream reader does not allow using skip_bits_long() to seek to a
point before the start of the buffer, which was needed by the mp3 decoder.
This change instead calculates the start point of the first valid granule and
skips to that position.

Signed-off-by: Justin Ruggles <justin.ruggles@gmail.com>
This commit is contained in:
Ronald S. Bultje 2011-12-30 13:08:21 -08:00 committed by Justin Ruggles
parent 481a7ff5bd
commit 464f26889c
1 changed files with 18 additions and 16 deletions

View File

@ -1551,25 +1551,27 @@ static int mp_decode_layer3(MPADecodeContext *s)
#if !UNCHECKED_BITSTREAM_READER #if !UNCHECKED_BITSTREAM_READER
s->gb.size_in_bits_plus8 += EXTRABYTES * 8; s->gb.size_in_bits_plus8 += EXTRABYTES * 8;
#endif #endif
skip_bits_long(&s->gb, 8*(s->last_buf_size - main_data_begin)); s->last_buf_size <<= 3;
for (gr = 0, ch = 0; gr < nb_granules && (s->last_buf_size >> 3) < main_data_begin; gr++, ch = 0) {
for (; ch < s->nb_channels && (s->last_buf_size >> 3) < main_data_begin; ch++) {
g = &s->granules[ch][gr];
s->last_buf_size += g->part2_3_length;
memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));
}
}
skip_bits_long(&s->gb, s->last_buf_size - 8 * main_data_begin);
if (get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer) {
skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits);
s->gb = s->in_gb;
s->in_gb.buffer = NULL;
}
} else {
gr = ch = 0;
} }
for (gr = 0; gr < nb_granules; gr++) { for (; gr < nb_granules; gr++, ch = 0) {
for (ch = 0; ch < s->nb_channels; ch++) { for (; ch < s->nb_channels; ch++) {
g = &s->granules[ch][gr]; g = &s->granules[ch][gr];
if (get_bits_count(&s->gb) < 0) {
av_log(s->avctx, AV_LOG_DEBUG, "mdb:%d, lastbuf:%d skipping granule %d\n",
main_data_begin, s->last_buf_size, gr);
skip_bits_long(&s->gb, g->part2_3_length);
memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));
if (get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer) {
skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits);
s->gb = s->in_gb;
s->in_gb.buffer = NULL;
}
continue;
}
bits_pos = get_bits_count(&s->gb); bits_pos = get_bits_count(&s->gb);
if (!s->lsf) { if (!s->lsf) {