• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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