diff options
author | Mashiat Sarker Shakkhar <shahriman_ams@yahoo.com> | 2011-11-30 22:41:12 +0600 |
---|---|---|
committer | Mashiat Sarker Shakkhar <shahriman_ams@yahoo.com> | 2011-11-30 22:44:59 +0600 |
commit | 8aa831c07b47c4f384919cd38930ac64ce04b05b (patch) | |
tree | 2a8211c5b1c018fa230126cfa17e91ef2ef942e5 /libavcodec/wmalosslessdec.c | |
parent | bf8715719a3ec85010e7f909c0cdafb265f50fea (diff) | |
download | ffmpeg-8aa831c07b47c4f384919cd38930ac64ce04b05b.tar.gz |
Implement revert_mclms() and associated functions
Diffstat (limited to 'libavcodec/wmalosslessdec.c')
-rw-r--r-- | libavcodec/wmalosslessdec.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c index 2a0789bdf0..795fcaed47 100644 --- a/libavcodec/wmalosslessdec.c +++ b/libavcodec/wmalosslessdec.c @@ -786,6 +786,93 @@ static void reset_codec(WmallDecodeCtx *s) +static void mclms_update(WmallDecodeCtx *s, int icoef) +{ + int i, j, ich; + int16_t pred_error; + int order = s->mclms_order; + int num_channels = s->num_channels; + int16_t range = 1 << (s->bits_per_sample - 1); + int bps = s->bits_per_sample > 16 ? 4 : 2; // bytes per sample + + for (ich = 0; ich < num_channels; ich++) { + pred_error = s->channel_coeffs[ich][icoef] - + s->channel_residues[ich][icoef]; + if (pred_error > 0) { + for (i = 0; i < order * num_channels; i++) + s->mclms_coeffs[i + ich * order * num_channels] += + s->mclms_updates[s->mclms_recent + i]; + for (j = 0; j < i; j++) { + if (s->channel_coeffs[ich][icoef] > 0) + s->mclms_coeffs_cur[ich * num_channels + j] += 1; + else if (s->channel_coeffs[ich][icoef] < 0) + s->mclms_coeffs_cur[ich * num_channels + j] -= 1; + } + } else if (pred_error < 0) { + for (i = 0; i < order * num_channels; i++) + s->mclms_coeffs[i + ich * order * num_channels] -= + s->mclms_updates[s->mclms_recent + i]; + for (j = 0; j < i; j++) { + if (s->channel_coeffs[ich][icoef] > 0) + s->mclms_coeffs_cur[ich * num_channels + j] -= 1; + else if (s->channel_coeffs[ich][icoef] < 0) + s->mclms_coeffs_cur[ich * num_channels + j] += 1; + } + } + } + + for (ich = num_channels - 1; ich >= 0; ich--) { + s->mclms_recent--; + if (s->channel_coeffs[ich][icoef] > range - 1) + s->mclms_prevvalues[s->mclms_recent] = range - 1; + else if (s->channel_coeffs[ich][icoef] <= -range) + s->mclms_prevvalues[s->mclms_recent] = -range; + + s->mclms_updates[s->mclms_recent] = + av_clip(-1, s->channel_coeffs[ich][icoef], 1); + } + + if (s->mclms_recent == 0) { + memcpy(s->mclms_prevvalues[order * num_channels], + s->mclms_prevvalues, + bps * order * num_channels); + memcpy(s->mclms_updates[order * num_channels], + s->mclms_updates, + bps * order * num_channels); + s->mclms_recent = num_channels * order; + } +} +static void mclms_predict(WmallDecodeCtx *s, int icoef) +{ + int ich, i; + int16_t pred; + int order = s->mclms_order; + int num_channels = s->num_channels; + + for (ich = 0; ich < num_channels; ich++) { + if (!s->is_channel_coded[ich]) + continue; + pred = 0; + for (i = 0; i < order * num_channels; i++) + pred += s->mclms_prevvalues[i] * + s->mclms_coeffs[i + order * num_channels * ich]; + for (i = 0; i < ich; i++) + pred += s->channel_coeffs[ich][icoef] * + s->mclms_coeffs_cur[i + order * num_channels * ich]; + s->channel_coeffs[ich][icoef] = + s->channel_residues[ich][icoef] + pred; + } +} + +static void revert_mclms(WmallDecodeCtx *s, int tile_size) +{ + int icoef; + for (icoef = 0; icoef < tile_size; icoef++) { + mclms_predict(s, icoef); + mclms_update(s, icoef); + } +} + static int lms_predict(WmallDecodeCtx *s, int ich, int ilms) { int16_t pred = 0, icoef; |