mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
add support for files where the frames do not have a length prefix
Originally committed as revision 26265 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
2a81f4bde5
commit
8b5a780e73
@ -300,11 +300,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
|||||||
s->packet_loss = 1;
|
s->packet_loss = 1;
|
||||||
s->len_prefix = (s->decode_flags & 0x40);
|
s->len_prefix = (s->decode_flags & 0x40);
|
||||||
|
|
||||||
if (!s->len_prefix) {
|
|
||||||
av_log_ask_for_sample(avctx, "no length prefix\n");
|
|
||||||
return AVERROR_INVALIDDATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** get frame len */
|
/** get frame len */
|
||||||
s->samples_per_frame = 1 << ff_wma_get_frame_len_bits(avctx->sample_rate,
|
s->samples_per_frame = 1 << ff_wma_get_frame_len_bits(avctx->sample_rate,
|
||||||
3, s->decode_flags);
|
3, s->decode_flags);
|
||||||
@ -1368,6 +1363,7 @@ static int decode_frame(WMAProDecodeCtx *s)
|
|||||||
} else
|
} else
|
||||||
s->samples += s->num_channels * s->samples_per_frame;
|
s->samples += s->num_channels * s->samples_per_frame;
|
||||||
|
|
||||||
|
if (s->len_prefix) {
|
||||||
if (len != (get_bits_count(gb) - s->frame_offset) + 2) {
|
if (len != (get_bits_count(gb) - s->frame_offset) + 2) {
|
||||||
/** FIXME: not sure if this is always an error */
|
/** FIXME: not sure if this is always an error */
|
||||||
av_log(s->avctx, AV_LOG_ERROR, "frame[%i] would have to skip %i bits\n",
|
av_log(s->avctx, AV_LOG_ERROR, "frame[%i] would have to skip %i bits\n",
|
||||||
@ -1378,6 +1374,10 @@ static int decode_frame(WMAProDecodeCtx *s)
|
|||||||
|
|
||||||
/** skip the rest of the frame data */
|
/** skip the rest of the frame data */
|
||||||
skip_bits_long(gb, len - (get_bits_count(gb) - s->frame_offset) - 1);
|
skip_bits_long(gb, len - (get_bits_count(gb) - s->frame_offset) - 1);
|
||||||
|
} else {
|
||||||
|
while (get_bits_count(gb) < s->num_saved_bits && get_bits1(gb) == 0) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** decode trailer bit */
|
/** decode trailer bit */
|
||||||
more_frames = get_bits1(gb);
|
more_frames = get_bits1(gb);
|
||||||
@ -1515,18 +1515,34 @@ static int decode_packet(AVCodecContext *avctx,
|
|||||||
s->num_saved_bits - s->frame_offset);
|
s->num_saved_bits - s->frame_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
s->packet_loss = 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
int frame_size;
|
int frame_size;
|
||||||
s->buf_bit_size = avpkt->size << 3;
|
s->buf_bit_size = avpkt->size << 3;
|
||||||
init_get_bits(gb, avpkt->data, s->buf_bit_size);
|
init_get_bits(gb, avpkt->data, s->buf_bit_size);
|
||||||
skip_bits(gb, s->packet_offset);
|
skip_bits(gb, s->packet_offset);
|
||||||
if (remaining_bits(s, gb) > s->log2_frame_size &&
|
if (s->len_prefix && remaining_bits(s, gb) > s->log2_frame_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);
|
||||||
s->packet_done = !decode_frame(s);
|
s->packet_done = !decode_frame(s);
|
||||||
|
} else if (!s->len_prefix
|
||||||
|
&& s->num_saved_bits > get_bits_count(&s->gb)) {
|
||||||
|
/** when the frames do not have a length prefix, we don't know
|
||||||
|
the compressed length of the individual frames
|
||||||
|
however, we know what part of a new packet belongs to the
|
||||||
|
previous frame
|
||||||
|
therefore we save the incoming packet first, then we append
|
||||||
|
the "previous frame" data from the next packet so that
|
||||||
|
we get a buffer that only contains full frames */
|
||||||
|
s->packet_done = !decode_frame(s);
|
||||||
} else
|
} else
|
||||||
s->packet_done = 1;
|
s->packet_done = 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user