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

📄 h264.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 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 h264.c * H.264 / AVC / MPEG4 part10 codec. * @author Michael Niedermayer <michaelni@gmx.at> */#include "dsputil.h"#include "avcodec.h"#include "mpegvideo.h"#include "h264.h"#include "h264data.h"#include "h264_parser.h"#include "golomb.h"#include "rectangle.h"#include "cabac.h"//#undef NDEBUG#include <assert.h>/** * 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 chroma_dc_coeff_token_vlc;static VLC total_zeros_vlc[15];static VLC chroma_dc_total_zeros_vlc[3];static VLC run_vlc[6];static VLC run7_vlc;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 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}const uint8_t ff_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,};const uint8_t ff_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 void fill_caches(H264Context *h, int mb_type, int for_deblock){    MpegEncContext * const s = &h->s;    const int mb_xy= s->mb_x + s->mb_y*s->mb_stride;    int topleft_xy, top_xy, topright_xy, left_xy[2];    int topleft_type, top_type, topright_type, left_type[2];    int left_block[8];    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[0]= 0;    left_block[1]= 1;    left_block[2]= 2;    left_block[3]= 3;    left_block[4]= 7;    left_block[5]= 10;    left_block[6]= 8;    left_block[7]= 11;    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_frame_flag  = !IS_INTERLACED(s->current_picture.mb_type[topleft_pair_xy]);        const int top_mb_frame_flag      = !IS_INTERLACED(s->current_picture.mb_type[top_pair_xy]);        const int topright_mb_frame_flag = !IS_INTERLACED(s->current_picture.mb_type[topright_pair_xy]);        const int left_mb_frame_flag = !IS_INTERLACED(s->current_picture.mb_type[pair_xy-1]);        const int curr_mb_frame_flag = !IS_INTERLACED(mb_type);        const int bottom = (s->mb_y & 1);        tprintf(s->avctx, "fill_caches: curr_mb_frame_flag:%d, left_mb_frame_flag:%d, topleft_mb_frame_flag:%d, top_mb_frame_flag:%d, topright_mb_frame_flag:%d\n", curr_mb_frame_flag, left_mb_frame_flag, topleft_mb_frame_flag, top_mb_frame_flag, topright_mb_frame_flag);        if (bottom                ? !curr_mb_frame_flag // bottom macroblock                : (!curr_mb_frame_flag && !top_mb_frame_flag) // top macroblock                ) {            top_xy -= s->mb_stride;        }        if (bottom                ? !curr_mb_frame_flag // bottom macroblock                : (!curr_mb_frame_flag && !topleft_mb_frame_flag) // top macroblock                ) {            topleft_xy -= s->mb_stride;        } else if(bottom && curr_mb_frame_flag && !left_mb_frame_flag) {            topleft_xy += s->mb_stride;            // take topleft mv from the middle of the mb, as opposed to all other modes which use the bottom-right partition            topleft_partition = 0;        }        if (bottom                ? !curr_mb_frame_flag // bottom macroblock                : (!curr_mb_frame_flag && !topright_mb_frame_flag) // top macroblock                ) {            topright_xy -= s->mb_stride;        }        if (left_mb_frame_flag != curr_mb_frame_flag) {            left_xy[1] = left_xy[0] = pair_xy - 1;            if (curr_mb_frame_flag) {                if (bottom) {                    left_block[0]= 2;                    left_block[1]= 2;                    left_block[2]= 3;                    left_block[3]= 3;                    left_block[4]= 8;                    left_block[5]= 11;                    left_block[6]= 8;                    left_block[7]= 11;                } else {                    left_block[0]= 0;                    left_block[1]= 0;                    left_block[2]= 1;                    left_block[3]= 1;                    left_block[4]= 7;                    left_block[5]= 10;                    left_block[6]= 7;                    left_block[7]= 10;                }            } else {                left_xy[1] += s->mb_stride;                //left_block[0]= 0;                left_block[1]= 2;                left_block[2]= 0;                left_block[3]= 2;                //left_block[4]= 7;                left_block[5]= 10;                left_block[6]= 7;                left_block[7]= 10;            }        }    }    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     ] < 255 ? s->current_picture.mb_type[top_xy]     : 0;        left_type[0] = h->slice_table[left_xy[0] ] < 255 ? s->current_picture.mb_type[left_xy[0]] : 0;        left_type[1] = h->slice_table[left_xy[1] ] < 255 ? s->current_picture.mb_type[left_xy[1]] : 0;        if(FRAME_MBAFF && !IS_INTRA(mb_type)){            int list;            int v = *(uint16_t*)&h->non_zero_count[mb_xy][14];            for(i=0; i<16; i++)                h->non_zero_count_cache[scan8[i]] = (v>>i)&1;            for(list=0; list<h->list_count; list++){                if(USES_LIST(mb_type,list)){                    uint32_t *src = (uint32_t*)s->current_picture.motion_val[list][h->mb2b_xy[mb_xy]];                    uint32_t *dst = (uint32_t*)h->mv_cache[list][scan8[0]];                    int8_t *ref = &s->current_picture.ref_index[list][h->mb2b8_xy[mb_xy]];                    for(i=0; i<4; i++, dst+=8, src+=h->b_stride){                        dst[0] = src[0];                        dst[1] = src[1];                        dst[2] = src[2];                        dst[3] = src[3];                    }                    *(uint32_t*)&h->ref_cache[list][scan8[ 0]] =                    *(uint32_t*)&h->ref_cache[list][scan8[ 2]] = pack16to32(ref[0],ref[1])*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])*0x0101;                }else{                    fill_rectangle(&h-> mv_cache[list][scan8[ 0]], 4, 4, 8, 0, 4);                    fill_rectangle(&h->ref_cache[list][scan8[ 0]], 4, 4, 8, (uint8_t)LIST_NOT_USED, 1);                }            }        }    }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)){        h->topleft_samples_available=        h->top_samples_available=        h->left_samples_available= 0xFFFF;        h->topright_samples_available= 0xEEEA;        if(!IS_INTRA(top_type) && (top_type==0 || h->pps.constrained_intra_pred)){            h->topleft_samples_available= 0xB3FF;            h->top_samples_available= 0x33FF;            h->topright_samples_available= 0x26EA;        }        for(i=0; i<2; i++){            if(!IS_INTRA(left_type[i]) && (left_type[i]==0 || h->pps.constrained_intra_pred)){                h->topleft_samples_available&= 0xDF5F;                h->left_samples_available&= 0x5F5F;            }        }        if(!IS_INTRA(topleft_type) && (topleft_type==0 || h->pps.constrained_intra_pred))            h->topleft_samples_available&= 0x7FFF;        if(!IS_INTRA(topright_type) && (topright_type==0 || h->pps.constrained_intra_pred))            h->topright_samples_available&= 0xFBFF;        if(IS_INTRA4x4(mb_type)){            if(IS_INTRA4x4(top_type)){                h->intra4x4_pred_mode_cache[4+8*0]= h->intra4x4_pred_mode[top_xy][4];                h->intra4x4_pred_mode_cache[5+8*0]= h->intra4x4_pred_mode[top_xy][5];                h->intra4x4_pred_mode_cache[6+8*0]= h->intra4x4_pred_mode[top_xy][6];                h->intra4x4_pred_mode_cache[7+8*0]= h->intra4x4_pred_mode[top_xy][3];            }else{                int pred;                if(!top_type || (IS_INTER(top_type) && h->pps.constrained_intra_pred))                    pred= -1;                else{                    pred= 2;                }                h->intra4x4_pred_mode_cache[4+8*0]=                h->intra4x4_pred_mode_cache[5+8*0]=                h->intra4x4_pred_mode_cache[6+8*0]=                h->intra4x4_pred_mode_cache[7+8*0]= pred;            }            for(i=0; i<2; i++){                if(IS_INTRA4x4(left_type[i])){                    h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]= h->intra4x4_pred_mode[left_xy[i]][left_block[0+2*i]];                    h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= h->intra4x4_pred_mode[left_xy[i]][left_block[1+2*i]];                }else{                    int pred;                    if(!left_type[i] || (IS_INTER(left_type[i]) && h->pps.constrained_intra_pred))                        pred= -1;                    else{                        pred= 2;                    }                    h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]=                    h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= pred;                }            }        }    }/*0 . T T. T T T T1 L . .L . . . .2 L . .L . . . .3 . T TL . . . .4 L . .L . . . .5 L . .. . . . .*///FIXME constraint_intra_pred & partitioning & nnz (lets hope this is just a typo in the spec)    if(top_type){        h->non_zero_count_cache[4+8*0]= h->non_zero_count[top_xy][4];        h->non_zero_count_cache[5+8*0]= h->non_zero_count[top_xy][5];        h->non_zero_count_cache[6+8*0]= h->non_zero_count[top_xy][6];        h->non_zero_count_cache[7+8*0]= h->non_zero_count[top_xy][3];        h->non_zero_count_cache[1+8*0]= h->non_zero_count[top_xy][9];        h->non_zero_count_cache[2+8*0]= h->non_zero_count[top_xy][8];        h->non_zero_count_cache[1+8*3]= h->non_zero_count[top_xy][12];        h->non_zero_count_cache[2+8*3]= h->non_zero_count[top_xy][11];    }else{        h->non_zero_count_cache[4+8*0]=        h->non_zero_count_cache[5+8*0]=        h->non_zero_count_cache[6+8*0]=        h->non_zero_count_cache[7+8*0]=        h->non_zero_count_cache[1+8*0]=        h->non_zero_count_cache[2+8*0]=

⌨️ 快捷键说明

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