opus_packet_parse_impl() now computes the packet size with padding
This should fix decoding of padded multistream packets and (hopefully) multistream fec.
This commit is contained in:
parent
2a82908062
commit
58042adc19
3 changed files with 24 additions and 24 deletions
|
@ -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 opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
|
||||||
int self_delimited, unsigned char *out_toc,
|
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 i, bytes;
|
||||||
int count;
|
int count;
|
||||||
|
@ -609,6 +610,7 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
|
||||||
unsigned char ch, toc;
|
unsigned char ch, toc;
|
||||||
int framesize;
|
int framesize;
|
||||||
opus_int32 last_size;
|
opus_int32 last_size;
|
||||||
|
opus_int32 pad = 0;
|
||||||
const unsigned char *data0 = data;
|
const unsigned char *data0 = data;
|
||||||
|
|
||||||
if (size==NULL)
|
if (size==NULL)
|
||||||
|
@ -664,11 +666,14 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
|
||||||
{
|
{
|
||||||
int p;
|
int p;
|
||||||
do {
|
do {
|
||||||
|
int tmp;
|
||||||
if (len<=0)
|
if (len<=0)
|
||||||
return OPUS_INVALID_PACKET;
|
return OPUS_INVALID_PACKET;
|
||||||
p = *data++;
|
p = *data++;
|
||||||
len--;
|
len--;
|
||||||
len -= p==255 ? 254: p;
|
tmp = p==255 ? 254: p;
|
||||||
|
len -= tmp;
|
||||||
|
pad += tmp;
|
||||||
} while (p==255);
|
} while (p==255);
|
||||||
}
|
}
|
||||||
if (len<0)
|
if (len<0)
|
||||||
|
@ -731,15 +736,16 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
|
||||||
if (payload_offset)
|
if (payload_offset)
|
||||||
*payload_offset = (int)(data-data0);
|
*payload_offset = (int)(data-data0);
|
||||||
|
|
||||||
if (frames)
|
for (i=0;i<count;i++)
|
||||||
{
|
{
|
||||||
for (i=0;i<count;i++)
|
if (frames)
|
||||||
{
|
|
||||||
frames[i] = data;
|
frames[i] = data;
|
||||||
data += size[i];
|
data += size[i];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (packet_offset)
|
||||||
|
*packet_offset = pad+(opus_int32)(data-data0);
|
||||||
|
|
||||||
if (out_toc)
|
if (out_toc)
|
||||||
*out_toc = 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)
|
opus_int16 size[48], int *payload_offset)
|
||||||
{
|
{
|
||||||
return opus_packet_parse_impl(data, len, 0, out_toc,
|
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,
|
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 i, nb_samples;
|
||||||
int count, offset;
|
int count, offset;
|
||||||
unsigned char toc;
|
unsigned char toc;
|
||||||
int tot_offset;
|
|
||||||
int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
|
int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
|
||||||
/* 48 x 2.5 ms = 120 ms */
|
/* 48 x 2.5 ms = 120 ms */
|
||||||
opus_int16 size[48];
|
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_frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
|
||||||
packet_stream_channels = opus_packet_get_nb_channels(data);
|
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)
|
if (count<0)
|
||||||
return count;
|
return count;
|
||||||
|
|
||||||
|
@ -835,7 +840,6 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
|
||||||
return frame_size;
|
return frame_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tot_offset = offset;
|
|
||||||
|
|
||||||
if (count*packet_frame_size > frame_size)
|
if (count*packet_frame_size > frame_size)
|
||||||
return OPUS_BUFFER_TOO_SMALL;
|
return OPUS_BUFFER_TOO_SMALL;
|
||||||
|
@ -855,11 +859,8 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
|
||||||
return ret;
|
return ret;
|
||||||
celt_assert(ret==packet_frame_size);
|
celt_assert(ret==packet_frame_size);
|
||||||
data += size[i];
|
data += size[i];
|
||||||
tot_offset += size[i];
|
|
||||||
nb_samples += ret;
|
nb_samples += ret;
|
||||||
}
|
}
|
||||||
if (packet_offset != NULL)
|
|
||||||
*packet_offset = tot_offset;
|
|
||||||
st->last_packet_duration = nb_samples;
|
st->last_packet_duration = nb_samples;
|
||||||
if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels))
|
if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels))
|
||||||
OPUS_PRINT_INT(nb_samples);
|
OPUS_PRINT_INT(nb_samples);
|
||||||
|
|
|
@ -156,29 +156,27 @@ static int opus_multistream_packet_validate(const unsigned char *data,
|
||||||
opus_int32 len, int nb_streams, opus_int32 Fs)
|
opus_int32 len, int nb_streams, opus_int32 Fs)
|
||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
int i;
|
|
||||||
int count;
|
int count;
|
||||||
unsigned char toc;
|
unsigned char toc;
|
||||||
opus_int16 size[48];
|
opus_int16 size[48];
|
||||||
int offset;
|
|
||||||
int samples=0;
|
int samples=0;
|
||||||
|
opus_int32 packet_offset;
|
||||||
|
|
||||||
for (s=0;s<nb_streams;s++)
|
for (s=0;s<nb_streams;s++)
|
||||||
{
|
{
|
||||||
int tmp_samples;
|
int tmp_samples;
|
||||||
if (len<=0)
|
if (len<=0)
|
||||||
return OPUS_INVALID_PACKET;
|
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)
|
if (count<0)
|
||||||
return count;
|
return count;
|
||||||
for (i=0;i<count;i++)
|
tmp_samples = opus_packet_get_nb_samples(data, packet_offset, Fs);
|
||||||
offset += size[i];
|
|
||||||
tmp_samples = opus_packet_get_nb_samples(data, offset, Fs);
|
|
||||||
if (s!=0 && samples != tmp_samples)
|
if (s!=0 && samples != tmp_samples)
|
||||||
return OPUS_INVALID_PACKET;
|
return OPUS_INVALID_PACKET;
|
||||||
samples = tmp_samples;
|
samples = tmp_samples;
|
||||||
data += offset;
|
data += packet_offset;
|
||||||
len -= offset;
|
len -= packet_offset;
|
||||||
}
|
}
|
||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,8 @@ static inline int align(int i)
|
||||||
|
|
||||||
int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
|
int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
|
||||||
int self_delimited, unsigned char *out_toc,
|
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);
|
opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen, int self_delimited);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue