Merge remote-tracking branch 'shariman/wmall'
* shariman/wmall: Fix lms_update() Move num_lms reading out of a loop Use correct value for range Fix some int / int16_t / int32_t confusion Implement revert_mclms() and associated functions Fix two more int16_t vs. int confusion Init s->cdlms[][].recent to order - 1 Add a size argument to dump_int_buffer() Get rid of logging that are not required anymore Fix some int vs. int16_t confusion Conflicts: libavcodec/wmalosslessdec.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
1fa8ff38e4
@ -237,7 +237,7 @@ typedef struct WmallDecodeCtx {
|
|||||||
int8_t mclms_scaling;
|
int8_t mclms_scaling;
|
||||||
int16_t mclms_coeffs[128];
|
int16_t mclms_coeffs[128];
|
||||||
int16_t mclms_coeffs_cur[4];
|
int16_t mclms_coeffs_cur[4];
|
||||||
int mclms_prevvalues[64]; // FIXME: should be 32-bit / 16-bit depending on bit-depth
|
int16_t mclms_prevvalues[64]; // FIXME: should be 32-bit / 16-bit depending on bit-depth
|
||||||
int16_t mclms_updates[64];
|
int16_t mclms_updates[64];
|
||||||
int mclms_recent;
|
int mclms_recent;
|
||||||
|
|
||||||
@ -250,7 +250,7 @@ typedef struct WmallDecodeCtx {
|
|||||||
int coefsend;
|
int coefsend;
|
||||||
int bitsend;
|
int bitsend;
|
||||||
int16_t coefs[256];
|
int16_t coefs[256];
|
||||||
int lms_prevvalues[512]; // FIXME: see above
|
int16_t lms_prevvalues[512]; // FIXME: see above
|
||||||
int16_t lms_updates[512]; // and here too
|
int16_t lms_updates[512]; // and here too
|
||||||
int recent;
|
int recent;
|
||||||
} cdlms[2][9]; /* XXX: Here, 2 is the max. no. of channels allowed,
|
} cdlms[2][9]; /* XXX: Here, 2 is the max. no. of channels allowed,
|
||||||
@ -279,7 +279,7 @@ typedef struct WmallDecodeCtx {
|
|||||||
int lpc_scaling;
|
int lpc_scaling;
|
||||||
int lpc_intbits;
|
int lpc_intbits;
|
||||||
|
|
||||||
int channel_coeffs[2][2048];
|
int16_t channel_coeffs[2][2048]; // FIXME: should be 32-bit / 16-bit depending on bit-depth
|
||||||
|
|
||||||
} WmallDecodeCtx;
|
} WmallDecodeCtx;
|
||||||
|
|
||||||
@ -289,6 +289,8 @@ typedef struct WmallDecodeCtx {
|
|||||||
|
|
||||||
|
|
||||||
static int num_logged_tiles = 0;
|
static int num_logged_tiles = 0;
|
||||||
|
static int num_logged_subframes = 0;
|
||||||
|
static int num_lms_update_call = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*@brief helper function to print the most important members of the context
|
*@brief helper function to print the most important members of the context
|
||||||
@ -308,14 +310,14 @@ static void av_cold dump_context(WmallDecodeCtx *s)
|
|||||||
PRINT("num channels", s->num_channels);
|
PRINT("num channels", s->num_channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_int_buffer(int *buffer, int length, int delimiter)
|
static void dump_int_buffer(uint8_t *buffer, int size, int length, int delimiter)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0 ; i<length ; i++) {
|
for (i=0 ; i<length ; i++) {
|
||||||
if (!(i%delimiter))
|
if (!(i%delimiter))
|
||||||
av_log(0, 0, "\n[%d] ", i);
|
av_log(0, 0, "\n[%d] ", i);
|
||||||
av_log(0, 0, "%d, ", buffer[i]);
|
av_log(0, 0, "%d, ", *(int16_t *)(buffer + i * size));
|
||||||
}
|
}
|
||||||
av_log(0, 0, "\n");
|
av_log(0, 0, "\n");
|
||||||
|
|
||||||
@ -716,11 +718,8 @@ static int decode_channel_residues(WmallDecodeCtx *s, int ch, int tile_size)
|
|||||||
else
|
else
|
||||||
residue = residue >> 1;
|
residue = residue >> 1;
|
||||||
s->channel_residues[ch][i] = residue;
|
s->channel_residues[ch][i] = residue;
|
||||||
|
|
||||||
/*if (num_logged_tiles < 1)
|
|
||||||
av_log(0, 0, "%4d ", residue); */
|
|
||||||
}
|
}
|
||||||
dump_int_buffer(s->channel_residues[ch], tile_size, 16);
|
dump_int_buffer(s->channel_residues[ch], 4, tile_size, 16);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -761,7 +760,7 @@ static void clear_codec_buffers(WmallDecodeCtx *s)
|
|||||||
for (ich = 0; ich < s->num_channels; ich++) {
|
for (ich = 0; ich < s->num_channels; ich++) {
|
||||||
for (ilms = 0; ilms < s->cdlms_ttl[ich]; ilms++) {
|
for (ilms = 0; ilms < s->cdlms_ttl[ich]; ilms++) {
|
||||||
memset(s->cdlms[ich][ilms].coefs , 0, 256 * sizeof(int16_t));
|
memset(s->cdlms[ich][ilms].coefs , 0, 256 * sizeof(int16_t));
|
||||||
memset(s->cdlms[ich][ilms].lms_prevvalues, 0, 512 * sizeof(int));
|
memset(s->cdlms[ich][ilms].lms_prevvalues, 0, 512 * sizeof(int16_t));
|
||||||
memset(s->cdlms[ich][ilms].lms_updates , 0, 512 * sizeof(int16_t));
|
memset(s->cdlms[ich][ilms].lms_updates , 0, 512 * sizeof(int16_t));
|
||||||
}
|
}
|
||||||
s->ave_sum[ich] = 0;
|
s->ave_sum[ich] = 0;
|
||||||
@ -777,7 +776,7 @@ static void reset_codec(WmallDecodeCtx *s)
|
|||||||
s->mclms_recent = s->mclms_order * s->num_channels;
|
s->mclms_recent = s->mclms_order * s->num_channels;
|
||||||
for (ich = 0; ich < s->num_channels; ich++) {
|
for (ich = 0; ich < s->num_channels; ich++) {
|
||||||
for (ilms = 0; ilms < s->cdlms_ttl[ich]; ilms++)
|
for (ilms = 0; ilms < s->cdlms_ttl[ich]; ilms++)
|
||||||
s->cdlms[ich][ilms].recent = s->cdlms[ich][ilms].order;
|
s->cdlms[ich][ilms].recent = s->cdlms[ich][ilms].order - 1;
|
||||||
/* first sample of a seekable subframe is considered as the starting of
|
/* first sample of a seekable subframe is considered as the starting of
|
||||||
a transient area which is samples_per_frame samples long */
|
a transient area which is samples_per_frame samples long */
|
||||||
s->channel[ich].transient_counter = s->samples_per_frame;
|
s->channel[ich].transient_counter = s->samples_per_frame;
|
||||||
@ -787,9 +786,97 @@ 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)
|
static int lms_predict(WmallDecodeCtx *s, int ich, int ilms)
|
||||||
{
|
{
|
||||||
int32_t pred = 0, icoef;
|
int16_t pred = 0;
|
||||||
|
int icoef;
|
||||||
int recent = s->cdlms[ich][ilms].recent;
|
int recent = s->cdlms[ich][ilms].recent;
|
||||||
|
|
||||||
for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
|
for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
|
||||||
@ -804,21 +891,23 @@ static int lms_predict(WmallDecodeCtx *s, int ich, int ilms)
|
|||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lms_update(WmallDecodeCtx *s, int ich, int ilms, int32_t input, int32_t pred)
|
static void lms_update(WmallDecodeCtx *s, int ich, int ilms, int16_t residue, int16_t pred)
|
||||||
{
|
{
|
||||||
int icoef;
|
int16_t icoef;
|
||||||
int recent = s->cdlms[ich][ilms].recent;
|
int recent = s->cdlms[ich][ilms].recent;
|
||||||
int range = 1 << (s->bits_per_sample - 1);
|
int16_t range = (1 << s->bits_per_sample - 1) - 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
|
||||||
|
int16_t input = residue + pred;
|
||||||
|
|
||||||
if (input > pred) {
|
if (residue > 0) {
|
||||||
for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
|
for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
|
||||||
s->cdlms[ich][ilms].coefs[icoef] +=
|
s->cdlms[ich][ilms].coefs[icoef] +=
|
||||||
s->cdlms[ich][ilms].lms_updates[icoef + recent];
|
s->cdlms[ich][ilms].lms_updates[icoef + recent];
|
||||||
} else {
|
} else {
|
||||||
for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
|
for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
|
||||||
s->cdlms[ich][ilms].coefs[icoef] -=
|
s->cdlms[ich][ilms].coefs[icoef] -=
|
||||||
s->cdlms[ich][ilms].lms_updates[icoef]; // XXX: [icoef + recent] ?
|
s->cdlms[ich][ilms].lms_updates[icoef + recent]; /* spec mistakenly
|
||||||
|
dropped the recent */
|
||||||
}
|
}
|
||||||
s->cdlms[ich][ilms].recent--;
|
s->cdlms[ich][ilms].recent--;
|
||||||
s->cdlms[ich][ilms].lms_prevvalues[recent] = av_clip(input, -range, range - 1);
|
s->cdlms[ich][ilms].lms_prevvalues[recent] = av_clip(input, -range, range - 1);
|
||||||
@ -888,14 +977,14 @@ static void use_normal_update_speed(WmallDecodeCtx *s, int ich)
|
|||||||
static void revert_cdlms(WmallDecodeCtx *s, int tile_size)
|
static void revert_cdlms(WmallDecodeCtx *s, int tile_size)
|
||||||
{
|
{
|
||||||
int icoef, ich;
|
int icoef, ich;
|
||||||
int32_t pred, channel_coeff;
|
int16_t pred, channel_coeff;
|
||||||
int ilms, num_lms;
|
int ilms, num_lms;
|
||||||
|
|
||||||
for (ich = 0; ich < s->num_channels; ich++) {
|
for (ich = 0; ich < s->num_channels; ich++) {
|
||||||
if (!s->is_channel_coded[ich])
|
if (!s->is_channel_coded[ich])
|
||||||
continue;
|
continue;
|
||||||
for (icoef = 0; icoef < tile_size; icoef++) {
|
|
||||||
num_lms = s->cdlms_ttl[ich];
|
num_lms = s->cdlms_ttl[ich];
|
||||||
|
for (icoef = 0; icoef < tile_size; icoef++) {
|
||||||
channel_coeff = s->channel_residues[ich][icoef];
|
channel_coeff = s->channel_residues[ich][icoef];
|
||||||
if (icoef == s->transient_pos[ich]) {
|
if (icoef == s->transient_pos[ich]) {
|
||||||
s->transient[ich] = 1;
|
s->transient[ich] = 1;
|
||||||
@ -903,8 +992,8 @@ static void revert_cdlms(WmallDecodeCtx *s, int tile_size)
|
|||||||
}
|
}
|
||||||
for (ilms = num_lms - 1; ilms >= 0; ilms--) {
|
for (ilms = num_lms - 1; ilms >= 0; ilms--) {
|
||||||
pred = lms_predict(s, ich, ilms);
|
pred = lms_predict(s, ich, ilms);
|
||||||
channel_coeff += pred;
|
|
||||||
lms_update(s, ich, ilms, channel_coeff, pred);
|
lms_update(s, ich, ilms, channel_coeff, pred);
|
||||||
|
channel_coeff += pred;
|
||||||
}
|
}
|
||||||
if (s->transient[ich]) {
|
if (s->transient[ich]) {
|
||||||
--s->channel[ich].transient_counter;
|
--s->channel[ich].transient_counter;
|
||||||
@ -1056,6 +1145,7 @@ static int decode_subframe(WmallDecodeCtx *s)
|
|||||||
}
|
}
|
||||||
++s->channel[c].cur_subframe;
|
++s->channel[c].cur_subframe;
|
||||||
}
|
}
|
||||||
|
num_logged_subframes++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user