Skip to content
Snippets Groups Projects
ac3dec.c 39.9 KiB
Newer Older
  • Learn to ignore specific revisions
  •             /* Compute excitation function, Compute masking curve, and
                   Apply delta bit allocation */
    
                ff_ac3_bit_alloc_calc_mask(&s->bit_alloc_params, s->band_psd[ch],
                                           s->start_freq[ch], s->end_freq[ch],
                                           s->fast_gain[ch], (ch == s->lfe_ch),
                                           s->dba_mode[ch], s->dba_nsegs[ch],
                                           s->dba_offsets[ch], s->dba_lengths[ch],
                                           s->dba_values[ch], s->mask[ch]);
    
            if(bit_alloc_stages[ch] > 0) {
                /* Compute bit allocation */
    
                ff_ac3_bit_alloc_calc_bap(s->mask[ch], s->psd[ch],
                                          s->start_freq[ch], s->end_freq[ch],
                                          s->snr_offset[ch],
                                          s->bit_alloc_params.floor,
                                          s->bap[ch]);
    
        if (get_bits1(gbc)) {
            int skipl = get_bits(gbc, 9);
    
                skip_bits(gbc, 8);
    
        /* unpack the transform coefficients
    
           this also uncouples channels if coupling is in use. */
    
        if (get_transform_coeffs(s)) {
            av_log(s->avctx, AV_LOG_ERROR, "Error in routine get_transform_coeffs\n");
    
        /* recover coefficients if rematrixing is in use */
    
        if(s->channel_mode == AC3_CHMODE_STEREO)
            do_rematrixing(s);
    
        /* apply scaling to coefficients (headroom, dynrng) */
    
        for(ch=1; ch<=s->channels; ch++) {
            float gain = 2.0f * s->mul_bias;
            if(s->channel_mode == AC3_CHMODE_DUALMONO) {
                gain *= s->dynamic_range[ch-1];
    
            for(i=0; i<s->end_freq[ch]; i++) {
                s->transform_coeffs[ch][i] *= gain;
    
        if(s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) &&
                s->fbw_channels == s->out_channels)) {
    
        /* convert float to 16-bit integer */
    
        for(ch=0; ch<s->out_channels; ch++) {
    
            for(i=0; i<256; i++) {
    
                s->output[ch][i] += s->add_bias;
    
            s->dsp.float_to_int16(s->int_output[ch], s->output[ch], 256);
    
    /**
     * Decode a single AC-3 frame.
    
    static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t *buf, int buf_size)
    
        AC3DecodeContext *s = avctx->priv_data;
    
        int16_t *out_samples = (int16_t *)data;
    
        int i, blk, ch, err;
    
        /* initialize the GetBitContext with the start of valid AC-3 Frame */
    
        init_get_bits(&s->gbc, buf, buf_size * 8);
    
        if(err) {
            switch(err) {
                case AC3_PARSE_ERROR_SYNC:
                    av_log(avctx, AV_LOG_ERROR, "frame sync error\n");
                    break;
                case AC3_PARSE_ERROR_BSID:
                    av_log(avctx, AV_LOG_ERROR, "invalid bitstream id\n");
                    break;
                case AC3_PARSE_ERROR_SAMPLE_RATE:
                    av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n");
                    break;
                case AC3_PARSE_ERROR_FRAME_SIZE:
                    av_log(avctx, AV_LOG_ERROR, "invalid frame size\n");
                    break;
                default:
                    av_log(avctx, AV_LOG_ERROR, "invalid header\n");
                    break;
            }
            return -1;
    
    Justin Ruggles's avatar
    Justin Ruggles committed
        /* check that reported frame size fits in input buffer */
    
        if(s->frame_size > buf_size) {
    
    Justin Ruggles's avatar
    Justin Ruggles committed
            av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
            return -1;
        }
    
    
        /* check for crc mismatch */
    
        if(avctx->error_resilience > 0) {
    
    Aurelien Jacobs's avatar
    Aurelien Jacobs committed
            if(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2], s->frame_size-2)) {
    
                av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n");
                return -1;
            }
            /* TODO: error concealment */
    
    
        avctx->sample_rate = s->sample_rate;
        avctx->bit_rate = s->bit_rate;
    
    
        s->out_channels = s->channels;
    
        if (avctx->request_channels > 0 && avctx->request_channels <= 2 &&
    
            avctx->request_channels < s->channels) {
            s->out_channels = avctx->request_channels;
            s->output_mode  = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO;
    
        avctx->channels = s->out_channels;
    
        /* parse the audio blocks */
    
        for (blk = 0; blk < NB_BLOCKS; blk++) {
    
            if (ac3_parse_audio_block(s, blk)) {
    
                av_log(avctx, AV_LOG_ERROR, "error parsing the audio block\n");
                *data_size = 0;
    
                for (ch = 0; ch < s->out_channels; ch++)
                    *(out_samples++) = s->int_output[ch][i];
    
        *data_size = NB_BLOCKS * 256 * avctx->channels * sizeof (int16_t);
    
    /**
     * Uninitialize the AC-3 decoder.
    
     */
    static int ac3_decode_end(AVCodecContext *avctx)
    
        AC3DecodeContext *s = avctx->priv_data;
    
        ff_mdct_end(&s->imdct_512);
        ff_mdct_end(&s->imdct_256);
    
        .name = "ac3",
        .type = CODEC_TYPE_AUDIO,
        .id = CODEC_ID_AC3,
        .priv_data_size = sizeof (AC3DecodeContext),
        .init = ac3_decode_init,
        .close = ac3_decode_end,
        .decode = ac3_decode_frame,