summaryrefslogtreecommitdiff
path: root/libavcodec/wmaprodec.c
diff options
context:
space:
mode:
authorSascha Sommer <saschasommer@freenet.de>2011-01-08 15:32:31 +0000
committerSascha Sommer <saschasommer@freenet.de>2011-01-08 15:32:31 +0000
commit8b5a780e73e1c2d2f8a4d0e0bbd1051f5a145653 (patch)
tree8ce52611b7190967a15b11f53c099423986f2590 /libavcodec/wmaprodec.c
parent2a81f4bde50f731074c1be7368128de49f78925a (diff)
downloadffmpeg-8b5a780e73e1c2d2f8a4d0e0bbd1051f5a145653.tar.gz
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.c30
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;
}