Copy from Berkano Overlay
[otih-overlay.git] / media-libs / x264 / files / x264-psyrd-0.6-psytrellis-0.1.diff
blob3b8738c8410d8c81362f0ab04722645862575ac0
1 diff --git a/common/common.c b/common/common.c
2 index 71a29b1..21155eb 100644
3 --- a/common/common.c
4 +++ b/common/common.c
5 @@ -117,6 +117,7 @@ void x264_param_default( x264_param_t *param )
6 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16;
7 param->analyse.i_direct_mv_pred = X264_DIRECT_PRED_SPATIAL;
8 param->analyse.i_me_method = X264_ME_HEX;
9 + param->analyse.f_psy_rd = 1.0;
10 param->analyse.i_me_range = 16;
11 param->analyse.i_subpel_refine = 5;
12 param->analyse.b_chroma_me = 1;
13 @@ -464,6 +465,8 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value )
14 p->analyse.i_mv_range_thread = atoi(value);
15 OPT2("subme", "subq")
16 p->analyse.i_subpel_refine = atoi(value);
17 + OPT("psy-rd")
18 + p->analyse.f_psy_rd = atof(value);
19 OPT("bime")
20 p->analyse.b_bidir_me = atobool(value);
21 OPT("chroma-me")
22 @@ -856,6 +859,7 @@ char *x264_param2string( x264_param_t *p, int b_res )
23 s += sprintf( s, " analyse=%#x:%#x", p->analyse.intra, p->analyse.inter );
24 s += sprintf( s, " me=%s", x264_motion_est_names[ p->analyse.i_me_method ] );
25 s += sprintf( s, " subme=%d", p->analyse.i_subpel_refine );
26 + s += sprintf( s, " psy_rd=%.1f", p->analyse.f_psy_rd );
27 s += sprintf( s, " brdo=%d", p->analyse.b_bframe_rdo );
28 s += sprintf( s, " mixed_ref=%d", p->analyse.b_mixed_references );
29 s += sprintf( s, " me_range=%d", p->analyse.i_me_range );
30 diff --git a/common/common.h b/common/common.h
31 index 80648a8..78cdb05 100644
32 --- a/common/common.h
33 +++ b/common/common.h
34 @@ -342,8 +342,6 @@ struct x264_t
35 x264_frame_t *fref1[16+3]; /* ref list 1 */
36 int b_ref_reorder[2];
40 /* Current MB DCT coeffs */
41 struct
43 @@ -454,6 +452,16 @@ struct x264_t
44 DECLARE_ALIGNED_16( int16_t i8x8_dct_buf[3][64] );
45 DECLARE_ALIGNED_16( int16_t i4x4_dct_buf[15][16] );
47 + /* Psy trellis DCT data */
48 + DECLARE_ALIGNED_16( int16_t fenc_dct8[4][64] );
49 + DECLARE_ALIGNED_16( int16_t fenc_dct4[16][16] );
51 + /* SATD scores for psy RD */
52 + int fenc_satd[4][4];
53 + int fenc_satd_sum;
54 + int fenc_sa8d[2][2];
55 + int fenc_sa8d_sum;
57 /* pointer over mb of the frame to be compressed */
58 uint8_t *p_fenc[3];
60 diff --git a/common/dct.h b/common/dct.h
61 index 1078023..daa96f4 100644
62 --- a/common/dct.h
63 +++ b/common/dct.h
64 @@ -41,6 +41,17 @@ static const uint16_t x264_dct8_weight_tab[64] = {
66 #undef W
68 +#define W(i) (i==0 ? FIX8(1.76777) :\
69 + i==1 ? FIX8(1.11803) :\
70 + i==2 ? FIX8(0.70711) :0)
71 +static const uint16_t x264_dct4_weight_tab[16] = {
72 + W(0), W(1), W(0), W(1),
73 + W(1), W(2), W(1), W(2),
74 + W(0), W(1), W(0), W(1),
75 + W(1), W(2), W(1), W(2)
76 +};
77 +#undef W
79 /* inverse squared */
80 #define W(i) (i==0 ? FIX8(3.125) :\
81 i==1 ? FIX8(1.25) :\
82 diff --git a/encoder/analyse.c b/encoder/analyse.c
83 index 270b90a..59cc89b 100644
84 --- a/encoder/analyse.c
85 +++ b/encoder/analyse.c
86 @@ -467,6 +467,34 @@ static void predict_4x4_mode_available( unsigned int i_neighbour,
90 +/* Pre-calculate fenc satd scores for psy RD, minus DC coefficients */
91 +static inline void x264_mb_cache_fenc_satd( x264_t *h )
93 + DECLARE_ALIGNED_16(uint8_t zero[16]) = {0};
94 + uint8_t *fenc;
95 + int x, y, satd_sum = 0, sa8d_sum = 0;
96 + if( !h->param.analyse.i_psy_rd )
97 + return;
98 + for( y = 0; y < 4; y++ )
99 + for( x = 0; x < 4; x++ )
101 + fenc = h->mb.pic.p_fenc[0]+x*4+y*4*FENC_STRIDE;
102 + h->mb.pic.fenc_satd[y][x] = h->pixf.satd[PIXEL_4x4]( zero, 0, fenc, FENC_STRIDE )
103 + - (h->pixf.sad[PIXEL_4x4]( zero, 0, fenc, FENC_STRIDE )>>1);
104 + satd_sum += h->mb.pic.fenc_satd[y][x];
106 + for( y = 0; y < 2; y++ )
107 + for( x = 0; x < 2; x++ )
109 + fenc = h->mb.pic.p_fenc[0]+x*8+y*8*FENC_STRIDE;
110 + h->mb.pic.fenc_sa8d[y][x] = h->pixf.sa8d[PIXEL_8x8]( zero, 0, fenc, FENC_STRIDE )
111 + - (h->pixf.sad[PIXEL_8x8]( zero, 0, fenc, FENC_STRIDE )>>2);
112 + sa8d_sum += h->mb.pic.fenc_sa8d[y][x];
114 + h->mb.pic.fenc_satd_sum = satd_sum;
115 + h->mb.pic.fenc_sa8d_sum = sa8d_sum;
118 static void x264_mb_analyse_intra_chroma( x264_t *h, x264_mb_analysis_t *a )
120 int i;
121 @@ -1016,12 +1044,15 @@ static void x264_mb_analyse_inter_p16x16( x264_t *h, x264_mb_analysis_t *a )
122 assert( a->l0.me16x16.mv[1] <= h->mb.mv_max_spel[1] || h->param.i_threads == 1 );
124 h->mb.i_type = P_L0;
125 - if( a->b_mbrd && a->l0.me16x16.i_ref == 0
126 - && *(uint32_t*)a->l0.me16x16.mv == *(uint32_t*)h->mb.cache.pskip_mv )
127 + if( a->b_mbrd )
129 - h->mb.i_partition = D_16x16;
130 - x264_macroblock_cache_mv_ptr( h, 0, 0, 4, 4, 0, a->l0.me16x16.mv );
131 - a->l0.i_rd16x16 = x264_rd_cost_mb( h, a->i_lambda2 );
132 + x264_mb_cache_fenc_satd( h );
133 + if( a->l0.me16x16.i_ref == 0 && *(uint32_t*)a->l0.me16x16.mv == *(uint32_t*)h->mb.cache.pskip_mv )
135 + h->mb.i_partition = D_16x16;
136 + x264_macroblock_cache_mv_ptr( h, 0, 0, 4, 4, 0, a->l0.me16x16.mv );
137 + a->l0.i_rd16x16 = x264_rd_cost_mb( h, a->i_lambda2 );
142 @@ -1906,7 +1937,7 @@ static void x264_mb_analyse_p_rd( x264_t *h, x264_mb_analysis_t *a, int i_satd )
144 static void x264_mb_analyse_b_rd( x264_t *h, x264_mb_analysis_t *a, int i_satd_inter )
146 - int thresh = i_satd_inter * 17/16;
147 + int thresh = i_satd_inter * (17 + (!!h->param.analyse.i_psy_rd))/16;
149 if( a->b_direct_available && a->i_rd16x16direct == COST_MAX )
151 @@ -2046,6 +2077,21 @@ static inline void x264_mb_analyse_transform_rd( x264_t *h, x264_mb_analysis_t *
155 +void x264_psy_trellis_init( x264_t *h )
157 + DECLARE_ALIGNED_16( int16_t dct8x8[4][8][8] );
158 + DECLARE_ALIGNED_16( int16_t dct4x4[16][4][4] );
159 + DECLARE_ALIGNED_16( uint8_t zero[16*FDEC_STRIDE] ) = {0};
160 + int i;
162 + /* For psy trellis: do DCT on input data */
163 + h->dctf.sub16x16_dct8( dct8x8, h->mb.pic.p_fenc[0], zero );
164 + for( i = 0; i < 4; i++ )
165 + h->zigzagf.scan_8x8( h->mb.pic.fenc_dct8[i], dct8x8[i] );
166 + h->dctf.sub16x16_dct( dct4x4, h->mb.pic.p_fenc[0], zero );
167 + for( i = 0; i < 16; i++ )
168 + h->zigzagf.scan_4x4( h->mb.pic.fenc_dct4[i], dct4x4[i] );
171 /*****************************************************************************
172 * x264_macroblock_analyse:
173 @@ -2062,12 +2108,18 @@ void x264_macroblock_analyse( x264_t *h )
175 x264_mb_analyse_init( h, &analysis, h->mb.i_qp );
177 + if( h->param.analyse.i_psy_rd && h->param.analyse.i_trellis )
178 + x264_psy_trellis_init( h );
180 /*--------------------------- Do the analysis ---------------------------*/
181 if( h->sh.i_type == SLICE_TYPE_I )
183 x264_mb_analyse_intra( h, &analysis, COST_MAX );
184 if( analysis.b_mbrd )
186 + x264_mb_cache_fenc_satd( h );
187 x264_intra_rd( h, &analysis, COST_MAX );
190 i_cost = analysis.i_satd_i16x16;
191 h->mb.i_type = I_16x16;
192 @@ -2342,6 +2394,9 @@ void x264_macroblock_analyse( x264_t *h )
194 int i_bskip_cost = COST_MAX;
195 int b_skip = 0;
197 + if( analysis.b_mbrd )
198 + x264_mb_cache_fenc_satd( h );
200 h->mb.i_type = B_SKIP;
201 if( h->mb.b_direct_auto_write )
202 diff --git a/encoder/encoder.c b/encoder/encoder.c
203 index 8f1ebac..b1d5f7b 100644
204 --- a/encoder/encoder.c
205 +++ b/encoder/encoder.c
206 @@ -411,5 +411,6 @@ static int x264_validate_parameters( x264_t *h )
207 h->param.analyse.b_fast_pskip = 0;
208 h->param.analyse.i_noise_reduction = 0;
209 + h->param.analyse.f_psy_rd = 0;
211 if( h->param.rc.i_rc_method == X264_RC_CQP )
213 @@ -482,10 +483,23 @@ static int x264_validate_parameters( x264_t *h )
214 h->param.analyse.inter &= ~X264_ANALYSE_I8x8;
215 h->param.analyse.intra &= ~X264_ANALYSE_I8x8;
217 - h->param.analyse.i_chroma_qp_offset = x264_clip3(h->param.analyse.i_chroma_qp_offset, -12, 12);
218 if( !h->param.b_cabac )
219 h->param.analyse.i_trellis = 0;
220 h->param.analyse.i_trellis = x264_clip3( h->param.analyse.i_trellis, 0, 2 );
221 + h->param.analyse.f_psy_rd = x264_clip3f( h->param.analyse.f_psy_rd, 0, 10 );
222 + if( h->param.analyse.i_subpel_refine < 6)
223 + h->param.analyse.f_psy_rd = 0;
224 + if( h->param.analyse.f_psy_rd )
226 + h->param.analyse.i_psy_rd = FIX8( h->param.analyse.f_psy_rd );
227 + /* Psy RDO increases overall quantizers to improve the quality of luma--this indirectly hurts chroma quality */
228 + /* so we lower the chroma QP offset to compensate */
229 + h->param.analyse.i_chroma_qp_offset -= h->param.analyse.f_psy_rd < 0.25 ? 1 : 2;
230 + /* Psy trellis has a similar effect. */
231 + if( h->param.analyse.i_trellis )
232 + h->param.analyse.i_chroma_qp_offset -= 2;
234 + h->param.analyse.i_chroma_qp_offset = x264_clip3(h->param.analyse.i_chroma_qp_offset, -12, 12);
235 h->param.rc.i_aq_mode = x264_clip3( h->param.rc.i_aq_mode, 0, 2 );
236 if( h->param.rc.f_aq_strength <= 0 )
237 h->param.rc.i_aq_mode = 0;
238 diff --git a/encoder/macroblock.c b/encoder/macroblock.c
239 index 788a8ea..b429c16 100644
240 --- a/encoder/macroblock.c
241 +++ b/encoder/macroblock.c
242 @@ -94,7 +94,7 @@ void x264_mb_encode_i4x4( x264_t *h, int idx, int i_qscale )
243 h->dctf.sub4x4_dct( dct4x4, p_src, p_dst );
245 if( h->mb.b_trellis )
246 - x264_quant_4x4_trellis( h, dct4x4, CQM_4IY, i_qscale, DCT_LUMA_4x4, 1 );
247 + x264_quant_4x4_trellis( h, dct4x4, CQM_4IY, i_qscale, DCT_LUMA_4x4, 1, idx );
248 else
249 h->quantf.quant_4x4( dct4x4, h->quant4_mf[CQM_4IY][i_qscale], h->quant4_bias[CQM_4IY][i_qscale] );
251 @@ -121,7 +121,7 @@ void x264_mb_encode_i8x8( x264_t *h, int idx, int i_qscale )
252 h->dctf.sub8x8_dct8( dct8x8, p_src, p_dst );
254 if( h->mb.b_trellis )
255 - x264_quant_8x8_trellis( h, dct8x8, CQM_8IY, i_qscale, 1 );
256 + x264_quant_8x8_trellis( h, dct8x8, CQM_8IY, i_qscale, 1, idx );
257 else
258 h->quantf.quant_8x8( dct8x8, h->quant8_mf[CQM_8IY][i_qscale], h->quant8_bias[CQM_8IY][i_qscale] );
260 @@ -163,7 +163,7 @@ static void x264_mb_encode_i16x16( x264_t *h, int i_qscale )
262 /* quant/scan/dequant */
263 if( h->mb.b_trellis )
264 - x264_quant_4x4_trellis( h, dct4x4[i], CQM_4IY, i_qscale, DCT_LUMA_AC, 1 );
265 + x264_quant_4x4_trellis( h, dct4x4[i], CQM_4IY, i_qscale, DCT_LUMA_AC, 1, i );
266 else
267 h->quantf.quant_4x4( dct4x4[i], h->quant4_mf[CQM_4IY][i_qscale], h->quant4_bias[CQM_4IY][i_qscale] );
269 @@ -447,7 +447,7 @@ void x264_macroblock_encode( x264_t *h )
270 if( h->mb.b_noise_reduction )
271 h->quantf.denoise_dct_core( *dct8x8[idx], h->nr_residual_sum[1], h->nr_offset[1], 64 );
272 if( h->mb.b_trellis )
273 - x264_quant_8x8_trellis( h, dct8x8[idx], CQM_8PY, i_qp, 0 );
274 + x264_quant_8x8_trellis( h, dct8x8[idx], CQM_8PY, i_qp, 0, idx );
275 else
276 h->quantf.quant_8x8( dct8x8[idx], h->quant8_mf[CQM_8PY][i_qp], h->quant8_bias[CQM_8PY][i_qp] );
278 @@ -495,7 +495,7 @@ void x264_macroblock_encode( x264_t *h )
279 if( h->mb.b_noise_reduction )
280 h->quantf.denoise_dct_core( *dct4x4[idx], h->nr_residual_sum[0], h->nr_offset[0], 16 );
281 if( h->mb.b_trellis )
282 - x264_quant_4x4_trellis( h, dct4x4[idx], CQM_4PY, i_qp, DCT_LUMA_4x4, 0 );
283 + x264_quant_4x4_trellis( h, dct4x4[idx], CQM_4PY, i_qp, DCT_LUMA_4x4, 0, idx );
284 else
285 h->quantf.quant_4x4( dct4x4[idx], h->quant4_mf[CQM_4PY][i_qp], h->quant4_bias[CQM_4PY][i_qp] );
287 diff --git a/encoder/macroblock.h b/encoder/macroblock.h
288 index 49d13a2..eb97d44 100644
289 --- a/encoder/macroblock.h
290 +++ b/encoder/macroblock.h
291 @@ -50,9 +50,9 @@ void x264_mb_encode_8x8_chroma( x264_t *h, int b_inter, int i_qscale );
292 void x264_cabac_mb_skip( x264_t *h, int b_skip );
294 void x264_quant_4x4_trellis( x264_t *h, int16_t dct[4][4], int i_quant_cat,
295 - int i_qp, int i_ctxBlockCat, int b_intra );
296 + int i_qp, int i_ctxBlockCat, int b_intra, int idx );
297 void x264_quant_8x8_trellis( x264_t *h, int16_t dct[8][8], int i_quant_cat,
298 - int i_qp, int b_intra );
299 + int i_qp, int b_intra, int idx );
301 void x264_noise_reduction_update( x264_t *h );
303 diff --git a/encoder/rdo.c b/encoder/rdo.c
304 index 76bf57b..5b23e18 100644
305 --- a/encoder/rdo.c
306 +++ b/encoder/rdo.c
307 @@ -50,21 +50,82 @@ static uint16_t cabac_prefix_size[15][128];
309 #define COPY_CABAC h->mc.memcpy_aligned( &cabac_tmp.f8_bits_encoded, &h->cabac.f8_bits_encoded, \
310 sizeof(x264_cabac_t) - offsetof(x264_cabac_t,f8_bits_encoded) )
312 -static int ssd_mb( x264_t *h )
314 +#define ADD_ABS_SATD(satdtype, pixel)\
315 + satd += abs((h->pixf.satdtype[pixel]( zero, 0, fdec, FDEC_STRIDE ) - dc_coef)\
316 + - sum_##satdtype( h, pixel, x, y ));
318 +/* Sum the cached SATDs to avoid repeating them. */
319 +static inline int sum_satd( x264_t *h, int pixel, int x, int y )
321 + int satd = 0;
322 + int min_x = x>>2;
323 + int min_y = y>>2;
324 + int max_x = (x>>2) + (x264_pixel_size[pixel].w>>2);
325 + int max_y = (y>>2) + (x264_pixel_size[pixel].h>>2);
326 + if( pixel == PIXEL_16x16 )
327 + return h->mb.pic.fenc_satd_sum;
328 + for( y = min_y; y < max_y; y++ )
329 + for( x = min_x; x < max_x; x++ )
330 + satd += h->mb.pic.fenc_satd[y][x];
331 + return satd;
334 +static inline int sum_sa8d( x264_t *h, int pixel, int x, int y )
336 + int sa8d = 0;
337 + int min_x = x>>3;
338 + int min_y = y>>3;
339 + int max_x = (x>>3) + (x264_pixel_size[pixel].w>>3);
340 + int max_y = (y>>3) + (x264_pixel_size[pixel].h>>3);
341 + if( pixel == PIXEL_16x16 )
342 + return h->mb.pic.fenc_sa8d_sum;
343 + for( y = min_y; y < max_y; y++ )
344 + for( x = min_x; x < max_x; x++ )
345 + sa8d += h->mb.pic.fenc_sa8d[y][x];
346 + return sa8d;
349 +/* Psy RD distortion metric: SSD plus "Absolute Difference of Complexities" */
350 +/* SATD and SA8D are used to measure block complexity. */
351 +/* Blocks with a complexity most similar to that of the source are scored best. */
352 +/* The difference between SATD and SA8D scores are both used to avoid bias from the DCT size. Using SATD */
353 +/* only, for example, results in overusage of 8x8dct, while the opposite occurs when using SA8D. */
354 +/* This is because frequencies stored in an 8x8dct sum up to a larger value when viewed through a 4x4 */
355 +/* transform and vice versa with a 4x4dct and an 8x8 transform. */
356 +/* SSD is still used as the primary RD metric; this value is merely added to it for psy purposes. */
358 +/* FIXME: Is there a better metric than averaged SATD/SA8D difference for complexity difference? */
359 +/* Hadamard transform is recursive, so a SATD+SA8D can be done faster by taking advantage of this fact. */
360 +/* This optimization can also be used in non-RD transform decision. */
362 +static inline int ssd_plane( x264_t *h, int size, int p, int x, int y )
364 - return h->pixf.ssd[PIXEL_16x16]( h->mb.pic.p_fenc[0], FENC_STRIDE,
365 - h->mb.pic.p_fdec[0], FDEC_STRIDE )
366 - + h->pixf.ssd[PIXEL_8x8]( h->mb.pic.p_fenc[1], FENC_STRIDE,
367 - h->mb.pic.p_fdec[1], FDEC_STRIDE )
368 - + h->pixf.ssd[PIXEL_8x8]( h->mb.pic.p_fenc[2], FENC_STRIDE,
369 - h->mb.pic.p_fdec[2], FDEC_STRIDE );
370 + DECLARE_ALIGNED_16(uint8_t zero[16]) = {0};
371 + int satd = 0;
372 + uint8_t *fdec = h->mb.pic.p_fdec[p] + x + y*FDEC_STRIDE;
373 + uint8_t *fenc = h->mb.pic.p_fenc[p] + x + y*FENC_STRIDE;
374 + if( p == 0 && h->param.analyse.i_psy_rd )
376 + int dc_coef = h->pixf.sad[size](zero, 0, fdec, FDEC_STRIDE) >> 1;
377 + ADD_ABS_SATD(satd, size);
378 + /* If the plane is smaller than 8x8, we can't do an SA8D; this probably isn't a big problem. */
379 + if(size <= PIXEL_8x8)
381 + dc_coef >>= 1;
382 + ADD_ABS_SATD(sa8d, size);
383 + satd >>= 1;
385 + satd = (satd * h->param.analyse.i_psy_rd * x264_lambda_tab[h->mb.i_qp] + 128) >> 8;
387 + return h->pixf.ssd[size](fenc, FENC_STRIDE, fdec, FDEC_STRIDE) + satd;
390 -static int ssd_plane( x264_t *h, int size, int p, int x, int y )
391 +static inline int ssd_mb( x264_t *h )
393 - return h->pixf.ssd[size]( h->mb.pic.p_fenc[p] + x+y*FENC_STRIDE, FENC_STRIDE,
394 - h->mb.pic.p_fdec[p] + x+y*FDEC_STRIDE, FDEC_STRIDE );
395 + return ssd_plane(h, PIXEL_16x16, 0, 0, 0)
396 + + ssd_plane(h, PIXEL_8x8, 1, 0, 0)
397 + + ssd_plane(h, PIXEL_8x8, 2, 0, 0);
400 static int x264_rd_cost_mb( x264_t *h, int i_lambda2 )
401 @@ -267,7 +328,7 @@ static const int lambda2_tab[2][52] = {
404 typedef struct {
405 - uint64_t score;
406 + int64_t score;
407 int level_idx; // index into level_tree[]
408 uint8_t cabac_state[10]; //just the contexts relevant to coding abs_level_m1
409 } trellis_node_t;
410 @@ -296,7 +357,7 @@ typedef struct {
411 static inline void quant_trellis_cabac( x264_t *h, int16_t *dct,
412 const uint16_t *quant_mf, const int *unquant_mf,
413 const int *coef_weight, const uint8_t *zigzag,
414 - int i_ctxBlockCat, int i_lambda2, int b_ac, int i_coefs )
415 + int i_ctxBlockCat, int i_lambda2, int b_ac, int i_coefs, int idx )
417 int abs_coefs[64], signs[64];
418 trellis_node_t nodes[2][8];
419 @@ -428,8 +489,19 @@ static inline void quant_trellis_cabac( x264_t *h, int16_t *dct,
420 // that are better left coded, especially at QP > 40.
421 for( abs_level = q; abs_level >= q-1; abs_level-- )
423 - int d = i_coef - ((unquant_mf[zigzag[i]] * abs_level + 128) >> 8);
424 - uint64_t ssd = (int64_t)d*d * coef_weight[i];
425 + int unquant_abs_level = ((unquant_mf[zigzag[i]] * abs_level + 128) >> 8);
426 + int d = i_coef - unquant_abs_level;
427 + int64_t ssd;
428 + if( h->param.analyse.i_psy_rd && i != 0 )
430 + int orig_coef = (i_coefs == 64) ? h->mb.pic.fenc_dct8[idx][i] : h->mb.pic.fenc_dct4[idx][i];
431 + int predicted_coef = abs(orig_coef - i_coef * signs[i] );
432 + int psy_value = h->param.analyse.i_psy_rd * abs(predicted_coef + unquant_abs_level * signs[i]);
433 + int psy_weight = (i_coefs == 64) ? x264_dct8_weight_tab[zigzag[i]] : x264_dct4_weight_tab[zigzag[i]];
434 + ssd = (int64_t)d*d * coef_weight[i] - psy_weight * (psy_value>>2);
436 + else
437 + ssd = (int64_t)d*d * coef_weight[i];
439 for( j = 0; j < 8; j++ )
441 @@ -493,24 +565,24 @@ static inline void quant_trellis_cabac( x264_t *h, int16_t *dct,
444 void x264_quant_4x4_trellis( x264_t *h, int16_t dct[4][4], int i_quant_cat,
445 - int i_qp, int i_ctxBlockCat, int b_intra )
446 + int i_qp, int i_ctxBlockCat, int b_intra, int idx )
448 int b_ac = (i_ctxBlockCat == DCT_LUMA_AC);
449 quant_trellis_cabac( h, (int16_t*)dct,
450 h->quant4_mf[i_quant_cat][i_qp], h->unquant4_mf[i_quant_cat][i_qp],
451 x264_dct4_weight2_zigzag[h->mb.b_interlaced],
452 x264_zigzag_scan4[h->mb.b_interlaced],
453 - i_ctxBlockCat, lambda2_tab[b_intra][i_qp], b_ac, 16 );
454 + i_ctxBlockCat, lambda2_tab[b_intra][h->mb.i_qp], b_ac, 16, idx );
458 void x264_quant_8x8_trellis( x264_t *h, int16_t dct[8][8], int i_quant_cat,
459 - int i_qp, int b_intra )
460 + int i_qp, int b_intra, int idx )
462 quant_trellis_cabac( h, (int16_t*)dct,
463 h->quant8_mf[i_quant_cat][i_qp], h->unquant8_mf[i_quant_cat][i_qp],
464 x264_dct8_weight2_zigzag[h->mb.b_interlaced],
465 x264_zigzag_scan8[h->mb.b_interlaced],
466 - DCT_LUMA_8x8, lambda2_tab[b_intra][i_qp], 0, 64 );
467 + DCT_LUMA_8x8, lambda2_tab[b_intra][h->mb.i_qp], 0, 64, idx );
470 diff --git a/x264.c b/x264.c
471 index 14466e5..504ca12 100644
472 --- a/x264.c
473 +++ b/x264.c
474 @@ -243,6 +243,9 @@ static void Help( x264_param_t *defaults, int b_longhelp )
475 H0( " -m, --subme <integer> Subpixel motion estimation and partition\n"
476 " decision quality: 1=fast, 7=best. [%d]\n", defaults->analyse.i_subpel_refine );
477 H0( " --b-rdo RD based mode decision for B-frames. Requires subme 6.\n" );
478 + H0( " --psy-rd Strength of mode decision psychovisual optimization [\"%.1f\"]\n"
479 + " Does nothing at subme < 6.\n",
480 + defaults->analyse.f_psy_rd );
481 H0( " --mixed-refs Decide references on a per partition basis\n" );
482 H1( " --no-chroma-me Ignore chroma in motion estimation\n" );
483 H1( " --bime Jointly optimize both MVs in B-frames\n" );
484 @@ -411,6 +414,7 @@ static int Parse( int argc, char **argv,
485 { "mvrange", required_argument, NULL, 0 },
486 { "mvrange-thread", required_argument, NULL, 0 },
487 { "subme", required_argument, NULL, 'm' },
488 + { "psy-rd", required_argument, NULL, 0 },
489 { "b-rdo", no_argument, NULL, 0 },
490 { "mixed-refs", no_argument, NULL, 0 },
491 { "no-chroma-me", no_argument, NULL, 0 },
492 diff --git a/x264.h b/x264.h
493 index 3b678dc..02266c1 100644
494 --- a/x264.h
495 +++ b/x264.h
496 @@ -239,6 +239,8 @@ typedef struct x264_param_t
497 int b_fast_pskip; /* early SKIP detection on P-frames */
498 int b_dct_decimate; /* transform coefficient thresholding on P-frames */
499 int i_noise_reduction; /* adaptive pseudo-deadzone */
500 + float f_psy_rd; /* Psy RD strength */
501 + int i_psy_rd; /* Psy RD strength--fixed point value*/
503 /* the deadzone size that will be used in luma quantization */
504 int i_luma_deadzone[2]; /* {inter, intra} */