X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvorbis_dec.c;h=16f6dec2b1509fb9f9033eb35001f2ab70439544;hb=78acb9e74b399588f7321ff87acd6dbeef6e387a;hp=d4a5402d861f55fc6a52cd2483265cea652b644e;hpb=b9fa32082c71013e90eab9e9997967d2939cf4a6;p=ffmpeg diff --git a/libavcodec/vorbis_dec.c b/libavcodec/vorbis_dec.c index d4a5402d861..16f6dec2b15 100644 --- a/libavcodec/vorbis_dec.c +++ b/libavcodec/vorbis_dec.c @@ -90,7 +90,7 @@ typedef struct { int_fast16_t subclass_books[16][8]; uint_fast8_t multiplier; uint_fast16_t x_list_dim; - floor1_entry_t * list; + vorbis_floor1_entry * list; } t1; } data; } vorbis_floor; @@ -153,9 +153,6 @@ typedef struct vorbis_context_s { float *channel_residues; float *channel_floors; float *saved; - float *ret; - float *buf; - float *buf_tmp; uint_fast32_t add_bias; // for float->int conversion uint_fast32_t exp_bias; } vorbis_context; @@ -181,9 +178,6 @@ static void vorbis_free(vorbis_context *vc) { av_freep(&vc->channel_residues); av_freep(&vc->channel_floors); av_freep(&vc->saved); - av_freep(&vc->ret); - av_freep(&vc->buf); - av_freep(&vc->buf_tmp); av_freep(&vc->residues); av_freep(&vc->modes); @@ -517,7 +511,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) { floor_setup->data.t1.x_list_dim+=floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]]; } - floor_setup->data.t1.list=av_mallocz(floor_setup->data.t1.x_list_dim * sizeof(floor1_entry_t)); + floor_setup->data.t1.list=av_mallocz(floor_setup->data.t1.x_list_dim * sizeof(vorbis_floor1_entry)); rangebits=get_bits(gb, 4); @@ -900,9 +894,6 @@ static int vorbis_parse_id_hdr(vorbis_context *vc){ vc->channel_residues= av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); vc->channel_floors = av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); vc->saved = av_mallocz((vc->blocksize[1]/4)*vc->audio_channels * sizeof(float)); - vc->ret = av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); - vc->buf = av_malloc( vc->blocksize[1]/2 * sizeof(float)); - vc->buf_tmp = av_malloc( vc->blocksize[1]/2 * sizeof(float)); vc->previous_window=0; ff_mdct_init(&vc->mdct[0], bl0, 1); @@ -935,7 +926,7 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext) { vc->avccontext = avccontext; dsputil_init(&vc->dsp, avccontext); - if(vc->dsp.float_to_int16 == ff_float_to_int16_c) { + if(vc->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) { vc->add_bias = 385; vc->exp_bias = 0; } else { @@ -969,6 +960,7 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext) { hdr_type=get_bits(gb, 8); if (hdr_type!=5) { av_log(avccontext, AV_LOG_ERROR, "Third header is not the setup header.\n"); + vorbis_free(vc); return -1; } if (vorbis_parse_setup_hdr(vc)) { @@ -980,6 +972,7 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext) { 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; return 0 ; } @@ -1232,7 +1225,7 @@ static uint_fast8_t vorbis_floor1_decode(vorbis_context *vc, vorbis_floor_data * // Read and decode residue -static int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr, uint_fast8_t ch, uint_fast8_t *do_not_decode, float *vec, uint_fast16_t vlen) { +static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, vorbis_residue *vr, uint_fast8_t ch, uint_fast8_t *do_not_decode, float *vec, uint_fast16_t vlen, int vr_type) { GetBitContext *gb=&vc->gb; uint_fast8_t c_p_c=vc->codebooks[vr->classbook].dimensions; uint_fast16_t n_to_read=vr->end-vr->begin; @@ -1243,7 +1236,7 @@ static int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr, uint_fa uint_fast8_t i,j,l; uint_fast16_t k; - if (vr->type==2) { + if (vr_type==2) { for(j=1;jpartition_size, dim); vorbis_codebook codebook= vc->codebooks[vqbook]; - if (vr->type==0) { + if (vr_type==0) { voffs=voffset+j*vlen; for(k=0;ktype==1) { + else if (vr_type==1) { voffs=voffset+j*vlen; for(k=0;ktype==2 && ch==2 && (voffset&1)==0 && (dim&1)==0) { // most frequent case optimized + else if (vr_type==2 && ch==2 && (voffset&1)==0 && (dim&1)==0) { // most frequent case optimized voffs=voffset>>1; if(dim==2) { @@ -1330,6 +1323,14 @@ static int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr, uint_fa vec[voffs+k ]+=codebook.codevectors[coffs ]; // FPMATH vec[voffs+k+vlen]+=codebook.codevectors[coffs+1]; // FPMATH } + } else if(dim==4) { + for(k=0;ktype==2) { + else if (vr_type==2) { voffs=voffset; for(k=0;kavccontext, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n"); - return 1; } } } @@ -1369,6 +1367,20 @@ static int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr, uint_fa return 0; } +static inline int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr, uint_fast8_t ch, uint_fast8_t *do_not_decode, float *vec, uint_fast16_t vlen) +{ + if (vr->type==2) + return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 2); + else if (vr->type==1) + return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 1); + else if (vr->type==0) + return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 0); + else { + av_log(vc->avccontext, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n"); + return 1; + } +} + void vorbis_inverse_coupling(float *mag, float *ang, int blocksize) { int i; @@ -1507,26 +1519,27 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) { vc->dsp.vorbis_inverse_coupling(mag, ang, blocksize/2); } -// Dotproduct +// Dotproduct, MDCT - for(j=0, ch_floor_ptr=vc->channel_floors;jaudio_channels;++j,ch_floor_ptr+=blocksize/2) { + 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); + ff_imdct_half(&vc->mdct[blockflag], ch_res_ptr, ch_floor_ptr); } -// MDCT, overlap/add, save data for next overlapping FPMATH +// Overlap/add, save data for next overlapping FPMATH retlen = (blocksize + vc->blocksize[previous_window])/4; - for(j=0;jaudio_channels;++j) { + for(j=0;jaudio_channels;j++) { uint_fast16_t bs0=vc->blocksize[0]; uint_fast16_t bs1=vc->blocksize[1]; + float *residue=vc->channel_residues+res_chan[j]*blocksize/2; float *saved=vc->saved+j*bs1/4; - float *ret=vc->ret+j*retlen; - float *buf=vc->buf; + float *ret=vc->channel_floors+j*retlen; + float *buf=residue; const float *win=vc->win[blockflag&previous_window]; - vc->mdct[0].fft.imdct_half(&vc->mdct[blockflag], buf, vc->channel_floors+j*blocksize/2, vc->buf_tmp); - if(blockflag == previous_window) { vc->dsp.vector_fmul_window(ret, saved, buf, win, fadd_bias, blocksize/4); } else if(blockflag > previous_window) { @@ -1551,6 +1564,8 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, { vorbis_context *vc = avccontext->priv_data ; GetBitContext *gb = &(vc->gb); + const float *channel_ptrs[vc->audio_channels]; + int i; int_fast16_t len; @@ -1577,7 +1592,9 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, AV_DEBUG("parsed %d bytes %d bits, returned %d samples (*ch*bits) \n", get_bits_count(gb)/8, get_bits_count(gb)%8, len); - vc->dsp.float_to_int16_interleave(data, vc->ret, len, vc->audio_channels); + for(i=0; iaudio_channels; i++) + channel_ptrs[i] = vc->channel_floors+i*len; + vc->dsp.float_to_int16_interleave(data, channel_ptrs, len, vc->audio_channels); *data_size=len*2*vc->audio_channels; return buf_size ;