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

📄 rv34.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * RV30/40 decoder common data * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov * * This file is part of FFmpeg. * * FFmpeg 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.1 of the License, or (at your option) any later version. * * FFmpeg 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 FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *//** * @file rv34.c * RV30/40 decoder common data */#include "avcodec.h"#include "dsputil.h"#include "mpegvideo.h"#include "golomb.h"#include "rectangle.h"#include "rv34vlc.h"#include "rv34data.h"#include "rv34.h"//#define DEBUG/** translation of RV30/40 macroblock types to lavc ones */static const int rv34_mb_type_to_lavc[12] = {    MB_TYPE_INTRA,    MB_TYPE_INTRA16x16,    MB_TYPE_16x16   | MB_TYPE_L0,    MB_TYPE_8x8     | MB_TYPE_L0,    MB_TYPE_16x16   | MB_TYPE_L0,    MB_TYPE_16x16   | MB_TYPE_L1,    MB_TYPE_SKIP,    MB_TYPE_DIRECT2 | MB_TYPE_16x16,    MB_TYPE_16x8    | MB_TYPE_L0,    MB_TYPE_8x16    | MB_TYPE_L0,    MB_TYPE_16x16   | MB_TYPE_L0L1,    MB_TYPE_16x16   | MB_TYPE_L0};static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES];/** * @defgroup vlc RV30/40 VLC generating functions * @{ *//** * Generate VLC from codeword lengths. * @param bits   codeword lengths (zeroes are accepted) * @param size   length of input data * @param insyms symbols for input codes (NULL for default ones) */static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *insyms){    int i;    int counts[17] = {0}, codes[17];#ifdef __CW32__    uint16_t *cw, *syms;    uint8_t *bits2;#else    uint16_t cw[size], syms[size];    uint8_t bits2[size];#endif    int maxbits = 0, realsize = 0;#ifdef __CW32__    cw = av_malloc(sizeof(uint16_t)*size);    syms = av_malloc(sizeof(uint16_t)*size);    bits2 = av_malloc(sizeof(uint8_t)*size);#endif    for(i = 0; i < size; i++){        if(bits[i]){            bits2[realsize] = bits[i];            syms[realsize] = insyms ? insyms[i] : i;            realsize++;            maxbits = FFMAX(maxbits, bits[i]);            counts[bits[i]]++;        }    }    codes[0] = 0;    for(i = 0; i < 16; i++)        codes[i+1] = (codes[i] + counts[i]) << 1;    for(i = 0; i < realsize; i++)        cw[i] = codes[bits2[i]]++;    init_vlc_sparse(vlc, FFMIN(maxbits, 9), realsize,                    bits2, 1, 1,                    cw,    2, 2,                    syms,  2, 2, INIT_VLC_USE_STATIC);#ifdef __CW32__    av_free(cw);    av_free(syms);    av_free(bits2);#endif}/** * Initialize all tables. */static av_cold void rv34_init_tables(){    int i, j, k;    for(i = 0; i < NUM_INTRA_TABLES; i++){        for(j = 0; j < 2; j++){            rv34_gen_vlc(rv34_table_intra_cbppat   [i][j], CBPPAT_VLC_SIZE,   &intra_vlcs[i].cbppattern[j],     NULL);            rv34_gen_vlc(rv34_table_intra_secondpat[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j], NULL);            rv34_gen_vlc(rv34_table_intra_thirdpat [i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j],  NULL);            for(k = 0; k < 4; k++)                rv34_gen_vlc(rv34_table_intra_cbp[i][j+k*2],  CBP_VLC_SIZE,   &intra_vlcs[i].cbp[j][k],         rv34_cbp_code);        }        for(j = 0; j < 4; j++)            rv34_gen_vlc(rv34_table_intra_firstpat[i][j], FIRSTBLK_VLC_SIZE, &intra_vlcs[i].first_pattern[j], NULL);        rv34_gen_vlc(rv34_intra_coeff[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient, NULL);    }    for(i = 0; i < NUM_INTER_TABLES; i++){        rv34_gen_vlc(rv34_inter_cbppat[i], CBPPAT_VLC_SIZE, &inter_vlcs[i].cbppattern[0], NULL);        for(j = 0; j < 4; j++)            rv34_gen_vlc(rv34_inter_cbp[i][j], CBP_VLC_SIZE, &inter_vlcs[i].cbp[0][j], rv34_cbp_code);        for(j = 0; j < 2; j++){            rv34_gen_vlc(rv34_table_inter_firstpat [i][j], FIRSTBLK_VLC_SIZE, &inter_vlcs[i].first_pattern[j],  NULL);            rv34_gen_vlc(rv34_table_inter_secondpat[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j], NULL);            rv34_gen_vlc(rv34_table_inter_thirdpat [i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j],  NULL);        }        rv34_gen_vlc(rv34_inter_coeff[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient, NULL);    }}/** @} */ // vlc group/** * @defgroup transform RV30/40 inverse transform functions * @{ */static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block){    int i;    for(i=0; i<4; i++){        const int z0= 13*(block[i+8*0] +    block[i+8*2]);        const int z1= 13*(block[i+8*0] -    block[i+8*2]);        const int z2=  7* block[i+8*1] - 17*block[i+8*3];        const int z3= 17* block[i+8*1] +  7*block[i+8*3];        temp[4*i+0]= z0+z3;        temp[4*i+1]= z1+z2;        temp[4*i+2]= z1-z2;        temp[4*i+3]= z0-z3;    }}/** * Real Video 3.0/4.0 inverse transform * Code is almost the same as in SVQ3, only scaling is different. */static void rv34_inv_transform(DCTELEM *block){    int temp[16];    int i;    rv34_row_transform(temp, block);    for(i=0; i<4; i++){        const int z0= 13*(temp[4*0+i] +    temp[4*2+i]) + 0x200;        const int z1= 13*(temp[4*0+i] -    temp[4*2+i]) + 0x200;        const int z2=  7* temp[4*1+i] - 17*temp[4*3+i];        const int z3= 17* temp[4*1+i] +  7*temp[4*3+i];        block[i*8+0]= (z0 + z3)>>10;        block[i*8+1]= (z1 + z2)>>10;        block[i*8+2]= (z1 - z2)>>10;        block[i*8+3]= (z0 - z3)>>10;    }}/** * RealVideo 3.0/4.0 inverse transform for DC block * * Code is almost the same as rv34_inv_transform() * but final coefficients are multiplied by 1.5 and have no rounding. */static void rv34_inv_transform_noround(DCTELEM *block){    int temp[16];    int i;    rv34_row_transform(temp, block);    for(i=0; i<4; i++){        const int z0= 13*(temp[4*0+i] +    temp[4*2+i]);        const int z1= 13*(temp[4*0+i] -    temp[4*2+i]);        const int z2=  7* temp[4*1+i] - 17*temp[4*3+i];        const int z3= 17* temp[4*1+i] +  7*temp[4*3+i];        block[i*8+0]= ((z0 + z3)*3)>>11;        block[i*8+1]= ((z1 + z2)*3)>>11;        block[i*8+2]= ((z1 - z2)*3)>>11;        block[i*8+3]= ((z0 - z3)*3)>>11;    }}/** @} */ // transform/** * @defgroup block RV30/40 4x4 block decoding functions * @{ *//** * Decode coded block pattern. */static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table){    int pattern, code, cbp=0;    int ones;    static const int cbp_masks[3] = {0x100000, 0x010000, 0x110000};    static const int shifts[4] = { 0, 2, 8, 10 };#ifdef __CW32__    int *curshift = (int*)shifts;#else    int *curshift = shifts;#endif    int i, t, mask;    code = get_vlc2(gb, vlc->cbppattern[table].table, 9, 2);    pattern = code & 0xF;    code >>= 4;    ones = rv34_count_ones[pattern];    for(mask = 8; mask; mask >>= 1, curshift++){        if(pattern & mask)            cbp |= get_vlc2(gb, vlc->cbp[table][ones].table, vlc->cbp[table][ones].bits, 1) << curshift[0];    }    for(i = 0; i < 4; i++){        t = modulo_three_table[code][i];        if(t == 1)            cbp |= cbp_masks[get_bits1(gb)] << i;        if(t == 2)            cbp |= cbp_masks[2] << i;    }    return cbp;}/** * Get one coefficient value from the bistream and store it. */static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc){    if(coef){        if(coef == esc){            coef = get_vlc2(gb, vlc->table, 9, 2);            if(coef > 23){                coef -= 23;                coef = 22 + ((1 << coef) | get_bits(gb, coef));            }            coef += esc;        }        if(get_bits1(gb))            coef = -coef;        *dst = coef;    }}/** * Decode 2x2 subblock of coefficients. */static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc){    int coeffs[4];    coeffs[0] = modulo_three_table[code][0];    coeffs[1] = modulo_three_table[code][1];    coeffs[2] = modulo_three_table[code][2];    coeffs[3] = modulo_three_table[code][3];    decode_coeff(dst  , coeffs[0], 3, gb, vlc);    if(is_block2){        decode_coeff(dst+8, coeffs[1], 2, gb, vlc);        decode_coeff(dst+1, coeffs[2], 2, gb, vlc);    }else{        decode_coeff(dst+1, coeffs[1], 2, gb, vlc);        decode_coeff(dst+8, coeffs[2], 2, gb, vlc);    }    decode_coeff(dst+9, coeffs[3], 2, gb, vlc);}/** * Decode coefficients for 4x4 block. * * This is done by filling 2x2 subblocks with decoded coefficients * in this order (the same for subblocks and subblock coefficients): *  o--o *    / *   / *  o--o */static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc){    int code, pattern;    code = get_vlc2(gb, rvlc->first_pattern[fc].table, 9, 2);    pattern = code & 0x7;    code >>= 3;    decode_subblock(dst, code, 0, gb, &rvlc->coefficient);    if(pattern & 4){        code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);        decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient);    }    if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block        code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);        decode_subblock(dst + 8*2, code, 1, gb, &rvlc->coefficient);    }    if(pattern & 1){

⌨️ 快捷键说明

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