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

📄 cook.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 * @param mlt_buffer1       pointer to left channel mlt coefficients * @param mlt_buffer2       pointer to right channel mlt coefficients */static void joint_decode(COOKContext *q, float* mlt_buffer1,                         float* mlt_buffer2) {    int i,j;    int decouple_tab[SUBBAND_SIZE];    float *decode_buffer = q->decode_buffer_0;    int idx, cpl_tmp;    float f1,f2;    const float* cplscale;    memset(decouple_tab, 0, sizeof(decouple_tab));    memset(decode_buffer, 0, sizeof(decode_buffer));    /* Make sure the buffers are zeroed out. */    memset(mlt_buffer1,0, 1024*sizeof(float));    memset(mlt_buffer2,0, 1024*sizeof(float));    decouple_info(q, decouple_tab);    mono_decode(q, decode_buffer);    /* The two channels are stored interleaved in decode_buffer. */    for (i=0 ; i<q->js_subband_start ; i++) {        for (j=0 ; j<SUBBAND_SIZE ; j++) {            mlt_buffer1[i*20+j] = decode_buffer[i*40+j];            mlt_buffer2[i*20+j] = decode_buffer[i*40+20+j];        }    }    /* When we reach js_subband_start (the higher frequencies)       the coefficients are stored in a coupling scheme. */    idx = (1 << q->js_vlc_bits) - 1;    for (i=q->js_subband_start ; i<q->subbands ; i++) {        cpl_tmp = cplband[i];        idx -=decouple_tab[cpl_tmp];        cplscale = q->cplscales[q->js_vlc_bits-2];  //choose decoupler table        f1 = cplscale[decouple_tab[cpl_tmp]];        f2 = cplscale[idx-1];        q->decouple (q, i, f1, f2, decode_buffer, mlt_buffer1, mlt_buffer2);        idx = (1 << q->js_vlc_bits) - 1;    }}/** * First part of subpacket decoding: *  decode raw stream bytes and read gain info. * * @param q                 pointer to the COOKContext * @param inbuffer          pointer to raw stream data * @param gain_ptr          array of current/prev gain pointers */static inline voiddecode_bytes_and_gain(COOKContext *q, const uint8_t *inbuffer,                      cook_gains *gains_ptr){    int offset;    offset = decode_bytes(inbuffer, q->decoded_bytes_buffer,                          q->bits_per_subpacket/8);    init_get_bits(&q->gb, q->decoded_bytes_buffer + offset,                  q->bits_per_subpacket);    decode_gain_info(&q->gb, gains_ptr->now);    /* Swap current and previous gains */    FFSWAP(int *, gains_ptr->now, gains_ptr->previous);} /** * Saturate the output signal to signed 16bit integers. * * @param q                 pointer to the COOKContext * @param chan              channel to saturate * @param out               pointer to the output vector */static voidsaturate_output_float (COOKContext *q, int chan, int16_t *out){    int j;    float *output = q->mono_mdct_output + q->samples_per_channel;    /* Clip and convert floats to 16 bits.     */    for (j = 0; j < q->samples_per_channel; j++) {        out[chan + q->nb_channels * j] =          av_clip_int16(lrintf(output[j]));    }}/** * Final part of subpacket decoding: *  Apply modulated lapped transform, gain compensation, *  clip and convert to integer. * * @param q                 pointer to the COOKContext * @param decode_buffer     pointer to the mlt coefficients * @param gain_ptr          array of current/prev gain pointers * @param previous_buffer   pointer to the previous buffer to be used for overlapping * @param out               pointer to the output buffer * @param chan              0: left or single channel, 1: right channel */static inline voidmlt_compensate_output(COOKContext *q, float *decode_buffer,                      cook_gains *gains, float *previous_buffer,                      int16_t *out, int chan){    imlt_gain(q, decode_buffer, gains, previous_buffer);    q->saturate_output (q, chan, out);}/** * Cook subpacket decoding. This function returns one decoded subpacket, * usually 1024 samples per channel. * * @param q                 pointer to the COOKContext * @param inbuffer          pointer to the inbuffer * @param sub_packet_size   subpacket size * @param outbuffer         pointer to the outbuffer */static int decode_subpacket(COOKContext *q, const uint8_t *inbuffer,                            int sub_packet_size, int16_t *outbuffer) {    /* packet dump *///    for (i=0 ; i<sub_packet_size ; i++) {//        av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]);//    }//    av_log(NULL, AV_LOG_ERROR, "\n");    decode_bytes_and_gain(q, inbuffer, &q->gains1);    if (q->joint_stereo) {        joint_decode(q, q->decode_buffer_1, q->decode_buffer_2);    } else {        mono_decode(q, q->decode_buffer_1);        if (q->nb_channels == 2) {            decode_bytes_and_gain(q, inbuffer + sub_packet_size/2, &q->gains2);            mono_decode(q, q->decode_buffer_2);        }    }    mlt_compensate_output(q, q->decode_buffer_1, &q->gains1,                          q->mono_previous_buffer1, outbuffer, 0);    if (q->nb_channels == 2) {        if (q->joint_stereo) {            mlt_compensate_output(q, q->decode_buffer_2, &q->gains1,                                  q->mono_previous_buffer2, outbuffer, 1);        } else {            mlt_compensate_output(q, q->decode_buffer_2, &q->gains2,                                  q->mono_previous_buffer2, outbuffer, 1);        }    }    return q->samples_per_frame * sizeof(int16_t);}/** * Cook frame decoding * * @param avctx     pointer to the AVCodecContext */static int cook_decode_frame(AVCodecContext *avctx,            void *data, int *data_size,            const uint8_t *buf, int buf_size) {    COOKContext *q = avctx->priv_data;    if (buf_size < avctx->block_align)        return buf_size;    *data_size = decode_subpacket(q, buf, avctx->block_align, data);    /* Discard the first two frames: no valid audio. */    if (avctx->frame_number < 2) *data_size = 0;    return avctx->block_align;}#ifdef COOKDEBUGstatic void dump_cook_context(COOKContext *q){    //int i=0;#define PRINT(a,b) av_log(NULL,AV_LOG_ERROR," %s = %d\n", a, b);    av_log(NULL,AV_LOG_ERROR,"COOKextradata\n");    av_log(NULL,AV_LOG_ERROR,"cookversion=%x\n",q->cookversion);    if (q->cookversion > STEREO) {        PRINT("js_subband_start",q->js_subband_start);        PRINT("js_vlc_bits",q->js_vlc_bits);    }    av_log(NULL,AV_LOG_ERROR,"COOKContext\n");    PRINT("nb_channels",q->nb_channels);    PRINT("bit_rate",q->bit_rate);    PRINT("sample_rate",q->sample_rate);    PRINT("samples_per_channel",q->samples_per_channel);    PRINT("samples_per_frame",q->samples_per_frame);    PRINT("subbands",q->subbands);    PRINT("random_state",q->random_state);    PRINT("js_subband_start",q->js_subband_start);    PRINT("log2_numvector_size",q->log2_numvector_size);    PRINT("numvector_size",q->numvector_size);    PRINT("total_subbands",q->total_subbands);}#endif/** * Cook initialization * * @param avctx     pointer to the AVCodecContext */static int cook_decode_init(AVCodecContext *avctx){    COOKContext *q = avctx->priv_data;    const uint8_t *edata_ptr = avctx->extradata;    /* Take care of the codec specific extradata. */    if (avctx->extradata_size <= 0) {        av_log(avctx,AV_LOG_ERROR,"Necessary extradata missing!\n");        return -1;    } else {        /* 8 for mono, 16 for stereo, ? for multichannel           Swap to right endianness so we don't need to care later on. */        av_log(avctx,AV_LOG_DEBUG,"codecdata_length=%d\n",avctx->extradata_size);        if (avctx->extradata_size >= 8){            q->cookversion = bytestream_get_be32(&edata_ptr);            q->samples_per_frame =  bytestream_get_be16(&edata_ptr);            q->subbands = bytestream_get_be16(&edata_ptr);        }        if (avctx->extradata_size >= 16){            bytestream_get_be32(&edata_ptr);    //Unknown unused            q->js_subband_start = bytestream_get_be16(&edata_ptr);            q->js_vlc_bits = bytestream_get_be16(&edata_ptr);        }    }    /* Take data from the AVCodecContext (RM container). */    q->sample_rate = avctx->sample_rate;    q->nb_channels = avctx->channels;    q->bit_rate = avctx->bit_rate;    /* Initialize RNG. */    av_init_random(1, &q->random_state);    /* Initialize extradata related variables. */    q->samples_per_channel = q->samples_per_frame / q->nb_channels;    q->bits_per_subpacket = avctx->block_align * 8;    /* Initialize default data states. */    q->log2_numvector_size = 5;    q->total_subbands = q->subbands;    /* Initialize version-dependent variables */    av_log(NULL,AV_LOG_DEBUG,"q->cookversion=%x\n",q->cookversion);    q->joint_stereo = 0;    switch (q->cookversion) {        case MONO:            if (q->nb_channels != 1) {                av_log(avctx,AV_LOG_ERROR,"Container channels != 1, report sample!\n");                return -1;            }            av_log(avctx,AV_LOG_DEBUG,"MONO\n");            break;        case STEREO:            if (q->nb_channels != 1) {                q->bits_per_subpacket = q->bits_per_subpacket/2;            }            av_log(avctx,AV_LOG_DEBUG,"STEREO\n");            break;        case JOINT_STEREO:            if (q->nb_channels != 2) {                av_log(avctx,AV_LOG_ERROR,"Container channels != 2, report sample!\n");                return -1;            }            av_log(avctx,AV_LOG_DEBUG,"JOINT_STEREO\n");            if (avctx->extradata_size >= 16){                q->total_subbands = q->subbands + q->js_subband_start;                q->joint_stereo = 1;            }            if (q->samples_per_channel > 256) {                q->log2_numvector_size  = 6;            }            if (q->samples_per_channel > 512) {                q->log2_numvector_size  = 7;            }            break;        case MC_COOK:            av_log(avctx,AV_LOG_ERROR,"MC_COOK not supported!\n");            return -1;            break;        default:            av_log(avctx,AV_LOG_ERROR,"Unknown Cook version, report sample!\n");            return -1;            break;    }    /* Initialize variable relations */    q->numvector_size = (1 << q->log2_numvector_size);    /* Generate tables */    init_pow2table();    init_gain_table(q);    init_cplscales_table(q);    if (init_cook_vlc_tables(q) != 0)        return -1;    if(avctx->block_align >= UINT_MAX/2)        return -1;    /* Pad the databuffer with:       DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(),       FF_INPUT_BUFFER_PADDING_SIZE, for the bitstreamreader. */    if (q->nb_channels==2 && q->joint_stereo==0) {        q->decoded_bytes_buffer =          av_mallocz(avctx->block_align/2                     + DECODE_BYTES_PAD2(avctx->block_align/2)                     + FF_INPUT_BUFFER_PADDING_SIZE);    } else {        q->decoded_bytes_buffer =          av_mallocz(avctx->block_align                     + DECODE_BYTES_PAD1(avctx->block_align)                     + FF_INPUT_BUFFER_PADDING_SIZE);    }    if (q->decoded_bytes_buffer == NULL)        return -1;    q->gains1.now      = q->gain_1;    q->gains1.previous = q->gain_2;    q->gains2.now      = q->gain_3;    q->gains2.previous = q->gain_4;    /* Initialize transform. */    if ( init_cook_mlt(q) != 0 )        return -1;    /* Initialize COOK signal arithmetic handling */    if (1) {        q->scalar_dequant  = scalar_dequant_float;        q->decouple        = decouple_float;        q->imlt_window     = imlt_window_float;        q->interpolate     = interpolate_float;        q->saturate_output = saturate_output_float;    }    /* Try to catch some obviously faulty streams, othervise it might be exploitable */    if (q->total_subbands > 53) {        av_log(avctx,AV_LOG_ERROR,"total_subbands > 53, report sample!\n");        return -1;    }    if (q->subbands > 50) {        av_log(avctx,AV_LOG_ERROR,"subbands > 50, report sample!\n");        return -1;    }    if ((q->samples_per_channel == 256) || (q->samples_per_channel == 512) || (q->samples_per_channel == 1024)) {    } else {        av_log(avctx,AV_LOG_ERROR,"unknown amount of samples_per_channel = %d, report sample!\n",q->samples_per_channel);        return -1;    }    if ((q->js_vlc_bits > 6) || (q->js_vlc_bits < 0)) {        av_log(avctx,AV_LOG_ERROR,"q->js_vlc_bits = %d, only >= 0 and <= 6 allowed!\n",q->js_vlc_bits);        return -1;    }#ifdef COOKDEBUG    dump_cook_context(q);#endif    return 0;}AVCodec cook_decoder ={#ifdef __CW32__    "cook",    CODEC_TYPE_AUDIO,    CODEC_ID_COOK,    sizeof(COOKContext),    cook_decode_init,    0,    cook_decode_close,    cook_decode_frame,    0,    0,    0,    0,    0,    NULL_IF_CONFIG_SMALL("COOK"),#else    .name = "cook",    .type = CODEC_TYPE_AUDIO,    .id = CODEC_ID_COOK,    .priv_data_size = sizeof(COOKContext),    .init = cook_decode_init,    .close = cook_decode_close,    .decode = cook_decode_frame,    .long_name = NULL_IF_CONFIG_SMALL("COOK"),#endif};

⌨️ 快捷键说明

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