static int vorbis_parse_audio_packet(vorbis_context *vc) { GetBitContext *gb = &vc->gb; FFTContext *mdct; unsigned previous_window = vc->previous_window; unsigned mode_number, blockflag, blocksize; int i, j; uint8_t no_residue[255]; uint8_t do_not_decode[255]; vorbis_mapping *mapping; float *ch_res_ptr = vc->channel_residues; float *ch_floor_ptr = vc->channel_floors; uint8_t res_chan[255]; unsigned res_num = 0; int retlen = 0; int ch_left = vc->audio_channels; if (get_bits1(gb)) { av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n"); return AVERROR_INVALIDDATA; // packet type not audio } if (vc->mode_count == 1) { mode_number = 0; } else { GET_VALIDATED_INDEX(mode_number, ilog(vc->mode_count-1), vc->mode_count) } vc->mode_number = mode_number; mapping = &vc->mappings[vc->modes[mode_number].mapping]; av_dlog(NULL, " Mode number: %u , mapping: %d , blocktype %d\n", mode_number, vc->modes[mode_number].mapping, vc->modes[mode_number].blockflag); blockflag = vc->modes[mode_number].blockflag; blocksize = vc->blocksize[blockflag]; if (blockflag) skip_bits(gb, 2); // previous_window, next_window memset(ch_res_ptr, 0, sizeof(float) * vc->audio_channels * blocksize / 2); //FIXME can this be removed ? memset(ch_floor_ptr, 0, sizeof(float) * vc->audio_channels * blocksize / 2); //FIXME can this be removed ? // Decode floor for (i = 0; i < vc->audio_channels; ++i) { vorbis_floor *floor; int ret; if (mapping->submaps > 1) { floor = &vc->floors[mapping->submap_floor[mapping->mux[i]]]; } else { floor = &vc->floors[mapping->submap_floor[0]]; } ret = floor->decode(vc, &floor->data, ch_floor_ptr); if (ret < 0) { av_log(vc->avccontext, AV_LOG_ERROR, "Invalid codebook in vorbis_floor_decode.\n"); return AVERROR_INVALIDDATA; } no_residue[i] = ret; ch_floor_ptr += blocksize / 2; } // Nonzero vector propagate for (i = mapping->coupling_steps - 1; i >= 0; --i) { if (!(no_residue[mapping->magnitude[i]] & no_residue[mapping->angle[i]])) { no_residue[mapping->magnitude[i]] = 0; no_residue[mapping->angle[i]] = 0; } } // Decode residue for (i = 0; i < mapping->submaps; ++i) { vorbis_residue *residue; unsigned ch = 0; for (j = 0; j < vc->audio_channels; ++j) { if ((mapping->submaps == 1) || (i == mapping->mux[j])) { res_chan[j] = res_num; if (no_residue[j]) { do_not_decode[ch] = 1; } else { do_not_decode[ch] = 0; } ++ch; ++res_num; } } residue = &vc->residues[mapping->submap_residue[i]]; if (ch_left < ch) { av_log(vc->avccontext, AV_LOG_ERROR, "Too many channels in vorbis_floor_decode.\n"); return -1; } vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, blocksize/2); ch_res_ptr += ch * blocksize / 2; ch_left -= ch; } // Inverse coupling for (i = mapping->coupling_steps - 1; i >= 0; --i) { //warning: i has to be signed float *mag, *ang; mag = vc->channel_residues+res_chan[mapping->magnitude[i]] * blocksize / 2; ang = vc->channel_residues+res_chan[mapping->angle[i]] * blocksize / 2; vc->dsp.vorbis_inverse_coupling(mag, ang, blocksize / 2); } // Dotproduct, MDCT mdct = &vc->mdct[blockflag]; 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_floor_ptr, ch_res_ptr, blocksize / 2); mdct->imdct_half(mdct, ch_res_ptr, ch_floor_ptr); } // Overlap/add, save data for next overlapping FPMATH retlen = (blocksize + vc->blocksize[previous_window]) / 4; for (j = 0; j < vc->audio_channels; j++) { unsigned bs0 = vc->blocksize[0]; unsigned bs1 = vc->blocksize[1]; float *residue = vc->channel_residues + res_chan[j] * blocksize / 2; float *saved = vc->saved + j * bs1 / 4; float *ret = vc->channel_floors + j * retlen; float *buf = residue; const float *win = vc->win[blockflag & previous_window]; if (blockflag == previous_window) { 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, bs0 / 4); memcpy(ret+bs0/2, buf+bs0/4, ((bs1-bs0)/4) * sizeof(float)); } else { 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)); } vc->previous_window = blockflag; return retlen; }
static int vorbis_parse_audio_packet(vorbis_context *vc) { GetBitContext *gb = &vc->gb; FFTContext *mdct; unsigned previous_window = vc->previous_window; unsigned mode_number, blockflag, blocksize; int i, j; uint8_t no_residue[255]; uint8_t do_not_decode[255]; vorbis_mapping *mapping; float *ch_res_ptr = vc->channel_residues; float *ch_floor_ptr = vc->channel_floors; uint8_t res_chan[255]; unsigned res_num = 0; int retlen = 0; int ch_left = vc->audio_channels; if (get_bits1(gb)) { av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n"); return AVERROR_INVALIDDATA;  