summaryrefslogtreecommitdiff
path: root/media/libopus/src/opus_multistream_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/libopus/src/opus_multistream_decoder.c')
-rw-r--r--media/libopus/src/opus_multistream_decoder.c97
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)
{