Mercurial > libavcodec.hg
annotate binkaudio.c @ 12512:58bd8cb86f5d libavcodec
Remove unused variable.
| author | rbultje |
|---|---|
| date | Fri, 24 Sep 2010 15:31:46 +0000 |
| parents | 7dd2a45249a9 |
| children |
| 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 /** | |
|
11644
7dd2a45249a9
Remove explicit filename from Doxygen @file commands.
diego
parents:
11582
diff
changeset
|
24 * @file |
| 11067 | 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" | |
| 11370 | 35 #include "fft.h" |
| 36 | |
| 11067 | 37 extern const uint16_t ff_wma_critical_freqs[25]; |
| 38 | |
| 39 #define MAX_CHANNELS 2 | |
| 40 #define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11) | |
| 41 | |
| 42 typedef struct { | |
| 43 AVCodecContext *avctx; | |
| 44 GetBitContext gb; | |
| 45 DSPContext dsp; | |
| 46 int first; | |
| 47 int channels; | |
| 48 int frame_len; ///< transform size (samples) | |
| 49 int overlap_len; ///< overlap size (samples) | |
| 50 int block_size; | |
| 51 int num_bands; | |
| 52 unsigned int *bands; | |
| 53 float root; | |
| 11369 | 54 DECLARE_ALIGNED(16, FFTSample, coeffs)[BINK_BLOCK_MAX_SIZE]; |
| 55 DECLARE_ALIGNED(16, short, previous)[BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block | |
| 11067 | 56 float *coeffs_ptr[MAX_CHANNELS]; ///< pointers to the coeffs arrays for float_to_int16_interleave |
| 57 union { | |
| 58 RDFTContext rdft; | |
| 59 DCTContext dct; | |
| 60 } trans; | |
| 61 } BinkAudioContext; | |
| 62 | |
| 63 | |
| 64 static av_cold int decode_init(AVCodecContext *avctx) | |
| 65 { | |
| 66 BinkAudioContext *s = avctx->priv_data; | |
| 67 int sample_rate = avctx->sample_rate; | |
| 68 int sample_rate_half; | |
| 69 int i; | |
| 70 int frame_len_bits; | |
| 71 | |
| 72 s->avctx = avctx; | |
| 73 dsputil_init(&s->dsp, avctx); | |
| 74 | |
| 75 /* determine frame length */ | |
| 76 if (avctx->sample_rate < 22050) { | |
| 77 frame_len_bits = 9; | |
| 78 } else if (avctx->sample_rate < 44100) { | |
| 79 frame_len_bits = 10; | |
| 80 } else { | |
| 81 frame_len_bits = 11; | |
| 82 } | |
| 83 s->frame_len = 1 << frame_len_bits; | |
| 84 | |
| 85 if (s->channels > MAX_CHANNELS) { | |
| 86 av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels); | |
| 87 return -1; | |
| 88 } | |
| 89 | |
| 90 if (avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) { | |
| 91 // audio is already interleaved for the RDFT format variant | |
| 92 sample_rate *= avctx->channels; | |
| 93 s->frame_len *= avctx->channels; | |
| 94 s->channels = 1; | |
| 95 if (avctx->channels == 2) | |
| 96 frame_len_bits++; | |
| 97 } else { | |
| 98 s->channels = avctx->channels; | |
| 99 } | |
| 100 | |
| 101 s->overlap_len = s->frame_len / 16; | |
| 102 s->block_size = (s->frame_len - s->overlap_len) * s->channels; | |
| 103 sample_rate_half = (sample_rate + 1) / 2; | |
| 104 s->root = 2.0 / sqrt(s->frame_len); | |
| 105 | |
| 106 /* calculate number of bands */ | |
| 107 for (s->num_bands = 1; s->num_bands < 25; s->num_bands++) | |
| 108 if (sample_rate_half <= ff_wma_critical_freqs[s->num_bands - 1]) | |
| 109 break; | |
| 110 | |
| 111 s->bands = av_malloc((s->num_bands + 1) * sizeof(*s->bands)); | |
| 112 if (!s->bands) | |
| 113 return AVERROR(ENOMEM); | |
| 114 | |
| 115 /* populate bands data */ | |
| 116 s->bands[0] = 1; | |
| 117 for (i = 1; i < s->num_bands; i++) | |
| 118 s->bands[i] = ff_wma_critical_freqs[i - 1] * (s->frame_len / 2) / sample_rate_half; | |
| 119 s->bands[s->num_bands] = s->frame_len / 2; | |
| 120 | |
| 121 s->first = 1; | |
| 122 avctx->sample_fmt = SAMPLE_FMT_S16; | |
| 123 | |
| 124 for (i = 0; i < s->channels; i++) | |
| 125 s->coeffs_ptr[i] = s->coeffs + i * s->frame_len; | |
| 126 | |
|
11216
359c8ba0698e
Fix compilation of binkaudio_rdft when dct is disabled
daniel
parents:
11069
diff
changeset
|
127 if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) |
| 11391 | 128 ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R); |
|
11216
359c8ba0698e
Fix compilation of binkaudio_rdft when dct is disabled
daniel
parents:
11069
diff
changeset
|
129 else if (CONFIG_BINKAUDIO_DCT_DECODER) |
|
11582
23cad4157bfb
Make code using 1d-DCT consistent with the API change
vitor
parents:
11560
diff
changeset
|
130 ff_dct_init(&s->trans.dct, frame_len_bits, DCT_III); |
| 11067 | 131 else |
|
11216
359c8ba0698e
Fix compilation of binkaudio_rdft when dct is disabled
daniel
parents:
11069
diff
changeset
|
132 return -1; |
| 11067 | 133 |
| 134 return 0; | |
| 135 } | |
| 136 | |
| 137 static float get_float(GetBitContext *gb) | |
| 138 { | |
| 139 int power = get_bits(gb, 5); | |
| 140 float f = ldexpf(get_bits_long(gb, 23), power - 23); | |
| 141 if (get_bits1(gb)) | |
| 142 f = -f; | |
| 143 return f; | |
| 144 } | |
| 145 | |
| 146 static const uint8_t rle_length_tab[16] = { | |
| 147 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64 | |
| 148 }; | |
| 149 | |
| 150 /** | |
| 151 * Decode Bink Audio block | |
| 152 * @param[out] out Output buffer (must contain s->block_size elements) | |
| 153 */ | |
| 154 static void decode_block(BinkAudioContext *s, short *out, int use_dct) | |
| 155 { | |
| 156 int ch, i, j, k; | |
| 157 float q, quant[25]; | |
| 158 int width, coeff; | |
| 159 GetBitContext *gb = &s->gb; | |
| 160 | |
| 161 if (use_dct) | |
| 162 skip_bits(gb, 2); | |
| 163 | |
| 164 for (ch = 0; ch < s->channels; ch++) { | |
| 165 FFTSample *coeffs = s->coeffs_ptr[ch]; | |
| 166 q = 0.0f; | |
| 167 coeffs[0] = get_float(gb) * s->root; | |
| 168 coeffs[1] = get_float(gb) * s->root; | |
| 169 | |
| 170 for (i = 0; i < s->num_bands; i++) { | |
| 171 /* constant is result of 0.066399999/log10(M_E) */ | |
| 172 int value = get_bits(gb, 8); | |
| 173 quant[i] = expf(FFMIN(value, 95) * 0.15289164787221953823f) * s->root; | |
| 174 } | |
| 175 | |
| 176 // find band (k) | |
| 177 for (k = 0; s->bands[k] < 1; k++) { | |
| 178 q = quant[k]; | |
| 179 } | |
| 180 | |
| 181 // parse coefficients | |
| 182 i = 2; | |
| 183 while (i < s->frame_len) { | |
| 184 if (get_bits1(gb)) { | |
| 185 j = i + rle_length_tab[get_bits(gb, 4)] * 8; | |
| 186 } else { | |
| 187 j = i + 8; | |
| 188 } | |
| 189 | |
| 190 j = FFMIN(j, s->frame_len); | |
| 191 | |
| 192 width = get_bits(gb, 4); | |
| 193 if (width == 0) { | |
| 194 memset(coeffs + i, 0, (j - i) * sizeof(*coeffs)); | |
| 195 i = j; | |
| 196 while (s->bands[k] * 2 < i) | |
| 197 q = quant[k++]; | |
| 198 } else { | |
| 199 while (i < j) { | |
| 200 if (s->bands[k] * 2 == i) | |
| 201 q = quant[k++]; | |
| 202 coeff = get_bits(gb, width); | |
| 203 if (coeff) { | |
| 204 if (get_bits1(gb)) | |
| 205 coeffs[i] = -q * coeff; | |
| 206 else | |
| 207 coeffs[i] = q * coeff; | |
| 208 } else { | |
| 209 coeffs[i] = 0.0f; | |
| 210 } | |
| 211 i++; | |
| 212 } | |
| 213 } | |
| 214 } | |
| 215 | |
|
11337
15dd07e86519
Perform coefficient transformations in Bink Audio DCT decoder (issue1770)
pross
parents:
11264
diff
changeset
|
216 if (CONFIG_BINKAUDIO_DCT_DECODER && use_dct) { |
|
15dd07e86519
Perform coefficient transformations in Bink Audio DCT decoder (issue1770)
pross
parents:
11264
diff
changeset
|
217 coeffs[0] /= 0.5; |
| 11067 | 218 ff_dct_calc (&s->trans.dct, coeffs); |
|
11337
15dd07e86519
Perform coefficient transformations in Bink Audio DCT decoder (issue1770)
pross
parents:
11264
diff
changeset
|
219 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
|
220 } |
|
11216
359c8ba0698e
Fix compilation of binkaudio_rdft when dct is disabled
daniel
parents:
11069
diff
changeset
|
221 else if (CONFIG_BINKAUDIO_RDFT_DECODER) |
| 11067 | 222 ff_rdft_calc(&s->trans.rdft, coeffs); |
| 223 } | |
| 224 | |
|
11461
908cc63498ec
Make binkaudio work with ff_float_to_int16_interleave_c (martin at martin dot st)
pross
parents:
11391
diff
changeset
|
225 if (s->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) { |
|
908cc63498ec
Make binkaudio work with ff_float_to_int16_interleave_c (martin at martin dot st)
pross
parents:
11391
diff
changeset
|
226 for (i = 0; i < s->channels; i++) |
|
908cc63498ec
Make binkaudio work with ff_float_to_int16_interleave_c (martin at martin dot st)
pross
parents:
11391
diff
changeset
|
227 for (j = 0; j < s->frame_len; j++) |
|
908cc63498ec
Make binkaudio work with ff_float_to_int16_interleave_c (martin at martin dot st)
pross
parents:
11391
diff
changeset
|
228 s->coeffs_ptr[i][j] = 385.0 + s->coeffs_ptr[i][j]*(1.0/32767.0); |
|
908cc63498ec
Make binkaudio work with ff_float_to_int16_interleave_c (martin at martin dot st)
pross
parents:
11391
diff
changeset
|
229 } |
| 11067 | 230 s->dsp.float_to_int16_interleave(out, (const float **)s->coeffs_ptr, s->frame_len, s->channels); |
| 231 | |
| 232 if (!s->first) { | |
| 233 int count = s->overlap_len * s->channels; | |
| 234 int shift = av_log2(count); | |
| 235 for (i = 0; i < count; i++) { | |
| 236 out[i] = (s->previous[i] * (count - i) + out[i] * i) >> shift; | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 memcpy(s->previous, out + s->block_size, | |
| 241 s->overlap_len * s->channels * sizeof(*out)); | |
| 242 | |
| 243 s->first = 0; | |
| 244 } | |
| 245 | |
| 246 static av_cold int decode_end(AVCodecContext *avctx) | |
| 247 { | |
| 248 BinkAudioContext * s = avctx->priv_data; | |
| 249 av_freep(&s->bands); | |
|
11216
359c8ba0698e
Fix compilation of binkaudio_rdft when dct is disabled
daniel
parents:
11069
diff
changeset
|
250 if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) |
| 11067 | 251 ff_rdft_end(&s->trans.rdft); |
|
11216
359c8ba0698e
Fix compilation of binkaudio_rdft when dct is disabled
daniel
parents:
11069
diff
changeset
|
252 else if (CONFIG_BINKAUDIO_DCT_DECODER) |
| 11067 | 253 ff_dct_end(&s->trans.dct); |
| 254 return 0; | |
| 255 } | |
| 256 | |
| 257 static void get_bits_align32(GetBitContext *s) | |
| 258 { | |
| 259 int n = (-get_bits_count(s)) & 31; | |
| 260 if (n) skip_bits(s, n); | |
| 261 } | |
| 262 | |
| 263 static int decode_frame(AVCodecContext *avctx, | |
| 264 void *data, int *data_size, | |
| 265 AVPacket *avpkt) | |
| 266 { | |
| 267 BinkAudioContext *s = avctx->priv_data; | |
| 268 const uint8_t *buf = avpkt->data; | |
| 269 int buf_size = avpkt->size; | |
| 270 short *samples = data; | |
| 271 short *samples_end = (short*)((uint8_t*)data + *data_size); | |
| 272 int reported_size; | |
| 273 GetBitContext *gb = &s->gb; | |
| 274 | |
| 275 init_get_bits(gb, buf, buf_size * 8); | |
| 276 | |
| 277 reported_size = get_bits_long(gb, 32); | |
| 278 while (get_bits_count(gb) / 8 < buf_size && | |
| 279 samples + s->block_size <= samples_end) { | |
| 280 decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT); | |
| 281 samples += s->block_size; | |
| 282 get_bits_align32(gb); | |
| 283 } | |
| 284 | |
|
11264
bfffb50b80bc
Use reported_size to truncate final Bink Audio frame
pross
parents:
11216
diff
changeset
|
285 *data_size = FFMIN(reported_size, (uint8_t*)samples - (uint8_t*)data); |
| 11067 | 286 return buf_size; |
| 287 } | |
| 288 | |
| 289 AVCodec binkaudio_rdft_decoder = { | |
| 290 "binkaudio_rdft", | |
|
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
11461
diff
changeset
|
291 AVMEDIA_TYPE_AUDIO, |
| 11067 | 292 CODEC_ID_BINKAUDIO_RDFT, |
| 293 sizeof(BinkAudioContext), | |
| 294 decode_init, | |
| 295 NULL, | |
| 296 decode_end, | |
| 297 decode_frame, | |
| 298 .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (RDFT)") | |
| 299 }; | |
| 300 | |
| 301 AVCodec binkaudio_dct_decoder = { | |
| 302 "binkaudio_dct", | |
|
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
11461
diff
changeset
|
303 AVMEDIA_TYPE_AUDIO, |
| 11067 | 304 CODEC_ID_BINKAUDIO_DCT, |
| 305 sizeof(BinkAudioContext), | |
| 306 decode_init, | |
| 307 NULL, | |
| 308 decode_end, | |
| 309 decode_frame, | |
| 310 .long_name = NULL_IF_CONFIG_SMALL("Bink Audio (DCT)") | |
| 311 }; |
