]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/wmalosslessdec.c
h264: rewrite has_b_frame calculation code,
[ffmpeg] / libavcodec / wmalosslessdec.c
index 7e8acf3b616c9136af48026441081857b5384396..7427cb873f4c6f318692313a55f6e6a2d7a9bca9 100644 (file)
@@ -141,6 +141,9 @@ typedef struct {
     DECLARE_ALIGNED(16, float, out)[WMALL_BLOCK_MAX_SIZE + WMALL_BLOCK_MAX_SIZE / 2]; ///< output buffer
 } WmallChannelCtx;
 
+                                                    /* XXX: probably we don't need subframe_config[],
+                                                    WmallChannelCtx holds all the necessary data. */
+
 /**
  * @brief channel group for channel transformations
  */
@@ -216,9 +219,9 @@ typedef struct WmallDecodeCtx {
     int8_t           esc_len;                       ///< length of escaped coefficients
 
     uint8_t          num_chgroups;                  ///< number of channel groups
-    WmallChannelGrp chgroup[WMALL_MAX_CHANNELS];  ///< channel group information
+    WmallChannelGrp chgroup[WMALL_MAX_CHANNELS];    ///< channel group information
 
-    WmallChannelCtx channel[WMALL_MAX_CHANNELS];  ///< per channel data
+    WmallChannelCtx channel[WMALL_MAX_CHANNELS];    ///< per channel data
 
     // WMA lossless
 
@@ -236,6 +239,9 @@ typedef struct WmallDecodeCtx {
     int8_t mclms_scaling;
     int16_t mclms_coeffs[128];
     int16_t mclms_coeffs_cur[4];
+    int mclms_prevvalues[64];   // FIXME: should be 32-bit / 16-bit depending on bit-depth
+    int16_t mclms_updates[64];
+    int mclms_recent;
 
     int movave_scaling;
     int quant_stepsize;
@@ -246,14 +252,20 @@ typedef struct WmallDecodeCtx {
         int coefsend;
         int bitsend;
         int16_t coefs[256];
-    } cdlms[2][9];
+    int lms_prevvalues[512];    // FIXME: see above
+    int16_t lms_updates[512];   // and here too
+    int recent;
+    } cdlms[2][9];              /* XXX: Here, 2 is the max. no. of channels allowed,
+                                        9 is the maximum no. of filters per channel.
+                                        Question is, why 2 if WMALL_MAX_CHANNELS == 8 */
 
 
     int cdlms_ttl[2];
 
     int bV3RTM;
 
-    int is_channel_coded[2];
+    int is_channel_coded[2];    // XXX: same question as above applies here too (and below)
+    int update_speed[2];
 
     int transient[2];
     int transient_pos[2];
@@ -278,6 +290,8 @@ typedef struct WmallDecodeCtx {
 #define dprintf(pctx, ...) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__)
 
 
+static int num_logged_tiles = 0;
+
 /**
  *@brief helper function to print the most important members of the context
  *@param s context
@@ -363,10 +377,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
         s->channel[i].prev_block_len = s->samples_per_frame;
 
     /** subframe info */
-    log2_max_num_subframes       = ((s->decode_flags & 0x38) >> 3);
-    s->max_num_subframes         = 1 << log2_max_num_subframes;
+    log2_max_num_subframes  = ((s->decode_flags & 0x38) >> 3);
+    s->max_num_subframes    = 1 << log2_max_num_subframes;
     s->max_subframe_len_bit = 0;
-    s->subframe_len_bits = av_log2(log2_max_num_subframes) + 1;
+    s->subframe_len_bits    = av_log2(log2_max_num_subframes) + 1;
 
     num_possible_block_sizes     = log2_max_num_subframes + 1;
     s->min_samples_per_subframe  = s->samples_per_frame / s->max_num_subframes;
@@ -420,8 +434,8 @@ static int decode_subframe_length(WmallDecodeCtx *s, int offset)
     if (offset == s->samples_per_frame - s->min_samples_per_subframe)
         return s->min_samples_per_subframe;
 
-    len = av_log2(s->max_num_subframes - 1) + 1;
-    frame_len_ratio = get_bits(&s->gb, len);
+    len = av_log2(s->max_num_subframes - 1) + 1;    // XXX: 5.3.3
+    frame_len_ratio = get_bits(&s->gb, len);        // XXX: tile_size_ratio
 
     subframe_len = s->min_samples_per_subframe * (frame_len_ratio + 1);
 
@@ -455,7 +469,7 @@ static int decode_subframe_length(WmallDecodeCtx *s, int offset)
  *@param s context
  *@return 0 on success, < 0 in case of an error
  */
-static int decode_tilehdr(WmallDecodeCtx *s)
+static int decode_tilehdr(WmallDecodeCtx *s)        /* XXX: decode_tile_configuration() [Table 9] */
 {
     uint16_t num_samples[WMALL_MAX_CHANNELS];        /**< sum of samples for all currently known subframes of a channel */
     uint8_t  contains_subframe[WMALL_MAX_CHANNELS];  /**< flag indicating if a channel contains the current subframe */
@@ -476,8 +490,8 @@ static int decode_tilehdr(WmallDecodeCtx *s)
 
     memset(num_samples, 0, sizeof(num_samples));
 
-    if (s->max_num_subframes == 1 || get_bits1(&s->gb))
-        fixed_channel_layout = 1;
+    if (s->max_num_subframes == 1 || get_bits1(&s->gb))     // XXX: locate in the spec
+        fixed_channel_layout = 1;                           // XXX: tile_aligned ?
 
     /** loop until the frame data is split between the subframes */
     do {
@@ -491,14 +505,14 @@ static int decode_tilehdr(WmallDecodeCtx *s)
                     contains_subframe[c] = 1;
                 }
                 else {
-                    contains_subframe[c] = get_bits1(&s->gb);
+                    contains_subframe[c] = get_bits1(&s->gb);   // XXX: locate in the spec
                 }
             } else
                 contains_subframe[c] = 0;
         }
 
         /** get subframe length, subframe_len == 0 is not allowed */
-        if ((subframe_len = decode_subframe_length(s, min_channel_len)) <= 0)
+        if ((subframe_len = decode_subframe_length(s, min_channel_len)) <= 0)   //XXX: this reads tile_size_ratio
             return AVERROR_INVALIDDATA;
         /** add subframes to the individual channels and find new min_channel_len */
         min_channel_len += subframe_len;
@@ -665,6 +679,7 @@ static int decode_channel_residues(WmallDecodeCtx *s, int ch, int tile_size)
             s->channel_residues[ch][0] = get_sbits(&s->gb, s->bits_per_sample);
         i++;
     }
+    av_log(0, 0, "%8d: ", num_logged_tiles++);
     for(; i < tile_size; i++) {
         int quo = 0, rem, rem_bits, residue;
         while(get_bits1(&s->gb))
@@ -685,8 +700,11 @@ static int decode_channel_residues(WmallDecodeCtx *s, int ch, int tile_size)
             residue = residue >> 1;
         s->channel_residues[ch][i] = residue;
 
+    //if (num_logged_tiles < 1)
+        av_log(0, 0, "%4d ", residue);
 //        dprintf(s->avctx, "%5d: %5d %10d %12d %12d %5d %-16d %04x\n",i, quo, ave_mean, s->ave_sum[ch], rem, rem_bits, s->channel_residues[ch][i], show_bits(&s->gb, 16));
     }
+    av_log(0, 0, "\n Tile size = %d\n", tile_size);
 
     return 0;
 
@@ -712,6 +730,136 @@ decode_lpc(WmallDecodeCtx *s)
 }
 
 
+static void clear_codec_buffers(WmallDecodeCtx *s)
+{
+    int ich, ilms;
+
+    memset(s->acfilter_coeffs, 0,     16 * sizeof(int));
+    memset(s->lpc_coefs      , 0, 40 * 2 * sizeof(int));
+
+    memset(s->mclms_coeffs    , 0, 128 * sizeof(int16_t));
+    memset(s->mclms_coeffs_cur, 0,   4 * sizeof(int16_t));
+    memset(s->mclms_prevvalues, 0,  64 * sizeof(int));
+    memset(s->mclms_updates   , 0,  64 * sizeof(int16_t));
+
+    for (ich = 0; ich < s->num_channels; ich++) {
+        for (ilms = 0; ilms < s->cdlms_ttl[ich]; ilms++) {
+            memset(s->cdlms[ich][ilms].coefs         , 0, 256 * sizeof(int16_t));
+            memset(s->cdlms[ich][ilms].lms_prevvalues, 0, 512 * sizeof(int));
+            memset(s->cdlms[ich][ilms].lms_updates   , 0, 512 * sizeof(int16_t));
+        }
+        s->ave_sum[ich] = 0;
+    }
+}
+
+static void reset_codec(WmallDecodeCtx *s)
+{
+    int ich, ilms;
+    s->mclms_recent = s->mclms_order * s->num_channels;
+    for (ich = 0; ich < s->num_channels; ich++)
+        for (ilms = 0; ilms < s->cdlms_ttl[ich]; ilms++)
+            s->cdlms[ich][ilms].recent = s->cdlms[ich][ilms].order;
+}
+
+
+
+static int lms_predict(WmallDecodeCtx *s, int ich, int ilms)
+{
+    int32_t pred, icoef;
+    int recent = s->cdlms[ich][ilms].recent;
+
+    for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
+        pred += s->cdlms[ich][ilms].coefs[icoef] *
+                    s->cdlms[ich][ilms].lms_prevvalues[icoef + recent];
+
+    pred += (1 << (s->cdlms[ich][ilms].scaling - 1));
+    /* XXX: Table 29 has:
+            iPred >= cdlms[iCh][ilms].scaling;
+       seems to me like a missing > */
+    pred >>= s->cdlms[ich][ilms].scaling;
+    return pred;
+}
+
+static void lms_update(WmallDecodeCtx *s, int ich, int ilms, int32_t input, int32_t pred)
+{
+    int icoef;
+    int recent = s->cdlms[ich][ilms].recent;
+    int range = 1 << (s->bits_per_sample - 1);
+    int bps = s->bits_per_sample > 16 ? 4 : 2; // bytes per sample
+
+    if (input > pred) {
+        for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
+            s->cdlms[ich][ilms].coefs[icoef] +=
+                s->cdlms[ich][ilms].lms_updates[icoef + recent];
+    } else {
+        for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
+            s->cdlms[ich][ilms].coefs[icoef] -=
+                s->cdlms[ich][ilms].lms_updates[icoef];     // XXX: [icoef + recent] ?
+    }
+    s->cdlms[ich][ilms].recent--;
+    s->cdlms[ich][ilms].lms_prevvalues[recent] = av_clip(input, -range, range - 1);
+
+    if (input > pred)
+        s->cdlms[ich][ilms].lms_updates[recent] = s->update_speed[ich];
+    else if (input < pred)
+        s->cdlms[ich][ilms].lms_updates[recent] = -s->update_speed[ich];
+
+    /* XXX: spec says:
+    cdlms[iCh][ilms].updates[iRecent + cdlms[iCh][ilms].order >> 4] >>= 2;
+    lms_updates[iCh][ilms][iRecent + cdlms[iCh][ilms].order >> 3] >>= 1;
+
+        Questions is - are cdlms[iCh][ilms].updates[] and lms_updates[][][] two
+        seperate buffers? Here I've assumed that the two are same which makes
+        more sense to me.
+    */
+    s->cdlms[ich][ilms].lms_updates[recent + s->cdlms[ich][ilms].order >> 4] >>= 2;
+    s->cdlms[ich][ilms].lms_updates[recent + s->cdlms[ich][ilms].order >> 3] >>= 1;
+    /* XXX: recent + (s->cdlms[ich][ilms].order >> 4) ? */
+
+    if (s->cdlms[ich][ilms].recent == 0) {
+        /* XXX: This memcpy()s will probably fail if a fixed 32-bit buffer is used.
+                follow kshishkov's suggestion of using a union. */
+        memcpy(s->cdlms[ich][ilms].lms_prevvalues + s->cdlms[ich][ilms].order,
+               s->cdlms[ich][ilms].lms_prevvalues,
+               bps * s->cdlms[ich][ilms].order);
+        memcpy(s->cdlms[ich][ilms].lms_updates + s->cdlms[ich][ilms].order,
+               s->cdlms[ich][ilms].lms_updates,
+               bps * s->cdlms[ich][ilms].order);
+        s->cdlms[ich][ilms].recent = s->cdlms[ich][ilms].order;
+    }
+}
+
+static void use_high_update_speed(WmallDecodeCtx *s, int ich)
+{
+    int ilms, recent, icoef;
+    s->update_speed[ich] = 16;
+    for (ilms = s->cdlms_ttl[ich]; ilms >= 0; ilms--) {
+        recent = s->cdlms[ich][ilms].recent;
+        if (s->bV3RTM) {
+            for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
+                s->cdlms[ich][ilms].lms_updates[icoef + recent] *= 2;
+        } else {
+            for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
+                s->cdlms[ich][ilms].lms_updates[icoef] *= 2;
+        }
+    }
+}
+
+static void use_normal_update_speed(WmallDecodeCtx *s, int ich)
+{
+    int ilms, recent, icoef;
+    s->update_speed[ich] = 8;
+    for (ilms = s->cdlms_ttl[ich]; ilms >= 0; ilms--) {
+        recent = s->cdlms[ich][ilms].recent;
+        if (s->bV3RTM) {
+            for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
+                s->cdlms[ich][ilms].lms_updates[icoef + recent] /= 2;
+        } else {
+            for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
+                s->cdlms[ich][ilms].lms_updates[icoef] /= 2;
+        }
+    }
+}
 
 /**
  *@brief Decode a single subframe (block).
@@ -768,6 +916,8 @@ static int decode_subframe(WmallDecodeCtx *s)
 
     s->seekable_tile = get_bits1(&s->gb);
     if(s->seekable_tile) {
+        clear_codec_buffers(s);
+
         s->do_arith_coding    = get_bits1(&s->gb);
         if(s->do_arith_coding) {
             dprintf(s->avctx, "do_arith_coding == 1");
@@ -786,6 +936,8 @@ static int decode_subframe(WmallDecodeCtx *s)
         decode_cdlms(s);
         s->movave_scaling = get_bits(&s->gb, 3);
         s->quant_stepsize = get_bits(&s->gb, 8) + 1;
+
+            reset_codec(s);
     }
 
     rawpcm_tile = get_bits1(&s->gb);
@@ -844,7 +996,7 @@ static int decode_subframe(WmallDecodeCtx *s)
             av_log(s->avctx, AV_LOG_ERROR, "broken subframe\n");
             return AVERROR_INVALIDDATA;
         }
-        ++s->channel[c].cur_subframe;
+        ++s->channel[c].cur_subframe;       // XXX: 6.4
     }
     return 0;
 }
@@ -873,17 +1025,17 @@ static int decode_frame(WmallDecodeCtx *s)
 
     /** get frame length */
     if (s->len_prefix)
-        len = get_bits(gb, s->log2_frame_size);
+        len = get_bits(gb, s->log2_frame_size);     // XXX: compressed_frame_size_bits [Table 8]
 
     /** decode tile information */
-    if (decode_tilehdr(s)) {
+    if (decode_tilehdr(s)) {    // should include decode_tile_configuration() [Table 9]
         s->packet_loss = 1;
         return 0;
     }
 
     /** read drc info */
     if (s->dynamic_range_compression) {
-        s->drc_gain = get_bits(gb, 8);
+        s->drc_gain = get_bits(gb, 8);      // XXX: drc_frame_scale_factor [Table 8]
     }
 
     /** no idea what these are for, might be the number of samples