aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-01 20:44:27 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-01 20:44:27 +0000
commit660e25f9ad9e0b421241dcf675c6883fecb859cd (patch)
tree2c3093f0459f0bf8089ec409accadb3c218909b4
parent6304b9628cb7244e3cc78f740aeb6659562f1857 (diff)
downloadsrc-660e25f9ad9e0b421241dcf675c6883fecb859cd.tar.gz
Update opus to 1.0.1
TBR=wez@chromium.org Review URL: https://codereview.chromium.org/11369030 git-svn-id: svn://svn.chromium.org/chrome/trunk/deps/third_party/opus@165487 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--include/opus_defines.h12
-rw-r--r--[-rwxr-xr-x]ltmain.sh0
-rw-r--r--src/opus_decoder.c13
-rw-r--r--src/opus_encoder.c11
-rw-r--r--src/opus_multistream.c275
-rw-r--r--win32/genversion.bat92
6 files changed, 277 insertions, 126 deletions
diff --git a/include/opus_defines.h b/include/opus_defines.h
index ec154ba..82a5f06 100644
--- a/include/opus_defines.h
+++ b/include/opus_defines.h
@@ -115,7 +115,8 @@ extern "C" {
#endif
/** These are the actual Encoder CTL ID numbers.
- * They should not be used directly by applications. */
+ * They should not be used directly by applications.
+ * In general, SETs should be even and GETs should be odd.*/
#define OPUS_SET_APPLICATION_REQUEST 4000
#define OPUS_GET_APPLICATION_REQUEST 4001
#define OPUS_SET_BITRATE_REQUEST 4002
@@ -142,6 +143,7 @@ extern "C" {
#define OPUS_GET_SIGNAL_REQUEST 4025
#define OPUS_GET_LOOKAHEAD_REQUEST 4027
/* #define OPUS_RESET_STATE 4028 */
+#define OPUS_GET_SAMPLE_RATE_REQUEST 4029
#define OPUS_GET_FINAL_RANGE_REQUEST 4031
#define OPUS_GET_PITCH_REQUEST 4033
#define OPUS_SET_GAIN_REQUEST 4034
@@ -426,6 +428,14 @@ extern "C" {
* @hideinitializer */
#define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x)
+/** Gets the sampling rate the encoder or decoder was initialized with.
+ * This simply returns the <code>Fs</code> value passed to opus_encoder_init()
+ * or opus_decoder_init().
+ * @param[out] x <tt>opus_int32 *</tt>: Sampling rate of encoder or decoder.
+ * @hideinitializer
+ */
+#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x)
+
/** Gets the total samples of delay added by the entire codec.
* This can be queried by the encoder and then the provided number of samples can be
* skipped on from the start of the decoder's output to provide time aligned input
diff --git a/ltmain.sh b/ltmain.sh
index 63ae69d..63ae69d 100755..100644
--- a/ltmain.sh
+++ b/ltmain.sh
diff --git a/src/opus_decoder.c b/src/opus_decoder.c
index 966ca87..161bd02 100644
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -228,6 +228,8 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
RESTORE_STACK;
return OPUS_BUFFER_TOO_SMALL;
}
+ /* Limit frame_size to avoid excessive stack allocations. */
+ frame_size = IMIN(frame_size, st->Fs/25*3);
/* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */
if (len<=1)
{
@@ -856,6 +858,17 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
st->frame_size = st->Fs/400;
}
break;
+ case OPUS_GET_SAMPLE_RATE_REQUEST:
+ {
+ opus_int32 *value = va_arg(ap, opus_int32*);
+ if (value==NULL)
+ {
+ ret = OPUS_BAD_ARG;
+ break;
+ }
+ *value = st->Fs;
+ }
+ break;
case OPUS_GET_PITCH_REQUEST:
{
opus_int32 *value = va_arg(ap, opus_int32*);
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index 1fcbf0f..b77e48e 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -1531,6 +1531,17 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
*value += st->delay_compensation;
}
break;
+ case OPUS_GET_SAMPLE_RATE_REQUEST:
+ {
+ opus_int32 *value = va_arg(ap, opus_int32*);
+ if (value==NULL)
+ {
+ ret = OPUS_BAD_ARG;
+ break;
+ }
+ *value = st->Fs;
+ }
+ break;
case OPUS_GET_FINAL_RANGE_REQUEST:
{
opus_uint32 *value = va_arg(ap, opus_uint32*);
diff --git a/src/opus_multistream.c b/src/opus_multistream.c
index a38b121..955dc81 100644
--- a/src/opus_multistream.c
+++ b/src/opus_multistream.c
@@ -55,7 +55,6 @@ struct OpusMSDecoder {
/* Decoder states go here */
};
-
#ifdef FIXED_POINT
#define opus_encode_native opus_encode
#else
@@ -221,23 +220,31 @@ OpusMSEncoder *opus_multistream_encoder_create(
return st;
}
+typedef void (*opus_copy_channel_in_func)(
+ opus_val16 *dst,
+ int dst_stride,
+ const void *src,
+ int src_stride,
+ int src_channel,
+ int frame_size
+);
+
/* Max size in case the encoder decides to return three frames */
#define MS_FRAME_TMP (3*1275+7)
-#ifdef FIXED_POINT
-int opus_multistream_encode(
-#else
-int opus_multistream_encode_float(
-#endif
+static int opus_multistream_encode_native
+(
OpusMSEncoder *st,
- const opus_val16 *pcm,
+ opus_copy_channel_in_func copy_channel_in,
+ const void *pcm,
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
)
{
+ opus_int32 Fs;
int coupled_size;
int mono_size;
- int s, i;
+ int s;
char *ptr;
int tot_size;
VARDECL(opus_val16, buf);
@@ -245,8 +252,18 @@ int opus_multistream_encode_float(
OpusRepacketizer rp;
ALLOC_STACK;
- ALLOC(buf, 2*frame_size, opus_val16);
ptr = (char*)st + align(sizeof(OpusMSEncoder));
+ opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
+ /* Validate frame_size before using it to allocate stack space.
+ This mirrors the checks in opus_encode[_float](). */
+ if (400*frame_size != Fs && 200*frame_size != Fs &&
+ 100*frame_size != Fs && 50*frame_size != Fs &&
+ 25*frame_size != Fs && 50*frame_size != 3*Fs)
+ {
+ RESTORE_STACK;
+ return OPUS_BAD_ARG;
+ }
+ ALLOC(buf, 2*frame_size, opus_val16);
coupled_size = opus_encoder_get_size(2);
mono_size = opus_encoder_get_size(1);
@@ -270,16 +287,15 @@ int opus_multistream_encode_float(
int left, right;
left = get_left_channel(&st->layout, s, -1);
right = get_right_channel(&st->layout, s, -1);
- for (i=0;i<frame_size;i++)
- {
- buf[2*i] = pcm[st->layout.nb_channels*i+left];
- buf[2*i+1] = pcm[st->layout.nb_channels*i+right];
- }
+ (*copy_channel_in)(buf, 2,
+ pcm, st->layout.nb_channels, left, frame_size);
+ (*copy_channel_in)(buf+1, 2,
+ pcm, st->layout.nb_channels, right, frame_size);
ptr += align(coupled_size);
} else {
int chan = get_mono_channel(&st->layout, s, -1);
- for (i=0;i<frame_size;i++)
- buf[i] = pcm[st->layout.nb_channels*i+chan];
+ (*copy_channel_in)(buf, 1,
+ pcm, st->layout.nb_channels, chan, frame_size);
ptr += align(mono_size);
}
/* number of bytes left (+Toc) */
@@ -306,7 +322,60 @@ int opus_multistream_encode_float(
}
+#if !defined(DISABLE_FLOAT_API)
+static void opus_copy_channel_in_float(
+ opus_val16 *dst,
+ int dst_stride,
+ const void *src,
+ int src_stride,
+ int src_channel,
+ int frame_size
+)
+{
+ const float *float_src;
+ int i;
+ float_src = (const float *)src;
+ for (i=0;i<frame_size;i++)
+#if defined(FIXED_POINT)
+ dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
+#else
+ dst[i*dst_stride] = float_src[i*src_stride+src_channel];
+#endif
+}
+#endif
+
+static void opus_copy_channel_in_short(
+ opus_val16 *dst,
+ int dst_stride,
+ const void *src,
+ int src_stride,
+ int src_channel,
+ int frame_size
+)
+{
+ const opus_int16 *short_src;
+ int i;
+ short_src = (const opus_int16 *)src;
+ for (i=0;i<frame_size;i++)
+#if defined(FIXED_POINT)
+ dst[i*dst_stride] = short_src[i*src_stride+src_channel];
+#else
+ dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
+#endif
+}
+
#ifdef FIXED_POINT
+int opus_multistream_encode(
+ OpusMSEncoder *st,
+ const opus_val16 *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+)
+{
+ return opus_multistream_encode_native(st, opus_copy_channel_in_short,
+ pcm, frame_size, data, max_data_bytes);
+}
#ifndef DISABLE_FLOAT_API
int opus_multistream_encode_float(
@@ -317,22 +386,26 @@ int opus_multistream_encode_float(
opus_int32 max_data_bytes
)
{
- int i, ret;
- VARDECL(opus_int16, in);
- ALLOC_STACK;
-
- ALLOC(in, frame_size*st->layout.nb_channels, opus_int16);
-
- for (i=0;i<frame_size*st->layout.nb_channels;i++)
- in[i] = FLOAT2INT16(pcm[i]);
- ret = opus_multistream_encode(st, in, frame_size, data, max_data_bytes);
- RESTORE_STACK;
- return ret;
+ return opus_multistream_encode_native(st, opus_copy_channel_in_float,
+ pcm, frame_size, data, max_data_bytes);
}
#endif
#else
+int opus_multistream_encode_float
+(
+ OpusMSEncoder *st,
+ const opus_val16 *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+)
+{
+ return opus_multistream_encode_native(st, opus_copy_channel_in_float,
+ pcm, frame_size, data, max_data_bytes);
+}
+
int opus_multistream_encode(
OpusMSEncoder *st,
const opus_int16 *pcm,
@@ -341,19 +414,9 @@ int opus_multistream_encode(
opus_int32 max_data_bytes
)
{
- int i, ret;
- VARDECL(float, in);
- ALLOC_STACK;
-
- ALLOC(in, frame_size*st->layout.nb_channels, float);
-
- for (i=0;i<frame_size*st->layout.nb_channels;i++)
- in[i] = (1.f/32768.f)*pcm[i];
- ret = opus_multistream_encode_float(st, in, frame_size, data, max_data_bytes);
- RESTORE_STACK;
- return ret;
+ return opus_multistream_encode_native(st, opus_copy_channel_in_short,
+ pcm, frame_size, data, max_data_bytes);
}
-
#endif
int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
@@ -418,6 +481,7 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
case OPUS_GET_VBR_CONSTRAINT_REQUEST:
case OPUS_GET_SIGNAL_REQUEST:
case OPUS_GET_LOOKAHEAD_REQUEST:
+ case OPUS_GET_SAMPLE_RATE_REQUEST:
case OPUS_GET_INBAND_FEC_REQUEST:
{
OpusEncoder *enc;
@@ -603,23 +667,37 @@ OpusMSDecoder *opus_multistream_decoder_create(
}
+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_decode_native(
OpusMSDecoder *st,
const unsigned char *data,
opus_int32 len,
- opus_val16 *pcm,
+ void *pcm,
+ opus_copy_channel_out_func copy_channel_out,
int frame_size,
int decode_fec
)
{
+ opus_int32 Fs;
int coupled_size;
int mono_size;
- int s, i, c;
+ int s, c;
char *ptr;
int do_plc=0;
VARDECL(opus_val16, buf);
ALLOC_STACK;
+ /* Limit frame_size to avoid excessive stack allocations. */
+ 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));
coupled_size = opus_decoder_get_size(2);
@@ -671,16 +749,16 @@ static int opus_multistream_decode_native(
/* Copy "left" audio to the channel(s) where it belongs */
while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
{
- for (i=0;i<frame_size;i++)
- pcm[st->layout.nb_channels*i+chan] = buf[2*i];
+ (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
+ buf, 2, frame_size);
prev = chan;
}
prev = -1;
/* Copy "right" audio to the channel(s) where it belongs */
while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
{
- for (i=0;i<frame_size;i++)
- pcm[st->layout.nb_channels*i+chan] = buf[2*i+1];
+ (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
+ buf+1, 2, frame_size);
prev = chan;
}
} else {
@@ -689,8 +767,8 @@ static int opus_multistream_decode_native(
/* Copy audio to the channel(s) where it belongs */
while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
{
- for (i=0;i<frame_size;i++)
- pcm[st->layout.nb_channels*i+chan] = buf[i];
+ (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
+ buf, 1, frame_size);
prev = chan;
}
}
@@ -700,14 +778,74 @@ static int opus_multistream_decode_native(
{
if (st->layout.mapping[c] == 255)
{
- for (i=0;i<frame_size;i++)
- pcm[st->layout.nb_channels*i+c] = 0;
+ (*copy_channel_out)(pcm, st->layout.nb_channels, c,
+ NULL, 0, frame_size);
}
}
RESTORE_STACK;
return frame_size;
}
+#if !defined(DISABLE_FLOAT_API)
+static void opus_copy_channel_out_float(
+ void *dst,
+ int dst_stride,
+ int dst_channel,
+ const opus_val16 *src,
+ int src_stride,
+ int frame_size
+)
+{
+ float *float_dst;
+ int i;
+ float_dst = (float*)dst;
+ if (src != NULL)
+ {
+ for (i=0;i<frame_size;i++)
+#if defined(FIXED_POINT)
+ float_dst[i*dst_stride+dst_channel] = (1/32768.f)*src[i*src_stride];
+#else
+ float_dst[i*dst_stride+dst_channel] = src[i*src_stride];
+#endif
+ }
+ else
+ {
+ for (i=0;i<frame_size;i++)
+ float_dst[i*dst_stride+dst_channel] = 0;
+ }
+}
+#endif
+
+static void opus_copy_channel_out_short(
+ void *dst,
+ int dst_stride,
+ int dst_channel,
+ const opus_val16 *src,
+ int src_stride,
+ int frame_size
+)
+{
+ opus_int16 *short_dst;
+ int i;
+ short_dst = (opus_int16*)dst;
+ if (src != NULL)
+ {
+ for (i=0;i<frame_size;i++)
+#if defined(FIXED_POINT)
+ short_dst[i*dst_stride+dst_channel] = src[i*src_stride];
+#else
+ short_dst[i*dst_stride+dst_channel] = FLOAT2INT16(src[i*src_stride]);
+#endif
+ }
+ else
+ {
+ for (i=0;i<frame_size;i++)
+ short_dst[i*dst_stride+dst_channel] = 0;
+ }
+}
+
+
+
#ifdef FIXED_POINT
int opus_multistream_decode(
OpusMSDecoder *st,
@@ -718,27 +856,16 @@ int opus_multistream_decode(
int decode_fec
)
{
- return opus_multistream_decode_native(st, data, len, pcm, frame_size, decode_fec);
+ return opus_multistream_decode_native(st, data, len,
+ pcm, opus_copy_channel_out_short, frame_size, decode_fec);
}
#ifndef DISABLE_FLOAT_API
int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
opus_int32 len, float *pcm, int frame_size, int decode_fec)
{
- VARDECL(opus_int16, out);
- int ret, i;
- ALLOC_STACK;
-
- ALLOC(out, frame_size*st->layout.nb_channels, opus_int16);
-
- ret = opus_multistream_decode_native(st, data, len, out, frame_size, decode_fec);
- if (ret > 0)
- {
- for (i=0;i<ret*st->layout.nb_channels;i++)
- pcm[i] = (1.f/32768.f)*(out[i]);
- }
- RESTORE_STACK;
- return ret;
+ return opus_multistream_decode_native(st, data, len,
+ pcm, opus_copy_channel_out_float, frame_size, decode_fec);
}
#endif
@@ -747,20 +874,8 @@ int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
{
- VARDECL(float, out);
- int ret, i;
- ALLOC_STACK;
-
- ALLOC(out, frame_size*st->layout.nb_channels, float);
-
- ret = opus_multistream_decode_native(st, data, len, out, frame_size, decode_fec);
- if (ret > 0)
- {
- for (i=0;i<ret*st->layout.nb_channels;i++)
- pcm[i] = FLOAT2INT16(out[i]);
- }
- RESTORE_STACK;
- return ret;
+ return opus_multistream_decode_native(st, data, len,
+ pcm, opus_copy_channel_out_short, frame_size, decode_fec);
}
int opus_multistream_decode_float(
@@ -772,7 +887,8 @@ int opus_multistream_decode_float(
int decode_fec
)
{
- return opus_multistream_decode_native(st, data, len, pcm, frame_size, decode_fec);
+ return opus_multistream_decode_native(st, data, len,
+ pcm, opus_copy_channel_out_float, frame_size, decode_fec);
}
#endif
@@ -791,6 +907,7 @@ int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
switch (request)
{
case OPUS_GET_BANDWIDTH_REQUEST:
+ case OPUS_GET_SAMPLE_RATE_REQUEST:
{
OpusDecoder *dec;
/* For int32* GET params, just query the first stream */
diff --git a/win32/genversion.bat b/win32/genversion.bat
index 09f65cc..7934ebf 100644
--- a/win32/genversion.bat
+++ b/win32/genversion.bat
@@ -1,46 +1,46 @@
-@echo off
-
-setlocal enableextensions enabledelayedexpansion
-
-for /f %%v in ('git describe --tags --match "v*"') do set version=%%v
-
-if not "%version%"=="" goto :gotversion
-
-if exist "%~dp0..\version.mk" goto :getversion
-
-echo Git cannot be found, nor can version.mk. Generating unknown version.
-
-set version=unknown
-
-goto :gotversion
-
-:getversion
-
-for /f "delims== tokens=2" %%v in (%~dp0..\version.mk) do set version=%%v
-
-set version=!version:^"=!
-set version=!version: =!
-
-:gotversion
-
-set version_out=#define %2 "%version%"
-set version_mk=%2 = "%version%"
-
-echo %version_out%> %1_temp
-
-if %version%==unknown goto :skipgenerate
-
-echo # static version string; update manually every release.> "%~dp0..\version.mk"
-echo %version_mk%>> "%~dp0..\version.mk"
-
-:skipgenerate
-
-echo n | comp %1_temp %1 > NUL 2> NUL
-
-if not errorlevel 1 goto exit
-
-copy /y %1_temp %1
-
-:exit
-
-del %1_temp
+@echo off
+
+setlocal enableextensions enabledelayedexpansion
+
+for /f %%v in ('git describe --tags --match "v*"') do set version=%%v
+
+if not "%version%"=="" goto :gotversion
+
+if exist "%~dp0..\version.mk" goto :getversion
+
+echo Git cannot be found, nor can version.mk. Generating unknown version.
+
+set version=unknown
+
+goto :gotversion
+
+:getversion
+
+for /f "delims== tokens=2" %%v in (%~dp0..\version.mk) do set version=%%v
+
+set version=!version:^"=!
+set version=!version: =!
+
+:gotversion
+
+set version_out=#define %2 "%version%"
+set version_mk=%2 = "%version%"
+
+echo %version_out%> %1_temp
+
+if %version%==unknown goto :skipgenerate
+
+echo # static version string; update manually every release.> "%~dp0..\version.mk"
+echo %version_mk%>> "%~dp0..\version.mk"
+
+:skipgenerate
+
+echo n | comp %1_temp %1 > NUL 2> NUL
+
+if not errorlevel 1 goto exit
+
+copy /y %1_temp %1
+
+:exit
+
+del %1_temp