Refactoring the decoder to create opus_packet_parse()

This commit is contained in:
Jean-Marc Valin 2011-08-08 11:57:13 -04:00
parent 5e9f7fc31d
commit 4154dad41e
2 changed files with 132 additions and 87 deletions

View file

@ -217,6 +217,10 @@ OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...);
OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st); OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st);
OPUS_EXPORT int opus_packet_parse(const unsigned char *data, int len,
unsigned char *out_toc, const unsigned char *frames[48],
short size[48], const unsigned char **payload);
OPUS_EXPORT int opus_packet_get_bandwidth(const unsigned char *data); OPUS_EXPORT int opus_packet_get_bandwidth(const unsigned char *data);
OPUS_EXPORT int opus_packet_get_samples_per_frame(const unsigned char *data, int Fs); OPUS_EXPORT int opus_packet_get_samples_per_frame(const unsigned char *data, int Fs);
OPUS_EXPORT int opus_packet_get_nb_channels(const unsigned char *data); OPUS_EXPORT int opus_packet_get_nb_channels(const unsigned char *data);

View file

@ -412,22 +412,20 @@ static int parse_size(const unsigned char *data, int len, short *size)
} }
} }
int opus_decode(OpusDecoder *st, const unsigned char *data, int opus_packet_parse(const unsigned char *data, int len,
int len, opus_int16 *pcm, int frame_size, int decode_fec) unsigned char *out_toc, const unsigned char *frames[48],
short size[48], const unsigned char **payload)
{ {
int i, bytes, nb_samples; int i, bytes;
int count; int count;
unsigned char ch, toc; unsigned char ch, toc;
/* 48 x 2.5 ms = 120 ms */ int framesize;
short size[48];
if (len==0 || data==NULL) if (size==NULL)
return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0);
else if (len<0)
return OPUS_BAD_ARG; return OPUS_BAD_ARG;
st->mode = opus_packet_get_mode(data);
st->bandwidth = opus_packet_get_bandwidth(data); framesize = opus_packet_get_samples_per_frame(data, 48000);
st->frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
st->stream_channels = opus_packet_get_nb_channels(data);
toc = *data++; toc = *data++;
len--; len--;
switch (toc&0x3) switch (toc&0x3)
@ -461,7 +459,7 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
/* Number of frames encoded in bits 0 to 5 */ /* Number of frames encoded in bits 0 to 5 */
ch = *data++; ch = *data++;
count = ch&0x3F; count = ch&0x3F;
if (count <= 0 || st->frame_size*count*25 > 3*st->Fs) if (count <= 0 || framesize*count > 5760)
return OPUS_CORRUPTED_DATA; return OPUS_CORRUPTED_DATA;
len--; len--;
/* Padding flag is bit 6 */ /* Padding flag is bit 6 */
@ -511,8 +509,49 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
last packet (or all the packets, for the CBR case) is larger than last packet (or all the packets, for the CBR case) is larger than
1275. 1275.
Reject them here.*/ Reject them here.*/
if (size[count-1] > MAX_PACKET) if (size[count-1] > 1275)
return OPUS_CORRUPTED_DATA; return OPUS_CORRUPTED_DATA;
if (frames)
{
for (i=0;i<count;i++)
{
frames[i] = data;
data += size[i];
}
}
if (out_toc)
*out_toc = toc;
if (payload)
*payload = data;
return count;
}
int opus_decode(OpusDecoder *st, const unsigned char *data,
int len, opus_int16 *pcm, int frame_size, int decode_fec)
{
int i, nb_samples;
int count;
unsigned char toc;
/* 48 x 2.5 ms = 120 ms */
short size[48];
if (len==0 || data==NULL)
return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0);
else if (len<0)
return OPUS_BAD_ARG;
st->mode = opus_packet_get_mode(data);
st->bandwidth = opus_packet_get_bandwidth(data);
st->frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
st->stream_channels = opus_packet_get_nb_channels(data);
count = opus_packet_parse(data, len, &toc, NULL, size, &data);
if (count < 0)
return count;
if (count*st->frame_size > frame_size) if (count*st->frame_size > frame_size)
return OPUS_BAD_ARG; return OPUS_BAD_ARG;
nb_samples=0; nb_samples=0;
@ -528,6 +567,8 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
} }
return nb_samples; return nb_samples;
} }
int opus_decoder_ctl(OpusDecoder *st, int request, ...) int opus_decoder_ctl(OpusDecoder *st, int request, ...)
{ {
va_list ap; va_list ap;