#include "get_bits.h"
#include "dsputil.h"
#include "fft.h"
+#include "fmtconvert.h"
#include "vorbis.h"
#include "xiph.h"
AVCodecContext *avccontext;
GetBitContext gb;
DSPContext dsp;
+ FmtConvertContext fmt_conv;
FFTContext mdct[2];
uint_fast8_t first_frame;
float *channel_residues;
float *channel_floors;
float *saved;
- uint_fast32_t add_bias; // for float->int conversion
- uint_fast32_t exp_bias;
+ float scale_bias; // for float->int conversion
} vorbis_context;
/* Helper functions */
if (floor_setup->floor_type == 1) {
int maximum_class = -1;
uint_fast8_t rangebits;
+ uint_fast32_t rangemax;
uint_fast16_t floor1_values = 2;
floor_setup->decode = vorbis_floor1_decode;
rangebits = get_bits(gb, 4);
+ rangemax = (1 << rangebits);
+ if (rangemax > vc->blocksize[1] / 2) {
+ av_log(vc->avccontext, AV_LOG_ERROR,
+ "Floor value is too large for blocksize: %d (%d)\n",
+ rangemax, vc->blocksize[1] / 2);
+ return -1;
+ }
floor_setup->data.t1.list[0].x = 0;
- floor_setup->data.t1.list[1].x = (1 << rangebits);
+ floor_setup->data.t1.list[1].x = rangemax;
for (j = 0; j < floor_setup->data.t1.partitions; ++j) {
for (k = 0; k < floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]]; ++k, ++floor1_values) {
/* zero would result in a div by zero later *
* 2^0 - 1 == 0 */
if (floor_setup->data.t0.amplitude_bits == 0) {
- av_log(vc->avccontext, AV_LOG_ERROR,
- "Floor 0 amplitude bits is 0.\n");
- return -1;
+ av_log(vc->avccontext, AV_LOG_ERROR,
+ "Floor 0 amplitude bits is 0.\n");
+ return -1;
}
floor_setup->data.t0.amplitude_offset = get_bits(gb, 8);
floor_setup->data.t0.num_books = get_bits(gb, 4) + 1;
create_map(vc, i);
- /* allocate mem for lsp coefficients */
- {
- /* codebook dim is for padding if codebook dim doesn't *
- * divide order+1 then we need to read more data */
- floor_setup->data.t0.lsp =
- av_malloc((floor_setup->data.t0.order+1 + max_codebook_dim)
- * sizeof(float));
- if (!floor_setup->data.t0.lsp)
- return -1;
- }
+ /* codebook dim is for padding if codebook dim doesn't *
+ * divide order+1 then we need to read more data */
+ floor_setup->data.t0.lsp =
+ av_malloc((floor_setup->data.t0.order+1 + max_codebook_dim)
+ * sizeof(float));
+ if (!floor_setup->data.t0.lsp)
+ return -1;
#ifdef V_DEBUG /* debug output parsed headers */
AV_DEBUG("floor0 order: %u\n", floor_setup->data.t0.order);
AV_DEBUG("floor0 rate: %u\n", floor_setup->data.t0.rate);
AV_DEBUG("floor0 bark map size: %u\n",
- floor_setup->data.t0.bark_map_size);
+ floor_setup->data.t0.bark_map_size);
AV_DEBUG("floor0 amplitude bits: %u\n",
- floor_setup->data.t0.amplitude_bits);
+ floor_setup->data.t0.amplitude_bits);
AV_DEBUG("floor0 amplitude offset: %u\n",
- floor_setup->data.t0.amplitude_offset);
+ floor_setup->data.t0.amplitude_offset);
AV_DEBUG("floor0 number of books: %u\n",
- floor_setup->data.t0.num_books);
+ floor_setup->data.t0.num_books);
AV_DEBUG("floor0 book list pointer: %p\n",
- floor_setup->data.t0.book_list);
+ floor_setup->data.t0.book_list);
{
- int idx;
- for (idx = 0; idx < floor_setup->data.t0.num_books; ++idx) {
- AV_DEBUG(" Book %d: %u\n",
- idx+1,
- floor_setup->data.t0.book_list[idx]);
- }
+ int idx;
+ for (idx = 0; idx < floor_setup->data.t0.num_books; ++idx) {
+ AV_DEBUG(" Book %d: %u\n",
+ idx+1,
+ floor_setup->data.t0.book_list[idx]);
+ }
}
#endif
} else {
res_setup->partition_size = get_bits(gb, 24) + 1;
/* Validations to prevent a buffer overflow later. */
if (res_setup->begin>res_setup->end ||
- res_setup->end > vc->avccontext->channels * vc->blocksize[1] / (res_setup->type == 2 ? 1 : 2) ||
+ res_setup->end > vc->avccontext->channels * vc->blocksize[1] / 2 ||
(res_setup->end-res_setup->begin) / res_setup->partition_size > V_MAX_PARTITIONS) {
av_log(vc->avccontext, AV_LOG_ERROR, "partition out of bounds: type, begin, end, size, blocksize: %"PRIdFAST16", %"PRIdFAST32", %"PRIdFAST32", %u, %"PRIdFAST32"\n", res_setup->type, res_setup->begin, res_setup->end, res_setup->partition_size, vc->blocksize[1] / 2);
return -1;
vf->map_size[blockflag] = n;
}
-# ifdef V_DEBUG
+#ifdef V_DEBUG
for (idx = 0; idx <= n; ++idx) {
AV_DEBUG("floor0 map: map at pos %d is %d\n",
idx, map[idx]);
}
-# endif
+#endif
}
static int vorbis_parse_setup_hdr_modes(vorbis_context *vc)
vc->saved = av_mallocz((vc->blocksize[1] / 4) * vc->audio_channels * sizeof(float));
vc->previous_window = 0;
- ff_mdct_init(&vc->mdct[0], bl0, 1, vc->exp_bias ? -(1 << 15) : -1.0);
- ff_mdct_init(&vc->mdct[1], bl1, 1, vc->exp_bias ? -(1 << 15) : -1.0);
+ ff_mdct_init(&vc->mdct[0], bl0, 1, -vc->scale_bias);
+ ff_mdct_init(&vc->mdct[1], bl1, 1, -vc->scale_bias);
AV_DEBUG(" vorbis version %d \n audio_channels %d \n audio_samplerate %d \n bitrate_max %d \n bitrate_nom %d \n bitrate_min %d \n blk_0 %d blk_1 %d \n ",
vc->version, vc->audio_channels, vc->audio_samplerate, vc->bitrate_maximum, vc->bitrate_nominal, vc->bitrate_minimum, vc->blocksize[0], vc->blocksize[1]);
vc->avccontext = avccontext;
dsputil_init(&vc->dsp, avccontext);
+ ff_fmt_convert_init(&vc->fmt_conv, avccontext);
- if (vc->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) {
- vc->add_bias = 385;
- vc->exp_bias = 0;
- } else {
- vc->add_bias = 0;
- vc->exp_bias = 15 << 23;
- }
+ vc->scale_bias = 32768.0f;
if (!headers_len) {
av_log(avccontext, AV_LOG_ERROR, "Extradata missing.\n");
avccontext->channels = vc->audio_channels;
avccontext->sample_rate = vc->audio_samplerate;
avccontext->frame_size = FFMIN(vc->blocksize[0], vc->blocksize[1]) >> 2;
- avccontext->sample_fmt = SAMPLE_FMT_S16;
+ avccontext->sample_fmt = AV_SAMPLE_FMT_S16;
return 0 ;
}
av_log(vc->avccontext, AV_LOG_ERROR,
"floor0 dec: booknumber too high!\n");
book_idx = 0;
- //FIXME: look above
}
AV_DEBUG("floor0 dec: booknumber: %u\n", book_idx);
codebook = vc->codebooks[vf->book_list[book_idx]];
}
/* calculate linear floor value */
- {
- q = exp((((amplitude*vf->amplitude_offset) /
- (((1 << vf->amplitude_bits) - 1) * sqrt(p + q)))
- - vf->amplitude_offset) * .11512925f);
- }
+ q = exp((((amplitude*vf->amplitude_offset) /
+ (((1 << vf->amplitude_bits) - 1) * sqrt(p + q)))
+ - vf->amplitude_offset) * .11512925f);
/* fill vector */
do {
}
}
-static void copy_normalize(float *dst, float *src, int len, int exp_bias,
- float add_bias)
-{
- int i;
- if (exp_bias) {
- memcpy(dst, src, len * sizeof(float));
- } else {
- for (i = 0; i < len; i++)
- dst[i] = src[i] + add_bias;
- }
-}
-
// Decode the audio packet using the functions above
static int vorbis_parse_audio_packet(vorbis_context *vc)
uint_fast8_t res_chan[255];
uint_fast8_t res_num = 0;
int_fast16_t retlen = 0;
- float fadd_bias = vc->add_bias;
if (get_bits1(gb)) {
av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n");
for (j = vc->audio_channels-1;j >= 0; j--) {
ch_floor_ptr = vc->channel_floors + j * blocksize / 2;
ch_res_ptr = vc->channel_residues + res_chan[j] * blocksize / 2;
- vc->dsp.vector_fmul(ch_floor_ptr, ch_res_ptr, blocksize / 2);
+ vc->dsp.vector_fmul(ch_floor_ptr, ch_floor_ptr, ch_res_ptr, blocksize / 2);
ff_imdct_half(&vc->mdct[blockflag], ch_res_ptr, ch_floor_ptr);
}
const float *win = vc->win[blockflag & previous_window];
if (blockflag == previous_window) {
- vc->dsp.vector_fmul_window(ret, saved, buf, win, fadd_bias, blocksize / 4);
+ vc->dsp.vector_fmul_window(ret, saved, buf, win, blocksize / 4);
} else if (blockflag > previous_window) {
- vc->dsp.vector_fmul_window(ret, saved, buf, win, fadd_bias, bs0 / 4);
- copy_normalize(ret+bs0/2, buf+bs0/4, (bs1-bs0)/4, vc->exp_bias, fadd_bias);
+ vc->dsp.vector_fmul_window(ret, saved, buf, win, bs0 / 4);
+ memcpy(ret+bs0/2, buf+bs0/4, ((bs1-bs0)/4) * sizeof(float));
} else {
- copy_normalize(ret, saved, (bs1 - bs0) / 4, vc->exp_bias, fadd_bias);
- vc->dsp.vector_fmul_window(ret + (bs1 - bs0) / 4, saved + (bs1 - bs0) / 4, buf, win, fadd_bias, bs0 / 4);
+ memcpy(ret, saved, ((bs1 - bs0) / 4) * sizeof(float));
+ vc->dsp.vector_fmul_window(ret + (bs1 - bs0) / 4, saved + (bs1 - bs0) / 4, buf, win, bs0 / 4);
}
memcpy(saved, buf + blocksize / 4, blocksize / 4 * sizeof(float));
}
len * ff_vorbis_channel_layout_offsets[vc->audio_channels - 1][i];
}
- vc->dsp.float_to_int16_interleave(data, channel_ptrs, len, vc->audio_channels);
+ vc->fmt_conv.float_to_int16_interleave(data, channel_ptrs, len,
+ vc->audio_channels);
*data_size = len * 2 * vc->audio_channels;
return buf_size ;
return 0 ;
}
-AVCodec vorbis_decoder = {
+AVCodec ff_vorbis_decoder = {
"vorbis",
AVMEDIA_TYPE_AUDIO,
CODEC_ID_VORBIS,