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

📄 qdm2.c

📁 现在关于h.264的源码很多
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * QDM2 compatible decoder * Copyright (c) 2003 Ewald Snel * Copyright (c) 2005 Benjamin Larsson * Copyright (c) 2005 Alex Beregszaszi * Copyright (c) 2005 Roberto Togni * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * *//** * @file qdm2.c * QDM2 decoder * @author Ewald Snel, Benjamin Larsson, Alex Beregszaszi, Roberto Togni * The decoder is not perfect yet, there are still some distortions * especially on files encoded with 16 or 8 subbands. */#include <math.h>#include <stddef.h>#include <stdio.h>#define ALT_BITSTREAM_READER_LE#include "avcodec.h"#include "bitstream.h"#include "dsputil.h"#ifdef CONFIG_MPEGAUDIO_HP#define USE_HIGHPRECISION#endif#include "mpegaudio.h"#include "qdm2data.h"#undef NDEBUG#include <assert.h>#define SOFTCLIP_THRESHOLD 27600#define HARDCLIP_THRESHOLD 35716#define QDM2_LIST_ADD(list, size, packet) \do { \      if (size > 0) { \    list[size - 1].next = &list[size]; \      } \      list[size].packet = packet; \      list[size].next = NULL; \      size++; \} while(0)// Result is 8, 16 or 30#define QDM2_SB_USED(sub_sampling) (((sub_sampling) >= 2) ? 30 : 8 << (sub_sampling))#define FIX_NOISE_IDX(noise_idx) \  if ((noise_idx) >= 3840) \    (noise_idx) -= 3840; \#define SB_DITHERING_NOISE(sb,noise_idx) (noise_table[(noise_idx)++] * sb_noise_attenuation[(sb)])#define BITS_LEFT(length,gb) ((length) - get_bits_count ((gb)))#define SAMPLES_NEEDED \     av_log (NULL,AV_LOG_INFO,"This file triggers some untested code. Please contact the developers.\n");#define SAMPLES_NEEDED_2(why) \     av_log (NULL,AV_LOG_INFO,"This file triggers some missing code. Please contact the developers.\nPosition: %s\n",why);typedef int8_t sb_int8_array[2][30][64];/** * Subpacket */typedef struct {    int type;            ///< subpacket type    unsigned int size;   ///< subpacket size    const uint8_t *data; ///< pointer to subpacket data (points to input data buffer, it's not a private copy)} QDM2SubPacket;/** * A node in the subpacket list */typedef struct _QDM2SubPNode {    QDM2SubPacket *packet;      ///< packet    struct _QDM2SubPNode *next; ///< pointer to next packet in the list, NULL if leaf node} QDM2SubPNode;typedef struct {    float level;    float *samples_im;    float *samples_re;    float *table;    int   phase;    int   phase_shift;    int   duration;    short time_index;    short cutoff;} FFTTone;typedef struct {    int16_t sub_packet;    uint8_t channel;    int16_t offset;    int16_t exp;    uint8_t phase;} FFTCoefficient;typedef struct {    float re;    float im;} QDM2Complex;typedef struct {    QDM2Complex complex[256 + 1] __attribute__((aligned(16)));    float       samples_im[MPA_MAX_CHANNELS][256];    float       samples_re[MPA_MAX_CHANNELS][256];} QDM2FFT;/** * QDM2 decoder context */typedef struct {    /// Parameters from codec header, do not change during playback    int nb_channels;         ///< number of channels    int channels;            ///< number of channels    int group_size;          ///< size of frame group (16 frames per group)    int fft_size;            ///< size of FFT, in complex numbers    int checksum_size;       ///< size of data block, used also for checksum    /// Parameters built from header parameters, do not change during playback    int group_order;         ///< order of frame group    int fft_order;           ///< order of FFT (actually fftorder+1)    int fft_frame_size;      ///< size of fft frame, in components (1 comples = re + im)    int frame_size;          ///< size of data frame    int frequency_range;    int sub_sampling;        ///< subsampling: 0=25%, 1=50%, 2=100% */    int coeff_per_sb_select; ///< selector for "num. of coeffs. per subband" tables. Can be 0, 1, 2    int cm_table_select;     ///< selector for "coding method" tables. Can be 0, 1 (from init: 0-4)    /// Packets and packet lists    QDM2SubPacket sub_packets[16];      ///< the packets themselves    QDM2SubPNode sub_packet_list_A[16]; ///< list of all packets    QDM2SubPNode sub_packet_list_B[16]; ///< FFT packets B are on list    int sub_packets_B;                  ///< number of packets on 'B' list    QDM2SubPNode sub_packet_list_C[16]; ///< packets with errors?    QDM2SubPNode sub_packet_list_D[16]; ///< DCT packets    /// FFT and tones    FFTTone fft_tones[1000];    int fft_tone_start;    int fft_tone_end;    FFTCoefficient fft_coefs[1000];    int fft_coefs_index;    int fft_coefs_min_index[5];    int fft_coefs_max_index[5];    int fft_level_exp[6];    FFTContext fft_ctx;    FFTComplex exptab[128];    QDM2FFT fft;    /// I/O data    uint8_t *compressed_data;    int compressed_size;    float output_buffer[1024];    /// Synthesis filter    MPA_INT synth_buf[MPA_MAX_CHANNELS][512*2] __attribute__((aligned(16)));    int synth_buf_offset[MPA_MAX_CHANNELS];    int32_t sb_samples[MPA_MAX_CHANNELS][128][SBLIMIT] __attribute__((aligned(16)));    /// Mixed temporary data used in decoding    float tone_level[MPA_MAX_CHANNELS][30][64];    int8_t coding_method[MPA_MAX_CHANNELS][30][64];    int8_t quantized_coeffs[MPA_MAX_CHANNELS][10][8];    int8_t tone_level_idx_base[MPA_MAX_CHANNELS][30][8];    int8_t tone_level_idx_hi1[MPA_MAX_CHANNELS][3][8][8];    int8_t tone_level_idx_mid[MPA_MAX_CHANNELS][26][8];    int8_t tone_level_idx_hi2[MPA_MAX_CHANNELS][26];    int8_t tone_level_idx[MPA_MAX_CHANNELS][30][64];    int8_t tone_level_idx_temp[MPA_MAX_CHANNELS][30][64];    // Flags    int has_errors;         ///< packet has errors    int superblocktype_2_3; ///< select fft tables and some algorithm based on superblock type    int do_synth_filter;    ///< used to perform or skip synthesis filter    int sub_packet;    int noise_idx; ///< index for dithering noise table} QDM2Context;static uint8_t empty_buffer[FF_INPUT_BUFFER_PADDING_SIZE];static VLC vlc_tab_level;static VLC vlc_tab_diff;static VLC vlc_tab_run;static VLC fft_level_exp_alt_vlc;static VLC fft_level_exp_vlc;static VLC fft_stereo_exp_vlc;static VLC fft_stereo_phase_vlc;static VLC vlc_tab_tone_level_idx_hi1;static VLC vlc_tab_tone_level_idx_mid;static VLC vlc_tab_tone_level_idx_hi2;static VLC vlc_tab_type30;static VLC vlc_tab_type34;static VLC vlc_tab_fft_tone_offset[5];static uint16_t softclip_table[HARDCLIP_THRESHOLD - SOFTCLIP_THRESHOLD + 1];static float noise_table[4096];static uint8_t random_dequant_index[256][5];static uint8_t random_dequant_type24[128][3];static float noise_samples[128];static MPA_INT mpa_window[512] __attribute__((aligned(16)));static void softclip_table_init(void) {    int i;    double dfl = SOFTCLIP_THRESHOLD - 32767;    float delta = 1.0 / -dfl;    for (i = 0; i < HARDCLIP_THRESHOLD - SOFTCLIP_THRESHOLD + 1; i++)        softclip_table[i] = SOFTCLIP_THRESHOLD - ((int)(sin((float)i * delta) * dfl) & 0x0000FFFF);}// random generated tablestatic void rnd_table_init(void) {    int i,j;    uint32_t ldw,hdw;    uint64_t tmp64_1;    uint64_t random_seed = 0;    float delta = 1.0 / 16384.0;    for(i = 0; i < 4096 ;i++) {        random_seed = random_seed * 214013 + 2531011;        noise_table[i] = (delta * (float)(((int32_t)random_seed >> 16) & 0x00007FFF)- 1.0) * 1.3;    }    for (i = 0; i < 256 ;i++) {        random_seed = 81;        ldw = i;        for (j = 0; j < 5 ;j++) {            random_dequant_index[i][j] = (uint8_t)((ldw / random_seed) & 0xFF);            ldw = (uint32_t)ldw % (uint32_t)random_seed;            tmp64_1 = (random_seed * 0x55555556);            hdw = (uint32_t)(tmp64_1 >> 32);            random_seed = (uint64_t)(hdw + (ldw >> 31));        }    }    for (i = 0; i < 128 ;i++) {        random_seed = 25;        ldw = i;        for (j = 0; j < 3 ;j++) {            random_dequant_type24[i][j] = (uint8_t)((ldw / random_seed) & 0xFF);            ldw = (uint32_t)ldw % (uint32_t)random_seed;            tmp64_1 = (random_seed * 0x66666667);            hdw = (uint32_t)(tmp64_1 >> 33);            random_seed = hdw + (ldw >> 31);        }    }}static void init_noise_samples(void) {    int i;    int random_seed = 0;    float delta = 1.0 / 16384.0;    for (i = 0; i < 128;i++) {        random_seed = random_seed * 214013 + 2531011;        noise_samples[i] = (delta * (float)((random_seed >> 16) & 0x00007fff) - 1.0);    }}static void qdm2_init_vlc(void){    init_vlc (&vlc_tab_level, 8, 24,        vlc_tab_level_huffbits, 1, 1,        vlc_tab_level_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&vlc_tab_diff, 8, 37,        vlc_tab_diff_huffbits, 1, 1,        vlc_tab_diff_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&vlc_tab_run, 5, 6,        vlc_tab_run_huffbits, 1, 1,        vlc_tab_run_huffcodes, 1, 1, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&fft_level_exp_alt_vlc, 8, 28,        fft_level_exp_alt_huffbits, 1, 1,        fft_level_exp_alt_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&fft_level_exp_vlc, 8, 20,        fft_level_exp_huffbits, 1, 1,        fft_level_exp_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&fft_stereo_exp_vlc, 6, 7,        fft_stereo_exp_huffbits, 1, 1,        fft_stereo_exp_huffcodes, 1, 1, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&fft_stereo_phase_vlc, 6, 9,        fft_stereo_phase_huffbits, 1, 1,        fft_stereo_phase_huffcodes, 1, 1, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&vlc_tab_tone_level_idx_hi1, 8, 20,        vlc_tab_tone_level_idx_hi1_huffbits, 1, 1,        vlc_tab_tone_level_idx_hi1_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&vlc_tab_tone_level_idx_mid, 8, 24,        vlc_tab_tone_level_idx_mid_huffbits, 1, 1,        vlc_tab_tone_level_idx_mid_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&vlc_tab_tone_level_idx_hi2, 8, 24,        vlc_tab_tone_level_idx_hi2_huffbits, 1, 1,        vlc_tab_tone_level_idx_hi2_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&vlc_tab_type30, 6, 9,        vlc_tab_type30_huffbits, 1, 1,        vlc_tab_type30_huffcodes, 1, 1, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&vlc_tab_type34, 5, 10,        vlc_tab_type34_huffbits, 1, 1,        vlc_tab_type34_huffcodes, 1, 1, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&vlc_tab_fft_tone_offset[0], 8, 23,        vlc_tab_fft_tone_offset_0_huffbits, 1, 1,        vlc_tab_fft_tone_offset_0_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&vlc_tab_fft_tone_offset[1], 8, 28,        vlc_tab_fft_tone_offset_1_huffbits, 1, 1,        vlc_tab_fft_tone_offset_1_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&vlc_tab_fft_tone_offset[2], 8, 32,        vlc_tab_fft_tone_offset_2_huffbits, 1, 1,        vlc_tab_fft_tone_offset_2_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&vlc_tab_fft_tone_offset[3], 8, 35,        vlc_tab_fft_tone_offset_3_huffbits, 1, 1,        vlc_tab_fft_tone_offset_3_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);    init_vlc (&vlc_tab_fft_tone_offset[4], 8, 38,        vlc_tab_fft_tone_offset_4_huffbits, 1, 1,        vlc_tab_fft_tone_offset_4_huffcodes, 2, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE);}/* for floating point to fixed point conversion */static float f2i_scale = (float) (1 << (FRAC_BITS - 15));static int qdm2_get_vlc (GetBitContext *gb, VLC *vlc, int flag, int depth){    int value;    value = get_vlc2(gb, vlc->table, vlc->bits, depth);    /* stage-2, 3 bits exponent escape sequence */    if (value-- == 0)        value = get_bits (gb, get_bits (gb, 3) + 1);    /* stage-3, optional */    if (flag) {        int tmp = vlc_stage3_values[value];        if ((value & ~3) > 0)            tmp += get_bits (gb, (value >> 2));        value = tmp;    }

⌨️ 快捷键说明

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