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); } }