Index: encoder/macroblock.c =================================================================== --- encoder/macroblock.c (revision 263) +++ encoder/macroblock.c (working copy) @@ -554,34 +554,6 @@ } /***************************************************************************** - * x264_macroblock_encode_pskip: - * Encode an already marked skip block - *****************************************************************************/ -void x264_macroblock_encode_pskip( x264_t *h ) -{ - const int mvx = x264_clip3( h->mb.cache.mv[0][x264_scan8[0]][0], - h->mb.mv_min[0], h->mb.mv_max[0] ); - const int mvy = x264_clip3( h->mb.cache.mv[0][x264_scan8[0]][1], - h->mb.mv_min[1], h->mb.mv_max[1] ); - - /* Motion compensation XXX probably unneeded */ - h->mc.mc_luma( h->mb.pic.p_fref[0][0], h->mb.pic.i_stride[0], - h->mb.pic.p_fdec[0], h->mb.pic.i_stride[0], - mvx, mvy, 16, 16 ); - - /* Chroma MC */ - h->mc.mc_chroma( h->mb.pic.p_fref[0][0][4], h->mb.pic.i_stride[1], - h->mb.pic.p_fdec[1], h->mb.pic.i_stride[1], - mvx, mvy, 8, 8 ); - - h->mc.mc_chroma( h->mb.pic.p_fref[0][0][5], h->mb.pic.i_stride[2], - h->mb.pic.p_fdec[2], h->mb.pic.i_stride[2], - mvx, mvy, 8, 8 ); - - x264_macroblock_encode_skip( h ); -} - -/***************************************************************************** * x264_macroblock_encode: *****************************************************************************/ void x264_macroblock_encode( x264_t *h ) @@ -592,8 +564,8 @@ if( h->mb.i_type == P_SKIP ) { - /* A bit special */ - x264_macroblock_encode_pskip( h ); + x264_mb_mc_pskip( h ); + x264_macroblock_encode_skip( h ); return; } if( h->mb.i_type == B_SKIP ) @@ -829,11 +801,8 @@ h->mb.i_cbp_luma == 0x00 && h->mb.i_cbp_chroma== 0x00 && h->mb.cache.ref[0][x264_scan8[0]] == 0 ) { - int mvp[2]; - - x264_mb_predict_mv_pskip( h, mvp ); - if( h->mb.cache.mv[0][x264_scan8[0]][0] == mvp[0] && - h->mb.cache.mv[0][x264_scan8[0]][1] == mvp[1] ) + if( h->mb.cache.mv[0][x264_scan8[0]][0] == h->mb.cache.pskip_mv[0] && + h->mb.cache.mv[0][x264_scan8[0]][1] == h->mb.cache.pskip_mv[1] ) { h->mb.i_type = P_SKIP; h->mb.qp[h->mb.i_mb_xy] = h->mb.i_last_qp; /* Needed */ @@ -858,7 +827,7 @@ * Check if the current MB could be encoded as a [PB]_SKIP (it supposes you use * the previous QP *****************************************************************************/ -int x264_macroblock_probe_skip( x264_t *h, int b_bidir ) +int x264_macroblock_probe_skip( x264_t *h, int b_mc ) { DECLARE_ALIGNED( int16_t, dct4x4[16][4][4], 16 ); DECLARE_ALIGNED( int16_t, dct2x2[2][2], 16 ); @@ -871,12 +840,11 @@ int i8x8, i4x4; int i_decimate_mb; - if( !b_bidir ) + if( b_mc ) { /* Get the MV */ - x264_mb_predict_mv_pskip( h, mvp ); - mvp[0] = x264_clip3( mvp[0], h->mb.mv_min[0], h->mb.mv_max[0] ); - mvp[1] = x264_clip3( mvp[1], h->mb.mv_min[1], h->mb.mv_max[1] ); + mvp[0] = x264_clip3( h->mb.cache.pskip_mv[0], h->mb.mv_min[0], h->mb.mv_max[0] ); + mvp[1] = x264_clip3( h->mb.cache.pskip_mv[1], h->mb.mv_min[1], h->mb.mv_max[1] ); /* Motion compensation */ h->mc.mc_luma( h->mb.pic.p_fref[0][0], h->mb.pic.i_stride[0], @@ -917,7 +885,7 @@ uint8_t *p_src = h->mb.pic.p_fenc[1+ch]; uint8_t *p_dst = h->mb.pic.p_fdec[1+ch]; - if( !b_bidir ) + if( b_mc ) { h->mc.mc_chroma( h->mb.pic.p_fref[0][0][4+ch], i_stride, h->mb.pic.p_fdec[1+ch], i_stride, Index: encoder/macroblock.h =================================================================== --- encoder/macroblock.h (revision 263) +++ encoder/macroblock.h (working copy) @@ -29,9 +29,9 @@ int x264_macroblock_probe_skip( x264_t *h, int b_bidir ); static inline int x264_macroblock_probe_pskip( x264_t *h ) + { return x264_macroblock_probe_skip( h, 1 ); } +static inline int x264_macroblock_probe_bskip( x264_t *h ) { return x264_macroblock_probe_skip( h, 0 ); } -static inline int x264_macroblock_probe_bskip( x264_t *h ) - { return x264_macroblock_probe_skip( h, 1 ); } void x264_macroblock_encode ( x264_t *h ); void x264_macroblock_write_cabac ( x264_t *h, x264_cabac_t *cb ); Index: encoder/rdo.c =================================================================== --- encoder/rdo.c (revision 263) +++ encoder/rdo.c (working copy) @@ -39,7 +39,7 @@ if( IS_SKIP( h->mb.i_type ) ) { - i_bits = 1; + i_bits = 0; } else if( h->param.b_cabac ) { Index: encoder/analyse.c =================================================================== --- encoder/analyse.c (revision 263) +++ encoder/analyse.c (working copy) @@ -1522,15 +1522,30 @@ else if( h->sh.i_type == SLICE_TYPE_P ) { int b_skip = 0; + int i_skip_cost = COST_MAX; int i_cost; int i_intra_cost, i_intra_type; + x264_mb_predict_mv_pskip( h, h->mb.cache.pskip_mv ); /* Fast P_SKIP detection */ - if( ( h->mb.i_mb_type_left == P_SKIP ) || - ( h->mb.i_mb_type_top == P_SKIP ) || - ( h->mb.i_mb_type_topleft == P_SKIP ) || - ( h->mb.i_mb_type_topright == P_SKIP ) ) + if( analysis.b_mbrd ) { + x264_mb_mc_pskip( h ); + i_skip_cost = h->pixf.ssd[PIXEL_16x16]( h->mb.pic.p_fenc[0], h->mb.pic.i_stride[0], + h->mb.pic.p_fdec[0], h->mb.pic.i_stride[0] ) + + h->pixf.ssd[PIXEL_8x8]( h->mb.pic.p_fenc[1], h->mb.pic.i_stride[1], + h->mb.pic.p_fdec[1], h->mb.pic.i_stride[1] ) + + h->pixf.ssd[PIXEL_8x8]( h->mb.pic.p_fenc[2], h->mb.pic.i_stride[2], + h->mb.pic.p_fdec[2], h->mb.pic.i_stride[2] ) + + ((h->mb.i_mb_type_left != P_SKIP) + (h->mb.i_mb_type_top != P_SKIP)) + * analysis.i_lambda2; + } + else if( h->mb.i_mb_type_left == P_SKIP + || h->mb.i_mb_type_top == P_SKIP + || h->mb.i_mb_type_topleft == P_SKIP + || h->mb.i_mb_type_topright == P_SKIP ) + { + //b_skip = x264_macroblock_probe_skip( h, !analysis.b_mbrd, analysis.b_mbrd ? 1 : 6 ); b_skip = x264_macroblock_probe_pskip( h ); } @@ -1644,8 +1659,17 @@ //FIXME mb_type costs? if( analysis.b_mbrd ) { - h->mb.i_type = i_type; - x264_mb_analyse_transform_rd( h, &analysis, &i_cost ); + if( i_skip_cost < i_cost ) + { + h->mb.i_type = P_SKIP; + x264_analyse_update_cache( h, &analysis ); + return; + } + else + { + h->mb.i_type = i_type; + x264_mb_analyse_transform_rd( h, &analysis, &i_cost ); + } } else if( i_partition == D_16x16 ) { @@ -2021,12 +2045,9 @@ case P_SKIP: { - int mvp[2]; - x264_mb_predict_mv_pskip( h, mvp ); - /* */ h->mb.i_partition = D_16x16; x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, 0 ); - x264_macroblock_cache_mv ( h, 0, 0, 4, 4, 0, mvp[0], mvp[1] ); + x264_macroblock_cache_mv ( h, 0, 0, 4, 4, 0, h->mb.cache.pskip_mv[0], h->mb.cache.pskip_mv[1] ); break; } Index: common/macroblock.c =================================================================== --- common/macroblock.c (revision 263) +++ common/macroblock.c (working copy) @@ -926,6 +926,26 @@ } } +void x264_mb_mc_pskip( x264_t *h ) +{ + const int mvx = x264_clip3( h->mb.cache.pskip_mv[0], + h->mb.mv_min[0], h->mb.mv_max[0] ); + const int mvy = x264_clip3( h->mb.cache.pskip_mv[1], + h->mb.mv_min[1], h->mb.mv_max[1] ); + + h->mc.mc_luma( h->mb.pic.p_fref[0][0], h->mb.pic.i_stride[0], + h->mb.pic.p_fdec[0], h->mb.pic.i_stride[0], + mvx, mvy, 16, 16 ); + + h->mc.mc_chroma( h->mb.pic.p_fref[0][0][4], h->mb.pic.i_stride[1], + h->mb.pic.p_fdec[1], h->mb.pic.i_stride[1], + mvx, mvy, 8, 8 ); + + h->mc.mc_chroma( h->mb.pic.p_fref[0][0][5], h->mb.pic.i_stride[2], + h->mb.pic.p_fdec[2], h->mb.pic.i_stride[2], + mvx, mvy, 8, 8 ); +} + void x264_macroblock_cache_init( x264_t *h ) { int i, j; Index: common/macroblock.h =================================================================== --- common/macroblock.h (revision 263) +++ common/macroblock.h (working copy) @@ -212,6 +212,7 @@ void x264_mb_encode_i8x8( x264_t *h, int idx, int i_qscale ); void x264_mb_mc( x264_t *h ); +void x264_mb_mc_pskip( x264_t *h ); static inline void x264_macroblock_cache_ref( x264_t *h, int x, int y, int width, int height, int i_list, int ref ) Index: common/common.h =================================================================== --- common/common.h (revision 263) +++ common/common.h (working copy) @@ -397,6 +397,7 @@ int16_t direct_mv[2][X264_SCAN8_SIZE][2]; int8_t direct_ref[2][X264_SCAN8_SIZE]; + int pskip_mv[2]; /* number of neighbors (top and left) that used 8x8 dct */ int i_neighbour_transform_size;