1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12 #include <limits.h>
13 #include <math.h>
14 #include <stdio.h>
15
16 #include "config/aom_dsp_rtcd.h"
17 #include "config/aom_scale_rtcd.h"
18
19 #include "aom_dsp/aom_dsp_common.h"
20 #include "aom_mem/aom_mem.h"
21 #include "aom_ports/mem.h"
22 #include "aom_ports/system_state.h"
23 #include "aom_scale/aom_scale.h"
24 #include "aom_scale/yv12config.h"
25
26 #include "aom_dsp/variance.h"
27 #include "av1/common/entropymv.h"
28 #include "av1/common/quant_common.h"
29 #include "av1/common/reconinter.h" // av1_setup_dst_planes()
30 #include "av1/common/txb_common.h"
31 #include "av1/encoder/aq_variance.h"
32 #include "av1/encoder/av1_quantize.h"
33 #include "av1/encoder/block.h"
34 #include "av1/encoder/dwt.h"
35 #include "av1/encoder/encodeframe.h"
36 #include "av1/encoder/encodemb.h"
37 #include "av1/encoder/encodemv.h"
38 #include "av1/encoder/encoder.h"
39 #include "av1/encoder/encode_strategy.h"
40 #include "av1/encoder/extend.h"
41 #include "av1/encoder/firstpass.h"
42 #include "av1/encoder/mcomp.h"
43 #include "av1/encoder/rd.h"
44 #include "av1/encoder/reconinter_enc.h"
45
46 #define OUTPUT_FPF 0
47
48 #define FIRST_PASS_Q 10.0
49 #define INTRA_MODE_PENALTY 1024
50 #define NEW_MV_MODE_PENALTY 32
51 #define DARK_THRESH 64
52
53 #define NCOUNT_INTRA_THRESH 8192
54 #define NCOUNT_INTRA_FACTOR 3
55
output_stats(FIRSTPASS_STATS * stats,struct aom_codec_pkt_list * pktlist)56 static void output_stats(FIRSTPASS_STATS *stats,
57 struct aom_codec_pkt_list *pktlist) {
58 struct aom_codec_cx_pkt pkt;
59 pkt.kind = AOM_CODEC_STATS_PKT;
60 pkt.data.twopass_stats.buf = stats;
61 pkt.data.twopass_stats.sz = sizeof(FIRSTPASS_STATS);
62 aom_codec_pkt_list_add(pktlist, &pkt);
63
64 // TEMP debug code
65 #if OUTPUT_FPF
66 {
67 FILE *fpfile;
68 fpfile = fopen("firstpass.stt", "a");
69
70 fprintf(fpfile,
71 "%12.0lf %12.4lf %12.0lf %12.0lf %12.0lf %12.4lf %12.4lf"
72 "%12.4lf %12.4lf %12.4lf %12.4lf %12.4lf %12.4lf %12.4lf %12.4lf"
73 "%12.4lf %12.4lf %12.0lf %12.0lf %12.0lf %12.4lf %12.4lf\n",
74 stats->frame, stats->weight, stats->intra_error, stats->coded_error,
75 stats->sr_coded_error, stats->pcnt_inter, stats->pcnt_motion,
76 stats->pcnt_second_ref, stats->pcnt_neutral, stats->intra_skip_pct,
77 stats->inactive_zone_rows, stats->inactive_zone_cols, stats->MVr,
78 stats->mvr_abs, stats->MVc, stats->mvc_abs, stats->MVrv,
79 stats->MVcv, stats->mv_in_out_count, stats->new_mv_count,
80 stats->count, stats->duration);
81 fclose(fpfile);
82 }
83 #endif
84 }
85
av1_twopass_zero_stats(FIRSTPASS_STATS * section)86 void av1_twopass_zero_stats(FIRSTPASS_STATS *section) {
87 section->frame = 0.0;
88 section->weight = 0.0;
89 section->intra_error = 0.0;
90 section->frame_avg_wavelet_energy = 0.0;
91 section->coded_error = 0.0;
92 section->sr_coded_error = 0.0;
93 section->pcnt_inter = 0.0;
94 section->pcnt_motion = 0.0;
95 section->pcnt_second_ref = 0.0;
96 section->pcnt_neutral = 0.0;
97 section->intra_skip_pct = 0.0;
98 section->inactive_zone_rows = 0.0;
99 section->inactive_zone_cols = 0.0;
100 section->MVr = 0.0;
101 section->mvr_abs = 0.0;
102 section->MVc = 0.0;
103 section->mvc_abs = 0.0;
104 section->MVrv = 0.0;
105 section->MVcv = 0.0;
106 section->mv_in_out_count = 0.0;
107 section->new_mv_count = 0.0;
108 section->count = 0.0;
109 section->duration = 1.0;
110 }
111
accumulate_stats(FIRSTPASS_STATS * section,const FIRSTPASS_STATS * frame)112 static void accumulate_stats(FIRSTPASS_STATS *section,
113 const FIRSTPASS_STATS *frame) {
114 section->frame += frame->frame;
115 section->weight += frame->weight;
116 section->intra_error += frame->intra_error;
117 section->frame_avg_wavelet_energy += frame->frame_avg_wavelet_energy;
118 section->coded_error += frame->coded_error;
119 section->sr_coded_error += frame->sr_coded_error;
120 section->pcnt_inter += frame->pcnt_inter;
121 section->pcnt_motion += frame->pcnt_motion;
122 section->pcnt_second_ref += frame->pcnt_second_ref;
123 section->pcnt_neutral += frame->pcnt_neutral;
124 section->intra_skip_pct += frame->intra_skip_pct;
125 section->inactive_zone_rows += frame->inactive_zone_rows;
126 section->inactive_zone_cols += frame->inactive_zone_cols;
127 section->MVr += frame->MVr;
128 section->mvr_abs += frame->mvr_abs;
129 section->MVc += frame->MVc;
130 section->mvc_abs += frame->mvc_abs;
131 section->MVrv += frame->MVrv;
132 section->MVcv += frame->MVcv;
133 section->mv_in_out_count += frame->mv_in_out_count;
134 section->new_mv_count += frame->new_mv_count;
135 section->count += frame->count;
136 section->duration += frame->duration;
137 }
138
av1_init_first_pass(AV1_COMP * cpi)139 void av1_init_first_pass(AV1_COMP *cpi) {
140 av1_twopass_zero_stats(&cpi->twopass.total_stats);
141 }
142
av1_end_first_pass(AV1_COMP * cpi)143 void av1_end_first_pass(AV1_COMP *cpi) {
144 output_stats(&cpi->twopass.total_stats, cpi->output_pkt_list);
145 }
146
get_block_variance_fn(BLOCK_SIZE bsize)147 static aom_variance_fn_t get_block_variance_fn(BLOCK_SIZE bsize) {
148 switch (bsize) {
149 case BLOCK_8X8: return aom_mse8x8;
150 case BLOCK_16X8: return aom_mse16x8;
151 case BLOCK_8X16: return aom_mse8x16;
152 default: return aom_mse16x16;
153 }
154 }
155
get_prediction_error(BLOCK_SIZE bsize,const struct buf_2d * src,const struct buf_2d * ref)156 static unsigned int get_prediction_error(BLOCK_SIZE bsize,
157 const struct buf_2d *src,
158 const struct buf_2d *ref) {
159 unsigned int sse;
160 const aom_variance_fn_t fn = get_block_variance_fn(bsize);
161 fn(src->buf, src->stride, ref->buf, ref->stride, &sse);
162 return sse;
163 }
164
highbd_get_block_variance_fn(BLOCK_SIZE bsize,int bd)165 static aom_variance_fn_t highbd_get_block_variance_fn(BLOCK_SIZE bsize,
166 int bd) {
167 switch (bd) {
168 default:
169 switch (bsize) {
170 case BLOCK_8X8: return aom_highbd_8_mse8x8;
171 case BLOCK_16X8: return aom_highbd_8_mse16x8;
172 case BLOCK_8X16: return aom_highbd_8_mse8x16;
173 default: return aom_highbd_8_mse16x16;
174 }
175 break;
176 case 10:
177 switch (bsize) {
178 case BLOCK_8X8: return aom_highbd_10_mse8x8;
179 case BLOCK_16X8: return aom_highbd_10_mse16x8;
180 case BLOCK_8X16: return aom_highbd_10_mse8x16;
181 default: return aom_highbd_10_mse16x16;
182 }
183 break;
184 case 12:
185 switch (bsize) {
186 case BLOCK_8X8: return aom_highbd_12_mse8x8;
187 case BLOCK_16X8: return aom_highbd_12_mse16x8;
188 case BLOCK_8X16: return aom_highbd_12_mse8x16;
189 default: return aom_highbd_12_mse16x16;
190 }
191 break;
192 }
193 }
194
highbd_get_prediction_error(BLOCK_SIZE bsize,const struct buf_2d * src,const struct buf_2d * ref,int bd)195 static unsigned int highbd_get_prediction_error(BLOCK_SIZE bsize,
196 const struct buf_2d *src,
197 const struct buf_2d *ref,
198 int bd) {
199 unsigned int sse;
200 const aom_variance_fn_t fn = highbd_get_block_variance_fn(bsize, bd);
201 fn(src->buf, src->stride, ref->buf, ref->stride, &sse);
202 return sse;
203 }
204
205 // Refine the motion search range according to the frame dimension
206 // for first pass test.
get_search_range(const AV1_COMP * cpi)207 static int get_search_range(const AV1_COMP *cpi) {
208 int sr = 0;
209 const int dim = AOMMIN(cpi->initial_width, cpi->initial_height);
210
211 while ((dim << sr) < MAX_FULL_PEL_VAL) ++sr;
212 return sr;
213 }
214
first_pass_motion_search(AV1_COMP * cpi,MACROBLOCK * x,const MV * ref_mv,MV * best_mv,int * best_motion_err)215 static void first_pass_motion_search(AV1_COMP *cpi, MACROBLOCK *x,
216 const MV *ref_mv, MV *best_mv,
217 int *best_motion_err) {
218 MACROBLOCKD *const xd = &x->e_mbd;
219 MV tmp_mv = kZeroMv;
220 MV ref_mv_full = { ref_mv->row >> 3, ref_mv->col >> 3 };
221 int num00, tmp_err, n;
222 const BLOCK_SIZE bsize = xd->mi[0]->sb_type;
223 aom_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
224 const int new_mv_mode_penalty = NEW_MV_MODE_PENALTY;
225
226 int step_param = 3;
227 int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
228 const int sr = get_search_range(cpi);
229 step_param += sr;
230 further_steps -= sr;
231
232 // Override the default variance function to use MSE.
233 v_fn_ptr.vf = get_block_variance_fn(bsize);
234 if (is_cur_buf_hbd(xd)) {
235 v_fn_ptr.vf = highbd_get_block_variance_fn(bsize, xd->bd);
236 }
237
238 // Center the initial step/diamond search on best mv.
239 tmp_err = cpi->diamond_search_sad(x, &cpi->ss_cfg[SS_CFG_SRC], &ref_mv_full,
240 &tmp_mv, step_param, x->sadperbit16, &num00,
241 &v_fn_ptr, ref_mv);
242 if (tmp_err < INT_MAX)
243 tmp_err = av1_get_mvpred_var(x, &tmp_mv, ref_mv, &v_fn_ptr, 1);
244 if (tmp_err < INT_MAX - new_mv_mode_penalty) tmp_err += new_mv_mode_penalty;
245
246 if (tmp_err < *best_motion_err) {
247 *best_motion_err = tmp_err;
248 *best_mv = tmp_mv;
249 }
250
251 // Carry out further step/diamond searches as necessary.
252 n = num00;
253 num00 = 0;
254
255 while (n < further_steps) {
256 ++n;
257
258 if (num00) {
259 --num00;
260 } else {
261 tmp_err = cpi->diamond_search_sad(
262 x, &cpi->ss_cfg[SS_CFG_SRC], &ref_mv_full, &tmp_mv, step_param + n,
263 x->sadperbit16, &num00, &v_fn_ptr, ref_mv);
264 if (tmp_err < INT_MAX)
265 tmp_err = av1_get_mvpred_var(x, &tmp_mv, ref_mv, &v_fn_ptr, 1);
266 if (tmp_err < INT_MAX - new_mv_mode_penalty)
267 tmp_err += new_mv_mode_penalty;
268
269 if (tmp_err < *best_motion_err) {
270 *best_motion_err = tmp_err;
271 *best_mv = tmp_mv;
272 }
273 }
274 }
275 }
276
get_bsize(const AV1_COMMON * cm,int mb_row,int mb_col)277 static BLOCK_SIZE get_bsize(const AV1_COMMON *cm, int mb_row, int mb_col) {
278 if (mi_size_wide[BLOCK_16X16] * mb_col + mi_size_wide[BLOCK_8X8] <
279 cm->mi_cols) {
280 return mi_size_wide[BLOCK_16X16] * mb_row + mi_size_wide[BLOCK_8X8] <
281 cm->mi_rows
282 ? BLOCK_16X16
283 : BLOCK_16X8;
284 } else {
285 return mi_size_wide[BLOCK_16X16] * mb_row + mi_size_wide[BLOCK_8X8] <
286 cm->mi_rows
287 ? BLOCK_8X16
288 : BLOCK_8X8;
289 }
290 }
291
find_fp_qindex(aom_bit_depth_t bit_depth)292 static int find_fp_qindex(aom_bit_depth_t bit_depth) {
293 return av1_find_qindex(FIRST_PASS_Q, bit_depth, 0, QINDEX_RANGE - 1);
294 }
295
raw_motion_error_stdev(int * raw_motion_err_list,int raw_motion_err_counts)296 static double raw_motion_error_stdev(int *raw_motion_err_list,
297 int raw_motion_err_counts) {
298 int64_t sum_raw_err = 0;
299 double raw_err_avg = 0;
300 double raw_err_stdev = 0;
301 if (raw_motion_err_counts == 0) return 0;
302
303 int i;
304 for (i = 0; i < raw_motion_err_counts; i++) {
305 sum_raw_err += raw_motion_err_list[i];
306 }
307 raw_err_avg = (double)sum_raw_err / raw_motion_err_counts;
308 for (i = 0; i < raw_motion_err_counts; i++) {
309 raw_err_stdev += (raw_motion_err_list[i] - raw_err_avg) *
310 (raw_motion_err_list[i] - raw_err_avg);
311 }
312 // Calculate the standard deviation for the motion error of all the inter
313 // blocks of the 0,0 motion using the last source
314 // frame as the reference.
315 raw_err_stdev = sqrt(raw_err_stdev / raw_motion_err_counts);
316 return raw_err_stdev;
317 }
318
319 #define UL_INTRA_THRESH 50
320 #define INVALID_ROW -1
av1_first_pass(AV1_COMP * cpi,const int64_t ts_duration)321 void av1_first_pass(AV1_COMP *cpi, const int64_t ts_duration) {
322 int mb_row, mb_col;
323 MACROBLOCK *const x = &cpi->td.mb;
324 AV1_COMMON *const cm = &cpi->common;
325 CurrentFrame *const current_frame = &cm->current_frame;
326 const SequenceHeader *const seq_params = &cm->seq_params;
327 const int num_planes = av1_num_planes(cm);
328 MACROBLOCKD *const xd = &x->e_mbd;
329 TileInfo tile;
330 struct macroblock_plane *const p = x->plane;
331 struct macroblockd_plane *const pd = xd->plane;
332 const PICK_MODE_CONTEXT *ctx =
333 &cpi->td.pc_root[MAX_MIB_SIZE_LOG2 - MIN_MIB_SIZE_LOG2]->none;
334 int i;
335
336 int recon_yoffset, src_yoffset, recon_uvoffset;
337 int64_t intra_error = 0;
338 int64_t frame_avg_wavelet_energy = 0;
339 int64_t coded_error = 0;
340 int64_t sr_coded_error = 0;
341
342 int sum_mvr = 0, sum_mvc = 0;
343 int sum_mvr_abs = 0, sum_mvc_abs = 0;
344 int64_t sum_mvrs = 0, sum_mvcs = 0;
345 int mvcount = 0;
346 int intercount = 0;
347 int second_ref_count = 0;
348 const int intrapenalty = INTRA_MODE_PENALTY;
349 double neutral_count;
350 int intra_skip_count = 0;
351 int image_data_start_row = INVALID_ROW;
352 int new_mv_count = 0;
353 int sum_in_vectors = 0;
354 MV lastmv = kZeroMv;
355 TWO_PASS *twopass = &cpi->twopass;
356 int recon_y_stride, src_y_stride, recon_uv_stride, uv_mb_height;
357
358 const YV12_BUFFER_CONFIG *const lst_yv12 =
359 get_ref_frame_yv12_buf(cm, LAST_FRAME);
360 const YV12_BUFFER_CONFIG *gld_yv12 = get_ref_frame_yv12_buf(cm, GOLDEN_FRAME);
361 YV12_BUFFER_CONFIG *const new_yv12 = &cm->cur_frame->buf;
362 const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12;
363 double intra_factor;
364 double brightness_factor;
365 const int qindex = find_fp_qindex(seq_params->bit_depth);
366 const int mb_scale = mi_size_wide[BLOCK_16X16];
367
368 int *raw_motion_err_list;
369 int raw_motion_err_counts = 0;
370 CHECK_MEM_ERROR(
371 cm, raw_motion_err_list,
372 aom_calloc(cm->mb_rows * cm->mb_cols, sizeof(*raw_motion_err_list)));
373 // First pass code requires valid last and new frame buffers.
374 assert(new_yv12 != NULL);
375 assert(frame_is_intra_only(cm) || (lst_yv12 != NULL));
376
377 av1_setup_frame_size(cpi);
378 aom_clear_system_state();
379
380 xd->mi = cm->mi_grid_visible;
381 xd->mi[0] = cm->mi;
382 x->e_mbd.mi[0]->sb_type = BLOCK_16X16;
383
384 intra_factor = 0.0;
385 brightness_factor = 0.0;
386 neutral_count = 0.0;
387
388 // Do not use periodic key frames.
389 cpi->rc.frames_to_key = INT_MAX;
390
391 av1_set_quantizer(cm, qindex);
392
393 av1_setup_block_planes(&x->e_mbd, seq_params->subsampling_x,
394 seq_params->subsampling_y, num_planes);
395
396 av1_setup_src_planes(x, cpi->source, 0, 0, num_planes,
397 x->e_mbd.mi[0]->sb_type);
398 av1_setup_dst_planes(xd->plane, seq_params->sb_size, new_yv12, 0, 0, 0,
399 num_planes);
400
401 if (!frame_is_intra_only(cm)) {
402 av1_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL, num_planes);
403 }
404
405 xd->mi = cm->mi_grid_visible;
406 xd->mi[0] = cm->mi;
407
408 // Don't store luma on the fist pass since chroma is not computed
409 xd->cfl.store_y = 0;
410 av1_frame_init_quantizer(cpi);
411
412 for (i = 0; i < num_planes; ++i) {
413 p[i].coeff = ctx->coeff[i];
414 p[i].qcoeff = ctx->qcoeff[i];
415 pd[i].dqcoeff = ctx->dqcoeff[i];
416 p[i].eobs = ctx->eobs[i];
417 p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
418 }
419
420 av1_init_mv_probs(cm);
421 av1_initialize_rd_consts(cpi);
422
423 // Tiling is ignored in the first pass.
424 av1_tile_init(&tile, cm, 0, 0);
425 src_y_stride = cpi->source->y_stride;
426 recon_y_stride = new_yv12->y_stride;
427 recon_uv_stride = new_yv12->uv_stride;
428 uv_mb_height = 16 >> (new_yv12->y_height > new_yv12->uv_height);
429
430 for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
431 MV best_ref_mv = kZeroMv;
432
433 // Reset above block coeffs.
434 xd->up_available = (mb_row != 0);
435 recon_yoffset = (mb_row * recon_y_stride * 16);
436 src_yoffset = (mb_row * src_y_stride * 16);
437 recon_uvoffset = (mb_row * recon_uv_stride * uv_mb_height);
438
439 // Set up limit values for motion vectors to prevent them extending
440 // outside the UMV borders.
441 x->mv_limits.row_min = -((mb_row * 16) + BORDER_MV_PIXELS_B16);
442 x->mv_limits.row_max =
443 ((cm->mb_rows - 1 - mb_row) * 16) + BORDER_MV_PIXELS_B16;
444
445 for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
446 int this_error;
447 const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
448 const BLOCK_SIZE bsize = get_bsize(cm, mb_row, mb_col);
449 double log_intra;
450 int level_sample;
451
452 aom_clear_system_state();
453
454 const int idx_str = xd->mi_stride * mb_row * mb_scale + mb_col * mb_scale;
455 xd->mi = cm->mi_grid_visible + idx_str;
456 xd->mi[0] = cm->mi + idx_str;
457 xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset;
458 xd->plane[1].dst.buf = new_yv12->u_buffer + recon_uvoffset;
459 xd->plane[2].dst.buf = new_yv12->v_buffer + recon_uvoffset;
460 xd->left_available = (mb_col != 0);
461 xd->mi[0]->sb_type = bsize;
462 xd->mi[0]->ref_frame[0] = INTRA_FRAME;
463 set_mi_row_col(xd, &tile, mb_row * mb_scale, mi_size_high[bsize],
464 mb_col * mb_scale, mi_size_wide[bsize], cm->mi_rows,
465 cm->mi_cols);
466
467 set_plane_n4(xd, mi_size_wide[bsize], mi_size_high[bsize], num_planes);
468
469 // Do intra 16x16 prediction.
470 xd->mi[0]->segment_id = 0;
471 xd->lossless[xd->mi[0]->segment_id] = (qindex == 0);
472 xd->mi[0]->mode = DC_PRED;
473 xd->mi[0]->tx_size =
474 use_dc_pred ? (bsize >= BLOCK_16X16 ? TX_16X16 : TX_8X8) : TX_4X4;
475 av1_encode_intra_block_plane(cpi, x, bsize, 0, 0, mb_row * 2, mb_col * 2);
476 this_error = aom_get_mb_ss(x->plane[0].src_diff);
477
478 if (this_error < UL_INTRA_THRESH) {
479 ++intra_skip_count;
480 } else if ((mb_col > 0) && (image_data_start_row == INVALID_ROW)) {
481 image_data_start_row = mb_row;
482 }
483
484 if (seq_params->use_highbitdepth) {
485 switch (seq_params->bit_depth) {
486 case AOM_BITS_8: break;
487 case AOM_BITS_10: this_error >>= 4; break;
488 case AOM_BITS_12: this_error >>= 8; break;
489 default:
490 assert(0 &&
491 "seq_params->bit_depth should be AOM_BITS_8, "
492 "AOM_BITS_10 or AOM_BITS_12");
493 return;
494 }
495 }
496
497 aom_clear_system_state();
498 log_intra = log(this_error + 1.0);
499 if (log_intra < 10.0)
500 intra_factor += 1.0 + ((10.0 - log_intra) * 0.05);
501 else
502 intra_factor += 1.0;
503
504 if (seq_params->use_highbitdepth)
505 level_sample = CONVERT_TO_SHORTPTR(x->plane[0].src.buf)[0];
506 else
507 level_sample = x->plane[0].src.buf[0];
508 if ((level_sample < DARK_THRESH) && (log_intra < 9.0))
509 brightness_factor += 1.0 + (0.01 * (DARK_THRESH - level_sample));
510 else
511 brightness_factor += 1.0;
512
513 // Intrapenalty below deals with situations where the intra and inter
514 // error scores are very low (e.g. a plain black frame).
515 // We do not have special cases in first pass for 0,0 and nearest etc so
516 // all inter modes carry an overhead cost estimate for the mv.
517 // When the error score is very low this causes us to pick all or lots of
518 // INTRA modes and throw lots of key frames.
519 // This penalty adds a cost matching that of a 0,0 mv to the intra case.
520 this_error += intrapenalty;
521
522 // Accumulate the intra error.
523 intra_error += (int64_t)this_error;
524
525 const int hbd = is_cur_buf_hbd(xd);
526 const int stride = x->plane[0].src.stride;
527 uint8_t *buf = x->plane[0].src.buf;
528 for (int r8 = 0; r8 < 2; ++r8) {
529 for (int c8 = 0; c8 < 2; ++c8) {
530 frame_avg_wavelet_energy += av1_haar_ac_sad_8x8_uint8_input(
531 buf + c8 * 8 + r8 * 8 * stride, stride, hbd);
532 }
533 }
534
535 // Set up limit values for motion vectors to prevent them extending
536 // outside the UMV borders.
537 x->mv_limits.col_min = -((mb_col * 16) + BORDER_MV_PIXELS_B16);
538 x->mv_limits.col_max =
539 ((cm->mb_cols - 1 - mb_col) * 16) + BORDER_MV_PIXELS_B16;
540
541 if (!frame_is_intra_only(cm)) { // Do a motion search
542 int tmp_err, motion_error, raw_motion_error;
543 // Assume 0,0 motion with no mv overhead.
544 MV mv = kZeroMv, tmp_mv = kZeroMv;
545 struct buf_2d unscaled_last_source_buf_2d;
546
547 xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
548 if (is_cur_buf_hbd(xd)) {
549 motion_error = highbd_get_prediction_error(
550 bsize, &x->plane[0].src, &xd->plane[0].pre[0], xd->bd);
551 } else {
552 motion_error = get_prediction_error(bsize, &x->plane[0].src,
553 &xd->plane[0].pre[0]);
554 }
555
556 // Compute the motion error of the 0,0 motion using the last source
557 // frame as the reference. Skip the further motion search on
558 // reconstructed frame if this error is small.
559 unscaled_last_source_buf_2d.buf =
560 cpi->unscaled_last_source->y_buffer + src_yoffset;
561 unscaled_last_source_buf_2d.stride =
562 cpi->unscaled_last_source->y_stride;
563 if (is_cur_buf_hbd(xd)) {
564 raw_motion_error = highbd_get_prediction_error(
565 bsize, &x->plane[0].src, &unscaled_last_source_buf_2d, xd->bd);
566 } else {
567 raw_motion_error = get_prediction_error(bsize, &x->plane[0].src,
568 &unscaled_last_source_buf_2d);
569 }
570
571 // TODO(pengchong): Replace the hard-coded threshold
572 if (raw_motion_error > 25) {
573 // Test last reference frame using the previous best mv as the
574 // starting point (best reference) for the search.
575 first_pass_motion_search(cpi, x, &best_ref_mv, &mv, &motion_error);
576
577 // If the current best reference mv is not centered on 0,0 then do a
578 // 0,0 based search as well.
579 if (!is_zero_mv(&best_ref_mv)) {
580 tmp_err = INT_MAX;
581 first_pass_motion_search(cpi, x, &kZeroMv, &tmp_mv, &tmp_err);
582
583 if (tmp_err < motion_error) {
584 motion_error = tmp_err;
585 mv = tmp_mv;
586 }
587 }
588
589 // Search in an older reference frame.
590 if ((current_frame->frame_number > 1) && gld_yv12 != NULL) {
591 // Assume 0,0 motion with no mv overhead.
592 int gf_motion_error;
593
594 xd->plane[0].pre[0].buf = gld_yv12->y_buffer + recon_yoffset;
595 if (is_cur_buf_hbd(xd)) {
596 gf_motion_error = highbd_get_prediction_error(
597 bsize, &x->plane[0].src, &xd->plane[0].pre[0], xd->bd);
598 } else {
599 gf_motion_error = get_prediction_error(bsize, &x->plane[0].src,
600 &xd->plane[0].pre[0]);
601 }
602
603 first_pass_motion_search(cpi, x, &kZeroMv, &tmp_mv,
604 &gf_motion_error);
605
606 if (gf_motion_error < motion_error && gf_motion_error < this_error)
607 ++second_ref_count;
608
609 // Reset to last frame as reference buffer.
610 xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
611 xd->plane[1].pre[0].buf = first_ref_buf->u_buffer + recon_uvoffset;
612 xd->plane[2].pre[0].buf = first_ref_buf->v_buffer + recon_uvoffset;
613
614 // In accumulating a score for the older reference frame take the
615 // best of the motion predicted score and the intra coded error
616 // (just as will be done for) accumulation of "coded_error" for
617 // the last frame.
618 if (gf_motion_error < this_error)
619 sr_coded_error += gf_motion_error;
620 else
621 sr_coded_error += this_error;
622 } else {
623 sr_coded_error += motion_error;
624 }
625 } else {
626 sr_coded_error += motion_error;
627 }
628
629 // Start by assuming that intra mode is best.
630 best_ref_mv.row = 0;
631 best_ref_mv.col = 0;
632
633 if (motion_error <= this_error) {
634 aom_clear_system_state();
635
636 // Keep a count of cases where the inter and intra were very close
637 // and very low. This helps with scene cut detection for example in
638 // cropped clips with black bars at the sides or top and bottom.
639 if (((this_error - intrapenalty) * 9 <= motion_error * 10) &&
640 (this_error < (2 * intrapenalty))) {
641 neutral_count += 1.0;
642 // Also track cases where the intra is not much worse than the inter
643 // and use this in limiting the GF/arf group length.
644 } else if ((this_error > NCOUNT_INTRA_THRESH) &&
645 (this_error < (NCOUNT_INTRA_FACTOR * motion_error))) {
646 neutral_count +=
647 (double)motion_error / DOUBLE_DIVIDE_CHECK((double)this_error);
648 }
649
650 mv.row *= 8;
651 mv.col *= 8;
652 this_error = motion_error;
653 xd->mi[0]->mode = NEWMV;
654 xd->mi[0]->mv[0].as_mv = mv;
655 xd->mi[0]->tx_size = TX_4X4;
656 xd->mi[0]->ref_frame[0] = LAST_FRAME;
657 xd->mi[0]->ref_frame[1] = NONE_FRAME;
658 av1_enc_build_inter_predictor(cm, xd, mb_row * mb_scale,
659 mb_col * mb_scale, NULL, bsize,
660 AOM_PLANE_Y, AOM_PLANE_Y);
661 av1_encode_sby_pass1(cm, x, bsize);
662 sum_mvr += mv.row;
663 sum_mvr_abs += abs(mv.row);
664 sum_mvc += mv.col;
665 sum_mvc_abs += abs(mv.col);
666 sum_mvrs += mv.row * mv.row;
667 sum_mvcs += mv.col * mv.col;
668 ++intercount;
669
670 best_ref_mv = mv;
671
672 if (!is_zero_mv(&mv)) {
673 ++mvcount;
674
675 // Non-zero vector, was it different from the last non zero vector?
676 if (!is_equal_mv(&mv, &lastmv)) ++new_mv_count;
677 lastmv = mv;
678
679 // Does the row vector point inwards or outwards?
680 if (mb_row < cm->mb_rows / 2) {
681 if (mv.row > 0)
682 --sum_in_vectors;
683 else if (mv.row < 0)
684 ++sum_in_vectors;
685 } else if (mb_row > cm->mb_rows / 2) {
686 if (mv.row > 0)
687 ++sum_in_vectors;
688 else if (mv.row < 0)
689 --sum_in_vectors;
690 }
691
692 // Does the col vector point inwards or outwards?
693 if (mb_col < cm->mb_cols / 2) {
694 if (mv.col > 0)
695 --sum_in_vectors;
696 else if (mv.col < 0)
697 ++sum_in_vectors;
698 } else if (mb_col > cm->mb_cols / 2) {
699 if (mv.col > 0)
700 ++sum_in_vectors;
701 else if (mv.col < 0)
702 --sum_in_vectors;
703 }
704 }
705 }
706 raw_motion_err_list[raw_motion_err_counts++] = raw_motion_error;
707 } else {
708 sr_coded_error += (int64_t)this_error;
709 }
710 coded_error += (int64_t)this_error;
711
712 // Adjust to the next column of MBs.
713 x->plane[0].src.buf += 16;
714 x->plane[1].src.buf += uv_mb_height;
715 x->plane[2].src.buf += uv_mb_height;
716
717 recon_yoffset += 16;
718 src_yoffset += 16;
719 recon_uvoffset += uv_mb_height;
720 }
721 // Adjust to the next row of MBs.
722 x->plane[0].src.buf += 16 * x->plane[0].src.stride - 16 * cm->mb_cols;
723 x->plane[1].src.buf +=
724 uv_mb_height * x->plane[1].src.stride - uv_mb_height * cm->mb_cols;
725 x->plane[2].src.buf +=
726 uv_mb_height * x->plane[1].src.stride - uv_mb_height * cm->mb_cols;
727
728 aom_clear_system_state();
729 }
730 const double raw_err_stdev =
731 raw_motion_error_stdev(raw_motion_err_list, raw_motion_err_counts);
732 aom_free(raw_motion_err_list);
733
734 // Clamp the image start to rows/2. This number of rows is discarded top
735 // and bottom as dead data so rows / 2 means the frame is blank.
736 if ((image_data_start_row > cm->mb_rows / 2) ||
737 (image_data_start_row == INVALID_ROW)) {
738 image_data_start_row = cm->mb_rows / 2;
739 }
740 // Exclude any image dead zone
741 if (image_data_start_row > 0) {
742 intra_skip_count =
743 AOMMAX(0, intra_skip_count - (image_data_start_row * cm->mb_cols * 2));
744 }
745
746 {
747 FIRSTPASS_STATS fps;
748 // The minimum error here insures some bit allocation to frames even
749 // in static regions. The allocation per MB declines for larger formats
750 // where the typical "real" energy per MB also falls.
751 // Initial estimate here uses sqrt(mbs) to define the min_err, where the
752 // number of mbs is proportional to the image area.
753 const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE)
754 ? cpi->initial_mbs
755 : cpi->common.MBs;
756 const double min_err = 200 * sqrt(num_mbs);
757
758 intra_factor = intra_factor / (double)num_mbs;
759 brightness_factor = brightness_factor / (double)num_mbs;
760 fps.weight = intra_factor * brightness_factor;
761
762 fps.frame = current_frame->frame_number;
763 fps.coded_error = (double)(coded_error >> 8) + min_err;
764 fps.sr_coded_error = (double)(sr_coded_error >> 8) + min_err;
765 fps.intra_error = (double)(intra_error >> 8) + min_err;
766 fps.frame_avg_wavelet_energy = (double)frame_avg_wavelet_energy;
767 fps.count = 1.0;
768 fps.pcnt_inter = (double)intercount / num_mbs;
769 fps.pcnt_second_ref = (double)second_ref_count / num_mbs;
770 fps.pcnt_neutral = (double)neutral_count / num_mbs;
771 fps.intra_skip_pct = (double)intra_skip_count / num_mbs;
772 fps.inactive_zone_rows = (double)image_data_start_row;
773 fps.inactive_zone_cols = (double)0; // TODO(paulwilkins): fix
774 fps.raw_error_stdev = raw_err_stdev;
775
776 if (mvcount > 0) {
777 fps.MVr = (double)sum_mvr / mvcount;
778 fps.mvr_abs = (double)sum_mvr_abs / mvcount;
779 fps.MVc = (double)sum_mvc / mvcount;
780 fps.mvc_abs = (double)sum_mvc_abs / mvcount;
781 fps.MVrv =
782 ((double)sum_mvrs - ((double)sum_mvr * sum_mvr / mvcount)) / mvcount;
783 fps.MVcv =
784 ((double)sum_mvcs - ((double)sum_mvc * sum_mvc / mvcount)) / mvcount;
785 fps.mv_in_out_count = (double)sum_in_vectors / (mvcount * 2);
786 fps.new_mv_count = new_mv_count;
787 fps.pcnt_motion = (double)mvcount / num_mbs;
788 } else {
789 fps.MVr = 0.0;
790 fps.mvr_abs = 0.0;
791 fps.MVc = 0.0;
792 fps.mvc_abs = 0.0;
793 fps.MVrv = 0.0;
794 fps.MVcv = 0.0;
795 fps.mv_in_out_count = 0.0;
796 fps.new_mv_count = 0.0;
797 fps.pcnt_motion = 0.0;
798 }
799
800 // TODO(paulwilkins): Handle the case when duration is set to 0, or
801 // something less than the full time between subsequent values of
802 // cpi->source_time_stamp.
803 fps.duration = (double)ts_duration;
804
805 // Don't want to do output stats with a stack variable!
806 twopass->this_frame_stats = fps;
807 output_stats(&twopass->this_frame_stats, cpi->output_pkt_list);
808 accumulate_stats(&twopass->total_stats, &fps);
809 }
810
811 // Copy the previous Last Frame back into gf and and arf buffers if
812 // the prediction is good enough... but also don't allow it to lag too far.
813 if ((twopass->sr_update_lag > 3) ||
814 ((current_frame->frame_number > 0) &&
815 (twopass->this_frame_stats.pcnt_inter > 0.20) &&
816 ((twopass->this_frame_stats.intra_error /
817 DOUBLE_DIVIDE_CHECK(twopass->this_frame_stats.coded_error)) > 2.0))) {
818 if (gld_yv12 != NULL) {
819 assign_frame_buffer_p(
820 &cm->ref_frame_map[get_ref_frame_map_idx(cm, GOLDEN_FRAME)],
821 cm->ref_frame_map[get_ref_frame_map_idx(cm, LAST_FRAME)]);
822 }
823 twopass->sr_update_lag = 1;
824 } else {
825 ++twopass->sr_update_lag;
826 }
827
828 aom_extend_frame_borders(new_yv12, num_planes);
829
830 // The frame we just compressed now becomes the last frame.
831 assign_frame_buffer_p(
832 &cm->ref_frame_map[get_ref_frame_map_idx(cm, LAST_FRAME)], cm->cur_frame);
833
834 // Special case for the first frame. Copy into the GF buffer as a second
835 // reference.
836 if (current_frame->frame_number == 0 &&
837 get_ref_frame_map_idx(cm, GOLDEN_FRAME) != INVALID_IDX) {
838 assign_frame_buffer_p(
839 &cm->ref_frame_map[get_ref_frame_map_idx(cm, GOLDEN_FRAME)],
840 cm->ref_frame_map[get_ref_frame_map_idx(cm, LAST_FRAME)]);
841 }
842
843 // Use this to see what the first pass reconstruction looks like.
844 if (0) {
845 char filename[512];
846 FILE *recon_file;
847 snprintf(filename, sizeof(filename), "enc%04d.yuv",
848 (int)current_frame->frame_number);
849
850 if (current_frame->frame_number == 0)
851 recon_file = fopen(filename, "wb");
852 else
853 recon_file = fopen(filename, "ab");
854
855 (void)fwrite(lst_yv12->buffer_alloc, lst_yv12->frame_size, 1, recon_file);
856 fclose(recon_file);
857 }
858
859 ++current_frame->frame_number;
860 }
861