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

📄 h264.c

📁 播放H264文件的播放器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * * 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 libavcodec/h264.c * H.264 / AVC / MPEG4 part10 codec. * @author Michael Niedermayer <michaelni@gmx.at> */#include "internal.h"#include "dsputil.h"#include "avcodec.h"#include "mpegvideo.h"#include "h264.h"#include "h264data.h"#include "h264_parser.h"#include "golomb.h"#include "mathops.h"#include "rectangle.h"#include "vdpau_internal.h"#include "cabac.h"#if ARCH_X86#include "x86/h264_i386.h"#endif//#undef NDEBUG#include <assert.h>static const uint32_t svq3_dequant_coeff[32] = {
     3881,  4351,  4890,  5481,  6154,  6914,  7761,  8718,
     9781, 10987, 12339, 13828, 15523, 17435, 19561, 21873,
    24552, 27656, 30847, 34870, 38807, 43747, 49103, 54683,
    61694, 68745, 77615, 89113,100253,109366,126635,141533
};


static void svq3_luma_dc_dequant_idct_c(DCTELEM *block, int qp)
{
    const int qmul = svq3_dequant_coeff[qp];
#define stride 16
    int i;
    int temp[16];
    static const int x_offset[4] = {0, 1*stride, 4* stride,  5*stride};
    static const int y_offset[4] = {0, 2*stride, 8* stride, 10*stride};

    for (i = 0; i < 4; i++){
        const int offset = y_offset[i];
        const int z0 = 13*(block[offset+stride*0] +    block[offset+stride*4]);
        const int z1 = 13*(block[offset+stride*0] -    block[offset+stride*4]);
        const int z2 =  7* block[offset+stride*1] - 17*block[offset+stride*5];
        const int z3 = 17* block[offset+stride*1] +  7*block[offset+stride*5];

        temp[4*i+0] = z0+z3;
        temp[4*i+1] = z1+z2;
        temp[4*i+2] = z1-z2;
        temp[4*i+3] = z0-z3;
    }

    for (i = 0; i < 4; i++){
        const int offset = x_offset[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[stride*0 +offset] = ((z0 + z3)*qmul + 0x80000) >> 20;
        block[stride*2 +offset] = ((z1 + z2)*qmul + 0x80000) >> 20;
        block[stride*8 +offset] = ((z1 - z2)*qmul + 0x80000) >> 20;
        block[stride*10+offset] = ((z0 - z3)*qmul + 0x80000) >> 20;
    }
}
#undef stridestatic void svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp,
                            int dc)
{
    const int qmul = svq3_dequant_coeff[qp];
    int i;
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;

    if (dc) {
        dc = 13*13*((dc == 1) ? 1538*block[0] : ((qmul*(block[0] >> 3)) / 2));
        block[0] = 0;
    }

    for (i = 0; i < 4; i++) {
        const int z0 = 13*(block[0 + 4*i] +    block[2 + 4*i]);
        const int z1 = 13*(block[0 + 4*i] -    block[2 + 4*i]);
        const int z2 =  7* block[1 + 4*i] - 17*block[3 + 4*i];
        const int z3 = 17* block[1 + 4*i] +  7*block[3 + 4*i];

        block[0 + 4*i] = z0 + z3;
        block[1 + 4*i] = z1 + z2;
        block[2 + 4*i] = z1 - z2;
        block[3 + 4*i] = z0 - z3;
    }

    for (i = 0; i < 4; i++) {
        const int z0 = 13*(block[i + 4*0] +    block[i + 4*2]);
        const int z1 = 13*(block[i + 4*0] -    block[i + 4*2]);
        const int z2 =  7* block[i + 4*1] - 17*block[i + 4*3];
        const int z3 = 17* block[i + 4*1] +  7*block[i + 4*3];
        const int rr = (dc + 0x80000);

        dst[i + stride*0] = cm[ dst[i + stride*0] + (((z0 + z3)*qmul + rr) >> 20) ];
        dst[i + stride*1] = cm[ dst[i + stride*1] + (((z1 + z2)*qmul + rr) >> 20) ];
        dst[i + stride*2] = cm[ dst[i + stride*2] + (((z1 - z2)*qmul + rr) >> 20) ];
        dst[i + stride*3] = cm[ dst[i + stride*3] + (((z0 - z3)*qmul + rr) >> 20) ];
    }
}/** * Value of Picture.reference when Picture is not a reference picture, but * is held for delayed output. */#define DELAYED_PIC_REF 4static VLC coeff_token_vlc[4];static VLC_TYPE coeff_token_vlc_tables[520+332+280+256][2];static const int coeff_token_vlc_tables_size[4]={520,332,280,256};static VLC chroma_dc_coeff_token_vlc;static VLC_TYPE chroma_dc_coeff_token_vlc_table[256][2];static const int chroma_dc_coeff_token_vlc_table_size = 256;static VLC total_zeros_vlc[15];static VLC_TYPE total_zeros_vlc_tables[15][512][2];static const int total_zeros_vlc_tables_size = 512;static VLC chroma_dc_total_zeros_vlc[3];static VLC_TYPE chroma_dc_total_zeros_vlc_tables[3][8][2];static const int chroma_dc_total_zeros_vlc_tables_size = 8;static VLC run_vlc[6];static VLC_TYPE run_vlc_tables[6][8][2];static const int run_vlc_tables_size = 8;static VLC run7_vlc;static VLC_TYPE run7_vlc_table[96][2];static const int run7_vlc_table_size = 96;//static void svq3_luma_dc_dequant_idct_c(DCTELEM *block, int qp);//static void svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, int dc);static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize);static void filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize);static Picture * remove_long(H264Context *h, int i, int ref_mask);static av_always_inline uint32_t pack16to32(int a, int b){#ifdef WORDS_BIGENDIAN   return (b&0xFFFF) + (a<<16);#else   return (a&0xFFFF) + (b<<16);#endif}static const uint8_t rem6[52]={0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3,};static const uint8_t div6[52]={0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,};static const uint8_t left_block_options[4][8]={    {0,1,2,3,7,10,8,11},    {2,2,3,3,8,11,8,11},    {0,0,1,1,7,10,7,10},    {0,2,0,2,7,10,7,10}};#define LEVEL_TAB_BITS 8static int8_t cavlc_level_tab[7][1<<LEVEL_TAB_BITS][2];static void fill_caches(H264Context *h, int mb_type, int for_deblock){    MpegEncContext * const s = &h->s;    const int mb_xy= h->mb_xy;    int topleft_xy, top_xy, topright_xy, left_xy[2];    int topleft_type, top_type, topright_type, left_type[2];    const uint8_t * left_block;    int topleft_partition= -1;    int i;    top_xy     = mb_xy  - (s->mb_stride << FIELD_PICTURE);    //FIXME deblocking could skip the intra and nnz parts.    if(for_deblock && (h->slice_num == 1 || h->slice_table[mb_xy] == h->slice_table[top_xy]) && !FRAME_MBAFF)        return;    /* Wow, what a mess, why didn't they simplify the interlacing & intra     * stuff, I can't imagine that these complex rules are worth it. */    topleft_xy = top_xy - 1;    topright_xy= top_xy + 1;    left_xy[1] = left_xy[0] = mb_xy-1;    left_block = left_block_options[0];    if(FRAME_MBAFF){        const int pair_xy          = s->mb_x     + (s->mb_y & ~1)*s->mb_stride;        const int top_pair_xy      = pair_xy     - s->mb_stride;        const int topleft_pair_xy  = top_pair_xy - 1;        const int topright_pair_xy = top_pair_xy + 1;        const int topleft_mb_field_flag  = IS_INTERLACED(s->current_picture.mb_type[topleft_pair_xy]);        const int top_mb_field_flag      = IS_INTERLACED(s->current_picture.mb_type[top_pair_xy]);        const int topright_mb_field_flag = IS_INTERLACED(s->current_picture.mb_type[topright_pair_xy]);        const int left_mb_field_flag     = IS_INTERLACED(s->current_picture.mb_type[pair_xy-1]);        const int curr_mb_field_flag     = IS_INTERLACED(mb_type);        const int bottom = (s->mb_y & 1);        tprintf(s->avctx, "fill_caches: curr_mb_field_flag:%d, left_mb_field_flag:%d, topleft_mb_field_flag:%d, top_mb_field_flag:%d, topright_mb_field_flag:%d\n", curr_mb_field_flag, left_mb_field_flag, topleft_mb_field_flag, top_mb_field_flag, topright_mb_field_flag);        if (curr_mb_field_flag && (bottom || top_mb_field_flag)){            top_xy -= s->mb_stride;        }        if (curr_mb_field_flag && (bottom || topleft_mb_field_flag)){            topleft_xy -= s->mb_stride;        } else if(bottom && !curr_mb_field_flag && left_mb_field_flag) {            topleft_xy += s->mb_stride;            // take top left mv from the middle of the mb, as opposed to all other modes which use the bottom right partition            topleft_partition = 0;        }        if (curr_mb_field_flag && (bottom || topright_mb_field_flag)){            topright_xy -= s->mb_stride;        }        if (left_mb_field_flag != curr_mb_field_flag) {            left_xy[1] = left_xy[0] = pair_xy - 1;            if (curr_mb_field_flag) {                left_xy[1] += s->mb_stride;                left_block = left_block_options[3];            } else {                left_block= left_block_options[2 - bottom];            }        }    }    h->top_mb_xy = top_xy;    h->left_mb_xy[0] = left_xy[0];    h->left_mb_xy[1] = left_xy[1];    if(for_deblock){        topleft_type = 0;        topright_type = 0;        top_type     = h->slice_table[top_xy     ] < 0xFFFF ? s->current_picture.mb_type[top_xy]     : 0;        left_type[0] = h->slice_table[left_xy[0] ] < 0xFFFF ? s->current_picture.mb_type[left_xy[0]] : 0;        left_type[1] = h->slice_table[left_xy[1] ] < 0xFFFF ? s->current_picture.mb_type[left_xy[1]] : 0;        if(MB_MBAFF && !IS_INTRA(mb_type)){            int list;            for(list=0; list<h->list_count; list++){                //These values where changed for ease of performing MC, we need to change them back                //FIXME maybe we can make MC and loop filter use the same values or prevent                //the MC code from changing ref_cache and rather use a temporary array.                if(USES_LIST(mb_type,list)){                    int8_t *ref = &s->current_picture.ref_index[list][h->mb2b8_xy[mb_xy]];                    *(uint32_t*)&h->ref_cache[list][scan8[ 0]] =                    *(uint32_t*)&h->ref_cache[list][scan8[ 2]] = (pack16to32(ref[0],ref[1])&0x00FF00FF)*0x0101;                    ref += h->b8_stride;                    *(uint32_t*)&h->ref_cache[list][scan8[ 8]] =                    *(uint32_t*)&h->ref_cache[list][scan8[10]] = (pack16to32(ref[0],ref[1])&0x00FF00FF)*0x0101;                }            }        }    }else{        topleft_type = h->slice_table[topleft_xy ] == h->slice_num ? s->current_picture.mb_type[topleft_xy] : 0;        top_type     = h->slice_table[top_xy     ] == h->slice_num ? s->current_picture.mb_type[top_xy]     : 0;        topright_type= h->slice_table[topright_xy] == h->slice_num ? s->current_picture.mb_type[topright_xy]: 0;        left_type[0] = h->slice_table[left_xy[0] ] == h->slice_num ? s->current_picture.mb_type[left_xy[0]] : 0;        left_type[1] = h->slice_table[left_xy[1] ] == h->slice_num ? s->current_picture.mb_type[left_xy[1]] : 0;    if(IS_INTRA(mb_type)){        int type_mask= h->pps.constrained_intra_pred ? IS_INTRA(-1) : -1;        h->topleft_samples_available=        h->top_samples_available=        h->left_samples_available= 0xFFFF;        h->topright_samples_available= 0xEEEA;        if(!(top_type & type_mask)){            h->topleft_samples_available= 0xB3FF;            h->top_samples_available= 0x33FF;            h->topright_samples_available= 0x26EA;        }        if(IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[0])){            if(IS_INTERLACED(mb_type)){                if(!(left_type[0] & type_mask)){                    h->topleft_samples_available&= 0xDFFF;                    h->left_samples_available&= 0x5FFF;                }                if(!(left_type[1] & type_mask)){                    h->topleft_samples_available&= 0xFF5F;                    h->left_samples_available&= 0xFF5F;                }            }else{                int left_typei = h->slice_table[left_xy[0] + s->mb_stride ] == h->slice_num                                ? s->current_picture.mb_type[left_xy[0] + s->mb_stride] : 0;                assert(left_xy[0] == left_xy[1]);                if(!((left_typei & type_mask) && (left_type[0] & type_mask))){

⌨️ 快捷键说明

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