summaryrefslogtreecommitdiff
path: root/libavcodec/wmalosslessdec.c
diff options
context:
space:
mode:
authorMashiat Sarker Shakkhar <shahriman_ams@yahoo.com>2011-12-22 23:48:02 +0600
committerMashiat Sarker Shakkhar <shahriman_ams@yahoo.com>2011-12-22 23:48:02 +0600
commit302d5df834e56ade38ef27397385c0c815d501d4 (patch)
treedd9353e9a6505cd1bebd0f2509addd9430e5c39b /libavcodec/wmalosslessdec.c
parent4fa3f1c50718622ca04298d2d01b5a4c7d319cbf (diff)
Fix inverse-MCLMS filtering routines
Diffstat (limited to 'libavcodec/wmalosslessdec.c')
-rw-r--r--libavcodec/wmalosslessdec.c58
1 files changed, 31 insertions, 27 deletions
diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index c61e39645a..29dce56510 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -787,36 +787,35 @@ static void reset_codec(WmallDecodeCtx *s)
-static void mclms_update(WmallDecodeCtx *s, int icoef)
+static void mclms_update(WmallDecodeCtx *s, int icoef, int *pred)
{
int i, j, ich;
- int16_t pred_error;
+ int pred_error;
int order = s->mclms_order;
int num_channels = s->num_channels;
- int16_t range = 1 << (s->bits_per_sample - 1);
+ int 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];
+ pred_error = s->channel_residues[ich][icoef] - pred[ich];
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)
+ for (j = 0; j < ich; j++) {
+ if (s->channel_residues[j][icoef] > 0)
s->mclms_coeffs_cur[ich * num_channels + j] += 1;
- else if (s->channel_coeffs[ich][icoef] < 0)
+ else if (s->channel_residues[j][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)
+ for (j = 0; j < ich; j++) {
+ if (s->channel_residues[j][icoef] > 0)
s->mclms_coeffs_cur[ich * num_channels + j] -= 1;
- else if (s->channel_coeffs[ich][icoef] < 0)
+ else if (s->channel_residues[j][icoef] < 0)
s->mclms_coeffs_cur[ich * num_channels + j] += 1;
}
}
@@ -824,13 +823,17 @@ static void mclms_update(WmallDecodeCtx *s, int icoef)
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] = s->channel_residues[ich][icoef];
+ if (s->channel_residues[ich][icoef] > range - 1)
s->mclms_prevvalues[s->mclms_recent] = range - 1;
- else if (s->channel_coeffs[ich][icoef] <= -range)
+ else if (s->channel_residues[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);
+ s->mclms_updates[s->mclms_recent] = 0;
+ if (s->channel_residues[ich][icoef] > 0)
+ s->mclms_updates[s->mclms_recent] = 1;
+ else if (s->channel_residues[ich][icoef] < 0)
+ s->mclms_updates[s->mclms_recent] = -1;
}
if (s->mclms_recent == 0) {
@@ -843,34 +846,35 @@ static void mclms_update(WmallDecodeCtx *s, int icoef)
s->mclms_recent = num_channels * order;
}
}
-static void mclms_predict(WmallDecodeCtx *s, int icoef)
+
+static void mclms_predict(WmallDecodeCtx *s, int icoef, int *pred)
{
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;
+ pred[ich] = 0;
for (i = 0; i < order * num_channels; i++)
- pred += s->mclms_prevvalues[i] *
- s->mclms_coeffs[i + order * num_channels * ich];
+ pred[ich] += s->mclms_prevvalues[i + s->mclms_recent] *
+ 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;
+ pred[ich] += s->channel_residues[i][icoef] *
+ s->mclms_coeffs_cur[i + num_channels * ich];
+ pred[ich] += 1 << s->mclms_scaling - 1;
+ pred[ich] >>= s->mclms_scaling;
+ s->channel_residues[ich][icoef] += pred[ich];
}
}
static void revert_mclms(WmallDecodeCtx *s, int tile_size)
{
- int icoef;
+ int icoef, pred[s->num_channels];
for (icoef = 0; icoef < tile_size; icoef++) {
- mclms_predict(s, icoef);
- mclms_update(s, icoef);
+ mclms_predict(s, icoef, pred);
+ mclms_update(s, icoef, pred);
}
}