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_dsp/variance.h"
21 #include "aom_mem/aom_mem.h"
22 #include "aom_ports/mem.h"
23 #include "aom_ports/system_state.h"
24 #include "aom_scale/aom_scale.h"
25 #include "aom_scale/yv12config.h"
26
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 AOM_INLINE 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 if (pktlist != NULL) 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 AOM_INLINE 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_end_first_pass(AV1_COMP * cpi)139 void av1_end_first_pass(AV1_COMP *cpi) {
140 if (cpi->twopass.stats_buf_ctx->total_stats)
141 output_stats(cpi->twopass.stats_buf_ctx->total_stats, cpi->output_pkt_list);
142 }
143
get_block_variance_fn(BLOCK_SIZE bsize)144 static aom_variance_fn_t get_block_variance_fn(BLOCK_SIZE bsize) {
145 switch (bsize) {
146 case BLOCK_8X8: return aom_mse8x8;
147 case BLOCK_16X8: return aom_mse16x8;
148 case BLOCK_8X16: return aom_mse8x16;
149 default: return aom_mse16x16;
150 }
151 }
152
get_prediction_error(BLOCK_SIZE bsize,const struct buf_2d * src,const struct buf_2d * ref)153 static unsigned int get_prediction_error(BLOCK_SIZE bsize,
154 const struct buf_2d *src,
155 const struct buf_2d *ref) {
156 unsigned int sse;
157 const aom_variance_fn_t fn = get_block_variance_fn(bsize);
158 fn(src->buf, src->stride, ref->buf, ref->stride, &sse);
159 return sse;
160 }
161
162 #if CONFIG_AV1_HIGHBITDEPTH
highbd_get_block_variance_fn(BLOCK_SIZE bsize,int bd)163 static aom_variance_fn_t highbd_get_block_variance_fn(BLOCK_SIZE bsize,
164 int bd) {
165 switch (bd) {
166 default:
167 switch (bsize) {
168 case BLOCK_8X8: return aom_highbd_8_mse8x8;
169 case BLOCK_16X8: return aom_highbd_8_mse16x8;
170 case BLOCK_8X16: return aom_highbd_8_mse8x16;
171 default: return aom_highbd_8_mse16x16;
172 }
173 break;
174 case 10:
175 switch (bsize) {
176 case BLOCK_8X8: return aom_highbd_10_mse8x8;
177 case BLOCK_16X8: return aom_highbd_10_mse16x8;
178 case BLOCK_8X16: return aom_highbd_10_mse8x16;
179 default: return aom_highbd_10_mse16x16;
180 }
181 break;
182 case 12:
183 switch (bsize) {
184 case BLOCK_8X8: return aom_highbd_12_mse8x8;
185 case BLOCK_16X8: return aom_highbd_12_mse16x8;
186 case BLOCK_8X16: return aom_highbd_12_mse8x16;
187 default: return aom_highbd_12_mse16x16;
188 }
189 break;
190 }
191 }
192
highbd_get_prediction_error(BLOCK_SIZE bsize,const struct buf_2d * src,const struct buf_2d * ref,int bd)193 static unsigned int highbd_get_prediction_error(BLOCK_SIZE bsize,
194 const struct buf_2d *src,
195 const struct buf_2d *ref,
196 int bd) {
197 unsigned int sse;
198 const aom_variance_fn_t fn = highbd_get_block_variance_fn(bsize, bd);
199 fn(src->buf, src->stride, ref->buf, ref->stride, &sse);
200 return sse;
201 }
202 #endif // CONFIG_AV1_HIGHBITDEPTH
203
204 // Refine the motion search range according to the frame dimension
205 // for first pass test.
get_search_range(const AV1_COMP * cpi)206 static int get_search_range(const AV1_COMP *cpi) {
207 int sr = 0;
208 const int dim = AOMMIN(cpi->initial_width, cpi->initial_height);
209
210 while ((dim << sr) < MAX_FULL_PEL_VAL) ++sr;
211 return sr;
212 }
213
first_pass_motion_search(AV1_COMP * cpi,MACROBLOCK * x,const MV * ref_mv,FULLPEL_MV * best_mv,int * best_motion_err)214 static AOM_INLINE void first_pass_motion_search(AV1_COMP *cpi, MACROBLOCK *x,
215 const MV *ref_mv,
216 FULLPEL_MV *best_mv,
217 int *best_motion_err) {
218 MACROBLOCKD *const xd = &x->e_mbd;
219 FULLPEL_MV start_mv = get_fullmv_from_mv(ref_mv);
220 int tmp_err;
221 const BLOCK_SIZE bsize = xd->mi[0]->sb_type;
222 aom_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
223 const int new_mv_mode_penalty = NEW_MV_MODE_PENALTY;
224 const int sr = get_search_range(cpi);
225 const int step_param = 3 + sr;
226
227 const search_site_config *first_pass_search_sites =
228 &cpi->mv_search_params.ss_cfg[SS_CFG_FPF];
229 FULLPEL_MOTION_SEARCH_PARAMS ms_params;
230 av1_make_default_fullpel_ms_params(&ms_params, cpi, x, bsize, ref_mv,
231 first_pass_search_sites);
232 ms_params.search_method = NSTEP;
233
234 FULLPEL_MV this_best_mv;
235 tmp_err = av1_full_pixel_search(start_mv, &ms_params, step_param, NULL,
236 &this_best_mv, NULL);
237
238 if (tmp_err < INT_MAX) {
239 tmp_err = av1_get_mvpred_sse(x, &this_best_mv, ref_mv, &v_fn_ptr) +
240 new_mv_mode_penalty;
241 }
242
243 if (tmp_err < *best_motion_err) {
244 *best_motion_err = tmp_err;
245 *best_mv = this_best_mv;
246 }
247 }
248
get_bsize(const CommonModeInfoParams * const mi_params,int mb_row,int mb_col)249 static BLOCK_SIZE get_bsize(const CommonModeInfoParams *const mi_params,
250 int mb_row, int mb_col) {
251 if (mi_size_wide[BLOCK_16X16] * mb_col + mi_size_wide[BLOCK_8X8] <
252 mi_params->mi_cols) {
253 return mi_size_wide[BLOCK_16X16] * mb_row + mi_size_wide[BLOCK_8X8] <
254 mi_params->mi_rows
255 ? BLOCK_16X16
256 : BLOCK_16X8;
257 } else {
258 return mi_size_wide[BLOCK_16X16] * mb_row + mi_size_wide[BLOCK_8X8] <
259 mi_params->mi_rows
260 ? BLOCK_8X16
261 : BLOCK_8X8;
262 }
263 }
264
find_fp_qindex(aom_bit_depth_t bit_depth)265 static int find_fp_qindex(aom_bit_depth_t bit_depth) {
266 return av1_find_qindex(FIRST_PASS_Q, bit_depth, 0, QINDEX_RANGE - 1);
267 }
268
raw_motion_error_stdev(int * raw_motion_err_list,int raw_motion_err_counts)269 static double raw_motion_error_stdev(int *raw_motion_err_list,
270 int raw_motion_err_counts) {
271 int64_t sum_raw_err = 0;
272 double raw_err_avg = 0;
273 double raw_err_stdev = 0;
274 if (raw_motion_err_counts == 0) return 0;
275
276 int i;
277 for (i = 0; i < raw_motion_err_counts; i++) {
278 sum_raw_err += raw_motion_err_list[i];
279 }
280 raw_err_avg = (double)sum_raw_err / raw_motion_err_counts;
281 for (i = 0; i < raw_motion_err_counts; i++) {
282 raw_err_stdev += (raw_motion_err_list[i] - raw_err_avg) *
283 (raw_motion_err_list[i] - raw_err_avg);
284 }
285 // Calculate the standard deviation for the motion error of all the inter
286 // blocks of the 0,0 motion using the last source
287 // frame as the reference.
288 raw_err_stdev = sqrt(raw_err_stdev / raw_motion_err_counts);
289 return raw_err_stdev;
290 }
291
292 // This structure contains several key parameters to be accumulate for this
293 // frame.
294 typedef struct {
295 // Intra prediction error.
296 int64_t intra_error;
297 // Average wavelet energy computed using Discrete Wavelet Transform (DWT).
298 int64_t frame_avg_wavelet_energy;
299 // Best of intra pred error and inter pred error using last frame as ref.
300 int64_t coded_error;
301 // Best of intra pred error and inter pred error using golden frame as ref.
302 int64_t sr_coded_error;
303 // Best of intra pred error and inter pred error using altref frame as ref.
304 int64_t tr_coded_error;
305 // Count of motion vector.
306 int mv_count;
307 // Count of blocks that pick inter prediction (inter pred error is smaller
308 // than intra pred error).
309 int inter_count;
310 // Count of blocks that pick second ref (golden frame).
311 int second_ref_count;
312 // Count of blocks that pick third ref (altref frame).
313 int third_ref_count;
314 // Count of blocks where the inter and intra are very close and very low.
315 double neutral_count;
316 // Count of blocks where intra error is very small.
317 int intra_skip_count;
318 // Start row.
319 int image_data_start_row;
320 // Count of unique non-zero motion vectors.
321 int new_mv_count;
322 // Sum of inward motion vectors.
323 int sum_in_vectors;
324 // Sum of motion vector row.
325 int sum_mvr;
326 // Sum of motion vector column.
327 int sum_mvc;
328 // Sum of absolute value of motion vector row.
329 int sum_mvr_abs;
330 // Sum of absolute value of motion vector column.
331 int sum_mvc_abs;
332 // Sum of the square of motion vector row.
333 int64_t sum_mvrs;
334 // Sum of the square of motion vector column.
335 int64_t sum_mvcs;
336 // A factor calculated using intra pred error.
337 double intra_factor;
338 // A factor that measures brightness.
339 double brightness_factor;
340 } FRAME_STATS;
341
342 #define UL_INTRA_THRESH 50
343 #define INVALID_ROW -1
344 // Computes and returns the intra pred error of a block.
345 // intra pred error: sum of squared error of the intra predicted residual.
346 // Inputs:
347 // cpi: the encoder setting. Only a few params in it will be used.
348 // this_frame: the current frame buffer.
349 // tile: tile information (not used in first pass, already init to zero)
350 // mb_row: row index in the unit of first pass block size.
351 // mb_col: column index in the unit of first pass block size.
352 // y_offset: the offset of y frame buffer, indicating the starting point of
353 // the current block.
354 // uv_offset: the offset of u and v frame buffer, indicating the starting
355 // point of the current block.
356 // fp_block_size: first pass block size.
357 // qindex: quantization step size to encode the frame.
358 // stats: frame encoding stats.
359 // Modifies:
360 // stats->intra_skip_count
361 // stats->image_data_start_row
362 // stats->intra_factor
363 // stats->brightness_factor
364 // stats->intra_error
365 // stats->frame_avg_wavelet_energy
366 // Returns:
367 // this_intra_error.
firstpass_intra_prediction(AV1_COMP * cpi,YV12_BUFFER_CONFIG * const this_frame,const TileInfo * const tile,const int mb_row,const int mb_col,const int y_offset,const int uv_offset,const BLOCK_SIZE fp_block_size,const int qindex,FRAME_STATS * const stats)368 static int firstpass_intra_prediction(
369 AV1_COMP *cpi, YV12_BUFFER_CONFIG *const this_frame,
370 const TileInfo *const tile, const int mb_row, const int mb_col,
371 const int y_offset, const int uv_offset, const BLOCK_SIZE fp_block_size,
372 const int qindex, FRAME_STATS *const stats) {
373 const AV1_COMMON *const cm = &cpi->common;
374 const CommonModeInfoParams *const mi_params = &cm->mi_params;
375 const SequenceHeader *const seq_params = &cm->seq_params;
376 MACROBLOCK *const x = &cpi->td.mb;
377 MACROBLOCKD *const xd = &x->e_mbd;
378 const int mb_scale = mi_size_wide[fp_block_size];
379 const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
380 const int num_planes = av1_num_planes(cm);
381 const BLOCK_SIZE bsize = get_bsize(mi_params, mb_row, mb_col);
382
383 aom_clear_system_state();
384 set_mi_offsets(mi_params, xd, mb_row * mb_scale, mb_col * mb_scale);
385 xd->plane[0].dst.buf = this_frame->y_buffer + y_offset;
386 xd->plane[1].dst.buf = this_frame->u_buffer + uv_offset;
387 xd->plane[2].dst.buf = this_frame->v_buffer + uv_offset;
388 xd->left_available = (mb_col != 0);
389 xd->mi[0]->sb_type = bsize;
390 xd->mi[0]->ref_frame[0] = INTRA_FRAME;
391 set_mi_row_col(xd, tile, mb_row * mb_scale, mi_size_high[bsize],
392 mb_col * mb_scale, mi_size_wide[bsize], mi_params->mi_rows,
393 mi_params->mi_cols);
394 set_plane_n4(xd, mi_size_wide[bsize], mi_size_high[bsize], num_planes);
395 xd->mi[0]->segment_id = 0;
396 xd->lossless[xd->mi[0]->segment_id] = (qindex == 0);
397 xd->mi[0]->mode = DC_PRED;
398 xd->mi[0]->tx_size =
399 use_dc_pred ? (bsize >= fp_block_size ? TX_16X16 : TX_8X8) : TX_4X4;
400
401 av1_encode_intra_block_plane(cpi, x, bsize, 0, DRY_RUN_NORMAL, 0);
402 int this_intra_error = aom_get_mb_ss(x->plane[0].src_diff);
403
404 if (this_intra_error < UL_INTRA_THRESH) {
405 ++stats->intra_skip_count;
406 } else if ((mb_col > 0) && (stats->image_data_start_row == INVALID_ROW)) {
407 stats->image_data_start_row = mb_row;
408 }
409
410 if (seq_params->use_highbitdepth) {
411 switch (seq_params->bit_depth) {
412 case AOM_BITS_8: break;
413 case AOM_BITS_10: this_intra_error >>= 4; break;
414 case AOM_BITS_12: this_intra_error >>= 8; break;
415 default:
416 assert(0 &&
417 "seq_params->bit_depth should be AOM_BITS_8, "
418 "AOM_BITS_10 or AOM_BITS_12");
419 return -1;
420 }
421 }
422
423 aom_clear_system_state();
424 double log_intra = log(this_intra_error + 1.0);
425 if (log_intra < 10.0) {
426 stats->intra_factor += 1.0 + ((10.0 - log_intra) * 0.05);
427 } else {
428 stats->intra_factor += 1.0;
429 }
430
431 int level_sample;
432 if (seq_params->use_highbitdepth) {
433 level_sample = CONVERT_TO_SHORTPTR(x->plane[0].src.buf)[0];
434 } else {
435 level_sample = x->plane[0].src.buf[0];
436 }
437 if ((level_sample < DARK_THRESH) && (log_intra < 9.0)) {
438 stats->brightness_factor += 1.0 + (0.01 * (DARK_THRESH - level_sample));
439 } else {
440 stats->brightness_factor += 1.0;
441 }
442
443 // Intrapenalty below deals with situations where the intra and inter
444 // error scores are very low (e.g. a plain black frame).
445 // We do not have special cases in first pass for 0,0 and nearest etc so
446 // all inter modes carry an overhead cost estimate for the mv.
447 // When the error score is very low this causes us to pick all or lots of
448 // INTRA modes and throw lots of key frames.
449 // This penalty adds a cost matching that of a 0,0 mv to the intra case.
450 this_intra_error += INTRA_MODE_PENALTY;
451
452 // Accumulate the intra error.
453 stats->intra_error += (int64_t)this_intra_error;
454
455 const int hbd = is_cur_buf_hbd(xd);
456 const int stride = x->plane[0].src.stride;
457 uint8_t *buf = x->plane[0].src.buf;
458 for (int r8 = 0; r8 < 2; ++r8) {
459 for (int c8 = 0; c8 < 2; ++c8) {
460 stats->frame_avg_wavelet_energy += av1_haar_ac_sad_8x8_uint8_input(
461 buf + c8 * 8 + r8 * 8 * stride, stride, hbd);
462 }
463 }
464
465 return this_intra_error;
466 }
467
468 // Returns the sum of square error between source and reference blocks.
get_prediction_error_bitdepth(const int is_high_bitdepth,const int bitdepth,const BLOCK_SIZE block_size,const struct buf_2d * src,const struct buf_2d * ref)469 static int get_prediction_error_bitdepth(const int is_high_bitdepth,
470 const int bitdepth,
471 const BLOCK_SIZE block_size,
472 const struct buf_2d *src,
473 const struct buf_2d *ref) {
474 (void)is_high_bitdepth;
475 (void)bitdepth;
476 #if CONFIG_AV1_HIGHBITDEPTH
477 if (is_high_bitdepth) {
478 return highbd_get_prediction_error(block_size, src, ref, bitdepth);
479 }
480 #endif // CONFIG_AV1_HIGHBITDEPTH
481 return get_prediction_error(block_size, src, ref);
482 }
483
484 // Accumulates motion vector stats.
485 // Modifies member variables of "stats".
accumulate_mv_stats(const MV best_mv,const FULLPEL_MV mv,const int mb_row,const int mb_col,const int mb_rows,const int mb_cols,MV * last_mv,FRAME_STATS * stats)486 static void accumulate_mv_stats(const MV best_mv, const FULLPEL_MV mv,
487 const int mb_row, const int mb_col,
488 const int mb_rows, const int mb_cols,
489 MV *last_mv, FRAME_STATS *stats) {
490 if (is_zero_mv(&best_mv)) return;
491
492 ++stats->mv_count;
493 // Non-zero vector, was it different from the last non zero vector?
494 if (!is_equal_mv(&best_mv, last_mv)) ++stats->new_mv_count;
495 *last_mv = best_mv;
496
497 // Does the row vector point inwards or outwards?
498 if (mb_row < mb_rows / 2) {
499 if (mv.row > 0) {
500 --stats->sum_in_vectors;
501 } else if (mv.row < 0) {
502 ++stats->sum_in_vectors;
503 }
504 } else if (mb_row > mb_rows / 2) {
505 if (mv.row > 0) {
506 ++stats->sum_in_vectors;
507 } else if (mv.row < 0) {
508 --stats->sum_in_vectors;
509 }
510 }
511
512 // Does the col vector point inwards or outwards?
513 if (mb_col < mb_cols / 2) {
514 if (mv.col > 0) {
515 --stats->sum_in_vectors;
516 } else if (mv.col < 0) {
517 ++stats->sum_in_vectors;
518 }
519 } else if (mb_col > mb_cols / 2) {
520 if (mv.col > 0) {
521 ++stats->sum_in_vectors;
522 } else if (mv.col < 0) {
523 --stats->sum_in_vectors;
524 }
525 }
526 }
527
528 #define LOW_MOTION_ERROR_THRESH 25
529 // Computes and returns the inter prediction error from the last frame.
530 // Computes inter prediction errors from the golden and alt ref frams and
531 // Updates stats accordingly.
532 // Inputs:
533 // cpi: the encoder setting. Only a few params in it will be used.
534 // last_frame: the frame buffer of the last frame.
535 // golden_frame: the frame buffer of the golden frame.
536 // alt_ref_frame: the frame buffer of the alt ref frame.
537 // mb_row: row index in the unit of first pass block size.
538 // mb_col: column index in the unit of first pass block size.
539 // recon_yoffset: the y offset of the reconstructed frame buffer,
540 // indicating the starting point of the current block.
541 // recont_uvoffset: the u/v offset of the reconstructed frame buffer,
542 // indicating the starting point of the current block.
543 // src_yoffset: the y offset of the source frame buffer.
544 // alt_ref_frame_offset: the y offset of the alt ref frame buffer.
545 // fp_block_size: first pass block size.
546 // this_intra_error: the intra prediction error of this block.
547 // raw_motion_err_counts: the count of raw motion vectors.
548 // raw_motion_err_list: the array that records the raw motion error.
549 // best_ref_mv: best reference mv found so far.
550 // last_mv: last mv.
551 // stats: frame encoding stats.
552 // Modifies:
553 // raw_motion_err_list
554 // best_ref_mv
555 // last_mv
556 // stats: many member params in it.
557 // Returns:
558 // this_inter_error
firstpass_inter_prediction(AV1_COMP * cpi,const YV12_BUFFER_CONFIG * const last_frame,const YV12_BUFFER_CONFIG * const golden_frame,const YV12_BUFFER_CONFIG * const alt_ref_frame,const int mb_row,const int mb_col,const int recon_yoffset,const int recon_uvoffset,const int src_yoffset,const int alt_ref_frame_yoffset,const BLOCK_SIZE fp_block_size,const int this_intra_error,const int raw_motion_err_counts,int * raw_motion_err_list,MV * best_ref_mv,MV * last_mv,FRAME_STATS * stats)559 static int firstpass_inter_prediction(
560 AV1_COMP *cpi, const YV12_BUFFER_CONFIG *const last_frame,
561 const YV12_BUFFER_CONFIG *const golden_frame,
562 const YV12_BUFFER_CONFIG *const alt_ref_frame, const int mb_row,
563 const int mb_col, const int recon_yoffset, const int recon_uvoffset,
564 const int src_yoffset, const int alt_ref_frame_yoffset,
565 const BLOCK_SIZE fp_block_size, const int this_intra_error,
566 const int raw_motion_err_counts, int *raw_motion_err_list, MV *best_ref_mv,
567 MV *last_mv, FRAME_STATS *stats) {
568 int this_inter_error = this_intra_error;
569 AV1_COMMON *const cm = &cpi->common;
570 const CommonModeInfoParams *const mi_params = &cm->mi_params;
571 CurrentFrame *const current_frame = &cm->current_frame;
572 MACROBLOCK *const x = &cpi->td.mb;
573 MACROBLOCKD *const xd = &x->e_mbd;
574 const int is_high_bitdepth = is_cur_buf_hbd(xd);
575 const int bitdepth = xd->bd;
576 const int mb_scale = mi_size_wide[fp_block_size];
577 const BLOCK_SIZE bsize = get_bsize(mi_params, mb_row, mb_col);
578 const int fp_block_size_height = block_size_wide[fp_block_size];
579 // Assume 0,0 motion with no mv overhead.
580 FULLPEL_MV mv = kZeroFullMv;
581 FULLPEL_MV tmp_mv = kZeroFullMv;
582 xd->plane[0].pre[0].buf = last_frame->y_buffer + recon_yoffset;
583 // Set up limit values for motion vectors to prevent them extending
584 // outside the UMV borders.
585 av1_set_mv_col_limits(mi_params, &x->mv_limits, (mb_col << 2),
586 (fp_block_size_height >> MI_SIZE_LOG2),
587 cpi->oxcf.border_in_pixels);
588
589 int motion_error =
590 get_prediction_error_bitdepth(is_high_bitdepth, bitdepth, bsize,
591 &x->plane[0].src, &xd->plane[0].pre[0]);
592
593 // Compute the motion error of the 0,0 motion using the last source
594 // frame as the reference. Skip the further motion search on
595 // reconstructed frame if this error is small.
596 struct buf_2d unscaled_last_source_buf_2d;
597 unscaled_last_source_buf_2d.buf =
598 cpi->unscaled_last_source->y_buffer + src_yoffset;
599 unscaled_last_source_buf_2d.stride = cpi->unscaled_last_source->y_stride;
600 const int raw_motion_error = get_prediction_error_bitdepth(
601 is_high_bitdepth, bitdepth, bsize, &x->plane[0].src,
602 &unscaled_last_source_buf_2d);
603 raw_motion_err_list[raw_motion_err_counts] = raw_motion_error;
604
605 // TODO(pengchong): Replace the hard-coded threshold
606 if (raw_motion_error > LOW_MOTION_ERROR_THRESH) {
607 // Test last reference frame using the previous best mv as the
608 // starting point (best reference) for the search.
609 first_pass_motion_search(cpi, x, best_ref_mv, &mv, &motion_error);
610
611 // If the current best reference mv is not centered on 0,0 then do a
612 // 0,0 based search as well.
613 if (!is_zero_mv(best_ref_mv)) {
614 int tmp_err = INT_MAX;
615 first_pass_motion_search(cpi, x, &kZeroMv, &tmp_mv, &tmp_err);
616
617 if (tmp_err < motion_error) {
618 motion_error = tmp_err;
619 mv = tmp_mv;
620 }
621 }
622
623 // Motion search in 2nd reference frame.
624 int gf_motion_error = motion_error;
625 if ((current_frame->frame_number > 1) && golden_frame != NULL) {
626 // Assume 0,0 motion with no mv overhead.
627 xd->plane[0].pre[0].buf = golden_frame->y_buffer + recon_yoffset;
628 xd->plane[0].pre[0].stride = golden_frame->y_stride;
629 gf_motion_error =
630 get_prediction_error_bitdepth(is_high_bitdepth, bitdepth, bsize,
631 &x->plane[0].src, &xd->plane[0].pre[0]);
632 first_pass_motion_search(cpi, x, &kZeroMv, &tmp_mv, &gf_motion_error);
633 }
634 if (gf_motion_error < motion_error && gf_motion_error < this_intra_error) {
635 ++stats->second_ref_count;
636 }
637 // In accumulating a score for the 2nd reference frame take the
638 // best of the motion predicted score and the intra coded error
639 // (just as will be done for) accumulation of "coded_error" for
640 // the last frame.
641 if ((current_frame->frame_number > 1) && golden_frame != NULL) {
642 stats->sr_coded_error += AOMMIN(gf_motion_error, this_intra_error);
643 } else {
644 // TODO(chengchen): I believe logically this should also be changed to
645 // stats->sr_coded_error += AOMMIN(gf_motion_error, this_intra_error).
646 stats->sr_coded_error += motion_error;
647 }
648
649 // Motion search in 3rd reference frame.
650 int alt_motion_error = motion_error;
651 if (alt_ref_frame != NULL) {
652 xd->plane[0].pre[0].buf = alt_ref_frame->y_buffer + alt_ref_frame_yoffset;
653 xd->plane[0].pre[0].stride = alt_ref_frame->y_stride;
654 alt_motion_error =
655 get_prediction_error_bitdepth(is_high_bitdepth, bitdepth, bsize,
656 &x->plane[0].src, &xd->plane[0].pre[0]);
657 first_pass_motion_search(cpi, x, &kZeroMv, &tmp_mv, &alt_motion_error);
658 }
659 if (alt_motion_error < motion_error && alt_motion_error < gf_motion_error &&
660 alt_motion_error < this_intra_error) {
661 ++stats->third_ref_count;
662 }
663 // In accumulating a score for the 3rd reference frame take the
664 // best of the motion predicted score and the intra coded error
665 // (just as will be done for) accumulation of "coded_error" for
666 // the last frame.
667 if (alt_ref_frame != NULL) {
668 stats->tr_coded_error += AOMMIN(alt_motion_error, this_intra_error);
669 } else {
670 // TODO(chengchen): I believe logically this should also be changed to
671 // stats->tr_coded_error += AOMMIN(alt_motion_error, this_intra_error).
672 stats->tr_coded_error += motion_error;
673 }
674
675 // Reset to last frame as reference buffer.
676 xd->plane[0].pre[0].buf = last_frame->y_buffer + recon_yoffset;
677 xd->plane[1].pre[0].buf = last_frame->u_buffer + recon_uvoffset;
678 xd->plane[2].pre[0].buf = last_frame->v_buffer + recon_uvoffset;
679 } else {
680 stats->sr_coded_error += motion_error;
681 stats->tr_coded_error += motion_error;
682 }
683
684 // Start by assuming that intra mode is best.
685 best_ref_mv->row = 0;
686 best_ref_mv->col = 0;
687
688 if (motion_error <= this_intra_error) {
689 aom_clear_system_state();
690
691 // Keep a count of cases where the inter and intra were very close
692 // and very low. This helps with scene cut detection for example in
693 // cropped clips with black bars at the sides or top and bottom.
694 if (((this_intra_error - INTRA_MODE_PENALTY) * 9 <= motion_error * 10) &&
695 (this_intra_error < (2 * INTRA_MODE_PENALTY))) {
696 stats->neutral_count += 1.0;
697 // Also track cases where the intra is not much worse than the inter
698 // and use this in limiting the GF/arf group length.
699 } else if ((this_intra_error > NCOUNT_INTRA_THRESH) &&
700 (this_intra_error < (NCOUNT_INTRA_FACTOR * motion_error))) {
701 stats->neutral_count +=
702 (double)motion_error / DOUBLE_DIVIDE_CHECK((double)this_intra_error);
703 }
704
705 const MV best_mv = get_mv_from_fullmv(&mv);
706 this_inter_error = motion_error;
707 xd->mi[0]->mode = NEWMV;
708 xd->mi[0]->mv[0].as_mv = best_mv;
709 xd->mi[0]->tx_size = TX_4X4;
710 xd->mi[0]->ref_frame[0] = LAST_FRAME;
711 xd->mi[0]->ref_frame[1] = NONE_FRAME;
712 av1_enc_build_inter_predictor(cm, xd, mb_row * mb_scale, mb_col * mb_scale,
713 NULL, bsize, AOM_PLANE_Y, AOM_PLANE_Y);
714 av1_encode_sby_pass1(cpi, x, bsize);
715 stats->sum_mvr += best_mv.row;
716 stats->sum_mvr_abs += abs(best_mv.row);
717 stats->sum_mvc += best_mv.col;
718 stats->sum_mvc_abs += abs(best_mv.col);
719 stats->sum_mvrs += best_mv.row * best_mv.row;
720 stats->sum_mvcs += best_mv.col * best_mv.col;
721 ++stats->inter_count;
722
723 *best_ref_mv = best_mv;
724 accumulate_mv_stats(best_mv, mv, mb_row, mb_col, mi_params->mb_rows,
725 mi_params->mb_cols, last_mv, stats);
726 }
727
728 return this_inter_error;
729 }
730
731 // Updates the first pass stats of this frame.
732 // Input:
733 // cpi: the encoder setting. Only a few params in it will be used.
734 // stats: stats accumulated for this frame.
735 // raw_err_stdev: the statndard deviation for the motion error of all the
736 // inter blocks of the (0,0) motion using the last source
737 // frame as the reference.
738 // frame_number: current frame number.
739 // ts_duration: Duration of the frame / collection of frames.
740 // Updates:
741 // twopass->total_stats: the accumulated stats.
742 // twopass->stats_buf_ctx->stats_in_end: the pointer to the current stats,
743 // update its value and its position
744 // in the buffer.
update_firstpass_stats(AV1_COMP * cpi,const FRAME_STATS * const stats,const double raw_err_stdev,const int frame_number,const int64_t ts_duration)745 static void update_firstpass_stats(AV1_COMP *cpi,
746 const FRAME_STATS *const stats,
747 const double raw_err_stdev,
748 const int frame_number,
749 const int64_t ts_duration) {
750 TWO_PASS *twopass = &cpi->twopass;
751 AV1_COMMON *const cm = &cpi->common;
752 const CommonModeInfoParams *const mi_params = &cm->mi_params;
753 FIRSTPASS_STATS *this_frame_stats = twopass->stats_buf_ctx->stats_in_end;
754 FIRSTPASS_STATS fps;
755 // The minimum error here insures some bit allocation to frames even
756 // in static regions. The allocation per MB declines for larger formats
757 // where the typical "real" energy per MB also falls.
758 // Initial estimate here uses sqrt(mbs) to define the min_err, where the
759 // number of mbs is proportional to the image area.
760 const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) ? cpi->initial_mbs
761 : mi_params->MBs;
762 const double min_err = 200 * sqrt(num_mbs);
763
764 fps.weight = stats->intra_factor * stats->brightness_factor;
765 fps.frame = frame_number;
766 fps.coded_error = (double)(stats->coded_error >> 8) + min_err;
767 fps.sr_coded_error = (double)(stats->sr_coded_error >> 8) + min_err;
768 fps.tr_coded_error = (double)(stats->tr_coded_error >> 8) + min_err;
769 fps.intra_error = (double)(stats->intra_error >> 8) + min_err;
770 fps.frame_avg_wavelet_energy = (double)stats->frame_avg_wavelet_energy;
771 fps.count = 1.0;
772 fps.pcnt_inter = (double)stats->inter_count / num_mbs;
773 fps.pcnt_second_ref = (double)stats->second_ref_count / num_mbs;
774 fps.pcnt_third_ref = (double)stats->third_ref_count / num_mbs;
775 fps.pcnt_neutral = (double)stats->neutral_count / num_mbs;
776 fps.intra_skip_pct = (double)stats->intra_skip_count / num_mbs;
777 fps.inactive_zone_rows = (double)stats->image_data_start_row;
778 fps.inactive_zone_cols = (double)0; // TODO(paulwilkins): fix
779 fps.raw_error_stdev = raw_err_stdev;
780
781 if (stats->mv_count > 0) {
782 fps.MVr = (double)stats->sum_mvr / stats->mv_count;
783 fps.mvr_abs = (double)stats->sum_mvr_abs / stats->mv_count;
784 fps.MVc = (double)stats->sum_mvc / stats->mv_count;
785 fps.mvc_abs = (double)stats->sum_mvc_abs / stats->mv_count;
786 fps.MVrv = ((double)stats->sum_mvrs -
787 ((double)stats->sum_mvr * stats->sum_mvr / stats->mv_count)) /
788 stats->mv_count;
789 fps.MVcv = ((double)stats->sum_mvcs -
790 ((double)stats->sum_mvc * stats->sum_mvc / stats->mv_count)) /
791 stats->mv_count;
792 fps.mv_in_out_count = (double)stats->sum_in_vectors / (stats->mv_count * 2);
793 fps.new_mv_count = stats->new_mv_count;
794 fps.pcnt_motion = (double)stats->mv_count / num_mbs;
795 } else {
796 fps.MVr = 0.0;
797 fps.mvr_abs = 0.0;
798 fps.MVc = 0.0;
799 fps.mvc_abs = 0.0;
800 fps.MVrv = 0.0;
801 fps.MVcv = 0.0;
802 fps.mv_in_out_count = 0.0;
803 fps.new_mv_count = 0.0;
804 fps.pcnt_motion = 0.0;
805 }
806
807 // TODO(paulwilkins): Handle the case when duration is set to 0, or
808 // something less than the full time between subsequent values of
809 // cpi->source_time_stamp.
810 fps.duration = (double)ts_duration;
811
812 // We will store the stats inside the persistent twopass struct (and NOT the
813 // local variable 'fps'), and then cpi->output_pkt_list will point to it.
814 *this_frame_stats = fps;
815 output_stats(this_frame_stats, cpi->output_pkt_list);
816 if (cpi->twopass.stats_buf_ctx->total_stats != NULL) {
817 accumulate_stats(cpi->twopass.stats_buf_ctx->total_stats, &fps);
818 }
819 /*In the case of two pass, first pass uses it as a circular buffer,
820 * when LAP is enabled it is used as a linear buffer*/
821 twopass->stats_buf_ctx->stats_in_end++;
822 if ((cpi->oxcf.pass == 1) && (twopass->stats_buf_ctx->stats_in_end >=
823 twopass->stats_buf_ctx->stats_in_buf_end)) {
824 twopass->stats_buf_ctx->stats_in_end =
825 twopass->stats_buf_ctx->stats_in_start;
826 }
827 }
828
print_reconstruction_frame(const YV12_BUFFER_CONFIG * const last_frame,int frame_number,int do_print)829 static void print_reconstruction_frame(
830 const YV12_BUFFER_CONFIG *const last_frame, int frame_number,
831 int do_print) {
832 if (!do_print) return;
833
834 char filename[512];
835 FILE *recon_file;
836 snprintf(filename, sizeof(filename), "enc%04d.yuv", frame_number);
837
838 if (frame_number == 0) {
839 recon_file = fopen(filename, "wb");
840 } else {
841 recon_file = fopen(filename, "ab");
842 }
843
844 fwrite(last_frame->buffer_alloc, last_frame->frame_size, 1, recon_file);
845 fclose(recon_file);
846 }
847
848 #define FIRST_PASS_ALT_REF_DISTANCE 16
av1_first_pass(AV1_COMP * cpi,const int64_t ts_duration)849 void av1_first_pass(AV1_COMP *cpi, const int64_t ts_duration) {
850 MACROBLOCK *const x = &cpi->td.mb;
851 AV1_COMMON *const cm = &cpi->common;
852 const CommonModeInfoParams *const mi_params = &cm->mi_params;
853 CurrentFrame *const current_frame = &cm->current_frame;
854 const SequenceHeader *const seq_params = &cm->seq_params;
855 const int num_planes = av1_num_planes(cm);
856 MACROBLOCKD *const xd = &x->e_mbd;
857 const PICK_MODE_CONTEXT *ctx = &cpi->td.pc_root->none;
858 MV last_mv = kZeroMv;
859 const int qindex = find_fp_qindex(seq_params->bit_depth);
860 // Detect if the key frame is screen content type.
861 if (frame_is_intra_only(cm)) {
862 FeatureFlags *const features = &cm->features;
863 av1_set_screen_content_options(cpi, features);
864 cpi->is_screen_content_type = features->allow_screen_content_tools;
865 }
866 // First pass coding proceeds in raster scan order with unit size of 16x16.
867 const BLOCK_SIZE fp_block_size = BLOCK_16X16;
868 const int fp_block_size_width = block_size_high[fp_block_size];
869 const int fp_block_size_height = block_size_wide[fp_block_size];
870 int *raw_motion_err_list;
871 int raw_motion_err_counts = 0;
872 CHECK_MEM_ERROR(cm, raw_motion_err_list,
873 aom_calloc(mi_params->mb_rows * mi_params->mb_cols,
874 sizeof(*raw_motion_err_list)));
875 // Tiling is ignored in the first pass.
876 TileInfo tile;
877 av1_tile_init(&tile, cm, 0, 0);
878 FRAME_STATS stats = { 0 };
879 stats.image_data_start_row = INVALID_ROW;
880
881 const YV12_BUFFER_CONFIG *const last_frame =
882 get_ref_frame_yv12_buf(cm, LAST_FRAME);
883 const YV12_BUFFER_CONFIG *golden_frame =
884 get_ref_frame_yv12_buf(cm, GOLDEN_FRAME);
885 const YV12_BUFFER_CONFIG *alt_ref_frame = NULL;
886 const int alt_ref_offset =
887 FIRST_PASS_ALT_REF_DISTANCE -
888 (current_frame->frame_number % FIRST_PASS_ALT_REF_DISTANCE);
889 if (alt_ref_offset < FIRST_PASS_ALT_REF_DISTANCE) {
890 const struct lookahead_entry *const alt_ref_frame_buffer =
891 av1_lookahead_peek(cpi->lookahead, alt_ref_offset,
892 cpi->compressor_stage);
893 if (alt_ref_frame_buffer != NULL) {
894 alt_ref_frame = &alt_ref_frame_buffer->img;
895 }
896 }
897 YV12_BUFFER_CONFIG *const this_frame = &cm->cur_frame->buf;
898 // First pass code requires valid last and new frame buffers.
899 assert(this_frame != NULL);
900 assert(frame_is_intra_only(cm) || (last_frame != NULL));
901
902 av1_setup_frame_size(cpi);
903 aom_clear_system_state();
904
905 set_mi_offsets(mi_params, xd, 0, 0);
906 xd->mi[0]->sb_type = fp_block_size;
907
908 // Do not use periodic key frames.
909 cpi->rc.frames_to_key = INT_MAX;
910
911 av1_set_quantizer(cm, cpi->oxcf.qm_minlevel, cpi->oxcf.qm_maxlevel, qindex);
912
913 av1_setup_block_planes(xd, seq_params->subsampling_x,
914 seq_params->subsampling_y, num_planes);
915
916 av1_setup_src_planes(x, cpi->source, 0, 0, num_planes, fp_block_size);
917 av1_setup_dst_planes(xd->plane, seq_params->sb_size, this_frame, 0, 0, 0,
918 num_planes);
919
920 if (!frame_is_intra_only(cm)) {
921 av1_setup_pre_planes(xd, 0, last_frame, 0, 0, NULL, num_planes);
922 }
923
924 set_mi_offsets(mi_params, xd, 0, 0);
925
926 // Don't store luma on the fist pass since chroma is not computed
927 xd->cfl.store_y = 0;
928 av1_frame_init_quantizer(cpi);
929
930 for (int i = 0; i < num_planes; ++i) {
931 x->plane[i].coeff = ctx->coeff[i];
932 x->plane[i].qcoeff = ctx->qcoeff[i];
933 x->plane[i].eobs = ctx->eobs[i];
934 x->plane[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
935 xd->plane[i].dqcoeff = ctx->dqcoeff[i];
936 }
937
938 av1_init_mv_probs(cm);
939 av1_initialize_rd_consts(cpi);
940
941 const int src_y_stride = cpi->source->y_stride;
942 const int recon_y_stride = this_frame->y_stride;
943 const int recon_uv_stride = this_frame->uv_stride;
944 const int uv_mb_height =
945 fp_block_size_height >> (this_frame->y_height > this_frame->uv_height);
946
947 for (int mb_row = 0; mb_row < mi_params->mb_rows; ++mb_row) {
948 MV best_ref_mv = kZeroMv;
949
950 // Reset above block coeffs.
951 xd->up_available = (mb_row != 0);
952 int recon_yoffset = (mb_row * recon_y_stride * fp_block_size_height);
953 int src_yoffset = (mb_row * src_y_stride * fp_block_size_height);
954 int recon_uvoffset = (mb_row * recon_uv_stride * uv_mb_height);
955 int alt_ref_frame_yoffset =
956 (alt_ref_frame != NULL)
957 ? mb_row * alt_ref_frame->y_stride * fp_block_size_height
958 : -1;
959
960 // Set up limit values for motion vectors to prevent them extending
961 // outside the UMV borders.
962 av1_set_mv_row_limits(mi_params, &x->mv_limits, (mb_row << 2),
963 (fp_block_size_height >> MI_SIZE_LOG2),
964 cpi->oxcf.border_in_pixels);
965
966 for (int mb_col = 0; mb_col < mi_params->mb_cols; ++mb_col) {
967 int this_intra_error = firstpass_intra_prediction(
968 cpi, this_frame, &tile, mb_row, mb_col, recon_yoffset, recon_uvoffset,
969 fp_block_size, qindex, &stats);
970
971 if (!frame_is_intra_only(cm)) {
972 const int this_inter_error = firstpass_inter_prediction(
973 cpi, last_frame, golden_frame, alt_ref_frame, mb_row, mb_col,
974 recon_yoffset, recon_uvoffset, src_yoffset, alt_ref_frame_yoffset,
975 fp_block_size, this_intra_error, raw_motion_err_counts,
976 raw_motion_err_list, &best_ref_mv, &last_mv, &stats);
977 stats.coded_error += this_inter_error;
978 ++raw_motion_err_counts;
979 } else {
980 stats.sr_coded_error += this_intra_error;
981 stats.tr_coded_error += this_intra_error;
982 stats.coded_error += this_intra_error;
983 }
984
985 // Adjust to the next column of MBs.
986 x->plane[0].src.buf += fp_block_size_width;
987 x->plane[1].src.buf += uv_mb_height;
988 x->plane[2].src.buf += uv_mb_height;
989
990 recon_yoffset += fp_block_size_width;
991 src_yoffset += fp_block_size_width;
992 recon_uvoffset += uv_mb_height;
993 alt_ref_frame_yoffset += fp_block_size_width;
994 }
995 // Adjust to the next row of MBs.
996 x->plane[0].src.buf += fp_block_size_height * x->plane[0].src.stride -
997 fp_block_size_width * mi_params->mb_cols;
998 x->plane[1].src.buf += uv_mb_height * x->plane[1].src.stride -
999 uv_mb_height * mi_params->mb_cols;
1000 x->plane[2].src.buf += uv_mb_height * x->plane[1].src.stride -
1001 uv_mb_height * mi_params->mb_cols;
1002 }
1003 const double raw_err_stdev =
1004 raw_motion_error_stdev(raw_motion_err_list, raw_motion_err_counts);
1005 aom_free(raw_motion_err_list);
1006
1007 // Clamp the image start to rows/2. This number of rows is discarded top
1008 // and bottom as dead data so rows / 2 means the frame is blank.
1009 if ((stats.image_data_start_row > mi_params->mb_rows / 2) ||
1010 (stats.image_data_start_row == INVALID_ROW)) {
1011 stats.image_data_start_row = mi_params->mb_rows / 2;
1012 }
1013 // Exclude any image dead zone
1014 if (stats.image_data_start_row > 0) {
1015 stats.intra_skip_count =
1016 AOMMAX(0, stats.intra_skip_count -
1017 (stats.image_data_start_row * mi_params->mb_cols * 2));
1018 }
1019
1020 TWO_PASS *twopass = &cpi->twopass;
1021 const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) ? cpi->initial_mbs
1022 : mi_params->MBs;
1023 stats.intra_factor = stats.intra_factor / (double)num_mbs;
1024 stats.brightness_factor = stats.brightness_factor / (double)num_mbs;
1025 FIRSTPASS_STATS *this_frame_stats = twopass->stats_buf_ctx->stats_in_end;
1026 update_firstpass_stats(cpi, &stats, raw_err_stdev,
1027 current_frame->frame_number, ts_duration);
1028
1029 // Copy the previous Last Frame back into gf buffer if the prediction is good
1030 // enough... but also don't allow it to lag too far.
1031 if ((twopass->sr_update_lag > 3) ||
1032 ((current_frame->frame_number > 0) &&
1033 (this_frame_stats->pcnt_inter > 0.20) &&
1034 ((this_frame_stats->intra_error /
1035 DOUBLE_DIVIDE_CHECK(this_frame_stats->coded_error)) > 2.0))) {
1036 if (golden_frame != NULL) {
1037 assign_frame_buffer_p(
1038 &cm->ref_frame_map[get_ref_frame_map_idx(cm, GOLDEN_FRAME)],
1039 cm->ref_frame_map[get_ref_frame_map_idx(cm, LAST_FRAME)]);
1040 }
1041 twopass->sr_update_lag = 1;
1042 } else {
1043 ++twopass->sr_update_lag;
1044 }
1045
1046 aom_extend_frame_borders(this_frame, num_planes);
1047
1048 // The frame we just compressed now becomes the last frame.
1049 assign_frame_buffer_p(
1050 &cm->ref_frame_map[get_ref_frame_map_idx(cm, LAST_FRAME)], cm->cur_frame);
1051
1052 // Special case for the first frame. Copy into the GF buffer as a second
1053 // reference.
1054 if (current_frame->frame_number == 0 &&
1055 get_ref_frame_map_idx(cm, GOLDEN_FRAME) != INVALID_IDX) {
1056 assign_frame_buffer_p(
1057 &cm->ref_frame_map[get_ref_frame_map_idx(cm, GOLDEN_FRAME)],
1058 cm->ref_frame_map[get_ref_frame_map_idx(cm, LAST_FRAME)]);
1059 }
1060
1061 print_reconstruction_frame(last_frame, current_frame->frame_number,
1062 /*do_print=*/0);
1063
1064 ++current_frame->frame_number;
1065 }
1066