aboutsummaryrefslogtreecommitdiff
path: root/src/opus_multistream_encoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/opus_multistream_encoder.c')
-rw-r--r--src/opus_multistream_encoder.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/src/opus_multistream_encoder.c b/src/opus_multistream_encoder.c
index c5fb3669..c6204185 100644
--- a/src/opus_multistream_encoder.c
+++ b/src/opus_multistream_encoder.c
@@ -36,8 +36,10 @@
#include <stdarg.h>
#include "float_cast.h"
#include "os_support.h"
+#include "analysis.h"
struct OpusMSEncoder {
+ TonalityAnalysisState analysis;
ChannelLayout layout;
int variable_duration;
opus_int32 bitrate_bps;
@@ -105,6 +107,7 @@ int opus_multistream_encoder_init(
st->layout.nb_coupled_streams = coupled_streams;
st->bitrate_bps = OPUS_AUTO;
+ st->variable_duration = OPUS_FRAMESIZE_ARG;
for (i=0;i<st->layout.nb_channels;i++)
st->layout.mapping[i] = mapping[i];
if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
@@ -187,6 +190,7 @@ static int opus_multistream_encode_native
int lsb_depth
#ifndef FIXED_POINT
, downmix_func downmix
+ , const void *pcm_analysis
#endif
)
{
@@ -202,10 +206,15 @@ static int opus_multistream_encode_native
int orig_frame_size;
int coded_channels;
opus_int32 channel_rate;
+ opus_int32 complexity;
+ AnalysisInfo analysis_info;
+ const CELTMode *celt_mode;
ALLOC_STACK;
ptr = (char*)st + align(sizeof(OpusMSEncoder));
opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
+ opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_COMPLEXITY(&complexity));
+ opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
if (400*frame_size < Fs)
{
@@ -213,24 +222,24 @@ static int opus_multistream_encode_native
return OPUS_BAD_ARG;
}
orig_frame_size = IMIN(frame_size,Fs/50);
- if (st->variable_duration)
+#ifndef FIXED_POINT
+ analysis_info.valid = 0;
+ if (complexity >= 7 && Fs==48000)
{
- int LM = 3;
- int channels;
opus_int32 delay_compensation;
+ int channels;
channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
delay_compensation -= Fs/400;
-#ifndef FIXED_POINT
- LM = optimize_framesize(pcm, frame_size, channels, Fs, st->bitrate_bps,
- 0.f, st->subframe_mem, delay_compensation, downmix);
+
+ frame_size = run_analysis(&st->analysis, celt_mode, pcm, pcm_analysis,
+ frame_size, st->variable_duration, channels, Fs, st->bitrate_bps, delay_compensation, lsb_depth, downmix, &analysis_info);
+ } else
#endif
- while ((Fs/400<<LM)>frame_size)
- LM--;
- frame_size = (Fs/400<<LM);
+ {
+ frame_size = frame_size_select(frame_size, st->variable_duration, 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 &&
@@ -262,10 +271,10 @@ static int opus_multistream_encode_native
channel_rate = st->bitrate_bps/coded_channels;
}
#ifndef FIXED_POINT
- if (st->variable_duration && orig_frame_size != frame_size)
+ if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
{
opus_int32 bonus;
- bonus = 60*(48000/frame_size-48000/orig_frame_size);
+ bonus = 60*(Fs/frame_size-50);
channel_rate += bonus;
}
#endif
@@ -313,7 +322,11 @@ static int opus_multistream_encode_native
/* Reserve three bytes for the last stream and four for the others */
curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1);
curr_max = IMIN(curr_max,MS_FRAME_TMP);
- len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth);
+ len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth
+#ifndef FIXED_POINT
+ , &analysis_info
+#endif
+ );
if (len<0)
{
RESTORE_STACK;
@@ -412,8 +425,9 @@ int opus_multistream_encode_float
opus_int32 max_data_bytes
)
{
+ int channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
return opus_multistream_encode_native(st, opus_copy_channel_in_float,
- pcm, frame_size, data, max_data_bytes, 24, downmix_float);
+ pcm, frame_size, data, max_data_bytes, 24, downmix_float, pcm+channels*st->analysis.analysis_offset);
}
int opus_multistream_encode(
@@ -424,8 +438,9 @@ int opus_multistream_encode(
opus_int32 max_data_bytes
)
{
+ int channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
return opus_multistream_encode_native(st, opus_copy_channel_in_short,
- pcm, frame_size, data, max_data_bytes, 16, downmix_int);
+ pcm, frame_size, data, max_data_bytes, 16, downmix_int, pcm+channels*st->analysis.analysis_offset);
}
#endif
@@ -562,7 +577,7 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
*value = (OpusEncoder*)ptr;
}
break;
- case OPUS_SET_EXPERT_VARIABLE_DURATION_REQUEST:
+ case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
if (value<0 || value>1)
@@ -570,7 +585,7 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
st->variable_duration = value;
}
break;
- case OPUS_GET_EXPERT_VARIABLE_DURATION_REQUEST:
+ case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
{
opus_int32 *value = va_arg(ap, opus_int32*);
*value = st->variable_duration;