diff options
author | Sascha Sommer <saschasommer@freenet.de> | 2011-01-08 18:32:31 +0300 |
---|---|---|
committer | Sascha Sommer <saschasommer@freenet.de> | 2011-01-08 18:32:31 +0300 |
commit | 8b5a780e73e1c2d2f8a4d0e0bbd1051f5a145653 (patch) | |
tree | 8ce52611b7190967a15b11f53c099423986f2590 /libavcodec/wmaprodec.c | |
parent | 2a81f4bde50f731074c1be7368128de49f78925a (diff) |
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
Diffstat (limited to 'libavcodec/wmaprodec.c')
-rw-r--r-- | libavcodec/wmaprodec.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 38810ee269..888801d36b 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -300,11 +300,6 @@ static av_cold int decode_init(AVCodecContext *avctx) s->packet_loss = 1; 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 */ s->samples_per_frame = 1 << ff_wma_get_frame_len_bits(avctx->sample_rate, 3, s->decode_flags); @@ -1368,6 +1363,7 @@ static int decode_frame(WMAProDecodeCtx *s) } else s->samples += s->num_channels * s->samples_per_frame; + if (s->len_prefix) { if (len != (get_bits_count(gb) - s->frame_offset) + 2) { /** 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", @@ -1378,6 +1374,10 @@ static int decode_frame(WMAProDecodeCtx *s) /** skip the rest of the frame data */ 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 */ more_frames = get_bits1(gb); @@ -1515,18 +1515,34 @@ static int decode_packet(AVCodecContext *avctx, 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 { int frame_size; s->buf_bit_size = avpkt->size << 3; init_get_bits(gb, avpkt->data, s->buf_bit_size); 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 <= remaining_bits(s, gb)) { save_bits(s, gb, frame_size, 0); 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 s->packet_done = 1; } |