Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
godot
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
community
godot
Commits
9845bdde
Commit
9845bdde
authored
Jan 05, 2017
by
Rémi Verschelde
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
opus: Update to upstream libopus 1.1.3
parent
2ca0337f
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
238 additions
and
77 deletions
+238
-77
README.md
thirdparty/README.md
+2
-2
COPYING
thirdparty/opus/COPYING
+28
-12
analysis.c
thirdparty/opus/analysis.c
+5
-8
opus.c
thirdparty/opus/opus.c
+7
-1
opus.h
thirdparty/opus/opus/opus.h
+1
-1
opus_defines.h
thirdparty/opus/opus/opus_defines.h
+1
-1
opus_multistream.h
thirdparty/opus/opus/opus_multistream.h
+4
-4
opus_encoder.c
thirdparty/opus/opus_encoder.c
+30
-21
opus_multistream_encoder.c
thirdparty/opus/opus_multistream_encoder.c
+157
-26
repacketizer.c
thirdparty/opus/repacketizer.c
+3
-1
No files found.
thirdparty/README.md
View file @
9845bdde
...
...
@@ -141,7 +141,7 @@ changes are marked with `// -- GODOT --` comments.
## openssl
-
Upstream: https://www.openssl.org
-
Version: 1.
2.0
h
-
Version: 1.
0.2
h
-
License: OpenSSL license / BSD-like
Files extracted from the upstream source:
...
...
@@ -152,7 +152,7 @@ TODO.
## opus
-
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
Files extracted from upstream source:
...
...
thirdparty/opus/COPYING
View file @
9845bdde
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
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
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.Org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
- Neither the name of Internet Society, IETF or IETF Trust, nor the
names of specific contributors, may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
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/
thirdparty/opus/analysis.c
View file @
9845bdde
...
...
@@ -540,17 +540,14 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
/* Instantaneous probability of speech and music, with beta pre-applied. */
float
speech0
;
float
music0
;
float
p
,
q
;
/* One transition every 3 minutes of active audio */
tau
=
.
00005
f
*
frame_probs
[
1
];
beta
=
.
05
f
;
if
(
1
)
{
/* Adapt beta based on how "unexpected" the new prob is */
float
p
,
q
;
p
=
MAX16
(.
05
f
,
MIN16
(.
95
f
,
frame_probs
[
0
]));
q
=
MAX16
(.
05
f
,
MIN16
(.
95
f
,
tonal
->
music_prob
));
beta
=
.
01
f
+
.
05
f
*
ABS16
(
p
-
q
)
/
(
p
*
(
1
-
q
)
+
q
*
(
1
-
p
));
}
/* Adapt beta based on how "unexpected" the new prob is */
p
=
MAX16
(.
05
f
,
MIN16
(.
95
f
,
frame_probs
[
0
]));
q
=
MAX16
(.
05
f
,
MIN16
(.
95
f
,
tonal
->
music_prob
));
beta
=
.
01
f
+
.
05
f
*
ABS16
(
p
-
q
)
/
(
p
*
(
1
-
q
)
+
q
*
(
1
-
p
));
/* p0 and p1 are the probabilities of speech and music at this frame
using only information from previous frame and applying the
state transition model */
...
...
thirdparty/opus/opus.c
View file @
9845bdde
...
...
@@ -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 */
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
)
a
=
-
a
;
/* Apply soft clipping */
...
...
@@ -201,8 +205,10 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
opus_int32
pad
=
0
;
const
unsigned
char
*
data0
=
data
;
if
(
size
==
NULL
)
if
(
size
==
NULL
||
len
<
0
)
return
OPUS_BAD_ARG
;
if
(
len
==
0
)
return
OPUS_INVALID_PACKET
;
framesize
=
opus_packet_get_samples_per_frame
(
data
,
48000
);
...
...
thirdparty/opus/opus/opus.h
View file @
9845bdde
...
...
@@ -142,7 +142,7 @@ extern "C" {
*
* 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
* 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
*
...
...
thirdparty/opus/opus/opus_defines.h
View file @
9845bdde
...
...
@@ -65,7 +65,7 @@ extern "C" {
#ifndef OPUS_EXPORT
# if defined(WIN32)
# if
def OPUS_BUILD
# if
defined(OPUS_BUILD) && defined(DLL_EXPORT)
# define OPUS_EXPORT __declspec(dllexport)
# else
# define OPUS_EXPORT
...
...
thirdparty/opus/opus/opus_multistream.h
View file @
9845bdde
...
...
@@ -110,10 +110,10 @@ extern "C" {
* packets produced by the encoder. Some basic information, such as packet
* duration, can be computed without any special negotiation.
*
* The format for multistream Opus packets is defined in
the
* <a href="https://tools.ietf.org/html/
draft-ietf-codec-oggopus">Ogg
*
encapsulation specification</a> and is based on the self-delimited Opus
*
framing described in Appendix B of
<a href="https://tools.ietf.org/html/rfc6716">RFC 6716</a>.
* The format for multistream Opus packets is defined in
* <a href="https://tools.ietf.org/html/
rfc7845">RFC 7845</a>
*
and is based on the self-delimited Opus framing described in Appendix B of
* <a href="https://tools.ietf.org/html/rfc6716">RFC 6716</a>.
* Normal Opus packets are just a degenerate case of multistream Opus packets,
* and can be encoded or decoded with the multistream API by setting
* <code>streams</code> to <code>1</code> when initializing the encoder or
...
...
thirdparty/opus/opus_encoder.c
View file @
9845bdde
...
...
@@ -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
corr
;
opus_val16
ldiff
;
opus_val16
width
;
opus_val32
xx
,
xy
,
yy
;
opus_val16
sqrt_xx
,
sqrt_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
;
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
;
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
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
);
if
(
MAX32
(
mem
->
XX
,
mem
->
YY
)
>
QCONST16
(
8e-4
f
,
18
))
{
opus_val16
corr
;
opus_val16
ldiff
;
opus_val16
width
;
sqrt_xx
=
celt_sqrt
(
mem
->
XX
);
sqrt_yy
=
celt_sqrt
(
mem
->
YY
);
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
);
corr
=
SHR32
(
frac_div32
(
mem
->
XY
,
EPSILON
+
MULT16_16
(
sqrt_xx
,
sqrt_yy
)),
16
);
/* 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
);
/* Smoothing over one second */
mem
->
smoothed_width
+=
(
width
-
mem
->
smoothed_width
)
/
frame_rate
;
/* Peak follower */
mem
->
max_follower
=
MAX16
(
mem
->
max_follower
-
QCONST16
(.
02
f
,
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);*/
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
,
...
...
@@ -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
);
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
||
(
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
;
else
if
(
tocmode
==
MODE_CELT_ONLY
&&
bw
==
OPUS_BANDWIDTH_MEDIUMBAND
)
bw
=
OPUS_BANDWIDTH_NARROWBAND
;
else
if
(
bw
<=
OPUS_BANDWIDTH_SUPERWIDEBAND
)
else
if
(
tocmode
==
MODE_HYBRID
&&
bw
<=
OPUS_BANDWIDTH_SUPERWIDEBAND
)
bw
=
OPUS_BANDWIDTH_SUPERWIDEBAND
;
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
;
return
1
;
}
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
;
return
ret
;
}
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
;
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
=
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
{
/* SILK gets all bits */
...
...
thirdparty/opus/opus_multistream_encoder.c
View file @
9845bdde
...
...
@@ -70,13 +70,22 @@ typedef void (*opus_copy_channel_in_func)(
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
{
ChannelLayout
layout
;
int
arch
;
int
lfe_stream
;
int
application
;
int
variable_duration
;
int
surround
;
MappingType
mapping_type
;
opus_int32
bitrate_bps
;
float
subframe_mem
[
3
];
/* 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
);
frame_size
=
len
*
upsample
;
/* LM = log2(frame_size / 120) */
for
(
LM
=
0
;
LM
<
celt_mode
->
maxLM
;
LM
++
)
if
(
celt_mode
->
shortMdctSize
<<
LM
==
frame_size
)
break
;
...
...
@@ -398,6 +408,12 @@ opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_
{
nb_streams
=
channels
;
nb_coupled_streams
=
0
;
#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
}
else
if
(
mapping_family
==
254
)
{
nb_streams
=
channels
;
nb_coupled_streams
=
0
;
#endif
}
else
return
0
;
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
;
}
static
int
opus_multistream_encoder_init_impl
(
OpusMSEncoder
*
st
,
opus_int32
Fs
,
...
...
@@ -417,7 +432,7 @@ static int opus_multistream_encoder_init_impl(
int
coupled_streams
,
const
unsigned
char
*
mapping
,
int
application
,
int
surround
MappingType
mapping_type
)
{
int
coupled_size
;
...
...
@@ -434,7 +449,7 @@ static int opus_multistream_encoder_init_impl(
st
->
layout
.
nb_streams
=
streams
;
st
->
layout
.
nb_coupled_streams
=
coupled_streams
;
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
->
bitrate_bps
=
OPUS_AUTO
;
st
->
application
=
application
;
...
...
@@ -463,12 +478,12 @@ static int opus_multistream_encoder_init_impl(
if
(
ret
!=
OPUS_OK
)
return
ret
;
ptr
+=
align
(
mono_size
);
}
if
(
surround
)
if
(
mapping_type
==
MAPPING_TYPE_SURROUND
)
{
OPUS_CLEAR
(
ms_get_preemph_mem
(
st
),
channels
);
OPUS_CLEAR
(
ms_get_window_mem
(
st
),
channels
*
120
);
}
st
->
surround
=
surround
;
st
->
mapping_type
=
mapping_type
;
return
OPUS_OK
;
}
...
...
@@ -482,7 +497,9 @@ int opus_multistream_encoder_init(
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
(
...
...
@@ -496,6 +513,8 @@ int opus_multistream_surround_encoder_init(
int
application
)
{
MappingType
mapping_type
;
if
((
channels
>
255
)
||
(
channels
<
1
))
return
OPUS_BAD_ARG
;
st
->
lfe_stream
=
-
1
;
...
...
@@ -530,10 +549,32 @@ int opus_multistream_surround_encoder_init(
*
coupled_streams
=
0
;
for
(
i
=
0
;
i
<
channels
;
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
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
(
...
...
@@ -618,24 +659,19 @@ OpusMSEncoder *opus_multistream_surround_encoder_create(
return
st
;
}
static
opus_int32
surround_rate_allocation
(
static
void
surround_rate_allocation
(
OpusMSEncoder
*
st
,
opus_int32
*
rate
,
int
frame_size
int
frame_size
,
opus_int32
Fs
)
{
int
i
;
opus_int32
channel_rate
;
opus_int32
Fs
;
char
*
ptr
;
int
stream_offset
;
int
lfe_offset
;
int
coupled_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
)
stream_offset
=
20000
;
...
...
@@ -688,6 +724,88 @@ static opus_int32 surround_rate_allocation(
rate
[
i
]
=
stream_offset
+
channel_rate
;
else
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_sum
+=
rate
[
i
];
}
...
...
@@ -730,7 +848,7 @@ static int opus_multistream_encode_native
opus_int32
smallest_packet
;
ALLOC_STACK
;
if
(
st
->
surround
)
if
(
st
->
mapping_type
==
MAPPING_TYPE_SURROUND
)
{
preemph_mem
=
ms_get_preemph_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
);
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
);
}
/* 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
)
{
...
...
@@ -813,7 +931,7 @@ static int opus_multistream_encode_native
else
ptr
+=
align
(
mono_size
);
opus_encoder_ctl
(
enc
,
OPUS_SET_BITRATE
(
bitrates
[
s
]));
if
(
st
->
surround
)
if
(
st
->
mapping_type
==
MAPPING_TYPE_SURROUND
)
{
opus_int32
equiv_rate
;
equiv_rate
=
st
->
bitrate_bps
;
...
...
@@ -834,6 +952,11 @@ static int opus_multistream_encode_native
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
));
...
...
@@ -845,6 +968,7 @@ static int opus_multistream_encode_native
int
len
;
int
curr_max
;
int
c1
,
c2
;
int
ret
;
opus_repacketizer_init
(
&
rp
);
enc
=
(
OpusEncoder
*
)
ptr
;
...
...
@@ -859,7 +983,7 @@ static int opus_multistream_encode_native
(
*
copy_channel_in
)(
buf
+
1
,
2
,
pcm
,
st
->
layout
.
nb_channels
,
right
,
frame_size
);
ptr
+=
align
(
coupled_size
);
if
(
st
->
surround
)
if
(
st
->
mapping_type
==
MAPPING_TYPE_SURROUND
)
{
for
(
i
=
0
;
i
<
21
;
i
++
)
{
...
...
@@ -875,7 +999,7 @@ static int opus_multistream_encode_native
(
*
copy_channel_in
)(
buf
,
1
,
pcm
,
st
->
layout
.
nb_channels
,
chan
,
frame_size
);
ptr
+=
align
(
mono_size
);
if
(
st
->
surround
)
if
(
st
->
mapping_type
==
MAPPING_TYPE_SURROUND
)
{
for
(
i
=
0
;
i
<
21
;
i
++
)
bandLogE
[
i
]
=
bandSMR
[
21
*
chan
+
i
];
...
...
@@ -883,7 +1007,7 @@ static int opus_multistream_encode_native
c1
=
chan
;
c2
=
-
1
;
}
if
(
st
->
surround
)
if
(
st
->
mapping_type
==
MAPPING_TYPE_SURROUND
)
opus_encoder_ctl
(
enc
,
OPUS_SET_ENERGY_MASK
(
bandLogE
));
/* number of bytes left (+Toc) */
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
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) */
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
),
data
,
max_data_bytes
-
tot_size
,
s
!=
st
->
layout
.
nb_streams
-
1
,
!
vbr
&&
s
==
st
->
layout
.
nb_streams
-
1
);
data
+=
len
;
...
...
@@ -1183,7 +1314,7 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
{
int
s
;
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_window_mem
(
st
),
st
->
layout
.
nb_channels
*
120
);
...
...
thirdparty/opus/repacketizer.c
View file @
9845bdde
...
...
@@ -249,7 +249,9 @@ int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len)
opus_repacketizer_init
(
&
rp
);
/* Moving payload to the end of the packet so we can do in-place padding */
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
);
if
(
ret
>
0
)
return
OPUS_OK
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment