Browse Source

Implement lms_update()

(cherry picked from commit 17219c7936)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
tags/n0.9
Mashiat Sarker Shakkhar Michael Niedermayer 14 years ago
parent
commit
80fa79a306
1 changed files with 49 additions and 0 deletions
  1. +49
    -0
      libavcodec/wmalosslessdec.c

+ 49
- 0
libavcodec/wmalosslessdec.c View File

@@ -774,6 +774,55 @@ static int lms_predict(WmallDecodeCtx *s, int ich, int ilms)
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;
}
}

/**
*@brief Decode a single subframe (block).
*@param s codec context


Loading…
Cancel
Save