?? cabac.c
字號:
{
int i_mba_xy = -1;
int i_mbb_xy = -1;
int x = luma_inverse_x[4*i8x8];
int y = luma_inverse_y[4*i8x8];
int ctx = 0;
if( x > 0 )
i_mba_xy = t->mb.mb_xy;
else if( t->mb.mb_x > 0 )
i_mba_xy = t->mb.mb_xy - 1;
if( y > 0 )
i_mbb_xy = t->mb.mb_xy;
else if( t->mb.mb_y > 0 )
i_mbb_xy = t->mb.mb_xy - t->mb_stride;
/* No need to test for PCM and SKIP */
if( i_mba_xy >= 0 )
{
const int i8x8a = block_idx_xy[(x-1)&0x03][y]/4;
if( ((mb_ctxs[i_mba_xy].cbp_y >> i8x8a)&0x01) == 0 )
{
ctx++;
}
}
if( i_mbb_xy >= 0 )
{
const int i8x8b = block_idx_xy[x][(y-1)&0x03]/4;
if( ((mb_ctxs[i_mbb_xy].cbp_y >> i8x8b)&0x01) == 0 )
{
ctx += 2;
}
}
T264_cabac_encode_decision( &t->cabac, 73 + ctx, (t->mb.cbp_y >> i8x8)&0x01 );
}
}
static void T264_cabac_mb_cbp_chroma( T264_t *t )
{
int cbp_a = -1;
int cbp_b = -1;
int ctx;
T264_mb_context_t *mb_ctxs = &(t->rec->mb[0]);
/* No need to test for SKIP/PCM */
if( t->mb.mb_x > 0 )
{
cbp_a = (mb_ctxs[t->mb.mb_xy - 1].cbp_c)&0x3;
}
if( t->mb.mb_y > 0 )
{
cbp_b = (mb_ctxs[t->mb.mb_xy - t->mb_stride].cbp_c)&0x3;
}
ctx = 0;
if( cbp_a > 0 ) ctx++;
if( cbp_b > 0 ) ctx += 2;
if( t->mb.cbp_c == 0 )
{
T264_cabac_encode_decision( &t->cabac, 77 + ctx, 0 );
}
else
{
T264_cabac_encode_decision( &t->cabac, 77 + ctx, 1 );
ctx = 4;
if( cbp_a == 2 ) ctx++;
if( cbp_b == 2 ) ctx += 2;
T264_cabac_encode_decision( &t->cabac, 77 + ctx, t->mb.cbp_c > 1 ? 1 : 0 );
}
}
/* TODO check it with != qp per mb */
static void T264_cabac_mb_qp_delta( T264_t *t )
{
int i_mbn_xy = t->mb.mb_xy - 1;
int i_dqp = t->mb.mb_qp_delta;
int val = i_dqp <= 0 ? (-2*i_dqp) : (2*i_dqp - 1);
int ctx;
T264_mb_context_t *mb_ctxs = &(t->rec->mb[0]);
/* No need to test for PCM / SKIP */
if( i_mbn_xy >= 0 && mb_ctxs[i_mbn_xy].mb_qp_delta != 0 &&
( mb_ctxs[i_mbn_xy].mb_mode == I_16x16 || mb_ctxs[i_mbn_xy].cbp_y || mb_ctxs[i_mbn_xy].cbp_c) )
ctx = 1;
else
ctx = 0;
while( val > 0 )
{
T264_cabac_encode_decision( &t->cabac, 60 + ctx, 1 );
if( ctx < 2 )
ctx = 2;
else
ctx = 3;
val--;
}
T264_cabac_encode_decision( &t->cabac, 60 + ctx, 0 );
}
void T264_cabac_mb_skip( T264_t *t, int b_skip )
{
T264_mb_context_t *mb_ctxs = &(t->rec->mb[0]);
int ctx = 0;
if( t->mb.mb_x > 0 && !IS_SKIP( mb_ctxs[t->mb.mb_xy -1].mb_mode) )
{
ctx++;
}
if( t->mb.mb_y > 0 && !IS_SKIP( mb_ctxs[t->mb.mb_xy - t->mb_stride].mb_mode) )
{
ctx++;
}
if( t->slice_type == SLICE_P )
T264_cabac_encode_decision( &t->cabac, 11 + ctx, b_skip ? 1 : 0 );
else /* SLICE_TYPE_B */
T264_cabac_encode_decision( &t->cabac, 24 + ctx, b_skip ? 1 : 0 );
}
static __inline void T264_cabac_mb_sub_p_partition( T264_t *t, int i_sub )
{
if( i_sub == MB_8x8 )
{
T264_cabac_encode_decision( &t->cabac, 21, 1 );
}
else if( i_sub == MB_8x4 )
{
T264_cabac_encode_decision( &t->cabac, 21, 0 );
T264_cabac_encode_decision( &t->cabac, 22, 0 );
}
else if( i_sub == MB_4x8 )
{
T264_cabac_encode_decision( &t->cabac, 21, 0 );
T264_cabac_encode_decision( &t->cabac, 22, 1 );
T264_cabac_encode_decision( &t->cabac, 23, 1 );
}
else if( i_sub == MB_4x4 )
{
T264_cabac_encode_decision( &t->cabac, 21, 0 );
T264_cabac_encode_decision( &t->cabac, 22, 1 );
T264_cabac_encode_decision( &t->cabac, 23, 0 );
}
}
static __inline void T264_cabac_mb_sub_b_partition( T264_t *t, int i_sub )
{
if( i_sub == B_DIRECT_8x8 )
{
T264_cabac_encode_decision( &t->cabac, 36, 0 );
}
else if( i_sub == B_L0_8x8 )
{
T264_cabac_encode_decision( &t->cabac, 36, 1 );
T264_cabac_encode_decision( &t->cabac, 37, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
}
else if( i_sub == B_L1_8x8 )
{
T264_cabac_encode_decision( &t->cabac, 36, 1 );
T264_cabac_encode_decision( &t->cabac, 37, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 1 );
}
else if( i_sub == B_Bi_8x8 )
{
T264_cabac_encode_decision( &t->cabac, 36, 1 );
T264_cabac_encode_decision( &t->cabac, 37, 1 );
T264_cabac_encode_decision( &t->cabac, 38, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
}
else if( i_sub == B_L0_8x4 )
{
T264_cabac_encode_decision( &t->cabac, 36, 1 );
T264_cabac_encode_decision( &t->cabac, 37, 1 );
T264_cabac_encode_decision( &t->cabac, 38, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 1 );
}
else if( i_sub == B_L0_4x8 )
{
T264_cabac_encode_decision( &t->cabac, 36, 1 );
T264_cabac_encode_decision( &t->cabac, 37, 1 );
T264_cabac_encode_decision( &t->cabac, 38, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 1 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
}
else if( i_sub == B_L1_8x4 )
{
T264_cabac_encode_decision( &t->cabac, 36, 1 );
T264_cabac_encode_decision( &t->cabac, 37, 1 );
T264_cabac_encode_decision( &t->cabac, 38, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 1 );
T264_cabac_encode_decision( &t->cabac, 39, 1 );
}
else if( i_sub == B_L1_4x8 )
{
T264_cabac_encode_decision( &t->cabac, 36, 1 );
T264_cabac_encode_decision( &t->cabac, 37, 1 );
T264_cabac_encode_decision( &t->cabac, 38, 1 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
}
else if( i_sub == B_Bi_8x4 )
{
T264_cabac_encode_decision( &t->cabac, 36, 1 );
T264_cabac_encode_decision( &t->cabac, 37, 1 );
T264_cabac_encode_decision( &t->cabac, 38, 1 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 1 );
}
else if( i_sub == B_Bi_4x8 )
{
T264_cabac_encode_decision( &t->cabac, 36, 1 );
T264_cabac_encode_decision( &t->cabac, 37, 1 );
T264_cabac_encode_decision( &t->cabac, 38, 1 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 1 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
}
else if( i_sub == B_L0_4x4 )
{
T264_cabac_encode_decision( &t->cabac, 36, 1 );
T264_cabac_encode_decision( &t->cabac, 37, 1 );
T264_cabac_encode_decision( &t->cabac, 38, 1 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
T264_cabac_encode_decision( &t->cabac, 39, 1 );
T264_cabac_encode_decision( &t->cabac, 39, 1 );
}
else if( i_sub == B_L1_4x4 )
{
T264_cabac_encode_decision( &t->cabac, 36, 1 );
T264_cabac_encode_decision( &t->cabac, 37, 1 );
T264_cabac_encode_decision( &t->cabac, 38, 1 );
T264_cabac_encode_decision( &t->cabac, 39, 1 );
T264_cabac_encode_decision( &t->cabac, 39, 0 );
}
else if( i_sub == B_Bi_4x4 )
{
T264_cabac_encode_decision( &t->cabac, 36, 1 );
T264_cabac_encode_decision( &t->cabac, 37, 1 );
T264_cabac_encode_decision( &t->cabac, 38, 1 );
T264_cabac_encode_decision( &t->cabac, 39, 1 );
T264_cabac_encode_decision( &t->cabac, 39, 1 );
}
}
static __inline void T264_cabac_mb_ref( T264_t *t, int i_list, int idx )
{
const int i8 = T264_scan8[idx];
T264_mb_context_t *mb_ctxs = &(t->rec->mb[0]);
const int i_refa = t->mb.vec_ref[i8 - 1].vec[i_list].refno;
const int i_refb = t->mb.vec_ref[i8 - 8].vec[i_list].refno;
int i_ref = t->mb.vec_ref[i8].vec[i_list].refno;
int a_direct, b_direct;
int ctx = 0;
int luma_idx = luma_index[idx];
if( t->slice_type==SLICE_B && t->mb.mb_x > 0 && (mb_ctxs[t->mb.mb_xy-1].mb_mode == B_SKIP||mb_ctxs[t->mb.mb_xy-1].is_copy ) && (luma_idx&0x03)==0)
{
a_direct = 1;
}
else
a_direct = 0;
if( t->slice_type==SLICE_B && t->mb.mb_y > 0 && (mb_ctxs[t->mb.mb_xy - t->mb_stride].mb_mode == B_SKIP||mb_ctxs[t->mb.mb_xy - t->mb_stride].is_copy) && luma_idx<4)
{
b_direct = 1;
}
else
b_direct = 0;
if( i_refa>0 && !a_direct)
ctx++;
if( i_refb>0 && !b_direct)
ctx += 2;
while( i_ref > 0 )
{
T264_cabac_encode_decision( &t->cabac, 54 + ctx, 1 );
if( ctx < 4 )
ctx = 4;
else
ctx = 5;
i_ref--;
}
T264_cabac_encode_decision( &t->cabac, 54 + ctx, 0 );
}
static __inline void T264_cabac_mb_mvd_cpn( T264_t *t, int i_list, int i8, int l, int mvd )
{
const int amvd = abs( t->mb.mvd_ref[i_list][i8 - 1][l] ) +
abs( t->mb.mvd_ref[i_list][i8 - 8][l] );
const int i_abs = abs( mvd );
const int i_prefix = T264_MIN( i_abs, 9 );
const int ctxbase = (l == 0 ? 40 : 47);
int ctx;
int i;
if( amvd < 3 )
ctx = 0;
else if( amvd > 32 )
ctx = 2;
else
ctx = 1;
for( i = 0; i < i_prefix; i++ )
{
T264_cabac_encode_decision( &t->cabac, ctxbase + ctx, 1 );
if( ctx < 3 )
ctx = 3;
else if( ctx < 6 )
ctx++;
}
if( i_prefix < 9 )
{
T264_cabac_encode_decision( &t->cabac, ctxbase + ctx, 0 );
}
if( i_prefix >= 9 )
{
int i_suffix = i_abs - 9;
int k = 3;
while( i_suffix >= (1<<k) )
{
T264_cabac_encode_bypass( &t->cabac, 1 );
i_suffix -= 1 << k;
k++;
}
T264_cabac_encode_bypass( &t->cabac, 0 );
while( k-- )
{
T264_cabac_encode_bypass( &t->cabac, (i_suffix >> k)&0x01 );
}
}
/* sign */
if( mvd > 0 )
T264_cabac_encode_bypass( &t->cabac, 0 );
else if( mvd < 0 )
T264_cabac_encode_bypass( &t->cabac, 1 );
}
static __inline void T264_cabac_mb_mvd( T264_t *t, int i_list, int idx, int width, int height )
{
T264_vector_t mvp;
int mdx, mdy;
int i, j;
int i8 = T264_scan8[idx];
int luma_idx = luma_index[idx];
/* Calculate mvd */
mvp.refno = t->mb.vec_ref[i8].vec[i_list].refno;
T264_predict_mv( t, i_list, luma_idx, width, &mvp );
mdx = t->mb.vec_ref[i8].vec[i_list].x - mvp.x;
mdy = t->mb.vec_ref[i8].vec[i_list].y - mvp.y;
/* encode */
T264_cabac_mb_mvd_cpn( t, i_list, i8, 0, mdx );
T264_cabac_mb_mvd_cpn( t, i_list, i8, 1, mdy );
/* save mvd value */
for(j=0; j<height; j++)
{
for(i=0; i<width; i++)
{
t->mb.mvd_ref[i_list][i8+i][0] = mdx;
t->mb.mvd_ref[i_list][i8+i][1] = mdy;
t->mb.mvd[i_list][luma_idx+i][0] = mdx;
t->mb.mvd[i_list][luma_idx+i][1] = mdy;
}
i8 += 8;
luma_idx += 4;
}
}
static __inline void T264_cabac_mb8x8_mvd( T264_t *t, int i_list )
{
int i;
int sub_part;
for( i = 0; i < 4; i++ )
{
sub_part = t->mb.submb_part[luma_index[i<<2]];
if( T264_mb_partition_listX_table[sub_part-B_DIRECT_8x8][i_list] == 0 )
{
continue;
}
switch( sub_part )
{
case B_DIRECT_8x8:
assert(0);
break;
case B_L0_8x8:
case B_L1_8x8:
case B_Bi_8x8:
T264_cabac_mb_mvd( t, i_list, 4*i, 2, 2 );
break;
case B_L0_8x4:
case B_L1_8x4:
case B_Bi_8x4:
T264_cabac_mb_mvd( t, i_list, 4*i+0, 2, 1 );
T264_cabac_mb_mvd( t, i_list, 4*i+2, 2, 1 );
break;
case B_L0_4x8:
case B_L1_4x8:
case B_Bi_4x8:
T264_cabac_mb_mvd( t, i_list, 4*i+0, 1, 2 );
T264_cabac_mb_mvd( t, i_list, 4*i+1, 1, 2 );
break;
case B_L0_4x4:
case B_L1_4x4:
case B_Bi_4x4:
T264_cabac_mb_mvd( t, i_list, 4*i+0, 1, 1 );
T264_cabac_mb_mvd( t, i_list, 4*i+1, 1, 1 );
T264_cabac_mb_mvd( t, i_list, 4*i+2, 1, 1 );
T264_cabac_mb_mvd( t, i_list, 4*i+3, 1, 1 );
break;
}
}
}
static int T264_cabac_mb_cbf_ctxidxinc( T264_t *t, int i_cat, int i_idx )
{
/* TODO: clean up/optimize */
T264_mb_context_t *mb_ctxs = &(t->rec->mb[0]);
T264_mb_context_t *mb_ctx;
int i_mba_xy = -1;
int i_mbb_xy = -1;
int i_nza = -1;
int i_nzb = -1;
int ctx = 0;
int cbp;
if( i_cat == 0 )
{
if( t->mb.mb_x > 0 )
{
i_mba_xy = t->mb.mb_xy -1;
mb_ctx = &(mb_ctxs[i_mba_xy]);
if( mb_ctx->mb_mode == I_16x16 )
{
i_nza = (mb_ctx->cbp & 0x100);
}
}
if( t->mb.mb_y > 0 )
{
i_mbb_xy = t->mb.mb_xy - t->mb_stride;
mb_ctx = &(mb_ctxs[i_mbb_xy]);
if( mb_ctx->mb_mode == I_16x16 )
{
i_nzb = (mb_ctx->cbp & 0x100);
}
}
}
else if( i_cat == 1 || i_cat == 2 )
{
int x = luma_inverse_x[i_idx];
int y = luma_inverse_y[i_idx];
int i8 = T264_scan8[i_idx];
if( x > 0 )
i_mba_xy = t->mb.mb_xy;
else if( t->mb.mb_x > 0 )
i_mba_xy = t->mb.mb_xy -1;
if( y > 0 )
i_mbb_xy = t->mb.mb_xy;
else if( t->mb.mb_y > 0 )
i_mbb_xy = t->mb.mb_xy - t->mb_stride;
/* no need to test for skip/pcm */
if( i_mba_xy >= 0 )
{
const int i8x8a = block_idx_xy[(x-1)&0x03][y]/4;
if( (mb_ctxs[i_mba_xy].cbp_y&0x0f)>> i8x8a )
{
i_nza = t->mb.nnz_ref[i8-1];
}
}
if( i_mbb_xy >= 0 )
{
const int i8x8b = block_idx_xy[x][(y-1)&0x03]/4;
if( (mb_ctxs[i_mbb_xy].cbp_y&0x0f)>> i8x8b )
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -