Commit da136c7e authored by Sascha Sommer's avatar Sascha Sommer

add approved hunks of the wmapro decoder

Originally committed as revision 19563 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 577d383b
...@@ -201,6 +201,7 @@ Codecs: ...@@ -201,6 +201,7 @@ Codecs:
vp6 Aurelien Jacobs vp6 Aurelien Jacobs
vqavideo.c Mike Melanson vqavideo.c Mike Melanson
wavpack.c Kostya Shishkov wavpack.c Kostya Shishkov
wmaprodec.c Sascha Sommer
wmv2.c Michael Niedermayer wmv2.c Michael Niedermayer
wnv1.c Kostya Shishkov wnv1.c Kostya Shishkov
xan.c Mike Melanson xan.c Mike Melanson
......
This diff is collapsed.
/**
*@brief Uninitialize the decoder and free all resources.
*@param avctx codec context
*@return 0 on success, < 0 otherwise
*/
static av_cold int decode_end(AVCodecContext *avctx)
{
WMA3DecodeContext *s = avctx->priv_data;
int i;
av_freep(&s->num_sfb);
av_freep(&s->sfb_offsets);
av_freep(&s->subwoofer_cutoffs);
av_freep(&s->sf_offsets);
for (i=0 ; i<WMAPRO_BLOCK_SIZES ; i++)
ff_mdct_end(&s->mdct_ctx[i]);
return 0;
}
/**
*@brief Calculate a decorrelation matrix from the bitstream parameters.
*@param s codec context
*@param chgroup channel group for which the matrix needs to be calculated
*/
static void decode_decorrelation_matrix(WMA3DecodeContext* s,
WMA3ChannelGroup* chgroup)
{
int i;
int offset = 0;
int8_t rotation_offset[WMAPRO_MAX_CHANNELS * WMAPRO_MAX_CHANNELS];
memset(chgroup->decorrelation_matrix,0,
sizeof(float) *s->num_channels * s->num_channels);
for (i=0;i<chgroup->num_channels * (chgroup->num_channels - 1) >> 1;i++)
rotation_offset[i] = get_bits(&s->gb,6);
for (i=0;i<chgroup->num_channels;i++)
chgroup->decorrelation_matrix[chgroup->num_channels * i + i] =
get_bits1(&s->gb) ? 1.0 : -1.0;
for (i=1;i<chgroup->num_channels;i++) {
int x;
for (x=0;x<i;x++) {
int y;
for (y=0;y < i + 1 ; y++) {
float v1 = chgroup->decorrelation_matrix[x * chgroup->num_channels + y];
float v2 = chgroup->decorrelation_matrix[i * chgroup->num_channels + y];
int n = rotation_offset[offset + x];
float sinv;
float cosv;
if (n<32) {
sinv = sin64[n];
cosv = sin64[32-n];
} else {
sinv = sin64[64-n];
cosv = -sin64[n-32];
}
chgroup->decorrelation_matrix[y + x * chgroup->num_channels] =
(v1 * sinv) - (v2 * cosv);
chgroup->decorrelation_matrix[y + i * chgroup->num_channels] =
(v1 * cosv) + (v2 * sinv);
}
}
offset += i;
}
}
/**
*@brief Reconstruct the individual channel data.
*@param s codec context
*/
static void inverse_channel_transform(WMA3DecodeContext *s)
{
int i;
for (i=0;i<s->num_chgroups;i++) {
if (s->chgroup[i].transform == 1) {
/** M/S stereo decoding */
int16_t* sfb_offsets = s->cur_sfb_offsets;
float* ch0 = *sfb_offsets + s->channel[0].coeffs;
float* ch1 = *sfb_offsets++ + s->channel[1].coeffs;
const char* tb = s->chgroup[i].transform_band;
const char* tb_end = tb + s->num_bands;
while (tb < tb_end) {
const float* ch0_end = s->channel[0].coeffs +
FFMIN(*sfb_offsets,s->subframe_len);
if (*tb++ == 1) {
while (ch0 < ch0_end) {
const float v1 = *ch0;
const float v2 = *ch1;
*ch0++ = v1 - v2;
*ch1++ = v1 + v2;
}
} else {
while (ch0 < ch0_end) {
*ch0++ *= 181.0 / 128;
*ch1++ *= 181.0 / 128;
}
}
++sfb_offsets;
}
} else if (s->chgroup[i].transform) {
float data[WMAPRO_MAX_CHANNELS];
const int num_channels = s->chgroup[i].num_channels;
float** ch_data = s->chgroup[i].channel_data;
float** ch_end = ch_data + num_channels;
const int8_t* tb = s->chgroup[i].transform_band;
int16_t* sfb;
/** multichannel decorrelation */
for (sfb = s->cur_sfb_offsets ;
sfb < s->cur_sfb_offsets + s->num_bands;sfb++) {
if (*tb++ == 1) {
int y;
/** multiply values with the decorrelation_matrix */
for (y=sfb[0];y<FFMIN(sfb[1], s->subframe_len);y++) {
const float* mat = s->chgroup[i].decorrelation_matrix;
const float* data_end= data + num_channels;
float* data_ptr= data;
float** ch;
for (ch = ch_data;ch < ch_end; ch++)
*data_ptr++ = (*ch)[y];
for (ch = ch_data; ch < ch_end; ch++) {
float sum = 0;
data_ptr = data;
while (data_ptr < data_end)
sum += *data_ptr++ * *mat++;
(*ch)[y] = sum;
}
}
}
}
}
}
}
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