Makes VBR rate variations less aggressive at low bit-rates and for CVBR
authorJean-Marc Valin <jmvalin@jmvalin.ca>
Fri, 27 Jul 2012 18:28:21 +0000 (14:28 -0400)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Fri, 27 Jul 2012 18:28:21 +0000 (14:28 -0400)
celt/celt.c

index 0dd22b6..a347743 100644 (file)
@@ -1565,16 +1565,16 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f
    {
       int effectiveRate;
 
-      /* Always use MS for 2.5 ms frames until we can do a better analysis */
-      if (LM!=0)
-         dual_stereo = stereo_analysis(st->mode, X, LM, N);
-
       static const opus_val16 intensity_thresholds[21]=
       /* 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19  20  off*/
         { 16,21,23,25,27,29,31,33,35,38,42,46,50,54,58,63,68,75,84,102,130};
       static const opus_val16 intensity_histeresis[21]=
         {  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 6,  8, 12};
 
+      /* Always use MS for 2.5 ms frames until we can do a better analysis */
+      if (LM!=0)
+         dual_stereo = stereo_analysis(st->mode, X, LM, N);
+
       /* Account for coarse energy */
       effectiveRate = (8*effectiveBytes - 80)>>LM;
 
@@ -1600,7 +1600,7 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f
      opus_val16 alpha;
      opus_int32 delta;
      /* The target rate in 8th bits per frame */
-     opus_int32 target, new_target;
+     opus_int32 target, base_target;
      opus_int32 min_allowed;
      int coded_bins;
      int coded_bands;
@@ -1614,6 +1614,8 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f
         The CELT allocator will just not be able to use more than that anyway. */
      nbCompressedBytes = IMIN(nbCompressedBytes,1275>>(3-LM));
      target = vbr_rate - ((40*C+20)<<BITRES);
+     base_target = target;
+
      if (st->constrained_vbr)
         target += (st->vbr_offset>>lm_diff);
 
@@ -1622,6 +1624,7 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f
      if (st->analysis.valid && st->analysis.activity<.4)
         target -= (coded_bins<<BITRES)*1*(.4-st->analysis.activity);
 #endif
+     /* Stereo savings */
      if (C==2)
      {
         int coded_stereo_bands;
@@ -1638,19 +1641,20 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f
      target += tot_boost;
      /* Compensates for the average transient boost */
      target = MULT16_32_Q15(QCONST16(0.96f,15),target);
-
-     new_target = SHL32(MULT16_32_Q15(tf_estimate, target),1);
+     /* Apply transient boost */
+     target = SHL32(MULT16_32_Q15(tf_estimate, target),1);
 
 #ifndef FIXED_POINT
+     /* Apply tonality boost */
      if (st->analysis.valid) {
         int tonal_target;
         float tonal;
         tonal = MAX16(0,st->analysis.tonality-.2);
-        tonal_target = new_target + (coded_bins<<BITRES)*2.0f*tonal;
+        tonal_target = target + (coded_bins<<BITRES)*2.0f*tonal;
         if (pitch_change)
            tonal_target +=  (coded_bins<<BITRES)*.8;
         /*printf("%f %f ", st->analysis.tonality, tonal);*/
-        new_target = IMAX(tonal_target,new_target);
+        target = IMAX(tonal_target,target);
      }
 #endif
 
@@ -1660,13 +1664,30 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f
         bins = st->mode->eBands[st->mode->nbEBands-2]<<LM;
         /*floor_depth = SHR32(MULT16_16((C*bins<<BITRES),celt_log2(SHL32(MAX16(1,sample_max),13))), DB_SHIFT);*/
         floor_depth = SHR32(MULT16_16((C*bins<<BITRES),maxDepth), DB_SHIFT);
-        floor_depth = IMAX(floor_depth, new_target>>2);
-        new_target = IMIN(new_target, floor_depth);
+        floor_depth = IMAX(floor_depth, target>>2);
+        target = IMIN(target, floor_depth);
         /*printf("%f %d\n", maxDepth, floor_depth);*/
      }
+
+     if (st->constrained_vbr || st->bitrate<64000)
+     {
+        opus_val16 rate_factor;
+#ifdef FIXED_POINT
+        rate_factor = MAX16(0,(st->bitrate-32000));
+#else
+        rate_factor = MAX16(0,(1.f/32768)*(st->bitrate-32000));
+#endif
+        if (st->constrained_vbr)
+           rate_factor = MIN16(rate_factor, QCONST16(0.67f, 15));
+        target = base_target + MULT16_32_Q15(rate_factor, target-base_target);
+
+     }
+     /* Don't allow more than doubling the rate */
+     target = IMIN(2*base_target, target);
+
      /* The current offset is removed from the target and the space used
         so far is added*/
-     target=new_target+tell;
+     target=target+tell;
      /* In VBR mode the frame size must not be reduced so much that it would
          result in the encoder running out of bits.
         The margin of 2 bytes ensures that none of the bust-prevention logic