diff options
author | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-10-14 13:45:58 -0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-10-14 13:45:58 -0400 |
commit | 58042adc1943a75fd39659d090ed75c896e4d4d5 (patch) | |
tree | 8c5fb818fc6137cbfbaddd9355a548cf48fd6776 /src | |
parent | 2a82908062b9396f8fcf9c020b14a55adc17c583 (diff) | |
download | opus-58042adc1943a75fd39659d090ed75c896e4d4d5.tar.gz |
opus_packet_parse_impl() now computes the packet size with padding
This should fix decoding of padded multistream packets and (hopefully)
multistream fec.
Diffstat (limited to 'src')
-rw-r--r-- | src/opus_decoder.c | 31 | ||||
-rw-r--r-- | src/opus_multistream_decoder.c | 14 | ||||
-rw-r--r-- | src/opus_private.h | 3 |
3 files changed, 24 insertions, 24 deletions
diff --git a/src/opus_decoder.c b/src/opus_decoder.c index 1f395789..112b7b58 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -601,7 +601,8 @@ static int parse_size(const unsigned char *data, opus_int32 len, opus_int16 *siz int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, int self_delimited, unsigned char *out_toc, - const unsigned char *frames[48], opus_int16 size[48], int *payload_offset) + const unsigned char *frames[48], opus_int16 size[48], + int *payload_offset, opus_int32 *packet_offset) { int i, bytes; int count; @@ -609,6 +610,7 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, unsigned char ch, toc; int framesize; opus_int32 last_size; + opus_int32 pad = 0; const unsigned char *data0 = data; if (size==NULL) @@ -664,11 +666,14 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, { int p; do { + int tmp; if (len<=0) return OPUS_INVALID_PACKET; p = *data++; len--; - len -= p==255 ? 254: p; + tmp = p==255 ? 254: p; + len -= tmp; + pad += tmp; } while (p==255); } if (len<0) @@ -731,15 +736,16 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, if (payload_offset) *payload_offset = (int)(data-data0); - if (frames) + for (i=0;i<count;i++) { - for (i=0;i<count;i++) - { + if (frames) frames[i] = data; - data += size[i]; - } + data += size[i]; } + if (packet_offset) + *packet_offset = pad+(opus_int32)(data-data0); + if (out_toc) *out_toc = toc; @@ -751,7 +757,7 @@ int opus_packet_parse(const unsigned char *data, opus_int32 len, opus_int16 size[48], int *payload_offset) { return opus_packet_parse_impl(data, len, 0, out_toc, - frames, size, payload_offset); + frames, size, payload_offset, NULL); } int opus_decode_native(OpusDecoder *st, const unsigned char *data, @@ -761,7 +767,6 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, int i, nb_samples; int count, offset; unsigned char toc; - int tot_offset; int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels; /* 48 x 2.5 ms = 120 ms */ opus_int16 size[48]; @@ -793,8 +798,8 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs); packet_stream_channels = opus_packet_get_nb_channels(data); - count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset); - + count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, + size, &offset, packet_offset); if (count<0) return count; @@ -835,7 +840,6 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, return frame_size; } } - tot_offset = offset; if (count*packet_frame_size > frame_size) return OPUS_BUFFER_TOO_SMALL; @@ -855,11 +859,8 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, return ret; celt_assert(ret==packet_frame_size); data += size[i]; - tot_offset += size[i]; nb_samples += ret; } - if (packet_offset != NULL) - *packet_offset = tot_offset; st->last_packet_duration = nb_samples; if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels)) OPUS_PRINT_INT(nb_samples); diff --git a/src/opus_multistream_decoder.c b/src/opus_multistream_decoder.c index f4b2d1be..e2111f76 100644 --- a/src/opus_multistream_decoder.c +++ b/src/opus_multistream_decoder.c @@ -156,29 +156,27 @@ static int opus_multistream_packet_validate(const unsigned char *data, opus_int32 len, int nb_streams, opus_int32 Fs) { int s; - int i; int count; unsigned char toc; opus_int16 size[48]; - int offset; int samples=0; + opus_int32 packet_offset; for (s=0;s<nb_streams;s++) { int tmp_samples; if (len<=0) return OPUS_INVALID_PACKET; - count = opus_packet_parse_impl(data, len, s!=nb_streams-1, &toc, NULL, size, &offset); + count = opus_packet_parse_impl(data, len, s!=nb_streams-1, &toc, NULL, + size, NULL, &packet_offset); if (count<0) return count; - for (i=0;i<count;i++) - offset += size[i]; - tmp_samples = opus_packet_get_nb_samples(data, offset, Fs); + tmp_samples = opus_packet_get_nb_samples(data, packet_offset, Fs); if (s!=0 && samples != tmp_samples) return OPUS_INVALID_PACKET; samples = tmp_samples; - data += offset; - len -= offset; + data += packet_offset; + len -= packet_offset; } return samples; } diff --git a/src/opus_private.h b/src/opus_private.h index aaf3cbf1..76069ed1 100644 --- a/src/opus_private.h +++ b/src/opus_private.h @@ -114,7 +114,8 @@ static inline int align(int i) int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, int self_delimited, unsigned char *out_toc, - const unsigned char *frames[48], opus_int16 size[48], int *payload_offset); + const unsigned char *frames[48], opus_int16 size[48], + int *payload_offset, int *opus_int32); opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen, int self_delimited); |