shithub: opus

Download patch

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 */