opus: Update to upstream libopus 1.1.3
This commit is contained in:
parent
2ca0337f5f
commit
9845bdde8d
10 changed files with 238 additions and 77 deletions
4
thirdparty/README.md
vendored
4
thirdparty/README.md
vendored
|
@ -141,7 +141,7 @@ changes are marked with `// -- GODOT --` comments.
|
||||||
## openssl
|
## openssl
|
||||||
|
|
||||||
- Upstream: https://www.openssl.org
|
- Upstream: https://www.openssl.org
|
||||||
- Version: 1.2.0h
|
- Version: 1.0.2h
|
||||||
- License: OpenSSL license / BSD-like
|
- License: OpenSSL license / BSD-like
|
||||||
|
|
||||||
Files extracted from the upstream source:
|
Files extracted from the upstream source:
|
||||||
|
@ -152,7 +152,7 @@ TODO.
|
||||||
## opus
|
## opus
|
||||||
|
|
||||||
- Upstream: https://opus-codec.org
|
- Upstream: https://opus-codec.org
|
||||||
- Version: 1.1.2 (opus) and 0.7 (opusfile)
|
- Version: 1.1.3 (opus) and 0.7 (opusfile)
|
||||||
- License: BSD-3-Clause
|
- License: BSD-3-Clause
|
||||||
|
|
||||||
Files extracted from upstream source:
|
Files extracted from upstream source:
|
||||||
|
|
40
thirdparty/opus/COPYING
vendored
40
thirdparty/opus/COPYING
vendored
|
@ -1,4 +1,7 @@
|
||||||
Copyright (c) 1994-2013 Xiph.Org Foundation and contributors
|
Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic,
|
||||||
|
Jean-Marc Valin, Timothy B. Terriberry,
|
||||||
|
CSIRO, Gregory Maxwell, Mark Borgerding,
|
||||||
|
Erik de Castro Lopo
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
|
@ -11,18 +14,31 @@ notice, this list of conditions and the following disclaimer.
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
- Neither the name of the Xiph.Org Foundation nor the names of its
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
contributors may be used to endorse or promote products derived from
|
names of specific contributors, may be used to endorse or promote
|
||||||
this software without specific prior written permission.
|
products derived from this software without specific prior written
|
||||||
|
permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
Opus is subject to the royalty-free patent licenses which are
|
||||||
|
specified at:
|
||||||
|
|
||||||
|
Xiph.Org Foundation:
|
||||||
|
https://datatracker.ietf.org/ipr/1524/
|
||||||
|
|
||||||
|
Microsoft Corporation:
|
||||||
|
https://datatracker.ietf.org/ipr/1914/
|
||||||
|
|
||||||
|
Broadcom Corporation:
|
||||||
|
https://datatracker.ietf.org/ipr/1526/
|
||||||
|
|
13
thirdparty/opus/analysis.c
vendored
13
thirdparty/opus/analysis.c
vendored
|
@ -540,17 +540,14 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
|
||||||
/* Instantaneous probability of speech and music, with beta pre-applied. */
|
/* Instantaneous probability of speech and music, with beta pre-applied. */
|
||||||
float speech0;
|
float speech0;
|
||||||
float music0;
|
float music0;
|
||||||
|
float p, q;
|
||||||
|
|
||||||
/* One transition every 3 minutes of active audio */
|
/* One transition every 3 minutes of active audio */
|
||||||
tau = .00005f*frame_probs[1];
|
tau = .00005f*frame_probs[1];
|
||||||
beta = .05f;
|
/* Adapt beta based on how "unexpected" the new prob is */
|
||||||
if (1) {
|
p = MAX16(.05f,MIN16(.95f,frame_probs[0]));
|
||||||
/* Adapt beta based on how "unexpected" the new prob is */
|
q = MAX16(.05f,MIN16(.95f,tonal->music_prob));
|
||||||
float p, q;
|
beta = .01f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p));
|
||||||
p = MAX16(.05f,MIN16(.95f,frame_probs[0]));
|
|
||||||
q = MAX16(.05f,MIN16(.95f,tonal->music_prob));
|
|
||||||
beta = .01f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p));
|
|
||||||
}
|
|
||||||
/* p0 and p1 are the probabilities of speech and music at this frame
|
/* p0 and p1 are the probabilities of speech and music at this frame
|
||||||
using only information from previous frame and applying the
|
using only information from previous frame and applying the
|
||||||
state transition model */
|
state transition model */
|
||||||
|
|
8
thirdparty/opus/opus.c
vendored
8
thirdparty/opus/opus.c
vendored
|
@ -104,6 +104,10 @@ OPUS_EXPORT void opus_pcm_soft_clip(float *_x, int N, int C, float *declip_mem)
|
||||||
|
|
||||||
/* Compute a such that maxval + a*maxval^2 = 1 */
|
/* Compute a such that maxval + a*maxval^2 = 1 */
|
||||||
a=(maxval-1)/(maxval*maxval);
|
a=(maxval-1)/(maxval*maxval);
|
||||||
|
/* Slightly boost "a" by 2^-22. This is just enough to ensure -ffast-math
|
||||||
|
does not cause output values larger than +/-1, but small enough not
|
||||||
|
to matter even for 24-bit output. */
|
||||||
|
a += a*2.4e-7;
|
||||||
if (x[i*C]>0)
|
if (x[i*C]>0)
|
||||||
a = -a;
|
a = -a;
|
||||||
/* Apply soft clipping */
|
/* Apply soft clipping */
|
||||||
|
@ -201,8 +205,10 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
|
||||||
opus_int32 pad = 0;
|
opus_int32 pad = 0;
|
||||||
const unsigned char *data0 = data;
|
const unsigned char *data0 = data;
|
||||||
|
|
||||||
if (size==NULL)
|
if (size==NULL || len<0)
|
||||||
return OPUS_BAD_ARG;
|
return OPUS_BAD_ARG;
|
||||||
|
if (len==0)
|
||||||
|
return OPUS_INVALID_PACKET;
|
||||||
|
|
||||||
framesize = opus_packet_get_samples_per_frame(data, 48000);
|
framesize = opus_packet_get_samples_per_frame(data, 48000);
|
||||||
|
|
||||||
|
|
2
thirdparty/opus/opus/opus.h
vendored
2
thirdparty/opus/opus/opus.h
vendored
|
@ -142,7 +142,7 @@ extern "C" {
|
||||||
*
|
*
|
||||||
* opus_encode() and opus_encode_float() return the number of bytes actually written to the packet.
|
* opus_encode() and opus_encode_float() return the number of bytes actually written to the packet.
|
||||||
* The return value <b>can be negative</b>, which indicates that an error has occurred. If the return value
|
* The return value <b>can be negative</b>, which indicates that an error has occurred. If the return value
|
||||||
* is 1 byte, then the packet does not need to be transmitted (DTX).
|
* is 2 bytes or less, then the packet does not need to be transmitted (DTX).
|
||||||
*
|
*
|
||||||
* Once the encoder state if no longer needed, it can be destroyed with
|
* Once the encoder state if no longer needed, it can be destroyed with
|
||||||
*
|
*
|
||||||
|
|
2
thirdparty/opus/opus/opus_defines.h
vendored
2
thirdparty/opus/opus/opus_defines.h
vendored
|
@ -65,7 +65,7 @@ extern "C" {
|
||||||
|
|
||||||
#ifndef OPUS_EXPORT
|
#ifndef OPUS_EXPORT
|
||||||
# if defined(WIN32)
|
# if defined(WIN32)
|
||||||
# ifdef OPUS_BUILD
|
# if defined(OPUS_BUILD) && defined(DLL_EXPORT)
|
||||||
# define OPUS_EXPORT __declspec(dllexport)
|
# define OPUS_EXPORT __declspec(dllexport)
|
||||||
# else
|
# else
|
||||||
# define OPUS_EXPORT
|
# define OPUS_EXPORT
|
||||||
|
|
8
thirdparty/opus/opus/opus_multistream.h
vendored
8
thirdparty/opus/opus/opus_multistream.h
vendored
|
@ -110,10 +110,10 @@ extern "C" {
|
||||||
* packets produced by the encoder. Some basic information, such as packet
|
* packets produced by the encoder. Some basic information, such as packet
|
||||||
* duration, can be computed without any special negotiation.
|
* duration, can be computed without any special negotiation.
|
||||||
*
|
*
|
||||||
* The format for multistream Opus packets is defined in the
|
* The format for multistream Opus packets is defined in
|
||||||
* <a href="https://tools.ietf.org/html/draft-ietf-codec-oggopus">Ogg
|
* <a href="https://tools.ietf.org/html/rfc7845">RFC 7845</a>
|
||||||
* encapsulation specification</a> and is based on the self-delimited Opus
|
* and is based on the self-delimited Opus framing described in Appendix B of
|
||||||
* framing described in Appendix B of <a href="https://tools.ietf.org/html/rfc6716">RFC 6716</a>.
|
* <a href="https://tools.ietf.org/html/rfc6716">RFC 6716</a>.
|
||||||
* Normal Opus packets are just a degenerate case of multistream Opus packets,
|
* Normal Opus packets are just a degenerate case of multistream Opus packets,
|
||||||
* and can be encoded or decoded with the multistream API by setting
|
* and can be encoded or decoded with the multistream API by setting
|
||||||
* <code>streams</code> to <code>1</code> when initializing the encoder or
|
* <code>streams</code> to <code>1</code> when initializing the encoder or
|
||||||
|
|
51
thirdparty/opus/opus_encoder.c
vendored
51
thirdparty/opus/opus_encoder.c
vendored
|
@ -860,9 +860,6 @@ opus_int32 compute_frame_size(const void *analysis_pcm, int frame_size,
|
||||||
|
|
||||||
opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int32 Fs, StereoWidthState *mem)
|
opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int32 Fs, StereoWidthState *mem)
|
||||||
{
|
{
|
||||||
opus_val16 corr;
|
|
||||||
opus_val16 ldiff;
|
|
||||||
opus_val16 width;
|
|
||||||
opus_val32 xx, xy, yy;
|
opus_val32 xx, xy, yy;
|
||||||
opus_val16 sqrt_xx, sqrt_yy;
|
opus_val16 sqrt_xx, sqrt_yy;
|
||||||
opus_val16 qrrt_xx, qrrt_yy;
|
opus_val16 qrrt_xx, qrrt_yy;
|
||||||
|
@ -871,9 +868,12 @@ opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int3
|
||||||
opus_val16 short_alpha;
|
opus_val16 short_alpha;
|
||||||
|
|
||||||
frame_rate = Fs/frame_size;
|
frame_rate = Fs/frame_size;
|
||||||
short_alpha = Q15ONE - 25*Q15ONE/IMAX(50,frame_rate);
|
short_alpha = Q15ONE - MULT16_16(25, Q15ONE)/IMAX(50,frame_rate);
|
||||||
xx=xy=yy=0;
|
xx=xy=yy=0;
|
||||||
for (i=0;i<frame_size;i+=4)
|
/* Unroll by 4. The frame size is always a multiple of 4 *except* for
|
||||||
|
2.5 ms frames at 12 kHz. Since this setting is very rare (and very
|
||||||
|
stupid), we just discard the last two samples. */
|
||||||
|
for (i=0;i<frame_size-3;i+=4)
|
||||||
{
|
{
|
||||||
opus_val32 pxx=0;
|
opus_val32 pxx=0;
|
||||||
opus_val32 pxy=0;
|
opus_val32 pxy=0;
|
||||||
|
@ -912,6 +912,9 @@ opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int3
|
||||||
mem->YY = MAX32(0, mem->YY);
|
mem->YY = MAX32(0, mem->YY);
|
||||||
if (MAX32(mem->XX, mem->YY)>QCONST16(8e-4f, 18))
|
if (MAX32(mem->XX, mem->YY)>QCONST16(8e-4f, 18))
|
||||||
{
|
{
|
||||||
|
opus_val16 corr;
|
||||||
|
opus_val16 ldiff;
|
||||||
|
opus_val16 width;
|
||||||
sqrt_xx = celt_sqrt(mem->XX);
|
sqrt_xx = celt_sqrt(mem->XX);
|
||||||
sqrt_yy = celt_sqrt(mem->YY);
|
sqrt_yy = celt_sqrt(mem->YY);
|
||||||
qrrt_xx = celt_sqrt(sqrt_xx);
|
qrrt_xx = celt_sqrt(sqrt_xx);
|
||||||
|
@ -920,19 +923,15 @@ opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int3
|
||||||
mem->XY = MIN32(mem->XY, sqrt_xx*sqrt_yy);
|
mem->XY = MIN32(mem->XY, sqrt_xx*sqrt_yy);
|
||||||
corr = SHR32(frac_div32(mem->XY,EPSILON+MULT16_16(sqrt_xx,sqrt_yy)),16);
|
corr = SHR32(frac_div32(mem->XY,EPSILON+MULT16_16(sqrt_xx,sqrt_yy)),16);
|
||||||
/* Approximate loudness difference */
|
/* Approximate loudness difference */
|
||||||
ldiff = Q15ONE*ABS16(qrrt_xx-qrrt_yy)/(EPSILON+qrrt_xx+qrrt_yy);
|
ldiff = MULT16_16(Q15ONE, ABS16(qrrt_xx-qrrt_yy))/(EPSILON+qrrt_xx+qrrt_yy);
|
||||||
width = MULT16_16_Q15(celt_sqrt(QCONST32(1.f,30)-MULT16_16(corr,corr)), ldiff);
|
width = MULT16_16_Q15(celt_sqrt(QCONST32(1.f,30)-MULT16_16(corr,corr)), ldiff);
|
||||||
/* Smoothing over one second */
|
/* Smoothing over one second */
|
||||||
mem->smoothed_width += (width-mem->smoothed_width)/frame_rate;
|
mem->smoothed_width += (width-mem->smoothed_width)/frame_rate;
|
||||||
/* Peak follower */
|
/* Peak follower */
|
||||||
mem->max_follower = MAX16(mem->max_follower-QCONST16(.02f,15)/frame_rate, mem->smoothed_width);
|
mem->max_follower = MAX16(mem->max_follower-QCONST16(.02f,15)/frame_rate, mem->smoothed_width);
|
||||||
} else {
|
|
||||||
width = 0;
|
|
||||||
corr=Q15ONE;
|
|
||||||
ldiff=0;
|
|
||||||
}
|
}
|
||||||
/*printf("%f %f %f %f %f ", corr/(float)Q15ONE, ldiff/(float)Q15ONE, width/(float)Q15ONE, mem->smoothed_width/(float)Q15ONE, mem->max_follower/(float)Q15ONE);*/
|
/*printf("%f %f %f %f %f ", corr/(float)Q15ONE, ldiff/(float)Q15ONE, width/(float)Q15ONE, mem->smoothed_width/(float)Q15ONE, mem->max_follower/(float)Q15ONE);*/
|
||||||
return EXTRACT16(MIN32(Q15ONE,20*mem->max_follower));
|
return EXTRACT16(MIN32(Q15ONE, MULT16_16(20, mem->max_follower)));
|
||||||
}
|
}
|
||||||
|
|
||||||
opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||||
|
@ -1050,6 +1049,16 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
|
||||||
st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes);
|
st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes);
|
||||||
|
|
||||||
frame_rate = st->Fs/frame_size;
|
frame_rate = st->Fs/frame_size;
|
||||||
|
if (!st->use_vbr)
|
||||||
|
{
|
||||||
|
int cbrBytes;
|
||||||
|
/* Multiply by 3 to make sure the division is exact. */
|
||||||
|
int frame_rate3 = 3*st->Fs/frame_size;
|
||||||
|
/* We need to make sure that "int" values always fit in 16 bits. */
|
||||||
|
cbrBytes = IMIN( (3*st->bitrate_bps/8 + frame_rate3/2)/frame_rate3, max_data_bytes);
|
||||||
|
st->bitrate_bps = cbrBytes*(opus_int32)frame_rate3*8/3;
|
||||||
|
max_data_bytes = cbrBytes;
|
||||||
|
}
|
||||||
if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8
|
if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8
|
||||||
|| (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400)))
|
|| (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400)))
|
||||||
{
|
{
|
||||||
|
@ -1066,18 +1075,18 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
|
||||||
bw=OPUS_BANDWIDTH_WIDEBAND;
|
bw=OPUS_BANDWIDTH_WIDEBAND;
|
||||||
else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND)
|
else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND)
|
||||||
bw=OPUS_BANDWIDTH_NARROWBAND;
|
bw=OPUS_BANDWIDTH_NARROWBAND;
|
||||||
else if (bw<=OPUS_BANDWIDTH_SUPERWIDEBAND)
|
else if (tocmode==MODE_HYBRID&&bw<=OPUS_BANDWIDTH_SUPERWIDEBAND)
|
||||||
bw=OPUS_BANDWIDTH_SUPERWIDEBAND;
|
bw=OPUS_BANDWIDTH_SUPERWIDEBAND;
|
||||||
data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels);
|
data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels);
|
||||||
|
ret = 1;
|
||||||
|
if (!st->use_vbr)
|
||||||
|
{
|
||||||
|
ret = opus_packet_pad(data, ret, max_data_bytes);
|
||||||
|
if (ret == OPUS_OK)
|
||||||
|
ret = max_data_bytes;
|
||||||
|
}
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
return 1;
|
return ret;
|
||||||
}
|
|
||||||
if (!st->use_vbr)
|
|
||||||
{
|
|
||||||
int cbrBytes;
|
|
||||||
cbrBytes = IMIN( (st->bitrate_bps + 4*frame_rate)/(8*frame_rate) , max_data_bytes);
|
|
||||||
st->bitrate_bps = cbrBytes * (8*frame_rate);
|
|
||||||
max_data_bytes = cbrBytes;
|
|
||||||
}
|
}
|
||||||
max_rate = frame_rate*max_data_bytes*8;
|
max_rate = frame_rate*max_data_bytes*8;
|
||||||
|
|
||||||
|
@ -1513,7 +1522,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
|
||||||
celt_rate = total_bitRate - st->silk_mode.bitRate;
|
celt_rate = total_bitRate - st->silk_mode.bitRate;
|
||||||
HB_gain_ref = (curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND) ? 3000 : 3600;
|
HB_gain_ref = (curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND) ? 3000 : 3600;
|
||||||
HB_gain = SHL32((opus_val32)celt_rate, 9) / SHR32((opus_val32)celt_rate + st->stream_channels * HB_gain_ref, 6);
|
HB_gain = SHL32((opus_val32)celt_rate, 9) / SHR32((opus_val32)celt_rate + st->stream_channels * HB_gain_ref, 6);
|
||||||
HB_gain = HB_gain < Q15ONE*6/7 ? HB_gain + Q15ONE/7 : Q15ONE;
|
HB_gain = HB_gain < (opus_val32)Q15ONE*6/7 ? HB_gain + Q15ONE/7 : Q15ONE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* SILK gets all bits */
|
/* SILK gets all bits */
|
||||||
|
|
183
thirdparty/opus/opus_multistream_encoder.c
vendored
183
thirdparty/opus/opus_multistream_encoder.c
vendored
|
@ -70,13 +70,22 @@ typedef void (*opus_copy_channel_in_func)(
|
||||||
int frame_size
|
int frame_size
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MAPPING_TYPE_NONE,
|
||||||
|
MAPPING_TYPE_SURROUND
|
||||||
|
#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
|
||||||
|
, /* Do not include comma at end of enumerator list */
|
||||||
|
MAPPING_TYPE_AMBISONICS
|
||||||
|
#endif
|
||||||
|
} MappingType;
|
||||||
|
|
||||||
struct OpusMSEncoder {
|
struct OpusMSEncoder {
|
||||||
ChannelLayout layout;
|
ChannelLayout layout;
|
||||||
int arch;
|
int arch;
|
||||||
int lfe_stream;
|
int lfe_stream;
|
||||||
int application;
|
int application;
|
||||||
int variable_duration;
|
int variable_duration;
|
||||||
int surround;
|
MappingType mapping_type;
|
||||||
opus_int32 bitrate_bps;
|
opus_int32 bitrate_bps;
|
||||||
float subframe_mem[3];
|
float subframe_mem[3];
|
||||||
/* Encoder states go here */
|
/* Encoder states go here */
|
||||||
|
@ -242,6 +251,7 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
|
||||||
upsample = resampling_factor(rate);
|
upsample = resampling_factor(rate);
|
||||||
frame_size = len*upsample;
|
frame_size = len*upsample;
|
||||||
|
|
||||||
|
/* LM = log2(frame_size / 120) */
|
||||||
for (LM=0;LM<celt_mode->maxLM;LM++)
|
for (LM=0;LM<celt_mode->maxLM;LM++)
|
||||||
if (celt_mode->shortMdctSize<<LM==frame_size)
|
if (celt_mode->shortMdctSize<<LM==frame_size)
|
||||||
break;
|
break;
|
||||||
|
@ -398,6 +408,12 @@ opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_
|
||||||
{
|
{
|
||||||
nb_streams=channels;
|
nb_streams=channels;
|
||||||
nb_coupled_streams=0;
|
nb_coupled_streams=0;
|
||||||
|
#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
|
||||||
|
} else if (mapping_family==254)
|
||||||
|
{
|
||||||
|
nb_streams=channels;
|
||||||
|
nb_coupled_streams=0;
|
||||||
|
#endif
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
|
size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
|
||||||
|
@ -408,7 +424,6 @@ opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int opus_multistream_encoder_init_impl(
|
static int opus_multistream_encoder_init_impl(
|
||||||
OpusMSEncoder *st,
|
OpusMSEncoder *st,
|
||||||
opus_int32 Fs,
|
opus_int32 Fs,
|
||||||
|
@ -417,7 +432,7 @@ static int opus_multistream_encoder_init_impl(
|
||||||
int coupled_streams,
|
int coupled_streams,
|
||||||
const unsigned char *mapping,
|
const unsigned char *mapping,
|
||||||
int application,
|
int application,
|
||||||
int surround
|
MappingType mapping_type
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int coupled_size;
|
int coupled_size;
|
||||||
|
@ -434,7 +449,7 @@ static int opus_multistream_encoder_init_impl(
|
||||||
st->layout.nb_streams = streams;
|
st->layout.nb_streams = streams;
|
||||||
st->layout.nb_coupled_streams = coupled_streams;
|
st->layout.nb_coupled_streams = coupled_streams;
|
||||||
st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0;
|
st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0;
|
||||||
if (!surround)
|
if (mapping_type != MAPPING_TYPE_SURROUND)
|
||||||
st->lfe_stream = -1;
|
st->lfe_stream = -1;
|
||||||
st->bitrate_bps = OPUS_AUTO;
|
st->bitrate_bps = OPUS_AUTO;
|
||||||
st->application = application;
|
st->application = application;
|
||||||
|
@ -463,12 +478,12 @@ static int opus_multistream_encoder_init_impl(
|
||||||
if(ret!=OPUS_OK)return ret;
|
if(ret!=OPUS_OK)return ret;
|
||||||
ptr += align(mono_size);
|
ptr += align(mono_size);
|
||||||
}
|
}
|
||||||
if (surround)
|
if (mapping_type == MAPPING_TYPE_SURROUND)
|
||||||
{
|
{
|
||||||
OPUS_CLEAR(ms_get_preemph_mem(st), channels);
|
OPUS_CLEAR(ms_get_preemph_mem(st), channels);
|
||||||
OPUS_CLEAR(ms_get_window_mem(st), channels*120);
|
OPUS_CLEAR(ms_get_window_mem(st), channels*120);
|
||||||
}
|
}
|
||||||
st->surround = surround;
|
st->mapping_type = mapping_type;
|
||||||
return OPUS_OK;
|
return OPUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,7 +497,9 @@ int opus_multistream_encoder_init(
|
||||||
int application
|
int application
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return opus_multistream_encoder_init_impl(st, Fs, channels, streams, coupled_streams, mapping, application, 0);
|
return opus_multistream_encoder_init_impl(st, Fs, channels, streams,
|
||||||
|
coupled_streams, mapping,
|
||||||
|
application, MAPPING_TYPE_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int opus_multistream_surround_encoder_init(
|
int opus_multistream_surround_encoder_init(
|
||||||
|
@ -496,6 +513,8 @@ int opus_multistream_surround_encoder_init(
|
||||||
int application
|
int application
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
MappingType mapping_type;
|
||||||
|
|
||||||
if ((channels>255) || (channels<1))
|
if ((channels>255) || (channels<1))
|
||||||
return OPUS_BAD_ARG;
|
return OPUS_BAD_ARG;
|
||||||
st->lfe_stream = -1;
|
st->lfe_stream = -1;
|
||||||
|
@ -530,10 +549,32 @@ int opus_multistream_surround_encoder_init(
|
||||||
*coupled_streams=0;
|
*coupled_streams=0;
|
||||||
for(i=0;i<channels;i++)
|
for(i=0;i<channels;i++)
|
||||||
mapping[i] = i;
|
mapping[i] = i;
|
||||||
|
#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
|
||||||
|
} else if (mapping_family==254)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
*streams=channels;
|
||||||
|
*coupled_streams=0;
|
||||||
|
for(i=0;i<channels;i++)
|
||||||
|
mapping[i] = i;
|
||||||
|
#endif
|
||||||
} else
|
} else
|
||||||
return OPUS_UNIMPLEMENTED;
|
return OPUS_UNIMPLEMENTED;
|
||||||
return opus_multistream_encoder_init_impl(st, Fs, channels, *streams, *coupled_streams,
|
|
||||||
mapping, application, channels>2&&mapping_family==1);
|
if (channels>2 && mapping_family==1) {
|
||||||
|
mapping_type = MAPPING_TYPE_SURROUND;
|
||||||
|
#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
|
||||||
|
} else if (mapping_family==254)
|
||||||
|
{
|
||||||
|
mapping_type = MAPPING_TYPE_AMBISONICS;
|
||||||
|
#endif
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
mapping_type = MAPPING_TYPE_NONE;
|
||||||
|
}
|
||||||
|
return opus_multistream_encoder_init_impl(st, Fs, channels, *streams,
|
||||||
|
*coupled_streams, mapping,
|
||||||
|
application, mapping_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpusMSEncoder *opus_multistream_encoder_create(
|
OpusMSEncoder *opus_multistream_encoder_create(
|
||||||
|
@ -618,24 +659,19 @@ OpusMSEncoder *opus_multistream_surround_encoder_create(
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
static opus_int32 surround_rate_allocation(
|
static void surround_rate_allocation(
|
||||||
OpusMSEncoder *st,
|
OpusMSEncoder *st,
|
||||||
opus_int32 *rate,
|
opus_int32 *rate,
|
||||||
int frame_size
|
int frame_size,
|
||||||
|
opus_int32 Fs
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
opus_int32 channel_rate;
|
opus_int32 channel_rate;
|
||||||
opus_int32 Fs;
|
|
||||||
char *ptr;
|
|
||||||
int stream_offset;
|
int stream_offset;
|
||||||
int lfe_offset;
|
int lfe_offset;
|
||||||
int coupled_ratio; /* Q8 */
|
int coupled_ratio; /* Q8 */
|
||||||
int lfe_ratio; /* Q8 */
|
int lfe_ratio; /* Q8 */
|
||||||
opus_int32 rate_sum=0;
|
|
||||||
|
|
||||||
ptr = (char*)st + align(sizeof(OpusMSEncoder));
|
|
||||||
opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
|
|
||||||
|
|
||||||
if (st->bitrate_bps > st->layout.nb_channels*40000)
|
if (st->bitrate_bps > st->layout.nb_channels*40000)
|
||||||
stream_offset = 20000;
|
stream_offset = 20000;
|
||||||
|
@ -688,6 +724,88 @@ static opus_int32 surround_rate_allocation(
|
||||||
rate[i] = stream_offset+channel_rate;
|
rate[i] = stream_offset+channel_rate;
|
||||||
else
|
else
|
||||||
rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
|
rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
|
||||||
|
static void ambisonics_rate_allocation(
|
||||||
|
OpusMSEncoder *st,
|
||||||
|
opus_int32 *rate,
|
||||||
|
int frame_size,
|
||||||
|
opus_int32 Fs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int non_mono_rate;
|
||||||
|
int total_rate;
|
||||||
|
|
||||||
|
/* The mono channel gets (rate_ratio_num / rate_ratio_den) times as many bits
|
||||||
|
* as all other channels */
|
||||||
|
const int rate_ratio_num = 4;
|
||||||
|
const int rate_ratio_den = 3;
|
||||||
|
const int num_channels = st->layout.nb_streams;
|
||||||
|
|
||||||
|
if (st->bitrate_bps==OPUS_AUTO)
|
||||||
|
{
|
||||||
|
total_rate = num_channels * (20000 + st->layout.nb_streams*(Fs+60*Fs/frame_size));
|
||||||
|
} else if (st->bitrate_bps==OPUS_BITRATE_MAX)
|
||||||
|
{
|
||||||
|
total_rate = num_channels * 320000;
|
||||||
|
} else {
|
||||||
|
total_rate = st->bitrate_bps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Let y be the non-mono rate and let p, q be integers such that the mono
|
||||||
|
* channel rate is (p/q) * y.
|
||||||
|
* Also let T be the total bitrate to allocate. Then
|
||||||
|
* (n - 1) y + (p/q) y = T
|
||||||
|
* y = (T q) / (qn - q + p)
|
||||||
|
*/
|
||||||
|
non_mono_rate =
|
||||||
|
total_rate * rate_ratio_den
|
||||||
|
/ (rate_ratio_den*num_channels + rate_ratio_num - rate_ratio_den);
|
||||||
|
|
||||||
|
#ifndef FIXED_POINT
|
||||||
|
if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
|
||||||
|
{
|
||||||
|
opus_int32 bonus = 60*(Fs/frame_size-50);
|
||||||
|
non_mono_rate += bonus;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rate[0] = total_rate - (num_channels - 1) * non_mono_rate;
|
||||||
|
for (i=1;i<st->layout.nb_streams;i++)
|
||||||
|
{
|
||||||
|
rate[i] = non_mono_rate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* ENABLE_EXPERIMENTAL_AMBISONICS */
|
||||||
|
|
||||||
|
static opus_int32 rate_allocation(
|
||||||
|
OpusMSEncoder *st,
|
||||||
|
opus_int32 *rate,
|
||||||
|
int frame_size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
opus_int32 rate_sum=0;
|
||||||
|
opus_int32 Fs;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
ptr = (char*)st + align(sizeof(OpusMSEncoder));
|
||||||
|
opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
|
||||||
|
|
||||||
|
#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
|
||||||
|
if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
|
||||||
|
ambisonics_rate_allocation(st, rate, frame_size, Fs);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
surround_rate_allocation(st, rate, frame_size, Fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0;i<st->layout.nb_streams;i++)
|
||||||
|
{
|
||||||
rate[i] = IMAX(rate[i], 500);
|
rate[i] = IMAX(rate[i], 500);
|
||||||
rate_sum += rate[i];
|
rate_sum += rate[i];
|
||||||
}
|
}
|
||||||
|
@ -730,7 +848,7 @@ static int opus_multistream_encode_native
|
||||||
opus_int32 smallest_packet;
|
opus_int32 smallest_packet;
|
||||||
ALLOC_STACK;
|
ALLOC_STACK;
|
||||||
|
|
||||||
if (st->surround)
|
if (st->mapping_type == MAPPING_TYPE_SURROUND)
|
||||||
{
|
{
|
||||||
preemph_mem = ms_get_preemph_mem(st);
|
preemph_mem = ms_get_preemph_mem(st);
|
||||||
mem = ms_get_window_mem(st);
|
mem = ms_get_window_mem(st);
|
||||||
|
@ -784,13 +902,13 @@ static int opus_multistream_encode_native
|
||||||
mono_size = opus_encoder_get_size(1);
|
mono_size = opus_encoder_get_size(1);
|
||||||
|
|
||||||
ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);
|
ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);
|
||||||
if (st->surround)
|
if (st->mapping_type == MAPPING_TYPE_SURROUND)
|
||||||
{
|
{
|
||||||
surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in, st->arch);
|
surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in, st->arch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute bitrate allocation between streams (this could be a lot better) */
|
/* Compute bitrate allocation between streams (this could be a lot better) */
|
||||||
rate_sum = surround_rate_allocation(st, bitrates, frame_size);
|
rate_sum = rate_allocation(st, bitrates, frame_size);
|
||||||
|
|
||||||
if (!vbr)
|
if (!vbr)
|
||||||
{
|
{
|
||||||
|
@ -813,7 +931,7 @@ static int opus_multistream_encode_native
|
||||||
else
|
else
|
||||||
ptr += align(mono_size);
|
ptr += align(mono_size);
|
||||||
opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
|
opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
|
||||||
if (st->surround)
|
if (st->mapping_type == MAPPING_TYPE_SURROUND)
|
||||||
{
|
{
|
||||||
opus_int32 equiv_rate;
|
opus_int32 equiv_rate;
|
||||||
equiv_rate = st->bitrate_bps;
|
equiv_rate = st->bitrate_bps;
|
||||||
|
@ -834,6 +952,11 @@ static int opus_multistream_encode_native
|
||||||
opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
|
opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
|
||||||
|
else if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
|
||||||
|
opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = (char*)st + align(sizeof(OpusMSEncoder));
|
ptr = (char*)st + align(sizeof(OpusMSEncoder));
|
||||||
|
@ -845,6 +968,7 @@ static int opus_multistream_encode_native
|
||||||
int len;
|
int len;
|
||||||
int curr_max;
|
int curr_max;
|
||||||
int c1, c2;
|
int c1, c2;
|
||||||
|
int ret;
|
||||||
|
|
||||||
opus_repacketizer_init(&rp);
|
opus_repacketizer_init(&rp);
|
||||||
enc = (OpusEncoder*)ptr;
|
enc = (OpusEncoder*)ptr;
|
||||||
|
@ -859,7 +983,7 @@ static int opus_multistream_encode_native
|
||||||
(*copy_channel_in)(buf+1, 2,
|
(*copy_channel_in)(buf+1, 2,
|
||||||
pcm, st->layout.nb_channels, right, frame_size);
|
pcm, st->layout.nb_channels, right, frame_size);
|
||||||
ptr += align(coupled_size);
|
ptr += align(coupled_size);
|
||||||
if (st->surround)
|
if (st->mapping_type == MAPPING_TYPE_SURROUND)
|
||||||
{
|
{
|
||||||
for (i=0;i<21;i++)
|
for (i=0;i<21;i++)
|
||||||
{
|
{
|
||||||
|
@ -875,7 +999,7 @@ static int opus_multistream_encode_native
|
||||||
(*copy_channel_in)(buf, 1,
|
(*copy_channel_in)(buf, 1,
|
||||||
pcm, st->layout.nb_channels, chan, frame_size);
|
pcm, st->layout.nb_channels, chan, frame_size);
|
||||||
ptr += align(mono_size);
|
ptr += align(mono_size);
|
||||||
if (st->surround)
|
if (st->mapping_type == MAPPING_TYPE_SURROUND)
|
||||||
{
|
{
|
||||||
for (i=0;i<21;i++)
|
for (i=0;i<21;i++)
|
||||||
bandLogE[i] = bandSMR[21*chan+i];
|
bandLogE[i] = bandSMR[21*chan+i];
|
||||||
|
@ -883,7 +1007,7 @@ static int opus_multistream_encode_native
|
||||||
c1 = chan;
|
c1 = chan;
|
||||||
c2 = -1;
|
c2 = -1;
|
||||||
}
|
}
|
||||||
if (st->surround)
|
if (st->mapping_type == MAPPING_TYPE_SURROUND)
|
||||||
opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
|
opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
|
||||||
/* number of bytes left (+Toc) */
|
/* number of bytes left (+Toc) */
|
||||||
curr_max = max_data_bytes - tot_size;
|
curr_max = max_data_bytes - tot_size;
|
||||||
|
@ -904,7 +1028,14 @@ static int opus_multistream_encode_native
|
||||||
/* We need to use the repacketizer to add the self-delimiting lengths
|
/* We need to use the repacketizer to add the self-delimiting lengths
|
||||||
while taking into account the fact that the encoder can now return
|
while taking into account the fact that the encoder can now return
|
||||||
more than one frame at a time (e.g. 60 ms CELT-only) */
|
more than one frame at a time (e.g. 60 ms CELT-only) */
|
||||||
opus_repacketizer_cat(&rp, tmp_data, len);
|
ret = opus_repacketizer_cat(&rp, tmp_data, len);
|
||||||
|
/* If the opus_repacketizer_cat() fails, then something's seriously wrong
|
||||||
|
with the encoder. */
|
||||||
|
if (ret != OPUS_OK)
|
||||||
|
{
|
||||||
|
RESTORE_STACK;
|
||||||
|
return OPUS_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp),
|
len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp),
|
||||||
data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1);
|
data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1);
|
||||||
data += len;
|
data += len;
|
||||||
|
@ -1183,7 +1314,7 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
|
||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
st->subframe_mem[0] = st->subframe_mem[1] = st->subframe_mem[2] = 0;
|
st->subframe_mem[0] = st->subframe_mem[1] = st->subframe_mem[2] = 0;
|
||||||
if (st->surround)
|
if (st->mapping_type == MAPPING_TYPE_SURROUND)
|
||||||
{
|
{
|
||||||
OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
|
OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
|
||||||
OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120);
|
OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120);
|
||||||
|
|
4
thirdparty/opus/repacketizer.c
vendored
4
thirdparty/opus/repacketizer.c
vendored
|
@ -249,7 +249,9 @@ int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len)
|
||||||
opus_repacketizer_init(&rp);
|
opus_repacketizer_init(&rp);
|
||||||
/* Moving payload to the end of the packet so we can do in-place padding */
|
/* Moving payload to the end of the packet so we can do in-place padding */
|
||||||
OPUS_MOVE(data+new_len-len, data, len);
|
OPUS_MOVE(data+new_len-len, data, len);
|
||||||
opus_repacketizer_cat(&rp, data+new_len-len, len);
|
ret = opus_repacketizer_cat(&rp, data+new_len-len, len);
|
||||||
|
if (ret != OPUS_OK)
|
||||||
|
return ret;
|
||||||
ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, new_len, 0, 1);
|
ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, new_len, 0, 1);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
return OPUS_OK;
|
return OPUS_OK;
|
||||||
|
|
Loading…
Reference in a new issue