ref: eab134c813725976181d6d66608d55597cea1e6f
parent: dabdb32ce6d33ab8998defd317e8e2813202b3d1
author: Jean-Marc Valin <[email protected]>
date: Mon Oct 14 11:01:36 EDT 2013
Surround encoder can now produce hard CBR streams again. Even when using SILK/hybrid.
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -244,7 +244,7 @@
return OPUS_OK;
}
-static int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len)
+int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len)
{
if (len == new_len)
return 0;
--- a/src/opus_multistream_encoder.c
+++ b/src/opus_multistream_encoder.c
@@ -686,7 +686,7 @@
VARDECL(opus_val16, bandSMR);
unsigned char tmp_data[MS_FRAME_TMP];
OpusRepacketizer rp;
- opus_int32 complexity;
+ opus_int32 vbr;
const CELTMode *celt_mode;
opus_int32 bitrates[256];
opus_val16 bandLogE[42];
@@ -703,7 +703,7 @@
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, OPUS_GET_VBR(&vbr));
opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
{
@@ -751,6 +751,9 @@
/* Compute bitrate allocation between streams (this could be a lot better) */
surround_rate_allocation(st, bitrates, frame_size);
+ if (!vbr)
+ max_data_bytes = IMIN(max_data_bytes, st->bitrate_bps/(8*Fs/frame_size));
+
ptr = (char*)st + align(sizeof(OpusMSEncoder));
for (s=0;s<st->layout.nb_streams;s++)
{
@@ -850,6 +853,15 @@
more than one frame at a time (e.g. 60 ms CELT-only) */
opus_repacketizer_cat(&rp, tmp_data, len);
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);
+ if (!vbr && s == st->layout.nb_streams-1 && curr_max > len)
+ {
+ if (pad_frame(data, len, curr_max))
+ {
+ RESTORE_STACK;
+ return OPUS_INTERNAL_ERROR;
+ }
+ len = curr_max;
+ }
data += len;
tot_size += len;
}
--- a/src/opus_private.h
+++ b/src/opus_private.h
@@ -119,4 +119,6 @@
opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen, int self_delimited);
+int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len);
+
#endif /* OPUS_PRIVATE_H */