📄 analyse.c
字号:
*pi_count = 1;
}
}
/* MAX = 9 */
static void predict_4x4_mode_available( unsigned int i_neighbour,
int *mode, int *pi_count )
{
int b_l = i_neighbour & MB_LEFT;
int b_t = i_neighbour & MB_TOP;
if( b_l && b_t )
{
*pi_count = 6;
*mode++ = I_PRED_4x4_DC;
*mode++ = I_PRED_4x4_H;
*mode++ = I_PRED_4x4_V;
*mode++ = I_PRED_4x4_DDL;
if( i_neighbour & MB_TOPLEFT )
{
*mode++ = I_PRED_4x4_DDR;
*mode++ = I_PRED_4x4_VR;
*mode++ = I_PRED_4x4_HD;
*pi_count += 3;
}
*mode++ = I_PRED_4x4_VL;
*mode++ = I_PRED_4x4_HU;
}
else if( b_l )
{
*mode++ = I_PRED_4x4_DC_LEFT;
*mode++ = I_PRED_4x4_H;
*mode++ = I_PRED_4x4_HU;
*pi_count = 3;
}
else if( b_t )
{
*mode++ = I_PRED_4x4_DC_TOP;
*mode++ = I_PRED_4x4_V;
*mode++ = I_PRED_4x4_DDL;
*mode++ = I_PRED_4x4_VL;
*pi_count = 4;
}
else
{
*mode++ = I_PRED_4x4_DC_128;
*pi_count = 1;
}
}
static void x264_mb_analyse_intra_chroma( x264_t *h, x264_mb_analysis_t *a )
{
int i;
int i_max;
int predict_mode[4];
uint8_t *p_dstc[2], *p_srcc[2];
if( a->i_satd_i8x8chroma < COST_MAX )
return;
/* 8x8 prediction selection for chroma */
p_dstc[0] = h->mb.pic.p_fdec[1];
p_dstc[1] = h->mb.pic.p_fdec[2];
p_srcc[0] = h->mb.pic.p_fenc[1];
p_srcc[1] = h->mb.pic.p_fenc[2];
predict_8x8chroma_mode_available( h->mb.i_neighbour, predict_mode, &i_max );
a->i_satd_i8x8chroma = COST_MAX;
if( i_max == 4 && h->pixf.intra_satd_x3_8x8c && h->pixf.mbcmp[0] == h->pixf.satd[0] )
{
int satdu[4], satdv[4];
h->pixf.intra_satd_x3_8x8c( p_srcc[0], p_dstc[0], satdu );
h->pixf.intra_satd_x3_8x8c( p_srcc[1], p_dstc[1], satdv );
h->predict_8x8c[I_PRED_CHROMA_P]( p_dstc[0] );
h->predict_8x8c[I_PRED_CHROMA_P]( p_dstc[1] );
satdu[I_PRED_CHROMA_P] =
h->pixf.mbcmp[PIXEL_8x8]( p_dstc[0], FDEC_STRIDE, p_srcc[0], FENC_STRIDE );
satdv[I_PRED_CHROMA_P] =
h->pixf.mbcmp[PIXEL_8x8]( p_dstc[1], FDEC_STRIDE, p_srcc[1], FENC_STRIDE );
for( i=0; i<i_max; i++ )
{
int i_mode = predict_mode[i];
int i_satd = satdu[i_mode] + satdv[i_mode]
+ a->i_lambda * bs_size_ue(i_mode);
COPY2_IF_LT( a->i_satd_i8x8chroma, i_satd, a->i_predict8x8chroma, i_mode );
}
}
else
{
for( i=0; i<i_max; i++ )
{
int i_satd;
int i_mode = predict_mode[i];
/* we do the prediction */
h->predict_8x8c[i_mode]( p_dstc[0] );
h->predict_8x8c[i_mode]( p_dstc[1] );
/* we calculate the cost */
i_satd = h->pixf.mbcmp[PIXEL_8x8]( p_dstc[0], FDEC_STRIDE,
p_srcc[0], FENC_STRIDE ) +
h->pixf.mbcmp[PIXEL_8x8]( p_dstc[1], FDEC_STRIDE,
p_srcc[1], FENC_STRIDE ) +
a->i_lambda * bs_size_ue( x264_mb_pred_mode8x8c_fix[i_mode] );
COPY2_IF_LT( a->i_satd_i8x8chroma, i_satd, a->i_predict8x8chroma, i_mode );
}
}
h->mb.i_chroma_pred_mode = a->i_predict8x8chroma;
}
static void x264_mb_analyse_intra( x264_t *h, x264_mb_analysis_t *a, int i_satd_inter )
{
const unsigned int flags = h->sh.i_type == SLICE_TYPE_I ? h->param.analyse.intra : h->param.analyse.inter;
uint8_t *p_src = h->mb.pic.p_fenc[0];
uint8_t *p_dst = h->mb.pic.p_fdec[0];
int i, idx;
int i_max;
int predict_mode[9];
int b_merged_satd = h->pixf.intra_satd_x3_16x16 && h->pixf.mbcmp[0] == h->pixf.satd[0];
/*---------------- Try all mode and calculate their score ---------------*/
/* 16x16 prediction selection */
predict_16x16_mode_available( h->mb.i_neighbour, predict_mode, &i_max );
if( b_merged_satd && i_max == 4 )
{
h->pixf.intra_satd_x3_16x16( p_src, p_dst, a->i_satd_i16x16_dir );
h->predict_16x16[I_PRED_16x16_P]( p_dst );
a->i_satd_i16x16_dir[I_PRED_16x16_P] =
h->pixf.mbcmp[PIXEL_16x16]( p_dst, FDEC_STRIDE, p_src, FENC_STRIDE );
for( i=0; i<4; i++ )
{
int cost = a->i_satd_i16x16_dir[i] += a->i_lambda * bs_size_ue(i);
COPY2_IF_LT( a->i_satd_i16x16, cost, a->i_predict16x16, i );
}
}
else
{
for( i = 0; i < i_max; i++ )
{
int i_satd;
int i_mode = predict_mode[i];
h->predict_16x16[i_mode]( p_dst );
i_satd = h->pixf.mbcmp[PIXEL_16x16]( p_dst, FDEC_STRIDE, p_src, FENC_STRIDE ) +
a->i_lambda * bs_size_ue( x264_mb_pred_mode16x16_fix[i_mode] );
COPY2_IF_LT( a->i_satd_i16x16, i_satd, a->i_predict16x16, i_mode );
a->i_satd_i16x16_dir[i_mode] = i_satd;
}
}
if( h->sh.i_type == SLICE_TYPE_B )
/* cavlc mb type prefix */
a->i_satd_i16x16 += a->i_lambda * i_mb_b_cost_table[I_16x16];
if( a->b_fast_intra && a->i_satd_i16x16 > 2*i_satd_inter )
return;
/* 8x8 prediction selection */
if( flags & X264_ANALYSE_I8x8 )
{
DECLARE_ALIGNED( uint8_t, edge[33], 8 );
x264_pixel_cmp_t sa8d = (*h->pixf.mbcmp == *h->pixf.sad) ? h->pixf.sad[PIXEL_8x8] : h->pixf.sa8d[PIXEL_8x8];
int i_satd_thresh = a->b_mbrd ? COST_MAX : X264_MIN( i_satd_inter, a->i_satd_i16x16 );
int i_cost = 0;
b_merged_satd = h->pixf.intra_sa8d_x3_8x8 && h->pixf.mbcmp[0] == h->pixf.satd[0];
// FIXME some bias like in i4x4?
if( h->sh.i_type == SLICE_TYPE_B )
i_cost += a->i_lambda * i_mb_b_cost_table[I_8x8];
for( idx = 0;; idx++ )
{
int x = idx&1;
int y = idx>>1;
uint8_t *p_src_by = p_src + 8*x + 8*y*FENC_STRIDE;
uint8_t *p_dst_by = p_dst + 8*x + 8*y*FDEC_STRIDE;
int i_best = COST_MAX;
int i_pred_mode = x264_mb_predict_intra4x4_mode( h, 4*idx );
predict_4x4_mode_available( h->mb.i_neighbour8[idx], predict_mode, &i_max );
x264_predict_8x8_filter( p_dst_by, edge, h->mb.i_neighbour8[idx], ALL_NEIGHBORS );
if( b_merged_satd && i_max == 9 )
{
int satd[3];
h->pixf.intra_sa8d_x3_8x8( p_src_by, edge, satd );
if( i_pred_mode < 3 )
satd[i_pred_mode] -= 3 * a->i_lambda;
for( i=2; i>=0; i-- )
{
int cost = a->i_satd_i8x8_dir[i][idx] = satd[i] + 4 * a->i_lambda;
COPY2_IF_LT( i_best, cost, a->i_predict8x8[idx], i );
}
i = 3;
}
else
i = 0;
for( ; i<i_max; i++ )
{
int i_satd;
int i_mode = predict_mode[i];
h->predict_8x8[i_mode]( p_dst_by, edge );
i_satd = sa8d( p_dst_by, FDEC_STRIDE, p_src_by, FENC_STRIDE )
+ a->i_lambda * (i_pred_mode == x264_mb_pred_mode4x4_fix(i_mode) ? 1 : 4);
COPY2_IF_LT( i_best, i_satd, a->i_predict8x8[idx], i_mode );
a->i_satd_i8x8_dir[i_mode][idx] = i_satd;
}
i_cost += i_best;
if( idx == 3 || i_cost > i_satd_thresh )
break;
/* we need to encode this block now (for next ones) */
h->predict_8x8[a->i_predict8x8[idx]]( p_dst_by, edge );
x264_mb_encode_i8x8( h, idx, a->i_qp );
x264_macroblock_cache_intra8x8_pred( h, 2*x, 2*y, a->i_predict8x8[idx] );
}
if( idx == 3 )
a->i_satd_i8x8 = i_cost;
else
{
a->i_satd_i8x8 = COST_MAX;
i_cost = i_cost * 4/(idx+1);
}
if( X264_MIN(i_cost, a->i_satd_i16x16) > i_satd_inter*(5+a->b_mbrd)/4 )
return;
}
/* 4x4 prediction selection */
if( flags & X264_ANALYSE_I4x4 )
{
int i_cost;
int i_satd_thresh = X264_MIN3( i_satd_inter, a->i_satd_i16x16, a->i_satd_i8x8 );
b_merged_satd = h->pixf.intra_satd_x3_4x4 && h->pixf.mbcmp[0] == h->pixf.satd[0];
if( a->b_mbrd )
i_satd_thresh = i_satd_thresh * (10-a->b_fast_intra)/8;
i_cost = a->i_lambda * 24; /* from JVT (SATD0) */
if( h->sh.i_type == SLICE_TYPE_B )
i_cost += a->i_lambda * i_mb_b_cost_table[I_4x4];
for( idx = 0;; idx++ )
{
int x = block_idx_x[idx];
int y = block_idx_y[idx];
uint8_t *p_src_by = p_src + 4*x + 4*y*FENC_STRIDE;
uint8_t *p_dst_by = p_dst + 4*x + 4*y*FDEC_STRIDE;
int i_best = COST_MAX;
int i_pred_mode = x264_mb_predict_intra4x4_mode( h, idx );
predict_4x4_mode_available( h->mb.i_neighbour4[idx], predict_mode, &i_max );
if( (h->mb.i_neighbour4[idx] & (MB_TOPRIGHT|MB_TOP)) == MB_TOP )
/* emulate missing topright samples */
*(uint32_t*) &p_dst_by[4 - FDEC_STRIDE] = p_dst_by[3 - FDEC_STRIDE] * 0x01010101U;
if( b_merged_satd && i_max >= 6 )
{
int satd[3];
h->pixf.intra_satd_x3_4x4( p_src_by, p_dst_by, satd );
if( i_pred_mode < 3 )
satd[i_pred_mode] -= 3 * a->i_lambda;
for( i=2; i>=0; i-- )
COPY2_IF_LT( i_best, satd[i] + 4 * a->i_lambda,
a->i_predict4x4[idx], i );
i = 3;
}
else
i = 0;
for( ; i<i_max; i++ )
{
int i_satd;
int i_mode = predict_mode[i];
h->predict_4x4[i_mode]( p_dst_by );
i_satd = h->pixf.mbcmp[PIXEL_4x4]( p_dst_by, FDEC_STRIDE,
p_src_by, FENC_STRIDE )
+ a->i_lambda * (i_pred_mode == x264_mb_pred_mode4x4_fix(i_mode) ? 1 : 4);
COPY2_IF_LT( i_best, i_satd, a->i_predict4x4[idx], i_mode );
}
i_cost += i_best;
if( i_cost > i_satd_thresh || idx == 15 )
break;
/* we need to encode this block now (for next ones) */
h->predict_4x4[a->i_predict4x4[idx]]( p_dst_by );
x264_mb_encode_i4x4( h, idx, a->i_qp );
h->mb.cache.intra4x4_pred_mode[x264_scan8[idx]] = a->i_predict4x4[idx];
}
if( idx == 15 )
a->i_satd_i4x4 = i_cost;
else
a->i_satd_i4x4 = COST_MAX;
}
}
static void x264_intra_rd( x264_t *h, x264_mb_analysis_t *a, int i_satd_thresh )
{
if( a->i_satd_i16x16 <= i_satd_thresh )
{
h->mb.i_type = I_16x16;
x264_analyse_update_cache( h, a );
a->i_satd_i16x16 = x264_rd_cost_mb( h, a->i_lambda2 );
}
else
a->i_satd_i16x16 = COST_MAX;
if( a->i_satd_i4x4 <= i_satd_thresh && a->i_satd_i4x4 < COST_MAX )
{
h->mb.i_type = I_4x4;
x264_analyse_update_cache( h, a );
a->i_satd_i4x4 = x264_rd_cost_mb( h, a->i_lambda2 );
}
else
a->i_satd_i4x4 = COST_MAX;
if( a->i_satd_i8x8 <= i_satd_thresh && a->i_satd_i8x8 < COST_MAX )
{
h->mb.i_type = I_8x8;
x264_analyse_update_cache( h, a );
a->i_satd_i8x8 = x264_rd_cost_mb( h, a->i_lambda2 );
}
else
a->i_satd_i8x8 = COST_MAX;
}
static void x264_intra_rd_refine( x264_t *h, x264_mb_analysis_t *a )
{
uint8_t *p_src = h->mb.pic.p_fenc[0];
uint8_t *p_dst = h->mb.pic.p_fdec[0];
int i, idx, x, y;
int i_max, i_satd, i_best, i_mode;
int i_pred_mode;
int predict_mode[9];
if( h->mb.i_type == I_16x16 )
{
int old_pred_mode = a->i_predict16x16;
int i_thresh = a->i_satd_i16x16_dir[old_pred_mode] * 9/8;
i_best = a->i_satd_i16x16;
predict_16x16_mode_available( h->mb.i_neighbour, predict_mode, &i_max );
for( i = 0; i < i_max; i++ )
{
int i_mode = predict_mode[i];
if( i_mode == old_pred_mode || a->i_satd_i16x16_dir[i_mode] > i_thresh )
continue;
h->mb.i_intra16x16_pred_mode = i_mode;
i_satd = x264_rd_cost_mb( h, a->i_lambda2 );
COPY2_IF_LT( i_best, i_satd, a->i_predict16x16, i_mode );
}
}
else if( h->mb.i_type == I_4x4 )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -