Surround encoder can now produce hard CBR streams again.
authorJean-Marc Valin <jmvalin@jmvalin.ca>
Mon, 14 Oct 2013 19:01:36 +0000 (15:01 -0400)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Mon, 14 Oct 2013 19:01:36 +0000 (15:01 -0400)
Even when using SILK/hybrid.

src/opus_encoder.c
src/opus_multistream_encoder.c
src/opus_private.h

index f6f0ce5..bdacb6b 100644 (file)
@@ -244,7 +244,7 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat
     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;
index 900c4f4..90597a9 100644 (file)
@@ -686,7 +686,7 @@ static int opus_multistream_encode_native
    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 @@ static int opus_multistream_encode_native
 
    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 @@ static int opus_multistream_encode_native
    /* 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 @@ static int opus_multistream_encode_native
          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;
    }
index de6f918..042b641 100644 (file)
@@ -119,4 +119,6 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
 
 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 */