Commit 39613393 authored by Loren Merritt's avatar Loren Merritt

lossless mode enabled at qp=0


git-svn-id: svn://svn.videolan.org/x264/trunk@264 df754926-b1dd-0310-bc7b-ec298dee348c
parent 2f9a70c0
......@@ -408,6 +408,7 @@ struct x264_t
int i_last_qp; /* last qp */
int i_last_dqp; /* last delta qp */
int b_variable_qp; /* whether qp is allowed to vary per macroblock */
int b_lossless;
/* B_direct and weighted prediction */
int dist_scale_factor[16][16];
......
......@@ -67,6 +67,7 @@ typedef struct
x264_pixel_cmp_t ssd[7];
x264_pixel_cmp_t satd[7];
x264_pixel_cmp_t sa8d[4];
x264_pixel_cmp_t mbcmp[7]; /* either satd or sad for subpel refine and mode decision */
x264_pixel_avg_t avg[10];
x264_pixel_avg_weight_t avg_weight[10];
} x264_pixel_function_t;
......
......@@ -98,6 +98,9 @@ typedef struct
/* FIXME to complete */
} vui;
int b_qpprime_y_zero_transform_bypass;
} x264_sps_t;
typedef struct
......
......@@ -445,10 +445,10 @@ static void x264_mb_analyse_intra_chroma( x264_t *h, x264_mb_analysis_t *a )
h->predict_8x8c[i_mode]( p_dstc[1], i_stride[1] );
/* we calculate the cost */
i_sad = h->pixf.satd[PIXEL_8x8]( p_dstc[0], i_stride[0],
p_srcc[0], i_stride[0] ) +
h->pixf.satd[PIXEL_8x8]( p_dstc[1], i_stride[1],
p_srcc[1], i_stride[1] ) +
i_sad = h->pixf.mbcmp[PIXEL_8x8]( p_dstc[0], i_stride[0],
p_srcc[0], i_stride[0] ) +
h->pixf.mbcmp[PIXEL_8x8]( p_dstc[1], i_stride[1],
p_srcc[1], i_stride[1] ) +
a->i_lambda * bs_size_ue( x264_mb_pred_mode8x8c_fix[i_mode] );
/* if i_score is lower it is better */
......@@ -488,7 +488,7 @@ static void x264_mb_analyse_intra( x264_t *h, x264_mb_analysis_t *a, int i_cost_
i_mode = predict_mode[i];
h->predict_16x16[i_mode]( p_dst, i_stride );
i_sad = h->pixf.satd[PIXEL_16x16]( p_dst, i_stride, p_src, i_stride ) +
i_sad = h->pixf.mbcmp[PIXEL_16x16]( p_dst, i_stride, p_src, i_stride ) +
a->i_lambda * bs_size_ue( x264_mb_pred_mode16x16_fix[i_mode] );
if( a->i_sad_i16x16 > i_sad )
{
......@@ -550,8 +550,8 @@ static void x264_mb_analyse_intra( x264_t *h, x264_mb_analysis_t *a, int i_cost_
i_mode = predict_mode[i];
h->predict_4x4[i_mode]( p_dst_by, i_stride );
i_sad = h->pixf.satd[PIXEL_4x4]( p_dst_by, i_stride,
p_src_by, i_stride )
i_sad = h->pixf.mbcmp[PIXEL_4x4]( p_dst_by, i_stride,
p_src_by, i_stride )
+ a->i_lambda * (i_pred_mode == x264_mb_pred_mode4x4_fix(i_mode) ? 1 : 4);
if( i_best > i_sad )
......@@ -619,8 +619,8 @@ static void x264_mb_analyse_intra( x264_t *h, x264_mb_analysis_t *a, int i_cost_
h->predict_8x8[i_mode]( p_dst_by, i_stride, h->mb.i_neighbour );
/* could use sa8d, but it doesn't seem worth the speed cost (without mmx at least) */
i_sad = h->pixf.satd[PIXEL_8x8]( p_dst_by, i_stride,
p_src_by, i_stride )
i_sad = h->pixf.mbcmp[PIXEL_8x8]( p_dst_by, i_stride,
p_src_by, i_stride )
+ a->i_lambda * (i_pred_mode == x264_mb_pred_mode4x4_fix(i_mode) ? 1 : 4);
if( i_best > i_sad )
......@@ -892,8 +892,8 @@ static int x264_mb_analyse_inter_p4x4_chroma( x264_t *h, x264_mb_analysis_t *a,
CHROMA4x4MC( 2,4, a->l0.me4x8[i8x8][1], 2,0 );
}
return h->pixf.satd[PIXEL_4x4]( &h->mb.pic.p_fenc[1][off], i_stride, pix1, 8 )
+ h->pixf.satd[PIXEL_4x4]( &h->mb.pic.p_fenc[2][off], i_stride, pix2, 8 );
return h->pixf.mbcmp[PIXEL_4x4]( &h->mb.pic.p_fenc[1][off], i_stride, pix1, 8 )
+ h->pixf.mbcmp[PIXEL_4x4]( &h->mb.pic.p_fenc[2][off], i_stride, pix2, 8 );
}
static void x264_mb_analyse_inter_p4x4( x264_t *h, x264_mb_analysis_t *a, int i8x8 )
......@@ -1028,7 +1028,7 @@ static void x264_mb_analyse_inter_direct( x264_t *h, x264_mb_analysis_t *a )
const int off = 8 * x8 + 8 * i_stride * y8;
a->i_cost16x16direct +=
a->i_cost8x8direct[i] =
h->pixf.satd[PIXEL_8x8]( &p_fenc[0][off], i_stride, &p_fdec[0][off], i_stride );
h->pixf.mbcmp[PIXEL_8x8]( &p_fenc[0][off], i_stride, &p_fdec[0][off], i_stride );
/* mb type cost */
a->i_cost8x8direct[i] += a->i_lambda * i_sub_mb_b_cost_table[D_DIRECT_8x8];
......@@ -1158,7 +1158,7 @@ static void x264_mb_analyse_inter_b16x16( x264_t *h, x264_mb_analysis_t *a )
else
h->pixf.avg[PIXEL_16x16]( pix1, 16, src2, stride2 );
a->i_cost16x16bi = h->pixf.satd[PIXEL_16x16]( h->mb.pic.p_fenc[0], h->mb.pic.i_stride[0], pix1, 16 )
a->i_cost16x16bi = h->pixf.mbcmp[PIXEL_16x16]( h->mb.pic.p_fenc[0], h->mb.pic.i_stride[0], pix1, 16 )
+ a->i_lambda * ( bs_size_te( h->sh.i_num_ref_idx_l0_active - 1, a->l0.i_ref )
+ bs_size_te( h->sh.i_num_ref_idx_l1_active - 1, a->l1.i_ref ) )
+ a->l0.me16x16.cost_mv
......@@ -1269,7 +1269,7 @@ static void x264_mb_analyse_inter_b8x8( x264_t *h, x264_mb_analysis_t *a )
}
WEIGHTED_AVG( PIXEL_8x8, pix[0], 8, pix[1], 8 );
i_part_cost_bi += h->pixf.satd[PIXEL_8x8]( a->l0.me8x8[i].p_fenc[0], h->mb.pic.i_stride[0], pix[0], 8 )
i_part_cost_bi += h->pixf.mbcmp[PIXEL_8x8]( a->l0.me8x8[i].p_fenc[0], h->mb.pic.i_stride[0], pix[0], 8 )
+ a->i_lambda * i_sub_mb_b_cost_table[D_BI_8x8];
a->l0.me8x8[i].cost += a->i_lambda * i_sub_mb_b_cost_table[D_L0_8x8];
a->l1.me8x8[i].cost += a->i_lambda * i_sub_mb_b_cost_table[D_L1_8x8];
......@@ -1346,7 +1346,7 @@ static void x264_mb_analyse_inter_b16x8( x264_t *h, x264_mb_analysis_t *a )
}
WEIGHTED_AVG( PIXEL_16x8, pix[0], 16, pix[1], 16 );
i_part_cost_bi += h->pixf.satd[PIXEL_16x8]( a->l0.me16x8[i].p_fenc[0], h->mb.pic.i_stride[0], pix[0], 16 );
i_part_cost_bi += h->pixf.mbcmp[PIXEL_16x8]( a->l0.me16x8[i].p_fenc[0], h->mb.pic.i_stride[0], pix[0], 16 );
i_part_cost = a->l0.me16x8[i].cost;
a->i_mb_partition16x8[i] = D_L0_8x8; /* not actually 8x8, only the L0 matters */
......@@ -1416,7 +1416,7 @@ static void x264_mb_analyse_inter_b8x16( x264_t *h, x264_mb_analysis_t *a )
}
WEIGHTED_AVG( PIXEL_8x16, pix[0], 8, pix[1], 8 );
i_part_cost_bi += h->pixf.satd[PIXEL_8x16]( a->l0.me8x16[i].p_fenc[0], h->mb.pic.i_stride[0], pix[0], 8 );
i_part_cost_bi += h->pixf.mbcmp[PIXEL_8x16]( a->l0.me8x16[i].p_fenc[0], h->mb.pic.i_stride[0], pix[0], 8 );
i_part_cost = a->l0.me8x16[i].cost;
a->i_mb_partition8x16[i] = D_L0_8x8;
......@@ -1526,10 +1526,11 @@ void x264_macroblock_analyse( x264_t *h )
int i_intra_cost, i_intra_type;
/* Fast P_SKIP detection */
if( ( h->mb.i_mb_type_left == P_SKIP ) ||
if( !h->mb.b_lossless &&
(( 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 ) )
( h->mb.i_mb_type_topright == P_SKIP )))
{
b_skip = x264_macroblock_probe_pskip( h );
}
......@@ -1755,7 +1756,7 @@ void x264_macroblock_analyse( x264_t *h )
/* Conditioning the probe on neighboring block types
* doesn't seem to help speed or quality. */
b_skip = x264_macroblock_probe_bskip( h );
b_skip = !h->mb.b_lossless && x264_macroblock_probe_bskip( h );
}
if( !b_skip )
......
......@@ -383,6 +383,15 @@ static int x264_validate_parameters( x264_t *h )
}
#endif
if( !h->param.rc.b_cbr && h->param.rc.i_qp_constant == 0 )
{
h->mb.b_lossless = 1;
h->param.analyse.b_transform_8x8 = 0;
h->param.rc.f_ip_factor = 1;
h->param.rc.f_pb_factor = 1;
h->param.analyse.b_psnr = 0;
}
h->param.i_frame_reference = x264_clip3( h->param.i_frame_reference, 1, 16 );
if( h->param.i_keyint_max <= 0 )
h->param.i_keyint_max = 1;
......@@ -559,6 +568,10 @@ x264_t *x264_encoder_open ( x264_param_t *param )
x264_mc_init( h->param.cpu, &h->mc );
x264_csp_init( h->param.cpu, h->param.i_csp, &h->csp );
memcpy( h->pixf.mbcmp,
( h->mb.b_lossless || h->param.analyse.i_subpel_refine <= 1 ) ? h->pixf.sad : h->pixf.satd,
sizeof(h->pixf.mbcmp) );
/* rate control */
if( x264_ratecontrol_new( h ) < 0 )
return NULL;
......@@ -594,6 +607,11 @@ int x264_encoder_reconfig( x264_t *h, x264_param_t *param )
if( h->sps->b_direct8x8_inference && h->param.i_bframe
&& h->param.analyse.i_direct_mv_pred == X264_DIRECT_PRED_TEMPORAL )
h->param.analyse.inter &= ~X264_ANALYSE_PSUB8x8;
memcpy( h->pixf.mbcmp,
( h->mb.b_lossless || h->param.analyse.i_subpel_refine <= 1 ) ? h->pixf.sad : h->pixf.satd,
sizeof(h->pixf.mbcmp) );
return x264_validate_parameters( h );
}
......
......@@ -179,6 +179,27 @@ static inline void scan_zigzag_2x2_dc( int level[4], int16_t dct[2][2] )
}
#undef ZIG
#define ZIG(i,y,x) {\
int o = x+y*i_stride;\
level[i] = p_src[o] - p_dst[o];\
p_dst[o] = p_src[o];\
}
static inline void sub_zigzag_4x4full( int level[16], const uint8_t *p_src, uint8_t *p_dst, int i_stride )
{
ZIG( 0,0,0) ZIG( 1,0,1) ZIG( 2,1,0) ZIG( 3,2,0)
ZIG( 4,1,1) ZIG( 5,0,2) ZIG( 6,0,3) ZIG( 7,1,2)
ZIG( 8,2,1) ZIG( 9,3,0) ZIG(10,3,1) ZIG(11,2,2)
ZIG(12,1,3) ZIG(13,2,3) ZIG(14,3,2) ZIG(15,3,3)
}
static inline void sub_zigzag_4x4( int level[15], const uint8_t *p_src, uint8_t *p_dst, int i_stride )
{
ZIG( 0,0,1) ZIG( 1,1,0) ZIG( 2,2,0)
ZIG( 3,1,1) ZIG( 4,0,2) ZIG( 5,0,3) ZIG( 6,1,2)
ZIG( 7,2,1) ZIG( 8,3,0) ZIG( 9,3,1) ZIG(10,2,2)
ZIG(11,1,3) ZIG(12,2,3) ZIG(13,3,2) ZIG(14,3,3)
}
#undef ZIG
static void quant_8x8( int16_t dct[8][8], int i_qscale, int b_intra )
{
const int i_qbits = 16 + i_qscale / 6;
......@@ -405,6 +426,12 @@ void x264_mb_encode_i4x4( x264_t *h, int idx, int i_qscale )
uint8_t *p_dst = &h->mb.pic.p_fdec[0][i_offset];
int16_t dct4x4[4][4];
if( h->mb.b_lossless )
{
sub_zigzag_4x4full( h->dct.block[idx].luma4x4, p_src, p_dst, i_stride );
return;
}
h->dctf.sub4x4_dct( dct4x4, p_src, i_stride, p_dst, i_stride );
quant_4x4( dct4x4, i_qscale, 1 );
scan_zigzag_4x4full( h->dct.block[idx].luma4x4, dct4x4 );
......@@ -439,6 +466,19 @@ static void x264_mb_encode_i16x16( x264_t *h, int i_qscale )
int i;
if( h->mb.b_lossless )
{
for( i = 0; i < 16; i++ )
{
int o = block_idx_x[i]*4 + block_idx_y[i]*4*i_stride;
sub_zigzag_4x4( h->dct.block[i].residual_ac, p_src+o, p_dst+o, i_stride );
dct4x4[0][block_idx_y[i]][block_idx_x[i]] = p_src[o] - p_dst[o];
p_dst[o] = p_src[o];
}
scan_zigzag_4x4full( h->dct.luma16x16_dc, dct4x4[0] );
return;
}
h->dctf.sub16x16_dct( &dct4x4[1], p_src, i_stride, p_dst, i_stride );
for( i = 0; i < 16; i++ )
{
......@@ -483,6 +523,18 @@ static void x264_mb_encode_8x8_chroma( x264_t *h, int b_inter, int i_qscale )
int16_t dct2x2[2][2];
int16_t dct4x4[4][4][4];
if( h->mb.b_lossless )
{
for( i = 0; i < 4; i++ )
{
int o = block_idx_x[i]*4 + block_idx_y[i]*4*i_stride;
sub_zigzag_4x4( h->dct.block[16+i+ch*4].residual_ac, p_src+o, p_dst+o, i_stride );
h->dct.chroma_dc[ch][i] = p_src[o] - p_dst[o];
p_dst[o] = p_src[o];
}
continue;
}
h->dctf.sub8x8_dct( dct4x4, p_src, i_stride, p_dst, i_stride );
/* calculate dct coeffs */
for( i = 0; i < 4; i++ )
......@@ -653,7 +705,15 @@ void x264_macroblock_encode( x264_t *h )
/* Motion compensation */
x264_mb_mc( h );
if( h->mb.b_transform_8x8 )
if( h->mb.b_lossless )
{
for( i4x4 = 0; i4x4 < 16; i4x4++ )
{
int o = block_idx_x[i4x4]*4 + block_idx_y[i4x4]*4 * h->mb.pic.i_stride[0];
sub_zigzag_4x4full( h->dct.block[i4x4].luma4x4, h->mb.pic.p_fenc[0]+o, h->mb.pic.p_fdec[0]+o, h->mb.pic.i_stride[0] );
}
}
else if( h->mb.b_transform_8x8 )
{
int16_t dct8x8[4][8][8];
h->dctf.sub16x16_dct8( dct8x8,
......@@ -758,8 +818,8 @@ void x264_macroblock_encode( x264_t *h )
}
else if( h->mb.b_transform_8x8 )
{
/* coded_block_flag is enough for CABAC,
* but CAVLC needs the full non_zero_count. */
/* coded_block_flag is enough for CABAC.
* the full non_zero_count is done only in CAVLC. */
for( i = 0; i < 4; i++ )
{
const int nz = array_non_zero( h->dct.luma8x8[i], 64 );
......
......@@ -246,7 +246,7 @@ umh_small_hex:
/* compute the real cost */
m->cost_mv = p_cost_mvx[ m->mv[0] ] + p_cost_mvy[ m->mv[1] ];
m->cost = h->pixf.satd[i_pixel]( m->p_fenc[0], m->i_stride[0],
m->cost = h->pixf.mbcmp[i_pixel]( m->p_fenc[0], m->i_stride[0],
&p_fref[bmy * m->i_stride[0] + bmx], m->i_stride[0] )
+ m->cost_mv;
if( b_chroma_me )
......@@ -256,8 +256,8 @@ umh_small_hex:
DECLARE_ALIGNED( uint8_t, pix[8*8*2], 16 );
h->mc.mc_chroma( m->p_fref[4], m->i_stride[1], pix, 8, m->mv[0], m->mv[1], bw/2, bh/2 );
h->mc.mc_chroma( m->p_fref[5], m->i_stride[1], pix+8*8, 8, m->mv[0], m->mv[1], bw/2, bh/2 );
m->cost += h->pixf.satd[i_pixel+3]( m->p_fenc[1], m->i_stride[1], pix, 8 )
+ h->pixf.satd[i_pixel+3]( m->p_fenc[2], m->i_stride[1], pix+8*8, 8 );
m->cost += h->pixf.mbcmp[i_pixel+3]( m->p_fenc[1], m->i_stride[1], pix, 8 )
+ h->pixf.mbcmp[i_pixel+3]( m->p_fenc[2], m->i_stride[1], pix+8*8, 8 );
}
/* subpel refine */
......@@ -295,16 +295,16 @@ void x264_me_refine_qpel( x264_t *h, x264_me_t *m )
{ \
int stride = 16; \
uint8_t *src = h->mc.get_ref( m->p_fref, m->i_stride[0], pix, &stride, mx, my, bw, bh ); \
int cost = h->pixf.satd[i_pixel]( m->p_fenc[0], m->i_stride[0], src, stride ) \
int cost = h->pixf.mbcmp[i_pixel]( m->p_fenc[0], m->i_stride[0], src, stride ) \
+ p_cost_mvx[ mx ] + p_cost_mvy[ my ]; \
if( b_chroma_me && cost < bcost ) \
{ \
h->mc.mc_chroma( m->p_fref[4], m->i_stride[1], pix, 8, mx, my, bw/2, bh/2 ); \
cost += h->pixf.satd[i_pixel+3]( m->p_fenc[1], m->i_stride[1], pix, 8 ); \
cost += h->pixf.mbcmp[i_pixel+3]( m->p_fenc[1], m->i_stride[1], pix, 8 ); \
if( cost < bcost ) \
{ \
h->mc.mc_chroma( m->p_fref[5], m->i_stride[1], pix, 8, mx, my, bw/2, bh/2 ); \
cost += h->pixf.satd[i_pixel+3]( m->p_fenc[2], m->i_stride[1], pix, 8 ); \
cost += h->pixf.mbcmp[i_pixel+3]( m->p_fenc[2], m->i_stride[1], pix, 8 ); \
} \
} \
if( cost < bcost ) \
......
......@@ -42,7 +42,10 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
{
sps->i_id = i_id;
if( param->analyse.b_transform_8x8 )
sps->b_qpprime_y_zero_transform_bypass = !param->rc.b_cbr && param->rc.i_qp_constant == 0;
if( sps->b_qpprime_y_zero_transform_bypass )
sps->i_profile_idc = PROFILE_HIGH444;
else if( param->analyse.b_transform_8x8 )
sps->i_profile_idc = PROFILE_HIGH;
else if( param->b_cabac || param->i_bframe > 0 )
sps->i_profile_idc = PROFILE_MAIN;
......@@ -168,7 +171,7 @@ void x264_sps_write( bs_t *s, x264_sps_t *sps )
bs_write_ue( s, 1 ); // chroma_format_idc = 4:2:0
bs_write_ue( s, 0 ); // bit_depth_luma_minus8
bs_write_ue( s, 0 ); // bit_depth_chroma_minus8
bs_write( s, 1, 0 ); // qpprime_y_zero_transform_bypass_flag
bs_write( s, 1, sps->b_qpprime_y_zero_transform_bypass );
bs_write( s, 1, 0 ); // seq_scaling_matrix_present_flag
}
......
......@@ -121,7 +121,7 @@ int x264_slicetype_mb_cost( x264_t *h, x264_mb_analysis_t *a,
src2 = h->mc.get_ref( m[1].p_fref, m[1].i_stride[0], pix2, &stride2, \
(mv1)[0], (mv1)[1], 8, 8 ); \
h->pixf.avg[PIXEL_8x8]( pix1, 8, src2, stride2 ); \
i_cost = penalty + h->pixf.satd[PIXEL_8x8]( \
i_cost = penalty + h->pixf.mbcmp[PIXEL_8x8]( \
m[0].p_fenc[0], m[0].i_stride[0], pix1, 8 ); \
if( i_bcost > i_cost ) \
{ \
......@@ -198,7 +198,7 @@ lowres_intra_mb:
{
int i_cost;
h->predict_8x8c[i]( &pix1[10], 9 );
i_cost = h->pixf.satd[PIXEL_8x8]( &pix1[10], 9, src, i_stride ) + intra_penalty;
i_cost = h->pixf.mbcmp[PIXEL_8x8]( &pix1[10], 9, src, i_stride ) + intra_penalty;
i_bcost = X264_MIN( i_bcost, i_cost );
}
if( i_bcost != i_cost_bak )
......
......@@ -180,7 +180,7 @@ static void Help( x264_param_t *defaults )
"\n"
"Ratecontrol:\n"
"\n"
" -q, --qp <integer> Set QP [%d]\n"
" -q, --qp <integer> Set QP (0=lossless) [%d]\n"
" -B, --bitrate <integer> Set bitrate\n"
" --qpmin <integer> Set min QP [%d]\n"
" --qpmax <integer> Set max QP [%d]\n"
......
......@@ -26,7 +26,7 @@
#include <stdarg.h>
#define X264_BUILD 30
#define X264_BUILD 31
/* x264_t:
* opaque handler for decoder and encoder */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment