diff options
Diffstat (limited to 'media/libopus/src/opus_multistream_decoder.c')
-rw-r--r-- | media/libopus/src/opus_multistream_decoder.c | 97 |
1 files changed, 56 insertions, 41 deletions
diff --git a/media/libopus/src/opus_multistream_decoder.c b/media/libopus/src/opus_multistream_decoder.c index b95eaa6eac..a2837c3549 100644 --- a/media/libopus/src/opus_multistream_decoder.c +++ b/media/libopus/src/opus_multistream_decoder.c @@ -37,15 +37,18 @@ #include "float_cast.h" #include "os_support.h" -struct OpusMSDecoder { - ChannelLayout layout; - /* Decoder states go here */ -}; - - +/* DECODER */ +#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS) +static void validate_ms_decoder(OpusMSDecoder *st) +{ + validate_layout(&st->layout); +} +#define VALIDATE_MS_DECODER(st) validate_ms_decoder(st) +#else +#define VALIDATE_MS_DECODER(st) +#endif -/* DECODER */ opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams) { @@ -143,15 +146,6 @@ OpusMSDecoder *opus_multistream_decoder_create( return st; } -typedef void (*opus_copy_channel_out_func)( - void *dst, - int dst_stride, - int dst_channel, - const opus_val16 *src, - int src_stride, - int frame_size -); - static int opus_multistream_packet_validate(const unsigned char *data, opus_int32 len, int nb_streams, opus_int32 Fs) { @@ -181,7 +175,7 @@ static int opus_multistream_packet_validate(const unsigned char *data, return samples; } -static int opus_multistream_decode_native( +int opus_multistream_decode_native( OpusMSDecoder *st, const unsigned char *data, opus_int32 len, @@ -189,7 +183,8 @@ static int opus_multistream_decode_native( opus_copy_channel_out_func copy_channel_out, int frame_size, int decode_fec, - int soft_clip + int soft_clip, + void *user_data ) { opus_int32 Fs; @@ -201,8 +196,14 @@ static int opus_multistream_decode_native( VARDECL(opus_val16, buf); ALLOC_STACK; + VALIDATE_MS_DECODER(st); + if (frame_size <= 0) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } /* Limit frame_size to avoid excessive stack allocations. */ - opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs)); + MUST_SUCCEED(opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs))); frame_size = IMIN(frame_size, Fs/25*3); ALLOC(buf, 2*frame_size, opus_val16); ptr = (char*)st + align(sizeof(OpusMSDecoder)); @@ -237,7 +238,8 @@ static int opus_multistream_decode_native( for (s=0;s<st->layout.nb_streams;s++) { OpusDecoder *dec; - int packet_offset, ret; + opus_int32 packet_offset; + int ret; dec = (OpusDecoder*)ptr; ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size); @@ -249,8 +251,11 @@ static int opus_multistream_decode_native( } packet_offset = 0; ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip); - data += packet_offset; - len -= packet_offset; + if (!do_plc) + { + data += packet_offset; + len -= packet_offset; + } if (ret <= 0) { RESTORE_STACK; @@ -265,7 +270,7 @@ static int opus_multistream_decode_native( while ( (chan = get_left_channel(&st->layout, s, prev)) != -1) { (*copy_channel_out)(pcm, st->layout.nb_channels, chan, - buf, 2, frame_size); + buf, 2, frame_size, user_data); prev = chan; } prev = -1; @@ -273,7 +278,7 @@ static int opus_multistream_decode_native( while ( (chan = get_right_channel(&st->layout, s, prev)) != -1) { (*copy_channel_out)(pcm, st->layout.nb_channels, chan, - buf+1, 2, frame_size); + buf+1, 2, frame_size, user_data); prev = chan; } } else { @@ -283,7 +288,7 @@ static int opus_multistream_decode_native( while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1) { (*copy_channel_out)(pcm, st->layout.nb_channels, chan, - buf, 1, frame_size); + buf, 1, frame_size, user_data); prev = chan; } } @@ -294,7 +299,7 @@ static int opus_multistream_decode_native( if (st->layout.mapping[c] == 255) { (*copy_channel_out)(pcm, st->layout.nb_channels, c, - NULL, 0, frame_size); + NULL, 0, frame_size, user_data); } } RESTORE_STACK; @@ -308,11 +313,13 @@ static void opus_copy_channel_out_float( int dst_channel, const opus_val16 *src, int src_stride, - int frame_size + int frame_size, + void *user_data ) { float *float_dst; opus_int32 i; + (void)user_data; float_dst = (float*)dst; if (src != NULL) { @@ -337,11 +344,13 @@ static void opus_copy_channel_out_short( int dst_channel, const opus_val16 *src, int src_stride, - int frame_size + int frame_size, + void *user_data ) { opus_int16 *short_dst; opus_int32 i; + (void)user_data; short_dst = (opus_int16*)dst; if (src != NULL) { @@ -372,7 +381,7 @@ int opus_multistream_decode( ) { return opus_multistream_decode_native(st, data, len, - pcm, opus_copy_channel_out_short, frame_size, decode_fec, 0); + pcm, opus_copy_channel_out_short, frame_size, decode_fec, 0, NULL); } #ifndef DISABLE_FLOAT_API @@ -380,7 +389,7 @@ int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data, opus_int32 len, float *pcm, int frame_size, int decode_fec) { return opus_multistream_decode_native(st, data, len, - pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0); + pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0, NULL); } #endif @@ -390,32 +399,30 @@ int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data, opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec) { return opus_multistream_decode_native(st, data, len, - pcm, opus_copy_channel_out_short, frame_size, decode_fec, 1); + pcm, opus_copy_channel_out_short, frame_size, decode_fec, 1, NULL); } int opus_multistream_decode_float( OpusMSDecoder *st, const unsigned char *data, opus_int32 len, - float *pcm, + opus_val16 *pcm, int frame_size, int decode_fec ) { return opus_multistream_decode_native(st, data, len, - pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0); + pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0, NULL); } #endif -int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) +int opus_multistream_decoder_ctl_va_list(OpusMSDecoder *st, int request, + va_list ap) { - va_list ap; int coupled_size, mono_size; char *ptr; int ret = OPUS_OK; - va_start(ap, request); - coupled_size = opus_decoder_get_size(2); mono_size = opus_decoder_get_size(1); ptr = (char*)st + align(sizeof(OpusMSDecoder)); @@ -425,6 +432,7 @@ int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) case OPUS_GET_SAMPLE_RATE_REQUEST: case OPUS_GET_GAIN_REQUEST: case OPUS_GET_LAST_PACKET_DURATION_REQUEST: + case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: { OpusDecoder *dec; /* For int32* GET params, just query the first stream */ @@ -482,7 +490,7 @@ int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OpusDecoder **value; stream_id = va_arg(ap, opus_int32); if (stream_id<0 || stream_id >= st->layout.nb_streams) - ret = OPUS_BAD_ARG; + goto bad_arg; value = va_arg(ap, OpusDecoder**); if (!value) { @@ -499,6 +507,7 @@ int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) } break; case OPUS_SET_GAIN_REQUEST: + case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: { int s; /* This works for int32 params */ @@ -522,14 +531,20 @@ int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) ret = OPUS_UNIMPLEMENTED; break; } - - va_end(ap); return ret; bad_arg: - va_end(ap); return OPUS_BAD_ARG; } +int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) +{ + int ret; + va_list ap; + va_start(ap, request); + ret = opus_multistream_decoder_ctl_va_list(st, request, ap); + va_end(ap); + return ret; +} void opus_multistream_decoder_destroy(OpusMSDecoder *st) { |