📄 macroblock1.c
字号:
/***************************************************************************** * macroblock.c: h264 decoder library ***************************************************************************** * Copyright (C) 2003 Laurent Aimar * $Id: macroblock.c,v 1.1 2004/06/03 19:27:07 fenrir Exp $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/#include <stdlib.h>#include <stdio.h>#include <string.h>#include "stdint_x264.h"#include "common.h"//#include "common/vlc.h"#include "vlc.h"#include "macroblock.h"#include "assert.h"static const uint8_t block_idx_x[16] ={ 0, 1, 0, 1, 2, 3, 2, 3, 0, 1, 0, 1, 2, 3, 2, 3};static const uint8_t block_idx_y[16] ={ 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3};static const uint8_t block_idx_xy[4][4] ={ { 0, 2, 8, 10}, { 1, 3, 9, 11}, { 4, 6, 12, 14}, { 5, 7, 13, 15}};static const int golomb_to_intra4x4_cbp[48]={ 47, 31, 15, 0, 23, 27, 29, 30, 7, 11, 13, 14, 39, 43, 45, 46, 16, 3, 5, 10, 12, 19, 21, 26, 28, 35, 37, 42, 44, 1, 2, 4, 8, 17, 18, 20, 24, 6, 9, 22, 25, 32, 33, 34, 36, 40, 38, 41};static const int golomb_to_inter_cbp[48]={ 0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13, 14, 6, 9, 31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46, 17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41};static const int i_chroma_qp_table[52] ={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 39};static int x264_macroblock_decode_ipcm( x264_t *h, bs_t *s ){ /* TODO */ int j,i; if(s->i_left!=8) { bs_align(s); } /*for luma ipcm*/ for(i=0; i<16; i++) for(j=0;j<16;j++) h->mb.pic.p_fdec[0][j+16*i]=bs_read(s, 8); /*for cb ipcm*/ for(i=0;i<8;i++) for(j=0;j<8;j++) h->mb.pic.p_fdec[1][j+8*i]=bs_read(s, 8); /*for cr ipcm*/ for(i=0;i<8;i++) for(j=0;j<8;j++) h->mb.pic.p_fdec[2][j+8*i]=bs_read(s, 8); return 1;}#define BLOCK_INDEX_CHROMA_DC (-1)#define BLOCK_INDEX_LUMA_DC (-2)static inline void array_zero_set( int *l, int i_count ){ int i; for( i = 0; i < i_count; i++ ) { l[i] = 0; }}static inline int array_non_zero_count( int *v, int i_count ){ int i; int i_nz; for( i = 0, i_nz = 0; i < i_count; i++ ) { if( v[i] ) { i_nz++; } } return i_nz;}static int x264_cabac_mb_ref( x264_t *h,int list, int n ){ int refa = h->mb.cache.ref[list][x264_scan8[n] - 1]; int refb = h->mb.cache.ref[list][x264_scan8[n] - 8]; int ref = 0; int ctx = 0; if( h->sh.i_type == SLICE_TYPE_B) { if( refa > 0 && !h->mb.cache.skip[x264_scan8[n] - 1] ) ctx++; if( refb > 0 && !h->mb.cache.skip[x264_scan8[n] - 8] ) ctx += 2; } else { if( refa > 0 ) ctx++; if( refb > 0 ) ctx += 2; } while( x264_cabac_decode_decision( &h->cabac, 54+ctx ) ) { ref++; if( ctx < 4 ) ctx = 4; else ctx = 5; } return ref;}/*static inline int x264_cabac_mb_mvd_cpn(x264_t * h, int i_list, int i8, int l){ int i_abs, i_prefix, i_suffix; const int amvd = abs( h->mb.cache.mvd[i_list][i8- 1][l] ) + abs( h->mb.cache.mvd[i_list][i8 - 8][l] ); const int ctxbase = (l == 0 ? 40 : 47); int ctx; if( amvd < 3 ) ctx = 0; else if( amvd > 32 ) ctx = 2; else ctx = 1; i_prefix = 0; while(i_prefix<9 && x264_cabac_decode_decision(&h->cabac, ctxbase+ctx)!=0) { i_prefix ++; if(ctx < 3) ctx = 3; else if(ctx < 6) ctx ++; } if(i_prefix >= 9) { int k = 3; i_suffix = 0; while(x264_cabac_decode_bypass(&h->cabac) != 0) { i_suffix += 1<<k; k++; } while(k--) { i_suffix += x264_cabac_decode_bypass(&h->cabac)<<k; } i_abs = 9 + i_suffix; } else i_abs = i_prefix; if(i_abs != 0) { if(x264_cabac_decode_bypass(&h->cabac) != 0) i_abs = -i_abs; } return i_abs;}*/static int x264_cabac_mb_mvd( x264_t *h, int list,int n, int l ) { int amvd = abs( h->mb.cache.mvd[list][x264_scan8[n] - 1][l] ) + abs( h->mb.cache.mvd[list][x264_scan8[n] - 8][l] ); int ctxbase = (l == 0) ? 40 : 47; int ctx, mvd; if( amvd < 3 ) ctx = 0; else if( amvd > 32 ) ctx = 2; else ctx = 1; if(!x264_cabac_decode_decision(&h->cabac, ctxbase+ctx)) return 0; mvd= 1; ctx= 3; while( mvd < 9 && x264_cabac_decode_decision( &h->cabac, ctxbase+ctx) ) { mvd++; if( ctx < 6 ) ctx++; } if( mvd >= 9 ) { int k = 3; while( x264_cabac_decode_bypass( &h->cabac ) ) { mvd += 1 << k; k++; } while( k-- ) { if( x264_cabac_decode_bypass( &h->cabac ) ) mvd += 1 << k; } } if( x264_cabac_decode_bypass( &h->cabac ) ) return -mvd; else return mvd;}/*static __inline void x264_cabac_mb8x8_mvd( x264_t *h, int i_list,int n, int l ){ int amvd = abs( h->mb.cache.mvd[list][x264_scan8[n] - 1][l] ) + abs( h->mb.cache.mvd[list][x264_scan8[n] - 8][l] ); int ctxbase = (l == 0) ? 40 : 47; int ctx, mvd; if( amvd < 3 ) ctx = 0; else if( amvd > 32 ) ctx = 2; else ctx = 1; if(!x264_cabac_decode_decision(&h->cabac, &h->cabac_state[ctxbase+ctx])) return 0; mvd= 1; ctx= 3; while( mvd < 9 && x264_cabac_decode_decision( &h->cabac, &h->cabac_state[ctxbase+ctx] ) ) { mvd++; if( ctx < 6 ) ctx++; } if( mvd >= 9 ) { int k = 3; while( x264_cabac_decode_bypass( &h->cabac ) ) { mvd += 1 << k; k++; } while( k-- ) { if( x264_cabac_decode_bypass( &h->cabac ) ) mvd += 1 << k; } } if( x264_cabac_decode_bypass( &h->cabac ) ) return -mvd; else return mvd;}*/static __inline int x264_cabac_mb_sub_p_partition( x264_t *h){ if(x264_cabac_decode_decision( &h->cabac, 21 ) ) return 0; /* 8x8 */ if( !x264_cabac_decode_decision( &h->cabac, 22 ) ) return 1; /* 8x4 */ if( x264_cabac_decode_decision( &h->cabac, 23 ) ) return 2; /* 4x8 */ return 3; /* 4x4 */}static __inline int x264_cabac_mb_sub_b_partition( x264_t *h) { int type = 0; if( !x264_cabac_decode_decision( &h->cabac, 36 ) ) return 0; /* B_Direct_8x8 */ if( !x264_cabac_decode_decision( &h->cabac, 37 ) ) return 1 + x264_cabac_decode_decision( &h->cabac, 39 ); /* B_L0_8x8, B_L1_8x8 */ type = 3; if( x264_cabac_decode_decision( &h->cabac, 38 ) ) { if( x264_cabac_decode_decision( &h->cabac, 39 ) ) return 11 + x264_cabac_decode_decision( &h->cabac, 39 ); /* B_L1_4x4, B_Bi_4x4 */ type += 4; } type += 2*x264_cabac_decode_decision( &h->cabac, 39 ); type += x264_cabac_decode_decision( &h->cabac, 39 ); return type; }static inline int x264_cabac_decode_mb_type_intra( x264_t *h, int ctx0, int ctx1, int ctx2, int ctx3, int ctx4, int ctx5 ){ int i_mb_type; if( x264_cabac_decode_decision( &h->cabac, ctx0 ) == 0 ) { return 0; /* I4x4 */ }// printf(" \nmb_type after dec1 %d %d",*h->cabac.s->p,h->cabac.s->i_left); if( x264_cabac_decode_terminal(&h->cabac) ) { return 25; /* I_PCM */ }// printf(" \nmb_type after dec2 %d %d",*h->cabac.s->p,h->cabac.s->i_left); i_mb_type = 1; /* I16x16 */ if( x264_cabac_decode_decision( &h->cabac, ctx1 ) ) { i_mb_type += 12; /* cbp_luma != 0 */ //h->mb.i_cbp_luma = 1 ; } else { //h->mb.i_cbp_luma = 0 ; }// printf(" \nmb_type after dec3 %d %d",*h->cabac.s->p,h->cabac.s->i_left); if( x264_cabac_decode_decision( &h->cabac, ctx2 ) ) { if( x264_cabac_decode_decision( &h->cabac, ctx3 ) ) { i_mb_type += 4 * 2; /* cbp_chroma == 2 */ //h->mb.i_cbp_chroma = 2 ; } else { i_mb_type += 4 * 1; /* cbp_chroma == 1 */ //h->mb.i_cbp_chroma = 1 ; } } else { //h->mb.i_cbp_chroma = 0 ; }// printf(" \nmb_type after dec4 %d %d",*h->cabac.s->p,h->cabac.s->i_left); if( x264_cabac_decode_decision( &h->cabac, ctx4 ) ) { i_mb_type += 2; }// printf(" \nmb_type after dec5 %d %d",*h->cabac.s->p,h->cabac.s->i_left); if( x264_cabac_decode_decision( &h->cabac, ctx5 ) ) { i_mb_type += 1; } //printf(" \nmb_type after dec6 %d %d",*h->cabac.s->p,h->cabac.s->i_left); return i_mb_type;}static int x264_cabac_decode_mb_type( x264_t *h ){ int i_mb_type = 0; int ctx;// int sym, sym1, sym2,sym3,sym4,sym5; int total = 0;// int act_sym; if( h->sh.i_type == SLICE_TYPE_I ) { ctx = 0; if( h->mb.i_mb_x > 0 && h->mb.type[h->mb.i_mb_xy - 1] != I_4x4 ) { ctx++; } if( h->mb.i_mb_y > 0 && h->mb.type[h->mb.i_mb_xy - h->mb.i_mb_stride] != I_4x4 ) { ctx++; } i_mb_type = x264_cabac_decode_mb_type_intra( h, 3+ctx, 3+3, 3+4, 3+5, 3+6, 3+7 ); return i_mb_type; } else if( h->sh.i_type == SLICE_TYPE_P) { if(x264_cabac_decode_decision( &h->cabac, 14 ) == 0 ) { /* P-type */ if( x264_cabac_decode_decision( &h->cabac, 15 ) == 0 ) { if( x264_cabac_decode_decision( &h->cabac, 16 ) == 0 ) return 0; /* P_L0_D16x16; */ else return 3; /* P_8x8; */ } else { if( x264_cabac_decode_decision( &h->cabac, 17 ) == 0 ) return 2; /* P_L0_D8x16; */ else return 1; /* P_L0_D16x8; */ } } else { return x264_cabac_decode_mb_type_intra( h, 17+0, 17+1, 17+2, 17+2, 17+3, 17+3 ) + 5; } } else if (h->sh.i_type == SLICE_TYPE_B) { int bits; ctx = 0; if( h->mb.i_mb_x > 0 && h->mb.type[h->mb.i_mb_xy - 1] != B_SKIP && h->mb.type[h->mb.i_mb_xy - 1] != B_DIRECT ) { ctx++; } if( h->mb.i_mb_y > 0 && h->mb.type[h->mb.i_mb_xy - h->mb.i_mb_stride] != B_SKIP && h->mb.type[h->mb.i_mb_xy - h->mb.i_mb_stride] != B_DIRECT ) { ctx++; } if( !x264_cabac_decode_decision( &h->cabac, 27+ctx) ) return 0; /* B_Direct_16x16 */ if( !x264_cabac_decode_decision( &h->cabac, 27+3 ) ) { return 1 + x264_cabac_decode_decision( &h->cabac, 27+5 ); /* B_L[01]_16x16 */ } bits = x264_cabac_decode_decision( &h->cabac,27+4) << 3; bits|= x264_cabac_decode_decision( &h->cabac, 27+5) << 2; bits|= x264_cabac_decode_decision( &h->cabac, 27+5) << 1; bits|= x264_cabac_decode_decision( &h->cabac, 27+5); if( bits < 8 ) return bits + 3; /* B_Bi_16x16 through B_L1_L0_16x8 */ else if( bits == 13 ) { return x264_cabac_decode_mb_type_intra( h, 32+0, 32+1, 32+2, 32+2, 32+3, 32+3 ) + 23; } else if( bits == 14 ) return 11; /* B_L1_L0_8x16 */ else if( bits == 15 ) return 22; /* B_8x8 */ bits= ( bits<<1 ) | x264_cabac_decode_decision( &h->cabac, 27+5); return bits - 4; /* B_L0_Bi_* through B_Bi_Bi_* */ } else { printf("\nerror in mb_type"); getchar(); return -1; }}static int x264_cabac_decode_mb_intra4x4_pred_mode( x264_t *h, int i_pred){ int i_mode = 0; if( x264_cabac_decode_decision( &h->cabac, 68 ) ) return i_pred; i_mode += 1 * x264_cabac_decode_decision( &h->cabac, 69 ); i_mode += 2 * x264_cabac_decode_decision( &h->cabac, 69 ); i_mode += 4 * x264_cabac_decode_decision( &h->cabac, 69 ); if( i_mode >= i_pred ) return i_mode + 1; else return i_mode;}static int x264_cabac_decode_mb_intra8x8_pred_mode( x264_t *h ){ int ctx = 0; /* No need to test for I4x4 or I_16x16 as cache_save handle that */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -