📄 h264.c
字号:
/* * 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 + -