Mercurial > libavcodec.hg
annotate binkaudio.c @ 11352:6e0af2cfdcfe libavcodec
Do MC and IDCT in coding (hilbert) order
This increases the slice size to 64 pixels, due to having to decode an
entire chroma superblock row per slice.
This can be up to 6% slower depending on clip and CPU, but is necessary
for future optimizations that gain significantly more than was lost.
author | conrad |
---|---|
date | Wed, 03 Mar 2010 23:27:40 +0000 |
parents | 15dd07e86519 |
children | 98970e51365a |
rev | line source |
---|---|
11067 | 1 /* |
2 * Bink Audio decoder | |
3 * Copyright (c) 2007-2010 Peter Ross (pross@xvid.org) | |
4 * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu) | |
5 * | |
6 * This file is part of FFmpeg. | |
7 * | |
8 * FFmpeg is free software; you can redistribute it and/or | |
9 * modify it under the terms of the GNU Lesser General Public | |
10 * License as published by the Free Software Foundation; either | |
11 * version 2.1 of the License, or (at your option) any later version. | |
12 * | |
13 * FFmpeg is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Lesser General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Lesser General Public | |
19 * License along with FFmpeg; if not, write to the Free Software | |
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
21 */ | |
22 | |
23 /** | |
24 * @file libavcodec/binkaudio.c | |
25 * Bink Audio decoder | |
26 * | |
27 * Technical details here: | |
28 * http://wiki.multimedia.cx/index.php?title=Bink_Audio | |
29 */ | |
30 | |
31 #include "avcodec.h" | |
32 #define ALT_BITSTREAM_READER_LE | |
33 #include "get_bits.h" | |
34 #include "dsputil.h" | |
35 extern const uint16_t ff_wma_critical_freqs[25]; | |
36 | |
37 #define MAX_CHANNELS 2 | |
38 #define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11) | |
39 | |
40 typedef struct { | |
41 AVCodecContext *avctx; | |
42 GetBitContext gb; | |
43 DSPContext dsp; | |
44 int first; | |
45 int channels; | |
46 int frame_len; ///< transform size (samples) | |
47 int overlap_len; ///< overlap size (samples) | |
48 int block_size; | |
49 int num_bands; | |
50 unsigned int *bands; | |
51 float root; | |
11069 | 52 DECLARE_ALIGNED_16(FFTSample, coeffs)[BINK_BLOCK_MAX_SIZE]; |
53 DECLARE_ALIGNED_16(short, previous)[BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block | |
11067 | 54 float *coeffs_ptr[MAX_CHANNELS]; ///< pointers to the coeffs arrays for float_to_int16_interleave |
55 union { | |
56 RDFTContext rdft; | |
57 DCTContext dct; | |
58 } trans; | |
59 } BinkAudioContext; | |
60 | |
61 | |
62 static av_cold int decode_init(AVCodecContext *avctx) | |
63 { | |
64 BinkAudioContext *s = avctx->priv_data; | |
65 int sample_rate = avctx->sample_rate; | |
66 int sample_rate_half; | |
67 int i; | |
68 int frame_len_bits; | |
69 | |
70 s->avctx = avctx; | |
71 dsputil_init(&s->dsp, avctx); | |
72 | |
73 /* determine frame length */ | |
74 if (avctx->sample_rate < 22050) { | |
75 frame_len_bits = 9; | |
76 } else if (avctx->sample_rate < 44100) { | |
77 frame_len_bits = 10; | |
78 } else { | |
79 frame_len_bits = 11; | |
80 } | |
81 s->frame_len = 1 << frame_len_bits; | |
82 | |
83 if (s->channels > MAX_CHANNELS) { | |
84 av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels); | |
85 return -1; | |
86 } | |
87 | |
88 if (avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) { | |
89 // audio is already interleaved for the RDFT format variant | |
90 sample_rate *= avctx->channels; | |
91 s->frame_len *= avctx->channels; | |
92 s->channels = 1; | |
93 if (avctx->channels == 2) | |
94 frame_len_bits++; | |
95 } else { | |
96 s->channels = avctx->channels; | |
97 } | |
98 | |
99 s->overlap_len = s->frame_len / 16; | |
100 s->block_size = (s->frame_len - s->overlap_len) * s->channels; | |
101 sample_rate_half = (sample_rate + 1) / 2; | |
102 s->root = 2.0 / sqrt(s->frame_len); | |
103 | |
104 /* calculate number of bands */ | |
105 for (s->num_bands = 1; s->num_bands < 25; s->num_bands++) | |
106 if (sample_rate_half <= ff_wma_critical_freqs[s->num_bands - 1]) | |
107 break; | |
108 | |
109 s->bands = av_malloc((s->num_bands + 1) * sizeof(*s->bands)); | |
110 if (!s->bands) | |
111 return AVERROR(ENOMEM); | |
112 | |
113 /* populate bands data */ | |
114 s->bands[0] = 1; | |
115 for (i = 1; i < s->num_bands; i++) | |
116 s->bands[i] = ff_wma_critical_freqs[i - 1] * (s->frame_len / 2) / sample_rate_half; | |
117 s->bands[s->num_bands] = s->frame_len / 2; | |
118 | |
119 s->first = 1; | |
120 avctx->sample_fmt = SAMPLE_FMT_S16; | |
121 | |
122 for (i = 0; i < s->channels; i++) | |
123 s->coeffs_ptr[i] = s->coeffs + i * s->frame_len; | |
124 | |
11216
359c8ba0698e
Fix compilation of binkaudio_rdft when dct is disabled
daniel
parents:
11069
diff
changeset
|
125 if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) |
11067 | 126 ff_rdft_init(&s->trans.rdft, frame_len_bits, IRIDFT); |
11216
359c8ba0698e
Fix compilation of binkaudio_rdft when dct is disabled
daniel
parents:
11069
diff
changeset
|
127 else if (CONFIG_BINKAUDIO_DCT_DECODER) |
11337
15dd07e86519
Perform coefficient transformations in Bink Audio DCT decoder (issue1770)
pross
parents:
11264
diff
changeset
|
128 ff_dct_init(&s->trans.dct, frame_len_bits, 1); |
11067 | 129 else |
11216
359c8ba0698e
Fix compilation of binkaudio_rdft when dct is disabled
daniel
parents:
11069
diff
changeset
|
130 return -1; |
11067 | 131 |
132 return 0; | |
133 } | |
134 | |
135 static float get_float(GetBitContext *gb) | |
136 { | |
137 int power = get_bits(gb, 5); | |
138 float f = ldexpf(get_bits_long(gb, 23), power - 23); | |
139 if (get_bits1(gb)) | |
140 f = -f; | |
141 return f; | |
142 } | |
143 | |
144 static const uint8_t rle_length_tab[16] = { | |
145 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64 | |
146 }; | |
147 | |
148 /** | |
149 * Decode Bink Audio block | |
150 * @param[out] out Output buffer (must contain s->block_size elements) | |
151 */ | |
152 static void decode_block(BinkAudioContext *s, short *out, int use_dct) | |
153 { | |
154 int ch, i, j, k; | |
155 float q, quant[25]; | |
156 int width, coeff; | |
157 GetBitContext *gb = &s->gb; | |
158 | |
159 if (use_dct) | |
160 skip_bits(gb, 2); | |
161 | |
162 for (ch = 0; ch < s->channels; ch++) { | |
163 FFTSample *coeffs = s->coeffs_ptr[ch]; | |
164 q = 0.0f; | |
165 coeffs[0] = get_float(gb) * s->root; | |
166 coeffs[1] = get_float(gb) * s->root; | |
167 | |
168 for (i = 0; i < s->num_bands; i++) { | |
169 /* constant is result of 0.066399999/log10(M_E) */ | |
170 int value = get_bits(gb, 8); | |
171 quant[i] = expf(FFMIN(value, 95) * 0.15289164787221953823f) * s->root; | |
172 } | |
173 | |
174 // find band (k) | |
175 for (k = 0; s->bands[k] < 1; k++) { | |
176 q = quant[k]; | |
177 } | |
178 | |
179 // parse coefficients | |
180 i = 2; | |
181 while (i < s->frame_len) { | |
182 if (get_bits1(gb)) { | |
183 j = i + rle_length_tab[get_bits(gb, 4)] * 8; | |
184 } else { | |
185 j = i + 8; | |
186 } | |
187 | |
188 j = FFMIN(j, s->frame_len); | |
189 | |
190 width = get_bits(gb, 4); | |
191 if (width == 0) { | |
192 memset(coeffs + i, 0, (j - i) * sizeof(*coeffs)); | |
193 i = j; | |
194 while (s->bands[k] * 2 < i) | |
195 q = quant[k++]; | |
196 } else { | |
197 while (i < j) { | |
198 if (s->bands[k] * 2 == i) | |
199 q = quant[k++]; | |
200 coeff = get_bits(gb, width); | |
201 if (coeff) { | |
202 if (get_bits1(gb)) | |
203 coeffs[i] = -q * coeff; | |
204 else | |
205 coeffs[i] = q * coeff; | |
206 } else { | |
207 coeffs[i] = 0.0f; | |
208 } | |
209 i++; | |
210 } | |
211 } | |
212 } | |
213 | |
11337
15dd07e86519
Perform coefficient transformations in Bink Audio DCT decoder (issue1770)
pross
parents:
11264
diff
changeset
|
214 if (CONFIG_BINKAUDIO_DCT_DECODER && use_dct) { |
15dd07e86519
Perform coefficient transformations in Bink Audio DCT decoder (issue1770)
pross
parents:
11264
diff
changeset
|
215 coeffs[0] /= 0.5; |
11067 | 216 ff_dct_calc (&s->trans.dct, coeffs); |
11337
15dd07e86519
Perform coefficient transformations in Bink Audio DCT decoder (issue1770)
pross
parents:
11264
diff
changeset
|
217 s->dsp.vector_fmul_scalar(coeffs, coeffs, s->frame_len / 2, s->frame_len); |
15dd07e86519
Perform coefficient transformations in Bink Audio DCT decoder (issue1770)
pross
parents:
11264
diff
changeset
|
218 } |
11216
359c8ba0698e
Fix compilation of binkaudio_rdft when dct is disabled
daniel
parents:
11069
diff
changeset
|
219 else if (CONFIG_BINKAUDIO_RDFT_DECODER) |
11067 | 220 ff_rdft_calc(&s->trans.rdft, coeffs); |
221 } | |
222 | |
223 s->dsp.float_to_int16_interleave(out, (const float **)s->coeffs_ptr, s->frame_len, s->channels); | |
224 | |
225 if (!s->first) { | |
226 int count = s->overlap_len * s->channels; | |
227 int shift = av_log2(count); | |
228 for (i = 0; i < count; i++) { | |
229 out[i] = (s->previous[i] * (count - i) + out[i] * i) >> shift; | |
230 } | |
231 } | |
232 | |
233 memcpy(s->previous, out + s->block_size, | |
234 s->overlap_len * s->channels * sizeof(*out)); | |
235 | |
236 s->first = 0; | |
237 } | |
238 | |
239 static av_cold int decode_end(AVCodecContext *avctx) | |
240 { | |
241 BinkAudioContext * s = avctx->priv_data; | |
242 av_freep(&s->bands); | |
11216
359c8ba0698e
Fix compilation of binkaudio_rdft when dct is disabled
daniel
parents:
11069
diff
changeset
|
243 if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) |
11067 | 244 ff_rdft_end(&s->trans.rdft); |
11216
359c8ba0698e
Fix compilation of binkaudio_rdft when dct is disabled
daniel
parents:
11069
diff
changeset
|
245 else if (CONFIG_BINKAUDIO_DCT_DECODER) |
11067 | 246 ff_dct_end(&s->trans.dct); |
247 return 0; | |
248 } | |
249 | |
250 static void get_bits_align32(GetBitContext *s) | |
251 { | |
252 int n = (-get_bits_count(s)) & 31; | |
253 if (n) skip_bits(s, n); | |
254 } | |
255 | |
256 static int decode_frame(AVCodecContext *avctx, | |
257 void *data, int *data_size, | |
258 AVPacket *avpkt) | |
259 { | |
260 BinkAudioContext *s = avctx->priv_data; | |
261 const uint8_t *buf = avpkt->data; | |
262 int buf_size = avpkt->size; | |
263 short *samples = data; | |
264 short *samples_end = (short*)((uint8_t*)data + *data_size); | |
265 int reported_size; | |
266 GetBitContext *gb = &s->gb; | |
267 | |
268 init_get_bits(gb, buf, buf_size * 8); | |
269 | |
270 reported_size = get_bits_long(gb, 32); | |
271 while (get_bits_count(gb) / 8 < buf_size && | |
272 samples + s->block_size <= samples_end) { | |
273 decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT); | |
274 samples += s->block_size; | |
275 get_bits_align32(gb); | |
276 } | |
277 | |
11264
bfffb50b80bc
Use reported_size to truncate final Bink Audio frame
pross
parents:
11216
diff
changeset
|
278 *data_size = FFMIN(reported_size, (uint8_t*)samples - (uint8_t*)data); |
11067 | 279 return buf_size; |
280 } | |
281 | |
282 AVCodec binkaudio_rdft_decoder = { | |
283 "binkaudio_rdft", | |
284 CODEC_TYPE_AUDIO, | |
285 CODEC_ID_BINKAUDIO_RDFT, | |
286 sizeof(BinkAudioContext), | |
287 decode_init, | |
288 NULL, | |
289 decode_end, | |
290 decode_frame, | |
291 .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (RDFT)") | |
292 }; | |
293 | |
294 AVCodec binkaudio_dct_decoder = { | |
295 "binkaudio_dct", | |
296 CODEC_TYPE_AUDIO, | |
297 CODEC_ID_BINKAUDIO_DCT, | |
298 sizeof(BinkAudioContext), | |
299 decode_init, | |
300 NULL, | |
301 decode_end, | |
302 decode_frame, | |
303 .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (DCT)") | |
304 }; |