summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2017-07-16 03:01:41 -0400
committerJean-Marc Valin <jmvalin@jmvalin.ca>2017-07-17 14:02:55 -0400
commit2a4f49448f66f664f90edd220b8467d9b06938ab (patch)
treee793bef8838d8fea907fd9f37e922f64b7348a58
parent047c11b5bc5a59156616a1ea861a9979b4449339 (diff)
downloadopus-2a4f49448f66f664f90edd220b8467d9b06938ab.tar.gz
Better rate allocation for stereo SILK in hybrid mode
SILK was being allocated too few bits for stereo hybrid, often resulting in forced narrowing of the width. We now allocate more bits to SILK and reduce the threshold for narrowing. This improves quality enough that the bitrate threshold for switching to SILK can be increased to 44 kb/s.
-rw-r--r--silk/stereo_LR_to_MS.c2
-rw-r--r--src/opus_encoder.c16
2 files changed, 13 insertions, 5 deletions
diff --git a/silk/stereo_LR_to_MS.c b/silk/stereo_LR_to_MS.c
index dda0298d..c8226663 100644
--- a/silk/stereo_LR_to_MS.c
+++ b/silk/stereo_LR_to_MS.c
@@ -109,7 +109,7 @@ void silk_stereo_LR_to_MS(
if( total_rate_bps < 1 ) {
total_rate_bps = 1;
}
- min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 900 );
+ min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 600 );
silk_assert( min_mid_rate_bps < 32767 );
/* Default bitrate distribution: 8 parts for Mid and (5+3*frac) parts for Side. so: mid_rate = ( 8 / ( 13 + 3 * frac ) ) * total_ rate */
frac_3_Q16 = silk_MUL( 3, frac_Q16 );
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index cd37fcdf..3770fc64 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -154,7 +154,7 @@ static const opus_int32 stereo_music_threshold = 24000;
static const opus_int32 mode_thresholds[2][2] = {
/* voice */ /* music */
{ 64000, 16000}, /* mono */
- { 36000, 16000}, /* stereo */
+ { 44000, 16000}, /* stereo */
};
static const opus_int32 fec_thresholds[] = {
@@ -762,7 +762,7 @@ static int decide_fec(int useInBandFEC, int PacketLoss_perc, int last_fec, int m
return 0;
}
-static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms, int vbr, int fec) {
+static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms, int vbr, int fec, int channels) {
int entry;
int i;
int N;
@@ -779,6 +779,8 @@ static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms,
{32000, 22000, 22000, 28000, 28000},
{64000, 38000, 38000, 50000, 50000}
};
+ /* Do the allocation per-channel. */
+ rate /= channels;
entry = 1 + frame20ms + 2*fec;
N = sizeof(rate_table)/sizeof(rate_table[0]);
for (i=1;i<N;i++)
@@ -805,6 +807,10 @@ static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms,
}
if (bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND)
silk_rate += 300;
+ silk_rate *= channels;
+ /* The CELT layer saves a bit more than SILK for stereo, so we boost SILK. */
+ if (channels == 2 && rate >= 12000)
+ silk_rate += 1000;
return silk_rate;
}
@@ -1673,7 +1679,8 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if( st->mode == MODE_HYBRID ) {
/* Base rate for SILK */
st->silk_mode.bitRate = compute_silk_rate_for_hybrid(total_bitRate,
- curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded);
+ curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded,
+ st->stream_channels);
if (!st->energy_masking)
{
/* Increasingly attenuate high band when it gets allocated fewer bits */
@@ -1788,7 +1795,8 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
{
/* Compute SILK bitrate corresponding to the max total bits available */
opus_int32 maxBitRate = compute_silk_rate_for_hybrid(st->silk_mode.maxBits*st->Fs / frame_size,
- curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded);
+ curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded,
+ st->stream_channels);
st->silk_mode.maxBits = maxBitRate * frame_size / st->Fs;
}
}