alsdec: Correct the ALS decoder by storing some parameters per-channel rather
[ffmpeg.git] / libavcodec / alsdec.c
index 9b71b2d..116e5e2 100644 (file)
@@ -205,6 +205,10 @@ typedef struct {
     uint8_t *bgmc_lut;              ///< pointer at lookup tables used for BGMC
     int *bgmc_lut_status;           ///< pointer at lookup table status flags used for BGMC
     int ltp_lag_length;             ///< number of bits used for ltp lag value
+    int *const_block;               ///< contains const_block flags for all channels
+    unsigned int *shift_lsbs;       ///< contains shift_lsbs flags for all channels
+    unsigned int *opt_order;        ///< contains opt_order flags for all channels
+    int *store_prev_samples;        ///< contains store_prev_samples flags for all channels
     int *use_ltp;                   ///< contains use_ltp flags for all channels
     int *ltp_lag;                   ///< contains ltp lag values for all channels
     int **ltp_gain;                 ///< gain values for ltp 5-tap filter for a channel
@@ -227,12 +231,11 @@ typedef struct {
 typedef struct {
     unsigned int block_length;      ///< number of samples within the block
     unsigned int ra_block;          ///< if true, this is a random access block
-    int          const_block;       ///< if true, this is a constant value block
-    int32_t      const_val;         ///< the sample value of a constant block
+    int          *const_block;      ///< if true, this is a constant value block
     int          js_blocks;         ///< true if this block contains a difference signal
-    unsigned int shift_lsbs;        ///< shift of values for this block
-    unsigned int opt_order;         ///< prediction order of this block
-    int          store_prev_samples;///< if true, carryover samples have to be stored
+    unsigned int *shift_lsbs;       ///< shift of values for this block
+    unsigned int *opt_order;        ///< prediction order of this block
+    int          *store_prev_samples;///< if true, carryover samples have to be stored
     int          *use_ltp;          ///< if true, long-term prediction is used
     int          *ltp_lag;          ///< lag value for long-term prediction
     int          *ltp_gain;         ///< gain values for ltp 5-tap filter
@@ -554,20 +557,20 @@ static void read_const_block_data(ALSDecContext *ctx, ALSBlockData *bd)
     AVCodecContext *avctx    = ctx->avctx;
     GetBitContext *gb        = &ctx->gb;
 
-    bd->const_val    = 0;
-    bd->const_block  = get_bits1(gb);    // 1 = constant value, 0 = zero block (silence)
+    *bd->raw_samples = 0;
+    *bd->const_block = get_bits1(gb);    // 1 = constant value, 0 = zero block (silence)
     bd->js_blocks    = get_bits1(gb);
 
     // skip 5 reserved bits
     skip_bits(gb, 5);
 
-    if (bd->const_block) {
+    if (*bd->const_block) {
         unsigned int const_val_bits = sconf->floating ? 24 : avctx->bits_per_raw_sample;
-        bd->const_val = get_sbits_long(gb, const_val_bits);
+        *bd->raw_samples = get_sbits_long(gb, const_val_bits);
     }
 
     // ensure constant block decoding by reusing this field
-    bd->const_block = 1;
+    *bd->const_block = 1;
 }
 
 
@@ -575,9 +578,9 @@ static void read_const_block_data(ALSDecContext *ctx, ALSBlockData *bd)
  */
 static void decode_const_block_data(ALSDecContext *ctx, ALSBlockData *bd)
 {
-    int      smp = bd->block_length;
-    int32_t  val = bd->const_val;
-    int32_t *dst = bd->raw_samples;
+    int      smp = bd->block_length - 1;
+    int32_t  val = *bd->raw_samples;
+    int32_t *dst = bd->raw_samples + 1;
 
     // write raw samples into buffer
     for (; smp; smp--)
@@ -604,12 +607,12 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd)
 
 
     // ensure variable block decoding by reusing this field
-    bd->const_block = 0;
+    *bd->const_block = 0;
 
-    bd->opt_order   = 1;
+    *bd->opt_order  = 1;
     bd->js_blocks   = get_bits1(gb);
 
-    opt_order       = bd->opt_order;
+    opt_order       = *bd->opt_order;
 
     // determine the number of subblocks for entropy decoding
     if (!sconf->bgmc && !sconf->sb_part) {
@@ -649,21 +652,21 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd)
     }
 
     if (get_bits1(gb))
-        bd->shift_lsbs = get_bits(gb, 4) + 1;
+        *bd->shift_lsbs = get_bits(gb, 4) + 1;
 
-    bd->store_prev_samples = (bd->js_blocks && bd->raw_other) || bd->shift_lsbs;
+    *bd->store_prev_samples = (bd->js_blocks && bd->raw_other) || *bd->shift_lsbs;
 
 
     if (!sconf->rlslms) {
         if (sconf->adapt_order) {
             int opt_order_length = av_ceil_log2(av_clip((bd->block_length >> 3) - 1,
                                                 2, sconf->max_order + 1));
-            bd->opt_order        = get_bits(gb, opt_order_length);
+            *bd->opt_order       = get_bits(gb, opt_order_length);
         } else {
-            bd->opt_order = sconf->max_order;
+            *bd->opt_order = sconf->max_order;
         }
 
-        opt_order = bd->opt_order;
+        opt_order = *bd->opt_order;
 
         if (opt_order) {
             int add_base;
@@ -840,7 +843,7 @@ static int decode_var_block_data(ALSDecContext *ctx, ALSBlockData *bd)
     unsigned int block_length = bd->block_length;
     unsigned int smp = 0;
     unsigned int k;
-    int opt_order             = bd->opt_order;
+    int opt_order             = *bd->opt_order;
     int sb;
     int64_t y;
     int32_t *quant_cof        = bd->quant_cof;
@@ -885,7 +888,7 @@ static int decode_var_block_data(ALSDecContext *ctx, ALSBlockData *bd)
             parcor_to_lpc(k, quant_cof, lpc_cof);
 
         // store previous samples in case that they have to be altered
-        if (bd->store_prev_samples)
+        if (*bd->store_prev_samples)
             memcpy(bd->prev_raw_samples, raw_samples - sconf->max_order,
                    sizeof(*bd->prev_raw_samples) * sconf->max_order);
 
@@ -906,9 +909,9 @@ static int decode_var_block_data(ALSDecContext *ctx, ALSBlockData *bd)
         }
 
         // reconstruct shifted signal
-        if (bd->shift_lsbs)
+        if (*bd->shift_lsbs)
             for (sb = -1; sb >= -sconf->max_order; sb--)
-                raw_samples[sb] >>= bd->shift_lsbs;
+                raw_samples[sb] >>= *bd->shift_lsbs;
     }
 
     // reverse linear prediction coefficients for efficiency
@@ -933,7 +936,7 @@ static int decode_var_block_data(ALSDecContext *ctx, ALSBlockData *bd)
     raw_samples = bd->raw_samples;
 
     // restore previous samples in case that they have been altered
-    if (bd->store_prev_samples)
+    if (*bd->store_prev_samples)
         memcpy(raw_samples - sconf->max_order, bd->prev_raw_samples,
                sizeof(*raw_samples) * sconf->max_order);
 
@@ -947,6 +950,7 @@ static int read_block(ALSDecContext *ctx, ALSBlockData *bd)
 {
     GetBitContext *gb        = &ctx->gb;
 
+    *bd->shift_lsbs = 0;
     // read block type flag and read the samples accordingly
     if (get_bits1(gb)) {
         if (read_var_block_data(ctx, bd))
@@ -966,16 +970,16 @@ static int decode_block(ALSDecContext *ctx, ALSBlockData *bd)
     unsigned int smp;
 
     // read block type flag and read the samples accordingly
-    if (bd->const_block)
+    if (*bd->const_block)
         decode_const_block_data(ctx, bd);
     else if (decode_var_block_data(ctx, bd))
         return -1;
 
     // TODO: read RLSLMS extension data
 
-    if (bd->shift_lsbs)
+    if (*bd->shift_lsbs)
         for (smp = 0; smp < bd->block_length; smp++)
-            bd->raw_samples[smp] <<= bd->shift_lsbs;
+            bd->raw_samples[smp] <<= *bd->shift_lsbs;
 
     return 0;
 }
@@ -1026,6 +1030,10 @@ static int decode_blocks_ind(ALSDecContext *ctx, unsigned int ra_frame,
     memset(&bd, 0, sizeof(ALSBlockData));
 
     bd.ra_block         = ra_frame;
+    bd.const_block      = ctx->const_block;
+    bd.shift_lsbs       = ctx->shift_lsbs;
+    bd.opt_order        = ctx->opt_order;
+    bd.store_prev_samples = ctx->store_prev_samples;
     bd.use_ltp          = ctx->use_ltp;
     bd.ltp_lag          = ctx->ltp_lag;
     bd.ltp_gain         = ctx->ltp_gain[0];
@@ -1036,7 +1044,6 @@ static int decode_blocks_ind(ALSDecContext *ctx, unsigned int ra_frame,
 
 
     for (b = 0; b < ctx->num_blocks; b++) {
-        bd.shift_lsbs       = 0;
         bd.block_length     = div_blocks[b];
 
         if (read_decode_block(ctx, &bd)) {
@@ -1066,6 +1073,10 @@ static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame,
     memset(bd, 0, 2 * sizeof(ALSBlockData));
 
     bd[0].ra_block         = ra_frame;
+    bd[0].const_block      = ctx->const_block;
+    bd[0].shift_lsbs       = ctx->shift_lsbs;
+    bd[0].opt_order        = ctx->opt_order;
+    bd[0].store_prev_samples = ctx->store_prev_samples;
     bd[0].use_ltp          = ctx->use_ltp;
     bd[0].ltp_lag          = ctx->ltp_lag;
     bd[0].ltp_gain         = ctx->ltp_gain[0];
@@ -1075,6 +1086,10 @@ static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame,
     bd[0].js_blocks        = *js_blocks;
 
     bd[1].ra_block         = ra_frame;
+    bd[1].const_block      = ctx->const_block;
+    bd[1].shift_lsbs       = ctx->shift_lsbs;
+    bd[1].opt_order        = ctx->opt_order;
+    bd[1].store_prev_samples = ctx->store_prev_samples;
     bd[1].use_ltp          = ctx->use_ltp;
     bd[1].ltp_lag          = ctx->ltp_lag;
     bd[1].ltp_gain         = ctx->ltp_gain[0];
@@ -1087,9 +1102,6 @@ static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame,
     for (b = 0; b < ctx->num_blocks; b++) {
         unsigned int s;
 
-        bd[0].shift_lsbs   = 0;
-        bd[1].shift_lsbs   = 0;
-
         bd[0].block_length = div_blocks[b];
         bd[1].block_length = div_blocks[b];
 
@@ -1207,6 +1219,10 @@ static int revert_channel_correlation(ALSDecContext *ctx, ALSBlockData *bd,
         return -1;
     }
 
+    bd->const_block = ctx->const_block + c;
+    bd->shift_lsbs  = ctx->shift_lsbs + c;
+    bd->opt_order   = ctx->opt_order + c;
+    bd->store_prev_samples = ctx->store_prev_samples + c;
     bd->use_ltp     = ctx->use_ltp + c;
     bd->ltp_lag     = ctx->ltp_lag + c;
     bd->ltp_gain    = ctx->ltp_gain[c];
@@ -1340,10 +1356,13 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame)
         get_block_sizes(ctx, div_blocks, &bs_info);
 
         for (b = 0; b < ctx->num_blocks; b++) {
-            bd.shift_lsbs   = 0;
             bd.block_length = div_blocks[b];
 
             for (c = 0; c < avctx->channels; c++) {
+                bd.const_block = ctx->const_block + c;
+                bd.shift_lsbs  = ctx->shift_lsbs + c;
+                bd.opt_order   = ctx->opt_order + c;
+                bd.store_prev_samples = ctx->store_prev_samples + c;
                 bd.use_ltp     = ctx->use_ltp + c;
                 bd.ltp_lag     = ctx->ltp_lag + c;
                 bd.ltp_gain    = ctx->ltp_gain[c];
@@ -1363,6 +1382,10 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame)
                     return -1;
 
             for (c = 0; c < avctx->channels; c++) {
+                bd.const_block = ctx->const_block + c;
+                bd.shift_lsbs  = ctx->shift_lsbs + c;
+                bd.opt_order   = ctx->opt_order + c;
+                bd.store_prev_samples = ctx->store_prev_samples + c;
                 bd.use_ltp     = ctx->use_ltp + c;
                 bd.ltp_lag     = ctx->ltp_lag + c;
                 bd.ltp_gain    = ctx->ltp_gain[c];
@@ -1522,6 +1545,10 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
     ff_bgmc_end(&ctx->bgmc_lut, &ctx->bgmc_lut_status);
 
+    av_freep(&ctx->const_block);
+    av_freep(&ctx->shift_lsbs);
+    av_freep(&ctx->opt_order);
+    av_freep(&ctx->store_prev_samples);
     av_freep(&ctx->use_ltp);
     av_freep(&ctx->ltp_lag);
     av_freep(&ctx->ltp_gain);
@@ -1616,13 +1643,19 @@ static av_cold int decode_init(AVCodecContext *avctx)
     }
 
     // allocate and assign lag and gain data buffer for ltp mode
+    ctx->const_block     = av_malloc (sizeof(*ctx->const_block) * num_buffers);
+    ctx->shift_lsbs      = av_malloc (sizeof(*ctx->shift_lsbs)  * num_buffers);
+    ctx->opt_order       = av_malloc (sizeof(*ctx->opt_order)   * num_buffers);
+    ctx->store_prev_samples = av_malloc(sizeof(*ctx->store_prev_samples) * num_buffers);
     ctx->use_ltp         = av_mallocz(sizeof(*ctx->use_ltp)  * num_buffers);
     ctx->ltp_lag         = av_malloc (sizeof(*ctx->ltp_lag)  * num_buffers);
     ctx->ltp_gain        = av_malloc (sizeof(*ctx->ltp_gain) * num_buffers);
     ctx->ltp_gain_buffer = av_malloc (sizeof(*ctx->ltp_gain_buffer) *
                                       num_buffers * 5);
 
-    if (!ctx->use_ltp  || !ctx->ltp_lag ||
+    if (!ctx->const_block || !ctx->shift_lsbs ||
+        !ctx->opt_order || !ctx->store_prev_samples ||
+        !ctx->use_ltp  || !ctx->ltp_lag ||
         !ctx->ltp_gain || !ctx->ltp_gain_buffer) {
         av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
         decode_end(avctx);