Skip to content

Commit 30cfba3

Browse files
committed
Simplify bitrate<->bits conversion code
Using common functions and avoiding overflows
1 parent 285ef69 commit 30cfba3

File tree

4 files changed

+30
-25
lines changed

4 files changed

+30
-25
lines changed

celt/celt.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,15 @@ typedef struct {
147147
#define CELT_SET_SILK_INFO_REQUEST 10028
148148
#define CELT_SET_SILK_INFO(x) CELT_SET_SILK_INFO_REQUEST, __celt_check_silkinfo_ptr(x)
149149

150+
151+
static OPUS_INLINE opus_int32 bits_to_bitrate(opus_int32 bits, opus_int32 Fs, opus_int32 frame_size) {
152+
return bits*(6*Fs/frame_size)/6;
153+
}
154+
155+
static OPUS_INLINE opus_int32 bitrate_to_bits(opus_int32 bitrate, opus_int32 Fs, opus_int32 frame_size) {
156+
return bitrate*6/(6*Fs/frame_size);
157+
}
158+
150159
/* Encoder stuff */
151160

152161
int celt_encoder_get_size(int channels);

celt/celt_encoder.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,8 +1891,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
18911891

18921892
if (st->vbr && st->bitrate!=OPUS_BITRATE_MAX)
18931893
{
1894-
opus_int32 den=mode->Fs>>(BITRES+2);
1895-
vbr_rate=((st->bitrate*(frame_size>>2))+(den>>1))/den;
1894+
vbr_rate = bitrate_to_bits(st->bitrate, mode->Fs, frame_size)<<BITRES;
18961895
#if defined(CUSTOM_MODES) || defined(ENABLE_OPUS_CUSTOM_API)
18971896
if (st->signalling)
18981897
vbr_rate -= 8<<BITRES;
@@ -2525,7 +2524,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
25252524
if (st->enable_qext) {
25262525
int new_compressedBytes;
25272526
/* Don't give any bits for the first 80 kb/s per channel. Then 80% of the excess. */
2528-
opus_int32 offset = C*80000*frame_size/mode->Fs/8;
2527+
opus_int32 offset = bitrate_to_bits(C*80000, mode->Fs, frame_size)/8;
25292528
qext_bytes = IMAX(nbCompressedBytes-1275, IMAX(0, (nbCompressedBytes-offset)*4/5));
25302529
if (qext_bytes > 20) {
25312530
opus_int32 target;

src/opus_encoder.c

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -702,13 +702,13 @@ static opus_int32 compute_dred_bitrate(OpusEncoder *st, opus_int32 bitrate_bps,
702702
qmax = 15;
703703
target_dred_bitrate = IMAX(0, (int)(dred_frac*(bitrate_bps-bitrate_offset)));
704704
if (st->dred_duration > 0) {
705-
opus_int32 target_bits = target_dred_bitrate*frame_size/st->Fs;
705+
opus_int32 target_bits = bitrate_to_bits(target_dred_bitrate, st->Fs, frame_size);
706706
max_dred_bits = estimate_dred_bitrate(q0, dQ, qmax, st->dred_duration, target_bits, &target_chunks);
707707
} else {
708708
max_dred_bits = 0;
709709
target_chunks=0;
710710
}
711-
dred_bitrate = IMIN(target_dred_bitrate, max_dred_bits*st->Fs/frame_size);
711+
dred_bitrate = IMIN(target_dred_bitrate, bits_to_bitrate(max_dred_bits, st->Fs, frame_size));
712712
/* If we can't afford enough bits, don't bother with DRED at all. */
713713
if (target_chunks < 2)
714714
dred_bitrate = 0;
@@ -724,7 +724,7 @@ static opus_int32 user_bitrate_to_bitrate(OpusEncoder *st, int frame_size, int m
724724
{
725725
opus_int32 max_bitrate, user_bitrate;
726726
if(!frame_size)frame_size=st->Fs/400;
727-
max_bitrate = max_data_bytes*8*(6*st->Fs/frame_size)/6;
727+
max_bitrate = bits_to_bitrate(max_data_bytes*8, st->Fs, frame_size);
728728
if (st->user_bitrate_bps==OPUS_AUTO)
729729
user_bitrate = 60*st->Fs/frame_size + st->Fs*st->channels;
730730
else if (st->user_bitrate_bps==OPUS_BITRATE_MAX)
@@ -1304,11 +1304,8 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_res *pcm, int frame_si
13041304
frame_rate = st->Fs/frame_size;
13051305
if (!st->use_vbr)
13061306
{
1307-
/* Multiply by 12 to make sure the division is exact. */
1308-
int frame_rate12 = 12*st->Fs/frame_size;
1309-
/* We need to make sure that "int" values always fit in 16 bits. */
1310-
cbr_bytes = IMIN( (12*st->bitrate_bps/8 + frame_rate12/2)/frame_rate12, max_data_bytes);
1311-
st->bitrate_bps = cbr_bytes*(opus_int32)frame_rate12*8/12;
1307+
cbr_bytes = IMIN((bitrate_to_bits(st->bitrate_bps, st->Fs, frame_size)+4)/8, max_data_bytes);
1308+
st->bitrate_bps = bits_to_bitrate(cbr_bytes*8, st->Fs, frame_size);
13121309
/* Make sure we provide at least one byte to avoid failing. */
13131310
max_data_bytes = IMAX(1, cbr_bytes);
13141311
}
@@ -1384,7 +1381,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_res *pcm, int frame_si
13841381
RESTORE_STACK;
13851382
return ret;
13861383
}
1387-
max_rate = frame_rate*max_data_bytes*8;
1384+
max_rate = bits_to_bitrate(max_data_bytes*8, st->Fs, frame_size);
13881385

13891386
/* Equivalent 20-ms rate for mode/channel/bandwidth decisions */
13901387
equiv_rate = compute_equiv_rate(st->bitrate_bps, st->channels, st->Fs/frame_size,
@@ -1503,7 +1500,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_res *pcm, int frame_si
15031500
#endif
15041501

15051502
/* If max_data_bytes represents less than 6 kb/s, switch to CELT-only mode */
1506-
if (max_data_bytes < (frame_rate > 50 ? 9000 : 6000)*frame_size / (st->Fs * 8))
1503+
if (max_data_bytes < bitrate_to_bits(frame_rate > 50 ? 9000 : 6000, st->Fs, frame_size)/8)
15071504
st->mode = MODE_CELT_ONLY;
15081505
} else {
15091506
st->mode = st->user_forced_mode;
@@ -1762,10 +1759,10 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_res *pcm, int frame_si
17621759
frame_to_celt = to_celt && i==nb_frames-1;
17631760
frame_redundancy = redundancy && (frame_to_celt || (!to_celt && i==0));
17641761

1765-
curr_max = IMIN(3*st->bitrate_bps/(3*8*st->Fs/enc_frame_size), max_len_sum/nb_frames);
1762+
curr_max = IMIN(bitrate_to_bits(st->bitrate_bps, st->Fs, enc_frame_size)/8, max_len_sum/nb_frames);
17661763
#ifdef ENABLE_DRED
1767-
curr_max = IMIN(curr_max, (max_len_sum-3*dred_bitrate_bps/(3*8*st->Fs/frame_size))/nb_frames);
1768-
if (first_frame) curr_max += 3*dred_bitrate_bps/(3*8*st->Fs/frame_size);
1764+
curr_max = IMIN(curr_max, (max_len_sum-bitrate_to_bits(dred_bitrate_bps, st->Fs, frame_size)/8)/nb_frames);
1765+
if (first_frame) curr_max += bitrate_to_bits(dred_bitrate_bps, st->Fs, frame_size)/8;
17691766
#endif
17701767
curr_max = IMIN(max_len_sum-tot_size, curr_max);
17711768
#ifndef DISABLE_FLOAT_API
@@ -1847,7 +1844,7 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_res *pcm,
18471844
int max_data_bytes;
18481845
opus_int32 nBytes;
18491846
ec_enc enc;
1850-
int bytes_target;
1847+
int bits_target;
18511848
int start_band = 0;
18521849
int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */
18531850
int nb_compr_bytes;
@@ -1932,7 +1929,7 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_res *pcm,
19321929
}
19331930

19341931
/* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */
1935-
bytes_target = IMIN(max_data_bytes-redundancy_bytes, (st->bitrate_bps/8) * frame_size / st->Fs) - 1;
1932+
bits_target = IMIN(8*(max_data_bytes-redundancy_bytes), bitrate_to_bits(st->bitrate_bps, st->Fs, frame_size)) - 8;
19361933

19371934
data += 1;
19381935

@@ -2023,7 +2020,7 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_res *pcm,
20232020
const opus_res *pcm_silk;
20242021

20252022
/* Distribute bits between SILK and CELT */
2026-
total_bitRate = 8 * bytes_target * frame_rate;
2023+
total_bitRate = bits_to_bitrate(bits_target, st->Fs, frame_size);
20272024
if( st->mode == MODE_HYBRID ) {
20282025
/* Base rate for SILK */
20292026
st->silk_mode.bitRate = compute_silk_rate_for_hybrid(total_bitRate,
@@ -2103,7 +2100,7 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_res *pcm,
21032100
st->silk_mode.maxInternalSampleRate = 16000;
21042101
if (st->mode == MODE_SILK_ONLY)
21052102
{
2106-
opus_int32 effective_max_rate = frame_rate*max_data_bytes*8;
2103+
opus_int32 effective_max_rate = bits_to_bitrate(max_data_bytes*8, st->Fs, frame_size);
21072104
if (frame_rate > 50)
21082105
effective_max_rate = effective_max_rate*2/3;
21092106
if (effective_max_rate < 8000)
@@ -2159,7 +2156,7 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_res *pcm,
21592156
opus_int32 maxBitRate = compute_silk_rate_for_hybrid(st->silk_mode.maxBits*st->Fs / frame_size,
21602157
curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded,
21612158
st->stream_channels);
2162-
st->silk_mode.maxBits = maxBitRate * frame_size / st->Fs;
2159+
st->silk_mode.maxBits = bitrate_to_bits(maxBitRate, st->Fs, frame_size);
21632160
}
21642161
}
21652162

@@ -2377,7 +2374,7 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_res *pcm,
23772374
if (st->dred_duration > 0)
23782375
{
23792376
int max_celt_bytes;
2380-
opus_int32 dred_bytes = dred_bitrate_bps/(frame_rate*8);
2377+
opus_int32 dred_bytes = bitrate_to_bits(dred_bitrate_bps, st->Fs, frame_size)/8;
23812378
/* Allow CELT to steal up to 25% of the remaining bits. */
23822379
max_celt_bytes = nb_compr_bytes - dred_bytes*3/4;
23832380
/* But try to give CELT at least 5 bytes to prevent a mismatch with

src/opus_multistream_encoder.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -914,11 +914,11 @@ int opus_multistream_encode_native
914914
{
915915
if (st->bitrate_bps == OPUS_AUTO)
916916
{
917-
max_data_bytes = IMIN(max_data_bytes, 3*rate_sum/(3*8*Fs/frame_size));
917+
max_data_bytes = IMIN(max_data_bytes, (bitrate_to_bits(rate_sum, Fs, frame_size)+4)/8);
918918
} else if (st->bitrate_bps != OPUS_BITRATE_MAX)
919919
{
920920
max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet,
921-
3*st->bitrate_bps/(3*8*Fs/frame_size)));
921+
(bitrate_to_bits(st->bitrate_bps, Fs, frame_size)+4)/8));
922922
}
923923
}
924924
ptr = (char*)st + align(sizeof(OpusMSEncoder));
@@ -1018,7 +1018,7 @@ int opus_multistream_encode_native
10181018
/* Repacketizer will add one or two bytes for self-delimited frames */
10191019
if (s != st->layout.nb_streams-1) curr_max -= curr_max>253 ? 2 : 1;
10201020
if (!vbr && s == st->layout.nb_streams-1)
1021-
opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size)));
1021+
opus_encoder_ctl(enc, OPUS_SET_BITRATE(bits_to_bitrate(curr_max*8, Fs, frame_size)));
10221022
len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth,
10231023
pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api);
10241024
if (len<0)

0 commit comments

Comments
 (0)