Fix inverse-MCLMS filtering routines

parent 4fa3f1c5
...@@ -787,36 +787,35 @@ static void reset_codec(WmallDecodeCtx *s) ...@@ -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; int i, j, ich;
int16_t pred_error; int pred_error;
int order = s->mclms_order; int order = s->mclms_order;
int num_channels = s->num_channels; 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 int bps = s->bits_per_sample > 16 ? 4 : 2; // bytes per sample
for (ich = 0; ich < num_channels; ich++) { for (ich = 0; ich < num_channels; ich++) {
pred_error = s->channel_coeffs[ich][icoef] - pred_error = s->channel_residues[ich][icoef] - pred[ich];
s->channel_residues[ich][icoef];
if (pred_error > 0) { if (pred_error > 0) {
for (i = 0; i < order * num_channels; i++) for (i = 0; i < order * num_channels; i++)
s->mclms_coeffs[i + ich * order * num_channels] += s->mclms_coeffs[i + ich * order * num_channels] +=
s->mclms_updates[s->mclms_recent + i]; s->mclms_updates[s->mclms_recent + i];
for (j = 0; j < i; j++) { for (j = 0; j < ich; j++) {
if (s->channel_coeffs[ich][icoef] > 0) if (s->channel_residues[j][icoef] > 0)
s->mclms_coeffs_cur[ich * num_channels + j] += 1; 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; s->mclms_coeffs_cur[ich * num_channels + j] -= 1;
} }
} else if (pred_error < 0) { } else if (pred_error < 0) {
for (i = 0; i < order * num_channels; i++) for (i = 0; i < order * num_channels; i++)
s->mclms_coeffs[i + ich * order * num_channels] -= s->mclms_coeffs[i + ich * order * num_channels] -=
s->mclms_updates[s->mclms_recent + i]; s->mclms_updates[s->mclms_recent + i];
for (j = 0; j < i; j++) { for (j = 0; j < ich; j++) {
if (s->channel_coeffs[ich][icoef] > 0) if (s->channel_residues[j][icoef] > 0)
s->mclms_coeffs_cur[ich * num_channels + j] -= 1; 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; s->mclms_coeffs_cur[ich * num_channels + j] += 1;
} }
} }
...@@ -824,13 +823,17 @@ static void mclms_update(WmallDecodeCtx *s, int icoef) ...@@ -824,13 +823,17 @@ static void mclms_update(WmallDecodeCtx *s, int icoef)
for (ich = num_channels - 1; ich >= 0; ich--) { for (ich = num_channels - 1; ich >= 0; ich--) {
s->mclms_recent--; 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; 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_prevvalues[s->mclms_recent] = -range;
s->mclms_updates[s->mclms_recent] = s->mclms_updates[s->mclms_recent] = 0;
av_clip(-1, s->channel_coeffs[ich][icoef], 1); 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) { if (s->mclms_recent == 0) {
...@@ -843,34 +846,35 @@ static void mclms_update(WmallDecodeCtx *s, int icoef) ...@@ -843,34 +846,35 @@ static void mclms_update(WmallDecodeCtx *s, int icoef)
s->mclms_recent = num_channels * order; 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; int ich, i;
int16_t pred;
int order = s->mclms_order; int order = s->mclms_order;
int num_channels = s->num_channels; int num_channels = s->num_channels;
for (ich = 0; ich < num_channels; ich++) { for (ich = 0; ich < num_channels; ich++) {
if (!s->is_channel_coded[ich]) if (!s->is_channel_coded[ich])
continue; continue;
pred = 0; pred[ich] = 0;
for (i = 0; i < order * num_channels; i++) for (i = 0; i < order * num_channels; i++)
pred += s->mclms_prevvalues[i] * pred[ich] += s->mclms_prevvalues[i + s->mclms_recent] *
s->mclms_coeffs[i + order * num_channels * ich]; s->mclms_coeffs[i + order * num_channels * ich];
for (i = 0; i < ich; i++) for (i = 0; i < ich; i++)
pred += s->channel_coeffs[ich][icoef] * pred[ich] += s->channel_residues[i][icoef] *
s->mclms_coeffs_cur[i + order * num_channels * ich]; s->mclms_coeffs_cur[i + num_channels * ich];
s->channel_coeffs[ich][icoef] = pred[ich] += 1 << s->mclms_scaling - 1;
s->channel_residues[ich][icoef] + pred; pred[ich] >>= s->mclms_scaling;
s->channel_residues[ich][icoef] += pred[ich];
} }
} }
static void revert_mclms(WmallDecodeCtx *s, int tile_size) static void revert_mclms(WmallDecodeCtx *s, int tile_size)
{ {
int icoef; int icoef, pred[s->num_channels];
for (icoef = 0; icoef < tile_size; icoef++) { for (icoef = 0; icoef < tile_size; icoef++) {
mclms_predict(s, icoef); mclms_predict(s, icoef, pred);
mclms_update(s, icoef); mclms_update(s, icoef, pred);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment