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

📄 qdm2.c

📁 现在关于h.264的源码很多
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (++tone->time_index < ((1 << (5 - tone->duration)) - 1)) {      memcpy(&q->fft_tones[q->fft_tone_end], tone, sizeof(FFTTone));      q->fft_tone_end = (q->fft_tone_end + 1) % 1000;    }}static void qdm2_fft_tone_synthesizer (QDM2Context *q, int sub_packet){    int i, j, ch;    const double iscale = 0.25 * M_PI;    for (ch = 0; ch < q->channels; ch++) {        memset(q->fft.samples_im[ch], 0, q->fft_size * sizeof(float));        memset(q->fft.samples_re[ch], 0, q->fft_size * sizeof(float));    }    /* apply FFT tones with duration 4 (1 FFT period) */    if (q->fft_coefs_min_index[4] >= 0)        for (i = q->fft_coefs_min_index[4]; i < q->fft_coefs_max_index[4]; i++) {            float level;            QDM2Complex c;            if (q->fft_coefs[i].sub_packet != sub_packet)                break;            ch = (q->channels == 1) ? 0 : q->fft_coefs[i].channel;            level = (q->fft_coefs[i].exp < 0) ? 0.0 : fft_tone_level_table[q->superblocktype_2_3 ? 0 : 1][q->fft_coefs[i].exp & 63];            c.re = level * cos(q->fft_coefs[i].phase * iscale);            c.im = level * sin(q->fft_coefs[i].phase * iscale);            q->fft.samples_re[ch][q->fft_coefs[i].offset + 0] += c.re;            q->fft.samples_im[ch][q->fft_coefs[i].offset + 0] += c.im;            q->fft.samples_re[ch][q->fft_coefs[i].offset + 1] -= c.re;            q->fft.samples_im[ch][q->fft_coefs[i].offset + 1] -= c.im;        }    /* generate existing FFT tones */    for (i = q->fft_tone_end; i != q->fft_tone_start; ) {        qdm2_fft_generate_tone(q, &q->fft_tones[q->fft_tone_start]);        q->fft_tone_start = (q->fft_tone_start + 1) % 1000;    }    /* create and generate new FFT tones with duration 0 (long) to 3 (short) */    for (i = 0; i < 4; i++)        if (q->fft_coefs_min_index[i] >= 0) {            for (j = q->fft_coefs_min_index[i]; j < q->fft_coefs_max_index[i]; j++) {                int offset, four_i;                FFTTone tone;                if (q->fft_coefs[j].sub_packet != sub_packet)                    break;                four_i = (4 - i);                offset = q->fft_coefs[j].offset >> four_i;                ch = (q->channels == 1) ? 0 : q->fft_coefs[j].channel;                if (offset < q->frequency_range) {                    if (offset < 2)                        tone.cutoff = offset;                    else                        tone.cutoff = (offset >= 60) ? 3 : 2;                    tone.level = (q->fft_coefs[j].exp < 0) ? 0.0 : fft_tone_level_table[q->superblocktype_2_3 ? 0 : 1][q->fft_coefs[j].exp & 63];                    tone.samples_im = &q->fft.samples_im[ch][offset];                    tone.samples_re = &q->fft.samples_re[ch][offset];                    tone.table = (float*)fft_tone_sample_table[i][q->fft_coefs[j].offset - (offset << four_i)];                    tone.phase = 64 * q->fft_coefs[j].phase - (offset << 8) - 128;                    tone.phase_shift = (2 * q->fft_coefs[j].offset + 1) << (7 - four_i);                    tone.duration = i;                    tone.time_index = 0;                    qdm2_fft_generate_tone(q, &tone);                }            }            q->fft_coefs_min_index[i] = j;        }}static void qdm2_calculate_fft (QDM2Context *q, int channel, int sub_packet){    const int n = 1 << (q->fft_order - 1);    const int n2 = n >> 1;    const float gain = (q->channels == 1 && q->nb_channels == 2) ? 0.25f : 0.50f;    float c, s, f0, f1, f2, f3;    int i, j;    /* prerotation (or something like that) */    for (i=1; i < n2; i++) {        j  = (n - i);        c = q->exptab[i].re;        s = -q->exptab[i].im;        f0 = (q->fft.samples_re[channel][i] - q->fft.samples_re[channel][j]) * gain;        f1 = (q->fft.samples_im[channel][i] + q->fft.samples_im[channel][j]) * gain;        f2 = (q->fft.samples_re[channel][i] + q->fft.samples_re[channel][j]) * gain;        f3 = (q->fft.samples_im[channel][i] - q->fft.samples_im[channel][j]) * gain;        q->fft.complex[i].re =  s * f0 - c * f1 + f2;        q->fft.complex[i].im =  c * f0 + s * f1 + f3;        q->fft.complex[j].re = -s * f0 + c * f1 + f2;        q->fft.complex[j].im =  c * f0 + s * f1 - f3;    }    q->fft.complex[ 0].re =  q->fft.samples_re[channel][ 0] * gain * 2.0;    q->fft.complex[ 0].im =  q->fft.samples_re[channel][ 0] * gain * 2.0;    q->fft.complex[n2].re =  q->fft.samples_re[channel][n2] * gain * 2.0;    q->fft.complex[n2].im = -q->fft.samples_im[channel][n2] * gain * 2.0;    ff_fft_permute(&q->fft_ctx, (FFTComplex *) q->fft.complex);    ff_fft_calc (&q->fft_ctx, (FFTComplex *) q->fft.complex);    /* add samples to output buffer */    for (i = 0; i < ((q->fft_frame_size + 15) & ~15); i++)        q->output_buffer[q->channels * i + channel] += ((float *) q->fft.complex)[i];}/** * @param q        context * @param index    subpacket number */static void qdm2_synthesis_filter (QDM2Context *q, int index){    OUT_INT samples[MPA_MAX_CHANNELS * MPA_FRAME_SIZE];    int i, k, ch, sb_used, sub_sampling, dither_state = 0;    /* copy sb_samples */    sb_used = QDM2_SB_USED(q->sub_sampling);    for (ch = 0; ch < q->channels; ch++)        for (i = 0; i < 8; i++)            for (k=sb_used; k < SBLIMIT; k++)                q->sb_samples[ch][(8 * index) + i][k] = 0;    for (ch = 0; ch < q->nb_channels; ch++) {        OUT_INT *samples_ptr = samples + ch;        for (i = 0; i < 8; i++) {            ff_mpa_synth_filter(q->synth_buf[ch], &(q->synth_buf_offset[ch]),                mpa_window, &dither_state,                samples_ptr, q->nb_channels,                q->sb_samples[ch][(8 * index) + i]);            samples_ptr += 32 * q->nb_channels;        }    }    /* add samples to output buffer */    sub_sampling = (4 >> q->sub_sampling);    for (ch = 0; ch < q->channels; ch++)        for (i = 0; i < q->frame_size; i++)            q->output_buffer[q->channels * i + ch] += (float)(samples[q->nb_channels * sub_sampling * i + ch] >> (sizeof(OUT_INT)*8-16));}/** * Init static data (does not depend on specific file) * * @param q    context */static void qdm2_init(QDM2Context *q) {    static int inited = 0;    if (inited != 0)        return;    inited = 1;    qdm2_init_vlc();    ff_mpa_synth_init(mpa_window);    softclip_table_init();    rnd_table_init();    init_noise_samples();    av_log(NULL, AV_LOG_DEBUG, "init done\n");}#if 0static void dump_context(QDM2Context *q){    int i;#define PRINT(a,b) av_log(NULL,AV_LOG_DEBUG," %s = %d\n", a, b);    PRINT("compressed_data",q->compressed_data);    PRINT("compressed_size",q->compressed_size);    PRINT("frame_size",q->frame_size);    PRINT("checksum_size",q->checksum_size);    PRINT("channels",q->channels);    PRINT("nb_channels",q->nb_channels);    PRINT("fft_frame_size",q->fft_frame_size);    PRINT("fft_size",q->fft_size);    PRINT("sub_sampling",q->sub_sampling);    PRINT("fft_order",q->fft_order);    PRINT("group_order",q->group_order);    PRINT("group_size",q->group_size);    PRINT("sub_packet",q->sub_packet);    PRINT("frequency_range",q->frequency_range);    PRINT("has_errors",q->has_errors);    PRINT("fft_tone_end",q->fft_tone_end);    PRINT("fft_tone_start",q->fft_tone_start);    PRINT("fft_coefs_index",q->fft_coefs_index);    PRINT("coeff_per_sb_select",q->coeff_per_sb_select);    PRINT("cm_table_select",q->cm_table_select);    PRINT("noise_idx",q->noise_idx);    for (i = q->fft_tone_start; i < q->fft_tone_end; i++)    {    FFTTone *t = &q->fft_tones[i];    av_log(NULL,AV_LOG_DEBUG,"Tone (%d) dump:\n", i);    av_log(NULL,AV_LOG_DEBUG,"  level = %f\n", t->level);//  PRINT(" level", t->level);    PRINT(" phase", t->phase);    PRINT(" phase_shift", t->phase_shift);    PRINT(" duration", t->duration);    PRINT(" samples_im", t->samples_im);    PRINT(" samples_re", t->samples_re);    PRINT(" table", t->table);    }}#endif/** * Init parameters from codec extradata */static int qdm2_decode_init(AVCodecContext *avctx){    QDM2Context *s = avctx->priv_data;    uint8_t *extradata;    int extradata_size;    int tmp_val, tmp, size;    int i;    float alpha;    /* extradata parsing    Structure:    wave {        frma (QDM2)        QDCA        QDCP    }    32  size (including this field)    32  tag (=frma)    32  type (=QDM2 or QDMC)    32  size (including this field, in bytes)    32  tag (=QDCA) // maybe mandatory parameters    32  unknown (=1)    32  channels (=2)    32  samplerate (=44100)    32  bitrate (=96000)    32  block size (=4096)    32  frame size (=256) (for one channel)    32  packet size (=1300)    32  size (including this field, in bytes)    32  tag (=QDCP) // maybe some tuneable parameters    32  float1 (=1.0)    32  zero ?    32  float2 (=1.0)    32  float3 (=1.0)    32  unknown (27)    32  unknown (8)    32  zero ?    */    if (!avctx->extradata || (avctx->extradata_size < 48)) {        av_log(avctx, AV_LOG_ERROR, "extradata missing or truncated\n");        return -1;    }    extradata = avctx->extradata;    extradata_size = avctx->extradata_size;    while (extradata_size > 7) {        if (!memcmp(extradata, "frmaQDM", 7))            break;        extradata++;        extradata_size--;    }    if (extradata_size < 12) {        av_log(avctx, AV_LOG_ERROR, "not enough extradata (%i)\n",               extradata_size);        return -1;    }    if (memcmp(extradata, "frmaQDM", 7)) {        av_log(avctx, AV_LOG_ERROR, "invalid headers, QDM? not found\n");        return -1;    }    if (extradata[7] == 'C') {//        s->is_qdmc = 1;        av_log(avctx, AV_LOG_ERROR, "stream is QDMC version 1, which is not supported\n");        return -1;    }    extradata += 8;    extradata_size -= 8;    size = BE_32(extradata);    if(size > extradata_size){        av_log(avctx, AV_LOG_ERROR, "extradata size too small, %i < %i\n",               extradata_size, size);        return -1;    }    extradata += 4;    av_log(avctx, AV_LOG_DEBUG, "size: %d\n", size);    if (BE_32(extradata) != MKBETAG('Q','D','C','A')) {        av_log(avctx, AV_LOG_ERROR, "invalid extradata, expecting QDCA\n");        return -1;    }    extradata += 8;    avctx->channels = s->nb_channels = s->channels = BE_32(extradata);    extradata += 4;    avctx->sample_rate = BE_32(extradata);    extradata += 4;    avctx->bit_rate = BE_32(extradata);    extradata += 4;    s->group_size = BE_32(extradata);    extradata += 4;    s->fft_size = BE_32(extradata);    extradata += 4;    s->checksum_size = BE_32(extradata);    extradata += 4;    s->fft_order = av_log2(s->fft_size) + 1;    s->fft_frame_size = 2 * s->fft_size; // complex has two floats    // something like max decodable tones    s->group_order = av_log2(s->group_size) + 1;    s->frame_size = s->group_size / 16; // 16 iterations per super block    s->sub_sampling = s->fft_order - 7;    s->frequency_range = 255 / (1 << (2 - s->sub_sampling));    switch ((s->sub_sampling * 2 + s->channels - 1)) {        case 0: tmp = 40; break;        case 1: tmp = 48; break;        case 2: tmp = 56; break;        case 3: tmp = 72; break;        case 4: tmp = 80; break;        case 5: tmp = 100;break;        default: tmp=s->sub_sampling; break;    }    tmp_val = 0;    if ((tmp * 1000) < avctx->bit_rate)  tmp_val = 1;    if ((tmp * 1440) < avctx->bit_rate)  tmp_val = 2;    if ((tmp * 1760) < avctx->bit_rate)  tmp_val = 3;    if ((tmp * 2240) < avctx->bit_rate)  tmp_val = 4;    s->cm_table_select = tmp_val;    if (s->sub_sampling == 0)        tmp = 7999;    else        tmp = ((-(s->sub_sampling -1)) & 8000) + 20000;    /*    0: 7999 -> 0    1: 20000 -> 2    2: 28000 -> 2    */    if (tmp < 8000)        s->coeff_per_sb_select = 0;    else if (tmp <= 16000)        s->coeff_per_sb_select = 1;    else        s->coeff_per_sb_select = 2;    // Fail on unknown fft order, if it's > 9 it can overflow s->exptab[] 

⌨️ 快捷键说明

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