mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
Merge remote-tracking branch 'shariman/wmall'
* shariman/wmall: Perform dequantization of channel coefficients Perform inverse inter-channel decorrelation and ac-filter Implement revert_inter_ch_decorr() and revert_acfilter() Enable inverse-MCLMS filter Fix inverse-MCLMS filtering routines Do not update buffers in case no speed change is necessary Use int for channel_coeffs instead of int16_t Conflicts: libavcodec/wmalosslessdec.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
28dff06176
@ -232,6 +232,7 @@ typedef struct WmallDecodeCtx {
|
||||
int8_t acfilter_order;
|
||||
int8_t acfilter_scaling;
|
||||
int acfilter_coeffs[16];
|
||||
int acfilter_prevvalues[16];
|
||||
|
||||
int8_t mclms_order;
|
||||
int8_t mclms_scaling;
|
||||
@ -279,7 +280,7 @@ typedef struct WmallDecodeCtx {
|
||||
int lpc_scaling;
|
||||
int lpc_intbits;
|
||||
|
||||
int16_t channel_coeffs[2][2048]; // FIXME: should be 32-bit / 16-bit depending on bit-depth
|
||||
int channel_coeffs[2][2048]; // FIXME: should be 32-bit / 16-bit depending on bit-depth
|
||||
|
||||
} WmallDecodeCtx;
|
||||
|
||||
@ -787,36 +788,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 +824,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 +847,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -948,9 +953,10 @@ static void lms_update(WmallDecodeCtx *s, int ich, int ilms, int input, int resi
|
||||
static void use_high_update_speed(WmallDecodeCtx *s, int ich)
|
||||
{
|
||||
int ilms, recent, icoef;
|
||||
s->update_speed[ich] = 16;
|
||||
for (ilms = s->cdlms_ttl[ich] - 1; ilms >= 0; ilms--) {
|
||||
recent = s->cdlms[ich][ilms].recent;
|
||||
if (s->update_speed[ich] == 16)
|
||||
continue;
|
||||
if (s->bV3RTM) {
|
||||
for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
|
||||
s->cdlms[ich][ilms].lms_updates[icoef + recent] *= 2;
|
||||
@ -959,14 +965,16 @@ static void use_high_update_speed(WmallDecodeCtx *s, int ich)
|
||||
s->cdlms[ich][ilms].lms_updates[icoef] *= 2;
|
||||
}
|
||||
}
|
||||
s->update_speed[ich] = 16;
|
||||
}
|
||||
|
||||
static void use_normal_update_speed(WmallDecodeCtx *s, int ich)
|
||||
{
|
||||
int ilms, recent, icoef;
|
||||
s->update_speed[ich] = 8;
|
||||
for (ilms = s->cdlms_ttl[ich] - 1; ilms >= 0; ilms--) {
|
||||
recent = s->cdlms[ich][ilms].recent;
|
||||
if (s->update_speed[ich] == 8)
|
||||
continue;
|
||||
if (s->bV3RTM) {
|
||||
for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++)
|
||||
s->cdlms[ich][ilms].lms_updates[icoef + recent] /= 2;
|
||||
@ -975,6 +983,7 @@ static void use_normal_update_speed(WmallDecodeCtx *s, int ich)
|
||||
s->cdlms[ich][ilms].lms_updates[icoef] /= 2;
|
||||
}
|
||||
}
|
||||
s->update_speed[ich] = 8;
|
||||
}
|
||||
|
||||
static void revert_cdlms(WmallDecodeCtx *s, int ch, int coef_begin, int coef_end)
|
||||
@ -998,7 +1007,41 @@ static void revert_cdlms(WmallDecodeCtx *s, int ch, int coef_begin, int coef_end
|
||||
}
|
||||
}
|
||||
|
||||
static void revert_inter_ch_decorr(WmallDecodeCtx *s, int tile_size)
|
||||
{
|
||||
int icoef;
|
||||
if (s->num_channels != 2)
|
||||
return;
|
||||
else {
|
||||
for (icoef = 0; icoef < tile_size; icoef++) {
|
||||
s->channel_residues[0][icoef] -= s->channel_residues[1][icoef] >> 1;
|
||||
s->channel_residues[1][icoef] += s->channel_residues[0][icoef];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void revert_acfilter(WmallDecodeCtx *s, int tile_size)
|
||||
{
|
||||
int ich, icoef;
|
||||
int pred = 0, itap;
|
||||
int **ch_coeffs = s->channel_residues;
|
||||
int *filter_coeffs = s->acfilter_coeffs;
|
||||
int *prevvalues = s->acfilter_prevvalues;
|
||||
int scaling = s->acfilter_scaling;
|
||||
int order = s->acfilter_order;
|
||||
|
||||
for (ich = 0; ich < s->num_channels; ich++) {
|
||||
for (icoef = 0; icoef < tile_size; icoef++) {
|
||||
for (itap = 0; itap < order; itap++)
|
||||
pred += filter_coeffs[itap] * prevvalues[itap];
|
||||
pred >>= scaling;
|
||||
ch_coeffs[ich][icoef] += pred;
|
||||
for (itap = 1; itap < order; itap++)
|
||||
prevvalues[itap] = prevvalues[itap - 1];
|
||||
prevvalues[0] = ch_coeffs[ich][icoef];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*@brief Decode a single subframe (block).
|
||||
@ -1009,10 +1052,11 @@ static int decode_subframe(WmallDecodeCtx *s)
|
||||
{
|
||||
int offset = s->samples_per_frame;
|
||||
int subframe_len = s->samples_per_frame;
|
||||
int i;
|
||||
int i, j;
|
||||
int total_samples = s->samples_per_frame * s->num_channels;
|
||||
int rawpcm_tile;
|
||||
int padding_zeroes;
|
||||
int quant_stepsize = s->quant_stepsize;
|
||||
|
||||
s->subframe_offset = get_bits_count(&s->gb);
|
||||
|
||||
@ -1112,7 +1156,6 @@ static int decode_subframe(WmallDecodeCtx *s)
|
||||
if(rawpcm_tile) {
|
||||
|
||||
int bits = s->bits_per_sample - padding_zeroes;
|
||||
int j;
|
||||
dprintf(s->avctx, "RAWPCM %d bits per sample. total %d bits, remain=%d\n", bits,
|
||||
bits * s->num_channels * subframe_len, get_bits_count(&s->gb));
|
||||
for(i = 0; i < s->num_channels; i++) {
|
||||
@ -1132,6 +1175,17 @@ static int decode_subframe(WmallDecodeCtx *s)
|
||||
revert_cdlms(s, i, 0, subframe_len);
|
||||
}
|
||||
}
|
||||
if (s->do_mclms)
|
||||
revert_mclms(s, subframe_len);
|
||||
if (s->do_inter_ch_decorr)
|
||||
revert_inter_ch_decorr(s, subframe_len);
|
||||
if(s->do_ac_filter)
|
||||
revert_acfilter(s, subframe_len);
|
||||
|
||||
/* Dequantize */
|
||||
for (i = 0; i < s->num_channels; i++)
|
||||
for (j = 0; j < subframe_len; j++)
|
||||
s->channel_residues[i][j] *= quant_stepsize;
|
||||
|
||||
/** handled one subframe */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user