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
*/
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
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;
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];
#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
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;
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);
*@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 */
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 {
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;
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))
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;
}
+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).
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");
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);
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;
}
/** 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