⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dca.c

📁 ffmpeg的完整源代码和作者自己写的文档。不但有在Linux的工程哦
💻 C
📖 第 1 页 / 共 3 页
字号:
static int dca_subsubframe(DCAContext * s){    int k, l;    int subsubframe = s->current_subsubframe;    float *quant_step_table;    /* FIXME */    float subband_samples[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8];    /*     * Audio data     */    /* Select quantization step size table */    if (s->bit_rate == 0x1f)        quant_step_table = (float *) lossless_quant_d;    else        quant_step_table = (float *) lossy_quant_d;    for (k = 0; k < s->prim_channels; k++) {        for (l = 0; l < s->vq_start_subband[k]; l++) {            int m;            /* Select the mid-tread linear quantizer */            int abits = s->bitalloc[k][l];            float quant_step_size = quant_step_table[abits];            float rscale;            /*             * Determine quantization index code book and its type             */            /* Select quantization index code book */            int sel = s->quant_index_huffman[k][abits];            /*             * Extract bits from the bit stream             */            if(!abits){                memset(subband_samples[k][l], 0, 8 * sizeof(subband_samples[0][0][0]));            }else if(abits >= 11 || !dca_smpl_bitalloc[abits].vlc[sel].table){                if(abits <= 7){                    /* Block code */                    int block_code1, block_code2, size, levels;                    int block[8];                    size = abits_sizes[abits-1];                    levels = abits_levels[abits-1];                    block_code1 = get_bits(&s->gb, size);                    /* FIXME Should test return value */                    decode_blockcode(block_code1, levels, block);                    block_code2 = get_bits(&s->gb, size);                    decode_blockcode(block_code2, levels, &block[4]);                    for (m = 0; m < 8; m++)                        subband_samples[k][l][m] = block[m];                }else{                    /* no coding */                    for (m = 0; m < 8; m++)                        subband_samples[k][l][m] = get_sbits(&s->gb, abits - 3);                }            }else{                /* Huffman coded */                for (m = 0; m < 8; m++)                    subband_samples[k][l][m] = get_bitalloc(&s->gb, &dca_smpl_bitalloc[abits], sel);            }            /* Deal with transients */            if (s->transition_mode[k][l] &&                subsubframe >= s->transition_mode[k][l])                rscale = quant_step_size * s->scale_factor[k][l][1];            else                rscale = quant_step_size * s->scale_factor[k][l][0];            rscale *= s->scalefactor_adj[k][sel];            for (m = 0; m < 8; m++)                subband_samples[k][l][m] *= rscale;            /*             * Inverse ADPCM if in prediction mode             */            if (s->prediction_mode[k][l]) {                int n;                for (m = 0; m < 8; m++) {                    for (n = 1; n <= 4; n++)                        if (m >= n)                            subband_samples[k][l][m] +=                                (adpcm_vb[s->prediction_vq[k][l]][n - 1] *                                 subband_samples[k][l][m - n] / 8192);                        else if (s->predictor_history)                            subband_samples[k][l][m] +=                                (adpcm_vb[s->prediction_vq[k][l]][n - 1] *                                 s->subband_samples_hist[k][l][m - n +                                                               4] / 8192);                }            }        }        /*         * Decode VQ encoded high frequencies         */        for (l = s->vq_start_subband[k]; l < s->subband_activity[k]; l++) {            /* 1 vector -> 32 samples but we only need the 8 samples             * for this subsubframe. */            int m;            if (!s->debug_flag & 0x01) {                av_log(s->avctx, AV_LOG_DEBUG, "Stream with high frequencies VQ coding\n");                s->debug_flag |= 0x01;            }            for (m = 0; m < 8; m++) {                subband_samples[k][l][m] =                    high_freq_vq[s->high_freq_vq[k][l]][subsubframe * 8 +                                                        m]                    * (float) s->scale_factor[k][l][0] / 16.0;            }        }    }    /* Check for DSYNC after subsubframe */    if (s->aspf || subsubframe == s->subsubframes - 1) {        if (0xFFFF == get_bits(&s->gb, 16)) {   /* 0xFFFF */#ifdef TRACE            av_log(s->avctx, AV_LOG_DEBUG, "Got subframe DSYNC\n");#endif        } else {            av_log(s->avctx, AV_LOG_ERROR, "Didn't get subframe DSYNC\n");        }    }    /* Backup predictor history for adpcm */    for (k = 0; k < s->prim_channels; k++)        for (l = 0; l < s->vq_start_subband[k]; l++)            memcpy(s->subband_samples_hist[k][l], &subband_samples[k][l][4],                        4 * sizeof(subband_samples[0][0][0]));    /* 32 subbands QMF */    for (k = 0; k < s->prim_channels; k++) {/*        static float pcm_to_double[8] =            {32768.0, 32768.0, 524288.0, 524288.0, 0, 8388608.0, 8388608.0};*/         qmf_32_subbands(s, k, subband_samples[k], &s->samples[256 * k],                            2.0 / 3 /*pcm_to_double[s->source_pcm_res] */ ,                            0 /*s->bias */ );    }    /* Down mixing */    if (s->prim_channels > dca_channels[s->output & DCA_CHANNEL_MASK]) {        dca_downmix(s->samples, s->amode, s->downmix_coef);    }    /* Generate LFE samples for this subsubframe FIXME!!! */    if (s->output & DCA_LFE) {        int lfe_samples = 2 * s->lfe * s->subsubframes;        int i_channels = dca_channels[s->output & DCA_CHANNEL_MASK];        lfe_interpolation_fir(s->lfe, 2 * s->lfe,                              s->lfe_data + lfe_samples +                              2 * s->lfe * subsubframe,                              &s->samples[256 * i_channels],                              8388608.0, s->bias);        /* Outputs 20bits pcm samples */    }    return 0;}static int dca_subframe_footer(DCAContext * s){    int aux_data_count = 0, i;    int lfe_samples;    /*     * Unpack optional information     */    if (s->timestamp)        get_bits(&s->gb, 32);    if (s->aux_data)        aux_data_count = get_bits(&s->gb, 6);    for (i = 0; i < aux_data_count; i++)        get_bits(&s->gb, 8);    if (s->crc_present && (s->downmix || s->dynrange))        get_bits(&s->gb, 16);    lfe_samples = 2 * s->lfe * s->subsubframes;    for (i = 0; i < lfe_samples; i++) {        s->lfe_data[i] = s->lfe_data[i + lfe_samples];    }    return 0;}/** * Decode a dca frame block * * @param s     pointer to the DCAContext */static int dca_decode_block(DCAContext * s){    /* Sanity check */    if (s->current_subframe >= s->subframes) {        av_log(s->avctx, AV_LOG_DEBUG, "check failed: %i>%i",               s->current_subframe, s->subframes);        return -1;    }    if (!s->current_subsubframe) {#ifdef TRACE        av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_header\n");#endif        /* Read subframe header */        if (dca_subframe_header(s))            return -1;    }    /* Read subsubframe */#ifdef TRACE    av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subsubframe\n");#endif    if (dca_subsubframe(s))        return -1;    /* Update state */    s->current_subsubframe++;    if (s->current_subsubframe >= s->subsubframes) {        s->current_subsubframe = 0;        s->current_subframe++;    }    if (s->current_subframe >= s->subframes) {#ifdef TRACE        av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_footer\n");#endif        /* Read subframe footer */        if (dca_subframe_footer(s))            return -1;    }    return 0;}/** * Convert bitstream to one representation based on sync marker */static int dca_convert_bitstream(uint8_t * src, int src_size, uint8_t * dst,                          int max_size){    uint32_t mrk;    int i, tmp;    uint16_t *ssrc = (uint16_t *) src, *sdst = (uint16_t *) dst;    PutBitContext pb;    if((unsigned)src_size > (unsigned)max_size) {        av_log(NULL, AV_LOG_ERROR, "Input frame size larger then DCA_MAX_FRAME_SIZE!\n");        return -1;    }    mrk = AV_RB32(src);    switch (mrk) {    case DCA_MARKER_RAW_BE:        memcpy(dst, src, FFMIN(src_size, max_size));        return FFMIN(src_size, max_size);    case DCA_MARKER_RAW_LE:        for (i = 0; i < (FFMIN(src_size, max_size) + 1) >> 1; i++)            *sdst++ = bswap_16(*ssrc++);        return FFMIN(src_size, max_size);    case DCA_MARKER_14B_BE:    case DCA_MARKER_14B_LE:        init_put_bits(&pb, dst, max_size);        for (i = 0; i < (src_size + 1) >> 1; i++, src += 2) {            tmp = ((mrk == DCA_MARKER_14B_BE) ? AV_RB16(src) : AV_RL16(src)) & 0x3FFF;            put_bits(&pb, 14, tmp);        }        flush_put_bits(&pb);        return (put_bits_count(&pb) + 7) >> 3;    default:        return -1;    }}/** * Main frame decoding function * FIXME add arguments */static int dca_decode_frame(AVCodecContext * avctx,                            void *data, int *data_size,                            uint8_t * buf, int buf_size){    int i, j, k;    int16_t *samples = data;    DCAContext *s = avctx->priv_data;    int channels;    s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer, DCA_MAX_FRAME_SIZE);    if (s->dca_buffer_size == -1) {        av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n");        return -1;    }    init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8);    if (dca_parse_frame_header(s) < 0) {        //seems like the frame is corrupt, try with the next one        *data_size=0;        return buf_size;    }    //set AVCodec values with parsed data    avctx->sample_rate = s->sample_rate;    avctx->bit_rate = s->bit_rate;    channels = s->prim_channels + !!s->lfe;    avctx->channels = avctx->request_channels;    if(avctx->channels == 0) {        avctx->channels = channels;    } else if(channels < avctx->channels) {        av_log(avctx, AV_LOG_WARNING, "DTS source channels are less than "               "specified: output to %d channels.\n", channels);        avctx->channels = channels;    }    if(avctx->channels == 2) {        s->output = DCA_STEREO;    } else if(avctx->channels != channels) {        av_log(avctx, AV_LOG_ERROR, "Cannot downmix DTS to %d channels.\n",               avctx->channels);        return -1;    }    channels = avctx->channels;    if(*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels)        return -1;    *data_size = 0;    for (i = 0; i < (s->sample_blocks / 8); i++) {        dca_decode_block(s);        s->dsp.float_to_int16(s->tsamples, s->samples, 256 * channels);        /* interleave samples */        for (j = 0; j < 256; j++) {            for (k = 0; k < channels; k++)                samples[k] = s->tsamples[j + k * 256];            samples += channels;        }        *data_size += 256 * sizeof(int16_t) * channels;    }    return buf_size;}/** * Build the cosine modulation tables for the QMF * * @param s     pointer to the DCAContext */static void pre_calc_cosmod(DCAContext * s){    int i, j, k;    static int cosmod_inited = 0;    if(cosmod_inited) return;    for (j = 0, k = 0; k < 16; k++)        for (i = 0; i < 16; i++)            cos_mod[j++] = cos((2 * i + 1) * (2 * k + 1) * M_PI / 64);    for (k = 0; k < 16; k++)        for (i = 0; i < 16; i++)            cos_mod[j++] = cos((i) * (2 * k + 1) * M_PI / 32);    for (k = 0; k < 16; k++)        cos_mod[j++] = 0.25 / (2 * cos((2 * k + 1) * M_PI / 128));    for (k = 0; k < 16; k++)        cos_mod[j++] = -0.25 / (2.0 * sin((2 * k + 1) * M_PI / 128));    cosmod_inited = 1;}/** * DCA initialization * * @param avctx     pointer to the AVCodecContext */static int dca_decode_init(AVCodecContext * avctx){    DCAContext *s = avctx->priv_data;    s->avctx = avctx;    dca_init_vlcs();    pre_calc_cosmod(s);    dsputil_init(&s->dsp, avctx);    return 0;}AVCodec dca_decoder = {    .name = "dca",    .type = CODEC_TYPE_AUDIO,    .id = CODEC_ID_DTS,    .priv_data_size = sizeof(DCAContext),    .init = dca_decode_init,    .decode = dca_decode_frame,};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -