40/60ms MDCT/Hybrid were not able to reach maximum bitrate. Now they can.

Also change the packet length in the API from int to opus_int32
because repacketized frames are able to go beyond 32767 bytes
in size.
This commit is contained in:
Gregory Maxwell 2011-11-19 23:58:09 -05:00 committed by Jean-Marc Valin
parent 8365b5d00d
commit e7028175af
4 changed files with 49 additions and 48 deletions

View file

@ -131,7 +131,7 @@ extern "C" {
* <li>audio_frame is the audio data in opus_int16 (or float for opus_encode_float())</li> * <li>audio_frame is the audio data in opus_int16 (or float for opus_encode_float())</li>
* <li>frame_size is the duration of the frame in samples (per channel)</li> * <li>frame_size is the duration of the frame in samples (per channel)</li>
* <li>packet is the byte array to which the compressed data is written</li> * <li>packet is the byte array to which the compressed data is written</li>
* <li>max_packet is the maximum number of bytes that can be written in the packet (1276 bytes is recommended)</li> * <li>max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended)</li>
* </ul> * </ul>
* *
* opus_encode() and opus_encode_frame() return the number of bytes actually written to the packet. * opus_encode() and opus_encode_frame() return the number of bytes actually written to the packet.
@ -224,15 +224,15 @@ OPUS_EXPORT int opus_encoder_init(
* @param [in] pcm <tt>opus_int16*</tt>: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16) * @param [in] pcm <tt>opus_int16*</tt>: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16)
* @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal
* @param [out] data <tt>char*</tt>: Output payload (at least max_data_bytes long) * @param [out] data <tt>char*</tt>: Output payload (at least max_data_bytes long)
* @param [in] max_data_bytes <tt>int</tt>: Allocated memory for payload; don't use for controlling bitrate * @param [in] max_data_bytes <tt>opus_int32</tt>: Allocated memory for payload; don't use for controlling bitrate
* @returns length of the data payload (in bytes) or @ref errorcodes * @returns length of the data payload (in bytes) or @ref errorcodes
*/ */
OPUS_EXPORT int opus_encode( OPUS_EXPORT opus_int32 opus_encode(
OpusEncoder *st, OpusEncoder *st,
const opus_int16 *pcm, const opus_int16 *pcm,
int frame_size, int frame_size,
unsigned char *data, unsigned char *data,
int max_data_bytes opus_int32 max_data_bytes
); );
/** Encodes an Opus frame from floating point input. /** Encodes an Opus frame from floating point input.
@ -244,15 +244,15 @@ OPUS_EXPORT int opus_encode(
* @param [in] pcm <tt>float*</tt>: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(float) * @param [in] pcm <tt>float*</tt>: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(float)
* @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal
* @param [out] data <tt>char*</tt>: Output payload (at least max_data_bytes long) * @param [out] data <tt>char*</tt>: Output payload (at least max_data_bytes long)
* @param [in] max_data_bytes <tt>int</tt>: Allocated memory for payload; don't use for controlling bitrate * @param [in] max_data_bytes <tt>opus_int32</tt>: Allocated memory for payload; don't use for controlling bitrate
* @returns length of the data payload (in bytes) or @ref errorcodes * @returns length of the data payload (in bytes) or @ref errorcodes
*/ */
OPUS_EXPORT int opus_encode_float( OPUS_EXPORT opus_int32 opus_encode_float(
OpusEncoder *st, OpusEncoder *st,
const float *pcm, const float *pcm,
int frame_size, int frame_size,
unsigned char *data, unsigned char *data,
int max_data_bytes opus_int32 max_data_bytes
); );
/** Frees an OpusEncoder allocated by opus_encoder_create. /** Frees an OpusEncoder allocated by opus_encoder_create.
@ -361,7 +361,7 @@ OPUS_EXPORT int opus_decoder_init(
/** Decode an Opus frame /** Decode an Opus frame
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state * @param [in] st <tt>OpusDecoder*</tt>: Decoder state
* @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
* @param [in] len <tt>int</tt>: Number of bytes in payload* * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload*
* @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length * @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length
* is frame_size*channels*sizeof(opus_int16) * is frame_size*channels*sizeof(opus_int16)
* @param [in] frame_size Number of samples per channel of available space in *pcm, * @param [in] frame_size Number of samples per channel of available space in *pcm,
@ -373,7 +373,7 @@ OPUS_EXPORT int opus_decoder_init(
OPUS_EXPORT int opus_decode( OPUS_EXPORT int opus_decode(
OpusDecoder *st, OpusDecoder *st,
const unsigned char *data, const unsigned char *data,
int len, opus_int32 len,
opus_int16 *pcm, opus_int16 *pcm,
int frame_size, int frame_size,
int decode_fec int decode_fec
@ -382,7 +382,7 @@ OPUS_EXPORT int opus_decode(
/** Decode an opus frame with floating point output /** Decode an opus frame with floating point output
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state * @param [in] st <tt>OpusDecoder*</tt>: Decoder state
* @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
* @param [in] len <tt>int</tt>: Number of bytes in payload * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload
* @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length * @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length
* is frame_size*channels*sizeof(float) * is frame_size*channels*sizeof(float)
* @param [in] frame_size Number of samples per channel of available space in *pcm, * @param [in] frame_size Number of samples per channel of available space in *pcm,
@ -394,7 +394,7 @@ OPUS_EXPORT int opus_decode(
OPUS_EXPORT int opus_decode_float( OPUS_EXPORT int opus_decode_float(
OpusDecoder *st, OpusDecoder *st,
const unsigned char *data, const unsigned char *data,
int len, opus_int32 len,
float *pcm, float *pcm,
int frame_size, int frame_size,
int decode_fec int decode_fec
@ -419,7 +419,7 @@ OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st);
* This function does not copy the frames, the returned pointers are pointers into * This function does not copy the frames, the returned pointers are pointers into
* the input packet. * the input packet.
* @param [in] data <tt>char*</tt>: Opus packet to be parsed * @param [in] data <tt>char*</tt>: Opus packet to be parsed
* @param [in] len <tt>int</tt>: size of data * @param [in] len <tt>opus_int32</tt>: size of data
* @param [out] out_toc <tt>char*</tt>: TOC pointer * @param [out] out_toc <tt>char*</tt>: TOC pointer
* @param [out] frames <tt>char*[48]</tt> encapsulated frames * @param [out] frames <tt>char*[48]</tt> encapsulated frames
* @param [out] size <tt>short[48]</tt> sizes of the encapsulated frames * @param [out] size <tt>short[48]</tt> sizes of the encapsulated frames
@ -428,7 +428,7 @@ OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st);
*/ */
OPUS_EXPORT int opus_packet_parse( OPUS_EXPORT int opus_packet_parse(
const unsigned char *data, const unsigned char *data,
int len, opus_int32 len,
unsigned char *out_toc, unsigned char *out_toc,
const unsigned char *frames[48], const unsigned char *frames[48],
short size[48], short size[48],
@ -463,20 +463,20 @@ OPUS_EXPORT int opus_packet_get_nb_channels(const unsigned char *data);
/** Gets the number of frames in an Opus packet. /** Gets the number of frames in an Opus packet.
* @param [in] packet <tt>char*</tt>: Opus packet * @param [in] packet <tt>char*</tt>: Opus packet
* @param [in] len <tt>int</tt>: Length of packet * @param [in] len <tt>opus_int32</tt>: Length of packet
* @returns Number of frames * @returns Number of frames
* @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
*/ */
OPUS_EXPORT int opus_packet_get_nb_frames(const unsigned char packet[], int len); OPUS_EXPORT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len);
/** Gets the number of samples of an Opus packet. /** Gets the number of samples of an Opus packet.
* @param [in] dec <tt>OpusDecoder*</tt>: Decoder state * @param [in] dec <tt>OpusDecoder*</tt>: Decoder state
* @param [in] packet <tt>char*</tt>: Opus packet * @param [in] packet <tt>char*</tt>: Opus packet
* @param [in] len <tt>int</tt>: Length of packet * @param [in] len <tt>opus_int32</tt>: Length of packet
* @returns Number of samples * @returns Number of samples
* @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
*/ */
OPUS_EXPORT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], int len); OPUS_EXPORT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len);
/**@}*/ /**@}*/
/** @defgroup repacketizer Repacketizer /** @defgroup repacketizer Repacketizer
@ -497,13 +497,13 @@ OPUS_EXPORT OpusRepacketizer *opus_repacketizer_create(void);
OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp); OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp);
OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, int len); OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len);
OPUS_EXPORT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, int maxlen); OPUS_EXPORT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen);
OPUS_EXPORT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp); OPUS_EXPORT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp);
OPUS_EXPORT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, int maxlen); OPUS_EXPORT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen);
/**@}*/ /**@}*/

View file

@ -187,7 +187,7 @@ static int opus_packet_get_mode(const unsigned char *data)
} }
static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
int len, opus_val16 *pcm, int frame_size, int decode_fec) opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
{ {
void *silk_dec; void *silk_dec;
CELTDecoder *celt_dec; CELTDecoder *celt_dec;
@ -505,7 +505,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
} }
static int parse_size(const unsigned char *data, int len, short *size) static int parse_size(const unsigned char *data, opus_int32 len, short *size)
{ {
if (len<1) if (len<1)
{ {
@ -525,7 +525,7 @@ static int parse_size(const unsigned char *data, int len, short *size)
} }
} }
static int opus_packet_parse_impl(const unsigned char *data, int len, static 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], short size[48], int *payload_offset) const unsigned char *frames[48], short size[48], int *payload_offset)
{ {
@ -672,7 +672,7 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
return count; return count;
} }
int opus_packet_parse(const unsigned char *data, int len, int opus_packet_parse(const unsigned char *data, opus_int32 len,
unsigned char *out_toc, const unsigned char *frames[48], unsigned char *out_toc, const unsigned char *frames[48],
short size[48], int *payload_offset) short size[48], int *payload_offset)
{ {
@ -681,7 +681,7 @@ int opus_packet_parse(const unsigned char *data, int len,
} }
int opus_decode_native(OpusDecoder *st, const unsigned char *data, int opus_decode_native(OpusDecoder *st, const unsigned char *data,
int len, opus_val16 *pcm, int frame_size, int decode_fec, opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec,
int self_delimited, int *packet_offset) int self_delimited, int *packet_offset)
{ {
int i, nb_samples; int i, nb_samples;
@ -732,14 +732,14 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
#ifdef FIXED_POINT #ifdef FIXED_POINT
int opus_decode(OpusDecoder *st, const unsigned char *data, int opus_decode(OpusDecoder *st, const unsigned char *data,
int len, opus_val16 *pcm, int frame_size, int decode_fec) opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
{ {
return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL); return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL);
} }
#ifndef DISABLE_FLOAT_API #ifndef DISABLE_FLOAT_API
int opus_decode_float(OpusDecoder *st, const unsigned char *data, int opus_decode_float(OpusDecoder *st, const unsigned char *data,
int len, float *pcm, int frame_size, int decode_fec) opus_int32 len, float *pcm, int frame_size, int decode_fec)
{ {
VARDECL(opus_int16, out); VARDECL(opus_int16, out);
int ret, i; int ret, i;
@ -761,7 +761,7 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data,
#else #else
int opus_decode(OpusDecoder *st, const unsigned char *data, int opus_decode(OpusDecoder *st, const unsigned char *data,
int len, opus_int16 *pcm, int frame_size, int decode_fec) opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
{ {
VARDECL(float, out); VARDECL(float, out);
int ret, i; int ret, i;
@ -782,7 +782,7 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
} }
int opus_decode_float(OpusDecoder *st, const unsigned char *data, int opus_decode_float(OpusDecoder *st, const unsigned char *data,
int len, opus_val16 *pcm, int frame_size, int decode_fec) opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
{ {
return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL); return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL);
} }
@ -902,7 +902,7 @@ int opus_packet_get_nb_channels(const unsigned char *data)
return (data[0]&0x4) ? 2 : 1; return (data[0]&0x4) ? 2 : 1;
} }
int opus_packet_get_nb_frames(const unsigned char packet[], int len) int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len)
{ {
int count; int count;
if (len<1) if (len<1)
@ -919,7 +919,7 @@ int opus_packet_get_nb_frames(const unsigned char packet[], int len)
} }
int opus_decoder_get_nb_samples(const OpusDecoder *dec, int opus_decoder_get_nb_samples(const OpusDecoder *dec,
const unsigned char packet[], int len) const unsigned char packet[], opus_int32 len)
{ {
int samples; int samples;
int count = opus_packet_get_nb_frames(packet, len); int count = opus_packet_get_nb_frames(packet, len);

View file

@ -220,7 +220,7 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat
return OPUS_OK; return OPUS_OK;
} }
static int pad_frame(unsigned char *data, int len, int new_len) static int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len)
{ {
if (len == new_len) if (len == new_len)
return 0; return 0;
@ -438,11 +438,11 @@ static opus_int32 user_bitrate_to_bitrate(OpusEncoder *st, int frame_size, int m
#ifdef FIXED_POINT #ifdef FIXED_POINT
#define opus_encode_native opus_encode #define opus_encode_native opus_encode
int opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size, int opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
unsigned char *data, int max_data_bytes) unsigned char *data, opus_int32 out_data_bytes)
#else #else
#define opus_encode_native opus_encode_float #define opus_encode_native opus_encode_float
int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
unsigned char *data, int max_data_bytes) unsigned char *data, opus_int32 out_data_bytes)
#endif #endif
{ {
void *silk_enc; void *silk_enc;
@ -468,11 +468,12 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
int frame_rate; int frame_rate;
opus_int32 max_rate; opus_int32 max_rate;
int curr_bandwidth; int curr_bandwidth;
opus_int32 max_data_bytes;
VARDECL(opus_val16, tmp_prefill); VARDECL(opus_val16, tmp_prefill);
ALLOC_STACK; ALLOC_STACK;
max_data_bytes = IMIN(1276, max_data_bytes); max_data_bytes = IMIN(1276, out_data_bytes);
st->rangeFinal = 0; st->rangeFinal = 0;
if (400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs && if (400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs &&
@ -746,11 +747,11 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
int nb_frames; int nb_frames;
int bak_mode, bak_bandwidth, bak_channels, bak_to_mono; int bak_mode, bak_bandwidth, bak_channels, bak_to_mono;
OpusRepacketizer rp; OpusRepacketizer rp;
int bytes_per_frame; opus_int32 bytes_per_frame;
nb_frames = frame_size > st->Fs/25 ? 3 : 2; nb_frames = frame_size > st->Fs/25 ? 3 : 2;
bytes_per_frame = max_data_bytes/nb_frames-3; bytes_per_frame = IMIN(1276,(out_data_bytes-3)/nb_frames);
ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char); ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char);
@ -783,7 +784,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
if (ret<0) if (ret<0)
return OPUS_INTERNAL_ERROR; return OPUS_INTERNAL_ERROR;
} }
ret = opus_repacketizer_out(&rp, data, max_data_bytes); ret = opus_repacketizer_out(&rp, data, out_data_bytes);
if (ret<0) if (ret<0)
return OPUS_INTERNAL_ERROR; return OPUS_INTERNAL_ERROR;
@ -1222,7 +1223,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
#ifndef DISABLE_FLOAT_API #ifndef DISABLE_FLOAT_API
int opus_encode_float(OpusEncoder *st, const float *pcm, int frame_size, int opus_encode_float(OpusEncoder *st, const float *pcm, int frame_size,
unsigned char *data, int max_data_bytes) unsigned char *data, opus_int32 max_data_bytes)
{ {
int i, ret; int i, ret;
VARDECL(opus_int16, in); VARDECL(opus_int16, in);
@ -1242,7 +1243,7 @@ int opus_encode_float(OpusEncoder *st, const float *pcm, int frame_size,
#else #else
int opus_encode(OpusEncoder *st, const opus_int16 *pcm, int frame_size, int opus_encode(OpusEncoder *st, const opus_int16 *pcm, int frame_size,
unsigned char *data, int max_data_bytes) unsigned char *data, opus_int32 max_data_bytes)
{ {
int i, ret; int i, ret;
VARDECL(float, in); VARDECL(float, in);

View file

@ -227,7 +227,7 @@ int opus_multistream_encode_float(
const opus_val16 *pcm, const opus_val16 *pcm,
int frame_size, int frame_size,
unsigned char *data, unsigned char *data,
int max_data_bytes opus_int32 max_data_bytes
) )
{ {
int coupled_size; int coupled_size;
@ -309,7 +309,7 @@ int opus_multistream_encode_float(
const float *pcm, const float *pcm,
int frame_size, int frame_size,
unsigned char *data, unsigned char *data,
int max_data_bytes opus_int32 max_data_bytes
) )
{ {
int i, ret; int i, ret;
@ -333,7 +333,7 @@ int opus_multistream_encode(
const opus_int16 *pcm, const opus_int16 *pcm,
int frame_size, int frame_size,
unsigned char *data, unsigned char *data,
int max_data_bytes opus_int32 max_data_bytes
) )
{ {
int i, ret; int i, ret;
@ -587,7 +587,7 @@ OpusMSDecoder *opus_multistream_decoder_create(
static int opus_multistream_decode_native( static int opus_multistream_decode_native(
OpusMSDecoder *st, OpusMSDecoder *st,
const unsigned char *data, const unsigned char *data,
int len, opus_int32 len,
opus_val16 *pcm, opus_val16 *pcm,
int frame_size, int frame_size,
int decode_fec int decode_fec
@ -693,7 +693,7 @@ static int opus_multistream_decode_native(
int opus_multistream_decode( int opus_multistream_decode(
OpusMSDecoder *st, OpusMSDecoder *st,
const unsigned char *data, const unsigned char *data,
int len, opus_int32 len,
opus_int16 *pcm, opus_int16 *pcm,
int frame_size, int frame_size,
int decode_fec int decode_fec
@ -704,7 +704,7 @@ int opus_multistream_decode(
#ifndef DISABLE_FLOAT_API #ifndef DISABLE_FLOAT_API
int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data, int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
int len, float *pcm, int frame_size, int decode_fec) opus_int32 len, float *pcm, int frame_size, int decode_fec)
{ {
VARDECL(opus_int16, out); VARDECL(opus_int16, out);
int ret, i; int ret, i;
@ -726,7 +726,7 @@ int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
#else #else
int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data, int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
int len, opus_int16 *pcm, int frame_size, int decode_fec) opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
{ {
VARDECL(float, out); VARDECL(float, out);
int ret, i; int ret, i;
@ -747,7 +747,7 @@ int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
int opus_multistream_decode_float( int opus_multistream_decode_float(
OpusMSDecoder *st, OpusMSDecoder *st,
const unsigned char *data, const unsigned char *data,
int len, opus_int32 len,
float *pcm, float *pcm,
int frame_size, int frame_size,
int decode_fec int decode_fec