Change FIX15() back to clipping to -32767..32767.
[ffmpeg.git] / libavcodec / ac3enc.c
index 274e76b..200fff4 100644 (file)
@@ -44,7 +44,7 @@
 #define SCALE_FLOAT(a, bits) lrintf((a) * (float)(1 << (bits)))
 
 /** Scale a float value by 2^15, convert to an integer, and clip to int16_t range. */
-#define FIX15(a) av_clip_int16(SCALE_FLOAT(a, 15))
+#define FIX15(a) av_clip(SCALE_FLOAT(a, 15), -32767, 32767)
 
 
 /**
@@ -101,6 +101,7 @@ typedef struct AC3EncodeContext {
     int frame_size_min;                     ///< minimum frame size in case rounding is necessary
     int frame_size;                         ///< current frame size in bytes
     int frame_size_code;                    ///< frame size code                        (frmsizecod)
+    uint16_t crc_inv[2];
     int bits_written;                       ///< bit count    (used to avg. bitrate)
     int samples_written;                    ///< sample count (used to avg. bitrate)
 
@@ -111,6 +112,7 @@ typedef struct AC3EncodeContext {
     int channel_mode;                       ///< channel mode                           (acmod)
     const uint8_t *channel_map;             ///< channel map used to reorder channels
 
+    int cutoff;                             ///< user-specified cutoff frequency, in Hz
     int bandwidth_code[AC3_MAX_CHANNELS];   ///< bandwidth code (0 to 60)               (chbwcod)
     int nb_coefs[AC3_MAX_CHANNELS];
 
@@ -585,6 +587,7 @@ static void compute_exp_strategy_ch(AC3EncodeContext *s, uint8_t *exp_strategy,
         else
             exp_strategy[blk] = EXP_REUSE;
     }
+    emms_c();
 
     /* now select the encoding strategy type : if exponents are often
        recoded, we use a coarse encoding */
@@ -1114,6 +1117,68 @@ static int cbr_bit_allocation(AC3EncodeContext *s)
 
 
 /**
+ * Downgrade exponent strategies to reduce the bits used by the exponents.
+ * This is a fallback for when bit allocation fails with the normal exponent
+ * strategies.  Each time this function is run it only downgrades the
+ * strategy in 1 channel of 1 block.
+ * @return non-zero if downgrade was unsuccessful
+ */
+static int downgrade_exponents(AC3EncodeContext *s)
+{
+    int ch, blk;
+
+    for (ch = 0; ch < s->fbw_channels; ch++) {
+        for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) {
+            if (s->blocks[blk].exp_strategy[ch] == EXP_D15) {
+                s->blocks[blk].exp_strategy[ch] = EXP_D25;
+                return 0;
+            }
+        }
+    }
+    for (ch = 0; ch < s->fbw_channels; ch++) {
+        for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) {
+            if (s->blocks[blk].exp_strategy[ch] == EXP_D25) {
+                s->blocks[blk].exp_strategy[ch] = EXP_D45;
+                return 0;
+            }
+        }
+    }
+    for (ch = 0; ch < s->fbw_channels; ch++) {
+        /* block 0 cannot reuse exponents, so only downgrade D45 to REUSE if
+           the block number > 0 */
+        for (blk = AC3_MAX_BLOCKS-1; blk > 0; blk--) {
+            if (s->blocks[blk].exp_strategy[ch] > EXP_REUSE) {
+                s->blocks[blk].exp_strategy[ch] = EXP_REUSE;
+                return 0;
+            }
+        }
+    }
+    return -1;
+}
+
+
+/**
+ * Reduce the bandwidth to reduce the number of bits used for a given SNR offset.
+ * This is a second fallback for when bit allocation still fails after exponents
+ * have been downgraded.
+ * @return non-zero if bandwidth reduction was unsuccessful
+ */
+static int reduce_bandwidth(AC3EncodeContext *s, int min_bw_code)
+{
+    int ch;
+
+    if (s->bandwidth_code[0] > min_bw_code) {
+        for (ch = 0; ch < s->fbw_channels; ch++) {
+            s->bandwidth_code[ch]--;
+            s->nb_coefs[ch] = s->bandwidth_code[ch] * 3 + 73;
+        }
+        return 0;
+    }
+    return -1;
+}
+
+
+/**
  * Perform bit allocation search.
  * Finds the SNR offset value that maximizes quality and fits in the specified
  * frame size.  Output is the SNR offset and a set of bit allocation pointers
@@ -1121,11 +1186,37 @@ static int cbr_bit_allocation(AC3EncodeContext *s)
  */
 static int compute_bit_allocation(AC3EncodeContext *s)
 {
+    int ret;
+
     count_frame_bits(s);
 
     bit_alloc_masking(s);
 
-    return cbr_bit_allocation(s);
+    ret = cbr_bit_allocation(s);
+    while (ret) {
+        /* fallback 1: downgrade exponents */
+        if (!downgrade_exponents(s)) {
+            extract_exponents(s);
+            encode_exponents(s);
+            group_exponents(s);
+            ret = compute_bit_allocation(s);
+            continue;
+        }
+
+        /* fallback 2: reduce bandwidth */
+        /* only do this if the user has not specified a specific cutoff
+           frequency */
+        if (!s->cutoff && !reduce_bandwidth(s, 0)) {
+            process_exponents(s);
+            ret = compute_bit_allocation(s);
+            continue;
+        }
+
+        /* fallbacks were not enough... */
+        break;
+    }
+
+    return ret;
 }
 
 
@@ -1498,8 +1589,7 @@ static void output_frame_end(AC3EncodeContext *s)
     /* this is not so easy because it is at the beginning of the data... */
     crc1 = av_bswap16(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0,
                              frame + 4, frame_size_58 - 4));
-    /* XXX: could precompute crc_inv */
-    crc_inv = pow_poly((CRC16_POLY >> 1), (8 * frame_size_58) - 16, CRC16_POLY);
+    crc_inv = s->crc_inv[s->frame_size > s->frame_size_min];
     crc1    = mul_poly(crc_inv, crc1, CRC16_POLY);
     AV_WB16(frame + 2, crc1);
 
@@ -1691,6 +1781,15 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s)
     s->bit_rate        = avctx->bit_rate;
     s->frame_size_code = i << 1;
 
+    /* validate cutoff */
+    if (avctx->cutoff < 0) {
+        av_log(avctx, AV_LOG_ERROR, "invalid cutoff frequency\n");
+        return AVERROR(EINVAL);
+    }
+    s->cutoff = avctx->cutoff;
+    if (s->cutoff > (s->sample_rate >> 1))
+        s->cutoff = s->sample_rate >> 1;
+
     return 0;
 }
 
@@ -1700,15 +1799,14 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s)
  * The user can optionally supply a cutoff frequency. Otherwise an appropriate
  * default value will be used.
  */
-static av_cold void set_bandwidth(AC3EncodeContext *s, int cutoff)
+static av_cold void set_bandwidth(AC3EncodeContext *s)
 {
     int ch, bw_code;
 
-    if (cutoff) {
+    if (s->cutoff) {
         /* calculate bandwidth based on user-specified cutoff frequency */
         int fbw_coeffs;
-        cutoff         = av_clip(cutoff, 1, s->sample_rate >> 1);
-        fbw_coeffs     = cutoff * 2 * AC3_MAX_COEFS / s->sample_rate;
+        fbw_coeffs     = s->cutoff * 2 * AC3_MAX_COEFS / s->sample_rate;
         bw_code        = av_clip((fbw_coeffs - 73) / 3, 0, 60);
     } else {
         /* use default bandwidth setting */
@@ -1800,7 +1898,7 @@ alloc_fail:
 static av_cold int ac3_encode_init(AVCodecContext *avctx)
 {
     AC3EncodeContext *s = avctx->priv_data;
-    int ret;
+    int ret, frame_size_58;
 
     avctx->frame_size = AC3_FRAME_SIZE;
 
@@ -1818,7 +1916,15 @@ static av_cold int ac3_encode_init(AVCodecContext *avctx)
     s->samples_written = 0;
     s->frame_size      = s->frame_size_min;
 
-    set_bandwidth(s, avctx->cutoff);
+    /* calculate crc_inv for both possible frame sizes */
+    frame_size_58 = (( s->frame_size    >> 2) + ( s->frame_size    >> 4)) << 1;
+    s->crc_inv[0] = pow_poly((CRC16_POLY >> 1), (8 * frame_size_58) - 16, CRC16_POLY);
+    if (s->bit_alloc.sr_code == 1) {
+        frame_size_58 = (((s->frame_size+2) >> 2) + ((s->frame_size+2) >> 4)) << 1;
+        s->crc_inv[1] = pow_poly((CRC16_POLY >> 1), (8 * frame_size_58) - 16, CRC16_POLY);
+    }
+
+    set_bandwidth(s);
 
     exponent_init(s);