annotate wmaprodec.c @ 10061:09f2db2d7c90 libavcodec

Fix bug caused by difference in stride and picture width. When a frame is allocated using libschroedinger routines, the frame data size does not match the actual frame size if the width is not a multiple of 16. So we cannot do a straightforward memcpy of the frame returned by libschroedinger into the FFmpeg picture as the stride differs from the width. Fix this bug by allocating for the libschroedinger frame with the dimensions in AVCodecContext within libavcodec and passing the frame to libschroedinger. patch by Anuradha Suraparaju, anuradha rd.bbc.co uk
author diego
date Sat, 15 Aug 2009 11:59:53 +0000
parents 4b91b74ff669
children 57d76996ccb8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
1 /**
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
2 *@brief Uninitialize the decoder and free all resources.
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
3 *@param avctx codec context
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
4 *@return 0 on success, < 0 otherwise
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
5 */
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
6 static av_cold int decode_end(AVCodecContext *avctx)
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
7 {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
8 WMA3DecodeContext *s = avctx->priv_data;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
9 int i;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
10
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
11 av_freep(&s->num_sfb);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
12 av_freep(&s->sfb_offsets);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
13 av_freep(&s->subwoofer_cutoffs);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
14 av_freep(&s->sf_offsets);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
15
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
16 for (i = 0 ; i < WMAPRO_BLOCK_SIZES ; i++)
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
17 ff_mdct_end(&s->mdct_ctx[i]);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
18
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
19 return 0;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
20 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
21
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
22 /**
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
23 *@brief Calculate a decorrelation matrix from the bitstream parameters.
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
24 *@param s codec context
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
25 *@param chgroup channel group for which the matrix needs to be calculated
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
26 */
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
27 static void decode_decorrelation_matrix(WMA3DecodeContext *s,
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
28 WMA3ChannelGroup *chgroup)
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
29 {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
30 int i;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
31 int offset = 0;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
32 int8_t rotation_offset[WMAPRO_MAX_CHANNELS * WMAPRO_MAX_CHANNELS];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
33 memset(chgroup->decorrelation_matrix,0,
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
34 sizeof(float) *s->num_channels * s->num_channels);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
35
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
36 for (i = 0; i < chgroup->num_channels * (chgroup->num_channels - 1) >> 1; i++)
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
37 rotation_offset[i] = get_bits(&s->gb,6);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
38
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
39 for (i = 0; i < chgroup->num_channels; i++)
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
40 chgroup->decorrelation_matrix[chgroup->num_channels * i + i] =
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
41 get_bits1(&s->gb) ? 1.0 : -1.0;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
42
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
43 for (i = 1; i < chgroup->num_channels; i++) {
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
44 int x;
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
45 for (x = 0; x < i; x++) {
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
46 int y;
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
47 for (y = 0; y < i + 1 ; y++) {
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
48 float v1 = chgroup->decorrelation_matrix[x * chgroup->num_channels + y];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
49 float v2 = chgroup->decorrelation_matrix[i * chgroup->num_channels + y];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
50 int n = rotation_offset[offset + x];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
51 float sinv;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
52 float cosv;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
53
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
54 if (n < 32) {
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
55 sinv = sin64[n];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
56 cosv = sin64[32-n];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
57 } else {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
58 sinv = sin64[64-n];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
59 cosv = -sin64[n-32];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
60 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
61
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
62 chgroup->decorrelation_matrix[y + x * chgroup->num_channels] =
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
63 (v1 * sinv) - (v2 * cosv);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
64 chgroup->decorrelation_matrix[y + i * chgroup->num_channels] =
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
65 (v1 * cosv) + (v2 * sinv);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
66 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
67 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
68 offset += i;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
69 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
70 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
71
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
72 /**
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
73 *@brief Reconstruct the individual channel data.
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
74 *@param s codec context
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
75 */
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
76 static void inverse_channel_transform(WMA3DecodeContext *s)
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
77 {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
78 int i;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
79
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
80 for (i = 0; i < s->num_chgroups; i++) {
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
81
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
82 if (s->chgroup[i].transform == 1) {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
83 /** M/S stereo decoding */
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
84 int16_t* sfb_offsets = s->cur_sfb_offsets;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
85 float* ch0 = *sfb_offsets + s->channel[0].coeffs;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
86 float* ch1 = *sfb_offsets++ + s->channel[1].coeffs;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
87 const char* tb = s->chgroup[i].transform_band;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
88 const char* tb_end = tb + s->num_bands;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
89
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
90 while (tb < tb_end) {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
91 const float* ch0_end = s->channel[0].coeffs +
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
92 FFMIN(*sfb_offsets,s->subframe_len);
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
93 if (*tb++ == 1) {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
94 while (ch0 < ch0_end) {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
95 const float v1 = *ch0;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
96 const float v2 = *ch1;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
97 *ch0++ = v1 - v2;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
98 *ch1++ = v1 + v2;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
99 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
100 } else {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
101 while (ch0 < ch0_end) {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
102 *ch0++ *= 181.0 / 128;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
103 *ch1++ *= 181.0 / 128;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
104 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
105 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
106 ++sfb_offsets;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
107 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
108 } else if (s->chgroup[i].transform) {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
109 float data[WMAPRO_MAX_CHANNELS];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
110 const int num_channels = s->chgroup[i].num_channels;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
111 float** ch_data = s->chgroup[i].channel_data;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
112 float** ch_end = ch_data + num_channels;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
113 const int8_t* tb = s->chgroup[i].transform_band;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
114 int16_t* sfb;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
115
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
116 /** multichannel decorrelation */
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
117 for (sfb = s->cur_sfb_offsets ;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
118 sfb < s->cur_sfb_offsets + s->num_bands;sfb++) {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
119 if (*tb++ == 1) {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
120 int y;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
121 /** multiply values with the decorrelation_matrix */
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
122 for (y = sfb[0]; y < FFMIN(sfb[1], s->subframe_len); y++) {
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
123 const float* mat = s->chgroup[i].decorrelation_matrix;
10006
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
124 const float* data_end = data + num_channels;
4b91b74ff669 cosmetics: K&R coding style, prettyprinting
diego
parents: 10005
diff changeset
125 float* data_ptr = data;
10005
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
126 float** ch;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
127
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
128 for (ch = ch_data;ch < ch_end; ch++)
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
129 *data_ptr++ = (*ch)[y];
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
130
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
131 for (ch = ch_data; ch < ch_end; ch++) {
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
132 float sum = 0;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
133 data_ptr = data;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
134 while (data_ptr < data_end)
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
135 sum += *data_ptr++ * *mat++;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
136
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
137 (*ch)[y] = sum;
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
138 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
139 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
140 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
141 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
142 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
143 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
144 }
ca678269fa64 add approved hunks of the wmapro decoder
faust3
parents:
diff changeset
145