blob: d119268c9d632cb85a549f4e6644424178f38ec8 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Urvang Joshi8a02d762016-07-28 15:51:12 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Urvang Joshi8a02d762016-07-28 15:51:12 -07004 * 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.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <limits.h>
13#include <math.h>
14#include <stdio.h>
15
Yaowu Xuf883b422016-08-30 14:01:10 -070016#include "./aom_config.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070017
18#include "av1/common/alloccommon.h"
19#if CONFIG_CLPF
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +020020#include "aom/aom_image.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021#include "av1/common/clpf.h"
Steinar Midtskogend06588a2016-05-06 13:48:20 +020022#include "av1/encoder/clpf_rdo.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070023#endif
24#if CONFIG_DERING
25#include "av1/common/dering.h"
26#endif // CONFIG_DERING
27#include "av1/common/filter.h"
28#include "av1/common/idct.h"
29#include "av1/common/reconinter.h"
30#include "av1/common/reconintra.h"
31#include "av1/common/tile_common.h"
32
33#include "av1/encoder/aq_complexity.h"
34#include "av1/encoder/aq_cyclicrefresh.h"
35#include "av1/encoder/aq_variance.h"
36#include "av1/encoder/bitstream.h"
37#if CONFIG_ANS
Alex Converse1ac1ae72016-09-17 15:11:16 -070038#include "aom_dsp/buf_ans.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070039#endif
40#include "av1/encoder/context_tree.h"
41#include "av1/encoder/encodeframe.h"
42#include "av1/encoder/encodemv.h"
43#include "av1/encoder/encoder.h"
44#include "av1/encoder/ethread.h"
45#include "av1/encoder/firstpass.h"
46#include "av1/encoder/mbgraph.h"
47#include "av1/encoder/picklpf.h"
48#if CONFIG_LOOP_RESTORATION
49#include "av1/encoder/pickrst.h"
50#endif // CONFIG_LOOP_RESTORATION
51#include "av1/encoder/ratectrl.h"
52#include "av1/encoder/rd.h"
53#include "av1/encoder/resize.h"
54#include "av1/encoder/segmentation.h"
55#include "av1/encoder/speed_features.h"
56#include "av1/encoder/temporal_filter.h"
57
Yaowu Xuf883b422016-08-30 14:01:10 -070058#include "./av1_rtcd.h"
59#include "./aom_dsp_rtcd.h"
60#include "./aom_scale_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070061#include "aom_dsp/psnr.h"
62#if CONFIG_INTERNAL_STATS
63#include "aom_dsp/ssim.h"
64#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070065#include "aom_dsp/aom_dsp_common.h"
66#include "aom_dsp/aom_filter.h"
Jingning Han1aab8182016-06-03 11:09:06 -070067#include "aom_ports/aom_timer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070068#include "aom_ports/mem.h"
69#include "aom_ports/system_state.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070070#include "aom_scale/aom_scale.h"
Angie Chiang6062a8b2016-09-21 16:01:04 -070071#if CONFIG_BITSTREAM_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -070072#include "aom_util/debug_util.h"
Angie Chiang6062a8b2016-09-21 16:01:04 -070073#endif // CONFIG_BITSTREAM_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -070074
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -080075#if CONFIG_ENTROPY_STATS
76FRAME_COUNTS aggregate_fc;
77#endif // CONFIG_ENTROPY_STATS
78
Yaowu Xuc27fc142016-08-22 16:08:15 -070079#define AM_SEGMENT_ID_INACTIVE 7
80#define AM_SEGMENT_ID_ACTIVE 0
81
82#define SHARP_FILTER_QTHRESH 0 /* Q threshold for 8-tap sharp filter */
83
84#define ALTREF_HIGH_PRECISION_MV 1 // Whether to use high precision mv
85 // for altref computation.
86#define HIGH_PRECISION_MV_QTHRESH 200 // Q threshold for high precision
87 // mv. Choose a very high value for
88 // now so that HIGH_PRECISION is always
89 // chosen.
90// #define OUTPUT_YUV_REC
91#ifdef OUTPUT_YUV_DENOISED
92FILE *yuv_denoised_file = NULL;
93#endif
94#ifdef OUTPUT_YUV_SKINMAP
95FILE *yuv_skinmap_file = NULL;
96#endif
97#ifdef OUTPUT_YUV_REC
98FILE *yuv_rec_file;
99#define FILE_NAME_LEN 100
100#endif
101
102#if 0
103FILE *framepsnr;
104FILE *kf_list;
105FILE *keyfile;
106#endif
107
Urvang Joshib5ed3502016-10-17 16:38:05 -0700108#if CONFIG_INTERNAL_STATS
109typedef enum { Y, U, V, ALL } STAT_TYPE;
110#endif // CONFIG_INTERNAL_STATS
111
Yaowu Xuf883b422016-08-30 14:01:10 -0700112static INLINE void Scale2Ratio(AOM_SCALING mode, int *hr, int *hs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700113 switch (mode) {
114 case NORMAL:
115 *hr = 1;
116 *hs = 1;
117 break;
118 case FOURFIVE:
119 *hr = 4;
120 *hs = 5;
121 break;
122 case THREEFIVE:
123 *hr = 3;
124 *hs = 5;
125 break;
126 case ONETWO:
127 *hr = 1;
128 *hs = 2;
129 break;
130 default:
131 *hr = 1;
132 *hs = 1;
133 assert(0);
134 break;
135 }
136}
137
138// Mark all inactive blocks as active. Other segmentation features may be set
139// so memset cannot be used, instead only inactive blocks should be reset.
Yaowu Xuf883b422016-08-30 14:01:10 -0700140static void suppress_active_map(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700141 unsigned char *const seg_map = cpi->segmentation_map;
142 int i;
143 if (cpi->active_map.enabled || cpi->active_map.update)
144 for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
145 if (seg_map[i] == AM_SEGMENT_ID_INACTIVE)
146 seg_map[i] = AM_SEGMENT_ID_ACTIVE;
147}
148
Yaowu Xuf883b422016-08-30 14:01:10 -0700149static void apply_active_map(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700150 struct segmentation *const seg = &cpi->common.seg;
151 unsigned char *const seg_map = cpi->segmentation_map;
152 const unsigned char *const active_map = cpi->active_map.map;
153 int i;
154
155 assert(AM_SEGMENT_ID_ACTIVE == CR_SEGMENT_ID_BASE);
156
157 if (frame_is_intra_only(&cpi->common)) {
158 cpi->active_map.enabled = 0;
159 cpi->active_map.update = 1;
160 }
161
162 if (cpi->active_map.update) {
163 if (cpi->active_map.enabled) {
164 for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
165 if (seg_map[i] == AM_SEGMENT_ID_ACTIVE) seg_map[i] = active_map[i];
Yaowu Xuf883b422016-08-30 14:01:10 -0700166 av1_enable_segmentation(seg);
167 av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
168 av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700169 // Setting the data to -MAX_LOOP_FILTER will result in the computed loop
170 // filter level being zero regardless of the value of seg->abs_delta.
Yaowu Xuf883b422016-08-30 14:01:10 -0700171 av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF,
172 -MAX_LOOP_FILTER);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700173 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700174 av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
175 av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700176 if (seg->enabled) {
177 seg->update_data = 1;
178 seg->update_map = 1;
179 }
180 }
181 cpi->active_map.update = 0;
182 }
183}
184
Yaowu Xuf883b422016-08-30 14:01:10 -0700185int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
186 int cols) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700187 if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols) {
188 unsigned char *const active_map_8x8 = cpi->active_map.map;
189 const int mi_rows = cpi->common.mi_rows;
190 const int mi_cols = cpi->common.mi_cols;
191 cpi->active_map.update = 1;
192 if (new_map_16x16) {
193 int r, c;
194 for (r = 0; r < mi_rows; ++r) {
195 for (c = 0; c < mi_cols; ++c) {
196 active_map_8x8[r * mi_cols + c] =
197 new_map_16x16[(r >> 1) * cols + (c >> 1)]
198 ? AM_SEGMENT_ID_ACTIVE
199 : AM_SEGMENT_ID_INACTIVE;
200 }
201 }
202 cpi->active_map.enabled = 1;
203 } else {
204 cpi->active_map.enabled = 0;
205 }
206 return 0;
207 } else {
208 return -1;
209 }
210}
211
Yaowu Xuf883b422016-08-30 14:01:10 -0700212int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
213 int cols) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700214 if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols &&
215 new_map_16x16) {
216 unsigned char *const seg_map_8x8 = cpi->segmentation_map;
217 const int mi_rows = cpi->common.mi_rows;
218 const int mi_cols = cpi->common.mi_cols;
219 memset(new_map_16x16, !cpi->active_map.enabled, rows * cols);
220 if (cpi->active_map.enabled) {
221 int r, c;
222 for (r = 0; r < mi_rows; ++r) {
223 for (c = 0; c < mi_cols; ++c) {
224 // Cyclic refresh segments are considered active despite not having
225 // AM_SEGMENT_ID_ACTIVE
226 new_map_16x16[(r >> 1) * cols + (c >> 1)] |=
227 seg_map_8x8[r * mi_cols + c] != AM_SEGMENT_ID_INACTIVE;
228 }
229 }
230 }
231 return 0;
232 } else {
233 return -1;
234 }
235}
236
Yaowu Xuf883b422016-08-30 14:01:10 -0700237void av1_set_high_precision_mv(AV1_COMP *cpi, int allow_high_precision_mv) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700238 MACROBLOCK *const mb = &cpi->td.mb;
239 cpi->common.allow_high_precision_mv = allow_high_precision_mv;
240
241#if CONFIG_REF_MV
242 if (cpi->common.allow_high_precision_mv) {
243 int i;
244 for (i = 0; i < NMV_CONTEXTS; ++i) {
245 mb->mv_cost_stack[i] = mb->nmvcost_hp[i];
246 mb->mvsadcost = mb->nmvsadcost_hp;
247 }
248 } else {
249 int i;
250 for (i = 0; i < NMV_CONTEXTS; ++i) {
251 mb->mv_cost_stack[i] = mb->nmvcost[i];
252 mb->mvsadcost = mb->nmvsadcost;
253 }
254 }
255#else
256 if (cpi->common.allow_high_precision_mv) {
257 mb->mvcost = mb->nmvcost_hp;
258 mb->mvsadcost = mb->nmvcost_hp;
259 } else {
260 mb->mvcost = mb->nmvcost;
261 mb->mvsadcost = mb->nmvcost;
262 }
263#endif
264}
265
Yaowu Xuf883b422016-08-30 14:01:10 -0700266static BLOCK_SIZE select_sb_size(const AV1_COMP *const cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700267#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -0700268 if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_64X64)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700269 return BLOCK_64X64;
270
Yaowu Xuf883b422016-08-30 14:01:10 -0700271 if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_128X128)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700272 return BLOCK_128X128;
273
Yaowu Xuf883b422016-08-30 14:01:10 -0700274 assert(cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_DYNAMIC);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700275
276 assert(IMPLIES(cpi->common.tile_cols > 1,
277 cpi->common.tile_width % MAX_MIB_SIZE == 0));
278 assert(IMPLIES(cpi->common.tile_rows > 1,
279 cpi->common.tile_height % MAX_MIB_SIZE == 0));
280
281 // TODO(any): Possibly could improve this with a heuristic.
282 return BLOCK_128X128;
283#else
284 (void)cpi;
285 return BLOCK_64X64;
286#endif // CONFIG_EXT_PARTITION
287}
288
Yaowu Xuf883b422016-08-30 14:01:10 -0700289static void setup_frame(AV1_COMP *cpi) {
290 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700291 // Set up entropy context depending on frame type. The decoder mandates
292 // the use of the default context, index 0, for keyframes and inter
293 // frames where the error_resilient_mode or intra_only flag is set. For
294 // other inter-frames the encoder currently uses only two contexts;
295 // context 1 for ALTREF frames and context 0 for the others.
296 if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700297 av1_setup_past_independence(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700298 } else {
299#if CONFIG_EXT_REFS
300 const GF_GROUP *gf_group = &cpi->twopass.gf_group;
301 if (gf_group->rf_level[gf_group->index] == GF_ARF_LOW)
302 cm->frame_context_idx = EXT_ARF_FRAME;
303 else if (cpi->refresh_alt_ref_frame)
304 cm->frame_context_idx = ARF_FRAME;
305#else
306 if (cpi->refresh_alt_ref_frame) cm->frame_context_idx = ARF_FRAME;
Zoe Liu6cfaff92016-10-18 17:12:11 -0700307#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700308 else if (cpi->rc.is_src_frame_alt_ref)
309 cm->frame_context_idx = OVERLAY_FRAME;
310 else if (cpi->refresh_golden_frame)
311 cm->frame_context_idx = GLD_FRAME;
312#if CONFIG_EXT_REFS
313 else if (cpi->refresh_bwd_ref_frame)
314 cm->frame_context_idx = BRF_FRAME;
Zoe Liu6cfaff92016-10-18 17:12:11 -0700315#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700316 else
317 cm->frame_context_idx = REGULAR_FRAME;
318 }
319
320 if (cm->frame_type == KEY_FRAME) {
321 cpi->refresh_golden_frame = 1;
322 cpi->refresh_alt_ref_frame = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -0700323 av1_zero(cpi->interp_filter_selected);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700324 } else {
325 *cm->fc = cm->frame_contexts[cm->frame_context_idx];
Yaowu Xuf883b422016-08-30 14:01:10 -0700326 av1_zero(cpi->interp_filter_selected[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700327 }
328
329 cpi->vaq_refresh = 0;
330
331 set_sb_size(cm, select_sb_size(cpi));
332}
333
Yaowu Xuf883b422016-08-30 14:01:10 -0700334static void av1_enc_setup_mi(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700335 int i;
336 cm->mi = cm->mip + cm->mi_stride + 1;
337 memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip));
338 cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
339 // Clear top border row
340 memset(cm->prev_mip, 0, sizeof(*cm->prev_mip) * cm->mi_stride);
341 // Clear left border column
342 for (i = 1; i < cm->mi_rows + 1; ++i)
343 memset(&cm->prev_mip[i * cm->mi_stride], 0, sizeof(*cm->prev_mip));
344
345 cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
346 cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;
347
348 memset(cm->mi_grid_base, 0,
349 cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mi_grid_base));
350}
351
Yaowu Xuf883b422016-08-30 14:01:10 -0700352static int av1_enc_alloc_mi(AV1_COMMON *cm, int mi_size) {
353 cm->mip = aom_calloc(mi_size, sizeof(*cm->mip));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700354 if (!cm->mip) return 1;
Yaowu Xuf883b422016-08-30 14:01:10 -0700355 cm->prev_mip = aom_calloc(mi_size, sizeof(*cm->prev_mip));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700356 if (!cm->prev_mip) return 1;
357 cm->mi_alloc_size = mi_size;
358
Yaowu Xuf883b422016-08-30 14:01:10 -0700359 cm->mi_grid_base = (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700360 if (!cm->mi_grid_base) return 1;
361 cm->prev_mi_grid_base =
Yaowu Xuf883b422016-08-30 14:01:10 -0700362 (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700363 if (!cm->prev_mi_grid_base) return 1;
364
365 return 0;
366}
367
Yaowu Xuf883b422016-08-30 14:01:10 -0700368static void av1_enc_free_mi(AV1_COMMON *cm) {
369 aom_free(cm->mip);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700370 cm->mip = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700371 aom_free(cm->prev_mip);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700372 cm->prev_mip = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700373 aom_free(cm->mi_grid_base);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700374 cm->mi_grid_base = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700375 aom_free(cm->prev_mi_grid_base);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700376 cm->prev_mi_grid_base = NULL;
377}
378
Yaowu Xuf883b422016-08-30 14:01:10 -0700379static void av1_swap_mi_and_prev_mi(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700380 // Current mip will be the prev_mip for the next frame.
381 MODE_INFO **temp_base = cm->prev_mi_grid_base;
382 MODE_INFO *temp = cm->prev_mip;
383 cm->prev_mip = cm->mip;
384 cm->mip = temp;
385
386 // Update the upper left visible macroblock ptrs.
387 cm->mi = cm->mip + cm->mi_stride + 1;
388 cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
389
390 cm->prev_mi_grid_base = cm->mi_grid_base;
391 cm->mi_grid_base = temp_base;
392 cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
393 cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;
394}
395
Yaowu Xuf883b422016-08-30 14:01:10 -0700396void av1_initialize_enc(void) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700397 static volatile int init_done = 0;
398
399 if (!init_done) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700400 av1_rtcd();
401 aom_dsp_rtcd();
402 aom_scale_rtcd();
403 av1_init_intra_predictors();
404 av1_init_me_luts();
405 av1_rc_init_minq_luts();
406 av1_entropy_mv_init();
407 av1_encode_token_init();
Yaowu Xuc27fc142016-08-22 16:08:15 -0700408#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700409 av1_init_wedge_masks();
Yaowu Xuc27fc142016-08-22 16:08:15 -0700410#endif
411 init_done = 1;
412 }
413}
414
Yaowu Xuf883b422016-08-30 14:01:10 -0700415static void dealloc_compressor_data(AV1_COMP *cpi) {
416 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700417 int i;
418
Yaowu Xuf883b422016-08-30 14:01:10 -0700419 aom_free(cpi->mbmi_ext_base);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700420 cpi->mbmi_ext_base = NULL;
421
Yushin Cho77bba8d2016-11-04 16:36:56 -0700422#if CONFIG_PVQ
423 if (cpi->oxcf.pass != 1) {
424 const int tile_cols = 1 << cm->log2_tile_cols;
425 const int tile_rows = 1 << cm->log2_tile_rows;
426 int tile_col, tile_row;
427
428 for (tile_row = 0; tile_row < tile_rows; ++tile_row)
429 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
430 TileDataEnc *tile_data =
431 &cpi->tile_data[tile_row * tile_cols + tile_col];
432 aom_free(tile_data->pvq_q.buf);
433 }
434 }
435#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700436 aom_free(cpi->tile_data);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700437 cpi->tile_data = NULL;
438
439 // Delete sementation map
Yaowu Xuf883b422016-08-30 14:01:10 -0700440 aom_free(cpi->segmentation_map);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700441 cpi->segmentation_map = NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700442
Yaowu Xuf883b422016-08-30 14:01:10 -0700443 av1_cyclic_refresh_free(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700444 cpi->cyclic_refresh = NULL;
445
Yaowu Xuf883b422016-08-30 14:01:10 -0700446 aom_free(cpi->active_map.map);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700447 cpi->active_map.map = NULL;
448
449 // Free up-sampled reference buffers.
450 for (i = 0; i < (REF_FRAMES + 1); i++)
Yaowu Xuf883b422016-08-30 14:01:10 -0700451 aom_free_frame_buffer(&cpi->upsampled_ref_bufs[i].buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700452
Yaowu Xuf883b422016-08-30 14:01:10 -0700453 av1_free_ref_frame_buffers(cm->buffer_pool);
454 av1_free_context_buffers(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700455
Yaowu Xuf883b422016-08-30 14:01:10 -0700456 aom_free_frame_buffer(&cpi->last_frame_uf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700457#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -0700458 av1_free_restoration_buffers(cm);
Debargha Mukherjee999d2f62016-12-15 13:23:21 -0800459 aom_free_frame_buffer(&cpi->last_frame_db);
460 aom_free_frame_buffer(&cpi->trial_frame_rst);
461 aom_free(cpi->extra_rstbuf);
Debargha Mukherjeea43a2d92017-01-03 15:14:57 -0800462 for (i = 0; i < MAX_MB_PLANE; ++i)
463 av1_free_restoration_struct(&cpi->rst_search[i]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700464#endif // CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -0700465 aom_free_frame_buffer(&cpi->scaled_source);
466 aom_free_frame_buffer(&cpi->scaled_last_source);
467 aom_free_frame_buffer(&cpi->alt_ref_buffer);
468 av1_lookahead_destroy(cpi->lookahead);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700469
Yaowu Xuf883b422016-08-30 14:01:10 -0700470 aom_free(cpi->tile_tok[0][0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700471 cpi->tile_tok[0][0] = 0;
472
Yaowu Xuf883b422016-08-30 14:01:10 -0700473 av1_free_pc_tree(&cpi->td);
474 av1_free_var_tree(&cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700475
Urvang Joshib100db72016-10-12 16:28:56 -0700476#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700477 if (cpi->common.allow_screen_content_tools)
Yaowu Xuf883b422016-08-30 14:01:10 -0700478 aom_free(cpi->td.mb.palette_buffer);
Urvang Joshib100db72016-10-12 16:28:56 -0700479#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700480
481 if (cpi->source_diff_var != NULL) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700482 aom_free(cpi->source_diff_var);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700483 cpi->source_diff_var = NULL;
484 }
485#if CONFIG_ANS
Alex Converse1ac1ae72016-09-17 15:11:16 -0700486 aom_buf_ans_free(&cpi->buf_ans);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700487#endif // CONFIG_ANS
488}
489
Yaowu Xuf883b422016-08-30 14:01:10 -0700490static void save_coding_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700491 CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xuf883b422016-08-30 14:01:10 -0700492 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700493#if CONFIG_REF_MV
494 int i;
495#endif
496
497// Stores a snapshot of key state variables which can subsequently be
Yaowu Xuf883b422016-08-30 14:01:10 -0700498// restored with a call to av1_restore_coding_context. These functions are
499// intended for use in a re-code loop in av1_compress_frame where the
Yaowu Xuc27fc142016-08-22 16:08:15 -0700500// quantizer value is adjusted between loop iterations.
501#if CONFIG_REF_MV
502 for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700503 av1_copy(cc->nmv_vec_cost[i], cpi->td.mb.nmv_vec_cost[i]);
Urvang Joshibffc0b52016-07-25 13:38:49 -0700504 av1_copy(cc->nmv_costs, cpi->nmv_costs);
505 av1_copy(cc->nmv_costs_hp, cpi->nmv_costs_hp);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700506 }
507#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700508 av1_copy(cc->nmvjointcost, cpi->td.mb.nmvjointcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700509#endif
510
Urvang Joshibffc0b52016-07-25 13:38:49 -0700511 av1_copy(cc->nmvcosts, cpi->nmvcosts);
512 av1_copy(cc->nmvcosts_hp, cpi->nmvcosts_hp);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700513
Yaowu Xuf883b422016-08-30 14:01:10 -0700514 av1_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
515 av1_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700516
517 cc->fc = *cm->fc;
518}
519
Yaowu Xuf883b422016-08-30 14:01:10 -0700520static void restore_coding_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700521 CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xuf883b422016-08-30 14:01:10 -0700522 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700523#if CONFIG_REF_MV
524 int i;
525#endif
526
527// Restore key state variables to the snapshot state stored in the
Yaowu Xuf883b422016-08-30 14:01:10 -0700528// previous call to av1_save_coding_context.
Yaowu Xuc27fc142016-08-22 16:08:15 -0700529#if CONFIG_REF_MV
530 for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700531 av1_copy(cpi->td.mb.nmv_vec_cost[i], cc->nmv_vec_cost[i]);
Urvang Joshibffc0b52016-07-25 13:38:49 -0700532 av1_copy(cpi->nmv_costs, cc->nmv_costs);
533 av1_copy(cpi->nmv_costs_hp, cc->nmv_costs_hp);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700534 }
535#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700536 av1_copy(cpi->td.mb.nmvjointcost, cc->nmvjointcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700537#endif
538
Urvang Joshibffc0b52016-07-25 13:38:49 -0700539 av1_copy(cpi->nmvcosts, cc->nmvcosts);
540 av1_copy(cpi->nmvcosts_hp, cc->nmvcosts_hp);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700541
Yaowu Xuf883b422016-08-30 14:01:10 -0700542 av1_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
543 av1_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700544
545 *cm->fc = cc->fc;
546}
547
Yaowu Xuf883b422016-08-30 14:01:10 -0700548static void configure_static_seg_features(AV1_COMP *cpi) {
549 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700550 const RATE_CONTROL *const rc = &cpi->rc;
551 struct segmentation *const seg = &cm->seg;
552
553 int high_q = (int)(rc->avg_q > 48.0);
554 int qi_delta;
555
556 // Disable and clear down for KF
557 if (cm->frame_type == KEY_FRAME) {
558 // Clear down the global segmentation map
559 memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
560 seg->update_map = 0;
561 seg->update_data = 0;
562 cpi->static_mb_pct = 0;
563
564 // Disable segmentation
Yaowu Xuf883b422016-08-30 14:01:10 -0700565 av1_disable_segmentation(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700566
567 // Clear down the segment features.
Yaowu Xuf883b422016-08-30 14:01:10 -0700568 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700569 } else if (cpi->refresh_alt_ref_frame) {
570 // If this is an alt ref frame
571 // Clear down the global segmentation map
572 memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
573 seg->update_map = 0;
574 seg->update_data = 0;
575 cpi->static_mb_pct = 0;
576
577 // Disable segmentation and individual segment features by default
Yaowu Xuf883b422016-08-30 14:01:10 -0700578 av1_disable_segmentation(seg);
579 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700580
581 // Scan frames from current to arf frame.
582 // This function re-enables segmentation if appropriate.
Yaowu Xuf883b422016-08-30 14:01:10 -0700583 av1_update_mbgraph_stats(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700584
585 // If segmentation was enabled set those features needed for the
586 // arf itself.
587 if (seg->enabled) {
588 seg->update_map = 1;
589 seg->update_data = 1;
590
591 qi_delta =
Yaowu Xuf883b422016-08-30 14:01:10 -0700592 av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875, cm->bit_depth);
593 av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
594 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700595
Yaowu Xuf883b422016-08-30 14:01:10 -0700596 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
597 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700598
599 // Where relevant assume segment data is delta data
600 seg->abs_delta = SEGMENT_DELTADATA;
601 }
602 } else if (seg->enabled) {
603 // All other frames if segmentation has been enabled
604
605 // First normal frame in a valid gf or alt ref group
606 if (rc->frames_since_golden == 0) {
607 // Set up segment features for normal frames in an arf group
608 if (rc->source_alt_ref_active) {
609 seg->update_map = 0;
610 seg->update_data = 1;
611 seg->abs_delta = SEGMENT_DELTADATA;
612
Yaowu Xuf883b422016-08-30 14:01:10 -0700613 qi_delta =
614 av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125, cm->bit_depth);
615 av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
616 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700617
Yaowu Xuf883b422016-08-30 14:01:10 -0700618 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
619 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700620
621 // Segment coding disabled for compred testing
622 if (high_q || (cpi->static_mb_pct == 100)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700623 av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
624 av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
625 av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700626 }
627 } else {
628 // Disable segmentation and clear down features if alt ref
629 // is not active for this group
630
Yaowu Xuf883b422016-08-30 14:01:10 -0700631 av1_disable_segmentation(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700632
633 memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
634
635 seg->update_map = 0;
636 seg->update_data = 0;
637
Yaowu Xuf883b422016-08-30 14:01:10 -0700638 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700639 }
640 } else if (rc->is_src_frame_alt_ref) {
641 // Special case where we are coding over the top of a previous
642 // alt ref frame.
643 // Segment coding disabled for compred testing
644
645 // Enable ref frame features for segment 0 as well
Yaowu Xuf883b422016-08-30 14:01:10 -0700646 av1_enable_segfeature(seg, 0, SEG_LVL_REF_FRAME);
647 av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700648
649 // All mbs should use ALTREF_FRAME
Yaowu Xuf883b422016-08-30 14:01:10 -0700650 av1_clear_segdata(seg, 0, SEG_LVL_REF_FRAME);
651 av1_set_segdata(seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
652 av1_clear_segdata(seg, 1, SEG_LVL_REF_FRAME);
653 av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700654
655 // Skip all MBs if high Q (0,0 mv and skip coeffs)
656 if (high_q) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700657 av1_enable_segfeature(seg, 0, SEG_LVL_SKIP);
658 av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700659 }
660 // Enable data update
661 seg->update_data = 1;
662 } else {
663 // All other frames.
664
665 // No updates.. leave things as they are.
666 seg->update_map = 0;
667 seg->update_data = 0;
668 }
669 }
670}
671
Yaowu Xuf883b422016-08-30 14:01:10 -0700672static void update_reference_segmentation_map(AV1_COMP *cpi) {
673 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700674 MODE_INFO **mi_8x8_ptr = cm->mi_grid_visible;
675 uint8_t *cache_ptr = cm->last_frame_seg_map;
676 int row, col;
677
678 for (row = 0; row < cm->mi_rows; row++) {
679 MODE_INFO **mi_8x8 = mi_8x8_ptr;
680 uint8_t *cache = cache_ptr;
681 for (col = 0; col < cm->mi_cols; col++, mi_8x8++, cache++)
682 cache[0] = mi_8x8[0]->mbmi.segment_id;
683 mi_8x8_ptr += cm->mi_stride;
684 cache_ptr += cm->mi_cols;
685 }
686}
687
Yaowu Xuf883b422016-08-30 14:01:10 -0700688static void alloc_raw_frame_buffers(AV1_COMP *cpi) {
689 AV1_COMMON *cm = &cpi->common;
690 const AV1EncoderConfig *oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700691
692 if (!cpi->lookahead)
Yaowu Xuf883b422016-08-30 14:01:10 -0700693 cpi->lookahead = av1_lookahead_init(oxcf->width, oxcf->height,
694 cm->subsampling_x, cm->subsampling_y,
695#if CONFIG_AOM_HIGHBITDEPTH
696 cm->use_highbitdepth,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700697#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700698 oxcf->lag_in_frames);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700699 if (!cpi->lookahead)
Yaowu Xuf883b422016-08-30 14:01:10 -0700700 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700701 "Failed to allocate lag buffers");
702
703 // TODO(agrange) Check if ARF is enabled and skip allocation if not.
Yaowu Xuf883b422016-08-30 14:01:10 -0700704 if (aom_realloc_frame_buffer(&cpi->alt_ref_buffer, oxcf->width, oxcf->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700705 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700706#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700707 cm->use_highbitdepth,
708#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700709 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
710 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700711 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700712 "Failed to allocate altref buffer");
713}
714
Yaowu Xuf883b422016-08-30 14:01:10 -0700715static void alloc_util_frame_buffers(AV1_COMP *cpi) {
Debargha Mukherjeea43a2d92017-01-03 15:14:57 -0800716#if CONFIG_LOOP_RESTORATION
717 int i;
718#endif // CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -0700719 AV1_COMMON *const cm = &cpi->common;
720 if (aom_realloc_frame_buffer(&cpi->last_frame_uf, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700721 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700722#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700723 cm->use_highbitdepth,
724#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700725 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
726 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700727 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700728 "Failed to allocate last frame buffer");
729
730#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -0700731 if (aom_realloc_frame_buffer(&cpi->last_frame_db, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700732 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700733#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700734 cm->use_highbitdepth,
735#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700736 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
737 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700738 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700739 "Failed to allocate last frame deblocked buffer");
Debargha Mukherjee999d2f62016-12-15 13:23:21 -0800740 if (aom_realloc_frame_buffer(&cpi->trial_frame_rst, cm->width, cm->height,
741 cm->subsampling_x, cm->subsampling_y,
742#if CONFIG_AOM_HIGHBITDEPTH
743 cm->use_highbitdepth,
744#endif
745 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
746 NULL, NULL))
Debargha Mukherjee874d36d2016-12-14 16:53:17 -0800747 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Debargha Mukherjee999d2f62016-12-15 13:23:21 -0800748 "Failed to allocate trial restored frame buffer");
David Barker3a0df182016-12-21 10:44:52 +0000749 cpi->extra_rstbuf =
750 (uint8_t *)aom_realloc(cpi->extra_rstbuf, RESTORATION_EXTBUF_SIZE);
Debargha Mukherjee999d2f62016-12-15 13:23:21 -0800751 if (!cpi->extra_rstbuf)
752 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
753 "Failed to allocate extra rstbuf for restoration");
Debargha Mukherjeea43a2d92017-01-03 15:14:57 -0800754 for (i = 0; i < MAX_MB_PLANE; ++i)
755 av1_alloc_restoration_struct(&cpi->rst_search[i], cm->width, cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700756#endif // CONFIG_LOOP_RESTORATION
757
Yaowu Xuf883b422016-08-30 14:01:10 -0700758 if (aom_realloc_frame_buffer(&cpi->scaled_source, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700759 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700760#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700761 cm->use_highbitdepth,
762#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700763 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
764 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700765 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700766 "Failed to allocate scaled source buffer");
767
Yaowu Xuf883b422016-08-30 14:01:10 -0700768 if (aom_realloc_frame_buffer(&cpi->scaled_last_source, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700769 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700770#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700771 cm->use_highbitdepth,
772#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700773 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
774 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700775 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700776 "Failed to allocate scaled last source buffer");
777}
778
Yaowu Xuf883b422016-08-30 14:01:10 -0700779static int alloc_context_buffers_ext(AV1_COMP *cpi) {
780 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700781 int mi_size = cm->mi_cols * cm->mi_rows;
782
Yaowu Xuf883b422016-08-30 14:01:10 -0700783 cpi->mbmi_ext_base = aom_calloc(mi_size, sizeof(*cpi->mbmi_ext_base));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700784 if (!cpi->mbmi_ext_base) return 1;
785
786 return 0;
787}
788
Yaowu Xuf883b422016-08-30 14:01:10 -0700789void av1_alloc_compressor_data(AV1_COMP *cpi) {
790 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700791
Yaowu Xuf883b422016-08-30 14:01:10 -0700792 av1_alloc_context_buffers(cm, cm->width, cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700793
794 alloc_context_buffers_ext(cpi);
795
Yaowu Xuf883b422016-08-30 14:01:10 -0700796 aom_free(cpi->tile_tok[0][0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700797
798 {
799 unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols);
800 CHECK_MEM_ERROR(cm, cpi->tile_tok[0][0],
Yaowu Xuf883b422016-08-30 14:01:10 -0700801 aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
Alex Converseeb780e72016-12-13 12:46:41 -0800802#if CONFIG_ANS && !ANS_MAX_SYMBOLS
803 aom_buf_ans_alloc(&cpi->buf_ans, &cm->error, (int)tokens);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700804#endif // CONFIG_ANS
805 }
806
Yaowu Xuf883b422016-08-30 14:01:10 -0700807 av1_setup_pc_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700808}
809
Yaowu Xuf883b422016-08-30 14:01:10 -0700810void av1_new_framerate(AV1_COMP *cpi, double framerate) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700811 cpi->framerate = framerate < 0.1 ? 30 : framerate;
Yaowu Xuf883b422016-08-30 14:01:10 -0700812 av1_rc_update_framerate(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700813}
814
Yaowu Xuf883b422016-08-30 14:01:10 -0700815static void set_tile_info(AV1_COMP *cpi) {
816 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700817
818#if CONFIG_EXT_TILE
819#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -0700820 if (cpi->oxcf.superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700821 cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 32);
822 cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 32);
823 cm->tile_width <<= MAX_MIB_SIZE_LOG2;
824 cm->tile_height <<= MAX_MIB_SIZE_LOG2;
825 } else {
826 cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
827 cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
828 cm->tile_width <<= MAX_MIB_SIZE_LOG2 - 1;
829 cm->tile_height <<= MAX_MIB_SIZE_LOG2 - 1;
830 }
831#else
832 cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
833 cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
834 cm->tile_width <<= MAX_MIB_SIZE_LOG2;
835 cm->tile_height <<= MAX_MIB_SIZE_LOG2;
836#endif // CONFIG_EXT_PARTITION
837
Yaowu Xuf883b422016-08-30 14:01:10 -0700838 cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
839 cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700840
841 assert(cm->tile_width >> MAX_MIB_SIZE <= 32);
842 assert(cm->tile_height >> MAX_MIB_SIZE <= 32);
843
844 // Get the number of tiles
845 cm->tile_cols = 1;
846 while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
847
848 cm->tile_rows = 1;
849 while (cm->tile_rows * cm->tile_height < cm->mi_rows) ++cm->tile_rows;
850#else
851 int min_log2_tile_cols, max_log2_tile_cols;
Yaowu Xuf883b422016-08-30 14:01:10 -0700852 av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700853
854 cm->log2_tile_cols =
855 clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols);
856 cm->log2_tile_rows = cpi->oxcf.tile_rows;
857
858 cm->tile_cols = 1 << cm->log2_tile_cols;
859 cm->tile_rows = 1 << cm->log2_tile_rows;
860
861 cm->tile_width = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
862 cm->tile_width >>= cm->log2_tile_cols;
863 cm->tile_height = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
864 cm->tile_height >>= cm->log2_tile_rows;
865
866 // round to integer multiples of max superblock size
867 cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
868 cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
869#endif // CONFIG_EXT_TILE
Ryan Lei7386eda2016-12-08 21:08:31 -0800870
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800871#if CONFIG_LOOPFILTERING_ACROSS_TILES
Ryan Lei7386eda2016-12-08 21:08:31 -0800872 cm->loop_filter_across_tiles_enabled =
873 cpi->oxcf.loop_filter_across_tiles_enabled;
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800874#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Yaowu Xuc27fc142016-08-22 16:08:15 -0700875}
876
Yaowu Xuf883b422016-08-30 14:01:10 -0700877static void update_frame_size(AV1_COMP *cpi) {
878 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700879 MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
880
Yaowu Xuf883b422016-08-30 14:01:10 -0700881 av1_set_mb_mi(cm, cm->width, cm->height);
882 av1_init_context_buffers(cm);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700883 av1_init_macroblockd(cm, xd,
884#if CONFIG_PVQ
885 NULL,
886#endif
887 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700888 memset(cpi->mbmi_ext_base, 0,
889 cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base));
890
891 set_tile_info(cpi);
892}
893
Yaowu Xuf883b422016-08-30 14:01:10 -0700894static void init_buffer_indices(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700895#if CONFIG_EXT_REFS
896 int fb_idx;
897 for (fb_idx = 0; fb_idx < LAST_REF_FRAMES; ++fb_idx)
898 cpi->lst_fb_idxes[fb_idx] = fb_idx;
899 cpi->gld_fb_idx = LAST_REF_FRAMES;
900 cpi->bwd_fb_idx = LAST_REF_FRAMES + 1;
901 cpi->alt_fb_idx = LAST_REF_FRAMES + 2;
902 for (fb_idx = 0; fb_idx < MAX_EXT_ARFS + 1; ++fb_idx)
903 cpi->arf_map[fb_idx] = LAST_REF_FRAMES + 2 + fb_idx;
904#else
905 cpi->lst_fb_idx = 0;
906 cpi->gld_fb_idx = 1;
907 cpi->alt_fb_idx = 2;
908#endif // CONFIG_EXT_REFS
909}
910
Yaowu Xuf883b422016-08-30 14:01:10 -0700911static void init_config(struct AV1_COMP *cpi, AV1EncoderConfig *oxcf) {
912 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700913
914 cpi->oxcf = *oxcf;
915 cpi->framerate = oxcf->init_framerate;
916
917 cm->profile = oxcf->profile;
918 cm->bit_depth = oxcf->bit_depth;
Yaowu Xuf883b422016-08-30 14:01:10 -0700919#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700920 cm->use_highbitdepth = oxcf->use_highbitdepth;
921#endif
922 cm->color_space = oxcf->color_space;
923 cm->color_range = oxcf->color_range;
924
925 cm->width = oxcf->width;
926 cm->height = oxcf->height;
Yaowu Xuf883b422016-08-30 14:01:10 -0700927 av1_alloc_compressor_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700928
929 // Single thread case: use counts in common.
930 cpi->td.counts = &cm->counts;
931
932 // change includes all joint functionality
Yaowu Xuf883b422016-08-30 14:01:10 -0700933 av1_change_config(cpi, oxcf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700934
935 cpi->static_mb_pct = 0;
936 cpi->ref_frame_flags = 0;
937
938 init_buffer_indices(cpi);
939}
940
941static void set_rc_buffer_sizes(RATE_CONTROL *rc,
Yaowu Xuf883b422016-08-30 14:01:10 -0700942 const AV1EncoderConfig *oxcf) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700943 const int64_t bandwidth = oxcf->target_bandwidth;
944 const int64_t starting = oxcf->starting_buffer_level_ms;
945 const int64_t optimal = oxcf->optimal_buffer_level_ms;
946 const int64_t maximum = oxcf->maximum_buffer_size_ms;
947
948 rc->starting_buffer_level = starting * bandwidth / 1000;
949 rc->optimal_buffer_level =
950 (optimal == 0) ? bandwidth / 8 : optimal * bandwidth / 1000;
951 rc->maximum_buffer_size =
952 (maximum == 0) ? bandwidth / 8 : maximum * bandwidth / 1000;
953}
954
Yaowu Xuf883b422016-08-30 14:01:10 -0700955#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700956#define HIGHBD_BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
957 cpi->fn_ptr[BT].sdf = SDF; \
958 cpi->fn_ptr[BT].sdaf = SDAF; \
959 cpi->fn_ptr[BT].vf = VF; \
960 cpi->fn_ptr[BT].svf = SVF; \
961 cpi->fn_ptr[BT].svaf = SVAF; \
962 cpi->fn_ptr[BT].sdx3f = SDX3F; \
963 cpi->fn_ptr[BT].sdx8f = SDX8F; \
964 cpi->fn_ptr[BT].sdx4df = SDX4DF;
965
966#define MAKE_BFP_SAD_WRAPPER(fnname) \
967 static unsigned int fnname##_bits8(const uint8_t *src_ptr, \
968 int source_stride, \
969 const uint8_t *ref_ptr, int ref_stride) { \
970 return fnname(src_ptr, source_stride, ref_ptr, ref_stride); \
971 } \
972 static unsigned int fnname##_bits10( \
973 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
974 int ref_stride) { \
975 return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 2; \
976 } \
977 static unsigned int fnname##_bits12( \
978 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
979 int ref_stride) { \
980 return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 4; \
981 }
982
983#define MAKE_BFP_SADAVG_WRAPPER(fnname) \
984 static unsigned int fnname##_bits8( \
985 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
986 int ref_stride, const uint8_t *second_pred) { \
987 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred); \
988 } \
989 static unsigned int fnname##_bits10( \
990 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
991 int ref_stride, const uint8_t *second_pred) { \
992 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \
993 2; \
994 } \
995 static unsigned int fnname##_bits12( \
996 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
997 int ref_stride, const uint8_t *second_pred) { \
998 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \
999 4; \
1000 }
1001
1002#define MAKE_BFP_SAD3_WRAPPER(fnname) \
1003 static void fnname##_bits8(const uint8_t *src_ptr, int source_stride, \
1004 const uint8_t *ref_ptr, int ref_stride, \
1005 unsigned int *sad_array) { \
1006 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1007 } \
1008 static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
1009 const uint8_t *ref_ptr, int ref_stride, \
1010 unsigned int *sad_array) { \
1011 int i; \
1012 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1013 for (i = 0; i < 3; i++) sad_array[i] >>= 2; \
1014 } \
1015 static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
1016 const uint8_t *ref_ptr, int ref_stride, \
1017 unsigned int *sad_array) { \
1018 int i; \
1019 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1020 for (i = 0; i < 3; i++) sad_array[i] >>= 4; \
1021 }
1022
1023#define MAKE_BFP_SAD8_WRAPPER(fnname) \
1024 static void fnname##_bits8(const uint8_t *src_ptr, int source_stride, \
1025 const uint8_t *ref_ptr, int ref_stride, \
1026 unsigned int *sad_array) { \
1027 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1028 } \
1029 static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
1030 const uint8_t *ref_ptr, int ref_stride, \
1031 unsigned int *sad_array) { \
1032 int i; \
1033 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1034 for (i = 0; i < 8; i++) sad_array[i] >>= 2; \
1035 } \
1036 static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
1037 const uint8_t *ref_ptr, int ref_stride, \
1038 unsigned int *sad_array) { \
1039 int i; \
1040 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1041 for (i = 0; i < 8; i++) sad_array[i] >>= 4; \
1042 }
1043#define MAKE_BFP_SAD4D_WRAPPER(fnname) \
1044 static void fnname##_bits8(const uint8_t *src_ptr, int source_stride, \
1045 const uint8_t *const ref_ptr[], int ref_stride, \
1046 unsigned int *sad_array) { \
1047 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1048 } \
1049 static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
1050 const uint8_t *const ref_ptr[], int ref_stride, \
1051 unsigned int *sad_array) { \
1052 int i; \
1053 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1054 for (i = 0; i < 4; i++) sad_array[i] >>= 2; \
1055 } \
1056 static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
1057 const uint8_t *const ref_ptr[], int ref_stride, \
1058 unsigned int *sad_array) { \
1059 int i; \
1060 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1061 for (i = 0; i < 4; i++) sad_array[i] >>= 4; \
1062 }
1063
1064#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001065MAKE_BFP_SAD_WRAPPER(aom_highbd_sad128x128)
1066MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad128x128_avg)
1067MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad128x128x3)
1068MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad128x128x8)
1069MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad128x128x4d)
1070MAKE_BFP_SAD_WRAPPER(aom_highbd_sad128x64)
1071MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad128x64_avg)
1072MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad128x64x4d)
1073MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x128)
1074MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x128_avg)
1075MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x128x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001076#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001077MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x16)
1078MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x16_avg)
1079MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x16x4d)
1080MAKE_BFP_SAD_WRAPPER(aom_highbd_sad16x32)
1081MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad16x32_avg)
1082MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad16x32x4d)
1083MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x32)
1084MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x32_avg)
1085MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x32x4d)
1086MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x64)
1087MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x64_avg)
1088MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x64x4d)
1089MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x32)
1090MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x32_avg)
1091MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad32x32x3)
1092MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad32x32x8)
1093MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x32x4d)
1094MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x64)
1095MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x64_avg)
1096MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad64x64x3)
1097MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad64x64x8)
1098MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x64x4d)
1099MAKE_BFP_SAD_WRAPPER(aom_highbd_sad16x16)
1100MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad16x16_avg)
1101MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad16x16x3)
1102MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad16x16x8)
1103MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad16x16x4d)
1104MAKE_BFP_SAD_WRAPPER(aom_highbd_sad16x8)
1105MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad16x8_avg)
1106MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad16x8x3)
1107MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad16x8x8)
1108MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad16x8x4d)
1109MAKE_BFP_SAD_WRAPPER(aom_highbd_sad8x16)
1110MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad8x16_avg)
1111MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad8x16x3)
1112MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad8x16x8)
1113MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad8x16x4d)
1114MAKE_BFP_SAD_WRAPPER(aom_highbd_sad8x8)
1115MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad8x8_avg)
1116MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad8x8x3)
1117MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad8x8x8)
1118MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad8x8x4d)
1119MAKE_BFP_SAD_WRAPPER(aom_highbd_sad8x4)
1120MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad8x4_avg)
1121MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad8x4x8)
1122MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad8x4x4d)
1123MAKE_BFP_SAD_WRAPPER(aom_highbd_sad4x8)
1124MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad4x8_avg)
1125MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad4x8x8)
1126MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad4x8x4d)
1127MAKE_BFP_SAD_WRAPPER(aom_highbd_sad4x4)
1128MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad4x4_avg)
1129MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad4x4x3)
1130MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad4x4x8)
1131MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad4x4x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001132
1133#if CONFIG_EXT_INTER
1134#define HIGHBD_MBFP(BT, MSDF, MVF, MSVF) \
1135 cpi->fn_ptr[BT].msdf = MSDF; \
1136 cpi->fn_ptr[BT].mvf = MVF; \
1137 cpi->fn_ptr[BT].msvf = MSVF;
1138
1139#define MAKE_MBFP_SAD_WRAPPER(fnname) \
1140 static unsigned int fnname##_bits8( \
1141 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1142 int ref_stride, const uint8_t *m, int m_stride) { \
1143 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, m, m_stride); \
1144 } \
1145 static unsigned int fnname##_bits10( \
1146 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1147 int ref_stride, const uint8_t *m, int m_stride) { \
1148 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, m, m_stride) >> \
1149 2; \
1150 } \
1151 static unsigned int fnname##_bits12( \
1152 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1153 int ref_stride, const uint8_t *m, int m_stride) { \
1154 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, m, m_stride) >> \
1155 4; \
1156 }
1157
1158#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001159MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad128x128)
1160MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad128x64)
1161MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001162#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001163MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad64x64)
1164MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad64x32)
1165MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad32x64)
1166MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad32x32)
1167MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad32x16)
1168MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad16x32)
1169MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad16x16)
1170MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad16x8)
1171MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad8x16)
1172MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad8x8)
1173MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad8x4)
1174MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad4x8)
1175MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001176#endif // CONFIG_EXT_INTER
1177
Yue Chencb60b182016-10-13 15:18:22 -07001178#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001179#define HIGHBD_OBFP(BT, OSDF, OVF, OSVF) \
1180 cpi->fn_ptr[BT].osdf = OSDF; \
1181 cpi->fn_ptr[BT].ovf = OVF; \
1182 cpi->fn_ptr[BT].osvf = OSVF;
1183
1184#define MAKE_OBFP_SAD_WRAPPER(fnname) \
1185 static unsigned int fnname##_bits8(const uint8_t *ref, int ref_stride, \
1186 const int32_t *wsrc, \
1187 const int32_t *msk) { \
1188 return fnname(ref, ref_stride, wsrc, msk); \
1189 } \
1190 static unsigned int fnname##_bits10(const uint8_t *ref, int ref_stride, \
1191 const int32_t *wsrc, \
1192 const int32_t *msk) { \
1193 return fnname(ref, ref_stride, wsrc, msk) >> 2; \
1194 } \
1195 static unsigned int fnname##_bits12(const uint8_t *ref, int ref_stride, \
1196 const int32_t *wsrc, \
1197 const int32_t *msk) { \
1198 return fnname(ref, ref_stride, wsrc, msk) >> 4; \
1199 }
1200
1201#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001202MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad128x128)
1203MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad128x64)
1204MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001205#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001206MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad64x64)
1207MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad64x32)
1208MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad32x64)
1209MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad32x32)
1210MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad32x16)
1211MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad16x32)
1212MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad16x16)
1213MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad16x8)
1214MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad8x16)
1215MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad8x8)
1216MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad8x4)
1217MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad4x8)
1218MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad4x4)
Yue Chencb60b182016-10-13 15:18:22 -07001219#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001220
Yaowu Xuf883b422016-08-30 14:01:10 -07001221static void highbd_set_var_fns(AV1_COMP *const cpi) {
1222 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001223 if (cm->use_highbitdepth) {
1224 switch (cm->bit_depth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001225 case AOM_BITS_8:
1226 HIGHBD_BFP(BLOCK_32X16, aom_highbd_sad32x16_bits8,
1227 aom_highbd_sad32x16_avg_bits8, aom_highbd_8_variance32x16,
1228 aom_highbd_8_sub_pixel_variance32x16,
1229 aom_highbd_8_sub_pixel_avg_variance32x16, NULL, NULL,
1230 aom_highbd_sad32x16x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001231
Yaowu Xuf883b422016-08-30 14:01:10 -07001232 HIGHBD_BFP(BLOCK_16X32, aom_highbd_sad16x32_bits8,
1233 aom_highbd_sad16x32_avg_bits8, aom_highbd_8_variance16x32,
1234 aom_highbd_8_sub_pixel_variance16x32,
1235 aom_highbd_8_sub_pixel_avg_variance16x32, NULL, NULL,
1236 aom_highbd_sad16x32x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001237
Yaowu Xuf883b422016-08-30 14:01:10 -07001238 HIGHBD_BFP(BLOCK_64X32, aom_highbd_sad64x32_bits8,
1239 aom_highbd_sad64x32_avg_bits8, aom_highbd_8_variance64x32,
1240 aom_highbd_8_sub_pixel_variance64x32,
1241 aom_highbd_8_sub_pixel_avg_variance64x32, NULL, NULL,
1242 aom_highbd_sad64x32x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001243
Yaowu Xuf883b422016-08-30 14:01:10 -07001244 HIGHBD_BFP(BLOCK_32X64, aom_highbd_sad32x64_bits8,
1245 aom_highbd_sad32x64_avg_bits8, aom_highbd_8_variance32x64,
1246 aom_highbd_8_sub_pixel_variance32x64,
1247 aom_highbd_8_sub_pixel_avg_variance32x64, NULL, NULL,
1248 aom_highbd_sad32x64x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001249
Yaowu Xuf883b422016-08-30 14:01:10 -07001250 HIGHBD_BFP(BLOCK_32X32, aom_highbd_sad32x32_bits8,
1251 aom_highbd_sad32x32_avg_bits8, aom_highbd_8_variance32x32,
1252 aom_highbd_8_sub_pixel_variance32x32,
1253 aom_highbd_8_sub_pixel_avg_variance32x32,
1254 aom_highbd_sad32x32x3_bits8, aom_highbd_sad32x32x8_bits8,
1255 aom_highbd_sad32x32x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001256
Yaowu Xuf883b422016-08-30 14:01:10 -07001257 HIGHBD_BFP(BLOCK_64X64, aom_highbd_sad64x64_bits8,
1258 aom_highbd_sad64x64_avg_bits8, aom_highbd_8_variance64x64,
1259 aom_highbd_8_sub_pixel_variance64x64,
1260 aom_highbd_8_sub_pixel_avg_variance64x64,
1261 aom_highbd_sad64x64x3_bits8, aom_highbd_sad64x64x8_bits8,
1262 aom_highbd_sad64x64x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001263
Yaowu Xuf883b422016-08-30 14:01:10 -07001264 HIGHBD_BFP(BLOCK_16X16, aom_highbd_sad16x16_bits8,
1265 aom_highbd_sad16x16_avg_bits8, aom_highbd_8_variance16x16,
1266 aom_highbd_8_sub_pixel_variance16x16,
1267 aom_highbd_8_sub_pixel_avg_variance16x16,
1268 aom_highbd_sad16x16x3_bits8, aom_highbd_sad16x16x8_bits8,
1269 aom_highbd_sad16x16x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001270
1271 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001272 BLOCK_16X8, aom_highbd_sad16x8_bits8, aom_highbd_sad16x8_avg_bits8,
1273 aom_highbd_8_variance16x8, aom_highbd_8_sub_pixel_variance16x8,
1274 aom_highbd_8_sub_pixel_avg_variance16x8, aom_highbd_sad16x8x3_bits8,
1275 aom_highbd_sad16x8x8_bits8, aom_highbd_sad16x8x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001276
1277 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001278 BLOCK_8X16, aom_highbd_sad8x16_bits8, aom_highbd_sad8x16_avg_bits8,
1279 aom_highbd_8_variance8x16, aom_highbd_8_sub_pixel_variance8x16,
1280 aom_highbd_8_sub_pixel_avg_variance8x16, aom_highbd_sad8x16x3_bits8,
1281 aom_highbd_sad8x16x8_bits8, aom_highbd_sad8x16x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001282
1283 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001284 BLOCK_8X8, aom_highbd_sad8x8_bits8, aom_highbd_sad8x8_avg_bits8,
1285 aom_highbd_8_variance8x8, aom_highbd_8_sub_pixel_variance8x8,
1286 aom_highbd_8_sub_pixel_avg_variance8x8, aom_highbd_sad8x8x3_bits8,
1287 aom_highbd_sad8x8x8_bits8, aom_highbd_sad8x8x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001288
Yaowu Xuf883b422016-08-30 14:01:10 -07001289 HIGHBD_BFP(BLOCK_8X4, aom_highbd_sad8x4_bits8,
1290 aom_highbd_sad8x4_avg_bits8, aom_highbd_8_variance8x4,
1291 aom_highbd_8_sub_pixel_variance8x4,
1292 aom_highbd_8_sub_pixel_avg_variance8x4, NULL,
1293 aom_highbd_sad8x4x8_bits8, aom_highbd_sad8x4x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001294
Yaowu Xuf883b422016-08-30 14:01:10 -07001295 HIGHBD_BFP(BLOCK_4X8, aom_highbd_sad4x8_bits8,
1296 aom_highbd_sad4x8_avg_bits8, aom_highbd_8_variance4x8,
1297 aom_highbd_8_sub_pixel_variance4x8,
1298 aom_highbd_8_sub_pixel_avg_variance4x8, NULL,
1299 aom_highbd_sad4x8x8_bits8, aom_highbd_sad4x8x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001300
1301 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001302 BLOCK_4X4, aom_highbd_sad4x4_bits8, aom_highbd_sad4x4_avg_bits8,
1303 aom_highbd_8_variance4x4, aom_highbd_8_sub_pixel_variance4x4,
1304 aom_highbd_8_sub_pixel_avg_variance4x4, aom_highbd_sad4x4x3_bits8,
1305 aom_highbd_sad4x4x8_bits8, aom_highbd_sad4x4x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001306
Jingning Hancc5bdf42016-12-19 11:14:30 -08001307#if CONFIG_CB4X4
1308 HIGHBD_BFP(BLOCK_2X2, NULL, NULL, aom_highbd_8_variance2x2, NULL, NULL,
1309 NULL, NULL, NULL)
1310 HIGHBD_BFP(BLOCK_4X2, NULL, NULL, aom_highbd_8_variance4x2, NULL, NULL,
1311 NULL, NULL, NULL)
1312 HIGHBD_BFP(BLOCK_2X4, NULL, NULL, aom_highbd_8_variance2x4, NULL, NULL,
1313 NULL, NULL, NULL)
1314#endif
1315
Yaowu Xuc27fc142016-08-22 16:08:15 -07001316#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001317 HIGHBD_BFP(BLOCK_128X128, aom_highbd_sad128x128_bits8,
1318 aom_highbd_sad128x128_avg_bits8,
1319 aom_highbd_8_variance128x128,
1320 aom_highbd_8_sub_pixel_variance128x128,
1321 aom_highbd_8_sub_pixel_avg_variance128x128,
1322 aom_highbd_sad128x128x3_bits8, aom_highbd_sad128x128x8_bits8,
1323 aom_highbd_sad128x128x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001324
Yaowu Xuf883b422016-08-30 14:01:10 -07001325 HIGHBD_BFP(BLOCK_128X64, aom_highbd_sad128x64_bits8,
1326 aom_highbd_sad128x64_avg_bits8, aom_highbd_8_variance128x64,
1327 aom_highbd_8_sub_pixel_variance128x64,
1328 aom_highbd_8_sub_pixel_avg_variance128x64, NULL, NULL,
1329 aom_highbd_sad128x64x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001330
Yaowu Xuf883b422016-08-30 14:01:10 -07001331 HIGHBD_BFP(BLOCK_64X128, aom_highbd_sad64x128_bits8,
1332 aom_highbd_sad64x128_avg_bits8, aom_highbd_8_variance64x128,
1333 aom_highbd_8_sub_pixel_variance64x128,
1334 aom_highbd_8_sub_pixel_avg_variance64x128, NULL, NULL,
1335 aom_highbd_sad64x128x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001336#endif // CONFIG_EXT_PARTITION
1337
1338#if CONFIG_EXT_INTER
1339#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001340 HIGHBD_MBFP(BLOCK_128X128, aom_highbd_masked_sad128x128_bits8,
1341 aom_highbd_masked_variance128x128,
1342 aom_highbd_masked_sub_pixel_variance128x128)
1343 HIGHBD_MBFP(BLOCK_128X64, aom_highbd_masked_sad128x64_bits8,
1344 aom_highbd_masked_variance128x64,
1345 aom_highbd_masked_sub_pixel_variance128x64)
1346 HIGHBD_MBFP(BLOCK_64X128, aom_highbd_masked_sad64x128_bits8,
1347 aom_highbd_masked_variance64x128,
1348 aom_highbd_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001349#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001350 HIGHBD_MBFP(BLOCK_64X64, aom_highbd_masked_sad64x64_bits8,
1351 aom_highbd_masked_variance64x64,
1352 aom_highbd_masked_sub_pixel_variance64x64)
1353 HIGHBD_MBFP(BLOCK_64X32, aom_highbd_masked_sad64x32_bits8,
1354 aom_highbd_masked_variance64x32,
1355 aom_highbd_masked_sub_pixel_variance64x32)
1356 HIGHBD_MBFP(BLOCK_32X64, aom_highbd_masked_sad32x64_bits8,
1357 aom_highbd_masked_variance32x64,
1358 aom_highbd_masked_sub_pixel_variance32x64)
1359 HIGHBD_MBFP(BLOCK_32X32, aom_highbd_masked_sad32x32_bits8,
1360 aom_highbd_masked_variance32x32,
1361 aom_highbd_masked_sub_pixel_variance32x32)
1362 HIGHBD_MBFP(BLOCK_32X16, aom_highbd_masked_sad32x16_bits8,
1363 aom_highbd_masked_variance32x16,
1364 aom_highbd_masked_sub_pixel_variance32x16)
1365 HIGHBD_MBFP(BLOCK_16X32, aom_highbd_masked_sad16x32_bits8,
1366 aom_highbd_masked_variance16x32,
1367 aom_highbd_masked_sub_pixel_variance16x32)
1368 HIGHBD_MBFP(BLOCK_16X16, aom_highbd_masked_sad16x16_bits8,
1369 aom_highbd_masked_variance16x16,
1370 aom_highbd_masked_sub_pixel_variance16x16)
1371 HIGHBD_MBFP(BLOCK_8X16, aom_highbd_masked_sad8x16_bits8,
1372 aom_highbd_masked_variance8x16,
1373 aom_highbd_masked_sub_pixel_variance8x16)
1374 HIGHBD_MBFP(BLOCK_16X8, aom_highbd_masked_sad16x8_bits8,
1375 aom_highbd_masked_variance16x8,
1376 aom_highbd_masked_sub_pixel_variance16x8)
1377 HIGHBD_MBFP(BLOCK_8X8, aom_highbd_masked_sad8x8_bits8,
1378 aom_highbd_masked_variance8x8,
1379 aom_highbd_masked_sub_pixel_variance8x8)
1380 HIGHBD_MBFP(BLOCK_4X8, aom_highbd_masked_sad4x8_bits8,
1381 aom_highbd_masked_variance4x8,
1382 aom_highbd_masked_sub_pixel_variance4x8)
1383 HIGHBD_MBFP(BLOCK_8X4, aom_highbd_masked_sad8x4_bits8,
1384 aom_highbd_masked_variance8x4,
1385 aom_highbd_masked_sub_pixel_variance8x4)
1386 HIGHBD_MBFP(BLOCK_4X4, aom_highbd_masked_sad4x4_bits8,
1387 aom_highbd_masked_variance4x4,
1388 aom_highbd_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001389#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07001390#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001391#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001392 HIGHBD_OBFP(BLOCK_128X128, aom_highbd_obmc_sad128x128_bits8,
1393 aom_highbd_obmc_variance128x128,
1394 aom_highbd_obmc_sub_pixel_variance128x128)
1395 HIGHBD_OBFP(BLOCK_128X64, aom_highbd_obmc_sad128x64_bits8,
1396 aom_highbd_obmc_variance128x64,
1397 aom_highbd_obmc_sub_pixel_variance128x64)
1398 HIGHBD_OBFP(BLOCK_64X128, aom_highbd_obmc_sad64x128_bits8,
1399 aom_highbd_obmc_variance64x128,
1400 aom_highbd_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001401#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001402 HIGHBD_OBFP(BLOCK_64X64, aom_highbd_obmc_sad64x64_bits8,
1403 aom_highbd_obmc_variance64x64,
1404 aom_highbd_obmc_sub_pixel_variance64x64)
1405 HIGHBD_OBFP(BLOCK_64X32, aom_highbd_obmc_sad64x32_bits8,
1406 aom_highbd_obmc_variance64x32,
1407 aom_highbd_obmc_sub_pixel_variance64x32)
1408 HIGHBD_OBFP(BLOCK_32X64, aom_highbd_obmc_sad32x64_bits8,
1409 aom_highbd_obmc_variance32x64,
1410 aom_highbd_obmc_sub_pixel_variance32x64)
1411 HIGHBD_OBFP(BLOCK_32X32, aom_highbd_obmc_sad32x32_bits8,
1412 aom_highbd_obmc_variance32x32,
1413 aom_highbd_obmc_sub_pixel_variance32x32)
1414 HIGHBD_OBFP(BLOCK_32X16, aom_highbd_obmc_sad32x16_bits8,
1415 aom_highbd_obmc_variance32x16,
1416 aom_highbd_obmc_sub_pixel_variance32x16)
1417 HIGHBD_OBFP(BLOCK_16X32, aom_highbd_obmc_sad16x32_bits8,
1418 aom_highbd_obmc_variance16x32,
1419 aom_highbd_obmc_sub_pixel_variance16x32)
1420 HIGHBD_OBFP(BLOCK_16X16, aom_highbd_obmc_sad16x16_bits8,
1421 aom_highbd_obmc_variance16x16,
1422 aom_highbd_obmc_sub_pixel_variance16x16)
1423 HIGHBD_OBFP(BLOCK_8X16, aom_highbd_obmc_sad8x16_bits8,
1424 aom_highbd_obmc_variance8x16,
1425 aom_highbd_obmc_sub_pixel_variance8x16)
1426 HIGHBD_OBFP(BLOCK_16X8, aom_highbd_obmc_sad16x8_bits8,
1427 aom_highbd_obmc_variance16x8,
1428 aom_highbd_obmc_sub_pixel_variance16x8)
1429 HIGHBD_OBFP(BLOCK_8X8, aom_highbd_obmc_sad8x8_bits8,
1430 aom_highbd_obmc_variance8x8,
1431 aom_highbd_obmc_sub_pixel_variance8x8)
1432 HIGHBD_OBFP(BLOCK_4X8, aom_highbd_obmc_sad4x8_bits8,
1433 aom_highbd_obmc_variance4x8,
1434 aom_highbd_obmc_sub_pixel_variance4x8)
1435 HIGHBD_OBFP(BLOCK_8X4, aom_highbd_obmc_sad8x4_bits8,
1436 aom_highbd_obmc_variance8x4,
1437 aom_highbd_obmc_sub_pixel_variance8x4)
1438 HIGHBD_OBFP(BLOCK_4X4, aom_highbd_obmc_sad4x4_bits8,
1439 aom_highbd_obmc_variance4x4,
1440 aom_highbd_obmc_sub_pixel_variance4x4)
Yue Chencb60b182016-10-13 15:18:22 -07001441#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001442 break;
1443
Yaowu Xuf883b422016-08-30 14:01:10 -07001444 case AOM_BITS_10:
1445 HIGHBD_BFP(BLOCK_32X16, aom_highbd_sad32x16_bits10,
1446 aom_highbd_sad32x16_avg_bits10, aom_highbd_10_variance32x16,
1447 aom_highbd_10_sub_pixel_variance32x16,
1448 aom_highbd_10_sub_pixel_avg_variance32x16, NULL, NULL,
1449 aom_highbd_sad32x16x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001450
Yaowu Xuf883b422016-08-30 14:01:10 -07001451 HIGHBD_BFP(BLOCK_16X32, aom_highbd_sad16x32_bits10,
1452 aom_highbd_sad16x32_avg_bits10, aom_highbd_10_variance16x32,
1453 aom_highbd_10_sub_pixel_variance16x32,
1454 aom_highbd_10_sub_pixel_avg_variance16x32, NULL, NULL,
1455 aom_highbd_sad16x32x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001456
Yaowu Xuf883b422016-08-30 14:01:10 -07001457 HIGHBD_BFP(BLOCK_64X32, aom_highbd_sad64x32_bits10,
1458 aom_highbd_sad64x32_avg_bits10, aom_highbd_10_variance64x32,
1459 aom_highbd_10_sub_pixel_variance64x32,
1460 aom_highbd_10_sub_pixel_avg_variance64x32, NULL, NULL,
1461 aom_highbd_sad64x32x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001462
Yaowu Xuf883b422016-08-30 14:01:10 -07001463 HIGHBD_BFP(BLOCK_32X64, aom_highbd_sad32x64_bits10,
1464 aom_highbd_sad32x64_avg_bits10, aom_highbd_10_variance32x64,
1465 aom_highbd_10_sub_pixel_variance32x64,
1466 aom_highbd_10_sub_pixel_avg_variance32x64, NULL, NULL,
1467 aom_highbd_sad32x64x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001468
Yaowu Xuf883b422016-08-30 14:01:10 -07001469 HIGHBD_BFP(BLOCK_32X32, aom_highbd_sad32x32_bits10,
1470 aom_highbd_sad32x32_avg_bits10, aom_highbd_10_variance32x32,
1471 aom_highbd_10_sub_pixel_variance32x32,
1472 aom_highbd_10_sub_pixel_avg_variance32x32,
1473 aom_highbd_sad32x32x3_bits10, aom_highbd_sad32x32x8_bits10,
1474 aom_highbd_sad32x32x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001475
Yaowu Xuf883b422016-08-30 14:01:10 -07001476 HIGHBD_BFP(BLOCK_64X64, aom_highbd_sad64x64_bits10,
1477 aom_highbd_sad64x64_avg_bits10, aom_highbd_10_variance64x64,
1478 aom_highbd_10_sub_pixel_variance64x64,
1479 aom_highbd_10_sub_pixel_avg_variance64x64,
1480 aom_highbd_sad64x64x3_bits10, aom_highbd_sad64x64x8_bits10,
1481 aom_highbd_sad64x64x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001482
Yaowu Xuf883b422016-08-30 14:01:10 -07001483 HIGHBD_BFP(BLOCK_16X16, aom_highbd_sad16x16_bits10,
1484 aom_highbd_sad16x16_avg_bits10, aom_highbd_10_variance16x16,
1485 aom_highbd_10_sub_pixel_variance16x16,
1486 aom_highbd_10_sub_pixel_avg_variance16x16,
1487 aom_highbd_sad16x16x3_bits10, aom_highbd_sad16x16x8_bits10,
1488 aom_highbd_sad16x16x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001489
Yaowu Xuf883b422016-08-30 14:01:10 -07001490 HIGHBD_BFP(BLOCK_16X8, aom_highbd_sad16x8_bits10,
1491 aom_highbd_sad16x8_avg_bits10, aom_highbd_10_variance16x8,
1492 aom_highbd_10_sub_pixel_variance16x8,
1493 aom_highbd_10_sub_pixel_avg_variance16x8,
1494 aom_highbd_sad16x8x3_bits10, aom_highbd_sad16x8x8_bits10,
1495 aom_highbd_sad16x8x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001496
Yaowu Xuf883b422016-08-30 14:01:10 -07001497 HIGHBD_BFP(BLOCK_8X16, aom_highbd_sad8x16_bits10,
1498 aom_highbd_sad8x16_avg_bits10, aom_highbd_10_variance8x16,
1499 aom_highbd_10_sub_pixel_variance8x16,
1500 aom_highbd_10_sub_pixel_avg_variance8x16,
1501 aom_highbd_sad8x16x3_bits10, aom_highbd_sad8x16x8_bits10,
1502 aom_highbd_sad8x16x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001503
1504 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001505 BLOCK_8X8, aom_highbd_sad8x8_bits10, aom_highbd_sad8x8_avg_bits10,
1506 aom_highbd_10_variance8x8, aom_highbd_10_sub_pixel_variance8x8,
1507 aom_highbd_10_sub_pixel_avg_variance8x8, aom_highbd_sad8x8x3_bits10,
1508 aom_highbd_sad8x8x8_bits10, aom_highbd_sad8x8x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001509
Yaowu Xuf883b422016-08-30 14:01:10 -07001510 HIGHBD_BFP(BLOCK_8X4, aom_highbd_sad8x4_bits10,
1511 aom_highbd_sad8x4_avg_bits10, aom_highbd_10_variance8x4,
1512 aom_highbd_10_sub_pixel_variance8x4,
1513 aom_highbd_10_sub_pixel_avg_variance8x4, NULL,
1514 aom_highbd_sad8x4x8_bits10, aom_highbd_sad8x4x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001515
Yaowu Xuf883b422016-08-30 14:01:10 -07001516 HIGHBD_BFP(BLOCK_4X8, aom_highbd_sad4x8_bits10,
1517 aom_highbd_sad4x8_avg_bits10, aom_highbd_10_variance4x8,
1518 aom_highbd_10_sub_pixel_variance4x8,
1519 aom_highbd_10_sub_pixel_avg_variance4x8, NULL,
1520 aom_highbd_sad4x8x8_bits10, aom_highbd_sad4x8x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001521
1522 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001523 BLOCK_4X4, aom_highbd_sad4x4_bits10, aom_highbd_sad4x4_avg_bits10,
1524 aom_highbd_10_variance4x4, aom_highbd_10_sub_pixel_variance4x4,
1525 aom_highbd_10_sub_pixel_avg_variance4x4, aom_highbd_sad4x4x3_bits10,
1526 aom_highbd_sad4x4x8_bits10, aom_highbd_sad4x4x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001527
Jingning Hancc5bdf42016-12-19 11:14:30 -08001528#if CONFIG_CB4X4
1529 HIGHBD_BFP(BLOCK_2X2, NULL, NULL, aom_highbd_10_variance2x2, NULL, NULL,
1530 NULL, NULL, NULL)
1531 HIGHBD_BFP(BLOCK_4X2, NULL, NULL, aom_highbd_10_variance4x2, NULL, NULL,
1532 NULL, NULL, NULL)
1533 HIGHBD_BFP(BLOCK_2X4, NULL, NULL, aom_highbd_10_variance2x4, NULL, NULL,
1534 NULL, NULL, NULL)
1535#endif
1536
Yaowu Xuc27fc142016-08-22 16:08:15 -07001537#if CONFIG_EXT_PARTITION
1538 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001539 BLOCK_128X128, aom_highbd_sad128x128_bits10,
1540 aom_highbd_sad128x128_avg_bits10, aom_highbd_10_variance128x128,
1541 aom_highbd_10_sub_pixel_variance128x128,
1542 aom_highbd_10_sub_pixel_avg_variance128x128,
1543 aom_highbd_sad128x128x3_bits10, aom_highbd_sad128x128x8_bits10,
1544 aom_highbd_sad128x128x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001545
Yaowu Xuf883b422016-08-30 14:01:10 -07001546 HIGHBD_BFP(BLOCK_128X64, aom_highbd_sad128x64_bits10,
1547 aom_highbd_sad128x64_avg_bits10,
1548 aom_highbd_10_variance128x64,
1549 aom_highbd_10_sub_pixel_variance128x64,
1550 aom_highbd_10_sub_pixel_avg_variance128x64, NULL, NULL,
1551 aom_highbd_sad128x64x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001552
Yaowu Xuf883b422016-08-30 14:01:10 -07001553 HIGHBD_BFP(BLOCK_64X128, aom_highbd_sad64x128_bits10,
1554 aom_highbd_sad64x128_avg_bits10,
1555 aom_highbd_10_variance64x128,
1556 aom_highbd_10_sub_pixel_variance64x128,
1557 aom_highbd_10_sub_pixel_avg_variance64x128, NULL, NULL,
1558 aom_highbd_sad64x128x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001559#endif // CONFIG_EXT_PARTITION
1560
1561#if CONFIG_EXT_INTER
1562#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001563 HIGHBD_MBFP(BLOCK_128X128, aom_highbd_masked_sad128x128_bits10,
1564 aom_highbd_10_masked_variance128x128,
1565 aom_highbd_10_masked_sub_pixel_variance128x128)
1566 HIGHBD_MBFP(BLOCK_128X64, aom_highbd_masked_sad128x64_bits10,
1567 aom_highbd_10_masked_variance128x64,
1568 aom_highbd_10_masked_sub_pixel_variance128x64)
1569 HIGHBD_MBFP(BLOCK_64X128, aom_highbd_masked_sad64x128_bits10,
1570 aom_highbd_10_masked_variance64x128,
1571 aom_highbd_10_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001572#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001573 HIGHBD_MBFP(BLOCK_64X64, aom_highbd_masked_sad64x64_bits10,
1574 aom_highbd_10_masked_variance64x64,
1575 aom_highbd_10_masked_sub_pixel_variance64x64)
1576 HIGHBD_MBFP(BLOCK_64X32, aom_highbd_masked_sad64x32_bits10,
1577 aom_highbd_10_masked_variance64x32,
1578 aom_highbd_10_masked_sub_pixel_variance64x32)
1579 HIGHBD_MBFP(BLOCK_32X64, aom_highbd_masked_sad32x64_bits10,
1580 aom_highbd_10_masked_variance32x64,
1581 aom_highbd_10_masked_sub_pixel_variance32x64)
1582 HIGHBD_MBFP(BLOCK_32X32, aom_highbd_masked_sad32x32_bits10,
1583 aom_highbd_10_masked_variance32x32,
1584 aom_highbd_10_masked_sub_pixel_variance32x32)
1585 HIGHBD_MBFP(BLOCK_32X16, aom_highbd_masked_sad32x16_bits10,
1586 aom_highbd_10_masked_variance32x16,
1587 aom_highbd_10_masked_sub_pixel_variance32x16)
1588 HIGHBD_MBFP(BLOCK_16X32, aom_highbd_masked_sad16x32_bits10,
1589 aom_highbd_10_masked_variance16x32,
1590 aom_highbd_10_masked_sub_pixel_variance16x32)
1591 HIGHBD_MBFP(BLOCK_16X16, aom_highbd_masked_sad16x16_bits10,
1592 aom_highbd_10_masked_variance16x16,
1593 aom_highbd_10_masked_sub_pixel_variance16x16)
1594 HIGHBD_MBFP(BLOCK_8X16, aom_highbd_masked_sad8x16_bits10,
1595 aom_highbd_10_masked_variance8x16,
1596 aom_highbd_10_masked_sub_pixel_variance8x16)
1597 HIGHBD_MBFP(BLOCK_16X8, aom_highbd_masked_sad16x8_bits10,
1598 aom_highbd_10_masked_variance16x8,
1599 aom_highbd_10_masked_sub_pixel_variance16x8)
1600 HIGHBD_MBFP(BLOCK_8X8, aom_highbd_masked_sad8x8_bits10,
1601 aom_highbd_10_masked_variance8x8,
1602 aom_highbd_10_masked_sub_pixel_variance8x8)
1603 HIGHBD_MBFP(BLOCK_4X8, aom_highbd_masked_sad4x8_bits10,
1604 aom_highbd_10_masked_variance4x8,
1605 aom_highbd_10_masked_sub_pixel_variance4x8)
1606 HIGHBD_MBFP(BLOCK_8X4, aom_highbd_masked_sad8x4_bits10,
1607 aom_highbd_10_masked_variance8x4,
1608 aom_highbd_10_masked_sub_pixel_variance8x4)
1609 HIGHBD_MBFP(BLOCK_4X4, aom_highbd_masked_sad4x4_bits10,
1610 aom_highbd_10_masked_variance4x4,
1611 aom_highbd_10_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001612#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07001613#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001614#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001615 HIGHBD_OBFP(BLOCK_128X128, aom_highbd_obmc_sad128x128_bits10,
1616 aom_highbd_10_obmc_variance128x128,
1617 aom_highbd_10_obmc_sub_pixel_variance128x128)
1618 HIGHBD_OBFP(BLOCK_128X64, aom_highbd_obmc_sad128x64_bits10,
1619 aom_highbd_10_obmc_variance128x64,
1620 aom_highbd_10_obmc_sub_pixel_variance128x64)
1621 HIGHBD_OBFP(BLOCK_64X128, aom_highbd_obmc_sad64x128_bits10,
1622 aom_highbd_10_obmc_variance64x128,
1623 aom_highbd_10_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001624#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001625 HIGHBD_OBFP(BLOCK_64X64, aom_highbd_obmc_sad64x64_bits10,
1626 aom_highbd_10_obmc_variance64x64,
1627 aom_highbd_10_obmc_sub_pixel_variance64x64)
1628 HIGHBD_OBFP(BLOCK_64X32, aom_highbd_obmc_sad64x32_bits10,
1629 aom_highbd_10_obmc_variance64x32,
1630 aom_highbd_10_obmc_sub_pixel_variance64x32)
1631 HIGHBD_OBFP(BLOCK_32X64, aom_highbd_obmc_sad32x64_bits10,
1632 aom_highbd_10_obmc_variance32x64,
1633 aom_highbd_10_obmc_sub_pixel_variance32x64)
1634 HIGHBD_OBFP(BLOCK_32X32, aom_highbd_obmc_sad32x32_bits10,
1635 aom_highbd_10_obmc_variance32x32,
1636 aom_highbd_10_obmc_sub_pixel_variance32x32)
1637 HIGHBD_OBFP(BLOCK_32X16, aom_highbd_obmc_sad32x16_bits10,
1638 aom_highbd_10_obmc_variance32x16,
1639 aom_highbd_10_obmc_sub_pixel_variance32x16)
1640 HIGHBD_OBFP(BLOCK_16X32, aom_highbd_obmc_sad16x32_bits10,
1641 aom_highbd_10_obmc_variance16x32,
1642 aom_highbd_10_obmc_sub_pixel_variance16x32)
1643 HIGHBD_OBFP(BLOCK_16X16, aom_highbd_obmc_sad16x16_bits10,
1644 aom_highbd_10_obmc_variance16x16,
1645 aom_highbd_10_obmc_sub_pixel_variance16x16)
1646 HIGHBD_OBFP(BLOCK_8X16, aom_highbd_obmc_sad8x16_bits10,
1647 aom_highbd_10_obmc_variance8x16,
1648 aom_highbd_10_obmc_sub_pixel_variance8x16)
1649 HIGHBD_OBFP(BLOCK_16X8, aom_highbd_obmc_sad16x8_bits10,
1650 aom_highbd_10_obmc_variance16x8,
1651 aom_highbd_10_obmc_sub_pixel_variance16x8)
1652 HIGHBD_OBFP(BLOCK_8X8, aom_highbd_obmc_sad8x8_bits10,
1653 aom_highbd_10_obmc_variance8x8,
1654 aom_highbd_10_obmc_sub_pixel_variance8x8)
1655 HIGHBD_OBFP(BLOCK_4X8, aom_highbd_obmc_sad4x8_bits10,
1656 aom_highbd_10_obmc_variance4x8,
1657 aom_highbd_10_obmc_sub_pixel_variance4x8)
1658 HIGHBD_OBFP(BLOCK_8X4, aom_highbd_obmc_sad8x4_bits10,
1659 aom_highbd_10_obmc_variance8x4,
1660 aom_highbd_10_obmc_sub_pixel_variance8x4)
1661 HIGHBD_OBFP(BLOCK_4X4, aom_highbd_obmc_sad4x4_bits10,
1662 aom_highbd_10_obmc_variance4x4,
1663 aom_highbd_10_obmc_sub_pixel_variance4x4)
Yue Chencb60b182016-10-13 15:18:22 -07001664#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001665 break;
1666
Yaowu Xuf883b422016-08-30 14:01:10 -07001667 case AOM_BITS_12:
1668 HIGHBD_BFP(BLOCK_32X16, aom_highbd_sad32x16_bits12,
1669 aom_highbd_sad32x16_avg_bits12, aom_highbd_12_variance32x16,
1670 aom_highbd_12_sub_pixel_variance32x16,
1671 aom_highbd_12_sub_pixel_avg_variance32x16, NULL, NULL,
1672 aom_highbd_sad32x16x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001673
Yaowu Xuf883b422016-08-30 14:01:10 -07001674 HIGHBD_BFP(BLOCK_16X32, aom_highbd_sad16x32_bits12,
1675 aom_highbd_sad16x32_avg_bits12, aom_highbd_12_variance16x32,
1676 aom_highbd_12_sub_pixel_variance16x32,
1677 aom_highbd_12_sub_pixel_avg_variance16x32, NULL, NULL,
1678 aom_highbd_sad16x32x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001679
Yaowu Xuf883b422016-08-30 14:01:10 -07001680 HIGHBD_BFP(BLOCK_64X32, aom_highbd_sad64x32_bits12,
1681 aom_highbd_sad64x32_avg_bits12, aom_highbd_12_variance64x32,
1682 aom_highbd_12_sub_pixel_variance64x32,
1683 aom_highbd_12_sub_pixel_avg_variance64x32, NULL, NULL,
1684 aom_highbd_sad64x32x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001685
Yaowu Xuf883b422016-08-30 14:01:10 -07001686 HIGHBD_BFP(BLOCK_32X64, aom_highbd_sad32x64_bits12,
1687 aom_highbd_sad32x64_avg_bits12, aom_highbd_12_variance32x64,
1688 aom_highbd_12_sub_pixel_variance32x64,
1689 aom_highbd_12_sub_pixel_avg_variance32x64, NULL, NULL,
1690 aom_highbd_sad32x64x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001691
Yaowu Xuf883b422016-08-30 14:01:10 -07001692 HIGHBD_BFP(BLOCK_32X32, aom_highbd_sad32x32_bits12,
1693 aom_highbd_sad32x32_avg_bits12, aom_highbd_12_variance32x32,
1694 aom_highbd_12_sub_pixel_variance32x32,
1695 aom_highbd_12_sub_pixel_avg_variance32x32,
1696 aom_highbd_sad32x32x3_bits12, aom_highbd_sad32x32x8_bits12,
1697 aom_highbd_sad32x32x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001698
Yaowu Xuf883b422016-08-30 14:01:10 -07001699 HIGHBD_BFP(BLOCK_64X64, aom_highbd_sad64x64_bits12,
1700 aom_highbd_sad64x64_avg_bits12, aom_highbd_12_variance64x64,
1701 aom_highbd_12_sub_pixel_variance64x64,
1702 aom_highbd_12_sub_pixel_avg_variance64x64,
1703 aom_highbd_sad64x64x3_bits12, aom_highbd_sad64x64x8_bits12,
1704 aom_highbd_sad64x64x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001705
Yaowu Xuf883b422016-08-30 14:01:10 -07001706 HIGHBD_BFP(BLOCK_16X16, aom_highbd_sad16x16_bits12,
1707 aom_highbd_sad16x16_avg_bits12, aom_highbd_12_variance16x16,
1708 aom_highbd_12_sub_pixel_variance16x16,
1709 aom_highbd_12_sub_pixel_avg_variance16x16,
1710 aom_highbd_sad16x16x3_bits12, aom_highbd_sad16x16x8_bits12,
1711 aom_highbd_sad16x16x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001712
Yaowu Xuf883b422016-08-30 14:01:10 -07001713 HIGHBD_BFP(BLOCK_16X8, aom_highbd_sad16x8_bits12,
1714 aom_highbd_sad16x8_avg_bits12, aom_highbd_12_variance16x8,
1715 aom_highbd_12_sub_pixel_variance16x8,
1716 aom_highbd_12_sub_pixel_avg_variance16x8,
1717 aom_highbd_sad16x8x3_bits12, aom_highbd_sad16x8x8_bits12,
1718 aom_highbd_sad16x8x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001719
Yaowu Xuf883b422016-08-30 14:01:10 -07001720 HIGHBD_BFP(BLOCK_8X16, aom_highbd_sad8x16_bits12,
1721 aom_highbd_sad8x16_avg_bits12, aom_highbd_12_variance8x16,
1722 aom_highbd_12_sub_pixel_variance8x16,
1723 aom_highbd_12_sub_pixel_avg_variance8x16,
1724 aom_highbd_sad8x16x3_bits12, aom_highbd_sad8x16x8_bits12,
1725 aom_highbd_sad8x16x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001726
1727 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001728 BLOCK_8X8, aom_highbd_sad8x8_bits12, aom_highbd_sad8x8_avg_bits12,
1729 aom_highbd_12_variance8x8, aom_highbd_12_sub_pixel_variance8x8,
1730 aom_highbd_12_sub_pixel_avg_variance8x8, aom_highbd_sad8x8x3_bits12,
1731 aom_highbd_sad8x8x8_bits12, aom_highbd_sad8x8x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001732
Yaowu Xuf883b422016-08-30 14:01:10 -07001733 HIGHBD_BFP(BLOCK_8X4, aom_highbd_sad8x4_bits12,
1734 aom_highbd_sad8x4_avg_bits12, aom_highbd_12_variance8x4,
1735 aom_highbd_12_sub_pixel_variance8x4,
1736 aom_highbd_12_sub_pixel_avg_variance8x4, NULL,
1737 aom_highbd_sad8x4x8_bits12, aom_highbd_sad8x4x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001738
Yaowu Xuf883b422016-08-30 14:01:10 -07001739 HIGHBD_BFP(BLOCK_4X8, aom_highbd_sad4x8_bits12,
1740 aom_highbd_sad4x8_avg_bits12, aom_highbd_12_variance4x8,
1741 aom_highbd_12_sub_pixel_variance4x8,
1742 aom_highbd_12_sub_pixel_avg_variance4x8, NULL,
1743 aom_highbd_sad4x8x8_bits12, aom_highbd_sad4x8x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001744
1745 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001746 BLOCK_4X4, aom_highbd_sad4x4_bits12, aom_highbd_sad4x4_avg_bits12,
1747 aom_highbd_12_variance4x4, aom_highbd_12_sub_pixel_variance4x4,
1748 aom_highbd_12_sub_pixel_avg_variance4x4, aom_highbd_sad4x4x3_bits12,
1749 aom_highbd_sad4x4x8_bits12, aom_highbd_sad4x4x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001750
Jingning Hancc5bdf42016-12-19 11:14:30 -08001751#if CONFIG_CB4X4
1752 HIGHBD_BFP(BLOCK_2X2, NULL, NULL, aom_highbd_12_variance2x2, NULL, NULL,
1753 NULL, NULL, NULL)
1754 HIGHBD_BFP(BLOCK_4X2, NULL, NULL, aom_highbd_12_variance4x2, NULL, NULL,
1755 NULL, NULL, NULL)
1756 HIGHBD_BFP(BLOCK_2X4, NULL, NULL, aom_highbd_12_variance2x4, NULL, NULL,
1757 NULL, NULL, NULL)
1758#endif
1759
Yaowu Xuc27fc142016-08-22 16:08:15 -07001760#if CONFIG_EXT_PARTITION
1761 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001762 BLOCK_128X128, aom_highbd_sad128x128_bits12,
1763 aom_highbd_sad128x128_avg_bits12, aom_highbd_12_variance128x128,
1764 aom_highbd_12_sub_pixel_variance128x128,
1765 aom_highbd_12_sub_pixel_avg_variance128x128,
1766 aom_highbd_sad128x128x3_bits12, aom_highbd_sad128x128x8_bits12,
1767 aom_highbd_sad128x128x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001768
Yaowu Xuf883b422016-08-30 14:01:10 -07001769 HIGHBD_BFP(BLOCK_128X64, aom_highbd_sad128x64_bits12,
1770 aom_highbd_sad128x64_avg_bits12,
1771 aom_highbd_12_variance128x64,
1772 aom_highbd_12_sub_pixel_variance128x64,
1773 aom_highbd_12_sub_pixel_avg_variance128x64, NULL, NULL,
1774 aom_highbd_sad128x64x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001775
Yaowu Xuf883b422016-08-30 14:01:10 -07001776 HIGHBD_BFP(BLOCK_64X128, aom_highbd_sad64x128_bits12,
1777 aom_highbd_sad64x128_avg_bits12,
1778 aom_highbd_12_variance64x128,
1779 aom_highbd_12_sub_pixel_variance64x128,
1780 aom_highbd_12_sub_pixel_avg_variance64x128, NULL, NULL,
1781 aom_highbd_sad64x128x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001782#endif // CONFIG_EXT_PARTITION
1783
1784#if CONFIG_EXT_INTER
1785#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001786 HIGHBD_MBFP(BLOCK_128X128, aom_highbd_masked_sad128x128_bits12,
1787 aom_highbd_12_masked_variance128x128,
1788 aom_highbd_12_masked_sub_pixel_variance128x128)
1789 HIGHBD_MBFP(BLOCK_128X64, aom_highbd_masked_sad128x64_bits12,
1790 aom_highbd_12_masked_variance128x64,
1791 aom_highbd_12_masked_sub_pixel_variance128x64)
1792 HIGHBD_MBFP(BLOCK_64X128, aom_highbd_masked_sad64x128_bits12,
1793 aom_highbd_12_masked_variance64x128,
1794 aom_highbd_12_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001795#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001796 HIGHBD_MBFP(BLOCK_64X64, aom_highbd_masked_sad64x64_bits12,
1797 aom_highbd_12_masked_variance64x64,
1798 aom_highbd_12_masked_sub_pixel_variance64x64)
1799 HIGHBD_MBFP(BLOCK_64X32, aom_highbd_masked_sad64x32_bits12,
1800 aom_highbd_12_masked_variance64x32,
1801 aom_highbd_12_masked_sub_pixel_variance64x32)
1802 HIGHBD_MBFP(BLOCK_32X64, aom_highbd_masked_sad32x64_bits12,
1803 aom_highbd_12_masked_variance32x64,
1804 aom_highbd_12_masked_sub_pixel_variance32x64)
1805 HIGHBD_MBFP(BLOCK_32X32, aom_highbd_masked_sad32x32_bits12,
1806 aom_highbd_12_masked_variance32x32,
1807 aom_highbd_12_masked_sub_pixel_variance32x32)
1808 HIGHBD_MBFP(BLOCK_32X16, aom_highbd_masked_sad32x16_bits12,
1809 aom_highbd_12_masked_variance32x16,
1810 aom_highbd_12_masked_sub_pixel_variance32x16)
1811 HIGHBD_MBFP(BLOCK_16X32, aom_highbd_masked_sad16x32_bits12,
1812 aom_highbd_12_masked_variance16x32,
1813 aom_highbd_12_masked_sub_pixel_variance16x32)
1814 HIGHBD_MBFP(BLOCK_16X16, aom_highbd_masked_sad16x16_bits12,
1815 aom_highbd_12_masked_variance16x16,
1816 aom_highbd_12_masked_sub_pixel_variance16x16)
1817 HIGHBD_MBFP(BLOCK_8X16, aom_highbd_masked_sad8x16_bits12,
1818 aom_highbd_12_masked_variance8x16,
1819 aom_highbd_12_masked_sub_pixel_variance8x16)
1820 HIGHBD_MBFP(BLOCK_16X8, aom_highbd_masked_sad16x8_bits12,
1821 aom_highbd_12_masked_variance16x8,
1822 aom_highbd_12_masked_sub_pixel_variance16x8)
1823 HIGHBD_MBFP(BLOCK_8X8, aom_highbd_masked_sad8x8_bits12,
1824 aom_highbd_12_masked_variance8x8,
1825 aom_highbd_12_masked_sub_pixel_variance8x8)
1826 HIGHBD_MBFP(BLOCK_4X8, aom_highbd_masked_sad4x8_bits12,
1827 aom_highbd_12_masked_variance4x8,
1828 aom_highbd_12_masked_sub_pixel_variance4x8)
1829 HIGHBD_MBFP(BLOCK_8X4, aom_highbd_masked_sad8x4_bits12,
1830 aom_highbd_12_masked_variance8x4,
1831 aom_highbd_12_masked_sub_pixel_variance8x4)
1832 HIGHBD_MBFP(BLOCK_4X4, aom_highbd_masked_sad4x4_bits12,
1833 aom_highbd_12_masked_variance4x4,
1834 aom_highbd_12_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001835#endif // CONFIG_EXT_INTER
1836
Yue Chencb60b182016-10-13 15:18:22 -07001837#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001838#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001839 HIGHBD_OBFP(BLOCK_128X128, aom_highbd_obmc_sad128x128_bits12,
1840 aom_highbd_12_obmc_variance128x128,
1841 aom_highbd_12_obmc_sub_pixel_variance128x128)
1842 HIGHBD_OBFP(BLOCK_128X64, aom_highbd_obmc_sad128x64_bits12,
1843 aom_highbd_12_obmc_variance128x64,
1844 aom_highbd_12_obmc_sub_pixel_variance128x64)
1845 HIGHBD_OBFP(BLOCK_64X128, aom_highbd_obmc_sad64x128_bits12,
1846 aom_highbd_12_obmc_variance64x128,
1847 aom_highbd_12_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001848#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001849 HIGHBD_OBFP(BLOCK_64X64, aom_highbd_obmc_sad64x64_bits12,
1850 aom_highbd_12_obmc_variance64x64,
1851 aom_highbd_12_obmc_sub_pixel_variance64x64)
1852 HIGHBD_OBFP(BLOCK_64X32, aom_highbd_obmc_sad64x32_bits12,
1853 aom_highbd_12_obmc_variance64x32,
1854 aom_highbd_12_obmc_sub_pixel_variance64x32)
1855 HIGHBD_OBFP(BLOCK_32X64, aom_highbd_obmc_sad32x64_bits12,
1856 aom_highbd_12_obmc_variance32x64,
1857 aom_highbd_12_obmc_sub_pixel_variance32x64)
1858 HIGHBD_OBFP(BLOCK_32X32, aom_highbd_obmc_sad32x32_bits12,
1859 aom_highbd_12_obmc_variance32x32,
1860 aom_highbd_12_obmc_sub_pixel_variance32x32)
1861 HIGHBD_OBFP(BLOCK_32X16, aom_highbd_obmc_sad32x16_bits12,
1862 aom_highbd_12_obmc_variance32x16,
1863 aom_highbd_12_obmc_sub_pixel_variance32x16)
1864 HIGHBD_OBFP(BLOCK_16X32, aom_highbd_obmc_sad16x32_bits12,
1865 aom_highbd_12_obmc_variance16x32,
1866 aom_highbd_12_obmc_sub_pixel_variance16x32)
1867 HIGHBD_OBFP(BLOCK_16X16, aom_highbd_obmc_sad16x16_bits12,
1868 aom_highbd_12_obmc_variance16x16,
1869 aom_highbd_12_obmc_sub_pixel_variance16x16)
1870 HIGHBD_OBFP(BLOCK_8X16, aom_highbd_obmc_sad8x16_bits12,
1871 aom_highbd_12_obmc_variance8x16,
1872 aom_highbd_12_obmc_sub_pixel_variance8x16)
1873 HIGHBD_OBFP(BLOCK_16X8, aom_highbd_obmc_sad16x8_bits12,
1874 aom_highbd_12_obmc_variance16x8,
1875 aom_highbd_12_obmc_sub_pixel_variance16x8)
1876 HIGHBD_OBFP(BLOCK_8X8, aom_highbd_obmc_sad8x8_bits12,
1877 aom_highbd_12_obmc_variance8x8,
1878 aom_highbd_12_obmc_sub_pixel_variance8x8)
1879 HIGHBD_OBFP(BLOCK_4X8, aom_highbd_obmc_sad4x8_bits12,
1880 aom_highbd_12_obmc_variance4x8,
1881 aom_highbd_12_obmc_sub_pixel_variance4x8)
1882 HIGHBD_OBFP(BLOCK_8X4, aom_highbd_obmc_sad8x4_bits12,
1883 aom_highbd_12_obmc_variance8x4,
1884 aom_highbd_12_obmc_sub_pixel_variance8x4)
1885 HIGHBD_OBFP(BLOCK_4X4, aom_highbd_obmc_sad4x4_bits12,
1886 aom_highbd_12_obmc_variance4x4,
1887 aom_highbd_12_obmc_sub_pixel_variance4x4)
Yue Chencb60b182016-10-13 15:18:22 -07001888#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001889 break;
1890
1891 default:
1892 assert(0 &&
Yaowu Xuf883b422016-08-30 14:01:10 -07001893 "cm->bit_depth should be AOM_BITS_8, "
1894 "AOM_BITS_10 or AOM_BITS_12");
Yaowu Xuc27fc142016-08-22 16:08:15 -07001895 }
1896 }
1897}
Yaowu Xuf883b422016-08-30 14:01:10 -07001898#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001899
Yaowu Xuf883b422016-08-30 14:01:10 -07001900static void realloc_segmentation_maps(AV1_COMP *cpi) {
1901 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001902
1903 // Create the encoder segmentation map and set all entries to 0
Yaowu Xuf883b422016-08-30 14:01:10 -07001904 aom_free(cpi->segmentation_map);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001905 CHECK_MEM_ERROR(cm, cpi->segmentation_map,
Yaowu Xuf883b422016-08-30 14:01:10 -07001906 aom_calloc(cm->mi_rows * cm->mi_cols, 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001907
1908 // Create a map used for cyclic background refresh.
Yaowu Xuf883b422016-08-30 14:01:10 -07001909 if (cpi->cyclic_refresh) av1_cyclic_refresh_free(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001910 CHECK_MEM_ERROR(cm, cpi->cyclic_refresh,
Yaowu Xuf883b422016-08-30 14:01:10 -07001911 av1_cyclic_refresh_alloc(cm->mi_rows, cm->mi_cols));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001912
1913 // Create a map used to mark inactive areas.
Yaowu Xuf883b422016-08-30 14:01:10 -07001914 aom_free(cpi->active_map.map);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001915 CHECK_MEM_ERROR(cm, cpi->active_map.map,
Yaowu Xuf883b422016-08-30 14:01:10 -07001916 aom_calloc(cm->mi_rows * cm->mi_cols, 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001917}
1918
Yaowu Xuf883b422016-08-30 14:01:10 -07001919void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf) {
1920 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001921 RATE_CONTROL *const rc = &cpi->rc;
1922
1923 if (cm->profile != oxcf->profile) cm->profile = oxcf->profile;
1924 cm->bit_depth = oxcf->bit_depth;
1925 cm->color_space = oxcf->color_space;
1926 cm->color_range = oxcf->color_range;
1927
1928 if (cm->profile <= PROFILE_1)
Yaowu Xuf883b422016-08-30 14:01:10 -07001929 assert(cm->bit_depth == AOM_BITS_8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001930 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001931 assert(cm->bit_depth > AOM_BITS_8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001932
1933 cpi->oxcf = *oxcf;
Yaowu Xuf883b422016-08-30 14:01:10 -07001934#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001935 cpi->td.mb.e_mbd.bd = (int)cm->bit_depth;
Yaowu Xuf883b422016-08-30 14:01:10 -07001936#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001937#if CONFIG_GLOBAL_MOTION
1938 cpi->td.mb.e_mbd.global_motion = cm->global_motion;
1939#endif // CONFIG_GLOBAL_MOTION
1940
Yaowu Xuf883b422016-08-30 14:01:10 -07001941 if ((oxcf->pass == 0) && (oxcf->rc_mode == AOM_Q)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001942 rc->baseline_gf_interval = FIXED_GF_INTERVAL;
1943 } else {
1944 rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2;
1945 }
1946
1947 cpi->refresh_last_frame = 1;
1948 cpi->refresh_golden_frame = 0;
1949#if CONFIG_EXT_REFS
1950 cpi->refresh_bwd_ref_frame = 0;
1951#endif // CONFIG_EXT_REFS
1952
1953 cm->refresh_frame_context =
1954 (oxcf->error_resilient_mode || oxcf->frame_parallel_decoding_mode)
1955 ? REFRESH_FRAME_CONTEXT_FORWARD
1956 : REFRESH_FRAME_CONTEXT_BACKWARD;
1957 cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
1958
Urvang Joshib100db72016-10-12 16:28:56 -07001959#if CONFIG_PALETTE
Yaowu Xuf883b422016-08-30 14:01:10 -07001960 cm->allow_screen_content_tools = (cpi->oxcf.content == AOM_CONTENT_SCREEN);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001961 if (cm->allow_screen_content_tools) {
1962 MACROBLOCK *x = &cpi->td.mb;
1963 if (x->palette_buffer == 0) {
1964 CHECK_MEM_ERROR(cm, x->palette_buffer,
Yaowu Xuf883b422016-08-30 14:01:10 -07001965 aom_memalign(16, sizeof(*x->palette_buffer)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001966 }
1967 // Reallocate the pc_tree, as it's contents depends on
1968 // the state of cm->allow_screen_content_tools
Yaowu Xuf883b422016-08-30 14:01:10 -07001969 av1_free_pc_tree(&cpi->td);
1970 av1_setup_pc_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001971 }
Urvang Joshib100db72016-10-12 16:28:56 -07001972#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001973
Yaowu Xuf883b422016-08-30 14:01:10 -07001974 av1_reset_segment_features(cm);
1975 av1_set_high_precision_mv(cpi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001976
Yaowu Xuc27fc142016-08-22 16:08:15 -07001977 set_rc_buffer_sizes(rc, &cpi->oxcf);
1978
1979 // Under a configuration change, where maximum_buffer_size may change,
1980 // keep buffer level clipped to the maximum allowed buffer size.
Yaowu Xuf883b422016-08-30 14:01:10 -07001981 rc->bits_off_target = AOMMIN(rc->bits_off_target, rc->maximum_buffer_size);
1982 rc->buffer_level = AOMMIN(rc->buffer_level, rc->maximum_buffer_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001983
1984 // Set up frame rate and related parameters rate control values.
Yaowu Xuf883b422016-08-30 14:01:10 -07001985 av1_new_framerate(cpi, cpi->framerate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001986
1987 // Set absolute upper and lower quality limits
1988 rc->worst_quality = cpi->oxcf.worst_allowed_q;
1989 rc->best_quality = cpi->oxcf.best_allowed_q;
1990
1991 cm->interp_filter = cpi->sf.default_interp_filter;
1992
1993 if (cpi->oxcf.render_width > 0 && cpi->oxcf.render_height > 0) {
1994 cm->render_width = cpi->oxcf.render_width;
1995 cm->render_height = cpi->oxcf.render_height;
1996 } else {
1997 cm->render_width = cpi->oxcf.width;
1998 cm->render_height = cpi->oxcf.height;
1999 }
2000 cm->width = cpi->oxcf.width;
2001 cm->height = cpi->oxcf.height;
2002
2003 if (cpi->initial_width) {
2004 if (cm->width > cpi->initial_width || cm->height > cpi->initial_height) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002005 av1_free_context_buffers(cm);
2006 av1_alloc_compressor_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002007 realloc_segmentation_maps(cpi);
2008 cpi->initial_width = cpi->initial_height = 0;
2009 }
2010 }
2011 update_frame_size(cpi);
2012
2013 cpi->alt_ref_source = NULL;
2014 rc->is_src_frame_alt_ref = 0;
2015
2016#if CONFIG_EXT_REFS
2017 rc->is_bwd_ref_frame = 0;
2018 rc->is_last_bipred_frame = 0;
2019 rc->is_bipred_frame = 0;
2020#endif // CONFIG_EXT_REFS
2021
2022#if 0
2023 // Experimental RD Code
2024 cpi->frame_distortion = 0;
2025 cpi->last_frame_distortion = 0;
2026#endif
2027
2028 set_tile_info(cpi);
2029
2030 cpi->ext_refresh_frame_flags_pending = 0;
2031 cpi->ext_refresh_frame_context_pending = 0;
2032
Yaowu Xuf883b422016-08-30 14:01:10 -07002033#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002034 highbd_set_var_fns(cpi);
2035#endif
Alex Converseeb780e72016-12-13 12:46:41 -08002036
2037#if CONFIG_ANS && ANS_MAX_SYMBOLS
2038 cpi->common.ans_window_size_log2 = cpi->oxcf.ans_window_size_log2;
2039 if (cpi->buf_ans.size != (1 << cpi->common.ans_window_size_log2)) {
2040 aom_buf_ans_free(&cpi->buf_ans);
2041 aom_buf_ans_alloc(&cpi->buf_ans, &cpi->common.error,
2042 1 << cpi->common.ans_window_size_log2);
2043 }
2044#endif // CONFIG_ANS && ANS_MAX_SYMBOLS
Yaowu Xuc27fc142016-08-22 16:08:15 -07002045}
2046
2047#ifndef M_LOG2_E
2048#define M_LOG2_E 0.693147180559945309417
2049#endif
2050#define log2f(x) (log(x) / (float)M_LOG2_E)
2051
2052#if !CONFIG_REF_MV
2053static void cal_nmvjointsadcost(int *mvjointsadcost) {
2054 mvjointsadcost[0] = 600;
2055 mvjointsadcost[1] = 300;
2056 mvjointsadcost[2] = 300;
2057 mvjointsadcost[3] = 300;
2058}
2059#endif
2060
2061static void cal_nmvsadcosts(int *mvsadcost[2]) {
2062 int i = 1;
2063
2064 mvsadcost[0][0] = 0;
2065 mvsadcost[1][0] = 0;
2066
2067 do {
2068 double z = 256 * (2 * (log2f(8 * i) + .6));
2069 mvsadcost[0][i] = (int)z;
2070 mvsadcost[1][i] = (int)z;
2071 mvsadcost[0][-i] = (int)z;
2072 mvsadcost[1][-i] = (int)z;
2073 } while (++i <= MV_MAX);
2074}
2075
2076static void cal_nmvsadcosts_hp(int *mvsadcost[2]) {
2077 int i = 1;
2078
2079 mvsadcost[0][0] = 0;
2080 mvsadcost[1][0] = 0;
2081
2082 do {
2083 double z = 256 * (2 * (log2f(8 * i) + .6));
2084 mvsadcost[0][i] = (int)z;
2085 mvsadcost[1][i] = (int)z;
2086 mvsadcost[0][-i] = (int)z;
2087 mvsadcost[1][-i] = (int)z;
2088 } while (++i <= MV_MAX);
2089}
2090
Yaowu Xuf883b422016-08-30 14:01:10 -07002091static INLINE void init_upsampled_ref_frame_bufs(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002092 int i;
2093
2094 for (i = 0; i < (REF_FRAMES + 1); ++i) {
2095 cpi->upsampled_ref_bufs[i].ref_count = 0;
2096 cpi->upsampled_ref_idx[i] = INVALID_IDX;
2097 }
2098}
2099
Yaowu Xuf883b422016-08-30 14:01:10 -07002100AV1_COMP *av1_create_compressor(AV1EncoderConfig *oxcf,
2101 BufferPool *const pool) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002102 unsigned int i;
Yaowu Xuf883b422016-08-30 14:01:10 -07002103 AV1_COMP *volatile const cpi = aom_memalign(32, sizeof(AV1_COMP));
2104 AV1_COMMON *volatile const cm = cpi != NULL ? &cpi->common : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002105
2106 if (!cm) return NULL;
2107
Yaowu Xuf883b422016-08-30 14:01:10 -07002108 av1_zero(*cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002109
2110 if (setjmp(cm->error.jmp)) {
2111 cm->error.setjmp = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07002112 av1_remove_compressor(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002113 return 0;
2114 }
2115
2116 cm->error.setjmp = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07002117 cm->alloc_mi = av1_enc_alloc_mi;
2118 cm->free_mi = av1_enc_free_mi;
2119 cm->setup_mi = av1_enc_setup_mi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002120
Angie Chianga5d96c42016-10-21 16:16:56 -07002121 CHECK_MEM_ERROR(cm, cm->fc,
2122 (FRAME_CONTEXT *)aom_memalign(32, sizeof(*cm->fc)));
2123 CHECK_MEM_ERROR(cm, cm->frame_contexts,
2124 (FRAME_CONTEXT *)aom_memalign(
2125 32, FRAME_CONTEXTS * sizeof(*cm->frame_contexts)));
2126 memset(cm->fc, 0, sizeof(*cm->fc));
2127 memset(cm->frame_contexts, 0, FRAME_CONTEXTS * sizeof(*cm->frame_contexts));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002128
2129 cpi->resize_state = 0;
2130 cpi->resize_avg_qp = 0;
2131 cpi->resize_buffer_underflow = 0;
2132 cpi->common.buffer_pool = pool;
2133
2134 init_config(cpi, oxcf);
Yaowu Xuf883b422016-08-30 14:01:10 -07002135 av1_rc_init(&cpi->oxcf, oxcf->pass, &cpi->rc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002136
2137 cm->current_video_frame = 0;
2138 cpi->partition_search_skippable_frame = 0;
2139 cpi->tile_data = NULL;
2140 cpi->last_show_frame_buf_idx = INVALID_IDX;
2141
2142 realloc_segmentation_maps(cpi);
2143
2144#if CONFIG_REF_MV
2145 for (i = 0; i < NMV_CONTEXTS; ++i) {
Urvang Joshibffc0b52016-07-25 13:38:49 -07002146 memset(cpi->nmv_costs, 0, sizeof(cpi->nmv_costs));
2147 memset(cpi->nmv_costs_hp, 0, sizeof(cpi->nmv_costs_hp));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002148 }
2149#endif
2150
Urvang Joshibffc0b52016-07-25 13:38:49 -07002151 memset(cpi->nmvcosts, 0, sizeof(cpi->nmvcosts));
2152 memset(cpi->nmvcosts_hp, 0, sizeof(cpi->nmvcosts_hp));
2153 memset(cpi->nmvsadcosts, 0, sizeof(cpi->nmvsadcosts));
2154 memset(cpi->nmvsadcosts_hp, 0, sizeof(cpi->nmvsadcosts_hp));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002155
2156 for (i = 0; i < (sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]));
2157 i++) {
2158 CHECK_MEM_ERROR(
2159 cm, cpi->mbgraph_stats[i].mb_stats,
Yaowu Xuf883b422016-08-30 14:01:10 -07002160 aom_calloc(cm->MBs * sizeof(*cpi->mbgraph_stats[i].mb_stats), 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002161 }
2162
2163#if CONFIG_FP_MB_STATS
2164 cpi->use_fp_mb_stats = 0;
2165 if (cpi->use_fp_mb_stats) {
2166 // a place holder used to store the first pass mb stats in the first pass
2167 CHECK_MEM_ERROR(cm, cpi->twopass.frame_mb_stats_buf,
Yaowu Xuf883b422016-08-30 14:01:10 -07002168 aom_calloc(cm->MBs * sizeof(uint8_t), 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002169 } else {
2170 cpi->twopass.frame_mb_stats_buf = NULL;
2171 }
2172#endif
2173
2174 cpi->refresh_alt_ref_frame = 0;
2175 cpi->multi_arf_last_grp_enabled = 0;
2176
2177 cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS;
2178#if CONFIG_INTERNAL_STATS
2179 cpi->b_calculate_blockiness = 1;
2180 cpi->b_calculate_consistency = 1;
2181 cpi->total_inconsistency = 0;
2182 cpi->psnr.worst = 100.0;
2183 cpi->worst_ssim = 100.0;
2184
2185 cpi->count = 0;
2186 cpi->bytes = 0;
2187
2188 if (cpi->b_calculate_psnr) {
2189 cpi->total_sq_error = 0;
2190 cpi->total_samples = 0;
2191 cpi->tot_recode_hits = 0;
2192 cpi->summed_quality = 0;
2193 cpi->summed_weights = 0;
2194 }
2195
2196 cpi->fastssim.worst = 100.0;
2197 cpi->psnrhvs.worst = 100.0;
2198
2199 if (cpi->b_calculate_blockiness) {
2200 cpi->total_blockiness = 0;
2201 cpi->worst_blockiness = 0.0;
2202 }
2203
2204 if (cpi->b_calculate_consistency) {
2205 CHECK_MEM_ERROR(cm, cpi->ssim_vars,
Yaowu Xuf883b422016-08-30 14:01:10 -07002206 aom_malloc(sizeof(*cpi->ssim_vars) * 4 *
Yaowu Xuc27fc142016-08-22 16:08:15 -07002207 cpi->common.mi_rows * cpi->common.mi_cols));
2208 cpi->worst_consistency = 100.0;
2209 }
2210#endif
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08002211#if CONFIG_ENTROPY_STATS
2212 av1_zero(aggregate_fc);
2213#endif // CONFIG_ENTROPY_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07002214
2215 cpi->first_time_stamp_ever = INT64_MAX;
2216
2217#if CONFIG_REF_MV
2218 for (i = 0; i < NMV_CONTEXTS; ++i) {
2219 cpi->td.mb.nmvcost[i][0] = &cpi->nmv_costs[i][0][MV_MAX];
2220 cpi->td.mb.nmvcost[i][1] = &cpi->nmv_costs[i][1][MV_MAX];
2221 cpi->td.mb.nmvcost_hp[i][0] = &cpi->nmv_costs_hp[i][0][MV_MAX];
2222 cpi->td.mb.nmvcost_hp[i][1] = &cpi->nmv_costs_hp[i][1][MV_MAX];
2223 }
2224#else
2225 cal_nmvjointsadcost(cpi->td.mb.nmvjointsadcost);
2226 cpi->td.mb.nmvcost[0] = &cpi->nmvcosts[0][MV_MAX];
2227 cpi->td.mb.nmvcost[1] = &cpi->nmvcosts[1][MV_MAX];
2228 cpi->td.mb.nmvcost_hp[0] = &cpi->nmvcosts_hp[0][MV_MAX];
2229 cpi->td.mb.nmvcost_hp[1] = &cpi->nmvcosts_hp[1][MV_MAX];
2230#endif
2231 cpi->td.mb.nmvsadcost[0] = &cpi->nmvsadcosts[0][MV_MAX];
2232 cpi->td.mb.nmvsadcost[1] = &cpi->nmvsadcosts[1][MV_MAX];
2233 cal_nmvsadcosts(cpi->td.mb.nmvsadcost);
2234
2235 cpi->td.mb.nmvsadcost_hp[0] = &cpi->nmvsadcosts_hp[0][MV_MAX];
2236 cpi->td.mb.nmvsadcost_hp[1] = &cpi->nmvsadcosts_hp[1][MV_MAX];
2237 cal_nmvsadcosts_hp(cpi->td.mb.nmvsadcost_hp);
2238
2239#ifdef OUTPUT_YUV_SKINMAP
2240 yuv_skinmap_file = fopen("skinmap.yuv", "ab");
2241#endif
2242#ifdef OUTPUT_YUV_REC
2243 yuv_rec_file = fopen("rec.yuv", "wb");
2244#endif
2245
2246#if 0
2247 framepsnr = fopen("framepsnr.stt", "a");
2248 kf_list = fopen("kf_list.stt", "w");
2249#endif
2250
Yaowu Xuc27fc142016-08-22 16:08:15 -07002251 if (oxcf->pass == 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002252 av1_init_first_pass(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002253 } else if (oxcf->pass == 2) {
2254 const size_t packet_sz = sizeof(FIRSTPASS_STATS);
2255 const int packets = (int)(oxcf->two_pass_stats_in.sz / packet_sz);
2256
2257#if CONFIG_FP_MB_STATS
2258 if (cpi->use_fp_mb_stats) {
2259 const size_t psz = cpi->common.MBs * sizeof(uint8_t);
2260 const int ps = (int)(oxcf->firstpass_mb_stats_in.sz / psz);
2261
2262 cpi->twopass.firstpass_mb_stats.mb_stats_start =
2263 oxcf->firstpass_mb_stats_in.buf;
2264 cpi->twopass.firstpass_mb_stats.mb_stats_end =
2265 cpi->twopass.firstpass_mb_stats.mb_stats_start +
2266 (ps - 1) * cpi->common.MBs * sizeof(uint8_t);
2267 }
2268#endif
2269
2270 cpi->twopass.stats_in_start = oxcf->two_pass_stats_in.buf;
2271 cpi->twopass.stats_in = cpi->twopass.stats_in_start;
2272 cpi->twopass.stats_in_end = &cpi->twopass.stats_in[packets - 1];
2273
Yaowu Xuf883b422016-08-30 14:01:10 -07002274 av1_init_second_pass(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002275 }
2276
2277 init_upsampled_ref_frame_bufs(cpi);
2278
Yaowu Xuf883b422016-08-30 14:01:10 -07002279 av1_set_speed_features_framesize_independent(cpi);
2280 av1_set_speed_features_framesize_dependent(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002281
2282 // Allocate memory to store variances for a frame.
Urvang Joshi454280d2016-10-14 16:51:44 -07002283 CHECK_MEM_ERROR(cm, cpi->source_diff_var,
2284 aom_calloc(cm->MBs, sizeof(*cpi->source_diff_var)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002285 cpi->source_var_thresh = 0;
2286 cpi->frames_till_next_var_check = 0;
2287
2288#define BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
2289 cpi->fn_ptr[BT].sdf = SDF; \
2290 cpi->fn_ptr[BT].sdaf = SDAF; \
2291 cpi->fn_ptr[BT].vf = VF; \
2292 cpi->fn_ptr[BT].svf = SVF; \
2293 cpi->fn_ptr[BT].svaf = SVAF; \
2294 cpi->fn_ptr[BT].sdx3f = SDX3F; \
2295 cpi->fn_ptr[BT].sdx8f = SDX8F; \
2296 cpi->fn_ptr[BT].sdx4df = SDX4DF;
2297
2298#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002299 BFP(BLOCK_128X128, aom_sad128x128, aom_sad128x128_avg, aom_variance128x128,
2300 aom_sub_pixel_variance128x128, aom_sub_pixel_avg_variance128x128,
2301 aom_sad128x128x3, aom_sad128x128x8, aom_sad128x128x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002302
Yaowu Xuf883b422016-08-30 14:01:10 -07002303 BFP(BLOCK_128X64, aom_sad128x64, aom_sad128x64_avg, aom_variance128x64,
2304 aom_sub_pixel_variance128x64, aom_sub_pixel_avg_variance128x64, NULL,
2305 NULL, aom_sad128x64x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002306
Yaowu Xuf883b422016-08-30 14:01:10 -07002307 BFP(BLOCK_64X128, aom_sad64x128, aom_sad64x128_avg, aom_variance64x128,
2308 aom_sub_pixel_variance64x128, aom_sub_pixel_avg_variance64x128, NULL,
2309 NULL, aom_sad64x128x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002310#endif // CONFIG_EXT_PARTITION
2311
Yaowu Xuf883b422016-08-30 14:01:10 -07002312 BFP(BLOCK_32X16, aom_sad32x16, aom_sad32x16_avg, aom_variance32x16,
2313 aom_sub_pixel_variance32x16, aom_sub_pixel_avg_variance32x16, NULL, NULL,
2314 aom_sad32x16x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002315
Yaowu Xuf883b422016-08-30 14:01:10 -07002316 BFP(BLOCK_16X32, aom_sad16x32, aom_sad16x32_avg, aom_variance16x32,
2317 aom_sub_pixel_variance16x32, aom_sub_pixel_avg_variance16x32, NULL, NULL,
2318 aom_sad16x32x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002319
Yaowu Xuf883b422016-08-30 14:01:10 -07002320 BFP(BLOCK_64X32, aom_sad64x32, aom_sad64x32_avg, aom_variance64x32,
2321 aom_sub_pixel_variance64x32, aom_sub_pixel_avg_variance64x32, NULL, NULL,
2322 aom_sad64x32x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002323
Yaowu Xuf883b422016-08-30 14:01:10 -07002324 BFP(BLOCK_32X64, aom_sad32x64, aom_sad32x64_avg, aom_variance32x64,
2325 aom_sub_pixel_variance32x64, aom_sub_pixel_avg_variance32x64, NULL, NULL,
2326 aom_sad32x64x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002327
Yaowu Xuf883b422016-08-30 14:01:10 -07002328 BFP(BLOCK_32X32, aom_sad32x32, aom_sad32x32_avg, aom_variance32x32,
2329 aom_sub_pixel_variance32x32, aom_sub_pixel_avg_variance32x32,
2330 aom_sad32x32x3, aom_sad32x32x8, aom_sad32x32x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002331
Yaowu Xuf883b422016-08-30 14:01:10 -07002332 BFP(BLOCK_64X64, aom_sad64x64, aom_sad64x64_avg, aom_variance64x64,
2333 aom_sub_pixel_variance64x64, aom_sub_pixel_avg_variance64x64,
2334 aom_sad64x64x3, aom_sad64x64x8, aom_sad64x64x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002335
Yaowu Xuf883b422016-08-30 14:01:10 -07002336 BFP(BLOCK_16X16, aom_sad16x16, aom_sad16x16_avg, aom_variance16x16,
2337 aom_sub_pixel_variance16x16, aom_sub_pixel_avg_variance16x16,
2338 aom_sad16x16x3, aom_sad16x16x8, aom_sad16x16x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002339
Yaowu Xuf883b422016-08-30 14:01:10 -07002340 BFP(BLOCK_16X8, aom_sad16x8, aom_sad16x8_avg, aom_variance16x8,
2341 aom_sub_pixel_variance16x8, aom_sub_pixel_avg_variance16x8, aom_sad16x8x3,
2342 aom_sad16x8x8, aom_sad16x8x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002343
Yaowu Xuf883b422016-08-30 14:01:10 -07002344 BFP(BLOCK_8X16, aom_sad8x16, aom_sad8x16_avg, aom_variance8x16,
2345 aom_sub_pixel_variance8x16, aom_sub_pixel_avg_variance8x16, aom_sad8x16x3,
2346 aom_sad8x16x8, aom_sad8x16x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002347
Yaowu Xuf883b422016-08-30 14:01:10 -07002348 BFP(BLOCK_8X8, aom_sad8x8, aom_sad8x8_avg, aom_variance8x8,
2349 aom_sub_pixel_variance8x8, aom_sub_pixel_avg_variance8x8, aom_sad8x8x3,
2350 aom_sad8x8x8, aom_sad8x8x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002351
Yaowu Xuf883b422016-08-30 14:01:10 -07002352 BFP(BLOCK_8X4, aom_sad8x4, aom_sad8x4_avg, aom_variance8x4,
2353 aom_sub_pixel_variance8x4, aom_sub_pixel_avg_variance8x4, NULL,
2354 aom_sad8x4x8, aom_sad8x4x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002355
Yaowu Xuf883b422016-08-30 14:01:10 -07002356 BFP(BLOCK_4X8, aom_sad4x8, aom_sad4x8_avg, aom_variance4x8,
2357 aom_sub_pixel_variance4x8, aom_sub_pixel_avg_variance4x8, NULL,
2358 aom_sad4x8x8, aom_sad4x8x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002359
Yaowu Xuf883b422016-08-30 14:01:10 -07002360 BFP(BLOCK_4X4, aom_sad4x4, aom_sad4x4_avg, aom_variance4x4,
2361 aom_sub_pixel_variance4x4, aom_sub_pixel_avg_variance4x4, aom_sad4x4x3,
2362 aom_sad4x4x8, aom_sad4x4x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002363
Jingning Han9e7c49f2016-12-06 11:20:10 -08002364#if CONFIG_CB4X4
2365 BFP(BLOCK_2X2, NULL, NULL, aom_variance2x2, NULL, NULL, NULL, NULL, NULL)
Jingning Hane2ffaf82016-12-14 15:26:30 -08002366 BFP(BLOCK_2X4, NULL, NULL, aom_variance2x4, NULL, NULL, NULL, NULL, NULL)
2367 BFP(BLOCK_4X2, NULL, NULL, aom_variance4x2, NULL, NULL, NULL, NULL, NULL)
Jingning Han9e7c49f2016-12-06 11:20:10 -08002368#endif
2369
Yue Chencb60b182016-10-13 15:18:22 -07002370#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07002371#define OBFP(BT, OSDF, OVF, OSVF) \
2372 cpi->fn_ptr[BT].osdf = OSDF; \
2373 cpi->fn_ptr[BT].ovf = OVF; \
2374 cpi->fn_ptr[BT].osvf = OSVF;
2375
2376#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002377 OBFP(BLOCK_128X128, aom_obmc_sad128x128, aom_obmc_variance128x128,
2378 aom_obmc_sub_pixel_variance128x128)
2379 OBFP(BLOCK_128X64, aom_obmc_sad128x64, aom_obmc_variance128x64,
2380 aom_obmc_sub_pixel_variance128x64)
2381 OBFP(BLOCK_64X128, aom_obmc_sad64x128, aom_obmc_variance64x128,
2382 aom_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002383#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002384 OBFP(BLOCK_64X64, aom_obmc_sad64x64, aom_obmc_variance64x64,
2385 aom_obmc_sub_pixel_variance64x64)
2386 OBFP(BLOCK_64X32, aom_obmc_sad64x32, aom_obmc_variance64x32,
2387 aom_obmc_sub_pixel_variance64x32)
2388 OBFP(BLOCK_32X64, aom_obmc_sad32x64, aom_obmc_variance32x64,
2389 aom_obmc_sub_pixel_variance32x64)
2390 OBFP(BLOCK_32X32, aom_obmc_sad32x32, aom_obmc_variance32x32,
2391 aom_obmc_sub_pixel_variance32x32)
2392 OBFP(BLOCK_32X16, aom_obmc_sad32x16, aom_obmc_variance32x16,
2393 aom_obmc_sub_pixel_variance32x16)
2394 OBFP(BLOCK_16X32, aom_obmc_sad16x32, aom_obmc_variance16x32,
2395 aom_obmc_sub_pixel_variance16x32)
2396 OBFP(BLOCK_16X16, aom_obmc_sad16x16, aom_obmc_variance16x16,
2397 aom_obmc_sub_pixel_variance16x16)
2398 OBFP(BLOCK_16X8, aom_obmc_sad16x8, aom_obmc_variance16x8,
2399 aom_obmc_sub_pixel_variance16x8)
2400 OBFP(BLOCK_8X16, aom_obmc_sad8x16, aom_obmc_variance8x16,
2401 aom_obmc_sub_pixel_variance8x16)
2402 OBFP(BLOCK_8X8, aom_obmc_sad8x8, aom_obmc_variance8x8,
2403 aom_obmc_sub_pixel_variance8x8)
2404 OBFP(BLOCK_4X8, aom_obmc_sad4x8, aom_obmc_variance4x8,
2405 aom_obmc_sub_pixel_variance4x8)
2406 OBFP(BLOCK_8X4, aom_obmc_sad8x4, aom_obmc_variance8x4,
2407 aom_obmc_sub_pixel_variance8x4)
2408 OBFP(BLOCK_4X4, aom_obmc_sad4x4, aom_obmc_variance4x4,
2409 aom_obmc_sub_pixel_variance4x4)
Yue Chencb60b182016-10-13 15:18:22 -07002410#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07002411
2412#if CONFIG_EXT_INTER
2413#define MBFP(BT, MSDF, MVF, MSVF) \
2414 cpi->fn_ptr[BT].msdf = MSDF; \
2415 cpi->fn_ptr[BT].mvf = MVF; \
2416 cpi->fn_ptr[BT].msvf = MSVF;
2417
2418#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002419 MBFP(BLOCK_128X128, aom_masked_sad128x128, aom_masked_variance128x128,
2420 aom_masked_sub_pixel_variance128x128)
2421 MBFP(BLOCK_128X64, aom_masked_sad128x64, aom_masked_variance128x64,
2422 aom_masked_sub_pixel_variance128x64)
2423 MBFP(BLOCK_64X128, aom_masked_sad64x128, aom_masked_variance64x128,
2424 aom_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002425#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002426 MBFP(BLOCK_64X64, aom_masked_sad64x64, aom_masked_variance64x64,
2427 aom_masked_sub_pixel_variance64x64)
2428 MBFP(BLOCK_64X32, aom_masked_sad64x32, aom_masked_variance64x32,
2429 aom_masked_sub_pixel_variance64x32)
2430 MBFP(BLOCK_32X64, aom_masked_sad32x64, aom_masked_variance32x64,
2431 aom_masked_sub_pixel_variance32x64)
2432 MBFP(BLOCK_32X32, aom_masked_sad32x32, aom_masked_variance32x32,
2433 aom_masked_sub_pixel_variance32x32)
2434 MBFP(BLOCK_32X16, aom_masked_sad32x16, aom_masked_variance32x16,
2435 aom_masked_sub_pixel_variance32x16)
2436 MBFP(BLOCK_16X32, aom_masked_sad16x32, aom_masked_variance16x32,
2437 aom_masked_sub_pixel_variance16x32)
2438 MBFP(BLOCK_16X16, aom_masked_sad16x16, aom_masked_variance16x16,
2439 aom_masked_sub_pixel_variance16x16)
2440 MBFP(BLOCK_16X8, aom_masked_sad16x8, aom_masked_variance16x8,
2441 aom_masked_sub_pixel_variance16x8)
2442 MBFP(BLOCK_8X16, aom_masked_sad8x16, aom_masked_variance8x16,
2443 aom_masked_sub_pixel_variance8x16)
2444 MBFP(BLOCK_8X8, aom_masked_sad8x8, aom_masked_variance8x8,
2445 aom_masked_sub_pixel_variance8x8)
2446 MBFP(BLOCK_4X8, aom_masked_sad4x8, aom_masked_variance4x8,
2447 aom_masked_sub_pixel_variance4x8)
2448 MBFP(BLOCK_8X4, aom_masked_sad8x4, aom_masked_variance8x4,
2449 aom_masked_sub_pixel_variance8x4)
2450 MBFP(BLOCK_4X4, aom_masked_sad4x4, aom_masked_variance4x4,
2451 aom_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002452#endif // CONFIG_EXT_INTER
2453
Yaowu Xuf883b422016-08-30 14:01:10 -07002454#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002455 highbd_set_var_fns(cpi);
2456#endif
2457
Yaowu Xuf883b422016-08-30 14:01:10 -07002458 /* av1_init_quantizer() is first called here. Add check in
2459 * av1_frame_init_quantizer() so that av1_init_quantizer is only
Yaowu Xuc27fc142016-08-22 16:08:15 -07002460 * called later when needed. This will avoid unnecessary calls of
Yaowu Xuf883b422016-08-30 14:01:10 -07002461 * av1_init_quantizer() for every frame.
Yaowu Xuc27fc142016-08-22 16:08:15 -07002462 */
Yaowu Xuf883b422016-08-30 14:01:10 -07002463 av1_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002464#if CONFIG_AOM_QM
2465 aom_qm_init(cm);
2466#endif
2467
Yaowu Xuf883b422016-08-30 14:01:10 -07002468 av1_loop_filter_init(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002469#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -07002470 av1_loop_restoration_precal();
Yaowu Xuc27fc142016-08-22 16:08:15 -07002471#endif // CONFIG_LOOP_RESTORATION
2472
2473 cm->error.setjmp = 0;
2474
2475 return cpi;
2476}
2477
2478#define SNPRINT(H, T) snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T))
2479
2480#define SNPRINT2(H, T, V) \
2481 snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T), (V))
2482
Yaowu Xuf883b422016-08-30 14:01:10 -07002483void av1_remove_compressor(AV1_COMP *cpi) {
2484 AV1_COMMON *cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002485 unsigned int i;
2486 int t;
2487
2488 if (!cpi) return;
2489
2490 cm = &cpi->common;
2491 if (cm->current_video_frame > 0) {
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08002492#if CONFIG_ENTROPY_STATS
2493 if (cpi->oxcf.pass != 1) {
2494 fprintf(stderr, "Writing counts.stt\n");
2495 FILE *f = fopen("counts.stt", "wb");
2496 fwrite(&aggregate_fc, sizeof(aggregate_fc), 1, f);
2497 fclose(f);
2498 }
2499#endif // CONFIG_ENTROPY_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07002500#if CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07002501 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07002502
2503 if (cpi->oxcf.pass != 1) {
2504 char headings[512] = { 0 };
2505 char results[512] = { 0 };
2506 FILE *f = fopen("opsnr.stt", "a");
2507 double time_encoded =
2508 (cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) /
2509 10000000.000;
2510 double total_encode_time =
2511 (cpi->time_receive_data + cpi->time_compress_data) / 1000.000;
2512 const double dr =
2513 (double)cpi->bytes * (double)8 / (double)1000 / time_encoded;
2514 const double peak = (double)((1 << cpi->oxcf.input_bit_depth) - 1);
2515 const double target_rate = (double)cpi->oxcf.target_bandwidth / 1000;
2516 const double rate_err = ((100.0 * (dr - target_rate)) / target_rate);
2517
2518 if (cpi->b_calculate_psnr) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002519 const double total_psnr = aom_sse_to_psnr(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002520 (double)cpi->total_samples, peak, (double)cpi->total_sq_error);
2521 const double total_ssim =
2522 100 * pow(cpi->summed_quality / cpi->summed_weights, 8.0);
2523 snprintf(headings, sizeof(headings),
2524 "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\t"
Yaowu Xuf883b422016-08-30 14:01:10 -07002525 "AOMSSIM\tVPSSIMP\tFASTSIM\tPSNRHVS\t"
Yaowu Xuc27fc142016-08-22 16:08:15 -07002526 "WstPsnr\tWstSsim\tWstFast\tWstHVS");
2527 snprintf(results, sizeof(results),
2528 "%7.2f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
2529 "%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
2530 "%7.3f\t%7.3f\t%7.3f\t%7.3f",
2531 dr, cpi->psnr.stat[ALL] / cpi->count, total_psnr,
2532 cpi->psnr.stat[ALL] / cpi->count, total_psnr, total_ssim,
2533 total_ssim, cpi->fastssim.stat[ALL] / cpi->count,
2534 cpi->psnrhvs.stat[ALL] / cpi->count, cpi->psnr.worst,
2535 cpi->worst_ssim, cpi->fastssim.worst, cpi->psnrhvs.worst);
2536
2537 if (cpi->b_calculate_blockiness) {
2538 SNPRINT(headings, "\t Block\tWstBlck");
2539 SNPRINT2(results, "\t%7.3f", cpi->total_blockiness / cpi->count);
2540 SNPRINT2(results, "\t%7.3f", cpi->worst_blockiness);
2541 }
2542
2543 if (cpi->b_calculate_consistency) {
2544 double consistency =
Yaowu Xuf883b422016-08-30 14:01:10 -07002545 aom_sse_to_psnr((double)cpi->total_samples, peak,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002546 (double)cpi->total_inconsistency);
2547
2548 SNPRINT(headings, "\tConsist\tWstCons");
2549 SNPRINT2(results, "\t%7.3f", consistency);
2550 SNPRINT2(results, "\t%7.3f", cpi->worst_consistency);
2551 }
Sarah Parkerf97b7862016-08-25 17:42:57 -07002552 fprintf(f, "%s\t Time\tRcErr\tAbsErr\n", headings);
2553 fprintf(f, "%s\t%8.0f\t%7.2f\t%7.2f\n", results, total_encode_time,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002554 rate_err, fabs(rate_err));
2555 }
2556
2557 fclose(f);
2558 }
2559
2560#endif
2561
2562#if 0
2563 {
2564 printf("\n_pick_loop_filter_level:%d\n", cpi->time_pick_lpf / 1000);
2565 printf("\n_frames recive_data encod_mb_row compress_frame Total\n");
2566 printf("%6d %10ld %10ld %10ld %10ld\n", cpi->common.current_video_frame,
2567 cpi->time_receive_data / 1000, cpi->time_encode_sb_row / 1000,
2568 cpi->time_compress_data / 1000,
2569 (cpi->time_receive_data + cpi->time_compress_data) / 1000);
2570 }
2571#endif
2572 }
2573
2574 for (t = 0; t < cpi->num_workers; ++t) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002575 AVxWorker *const worker = &cpi->workers[t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002576 EncWorkerData *const thread_data = &cpi->tile_thr_data[t];
2577
2578 // Deallocate allocated threads.
Yaowu Xuf883b422016-08-30 14:01:10 -07002579 aom_get_worker_interface()->end(worker);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002580
2581 // Deallocate allocated thread data.
2582 if (t < cpi->num_workers - 1) {
Urvang Joshib100db72016-10-12 16:28:56 -07002583#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002584 if (cpi->common.allow_screen_content_tools)
Yaowu Xuf883b422016-08-30 14:01:10 -07002585 aom_free(thread_data->td->mb.palette_buffer);
Urvang Joshib100db72016-10-12 16:28:56 -07002586#endif // CONFIG_PALETTE
Yaowu Xuf883b422016-08-30 14:01:10 -07002587 aom_free(thread_data->td->counts);
2588 av1_free_pc_tree(thread_data->td);
2589 av1_free_var_tree(thread_data->td);
2590 aom_free(thread_data->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002591 }
2592 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002593 aom_free(cpi->tile_thr_data);
2594 aom_free(cpi->workers);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002595
Yaowu Xuf883b422016-08-30 14:01:10 -07002596 if (cpi->num_workers > 1) av1_loop_filter_dealloc(&cpi->lf_row_sync);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002597
2598 dealloc_compressor_data(cpi);
2599
2600 for (i = 0; i < sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]);
2601 ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002602 aom_free(cpi->mbgraph_stats[i].mb_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002603 }
2604
2605#if CONFIG_FP_MB_STATS
2606 if (cpi->use_fp_mb_stats) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002607 aom_free(cpi->twopass.frame_mb_stats_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002608 cpi->twopass.frame_mb_stats_buf = NULL;
2609 }
2610#endif
Debargha Mukherjee5d157212017-01-10 14:44:47 -08002611#if CONFIG_INTERNAL_STATS
2612 aom_free(cpi->ssim_vars);
2613 cpi->ssim_vars = NULL;
2614#endif // CONFIG_INTERNAL_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07002615
Yaowu Xuf883b422016-08-30 14:01:10 -07002616 av1_remove_common(cm);
2617 av1_free_ref_frame_buffers(cm->buffer_pool);
2618 aom_free(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002619
2620#ifdef OUTPUT_YUV_SKINMAP
2621 fclose(yuv_skinmap_file);
2622#endif
2623#ifdef OUTPUT_YUV_REC
2624 fclose(yuv_rec_file);
2625#endif
2626
2627#if 0
2628
2629 if (keyfile)
2630 fclose(keyfile);
2631
2632 if (framepsnr)
2633 fclose(framepsnr);
2634
2635 if (kf_list)
2636 fclose(kf_list);
2637
2638#endif
2639}
2640
Yaowu Xuf883b422016-08-30 14:01:10 -07002641static void generate_psnr_packet(AV1_COMP *cpi) {
2642 struct aom_codec_cx_pkt pkt;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002643 int i;
2644 PSNR_STATS psnr;
Yaowu Xuf883b422016-08-30 14:01:10 -07002645#if CONFIG_AOM_HIGHBITDEPTH
2646 aom_calc_highbd_psnr(cpi->Source, cpi->common.frame_to_show, &psnr,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002647 cpi->td.mb.e_mbd.bd, cpi->oxcf.input_bit_depth);
2648#else
Yaowu Xuf883b422016-08-30 14:01:10 -07002649 aom_calc_psnr(cpi->Source, cpi->common.frame_to_show, &psnr);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002650#endif
2651
2652 for (i = 0; i < 4; ++i) {
2653 pkt.data.psnr.samples[i] = psnr.samples[i];
2654 pkt.data.psnr.sse[i] = psnr.sse[i];
2655 pkt.data.psnr.psnr[i] = psnr.psnr[i];
2656 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002657 pkt.kind = AOM_CODEC_PSNR_PKT;
2658 aom_codec_pkt_list_add(cpi->output_pkt_list, &pkt);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002659}
2660
Yaowu Xuf883b422016-08-30 14:01:10 -07002661int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002662 if (ref_frame_flags > ((1 << INTER_REFS_PER_FRAME) - 1)) return -1;
2663
2664 cpi->ref_frame_flags = ref_frame_flags;
2665 return 0;
2666}
2667
Yaowu Xuf883b422016-08-30 14:01:10 -07002668void av1_update_reference(AV1_COMP *cpi, int ref_frame_flags) {
2669 cpi->ext_refresh_golden_frame = (ref_frame_flags & AOM_GOLD_FLAG) != 0;
2670 cpi->ext_refresh_alt_ref_frame = (ref_frame_flags & AOM_ALT_FLAG) != 0;
2671 cpi->ext_refresh_last_frame = (ref_frame_flags & AOM_LAST_FLAG) != 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002672 cpi->ext_refresh_frame_flags_pending = 1;
2673}
2674
Yaowu Xuf883b422016-08-30 14:01:10 -07002675static YV12_BUFFER_CONFIG *get_av1_ref_frame_buffer(
2676 AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag) {
Emil Keyder01770b32017-01-20 18:03:11 -05002677 MV_REFERENCE_FRAME ref_frame = NONE_FRAME;
Yaowu Xuf883b422016-08-30 14:01:10 -07002678 if (ref_frame_flag == AOM_LAST_FLAG) ref_frame = LAST_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002679#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002680 else if (ref_frame_flag == AOM_LAST2_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002681 ref_frame = LAST2_FRAME;
Yaowu Xuf883b422016-08-30 14:01:10 -07002682 else if (ref_frame_flag == AOM_LAST3_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002683 ref_frame = LAST3_FRAME;
2684#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002685 else if (ref_frame_flag == AOM_GOLD_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002686 ref_frame = GOLDEN_FRAME;
2687#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002688 else if (ref_frame_flag == AOM_BWD_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002689 ref_frame = BWDREF_FRAME;
2690#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002691 else if (ref_frame_flag == AOM_ALT_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002692 ref_frame = ALTREF_FRAME;
2693
Emil Keyder01770b32017-01-20 18:03:11 -05002694 return ref_frame == NONE_FRAME ? NULL : get_ref_frame_buffer(cpi, ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002695}
2696
Yaowu Xuf883b422016-08-30 14:01:10 -07002697int av1_copy_reference_enc(AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002698 YV12_BUFFER_CONFIG *sd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002699 YV12_BUFFER_CONFIG *cfg = get_av1_ref_frame_buffer(cpi, ref_frame_flag);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002700 if (cfg) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002701 aom_yv12_copy_frame(cfg, sd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002702 return 0;
2703 } else {
2704 return -1;
2705 }
2706}
2707
Yaowu Xuf883b422016-08-30 14:01:10 -07002708int av1_set_reference_enc(AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag,
2709 YV12_BUFFER_CONFIG *sd) {
2710 YV12_BUFFER_CONFIG *cfg = get_av1_ref_frame_buffer(cpi, ref_frame_flag);
2711 if (cfg) {
2712 aom_yv12_copy_frame(sd, cfg);
2713 return 0;
2714 } else {
2715 return -1;
2716 }
2717}
2718
2719int av1_update_entropy(AV1_COMP *cpi, int update) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002720 cpi->ext_refresh_frame_context = update;
2721 cpi->ext_refresh_frame_context_pending = 1;
2722 return 0;
2723}
2724
2725#if defined(OUTPUT_YUV_DENOISED) || defined(OUTPUT_YUV_SKINMAP)
2726// The denoiser buffer is allocated as a YUV 440 buffer. This function writes it
2727// as YUV 420. We simply use the top-left pixels of the UV buffers, since we do
2728// not denoise the UV channels at this time. If ever we implement UV channel
2729// denoising we will have to modify this.
Yaowu Xuf883b422016-08-30 14:01:10 -07002730void aom_write_yuv_frame_420(YV12_BUFFER_CONFIG *s, FILE *f) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002731 uint8_t *src = s->y_buffer;
2732 int h = s->y_height;
2733
2734 do {
2735 fwrite(src, s->y_width, 1, f);
2736 src += s->y_stride;
2737 } while (--h);
2738
2739 src = s->u_buffer;
2740 h = s->uv_height;
2741
2742 do {
2743 fwrite(src, s->uv_width, 1, f);
2744 src += s->uv_stride;
2745 } while (--h);
2746
2747 src = s->v_buffer;
2748 h = s->uv_height;
2749
2750 do {
2751 fwrite(src, s->uv_width, 1, f);
2752 src += s->uv_stride;
2753 } while (--h);
2754}
2755#endif
2756
2757#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002758static void check_show_existing_frame(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002759 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
Yaowu Xuf883b422016-08-30 14:01:10 -07002760 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002761 const FRAME_UPDATE_TYPE next_frame_update_type =
2762 gf_group->update_type[gf_group->index];
2763 const int which_arf = gf_group->arf_update_idx[gf_group->index];
Zoe Liu5fca7242016-10-10 17:18:57 -07002764
2765 if (cm->show_existing_frame == 1) {
2766 cm->show_existing_frame = 0;
2767 } else if (cpi->rc.is_last_bipred_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002768 // NOTE(zoeliu): If the current frame is a last bi-predictive frame, it is
2769 // needed next to show the BWDREF_FRAME, which is pointed by
2770 // the last_fb_idxes[0] after reference frame buffer update
2771 cpi->rc.is_last_bipred_frame = 0;
2772 cm->show_existing_frame = 1;
2773 cpi->existing_fb_idx_to_show = cpi->lst_fb_idxes[0];
2774 } else if (cpi->is_arf_filter_off[which_arf] &&
2775 (next_frame_update_type == OVERLAY_UPDATE ||
2776 next_frame_update_type == INTNL_OVERLAY_UPDATE)) {
2777 // Other parameters related to OVERLAY_UPDATE will be taken care of
Yaowu Xuf883b422016-08-30 14:01:10 -07002778 // in av1_rc_get_second_pass_params(cpi)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002779 cm->show_existing_frame = 1;
2780 cpi->rc.is_src_frame_alt_ref = 1;
2781 cpi->existing_fb_idx_to_show = cpi->alt_fb_idx;
2782 cpi->is_arf_filter_off[which_arf] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002783 }
2784 cpi->rc.is_src_frame_ext_arf = 0;
2785}
2786#endif // CONFIG_EXT_REFS
2787
2788#ifdef OUTPUT_YUV_REC
Yaowu Xuf883b422016-08-30 14:01:10 -07002789void aom_write_one_yuv_frame(AV1_COMMON *cm, YV12_BUFFER_CONFIG *s) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002790 uint8_t *src = s->y_buffer;
2791 int h = cm->height;
2792
Yaowu Xuf883b422016-08-30 14:01:10 -07002793#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002794 if (s->flags & YV12_FLAG_HIGHBITDEPTH) {
2795 uint16_t *src16 = CONVERT_TO_SHORTPTR(s->y_buffer);
2796
2797 do {
2798 fwrite(src16, s->y_width, 2, yuv_rec_file);
2799 src16 += s->y_stride;
2800 } while (--h);
2801
2802 src16 = CONVERT_TO_SHORTPTR(s->u_buffer);
2803 h = s->uv_height;
2804
2805 do {
2806 fwrite(src16, s->uv_width, 2, yuv_rec_file);
2807 src16 += s->uv_stride;
2808 } while (--h);
2809
2810 src16 = CONVERT_TO_SHORTPTR(s->v_buffer);
2811 h = s->uv_height;
2812
2813 do {
2814 fwrite(src16, s->uv_width, 2, yuv_rec_file);
2815 src16 += s->uv_stride;
2816 } while (--h);
2817
2818 fflush(yuv_rec_file);
2819 return;
2820 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002821#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002822
2823 do {
2824 fwrite(src, s->y_width, 1, yuv_rec_file);
2825 src += s->y_stride;
2826 } while (--h);
2827
2828 src = s->u_buffer;
2829 h = s->uv_height;
2830
2831 do {
2832 fwrite(src, s->uv_width, 1, yuv_rec_file);
2833 src += s->uv_stride;
2834 } while (--h);
2835
2836 src = s->v_buffer;
2837 h = s->uv_height;
2838
2839 do {
2840 fwrite(src, s->uv_width, 1, yuv_rec_file);
2841 src += s->uv_stride;
2842 } while (--h);
2843
2844 fflush(yuv_rec_file);
2845}
2846#endif // OUTPUT_YUV_REC
2847
Yaowu Xuf883b422016-08-30 14:01:10 -07002848#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002849static void scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG *src,
2850 YV12_BUFFER_CONFIG *dst,
2851 int bd) {
2852#else
2853static void scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG *src,
2854 YV12_BUFFER_CONFIG *dst) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002855#endif // CONFIG_AOM_HIGHBITDEPTH
2856 // TODO(dkovalev): replace YV12_BUFFER_CONFIG with aom_image_t
Yaowu Xuc27fc142016-08-22 16:08:15 -07002857 int i;
2858 const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer,
2859 src->v_buffer };
2860 const int src_strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
2861 const int src_widths[3] = { src->y_crop_width, src->uv_crop_width,
2862 src->uv_crop_width };
2863 const int src_heights[3] = { src->y_crop_height, src->uv_crop_height,
2864 src->uv_crop_height };
2865 uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer };
2866 const int dst_strides[3] = { dst->y_stride, dst->uv_stride, dst->uv_stride };
2867 const int dst_widths[3] = { dst->y_crop_width, dst->uv_crop_width,
2868 dst->uv_crop_width };
2869 const int dst_heights[3] = { dst->y_crop_height, dst->uv_crop_height,
2870 dst->uv_crop_height };
2871
2872 for (i = 0; i < MAX_MB_PLANE; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002873#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002874 if (src->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002875 av1_highbd_resize_plane(srcs[i], src_heights[i], src_widths[i],
2876 src_strides[i], dsts[i], dst_heights[i],
2877 dst_widths[i], dst_strides[i], bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002878 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002879 av1_resize_plane(srcs[i], src_heights[i], src_widths[i], src_strides[i],
2880 dsts[i], dst_heights[i], dst_widths[i], dst_strides[i]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002881 }
2882#else
Yaowu Xuf883b422016-08-30 14:01:10 -07002883 av1_resize_plane(srcs[i], src_heights[i], src_widths[i], src_strides[i],
2884 dsts[i], dst_heights[i], dst_widths[i], dst_strides[i]);
2885#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002886 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002887 aom_extend_frame_borders(dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002888}
2889
Yaowu Xuf883b422016-08-30 14:01:10 -07002890#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002891static void scale_and_extend_frame(const YV12_BUFFER_CONFIG *src,
2892 YV12_BUFFER_CONFIG *dst, int planes,
2893 int bd) {
2894#else
2895static void scale_and_extend_frame(const YV12_BUFFER_CONFIG *src,
2896 YV12_BUFFER_CONFIG *dst, int planes) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002897#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002898 const int src_w = src->y_crop_width;
2899 const int src_h = src->y_crop_height;
2900 const int dst_w = dst->y_crop_width;
2901 const int dst_h = dst->y_crop_height;
2902 const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer,
2903 src->v_buffer };
2904 const int src_strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
2905 uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer };
2906 const int dst_strides[3] = { dst->y_stride, dst->uv_stride, dst->uv_stride };
2907 const InterpFilterParams interp_filter_params =
Yaowu Xuf883b422016-08-30 14:01:10 -07002908 av1_get_interp_filter_params(EIGHTTAP_REGULAR);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002909 const int16_t *kernel = interp_filter_params.filter_ptr;
2910 const int taps = interp_filter_params.taps;
2911 int x, y, i;
2912
Yaowu Xu637590c2016-11-16 15:15:46 -08002913 assert(planes <= 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002914 for (y = 0; y < dst_h; y += 16) {
2915 for (x = 0; x < dst_w; x += 16) {
2916 for (i = 0; i < planes; ++i) {
2917 const int factor = (i == 0 || i == 3 ? 1 : 2);
2918 const int x_q4 = x * (16 / factor) * src_w / dst_w;
2919 const int y_q4 = y * (16 / factor) * src_h / dst_h;
2920 const int src_stride = src_strides[i];
2921 const int dst_stride = dst_strides[i];
2922 const uint8_t *src_ptr = srcs[i] +
2923 (y / factor) * src_h / dst_h * src_stride +
2924 (x / factor) * src_w / dst_w;
2925 uint8_t *dst_ptr = dsts[i] + (y / factor) * dst_stride + (x / factor);
2926
Yaowu Xuf883b422016-08-30 14:01:10 -07002927#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002928 if (src->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002929 aom_highbd_convolve8(src_ptr, src_stride, dst_ptr, dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002930 &kernel[(x_q4 & 0xf) * taps], 16 * src_w / dst_w,
2931 &kernel[(y_q4 & 0xf) * taps], 16 * src_h / dst_h,
2932 16 / factor, 16 / factor, bd);
2933 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002934 aom_scaled_2d(src_ptr, src_stride, dst_ptr, dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002935 &kernel[(x_q4 & 0xf) * taps], 16 * src_w / dst_w,
2936 &kernel[(y_q4 & 0xf) * taps], 16 * src_h / dst_h,
2937 16 / factor, 16 / factor);
2938 }
2939#else
Yaowu Xuf883b422016-08-30 14:01:10 -07002940 aom_scaled_2d(src_ptr, src_stride, dst_ptr, dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002941 &kernel[(x_q4 & 0xf) * taps], 16 * src_w / dst_w,
2942 &kernel[(y_q4 & 0xf) * taps], 16 * src_h / dst_h,
2943 16 / factor, 16 / factor);
Yaowu Xuf883b422016-08-30 14:01:10 -07002944#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002945 }
2946 }
2947 }
2948
2949 if (planes == 1)
Yaowu Xuf883b422016-08-30 14:01:10 -07002950 aom_extend_frame_borders_y(dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002951 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002952 aom_extend_frame_borders(dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002953}
2954
Yaowu Xuf883b422016-08-30 14:01:10 -07002955static int scale_down(AV1_COMP *cpi, int q) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002956 RATE_CONTROL *const rc = &cpi->rc;
2957 GF_GROUP *const gf_group = &cpi->twopass.gf_group;
2958 int scale = 0;
2959 assert(frame_is_kf_gf_arf(cpi));
2960
2961 if (rc->frame_size_selector == UNSCALED &&
2962 q >= rc->rf_level_maxq[gf_group->rf_level[gf_group->index]]) {
2963 const int max_size_thresh =
2964 (int)(rate_thresh_mult[SCALE_STEP1] *
Yaowu Xuf883b422016-08-30 14:01:10 -07002965 AOMMAX(rc->this_frame_target, rc->avg_frame_bandwidth));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002966 scale = rc->projected_frame_size > max_size_thresh ? 1 : 0;
2967 }
2968 return scale;
2969}
2970
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002971#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002972static int recode_loop_test_global_motion(AV1_COMP *cpi) {
Debargha Mukherjee705544c2016-11-22 08:55:49 -08002973 static const int min_blocks[TRANS_TYPES] = { 0, 60, 120, 180, 240 };
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002974 int i;
2975 int recode = 0;
2976 AV1_COMMON *const cm = &cpi->common;
2977 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
2978 if (cm->global_motion[i].wmtype != IDENTITY &&
Debargha Mukherjee705544c2016-11-22 08:55:49 -08002979 cpi->global_motion_used[i][1] <
2980 min_blocks[cm->global_motion[i].wmtype]) {
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002981 set_default_gmparams(&cm->global_motion[i]);
David Barker43479c62016-11-30 10:34:20 +00002982#if CONFIG_REF_MV
2983 recode = 1;
2984#else
Debargha Mukherjee705544c2016-11-22 08:55:49 -08002985 recode |= (cpi->global_motion_used[i][1] > 0);
David Barker43479c62016-11-30 10:34:20 +00002986#endif
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002987 }
2988 }
2989 return recode;
2990}
2991#endif // CONFIG_GLOBAL_MOTION
2992
Yaowu Xuc27fc142016-08-22 16:08:15 -07002993// Function to test for conditions that indicate we should loop
2994// back and recode a frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07002995static int recode_loop_test(AV1_COMP *cpi, int high_limit, int low_limit, int q,
2996 int maxq, int minq) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002997 const RATE_CONTROL *const rc = &cpi->rc;
Yaowu Xuf883b422016-08-30 14:01:10 -07002998 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002999 const int frame_is_kfgfarf = frame_is_kf_gf_arf(cpi);
3000 int force_recode = 0;
3001
3002 if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
3003 (cpi->sf.recode_loop == ALLOW_RECODE) ||
3004 (frame_is_kfgfarf && (cpi->sf.recode_loop == ALLOW_RECODE_KFARFGF))) {
3005 if (frame_is_kfgfarf && (oxcf->resize_mode == RESIZE_DYNAMIC) &&
3006 scale_down(cpi, q)) {
3007 // Code this group at a lower resolution.
3008 cpi->resize_pending = 1;
3009 return 1;
3010 }
3011
3012 // TODO(agrange) high_limit could be greater than the scale-down threshold.
3013 if ((rc->projected_frame_size > high_limit && q < maxq) ||
3014 (rc->projected_frame_size < low_limit && q > minq)) {
3015 force_recode = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07003016 } else if (cpi->oxcf.rc_mode == AOM_CQ) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003017 // Deal with frame undershoot and whether or not we are
3018 // below the automatically set cq level.
3019 if (q > oxcf->cq_level &&
3020 rc->projected_frame_size < ((rc->this_frame_target * 7) >> 3)) {
3021 force_recode = 1;
3022 }
3023 }
3024 }
3025 return force_recode;
3026}
3027
3028static INLINE int get_free_upsampled_ref_buf(EncRefCntBuffer *ubufs) {
3029 int i;
3030
3031 for (i = 0; i < (REF_FRAMES + 1); i++) {
3032 if (!ubufs[i].ref_count) {
3033 return i;
3034 }
3035 }
3036 return INVALID_IDX;
3037}
3038
3039// Up-sample 1 reference frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07003040static INLINE int upsample_ref_frame(AV1_COMP *cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003041 const YV12_BUFFER_CONFIG *const ref) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003042 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003043 EncRefCntBuffer *ubufs = cpi->upsampled_ref_bufs;
3044 int new_uidx = get_free_upsampled_ref_buf(ubufs);
3045
3046 if (new_uidx == INVALID_IDX) {
3047 return INVALID_IDX;
3048 } else {
3049 YV12_BUFFER_CONFIG *upsampled_ref = &ubufs[new_uidx].buf;
3050
3051 // Can allocate buffer for Y plane only.
3052 if (upsampled_ref->buffer_alloc_sz < (ref->buffer_alloc_sz << 6))
Yaowu Xuf883b422016-08-30 14:01:10 -07003053 if (aom_realloc_frame_buffer(upsampled_ref, (cm->width << 3),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003054 (cm->height << 3), cm->subsampling_x,
3055 cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -07003056#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003057 cm->use_highbitdepth,
3058#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003059 (AOM_BORDER_IN_PIXELS << 3),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003060 cm->byte_alignment, NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003061 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003062 "Failed to allocate up-sampled frame buffer");
3063
3064// Currently, only Y plane is up-sampled, U, V are not used.
Yaowu Xuf883b422016-08-30 14:01:10 -07003065#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003066 scale_and_extend_frame(ref, upsampled_ref, 1, (int)cm->bit_depth);
3067#else
3068 scale_and_extend_frame(ref, upsampled_ref, 1);
3069#endif
3070 return new_uidx;
3071 }
3072}
3073
3074#define DUMP_REF_FRAME_IMAGES 0
3075
3076#if DUMP_REF_FRAME_IMAGES == 1
Yaowu Xuf883b422016-08-30 14:01:10 -07003077static int dump_one_image(AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003078 const YV12_BUFFER_CONFIG *const ref_buf,
3079 char *file_name) {
3080 int h;
3081 FILE *f_ref = NULL;
3082
3083 if (ref_buf == NULL) {
3084 printf("Frame data buffer is NULL.\n");
Yaowu Xuf883b422016-08-30 14:01:10 -07003085 return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003086 }
3087
3088 if ((f_ref = fopen(file_name, "wb")) == NULL) {
3089 printf("Unable to open file %s to write.\n", file_name);
Yaowu Xuf883b422016-08-30 14:01:10 -07003090 return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003091 }
3092
3093 // --- Y ---
3094 for (h = 0; h < cm->height; ++h) {
3095 fwrite(&ref_buf->y_buffer[h * ref_buf->y_stride], 1, cm->width, f_ref);
3096 }
3097 // --- U ---
3098 for (h = 0; h < (cm->height >> 1); ++h) {
3099 fwrite(&ref_buf->u_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
3100 f_ref);
3101 }
3102 // --- V ---
3103 for (h = 0; h < (cm->height >> 1); ++h) {
3104 fwrite(&ref_buf->v_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
3105 f_ref);
3106 }
3107
3108 fclose(f_ref);
3109
Yaowu Xuf883b422016-08-30 14:01:10 -07003110 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003111}
3112
Yaowu Xuf883b422016-08-30 14:01:10 -07003113static void dump_ref_frame_images(AV1_COMP *cpi) {
3114 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003115 MV_REFERENCE_FRAME ref_frame;
3116
3117 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3118 char file_name[256] = "";
3119 snprintf(file_name, sizeof(file_name), "/tmp/enc_F%d_ref_%d.yuv",
3120 cm->current_video_frame, ref_frame);
3121 dump_one_image(cm, get_ref_frame_buffer(cpi, ref_frame), file_name);
3122 }
3123}
3124#endif // DUMP_REF_FRAME_IMAGES == 1
3125
3126#if CONFIG_EXT_REFS
3127// This function is used to shift the virtual indices of last reference frames
3128// as follows:
3129// LAST_FRAME -> LAST2_FRAME -> LAST3_FRAME
3130// when the LAST_FRAME is updated.
Yaowu Xuf883b422016-08-30 14:01:10 -07003131static INLINE void shift_last_ref_frames(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003132 int ref_frame;
3133 for (ref_frame = LAST_REF_FRAMES - 1; ref_frame > 0; --ref_frame) {
3134 cpi->lst_fb_idxes[ref_frame] = cpi->lst_fb_idxes[ref_frame - 1];
3135
3136 // [0] is allocated to the current coded frame. The statistics for the
Zoe Liuf0e46692016-10-12 12:31:43 -07003137 // reference frames start at [LAST_FRAME], i.e. [1].
Yaowu Xuc27fc142016-08-22 16:08:15 -07003138 if (!cpi->rc.is_src_frame_alt_ref) {
Zoe Liuf0e46692016-10-12 12:31:43 -07003139 memcpy(cpi->interp_filter_selected[ref_frame + LAST_FRAME],
3140 cpi->interp_filter_selected[ref_frame - 1 + LAST_FRAME],
3141 sizeof(cpi->interp_filter_selected[ref_frame - 1 + LAST_FRAME]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003142 }
3143 }
3144}
Zoe Liuf0e46692016-10-12 12:31:43 -07003145#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07003146
Yaowu Xuf883b422016-08-30 14:01:10 -07003147void av1_update_reference_frames(AV1_COMP *cpi) {
3148 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003149 BufferPool *const pool = cm->buffer_pool;
3150 const int use_upsampled_ref = cpi->sf.use_upsampled_references;
3151 int new_uidx = 0;
3152
3153 // NOTE: Save the new show frame buffer index for --test-code=warn, i.e.,
3154 // for the purpose to verify no mismatch between encoder and decoder.
3155 if (cm->show_frame) cpi->last_show_frame_buf_idx = cm->new_fb_idx;
3156
3157 if (use_upsampled_ref) {
3158#if CONFIG_EXT_REFS
3159 if (cm->show_existing_frame) {
3160 new_uidx = cpi->upsampled_ref_idx[cpi->existing_fb_idx_to_show];
3161 // TODO(zoeliu): Once following is confirmed, remove it.
3162 assert(cpi->upsampled_ref_bufs[new_uidx].ref_count > 0);
3163 } else {
3164#endif // CONFIG_EXT_REFS
3165 // Up-sample the current encoded frame.
3166 RefCntBuffer *bufs = pool->frame_bufs;
3167 const YV12_BUFFER_CONFIG *const ref = &bufs[cm->new_fb_idx].buf;
3168
3169 new_uidx = upsample_ref_frame(cpi, ref);
3170#if CONFIG_EXT_REFS
3171 assert(new_uidx != INVALID_IDX);
3172 }
3173#endif // CONFIG_EXT_REFS
3174 }
3175 // At this point the new frame has been encoded.
3176 // If any buffer copy / swapping is signaled it should be done here.
3177 if (cm->frame_type == KEY_FRAME) {
3178 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
3179 cm->new_fb_idx);
3180#if CONFIG_EXT_REFS
3181 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->bwd_fb_idx],
3182 cm->new_fb_idx);
3183#endif // CONFIG_EXT_REFS
3184 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt_fb_idx],
3185 cm->new_fb_idx);
3186
3187 if (use_upsampled_ref) {
3188 uref_cnt_fb(cpi->upsampled_ref_bufs,
3189 &cpi->upsampled_ref_idx[cpi->gld_fb_idx], new_uidx);
3190#if CONFIG_EXT_REFS
3191 uref_cnt_fb(cpi->upsampled_ref_bufs,
3192 &cpi->upsampled_ref_idx[cpi->bwd_fb_idx], new_uidx);
3193#endif // CONFIG_EXT_REFS
3194 uref_cnt_fb(cpi->upsampled_ref_bufs,
3195 &cpi->upsampled_ref_idx[cpi->alt_fb_idx], new_uidx);
3196 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003197 } else if (av1_preserve_existing_gf(cpi)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003198 // We have decided to preserve the previously existing golden frame as our
3199 // new ARF frame. However, in the short term in function
Yaowu Xuf883b422016-08-30 14:01:10 -07003200 // av1_bitstream.c::get_refresh_mask() we left it in the GF slot and, if
Yaowu Xuc27fc142016-08-22 16:08:15 -07003201 // we're updating the GF with the current decoded frame, we save it to the
3202 // ARF slot instead.
3203 // We now have to update the ARF with the current frame and swap gld_fb_idx
3204 // and alt_fb_idx so that, overall, we've stored the old GF in the new ARF
3205 // slot and, if we're updating the GF, the current frame becomes the new GF.
3206 int tmp;
3207
3208 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt_fb_idx],
3209 cm->new_fb_idx);
3210 if (use_upsampled_ref)
3211 uref_cnt_fb(cpi->upsampled_ref_bufs,
3212 &cpi->upsampled_ref_idx[cpi->alt_fb_idx], new_uidx);
3213
3214 tmp = cpi->alt_fb_idx;
3215 cpi->alt_fb_idx = cpi->gld_fb_idx;
3216 cpi->gld_fb_idx = tmp;
3217
3218#if CONFIG_EXT_REFS
3219 // We need to modify the mapping accordingly
3220 cpi->arf_map[0] = cpi->alt_fb_idx;
3221#endif
3222// TODO(zoeliu): Do we need to copy cpi->interp_filter_selected[0] over to
3223// cpi->interp_filter_selected[GOLDEN_FRAME]?
3224#if CONFIG_EXT_REFS
3225 } else if (cpi->rc.is_last_bipred_frame) {
3226 // Refresh the LAST_FRAME with the BWDREF_FRAME and retire the LAST3_FRAME
3227 // by updating the virtual indices. Note that the frame BWDREF_FRAME points
3228 // to now should be retired, and it should not be used before refreshed.
3229 int tmp = cpi->lst_fb_idxes[LAST_REF_FRAMES - 1];
3230
3231 shift_last_ref_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003232 cpi->lst_fb_idxes[0] = cpi->bwd_fb_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003233 cpi->bwd_fb_idx = tmp;
Zoe Liuf0e46692016-10-12 12:31:43 -07003234
3235 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3236 cpi->interp_filter_selected[BWDREF_FRAME],
3237 sizeof(cpi->interp_filter_selected[BWDREF_FRAME]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003238 } else if (cpi->rc.is_src_frame_ext_arf && cm->show_existing_frame) {
3239 // Deal with the special case for showing existing internal ALTREF_FRAME
3240 // Refresh the LAST_FRAME with the ALTREF_FRAME and retire the LAST3_FRAME
3241 // by updating the virtual indices.
3242 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3243 int which_arf = gf_group->arf_ref_idx[gf_group->index];
3244 int tmp = cpi->lst_fb_idxes[LAST_REF_FRAMES - 1];
3245
3246 shift_last_ref_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003247 cpi->lst_fb_idxes[0] = cpi->alt_fb_idx;
Zoe Liuf0e46692016-10-12 12:31:43 -07003248 cpi->alt_fb_idx = tmp;
3249
3250 // We need to modify the mapping accordingly
3251 cpi->arf_map[which_arf] = cpi->alt_fb_idx;
3252
Yaowu Xuc27fc142016-08-22 16:08:15 -07003253 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3254 cpi->interp_filter_selected[ALTREF_FRAME + which_arf],
3255 sizeof(cpi->interp_filter_selected[ALTREF_FRAME + which_arf]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003256#endif // CONFIG_EXT_REFS
3257 } else { /* For non key/golden frames */
3258 if (cpi->refresh_alt_ref_frame) {
3259 int arf_idx = cpi->alt_fb_idx;
3260 int which_arf = 0;
3261#if CONFIG_EXT_REFS
3262 if (cpi->oxcf.pass == 2) {
3263 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3264 which_arf = gf_group->arf_update_idx[gf_group->index];
3265 arf_idx = cpi->arf_map[which_arf];
3266 }
3267#else
3268 if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
3269 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3270 arf_idx = gf_group->arf_update_idx[gf_group->index];
3271 }
3272#endif // CONFIG_EXT_REFS
3273 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[arf_idx], cm->new_fb_idx);
3274 if (use_upsampled_ref)
3275 uref_cnt_fb(cpi->upsampled_ref_bufs, &cpi->upsampled_ref_idx[arf_idx],
3276 new_uidx);
3277
3278 memcpy(cpi->interp_filter_selected[ALTREF_FRAME + which_arf],
3279 cpi->interp_filter_selected[0],
3280 sizeof(cpi->interp_filter_selected[0]));
3281 }
3282
3283 if (cpi->refresh_golden_frame) {
3284 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
3285 cm->new_fb_idx);
3286 if (use_upsampled_ref)
3287 uref_cnt_fb(cpi->upsampled_ref_bufs,
3288 &cpi->upsampled_ref_idx[cpi->gld_fb_idx], new_uidx);
3289
Zoe Liuf0e46692016-10-12 12:31:43 -07003290#if !CONFIG_EXT_REFS
3291 if (!cpi->rc.is_src_frame_alt_ref)
3292#endif // !CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07003293 memcpy(cpi->interp_filter_selected[GOLDEN_FRAME],
3294 cpi->interp_filter_selected[0],
3295 sizeof(cpi->interp_filter_selected[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003296 }
3297
3298#if CONFIG_EXT_REFS
3299 if (cpi->refresh_bwd_ref_frame) {
3300 if (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs) {
3301 // We have swapped the virtual indices to allow bwd_ref_frame to use
3302 // ALT0 as reference frame. We need to swap them back.
3303 // NOTE: The ALT_REFs' are indexed reversely, and ALT0 refers to the
3304 // farthest ALT_REF from the first frame in the gf group.
3305 int tmp = cpi->arf_map[0];
3306 cpi->arf_map[0] = cpi->alt_fb_idx;
3307 cpi->alt_fb_idx = cpi->bwd_fb_idx;
3308 cpi->bwd_fb_idx = tmp;
3309 }
Zoe Liuf0e46692016-10-12 12:31:43 -07003310
Yaowu Xuc27fc142016-08-22 16:08:15 -07003311 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->bwd_fb_idx],
3312 cm->new_fb_idx);
3313 if (use_upsampled_ref)
3314 uref_cnt_fb(cpi->upsampled_ref_bufs,
3315 &cpi->upsampled_ref_idx[cpi->bwd_fb_idx], new_uidx);
3316
3317 memcpy(cpi->interp_filter_selected[BWDREF_FRAME],
3318 cpi->interp_filter_selected[0],
3319 sizeof(cpi->interp_filter_selected[0]));
3320 }
3321#endif // CONFIG_EXT_REFS
3322 }
3323
3324 if (cpi->refresh_last_frame) {
3325#if CONFIG_EXT_REFS
3326 // NOTE(zoeliu): We have two layers of mapping (1) from the per-frame
3327 // reference to the reference frame buffer virtual index; and then (2) from
3328 // the virtual index to the reference frame buffer physical index:
3329 //
3330 // LAST_FRAME, ..., LAST3_FRAME, ..., ALTREF_FRAME
3331 // | | |
3332 // v v v
3333 // lst_fb_idxes[0], ..., lst_fb_idxes[2], ..., alt_fb_idx
3334 // | | |
3335 // v v v
3336 // ref_frame_map[], ..., ref_frame_map[], ..., ref_frame_map[]
3337 //
3338 // When refresh_last_frame is set, it is intended to retire LAST3_FRAME,
3339 // have the other 2 LAST reference frames shifted as follows:
3340 // LAST_FRAME -> LAST2_FRAME -> LAST3_FRAME
3341 // , and then have LAST_FRAME refreshed by the newly coded frame.
3342 //
3343 // To fulfill it, the decoder will be notified to execute following 2 steps:
3344 //
3345 // (a) To change ref_frame_map[] and have the virtual index of LAST3_FRAME
3346 // to point to the newly coded frame, i.e.
3347 // ref_frame_map[lst_fb_idexes[2]] => new_fb_idx;
3348 //
3349 // (b) To change the 1st layer mapping to have LAST_FRAME mapped to the
3350 // original virtual index of LAST3_FRAME and have the other mappings
3351 // shifted as follows:
3352 // LAST_FRAME, LAST2_FRAME, LAST3_FRAME
3353 // | | |
3354 // v v v
3355 // lst_fb_idxes[2], lst_fb_idxes[0], lst_fb_idxes[1]
3356 int ref_frame;
Zoe Liu5fca7242016-10-10 17:18:57 -07003357
Yaowu Xuc27fc142016-08-22 16:08:15 -07003358 if (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs) {
3359 // We have swapped the virtual indices to use ALT0 as BWD_REF
3360 // and we need to swap them back.
3361 int tmp = cpi->arf_map[0];
3362 cpi->arf_map[0] = cpi->alt_fb_idx;
3363 cpi->alt_fb_idx = cpi->bwd_fb_idx;
3364 cpi->bwd_fb_idx = tmp;
3365 }
Zoe Liu5fca7242016-10-10 17:18:57 -07003366
Yaowu Xuc27fc142016-08-22 16:08:15 -07003367 if (cm->frame_type == KEY_FRAME) {
3368 for (ref_frame = 0; ref_frame < LAST_REF_FRAMES; ++ref_frame) {
3369 ref_cnt_fb(pool->frame_bufs,
3370 &cm->ref_frame_map[cpi->lst_fb_idxes[ref_frame]],
3371 cm->new_fb_idx);
3372
3373 if (use_upsampled_ref)
3374 uref_cnt_fb(cpi->upsampled_ref_bufs,
3375 &cpi->upsampled_ref_idx[cpi->lst_fb_idxes[ref_frame]],
3376 new_uidx);
3377 }
3378 } else {
3379 int tmp;
3380
3381 ref_cnt_fb(pool->frame_bufs,
3382 &cm->ref_frame_map[cpi->lst_fb_idxes[LAST_REF_FRAMES - 1]],
3383 cm->new_fb_idx);
3384
3385 if (use_upsampled_ref)
3386 uref_cnt_fb(
3387 cpi->upsampled_ref_bufs,
3388 &cpi->upsampled_ref_idx[cpi->lst_fb_idxes[LAST_REF_FRAMES - 1]],
3389 new_uidx);
3390
3391 tmp = cpi->lst_fb_idxes[LAST_REF_FRAMES - 1];
3392
3393 shift_last_ref_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003394 cpi->lst_fb_idxes[0] = tmp;
3395
Zoe Liuf0e46692016-10-12 12:31:43 -07003396 assert(cm->show_existing_frame == 0);
3397 // NOTE: Currently only LF_UPDATE and INTNL_OVERLAY_UPDATE frames are to
3398 // refresh the LAST_FRAME.
3399 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3400 cpi->interp_filter_selected[0],
3401 sizeof(cpi->interp_filter_selected[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003402 }
3403#else
3404 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->lst_fb_idx],
3405 cm->new_fb_idx);
3406 if (use_upsampled_ref)
3407 uref_cnt_fb(cpi->upsampled_ref_bufs,
3408 &cpi->upsampled_ref_idx[cpi->lst_fb_idx], new_uidx);
3409 if (!cpi->rc.is_src_frame_alt_ref) {
3410 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3411 cpi->interp_filter_selected[0],
3412 sizeof(cpi->interp_filter_selected[0]));
3413 }
3414#endif // CONFIG_EXT_REFS
3415 }
3416
3417#if DUMP_REF_FRAME_IMAGES == 1
3418 // Dump out all reference frame images.
3419 dump_ref_frame_images(cpi);
3420#endif // DUMP_REF_FRAME_IMAGES
3421}
3422
Yaowu Xuf883b422016-08-30 14:01:10 -07003423static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003424 MACROBLOCKD *xd = &cpi->td.mb.e_mbd;
3425 struct loopfilter *lf = &cm->lf;
3426 if (is_lossless_requested(&cpi->oxcf)) {
3427 lf->filter_level = 0;
3428 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003429 struct aom_usec_timer timer;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003430
Yaowu Xuf883b422016-08-30 14:01:10 -07003431 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003432
Yaowu Xuf883b422016-08-30 14:01:10 -07003433 aom_usec_timer_start(&timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003434
3435#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -07003436 av1_pick_filter_restoration(cpi->Source, cpi, cpi->sf.lpf_pick);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003437#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003438 av1_pick_filter_level(cpi->Source, cpi, cpi->sf.lpf_pick);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003439#endif // CONFIG_LOOP_RESTORATION
3440
Yaowu Xuf883b422016-08-30 14:01:10 -07003441 aom_usec_timer_mark(&timer);
3442 cpi->time_pick_lpf += aom_usec_timer_elapsed(&timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003443 }
3444
3445 if (lf->filter_level > 0) {
3446#if CONFIG_VAR_TX || CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07003447 av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003448#else
3449 if (cpi->num_workers > 1)
Yaowu Xuf883b422016-08-30 14:01:10 -07003450 av1_loop_filter_frame_mt(cm->frame_to_show, cm, xd->plane,
3451 lf->filter_level, 0, 0, cpi->workers,
3452 cpi->num_workers, &cpi->lf_row_sync);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003453 else
Yaowu Xuf883b422016-08-30 14:01:10 -07003454 av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003455#endif
3456 }
Steinar Midtskogen5d56f4d2016-09-25 09:23:16 +02003457#if CONFIG_DERING
3458 if (is_lossless_requested(&cpi->oxcf)) {
3459 cm->dering_level = 0;
3460 } else {
3461 cm->dering_level =
3462 av1_dering_search(cm->frame_to_show, cpi->Source, cm, xd);
3463 av1_dering_frame(cm->frame_to_show, cm, xd, cm->dering_level);
3464 }
3465#endif // CONFIG_DERING
3466
Steinar Midtskogend06588a2016-05-06 13:48:20 +02003467#if CONFIG_CLPF
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003468 cm->clpf_strength_y = cm->clpf_strength_u = cm->clpf_strength_v = 0;
Yaowu Xud71be782016-10-14 08:47:03 -07003469 cm->clpf_size = CLPF_64X64;
3470
3471 // Allocate buffer to hold the status of all filter blocks:
3472 // 1 = On, 0 = off, -1 = implicitly off
3473 {
3474 int size;
3475 cm->clpf_stride = ((cm->frame_to_show->y_crop_width + MIN_FB_SIZE - 1) &
3476 ~(MIN_FB_SIZE - 1)) >>
3477 MIN_FB_SIZE_LOG2;
3478 size = cm->clpf_stride *
3479 ((cm->frame_to_show->y_crop_height + MIN_FB_SIZE - 1) &
3480 ~(MIN_FB_SIZE - 1)) >>
3481 MIN_FB_SIZE_LOG2;
3482 CHECK_MEM_ERROR(cm, cm->clpf_blocks, aom_malloc(size));
3483 memset(cm->clpf_blocks, CLPF_NOFLAG, size);
3484 }
3485
Steinar Midtskogend06588a2016-05-06 13:48:20 +02003486 if (!is_lossless_requested(&cpi->oxcf)) {
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003487 const YV12_BUFFER_CONFIG *const frame = cm->frame_to_show;
3488
Steinar Midtskogen499deb92016-09-02 10:56:54 +02003489 // Find the best strength and block size for the entire frame
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003490 int fb_size_log2, strength_y, strength_u, strength_v;
3491 av1_clpf_test_frame(frame, cpi->Source, cm, &strength_y, &fb_size_log2,
3492 AOM_PLANE_Y);
Steinar Midtskogen2e40cc42016-09-21 12:39:13 +02003493 av1_clpf_test_frame(frame, cpi->Source, cm, &strength_u, 0, AOM_PLANE_U);
3494 av1_clpf_test_frame(frame, cpi->Source, cm, &strength_v, 0, AOM_PLANE_V);
Steinar Midtskogend06588a2016-05-06 13:48:20 +02003495
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003496 if (strength_y) {
Steinar Midtskogen499deb92016-09-02 10:56:54 +02003497 // Apply the filter using the chosen strength
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003498 cm->clpf_strength_y = strength_y - (strength_y == 4);
Steinar Midtskogen499deb92016-09-02 10:56:54 +02003499 cm->clpf_size =
Yaowu Xud71be782016-10-14 08:47:03 -07003500 fb_size_log2 ? fb_size_log2 - MAX_FB_SIZE_LOG2 + 3 : CLPF_NOSIZE;
3501 av1_clpf_frame(frame, cpi->Source, cm, cm->clpf_size != CLPF_NOSIZE,
3502 strength_y, 4 + cm->clpf_size, AOM_PLANE_Y,
3503 av1_clpf_decision);
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003504 }
3505 if (strength_u) {
3506 cm->clpf_strength_u = strength_u - (strength_u == 4);
Yaowu Xud71be782016-10-14 08:47:03 -07003507 av1_clpf_frame(frame, NULL, cm, 0, strength_u, 4, AOM_PLANE_U, NULL);
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003508 }
3509 if (strength_v) {
3510 cm->clpf_strength_v = strength_v - (strength_v == 4);
Yaowu Xud71be782016-10-14 08:47:03 -07003511 av1_clpf_frame(frame, NULL, cm, 0, strength_v, 4, AOM_PLANE_V, NULL);
Steinar Midtskogend06588a2016-05-06 13:48:20 +02003512 }
3513 }
3514#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003515#if CONFIG_LOOP_RESTORATION
Debargha Mukherjeea43a2d92017-01-03 15:14:57 -08003516 if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
3517 cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
3518 cm->rst_info[2].frame_restoration_type != RESTORE_NONE) {
3519 av1_loop_restoration_frame(cm->frame_to_show, cm, cm->rst_info, 7, 0, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003520 }
3521#endif // CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -07003522 aom_extend_frame_inner_borders(cm->frame_to_show);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003523}
3524
Yaowu Xuf883b422016-08-30 14:01:10 -07003525static INLINE void alloc_frame_mvs(AV1_COMMON *const cm, int buffer_idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003526 RefCntBuffer *const new_fb_ptr = &cm->buffer_pool->frame_bufs[buffer_idx];
3527 if (new_fb_ptr->mvs == NULL || new_fb_ptr->mi_rows < cm->mi_rows ||
3528 new_fb_ptr->mi_cols < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003529 aom_free(new_fb_ptr->mvs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003530 CHECK_MEM_ERROR(cm, new_fb_ptr->mvs,
Yaowu Xuf883b422016-08-30 14:01:10 -07003531 (MV_REF *)aom_calloc(cm->mi_rows * cm->mi_cols,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003532 sizeof(*new_fb_ptr->mvs)));
3533 new_fb_ptr->mi_rows = cm->mi_rows;
3534 new_fb_ptr->mi_cols = cm->mi_cols;
3535 }
3536}
3537
Yaowu Xuf883b422016-08-30 14:01:10 -07003538void av1_scale_references(AV1_COMP *cpi) {
3539 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003540 MV_REFERENCE_FRAME ref_frame;
Yaowu Xuf883b422016-08-30 14:01:10 -07003541 const AOM_REFFRAME ref_mask[INTER_REFS_PER_FRAME] = {
3542 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003543#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003544 AOM_LAST2_FLAG,
3545 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003546#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003547 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003548#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003549 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003550#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003551 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07003552 };
3553
3554 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003555 // Need to convert from AOM_REFFRAME to index into ref_mask (subtract 1).
Yaowu Xuc27fc142016-08-22 16:08:15 -07003556 if (cpi->ref_frame_flags & ref_mask[ref_frame - 1]) {
3557 BufferPool *const pool = cm->buffer_pool;
3558 const YV12_BUFFER_CONFIG *const ref =
3559 get_ref_frame_buffer(cpi, ref_frame);
3560
3561 if (ref == NULL) {
3562 cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
3563 continue;
3564 }
3565
Yaowu Xuf883b422016-08-30 14:01:10 -07003566#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003567 if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
3568 RefCntBuffer *new_fb_ptr = NULL;
3569 int force_scaling = 0;
3570 int new_fb = cpi->scaled_ref_idx[ref_frame - 1];
3571 if (new_fb == INVALID_IDX) {
3572 new_fb = get_free_fb(cm);
3573 force_scaling = 1;
3574 }
3575 if (new_fb == INVALID_IDX) return;
3576 new_fb_ptr = &pool->frame_bufs[new_fb];
3577 if (force_scaling || new_fb_ptr->buf.y_crop_width != cm->width ||
3578 new_fb_ptr->buf.y_crop_height != cm->height) {
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003579 if (aom_realloc_frame_buffer(
3580 &new_fb_ptr->buf, cm->width, cm->height, cm->subsampling_x,
3581 cm->subsampling_y, cm->use_highbitdepth, AOM_BORDER_IN_PIXELS,
3582 cm->byte_alignment, NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003583 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003584 "Failed to allocate frame buffer");
3585 scale_and_extend_frame(ref, &new_fb_ptr->buf, MAX_MB_PLANE,
3586 (int)cm->bit_depth);
3587 cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
3588 alloc_frame_mvs(cm, new_fb);
3589 }
3590#else
3591 if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
3592 RefCntBuffer *new_fb_ptr = NULL;
3593 int force_scaling = 0;
3594 int new_fb = cpi->scaled_ref_idx[ref_frame - 1];
3595 if (new_fb == INVALID_IDX) {
3596 new_fb = get_free_fb(cm);
3597 force_scaling = 1;
3598 }
3599 if (new_fb == INVALID_IDX) return;
3600 new_fb_ptr = &pool->frame_bufs[new_fb];
3601 if (force_scaling || new_fb_ptr->buf.y_crop_width != cm->width ||
3602 new_fb_ptr->buf.y_crop_height != cm->height) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003603 if (aom_realloc_frame_buffer(&new_fb_ptr->buf, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003604 cm->subsampling_x, cm->subsampling_y,
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003605 AOM_BORDER_IN_PIXELS, cm->byte_alignment,
3606 NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003607 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003608 "Failed to allocate frame buffer");
3609 scale_and_extend_frame(ref, &new_fb_ptr->buf, MAX_MB_PLANE);
3610 cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
3611 alloc_frame_mvs(cm, new_fb);
3612 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003613#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003614
3615 if (cpi->sf.use_upsampled_references &&
3616 (force_scaling || new_fb_ptr->buf.y_crop_width != cm->width ||
3617 new_fb_ptr->buf.y_crop_height != cm->height)) {
3618 const int map_idx = get_ref_frame_map_idx(cpi, ref_frame);
3619 EncRefCntBuffer *ubuf =
3620 &cpi->upsampled_ref_bufs[cpi->upsampled_ref_idx[map_idx]];
3621
Yaowu Xuf883b422016-08-30 14:01:10 -07003622 if (aom_realloc_frame_buffer(&ubuf->buf, (cm->width << 3),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003623 (cm->height << 3), cm->subsampling_x,
3624 cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -07003625#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003626 cm->use_highbitdepth,
3627#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003628 (AOM_BORDER_IN_PIXELS << 3),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003629 cm->byte_alignment, NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003630 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003631 "Failed to allocate up-sampled frame buffer");
Yaowu Xuf883b422016-08-30 14:01:10 -07003632#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003633 scale_and_extend_frame(&new_fb_ptr->buf, &ubuf->buf, 1,
3634 (int)cm->bit_depth);
3635#else
3636 scale_and_extend_frame(&new_fb_ptr->buf, &ubuf->buf, 1);
3637#endif
3638 }
3639 } else {
3640 const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
3641 RefCntBuffer *const buf = &pool->frame_bufs[buf_idx];
3642 buf->buf.y_crop_width = ref->y_crop_width;
3643 buf->buf.y_crop_height = ref->y_crop_height;
3644 cpi->scaled_ref_idx[ref_frame - 1] = buf_idx;
3645 ++buf->ref_count;
3646 }
3647 } else {
3648 if (cpi->oxcf.pass != 0) cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
3649 }
3650 }
3651}
3652
Yaowu Xuf883b422016-08-30 14:01:10 -07003653static void release_scaled_references(AV1_COMP *cpi) {
3654 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003655 int i;
3656 if (cpi->oxcf.pass == 0) {
3657 // Only release scaled references under certain conditions:
3658 // if reference will be updated, or if scaled reference has same resolution.
3659 int refresh[INTER_REFS_PER_FRAME];
3660 refresh[0] = (cpi->refresh_last_frame) ? 1 : 0;
3661#if CONFIG_EXT_REFS
3662 refresh[1] = refresh[2] = 0;
3663 refresh[3] = (cpi->refresh_golden_frame) ? 1 : 0;
3664 refresh[4] = (cpi->refresh_bwd_ref_frame) ? 1 : 0;
3665 refresh[5] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
3666#else
3667 refresh[1] = (cpi->refresh_golden_frame) ? 1 : 0;
3668 refresh[2] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
3669#endif // CONFIG_EXT_REFS
3670 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
3671 const int idx = cpi->scaled_ref_idx[i - 1];
3672 RefCntBuffer *const buf =
3673 idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[idx] : NULL;
3674 const YV12_BUFFER_CONFIG *const ref = get_ref_frame_buffer(cpi, i);
3675 if (buf != NULL &&
3676 (refresh[i - 1] || (buf->buf.y_crop_width == ref->y_crop_width &&
3677 buf->buf.y_crop_height == ref->y_crop_height))) {
3678 --buf->ref_count;
3679 cpi->scaled_ref_idx[i - 1] = INVALID_IDX;
3680 }
3681 }
3682 } else {
3683 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) {
3684 const int idx = cpi->scaled_ref_idx[i];
3685 RefCntBuffer *const buf =
3686 idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[idx] : NULL;
3687 if (buf != NULL) {
3688 --buf->ref_count;
3689 cpi->scaled_ref_idx[i] = INVALID_IDX;
3690 }
3691 }
3692 }
3693}
3694
3695static void full_to_model_count(unsigned int *model_count,
3696 unsigned int *full_count) {
3697 int n;
3698 model_count[ZERO_TOKEN] = full_count[ZERO_TOKEN];
3699 model_count[ONE_TOKEN] = full_count[ONE_TOKEN];
3700 model_count[TWO_TOKEN] = full_count[TWO_TOKEN];
3701 for (n = THREE_TOKEN; n < EOB_TOKEN; ++n)
3702 model_count[TWO_TOKEN] += full_count[n];
3703 model_count[EOB_MODEL_TOKEN] = full_count[EOB_TOKEN];
3704}
3705
Yaowu Xuf883b422016-08-30 14:01:10 -07003706void av1_full_to_model_counts(av1_coeff_count_model *model_count,
3707 av1_coeff_count *full_count) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003708 int i, j, k, l;
3709
3710 for (i = 0; i < PLANE_TYPES; ++i)
3711 for (j = 0; j < REF_TYPES; ++j)
3712 for (k = 0; k < COEF_BANDS; ++k)
3713 for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l)
3714 full_to_model_count(model_count[i][j][k][l], full_count[i][j][k][l]);
3715}
3716
3717#if 0 && CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07003718static void output_frame_level_debug_stats(AV1_COMP *cpi) {
3719 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003720 FILE *const f = fopen("tmp.stt", cm->current_video_frame ? "a" : "w");
3721 int64_t recon_err;
3722
Yaowu Xuf883b422016-08-30 14:01:10 -07003723 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003724
Yaowu Xuf883b422016-08-30 14:01:10 -07003725 recon_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003726
3727 if (cpi->twopass.total_left_stats.coded_error != 0.0)
Yunqing Wang8c1e57c2016-10-25 15:15:23 -07003728 fprintf(f, "%10u %dx%d %d %d %10d %10d %10d %10d"
Yaowu Xuc27fc142016-08-22 16:08:15 -07003729 "%10"PRId64" %10"PRId64" %5d %5d %10"PRId64" "
3730 "%10"PRId64" %10"PRId64" %10d "
3731 "%7.2lf %7.2lf %7.2lf %7.2lf %7.2lf"
3732 "%6d %6d %5d %5d %5d "
3733 "%10"PRId64" %10.3lf"
3734 "%10lf %8u %10"PRId64" %10d %10d %10d\n",
3735 cpi->common.current_video_frame,
3736 cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003737 cpi->rc.source_alt_ref_pending,
3738 cpi->rc.source_alt_ref_active,
3739 cpi->rc.this_frame_target,
3740 cpi->rc.projected_frame_size,
3741 cpi->rc.projected_frame_size / cpi->common.MBs,
3742 (cpi->rc.projected_frame_size - cpi->rc.this_frame_target),
3743 cpi->rc.vbr_bits_off_target,
3744 cpi->rc.vbr_bits_off_target_fast,
3745 cpi->twopass.extend_minq,
3746 cpi->twopass.extend_minq_fast,
3747 cpi->rc.total_target_vs_actual,
3748 (cpi->rc.starting_buffer_level - cpi->rc.bits_off_target),
3749 cpi->rc.total_actual_bits, cm->base_qindex,
Yaowu Xuf883b422016-08-30 14:01:10 -07003750 av1_convert_qindex_to_q(cm->base_qindex, cm->bit_depth),
3751 (double)av1_dc_quant(cm->base_qindex, 0, cm->bit_depth) / 4.0,
3752 av1_convert_qindex_to_q(cpi->twopass.active_worst_quality,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003753 cm->bit_depth),
3754 cpi->rc.avg_q,
Yaowu Xuf883b422016-08-30 14:01:10 -07003755 av1_convert_qindex_to_q(cpi->oxcf.cq_level, cm->bit_depth),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003756 cpi->refresh_last_frame, cpi->refresh_golden_frame,
3757 cpi->refresh_alt_ref_frame, cm->frame_type, cpi->rc.gfu_boost,
3758 cpi->twopass.bits_left,
3759 cpi->twopass.total_left_stats.coded_error,
3760 cpi->twopass.bits_left /
3761 (1 + cpi->twopass.total_left_stats.coded_error),
3762 cpi->tot_recode_hits, recon_err, cpi->rc.kf_boost,
3763 cpi->twopass.kf_zeromotion_pct,
3764 cpi->twopass.fr_content_type);
3765
3766 fclose(f);
3767
3768 if (0) {
3769 FILE *const fmodes = fopen("Modes.stt", "a");
3770 int i;
3771
3772 fprintf(fmodes, "%6d:%1d:%1d:%1d ", cpi->common.current_video_frame,
3773 cm->frame_type, cpi->refresh_golden_frame,
3774 cpi->refresh_alt_ref_frame);
3775
3776 for (i = 0; i < MAX_MODES; ++i)
3777 fprintf(fmodes, "%5d ", cpi->mode_chosen_counts[i]);
3778
3779 fprintf(fmodes, "\n");
3780
3781 fclose(fmodes);
3782 }
3783}
3784#endif
3785
Yaowu Xuf883b422016-08-30 14:01:10 -07003786static void set_mv_search_params(AV1_COMP *cpi) {
3787 const AV1_COMMON *const cm = &cpi->common;
3788 const unsigned int max_mv_def = AOMMIN(cm->width, cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003789
3790 // Default based on max resolution.
Yaowu Xuf883b422016-08-30 14:01:10 -07003791 cpi->mv_step_param = av1_init_search_range(max_mv_def);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003792
3793 if (cpi->sf.mv.auto_mv_step_size) {
3794 if (frame_is_intra_only(cm)) {
3795 // Initialize max_mv_magnitude for use in the first INTER frame
3796 // after a key/intra-only frame.
3797 cpi->max_mv_magnitude = max_mv_def;
3798 } else {
3799 if (cm->show_frame) {
3800 // Allow mv_steps to correspond to twice the max mv magnitude found
3801 // in the previous frame, capped by the default max_mv_magnitude based
3802 // on resolution.
Yaowu Xuf883b422016-08-30 14:01:10 -07003803 cpi->mv_step_param = av1_init_search_range(
3804 AOMMIN(max_mv_def, 2 * cpi->max_mv_magnitude));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003805 }
3806 cpi->max_mv_magnitude = 0;
3807 }
3808 }
3809}
3810
Yaowu Xuf883b422016-08-30 14:01:10 -07003811static void set_size_independent_vars(AV1_COMP *cpi) {
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08003812#if CONFIG_GLOBAL_MOTION
3813 int i;
3814 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
3815 set_default_gmparams(&cpi->common.global_motion[i]);
3816 }
3817 cpi->global_motion_search_done = 0;
3818#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07003819 av1_set_speed_features_framesize_independent(cpi);
3820 av1_set_rd_speed_thresholds(cpi);
3821 av1_set_rd_speed_thresholds_sub8x8(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003822 cpi->common.interp_filter = cpi->sf.default_interp_filter;
3823}
3824
Yaowu Xuf883b422016-08-30 14:01:10 -07003825static void set_size_dependent_vars(AV1_COMP *cpi, int *q, int *bottom_index,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003826 int *top_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003827 AV1_COMMON *const cm = &cpi->common;
3828 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003829
3830 // Setup variables that depend on the dimensions of the frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07003831 av1_set_speed_features_framesize_dependent(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003832
3833 // Decide q and q bounds.
Yaowu Xuf883b422016-08-30 14:01:10 -07003834 *q = av1_rc_pick_q_and_bounds(cpi, bottom_index, top_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003835
3836 if (!frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003837 av1_set_high_precision_mv(cpi, (*q) < HIGH_PRECISION_MV_QTHRESH);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003838 }
3839
3840 // Configure experimental use of segmentation for enhanced coding of
3841 // static regions if indicated.
3842 // Only allowed in the second pass of a two pass encode, as it requires
3843 // lagged coding, and if the relevant speed feature flag is set.
3844 if (oxcf->pass == 2 && cpi->sf.static_segmentation)
3845 configure_static_seg_features(cpi);
3846}
3847
Yaowu Xuf883b422016-08-30 14:01:10 -07003848static void init_motion_estimation(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003849 int y_stride = cpi->scaled_source.y_stride;
3850
3851 if (cpi->sf.mv.search_method == NSTEP) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003852 av1_init3smotion_compensation(&cpi->ss_cfg, y_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003853 } else if (cpi->sf.mv.search_method == DIAMOND) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003854 av1_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003855 }
3856}
3857
Yaowu Xuf883b422016-08-30 14:01:10 -07003858static void set_frame_size(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003859 int ref_frame;
Yaowu Xuf883b422016-08-30 14:01:10 -07003860 AV1_COMMON *const cm = &cpi->common;
3861 AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003862 MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
3863
Yaowu Xuf883b422016-08-30 14:01:10 -07003864 if (oxcf->pass == 2 && oxcf->rc_mode == AOM_VBR &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003865 ((oxcf->resize_mode == RESIZE_FIXED && cm->current_video_frame == 0) ||
3866 (oxcf->resize_mode == RESIZE_DYNAMIC && cpi->resize_pending))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003867 av1_calculate_coded_size(cpi, &oxcf->scaled_frame_width,
3868 &oxcf->scaled_frame_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003869
3870 // There has been a change in frame size.
Yaowu Xuf883b422016-08-30 14:01:10 -07003871 av1_set_size_literal(cpi, oxcf->scaled_frame_width,
3872 oxcf->scaled_frame_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003873 }
3874
Yaowu Xuf883b422016-08-30 14:01:10 -07003875 if (oxcf->pass == 0 && oxcf->rc_mode == AOM_CBR &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003876 oxcf->resize_mode == RESIZE_DYNAMIC) {
3877 if (cpi->resize_pending == 1) {
3878 oxcf->scaled_frame_width =
3879 (cm->width * cpi->resize_scale_num) / cpi->resize_scale_den;
3880 oxcf->scaled_frame_height =
3881 (cm->height * cpi->resize_scale_num) / cpi->resize_scale_den;
3882 } else if (cpi->resize_pending == -1) {
3883 // Go back up to original size.
3884 oxcf->scaled_frame_width = oxcf->width;
3885 oxcf->scaled_frame_height = oxcf->height;
3886 }
3887 if (cpi->resize_pending != 0) {
3888 // There has been a change in frame size.
Yaowu Xuf883b422016-08-30 14:01:10 -07003889 av1_set_size_literal(cpi, oxcf->scaled_frame_width,
3890 oxcf->scaled_frame_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003891
3892 // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed.
3893 set_mv_search_params(cpi);
3894 }
3895 }
3896
3897 if (oxcf->pass == 2) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003898 av1_set_target_rate(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003899 }
3900
3901 alloc_frame_mvs(cm, cm->new_fb_idx);
3902
3903 // Reset the frame pointers to the current frame size.
Yaowu Xuf883b422016-08-30 14:01:10 -07003904 if (aom_realloc_frame_buffer(get_frame_new_buffer(cm), cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003905 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -07003906#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003907 cm->use_highbitdepth,
3908#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003909 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
3910 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003911 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003912 "Failed to allocate frame buffer");
3913
3914 alloc_util_frame_buffers(cpi);
3915 init_motion_estimation(cpi);
Debargha Mukherjee874d36d2016-12-14 16:53:17 -08003916#if CONFIG_LOOP_RESTORATION
3917 av1_alloc_restoration_buffers(cm);
3918#endif // CONFIG_LOOP_RESTORATION
Yaowu Xuc27fc142016-08-22 16:08:15 -07003919
3920 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3921 RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - LAST_FRAME];
3922 const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
3923
3924 ref_buf->idx = buf_idx;
3925
3926 if (buf_idx != INVALID_IDX) {
3927 YV12_BUFFER_CONFIG *const buf = &cm->buffer_pool->frame_bufs[buf_idx].buf;
3928 ref_buf->buf = buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07003929#if CONFIG_AOM_HIGHBITDEPTH
3930 av1_setup_scale_factors_for_frame(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003931 &ref_buf->sf, buf->y_crop_width, buf->y_crop_height, cm->width,
3932 cm->height, (buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0);
3933#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003934 av1_setup_scale_factors_for_frame(&ref_buf->sf, buf->y_crop_width,
3935 buf->y_crop_height, cm->width,
3936 cm->height);
3937#endif // CONFIG_AOM_HIGHBITDEPTH
3938 if (av1_is_scaled(&ref_buf->sf)) aom_extend_frame_borders(buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003939 } else {
3940 ref_buf->buf = NULL;
3941 }
3942 }
3943
3944 set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
3945}
3946
Yaowu Xuf883b422016-08-30 14:01:10 -07003947static void reset_use_upsampled_references(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003948 MV_REFERENCE_FRAME ref_frame;
3949
3950 // reset up-sampled reference buffer structure.
3951 init_upsampled_ref_frame_bufs(cpi);
3952
3953 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3954 const YV12_BUFFER_CONFIG *const ref = get_ref_frame_buffer(cpi, ref_frame);
3955 int new_uidx = upsample_ref_frame(cpi, ref);
3956
3957 // Update the up-sampled reference index.
3958 cpi->upsampled_ref_idx[get_ref_frame_map_idx(cpi, ref_frame)] = new_uidx;
3959 cpi->upsampled_ref_bufs[new_uidx].ref_count++;
3960 }
3961}
3962
Yaowu Xuf883b422016-08-30 14:01:10 -07003963static void encode_without_recode_loop(AV1_COMP *cpi) {
3964 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003965 int q = 0, bottom_index = 0, top_index = 0; // Dummy variables.
3966 const int use_upsampled_ref = cpi->sf.use_upsampled_references;
3967
Yaowu Xuf883b422016-08-30 14:01:10 -07003968 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003969
3970 set_frame_size(cpi);
3971
3972 // For 1 pass CBR under dynamic resize mode: use faster scaling for source.
3973 // Only for 2x2 scaling for now.
Yaowu Xuf883b422016-08-30 14:01:10 -07003974 if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == AOM_CBR &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003975 cpi->oxcf.resize_mode == RESIZE_DYNAMIC &&
3976 cpi->un_scaled_source->y_width == (cm->width << 1) &&
3977 cpi->un_scaled_source->y_height == (cm->height << 1)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003978 cpi->Source = av1_scale_if_required_fast(cm, cpi->un_scaled_source,
3979 &cpi->scaled_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003980 if (cpi->unscaled_last_source != NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07003981 cpi->Last_Source = av1_scale_if_required_fast(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003982 cm, cpi->unscaled_last_source, &cpi->scaled_last_source);
3983 } else {
3984 cpi->Source =
Yaowu Xuf883b422016-08-30 14:01:10 -07003985 av1_scale_if_required(cm, cpi->un_scaled_source, &cpi->scaled_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003986 if (cpi->unscaled_last_source != NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07003987 cpi->Last_Source = av1_scale_if_required(cm, cpi->unscaled_last_source,
3988 &cpi->scaled_last_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003989 }
3990
3991 if (frame_is_intra_only(cm) == 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003992 av1_scale_references(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003993 }
3994
3995 set_size_independent_vars(cpi);
3996 set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
3997
3998 // cpi->sf.use_upsampled_references can be different from frame to frame.
3999 // Every time when cpi->sf.use_upsampled_references is changed from 0 to 1.
4000 // The reference frames for this frame have to be up-sampled before encoding.
Yunqing Wangfe1e58e2016-12-12 14:14:41 -08004001 if (!use_upsampled_ref && cpi->sf.use_upsampled_references &&
4002 cm->frame_type != KEY_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004003 reset_use_upsampled_references(cpi);
4004
Yaowu Xuf883b422016-08-30 14:01:10 -07004005 av1_set_quantizer(cm, q);
4006 av1_set_variance_partition_thresholds(cpi, q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004007
4008 setup_frame(cpi);
4009
4010#if CONFIG_ENTROPY
4011 cm->do_subframe_update = cm->tile_cols == 1 && cm->tile_rows == 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07004012 av1_copy(cm->starting_coef_probs, cm->fc->coef_probs);
4013 av1_copy(cpi->subframe_stats.enc_starting_coef_probs, cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004014 cm->coef_probs_update_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07004015 av1_copy(cpi->subframe_stats.coef_probs_buf[0], cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004016#endif // CONFIG_ENTROPY
4017
4018 suppress_active_map(cpi);
4019 // Variance adaptive and in frame q adjustment experiments are mutually
4020 // exclusive.
4021 if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004022 av1_vaq_frame_setup(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004023 } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004024 av1_setup_in_frame_q_adj(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004025 } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004026 av1_cyclic_refresh_setup(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004027 }
4028 apply_active_map(cpi);
4029
4030 // transform / motion compensation build reconstruction frame
Yaowu Xuf883b422016-08-30 14:01:10 -07004031 av1_encode_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004032
4033 // Update some stats from cyclic refresh, and check if we should not update
4034 // golden reference, for 1 pass CBR.
4035 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->frame_type != KEY_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -07004036 (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == AOM_CBR))
4037 av1_cyclic_refresh_check_golden_update(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004038
4039 // Update the skip mb flag probabilities based on the distribution
4040 // seen in the last encoder iteration.
4041 // update_base_skip_probs(cpi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004042 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004043}
4044
Yaowu Xuf883b422016-08-30 14:01:10 -07004045static void encode_with_recode_loop(AV1_COMP *cpi, size_t *size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004046 uint8_t *dest) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004047 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004048 RATE_CONTROL *const rc = &cpi->rc;
4049 int bottom_index, top_index;
4050 int loop_count = 0;
4051 int loop_at_this_size = 0;
4052 int loop = 0;
4053 int overshoot_seen = 0;
4054 int undershoot_seen = 0;
4055 int frame_over_shoot_limit;
4056 int frame_under_shoot_limit;
4057 int q = 0, q_low = 0, q_high = 0;
4058 const int use_upsampled_ref = cpi->sf.use_upsampled_references;
4059
4060 set_size_independent_vars(cpi);
4061
Yaowu Xuc27fc142016-08-22 16:08:15 -07004062 do {
Yaowu Xuf883b422016-08-30 14:01:10 -07004063 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004064
4065 set_frame_size(cpi);
4066
4067 if (loop_count == 0 || cpi->resize_pending != 0) {
4068 set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
4069
Thomas Daede919bd6a2016-10-24 16:31:05 -07004070 // cpi->sf.use_upsampled_references can be different from frame to frame.
4071 // Every time when cpi->sf.use_upsampled_references is changed from 0 to
4072 // 1.
4073 // The reference frames for this frame have to be up-sampled before
4074 // encoding.
Yunqing Wangfe1e58e2016-12-12 14:14:41 -08004075 if (!use_upsampled_ref && cpi->sf.use_upsampled_references &&
4076 cm->frame_type != KEY_FRAME)
Thomas Daede919bd6a2016-10-24 16:31:05 -07004077 reset_use_upsampled_references(cpi);
4078
Yaowu Xuc27fc142016-08-22 16:08:15 -07004079 // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed.
4080 set_mv_search_params(cpi);
4081
4082 // Reset the loop state for new frame size.
4083 overshoot_seen = 0;
4084 undershoot_seen = 0;
4085
4086 // Reconfiguration for change in frame size has concluded.
4087 cpi->resize_pending = 0;
4088
4089 q_low = bottom_index;
4090 q_high = top_index;
4091
4092 loop_at_this_size = 0;
4093 }
4094
4095 // Decide frame size bounds first time through.
4096 if (loop_count == 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004097 av1_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
4098 &frame_under_shoot_limit,
4099 &frame_over_shoot_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004100 }
4101
4102 cpi->Source =
Yaowu Xuf883b422016-08-30 14:01:10 -07004103 av1_scale_if_required(cm, cpi->un_scaled_source, &cpi->scaled_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004104
4105 if (cpi->unscaled_last_source != NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07004106 cpi->Last_Source = av1_scale_if_required(cm, cpi->unscaled_last_source,
4107 &cpi->scaled_last_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004108
4109 if (frame_is_intra_only(cm) == 0) {
4110 if (loop_count > 0) {
4111 release_scaled_references(cpi);
4112 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004113 av1_scale_references(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004114 }
4115
Yaowu Xuf883b422016-08-30 14:01:10 -07004116 av1_set_quantizer(cm, q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004117
4118 if (loop_count == 0) setup_frame(cpi);
4119
4120#if CONFIG_ENTROPY
4121 // Base q-index may have changed, so we need to assign proper default coef
4122 // probs before every iteration.
4123 if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
4124 int i;
Yaowu Xuf883b422016-08-30 14:01:10 -07004125 av1_default_coef_probs(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004126 if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode ||
4127 cm->reset_frame_context == RESET_FRAME_CONTEXT_ALL) {
4128 for (i = 0; i < FRAME_CONTEXTS; ++i) cm->frame_contexts[i] = *cm->fc;
4129 } else if (cm->reset_frame_context == RESET_FRAME_CONTEXT_CURRENT) {
4130 cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
4131 }
4132 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004133
Yaowu Xuc27fc142016-08-22 16:08:15 -07004134 cm->do_subframe_update = cm->tile_cols == 1 && cm->tile_rows == 1;
4135 if (loop_count == 0 || frame_is_intra_only(cm) ||
4136 cm->error_resilient_mode) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004137 av1_copy(cm->starting_coef_probs, cm->fc->coef_probs);
4138 av1_copy(cpi->subframe_stats.enc_starting_coef_probs, cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004139 } else {
4140 if (cm->do_subframe_update) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004141 av1_copy(cm->fc->coef_probs,
4142 cpi->subframe_stats.enc_starting_coef_probs);
4143 av1_copy(cm->starting_coef_probs,
4144 cpi->subframe_stats.enc_starting_coef_probs);
4145 av1_zero(cpi->subframe_stats.coef_counts_buf);
4146 av1_zero(cpi->subframe_stats.eob_counts_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004147 }
4148 }
4149 cm->coef_probs_update_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07004150 av1_copy(cpi->subframe_stats.coef_probs_buf[0], cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004151#endif // CONFIG_ENTROPY
4152
4153 // Variance adaptive and in frame q adjustment experiments are mutually
4154 // exclusive.
4155 if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004156 av1_vaq_frame_setup(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004157 } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004158 av1_setup_in_frame_q_adj(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004159 }
4160
4161 // transform / motion compensation build reconstruction frame
Yaowu Xuf883b422016-08-30 14:01:10 -07004162 av1_encode_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004163
4164 // Update the skip mb flag probabilities based on the distribution
4165 // seen in the last encoder iteration.
4166 // update_base_skip_probs(cpi);
4167
Yaowu Xuf883b422016-08-30 14:01:10 -07004168 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004169
4170 // Dummy pack of the bitstream using up to date stats to get an
4171 // accurate estimate of output frame size to determine if we need
4172 // to recode.
4173 if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) {
4174 save_coding_context(cpi);
4175
Yaowu Xuf883b422016-08-30 14:01:10 -07004176 av1_pack_bitstream(cpi, dest, size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004177
4178 rc->projected_frame_size = (int)(*size) << 3;
4179 restore_coding_context(cpi);
4180
4181 if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1;
4182 }
4183
Yaowu Xuf883b422016-08-30 14:01:10 -07004184 if (cpi->oxcf.rc_mode == AOM_Q) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004185 loop = 0;
4186 } else {
4187 if ((cm->frame_type == KEY_FRAME) && rc->this_key_frame_forced &&
4188 (rc->projected_frame_size < rc->max_frame_bandwidth)) {
4189 int last_q = q;
4190 int64_t kf_err;
4191
4192 int64_t high_err_target = cpi->ambient_err;
4193 int64_t low_err_target = cpi->ambient_err >> 1;
4194
Yaowu Xuf883b422016-08-30 14:01:10 -07004195#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004196 if (cm->use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004197 kf_err = aom_highbd_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004198 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004199 kf_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004200 }
4201#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004202 kf_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
4203#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004204
4205 // Prevent possible divide by zero error below for perfect KF
4206 kf_err += !kf_err;
4207
4208 // The key frame is not good enough or we can afford
4209 // to make it better without undue risk of popping.
4210 if ((kf_err > high_err_target &&
4211 rc->projected_frame_size <= frame_over_shoot_limit) ||
4212 (kf_err > low_err_target &&
4213 rc->projected_frame_size <= frame_under_shoot_limit)) {
4214 // Lower q_high
4215 q_high = q > q_low ? q - 1 : q_low;
4216
4217 // Adjust Q
4218 q = (int)((q * high_err_target) / kf_err);
Yaowu Xuf883b422016-08-30 14:01:10 -07004219 q = AOMMIN(q, (q_high + q_low) >> 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004220 } else if (kf_err < low_err_target &&
4221 rc->projected_frame_size >= frame_under_shoot_limit) {
4222 // The key frame is much better than the previous frame
4223 // Raise q_low
4224 q_low = q < q_high ? q + 1 : q_high;
4225
4226 // Adjust Q
4227 q = (int)((q * low_err_target) / kf_err);
Yaowu Xuf883b422016-08-30 14:01:10 -07004228 q = AOMMIN(q, (q_high + q_low + 1) >> 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004229 }
4230
4231 // Clamp Q to upper and lower limits:
4232 q = clamp(q, q_low, q_high);
4233
4234 loop = q != last_q;
4235 } else if (recode_loop_test(cpi, frame_over_shoot_limit,
4236 frame_under_shoot_limit, q,
Yaowu Xuf883b422016-08-30 14:01:10 -07004237 AOMMAX(q_high, top_index), bottom_index)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004238 // Is the projected frame size out of range and are we allowed
4239 // to attempt to recode.
4240 int last_q = q;
4241 int retries = 0;
4242
4243 if (cpi->resize_pending == 1) {
4244 // Change in frame size so go back around the recode loop.
4245 cpi->rc.frame_size_selector =
4246 SCALE_STEP1 - cpi->rc.frame_size_selector;
4247 cpi->rc.next_frame_size_selector = cpi->rc.frame_size_selector;
4248
4249#if CONFIG_INTERNAL_STATS
4250 ++cpi->tot_recode_hits;
4251#endif
4252 ++loop_count;
4253 loop = 1;
4254 continue;
4255 }
4256
4257 // Frame size out of permitted range:
4258 // Update correction factor & compute new Q to try...
4259
4260 // Frame is too large
4261 if (rc->projected_frame_size > rc->this_frame_target) {
4262 // Special case if the projected size is > the max allowed.
4263 if (rc->projected_frame_size >= rc->max_frame_bandwidth)
4264 q_high = rc->worst_quality;
4265
4266 // Raise Qlow as to at least the current value
4267 q_low = q < q_high ? q + 1 : q_high;
4268
4269 if (undershoot_seen || loop_at_this_size > 1) {
4270 // Update rate_correction_factor unless
Yaowu Xuf883b422016-08-30 14:01:10 -07004271 av1_rc_update_rate_correction_factors(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004272
4273 q = (q_high + q_low + 1) / 2;
4274 } else {
4275 // Update rate_correction_factor unless
Yaowu Xuf883b422016-08-30 14:01:10 -07004276 av1_rc_update_rate_correction_factors(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004277
Yaowu Xuf883b422016-08-30 14:01:10 -07004278 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4279 AOMMAX(q_high, top_index));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004280
4281 while (q < q_low && retries < 10) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004282 av1_rc_update_rate_correction_factors(cpi);
4283 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4284 AOMMAX(q_high, top_index));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004285 retries++;
4286 }
4287 }
4288
4289 overshoot_seen = 1;
4290 } else {
4291 // Frame is too small
4292 q_high = q > q_low ? q - 1 : q_low;
4293
4294 if (overshoot_seen || loop_at_this_size > 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004295 av1_rc_update_rate_correction_factors(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004296 q = (q_high + q_low) / 2;
4297 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004298 av1_rc_update_rate_correction_factors(cpi);
4299 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4300 top_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004301 // Special case reset for qlow for constrained quality.
4302 // This should only trigger where there is very substantial
4303 // undershoot on a frame and the auto cq level is above
4304 // the user passsed in value.
Yaowu Xuf883b422016-08-30 14:01:10 -07004305 if (cpi->oxcf.rc_mode == AOM_CQ && q < q_low) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004306 q_low = q;
4307 }
4308
4309 while (q > q_high && retries < 10) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004310 av1_rc_update_rate_correction_factors(cpi);
4311 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4312 top_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004313 retries++;
4314 }
4315 }
4316
4317 undershoot_seen = 1;
4318 }
4319
4320 // Clamp Q to upper and lower limits:
4321 q = clamp(q, q_low, q_high);
4322
4323 loop = (q != last_q);
4324 } else {
4325 loop = 0;
4326 }
4327 }
4328
4329 // Special case for overlay frame.
4330 if (rc->is_src_frame_alt_ref &&
4331 rc->projected_frame_size < rc->max_frame_bandwidth)
4332 loop = 0;
4333
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08004334#if CONFIG_GLOBAL_MOTION
4335 if (recode_loop_test_global_motion(cpi)) {
4336 loop = 1;
4337 }
4338#endif // CONFIG_GLOBAL_MOTION
4339
Yaowu Xuc27fc142016-08-22 16:08:15 -07004340 if (loop) {
4341 ++loop_count;
4342 ++loop_at_this_size;
4343
4344#if CONFIG_INTERNAL_STATS
4345 ++cpi->tot_recode_hits;
4346#endif
4347 }
4348 } while (loop);
4349}
4350
Yaowu Xuf883b422016-08-30 14:01:10 -07004351static int get_ref_frame_flags(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004352 const int *const map = cpi->common.ref_frame_map;
4353
4354#if CONFIG_EXT_REFS
4355 const int last2_is_last =
4356 map[cpi->lst_fb_idxes[1]] == map[cpi->lst_fb_idxes[0]];
4357 const int last3_is_last =
4358 map[cpi->lst_fb_idxes[2]] == map[cpi->lst_fb_idxes[0]];
4359 const int gld_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[0]];
4360 const int bwd_is_last = map[cpi->bwd_fb_idx] == map[cpi->lst_fb_idxes[0]];
4361 const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idxes[0]];
4362
4363 const int last3_is_last2 =
4364 map[cpi->lst_fb_idxes[2]] == map[cpi->lst_fb_idxes[1]];
4365 const int gld_is_last2 = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[1]];
4366 const int bwd_is_last2 = map[cpi->bwd_fb_idx] == map[cpi->lst_fb_idxes[1]];
4367
4368 const int gld_is_last3 = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[2]];
4369 const int bwd_is_last3 = map[cpi->bwd_fb_idx] == map[cpi->lst_fb_idxes[2]];
4370
4371 const int bwd_is_gld = map[cpi->bwd_fb_idx] == map[cpi->gld_fb_idx];
4372
4373 const int last2_is_alt = map[cpi->lst_fb_idxes[1]] == map[cpi->alt_fb_idx];
4374 const int last3_is_alt = map[cpi->lst_fb_idxes[2]] == map[cpi->alt_fb_idx];
4375 const int gld_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
4376 const int bwd_is_alt = map[cpi->bwd_fb_idx] == map[cpi->alt_fb_idx];
4377#else
4378 const int gld_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx];
4379 const int gld_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
4380 const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx];
4381#endif // CONFIG_EXT_REFS
4382
Yaowu Xuf883b422016-08-30 14:01:10 -07004383 int flags = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004384
4385#if CONFIG_EXT_REFS
4386 // Disable the use of BWDREF_FRAME for non-bipredictive frames.
4387 if (!(cpi->rc.is_bipred_frame || cpi->rc.is_last_bipred_frame ||
4388 (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs)))
Yaowu Xuf883b422016-08-30 14:01:10 -07004389 flags &= ~AOM_BWD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004390#endif // CONFIG_EXT_REFS
4391
Yaowu Xuf883b422016-08-30 14:01:10 -07004392 if (gld_is_last || gld_is_alt) flags &= ~AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004393
Yaowu Xuf883b422016-08-30 14:01:10 -07004394 if (cpi->rc.frames_till_gf_update_due == INT_MAX) flags &= ~AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004395
Yaowu Xuf883b422016-08-30 14:01:10 -07004396 if (alt_is_last) flags &= ~AOM_ALT_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004397
4398#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004399 if (last2_is_last || last2_is_alt) flags &= ~AOM_LAST2_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004400
Yaowu Xuf883b422016-08-30 14:01:10 -07004401 if (last3_is_last || last3_is_last2 || last3_is_alt) flags &= ~AOM_LAST3_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004402
Yaowu Xuf883b422016-08-30 14:01:10 -07004403 if (gld_is_last2 || gld_is_last3) flags &= ~AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004404
4405 if ((bwd_is_last || bwd_is_last2 || bwd_is_last3 || bwd_is_gld ||
4406 bwd_is_alt) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07004407 (flags & AOM_BWD_FLAG))
4408 flags &= ~AOM_BWD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004409#endif // CONFIG_EXT_REFS
4410
4411 return flags;
4412}
4413
Yaowu Xuf883b422016-08-30 14:01:10 -07004414static void set_ext_overrides(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004415 // Overrides the defaults with the externally supplied values with
Yaowu Xuf883b422016-08-30 14:01:10 -07004416 // av1_update_reference() and av1_update_entropy() calls
Yaowu Xuc27fc142016-08-22 16:08:15 -07004417 // Note: The overrides are valid only for the next frame passed
4418 // to encode_frame_to_data_rate() function
4419 if (cpi->ext_refresh_frame_context_pending) {
4420 cpi->common.refresh_frame_context = cpi->ext_refresh_frame_context;
4421 cpi->ext_refresh_frame_context_pending = 0;
4422 }
4423 if (cpi->ext_refresh_frame_flags_pending) {
4424 cpi->refresh_last_frame = cpi->ext_refresh_last_frame;
4425 cpi->refresh_golden_frame = cpi->ext_refresh_golden_frame;
4426 cpi->refresh_alt_ref_frame = cpi->ext_refresh_alt_ref_frame;
4427 cpi->ext_refresh_frame_flags_pending = 0;
4428 }
4429}
4430
Yaowu Xuf883b422016-08-30 14:01:10 -07004431YV12_BUFFER_CONFIG *av1_scale_if_required_fast(AV1_COMMON *cm,
4432 YV12_BUFFER_CONFIG *unscaled,
4433 YV12_BUFFER_CONFIG *scaled) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004434 if (cm->mi_cols * MI_SIZE != unscaled->y_width ||
4435 cm->mi_rows * MI_SIZE != unscaled->y_height) {
4436 // For 2x2 scaling down.
Yaowu Xuf883b422016-08-30 14:01:10 -07004437 aom_scale_frame(unscaled, scaled, unscaled->y_buffer, 9, 2, 1, 2, 1, 0);
4438 aom_extend_frame_borders(scaled);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004439 return scaled;
4440 } else {
4441 return unscaled;
4442 }
4443}
4444
Yaowu Xuf883b422016-08-30 14:01:10 -07004445YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm,
4446 YV12_BUFFER_CONFIG *unscaled,
4447 YV12_BUFFER_CONFIG *scaled) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004448 if (cm->mi_cols * MI_SIZE != unscaled->y_width ||
4449 cm->mi_rows * MI_SIZE != unscaled->y_height) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004450#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004451 scale_and_extend_frame_nonnormative(unscaled, scaled, (int)cm->bit_depth);
4452#else
4453 scale_and_extend_frame_nonnormative(unscaled, scaled);
Yaowu Xuf883b422016-08-30 14:01:10 -07004454#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004455 return scaled;
4456 } else {
4457 return unscaled;
4458 }
4459}
4460
Yaowu Xuf883b422016-08-30 14:01:10 -07004461static void set_arf_sign_bias(AV1_COMP *cpi) {
4462 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004463 int arf_sign_bias;
4464#if CONFIG_EXT_REFS
4465 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
4466 // The arf_sign_bias will be one for internal ARFs'
4467 arf_sign_bias = cpi->rc.source_alt_ref_active &&
4468 (!cpi->refresh_alt_ref_frame ||
4469 (gf_group->rf_level[gf_group->index] == GF_ARF_LOW));
4470#else
4471 if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
4472 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
4473 arf_sign_bias = cpi->rc.source_alt_ref_active &&
4474 (!cpi->refresh_alt_ref_frame ||
4475 (gf_group->rf_level[gf_group->index] == GF_ARF_LOW));
4476 } else {
4477 arf_sign_bias =
4478 (cpi->rc.source_alt_ref_active && !cpi->refresh_alt_ref_frame);
4479 }
Zoe Liu6cfaff92016-10-18 17:12:11 -07004480#endif // CONFIG_EXT_REFS
4481
Yaowu Xuc27fc142016-08-22 16:08:15 -07004482 cm->ref_frame_sign_bias[ALTREF_FRAME] = arf_sign_bias;
4483#if CONFIG_EXT_REFS
4484 cm->ref_frame_sign_bias[BWDREF_FRAME] = cm->ref_frame_sign_bias[ALTREF_FRAME];
4485#endif // CONFIG_EXT_REFS
4486}
4487
Yaowu Xuf883b422016-08-30 14:01:10 -07004488static int setup_interp_filter_search_mask(AV1_COMP *cpi) {
James Zern7b9407a2016-05-18 23:48:05 -07004489 InterpFilter ifilter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004490 int ref_total[TOTAL_REFS_PER_FRAME] = { 0 };
4491 MV_REFERENCE_FRAME ref;
4492 int mask = 0;
4493 int arf_idx = ALTREF_FRAME;
4494
4495#if CONFIG_EXT_REFS
4496 // Get which arf used as ALTREF_FRAME
4497 if (cpi->oxcf.pass == 2)
4498 arf_idx += cpi->twopass.gf_group.arf_ref_idx[cpi->twopass.gf_group.index];
Zoe Liu6cfaff92016-10-18 17:12:11 -07004499#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07004500
4501 if (cpi->common.last_frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame)
4502 return mask;
4503
4504#if CONFIG_EXT_REFS
4505 for (ref = LAST_FRAME; ref < ALTREF_FRAME; ++ref)
4506 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter)
4507 ref_total[ref] += cpi->interp_filter_selected[ref][ifilter];
4508
4509 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter)
4510 ref_total[ref] += cpi->interp_filter_selected[arf_idx][ifilter];
4511#else
4512 for (ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref)
4513 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter)
4514 ref_total[ref] += cpi->interp_filter_selected[ref][ifilter];
Zoe Liu6cfaff92016-10-18 17:12:11 -07004515#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07004516
4517 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter) {
4518 if ((ref_total[LAST_FRAME] &&
4519 cpi->interp_filter_selected[LAST_FRAME][ifilter] == 0) &&
4520#if CONFIG_EXT_REFS
4521 (ref_total[LAST2_FRAME] == 0 ||
4522 cpi->interp_filter_selected[LAST2_FRAME][ifilter] * 50 <
4523 ref_total[LAST2_FRAME]) &&
4524 (ref_total[LAST3_FRAME] == 0 ||
4525 cpi->interp_filter_selected[LAST3_FRAME][ifilter] * 50 <
4526 ref_total[LAST3_FRAME]) &&
4527#endif // CONFIG_EXT_REFS
4528 (ref_total[GOLDEN_FRAME] == 0 ||
4529 cpi->interp_filter_selected[GOLDEN_FRAME][ifilter] * 50 <
4530 ref_total[GOLDEN_FRAME]) &&
4531#if CONFIG_EXT_REFS
4532 (ref_total[BWDREF_FRAME] == 0 ||
4533 cpi->interp_filter_selected[BWDREF_FRAME][ifilter] * 50 <
4534 ref_total[BWDREF_FRAME]) &&
4535#endif // CONFIG_EXT_REFS
4536 (ref_total[ALTREF_FRAME] == 0 ||
4537 cpi->interp_filter_selected[arf_idx][ifilter] * 50 <
4538 ref_total[ALTREF_FRAME]))
4539 mask |= 1 << ifilter;
4540 }
4541 return mask;
4542}
4543
4544#define DUMP_RECON_FRAMES 0
4545
4546#if DUMP_RECON_FRAMES == 1
4547// NOTE(zoeliu): For debug - Output the filtered reconstructed video.
Yaowu Xuf883b422016-08-30 14:01:10 -07004548static void dump_filtered_recon_frames(AV1_COMP *cpi) {
4549 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004550 const YV12_BUFFER_CONFIG *recon_buf = cm->frame_to_show;
4551 int h;
4552 char file_name[256] = "/tmp/enc_filtered_recon.yuv";
4553 FILE *f_recon = NULL;
4554
4555 if (recon_buf == NULL || !cm->show_frame) {
4556 printf("Frame %d is not ready or no show to dump.\n",
4557 cm->current_video_frame);
4558 return;
4559 }
4560
4561 if (cm->current_video_frame == 0) {
4562 if ((f_recon = fopen(file_name, "wb")) == NULL) {
4563 printf("Unable to open file %s to write.\n", file_name);
4564 return;
4565 }
4566 } else {
4567 if ((f_recon = fopen(file_name, "ab")) == NULL) {
4568 printf("Unable to open file %s to append.\n", file_name);
4569 return;
4570 }
4571 }
4572 printf(
4573 "\nFrame=%5d, encode_update_type[%5d]=%1d, show_existing_frame=%d, "
4574 "y_stride=%4d, uv_stride=%4d, width=%4d, height=%4d\n",
4575 cm->current_video_frame, cpi->twopass.gf_group.index,
4576 cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index],
4577 cm->show_existing_frame, recon_buf->y_stride, recon_buf->uv_stride,
4578 cm->width, cm->height);
4579
4580 // --- Y ---
4581 for (h = 0; h < cm->height; ++h) {
4582 fwrite(&recon_buf->y_buffer[h * recon_buf->y_stride], 1, cm->width,
4583 f_recon);
4584 }
4585 // --- U ---
4586 for (h = 0; h < (cm->height >> 1); ++h) {
4587 fwrite(&recon_buf->u_buffer[h * recon_buf->uv_stride], 1, (cm->width >> 1),
4588 f_recon);
4589 }
4590 // --- V ---
4591 for (h = 0; h < (cm->height >> 1); ++h) {
4592 fwrite(&recon_buf->v_buffer[h * recon_buf->uv_stride], 1, (cm->width >> 1),
4593 f_recon);
4594 }
4595
4596 fclose(f_recon);
4597}
4598#endif // DUMP_RECON_FRAMES
4599
Yaowu Xuf883b422016-08-30 14:01:10 -07004600static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004601 uint8_t *dest,
4602 unsigned int *frame_flags) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004603 AV1_COMMON *const cm = &cpi->common;
4604 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004605 struct segmentation *const seg = &cm->seg;
4606 TX_SIZE t;
4607 set_ext_overrides(cpi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004608 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004609
4610 // Set the arf sign bias for this frame.
4611 set_arf_sign_bias(cpi);
Fangwen Fu8d164de2016-12-14 13:40:54 -08004612#if CONFIG_TEMPMV_SIGNALING
4613 // frame type has been decided outside of this function call
4614 cm->cur_frame->intra_only = cm->frame_type == KEY_FRAME || cm->intra_only;
4615 cm->use_prev_frame_mvs =
4616 !cpi->oxcf.disable_tempmv && !cm->cur_frame->intra_only;
4617#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004618
4619#if CONFIG_EXT_REFS
4620 // NOTE:
4621 // (1) Move the setup of the ref_frame_flags upfront as it would be
4622 // determined by the current frame properties;
4623 // (2) The setup of the ref_frame_flags applies to both show_existing_frame's
4624 // and the other cases.
4625 if (cm->current_video_frame > 0)
4626 cpi->ref_frame_flags = get_ref_frame_flags(cpi);
4627
4628 if (cm->show_existing_frame) {
4629 // NOTE(zoeliu): In BIDIR_PRED, the existing frame to show is the current
4630 // BWDREF_FRAME in the reference frame buffer.
4631 cm->frame_type = INTER_FRAME;
4632 cm->show_frame = 1;
4633 cpi->frame_flags = *frame_flags;
4634
4635 // In the case of show_existing frame, we will not send fresh flag
4636 // to decoder. Any change in the reference frame buffer can be done by
4637 // switching the virtual indices.
4638
4639 cpi->refresh_last_frame = 0;
4640 cpi->refresh_golden_frame = 0;
4641 cpi->refresh_bwd_ref_frame = 0;
4642 cpi->refresh_alt_ref_frame = 0;
4643
4644 cpi->rc.is_bwd_ref_frame = 0;
4645 cpi->rc.is_last_bipred_frame = 0;
4646 cpi->rc.is_bipred_frame = 0;
4647
4648 // Build the bitstream
Yaowu Xuf883b422016-08-30 14:01:10 -07004649 av1_pack_bitstream(cpi, dest, size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004650
4651 // Set up frame to show to get ready for stats collection.
4652 cm->frame_to_show = get_frame_new_buffer(cm);
4653
4654#if DUMP_RECON_FRAMES == 1
4655 // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
4656 dump_filtered_recon_frames(cpi);
4657#endif // DUMP_RECON_FRAMES
4658
4659 // Update the LAST_FRAME in the reference frame buffer.
Yaowu Xuf883b422016-08-30 14:01:10 -07004660 av1_update_reference_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004661
4662 // Update frame flags
4663 cpi->frame_flags &= ~FRAMEFLAGS_GOLDEN;
4664 cpi->frame_flags &= ~FRAMEFLAGS_BWDREF;
4665 cpi->frame_flags &= ~FRAMEFLAGS_ALTREF;
4666
4667 *frame_flags = cpi->frame_flags & ~FRAMEFLAGS_KEY;
4668
4669 // Update the frame type
4670 cm->last_frame_type = cm->frame_type;
4671
Yaowu Xuc27fc142016-08-22 16:08:15 -07004672 // Since we allocate a spot for the OVERLAY frame in the gf group, we need
4673 // to do post-encoding update accordingly.
4674 if (cpi->rc.is_src_frame_alt_ref) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004675 av1_set_target_rate(cpi);
4676 av1_rc_postencode_update(cpi, *size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004677 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004678
4679 cm->last_width = cm->width;
4680 cm->last_height = cm->height;
4681
4682 ++cm->current_video_frame;
4683
4684 return;
4685 }
4686#endif // CONFIG_EXT_REFS
4687
4688 // Set default state for segment based loop filter update flags.
4689 cm->lf.mode_ref_delta_update = 0;
4690
4691 if (cpi->oxcf.pass == 2 && cpi->sf.adaptive_interp_filter_search)
4692 cpi->sf.interp_filter_search_mask = setup_interp_filter_search_mask(cpi);
4693
4694 // Set various flags etc to special state if it is a key frame.
4695 if (frame_is_intra_only(cm)) {
4696 // Reset the loop filter deltas and segmentation map.
Yaowu Xuf883b422016-08-30 14:01:10 -07004697 av1_reset_segment_features(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004698
4699 // If segmentation is enabled force a map update for key frames.
4700 if (seg->enabled) {
4701 seg->update_map = 1;
4702 seg->update_data = 1;
4703 }
4704
4705 // The alternate reference frame cannot be active for a key frame.
4706 cpi->rc.source_alt_ref_active = 0;
4707
4708 cm->error_resilient_mode = oxcf->error_resilient_mode;
4709
4710 // By default, encoder assumes decoder can use prev_mi.
4711 if (cm->error_resilient_mode) {
4712 cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
4713 cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_FORWARD;
4714 } else if (cm->intra_only) {
4715 // Only reset the current context.
4716 cm->reset_frame_context = RESET_FRAME_CONTEXT_CURRENT;
4717 }
4718 }
Thomas Davies80188d12016-10-26 16:08:35 -07004719#if CONFIG_TILE_GROUPS
Thomas Daviesaf6df172016-11-09 14:04:18 +00004720 if (cpi->oxcf.mtu == 0) {
4721 cm->num_tg = cpi->oxcf.num_tile_groups;
4722 } else {
Yaowu Xu859a5272016-11-10 15:32:21 -08004723 // Use a default value for the purposes of weighting costs in probability
4724 // updates
Thomas Daviesaf6df172016-11-09 14:04:18 +00004725 cm->num_tg = DEFAULT_MAX_NUM_TG;
4726 }
Thomas Davies80188d12016-10-26 16:08:35 -07004727#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004728
4729 // For 1 pass CBR, check if we are dropping this frame.
4730 // Never drop on key frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004731 if (oxcf->pass == 0 && oxcf->rc_mode == AOM_CBR &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004732 cm->frame_type != KEY_FRAME) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004733 if (av1_rc_drop_frame(cpi)) {
4734 av1_rc_postencode_update_drop_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004735 ++cm->current_video_frame;
4736 return;
4737 }
4738 }
4739
Yaowu Xuf883b422016-08-30 14:01:10 -07004740 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004741
4742#if CONFIG_INTERNAL_STATS
4743 memset(cpi->mode_chosen_counts, 0,
4744 MAX_MODES * sizeof(*cpi->mode_chosen_counts));
4745#endif
4746
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004747#if CONFIG_REFERENCE_BUFFER
4748 {
4749 /* Non-normative definition of current_frame_id ("frame counter" with
4750 * wraparound) */
Arild Fuldseth (arilfuld)788dc232016-12-20 17:55:52 +01004751 const int frame_id_length = FRAME_ID_LENGTH_MINUS7 + 7;
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004752 if (cm->current_frame_id == -1) {
David Barker49a76562016-12-07 14:50:21 +00004753 int lsb, msb;
Arild Fuldseth (arilfuld)bac17c12016-12-02 12:01:06 +01004754/* quasi-random initialization of current_frame_id for a key frame */
4755#if CONFIG_AOM_HIGHBITDEPTH
David Barker49a76562016-12-07 14:50:21 +00004756 if (cpi->Source->flags & YV12_FLAG_HIGHBITDEPTH) {
4757 lsb = CONVERT_TO_SHORTPTR(cpi->Source->y_buffer)[0] & 0xff;
4758 msb = CONVERT_TO_SHORTPTR(cpi->Source->y_buffer)[1] & 0xff;
4759 } else {
4760#endif
4761 lsb = cpi->Source->y_buffer[0] & 0xff;
4762 msb = cpi->Source->y_buffer[1] & 0xff;
4763#if CONFIG_AOM_HIGHBITDEPTH
4764 }
Arild Fuldseth (arilfuld)bac17c12016-12-02 12:01:06 +01004765#endif
Arild Fuldseth (arilfuld)788dc232016-12-20 17:55:52 +01004766 cm->current_frame_id = ((msb << 8) + lsb) % (1 << frame_id_length);
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004767 } else {
4768 cm->current_frame_id =
Arild Fuldseth (arilfuld)788dc232016-12-20 17:55:52 +01004769 (cm->current_frame_id + 1 + (1 << frame_id_length)) %
4770 (1 << frame_id_length);
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004771 }
4772 }
4773#endif
4774
Yaowu Xuc27fc142016-08-22 16:08:15 -07004775 if (cpi->sf.recode_loop == DISALLOW_RECODE) {
4776 encode_without_recode_loop(cpi);
4777 } else {
4778 encode_with_recode_loop(cpi, size, dest);
4779 }
4780
4781#ifdef OUTPUT_YUV_SKINMAP
4782 if (cpi->common.current_video_frame > 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004783 av1_compute_skin_map(cpi, yuv_skinmap_file);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004784 }
4785#endif // OUTPUT_YUV_SKINMAP
4786
4787 // Special case code to reduce pulsing when key frames are forced at a
4788 // fixed interval. Note the reconstruction error if it is the frame before
4789 // the force key frame
4790 if (cpi->rc.next_key_frame_forced && cpi->rc.frames_to_key == 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004791#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004792 if (cm->use_highbitdepth) {
4793 cpi->ambient_err =
Yaowu Xuf883b422016-08-30 14:01:10 -07004794 aom_highbd_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004795 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004796 cpi->ambient_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004797 }
4798#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004799 cpi->ambient_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
4800#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004801 }
4802
4803 // If the encoder forced a KEY_FRAME decision
4804 if (cm->frame_type == KEY_FRAME) {
4805 cpi->refresh_last_frame = 1;
4806 }
4807
4808 cm->frame_to_show = get_frame_new_buffer(cm);
4809 cm->frame_to_show->color_space = cm->color_space;
4810 cm->frame_to_show->color_range = cm->color_range;
4811 cm->frame_to_show->render_width = cm->render_width;
4812 cm->frame_to_show->render_height = cm->render_height;
4813
4814#if CONFIG_EXT_REFS
4815// TODO(zoeliu): For non-ref frames, loop filtering may need to be turned
4816// off.
4817#endif // CONFIG_EXT_REFS
4818
4819 // Pick the loop filter level for the frame.
4820 loopfilter_frame(cpi, cm);
4821
4822 // Build the bitstream
Yaowu Xuf883b422016-08-30 14:01:10 -07004823 av1_pack_bitstream(cpi, dest, size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004824
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004825#if CONFIG_REFERENCE_BUFFER
4826 {
4827 int i;
4828 /* Update reference frame id values based on the value of refresh_mask */
4829 for (i = 0; i < REF_FRAMES; i++) {
4830 if ((cm->refresh_mask >> i) & 1) {
4831 cm->ref_frame_id[i] = cm->current_frame_id;
4832 }
4833 }
4834 }
4835#endif
4836
Yaowu Xuc27fc142016-08-22 16:08:15 -07004837#if DUMP_RECON_FRAMES == 1
4838 // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
4839 if (cm->show_frame) dump_filtered_recon_frames(cpi);
4840#endif // DUMP_RECON_FRAMES
4841
Steinar Midtskogend06588a2016-05-06 13:48:20 +02004842#if CONFIG_CLPF
4843 aom_free(cm->clpf_blocks);
Steinar Midtskogenf4d41e62016-08-25 12:22:24 +02004844 cm->clpf_blocks = 0;
Steinar Midtskogend06588a2016-05-06 13:48:20 +02004845#endif
4846
Yaowu Xuc27fc142016-08-22 16:08:15 -07004847 if (cm->seg.update_map) update_reference_segmentation_map(cpi);
4848
4849 if (frame_is_intra_only(cm) == 0) {
4850 release_scaled_references(cpi);
4851 }
4852
Yaowu Xuf883b422016-08-30 14:01:10 -07004853 av1_update_reference_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004854
Jingning Han6de954c2016-12-16 09:52:04 -08004855 for (t = 0; t < TX_SIZES; t++)
Yaowu Xuf883b422016-08-30 14:01:10 -07004856 av1_full_to_model_counts(cpi->td.counts->coef[t],
4857 cpi->td.rd_counts.coef_counts[t]);
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08004858#if CONFIG_ENTROPY_STATS
4859 av1_accumulate_frame_counts(&aggregate_fc, &cm->counts);
4860#endif // CONFIG_ENTROPY_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07004861 if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
4862#if CONFIG_ENTROPY
4863 cm->partial_prob_update = 0;
4864#endif // CONFIG_ENTROPY
Yaowu Xuf883b422016-08-30 14:01:10 -07004865 av1_adapt_coef_probs(cm);
4866 av1_adapt_intra_frame_probs(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004867 }
4868
4869 if (!frame_is_intra_only(cm)) {
4870 if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004871 av1_adapt_inter_frame_probs(cm);
4872 av1_adapt_mv_probs(cm, cm->allow_high_precision_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004873 }
4874 }
4875
4876 if (cpi->refresh_golden_frame == 1)
4877 cpi->frame_flags |= FRAMEFLAGS_GOLDEN;
4878 else
4879 cpi->frame_flags &= ~FRAMEFLAGS_GOLDEN;
4880
4881 if (cpi->refresh_alt_ref_frame == 1)
4882 cpi->frame_flags |= FRAMEFLAGS_ALTREF;
4883 else
4884 cpi->frame_flags &= ~FRAMEFLAGS_ALTREF;
4885
4886#if CONFIG_EXT_REFS
4887 if (cpi->refresh_bwd_ref_frame == 1)
4888 cpi->frame_flags |= FRAMEFLAGS_BWDREF;
4889 else
4890 cpi->frame_flags &= ~FRAMEFLAGS_BWDREF;
4891#endif // CONFIG_EXT_REFS
4892
4893#if !CONFIG_EXT_REFS
4894 cpi->ref_frame_flags = get_ref_frame_flags(cpi);
4895#endif // !CONFIG_EXT_REFS
4896
Yaowu Xuc27fc142016-08-22 16:08:15 -07004897 cm->last_frame_type = cm->frame_type;
4898
Yaowu Xuf883b422016-08-30 14:01:10 -07004899 av1_rc_postencode_update(cpi, *size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004900
4901#if 0
4902 output_frame_level_debug_stats(cpi);
4903#endif
4904
4905 if (cm->frame_type == KEY_FRAME) {
4906 // Tell the caller that the frame was coded as a key frame
4907 *frame_flags = cpi->frame_flags | FRAMEFLAGS_KEY;
4908 } else {
4909 *frame_flags = cpi->frame_flags & ~FRAMEFLAGS_KEY;
4910 }
4911
4912 // Clear the one shot update flags for segmentation map and mode/ref loop
4913 // filter deltas.
4914 cm->seg.update_map = 0;
4915 cm->seg.update_data = 0;
4916 cm->lf.mode_ref_delta_update = 0;
4917
4918 // keep track of the last coded dimensions
4919 cm->last_width = cm->width;
4920 cm->last_height = cm->height;
4921
4922 // reset to normal state now that we are done.
4923 if (!cm->show_existing_frame) cm->last_show_frame = cm->show_frame;
4924
4925 if (cm->show_frame) {
4926#if CONFIG_EXT_REFS
4927// TODO(zoeliu): We may only swamp mi and prev_mi for those frames that are
4928// being used as reference.
4929#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004930 av1_swap_mi_and_prev_mi(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004931 // Don't increment frame counters if this was an altref buffer
4932 // update not a real frame
4933 ++cm->current_video_frame;
4934 }
4935
4936#if CONFIG_EXT_REFS
4937 // NOTE: Shall not refer to any frame not used as reference.
4938 if (cm->is_reference_frame)
4939#endif // CONFIG_EXT_REFS
4940 cm->prev_frame = cm->cur_frame;
4941}
4942
Yaowu Xuf883b422016-08-30 14:01:10 -07004943static void Pass0Encode(AV1_COMP *cpi, size_t *size, uint8_t *dest,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004944 unsigned int *frame_flags) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004945 if (cpi->oxcf.rc_mode == AOM_CBR) {
4946 av1_rc_get_one_pass_cbr_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004947 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004948 av1_rc_get_one_pass_vbr_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004949 }
4950 encode_frame_to_data_rate(cpi, size, dest, frame_flags);
4951}
4952
Yaowu Xuf883b422016-08-30 14:01:10 -07004953static void Pass2Encode(AV1_COMP *cpi, size_t *size, uint8_t *dest,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004954 unsigned int *frame_flags) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004955 encode_frame_to_data_rate(cpi, size, dest, frame_flags);
4956
4957#if CONFIG_EXT_REFS
4958 // Do not do post-encoding update for those frames that do not have a spot in
4959 // a gf group, but note that an OVERLAY frame always has a spot in a gf group,
4960 // even when show_existing_frame is used.
4961 if (!cpi->common.show_existing_frame || cpi->rc.is_src_frame_alt_ref) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004962 av1_twopass_postencode_update(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004963 }
4964 check_show_existing_frame(cpi);
4965#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004966 av1_twopass_postencode_update(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004967#endif // CONFIG_EXT_REFS
4968}
4969
Yaowu Xuf883b422016-08-30 14:01:10 -07004970static void init_ref_frame_bufs(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004971 int i;
4972 BufferPool *const pool = cm->buffer_pool;
4973 cm->new_fb_idx = INVALID_IDX;
4974 for (i = 0; i < REF_FRAMES; ++i) {
4975 cm->ref_frame_map[i] = INVALID_IDX;
4976 pool->frame_bufs[i].ref_count = 0;
4977 }
4978}
4979
Yaowu Xuf883b422016-08-30 14:01:10 -07004980static void check_initial_width(AV1_COMP *cpi,
4981#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004982 int use_highbitdepth,
4983#endif
4984 int subsampling_x, int subsampling_y) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004985 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004986
4987 if (!cpi->initial_width ||
Yaowu Xuf883b422016-08-30 14:01:10 -07004988#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004989 cm->use_highbitdepth != use_highbitdepth ||
4990#endif
4991 cm->subsampling_x != subsampling_x ||
4992 cm->subsampling_y != subsampling_y) {
4993 cm->subsampling_x = subsampling_x;
4994 cm->subsampling_y = subsampling_y;
Yaowu Xuf883b422016-08-30 14:01:10 -07004995#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004996 cm->use_highbitdepth = use_highbitdepth;
4997#endif
4998
4999 alloc_raw_frame_buffers(cpi);
5000 init_ref_frame_bufs(cm);
5001 alloc_util_frame_buffers(cpi);
5002
5003 init_motion_estimation(cpi); // TODO(agrange) This can be removed.
5004
5005 cpi->initial_width = cm->width;
5006 cpi->initial_height = cm->height;
5007 cpi->initial_mbs = cm->MBs;
5008 }
5009}
5010
Yaowu Xuf883b422016-08-30 14:01:10 -07005011int av1_receive_raw_frame(AV1_COMP *cpi, unsigned int frame_flags,
5012 YV12_BUFFER_CONFIG *sd, int64_t time_stamp,
5013 int64_t end_time) {
5014 AV1_COMMON *const cm = &cpi->common;
5015 struct aom_usec_timer timer;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005016 int res = 0;
5017 const int subsampling_x = sd->subsampling_x;
5018 const int subsampling_y = sd->subsampling_y;
Yaowu Xuf883b422016-08-30 14:01:10 -07005019#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005020 const int use_highbitdepth = (sd->flags & YV12_FLAG_HIGHBITDEPTH) != 0;
5021#endif
5022
Yaowu Xuf883b422016-08-30 14:01:10 -07005023#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005024 check_initial_width(cpi, use_highbitdepth, subsampling_x, subsampling_y);
5025#else
5026 check_initial_width(cpi, subsampling_x, subsampling_y);
Yaowu Xuf883b422016-08-30 14:01:10 -07005027#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005028
Yaowu Xuf883b422016-08-30 14:01:10 -07005029 aom_usec_timer_start(&timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005030
Yaowu Xuf883b422016-08-30 14:01:10 -07005031 if (av1_lookahead_push(cpi->lookahead, sd, time_stamp, end_time,
5032#if CONFIG_AOM_HIGHBITDEPTH
5033 use_highbitdepth,
5034#endif // CONFIG_AOM_HIGHBITDEPTH
5035 frame_flags))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005036 res = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -07005037 aom_usec_timer_mark(&timer);
5038 cpi->time_receive_data += aom_usec_timer_elapsed(&timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005039
5040 if ((cm->profile == PROFILE_0 || cm->profile == PROFILE_2) &&
5041 (subsampling_x != 1 || subsampling_y != 1)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005042 aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005043 "Non-4:2:0 color format requires profile 1 or 3");
5044 res = -1;
5045 }
5046 if ((cm->profile == PROFILE_1 || cm->profile == PROFILE_3) &&
5047 (subsampling_x == 1 && subsampling_y == 1)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005048 aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005049 "4:2:0 color format requires profile 0 or 2");
5050 res = -1;
5051 }
5052
5053 return res;
5054}
5055
Yaowu Xuf883b422016-08-30 14:01:10 -07005056static int frame_is_reference(const AV1_COMP *cpi) {
5057 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005058
5059 return cm->frame_type == KEY_FRAME || cpi->refresh_last_frame ||
5060 cpi->refresh_golden_frame ||
5061#if CONFIG_EXT_REFS
5062 cpi->refresh_bwd_ref_frame ||
5063#endif // CONFIG_EXT_REFS
5064 cpi->refresh_alt_ref_frame || !cm->error_resilient_mode ||
5065 cm->lf.mode_ref_delta_update || cm->seg.update_map ||
5066 cm->seg.update_data;
5067}
5068
Yaowu Xuf883b422016-08-30 14:01:10 -07005069static void adjust_frame_rate(AV1_COMP *cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005070 const struct lookahead_entry *source) {
5071 int64_t this_duration;
5072 int step = 0;
5073
5074 if (source->ts_start == cpi->first_time_stamp_ever) {
5075 this_duration = source->ts_end - source->ts_start;
5076 step = 1;
5077 } else {
5078 int64_t last_duration =
5079 cpi->last_end_time_stamp_seen - cpi->last_time_stamp_seen;
5080
5081 this_duration = source->ts_end - cpi->last_end_time_stamp_seen;
5082
5083 // do a step update if the duration changes by 10%
5084 if (last_duration)
5085 step = (int)((this_duration - last_duration) * 10 / last_duration);
5086 }
5087
5088 if (this_duration) {
5089 if (step) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005090 av1_new_framerate(cpi, 10000000.0 / this_duration);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005091 } else {
5092 // Average this frame's rate into the last second's average
5093 // frame rate. If we haven't seen 1 second yet, then average
5094 // over the whole interval seen.
Yaowu Xuf883b422016-08-30 14:01:10 -07005095 const double interval = AOMMIN(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005096 (double)(source->ts_end - cpi->first_time_stamp_ever), 10000000.0);
5097 double avg_duration = 10000000.0 / cpi->framerate;
5098 avg_duration *= (interval - avg_duration + this_duration);
5099 avg_duration /= interval;
5100
Yaowu Xuf883b422016-08-30 14:01:10 -07005101 av1_new_framerate(cpi, 10000000.0 / avg_duration);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005102 }
5103 }
5104 cpi->last_time_stamp_seen = source->ts_start;
5105 cpi->last_end_time_stamp_seen = source->ts_end;
5106}
5107
5108// Returns 0 if this is not an alt ref else the offset of the source frame
5109// used as the arf midpoint.
Yaowu Xuf883b422016-08-30 14:01:10 -07005110static int get_arf_src_index(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005111 RATE_CONTROL *const rc = &cpi->rc;
5112 int arf_src_index = 0;
5113 if (is_altref_enabled(cpi)) {
5114 if (cpi->oxcf.pass == 2) {
5115 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5116 if (gf_group->update_type[gf_group->index] == ARF_UPDATE) {
5117 arf_src_index = gf_group->arf_src_offset[gf_group->index];
5118 }
5119 } else if (rc->source_alt_ref_pending) {
5120 arf_src_index = rc->frames_till_gf_update_due;
5121 }
5122 }
5123 return arf_src_index;
5124}
5125
5126#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005127static int get_brf_src_index(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005128 int brf_src_index = 0;
5129 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5130
5131 // TODO(zoeliu): We need to add the check on the -bwd_ref command line setup
5132 // flag.
5133 if (gf_group->bidir_pred_enabled[gf_group->index]) {
5134 if (cpi->oxcf.pass == 2) {
5135 if (gf_group->update_type[gf_group->index] == BRF_UPDATE)
5136 brf_src_index = gf_group->brf_src_offset[gf_group->index];
5137 } else {
5138 // TODO(zoeliu): To re-visit the setup for this scenario
5139 brf_src_index = cpi->rc.bipred_group_interval - 1;
5140 }
5141 }
5142
5143 return brf_src_index;
5144}
5145#endif // CONFIG_EXT_REFS
5146
Yaowu Xuf883b422016-08-30 14:01:10 -07005147static void check_src_altref(AV1_COMP *cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005148 const struct lookahead_entry *source) {
5149 RATE_CONTROL *const rc = &cpi->rc;
5150
5151 // If pass == 2, the parameters set here will be reset in
Yaowu Xuf883b422016-08-30 14:01:10 -07005152 // av1_rc_get_second_pass_params()
Yaowu Xuc27fc142016-08-22 16:08:15 -07005153
5154 if (cpi->oxcf.pass == 2) {
5155 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5156 rc->is_src_frame_alt_ref =
5157#if CONFIG_EXT_REFS
5158 (gf_group->update_type[gf_group->index] == INTNL_OVERLAY_UPDATE) ||
Zoe Liu6cfaff92016-10-18 17:12:11 -07005159#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07005160 (gf_group->update_type[gf_group->index] == OVERLAY_UPDATE);
5161 } else {
5162 rc->is_src_frame_alt_ref =
5163 cpi->alt_ref_source && (source == cpi->alt_ref_source);
5164 }
5165
5166 if (rc->is_src_frame_alt_ref) {
5167 // Current frame is an ARF overlay frame.
5168 cpi->alt_ref_source = NULL;
5169
5170 // Don't refresh the last buffer for an ARF overlay frame. It will
5171 // become the GF so preserve last as an alternative prediction option.
5172 cpi->refresh_last_frame = 0;
5173 }
5174}
5175
5176#if CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07005177extern double av1_get_blockiness(const unsigned char *img1, int img1_pitch,
5178 const unsigned char *img2, int img2_pitch,
5179 int width, int height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005180
5181static void adjust_image_stat(double y, double u, double v, double all,
5182 ImageStat *s) {
5183 s->stat[Y] += y;
5184 s->stat[U] += u;
5185 s->stat[V] += v;
5186 s->stat[ALL] += all;
Yaowu Xuf883b422016-08-30 14:01:10 -07005187 s->worst = AOMMIN(s->worst, all);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005188}
5189
Yaowu Xuf883b422016-08-30 14:01:10 -07005190static void compute_internal_stats(AV1_COMP *cpi) {
5191 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005192 double samples = 0.0;
5193 uint32_t in_bit_depth = 8;
5194 uint32_t bit_depth = 8;
5195
Yaowu Xuf883b422016-08-30 14:01:10 -07005196#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005197 if (cm->use_highbitdepth) {
5198 in_bit_depth = cpi->oxcf.input_bit_depth;
5199 bit_depth = cm->bit_depth;
5200 }
5201#endif
5202 if (cm->show_frame) {
5203 const YV12_BUFFER_CONFIG *orig = cpi->Source;
5204 const YV12_BUFFER_CONFIG *recon = cpi->common.frame_to_show;
5205 double y, u, v, frame_all;
5206
5207 cpi->count++;
5208 if (cpi->b_calculate_psnr) {
5209 PSNR_STATS psnr;
5210 double frame_ssim2 = 0.0, weight = 0.0;
Yaowu Xuf883b422016-08-30 14:01:10 -07005211 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005212// TODO(yaowu): unify these two versions into one.
Yaowu Xuf883b422016-08-30 14:01:10 -07005213#if CONFIG_AOM_HIGHBITDEPTH
5214 aom_calc_highbd_psnr(orig, recon, &psnr, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005215#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005216 aom_calc_psnr(orig, recon, &psnr);
5217#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005218
5219 adjust_image_stat(psnr.psnr[1], psnr.psnr[2], psnr.psnr[3], psnr.psnr[0],
5220 &cpi->psnr);
5221 cpi->total_sq_error += psnr.sse[0];
5222 cpi->total_samples += psnr.samples[0];
5223 samples = psnr.samples[0];
5224// TODO(yaowu): unify these two versions into one.
Yaowu Xuf883b422016-08-30 14:01:10 -07005225#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005226 if (cm->use_highbitdepth)
5227 frame_ssim2 =
Yaowu Xuf883b422016-08-30 14:01:10 -07005228 aom_highbd_calc_ssim(orig, recon, &weight, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005229 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005230 frame_ssim2 = aom_calc_ssim(orig, recon, &weight);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005231#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005232 frame_ssim2 = aom_calc_ssim(orig, recon, &weight);
5233#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005234
Yaowu Xuf883b422016-08-30 14:01:10 -07005235 cpi->worst_ssim = AOMMIN(cpi->worst_ssim, frame_ssim2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005236 cpi->summed_quality += frame_ssim2 * weight;
5237 cpi->summed_weights += weight;
5238
5239#if 0
5240 {
5241 FILE *f = fopen("q_used.stt", "a");
5242 fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n",
5243 cpi->common.current_video_frame, y2, u2, v2,
5244 frame_psnr2, frame_ssim2);
5245 fclose(f);
5246 }
5247#endif
5248 }
5249 if (cpi->b_calculate_blockiness) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005250#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005251 if (!cm->use_highbitdepth)
5252#endif
5253 {
5254 const double frame_blockiness =
Yaowu Xuf883b422016-08-30 14:01:10 -07005255 av1_get_blockiness(orig->y_buffer, orig->y_stride, recon->y_buffer,
5256 recon->y_stride, orig->y_width, orig->y_height);
5257 cpi->worst_blockiness = AOMMAX(cpi->worst_blockiness, frame_blockiness);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005258 cpi->total_blockiness += frame_blockiness;
5259 }
5260
5261 if (cpi->b_calculate_consistency) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005262#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005263 if (!cm->use_highbitdepth)
5264#endif
5265 {
Yaowu Xuf883b422016-08-30 14:01:10 -07005266 const double this_inconsistency = aom_get_ssim_metrics(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005267 orig->y_buffer, orig->y_stride, recon->y_buffer, recon->y_stride,
5268 orig->y_width, orig->y_height, cpi->ssim_vars, &cpi->metrics, 1);
5269
5270 const double peak = (double)((1 << in_bit_depth) - 1);
5271 const double consistency =
Yaowu Xuf883b422016-08-30 14:01:10 -07005272 aom_sse_to_psnr(samples, peak, cpi->total_inconsistency);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005273 if (consistency > 0.0)
5274 cpi->worst_consistency =
Yaowu Xuf883b422016-08-30 14:01:10 -07005275 AOMMIN(cpi->worst_consistency, consistency);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005276 cpi->total_inconsistency += this_inconsistency;
5277 }
5278 }
5279 }
5280
5281 frame_all =
Yaowu Xuf883b422016-08-30 14:01:10 -07005282 aom_calc_fastssim(orig, recon, &y, &u, &v, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005283 adjust_image_stat(y, u, v, frame_all, &cpi->fastssim);
Yaowu Xuf883b422016-08-30 14:01:10 -07005284 frame_all = aom_psnrhvs(orig, recon, &y, &u, &v, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005285 adjust_image_stat(y, u, v, frame_all, &cpi->psnrhvs);
5286 }
5287}
5288#endif // CONFIG_INTERNAL_STATS
5289
Yaowu Xuf883b422016-08-30 14:01:10 -07005290int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags,
5291 size_t *size, uint8_t *dest, int64_t *time_stamp,
5292 int64_t *time_end, int flush) {
5293 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
5294 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005295 BufferPool *const pool = cm->buffer_pool;
5296 RATE_CONTROL *const rc = &cpi->rc;
Yaowu Xuf883b422016-08-30 14:01:10 -07005297 struct aom_usec_timer cmptimer;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005298 YV12_BUFFER_CONFIG *force_src_buffer = NULL;
5299 struct lookahead_entry *last_source = NULL;
5300 struct lookahead_entry *source = NULL;
5301 int arf_src_index;
5302#if CONFIG_EXT_REFS
5303 int brf_src_index;
5304#endif // CONFIG_EXT_REFS
5305 int i;
5306
5307#if CONFIG_BITSTREAM_DEBUG
5308 assert(cpi->oxcf.max_threads == 0 &&
5309 "bitstream debug tool does not support multithreading");
5310 bitstream_queue_record_write();
Angie Chiangcb9a9eb2016-09-01 16:10:50 -07005311 bitstream_queue_set_frame_write(cm->current_video_frame * 2 + cm->show_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005312#endif
5313
Yaowu Xuf883b422016-08-30 14:01:10 -07005314 aom_usec_timer_start(&cmptimer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005315
Yaowu Xuf883b422016-08-30 14:01:10 -07005316 av1_set_high_precision_mv(cpi, ALTREF_HIGH_PRECISION_MV);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005317
5318 // Is multi-arf enabled.
5319 // Note that at the moment multi_arf is only configured for 2 pass VBR
5320 if ((oxcf->pass == 2) && (cpi->oxcf.enable_auto_arf > 1))
5321 cpi->multi_arf_allowed = 1;
5322 else
5323 cpi->multi_arf_allowed = 0;
5324
5325 // Normal defaults
5326 cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
5327 cm->refresh_frame_context =
5328 (oxcf->error_resilient_mode || oxcf->frame_parallel_decoding_mode)
5329 ? REFRESH_FRAME_CONTEXT_FORWARD
5330 : REFRESH_FRAME_CONTEXT_BACKWARD;
5331
5332 cpi->refresh_last_frame = 1;
5333 cpi->refresh_golden_frame = 0;
5334#if CONFIG_EXT_REFS
5335 cpi->refresh_bwd_ref_frame = 0;
5336#endif // CONFIG_EXT_REFS
5337 cpi->refresh_alt_ref_frame = 0;
5338
5339#if CONFIG_EXT_REFS
5340 if (oxcf->pass == 2 && cm->show_existing_frame) {
5341 // Manage the source buffer and flush out the source frame that has been
5342 // coded already; Also get prepared for PSNR calculation if needed.
Yaowu Xuf883b422016-08-30 14:01:10 -07005343 if ((source = av1_lookahead_pop(cpi->lookahead, flush)) == NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005344 *size = 0;
5345 return -1;
5346 }
5347 cpi->Source = &source->img;
5348 // TODO(zoeliu): To track down to determine whether it's needed to adjust
5349 // the frame rate.
5350 *time_stamp = source->ts_start;
5351 *time_end = source->ts_end;
5352
5353 // We need to adjust frame rate for an overlay frame
5354 if (cpi->rc.is_src_frame_alt_ref) {
5355 adjust_frame_rate(cpi, source);
5356 }
5357
5358 // Find a free buffer for the new frame, releasing the reference previously
5359 // held.
5360 if (cm->new_fb_idx != INVALID_IDX) {
5361 --pool->frame_bufs[cm->new_fb_idx].ref_count;
5362 }
5363 cm->new_fb_idx = get_free_fb(cm);
5364
5365 if (cm->new_fb_idx == INVALID_IDX) return -1;
5366
5367 // Clear down mmx registers
Yaowu Xuf883b422016-08-30 14:01:10 -07005368 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005369
5370 // Start with a 0 size frame.
5371 *size = 0;
5372
5373 // We need to update the gf_group for show_existing overlay frame
5374 if (cpi->rc.is_src_frame_alt_ref) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005375 av1_rc_get_second_pass_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005376 }
5377
5378 Pass2Encode(cpi, size, dest, frame_flags);
5379
5380 if (cpi->b_calculate_psnr) generate_psnr_packet(cpi);
5381
5382#if CONFIG_INTERNAL_STATS
5383 compute_internal_stats(cpi);
5384 cpi->bytes += (int)(*size);
5385#endif // CONFIG_INTERNAL_STATS
5386
5387 // Clear down mmx registers
Yaowu Xuf883b422016-08-30 14:01:10 -07005388 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005389
5390 cm->show_existing_frame = 0;
5391 return 0;
5392 }
5393#endif // CONFIG_EXT_REFS
5394
5395 // Should we encode an arf frame.
5396 arf_src_index = get_arf_src_index(cpi);
5397 if (arf_src_index) {
5398 for (i = 0; i <= arf_src_index; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005399 struct lookahead_entry *e = av1_lookahead_peek(cpi->lookahead, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005400 // Avoid creating an alt-ref if there's a forced keyframe pending.
5401 if (e == NULL) {
5402 break;
Yaowu Xuf883b422016-08-30 14:01:10 -07005403 } else if (e->flags == AOM_EFLAG_FORCE_KF) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005404 arf_src_index = 0;
5405 flush = 1;
5406 break;
5407 }
5408 }
5409 }
5410
5411 if (arf_src_index) {
5412 assert(arf_src_index <= rc->frames_to_key);
5413
Yaowu Xuf883b422016-08-30 14:01:10 -07005414 if ((source = av1_lookahead_peek(cpi->lookahead, arf_src_index)) != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005415 cpi->alt_ref_source = source;
5416
5417 if (oxcf->arnr_max_frames > 0) {
5418 // Produce the filtered ARF frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07005419 av1_temporal_filter(cpi, arf_src_index);
5420 aom_extend_frame_borders(&cpi->alt_ref_buffer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005421 force_src_buffer = &cpi->alt_ref_buffer;
5422 }
5423
5424 cm->show_frame = 0;
5425 cm->intra_only = 0;
5426 cpi->refresh_alt_ref_frame = 1;
5427 cpi->refresh_golden_frame = 0;
5428 cpi->refresh_last_frame = 0;
5429 rc->is_src_frame_alt_ref = 0;
5430 }
5431 rc->source_alt_ref_pending = 0;
5432 }
5433
5434#if CONFIG_EXT_REFS
5435 rc->is_bwd_ref_frame = 0;
5436 brf_src_index = get_brf_src_index(cpi);
5437 if (brf_src_index) {
5438 assert(brf_src_index <= rc->frames_to_key);
Yaowu Xuf883b422016-08-30 14:01:10 -07005439 if ((source = av1_lookahead_peek(cpi->lookahead, brf_src_index)) != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005440 cm->show_frame = 0;
5441 cm->intra_only = 0;
5442
5443 cpi->refresh_bwd_ref_frame = 1;
5444 cpi->refresh_last_frame = 0;
5445 cpi->refresh_golden_frame = 0;
5446 cpi->refresh_alt_ref_frame = 0;
5447
5448 rc->is_bwd_ref_frame = 1;
5449 }
5450 }
5451#endif // CONFIG_EXT_REFS
5452
5453 if (!source) {
5454 // Get last frame source.
5455 if (cm->current_video_frame > 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005456 if ((last_source = av1_lookahead_peek(cpi->lookahead, -1)) == NULL)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005457 return -1;
5458 }
5459
5460 // Read in the source frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07005461 source = av1_lookahead_pop(cpi->lookahead, flush);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005462
5463 if (source != NULL) {
5464 cm->show_frame = 1;
5465 cm->intra_only = 0;
5466
5467 // Check to see if the frame should be encoded as an arf overlay.
5468 check_src_altref(cpi, source);
5469 }
5470 }
5471
5472 if (source) {
5473 cpi->un_scaled_source = cpi->Source =
5474 force_src_buffer ? force_src_buffer : &source->img;
5475
5476 cpi->unscaled_last_source = last_source != NULL ? &last_source->img : NULL;
5477
5478 *time_stamp = source->ts_start;
5479 *time_end = source->ts_end;
Yaowu Xuf883b422016-08-30 14:01:10 -07005480 *frame_flags = (source->flags & AOM_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005481
5482 } else {
5483 *size = 0;
5484 if (flush && oxcf->pass == 1 && !cpi->twopass.first_pass_done) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005485 av1_end_first_pass(cpi); /* get last stats packet */
Yaowu Xuc27fc142016-08-22 16:08:15 -07005486 cpi->twopass.first_pass_done = 1;
5487 }
5488 return -1;
5489 }
5490
5491 if (source->ts_start < cpi->first_time_stamp_ever) {
5492 cpi->first_time_stamp_ever = source->ts_start;
5493 cpi->last_end_time_stamp_seen = source->ts_start;
5494 }
5495
5496 // Clear down mmx registers
Yaowu Xuf883b422016-08-30 14:01:10 -07005497 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005498
5499 // adjust frame rates based on timestamps given
5500 if (cm->show_frame) adjust_frame_rate(cpi, source);
5501
5502 // Find a free buffer for the new frame, releasing the reference previously
5503 // held.
5504 if (cm->new_fb_idx != INVALID_IDX) {
5505 --pool->frame_bufs[cm->new_fb_idx].ref_count;
5506 }
5507 cm->new_fb_idx = get_free_fb(cm);
5508
5509 if (cm->new_fb_idx == INVALID_IDX) return -1;
5510
5511 cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx];
5512
5513#if CONFIG_EXT_REFS
5514 if (oxcf->pass == 2) {
5515 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5516 cpi->alt_fb_idx = cpi->arf_map[gf_group->arf_ref_idx[gf_group->index]];
5517 }
5518#else
5519 if (cpi->multi_arf_allowed) {
5520 if (cm->frame_type == KEY_FRAME) {
5521 init_buffer_indices(cpi);
5522 } else if (oxcf->pass == 2) {
5523 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5524 cpi->alt_fb_idx = gf_group->arf_ref_idx[gf_group->index];
5525 }
5526 }
Zoe Liu6cfaff92016-10-18 17:12:11 -07005527#endif // CONFIG_EXT_REFS
5528
Yaowu Xuc27fc142016-08-22 16:08:15 -07005529 // Start with a 0 size frame.
5530 *size = 0;
5531
5532 cpi->frame_flags = *frame_flags;
5533
5534 if (oxcf->pass == 2) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005535 av1_rc_get_second_pass_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005536 } else if (oxcf->pass == 1) {
5537 set_frame_size(cpi);
5538 }
5539
5540 if (cpi->oxcf.pass != 0 || frame_is_intra_only(cm) == 1) {
5541 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i)
5542 cpi->scaled_ref_idx[i] = INVALID_IDX;
5543 }
5544
5545#if CONFIG_AOM_QM
5546 cm->using_qmatrix = cpi->oxcf.using_qm;
5547 cm->min_qmlevel = cpi->oxcf.qm_minlevel;
5548 cm->max_qmlevel = cpi->oxcf.qm_maxlevel;
5549#endif
5550
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01005551#if CONFIG_REFERENCE_BUFFER
5552 if (*time_stamp == 0) {
5553 cpi->common.current_frame_id = -1;
5554 }
5555#endif
5556
Yaowu Xuc27fc142016-08-22 16:08:15 -07005557 if (oxcf->pass == 1) {
5558 cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(oxcf);
Yaowu Xuf883b422016-08-30 14:01:10 -07005559 av1_first_pass(cpi, source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005560 } else if (oxcf->pass == 2) {
5561 Pass2Encode(cpi, size, dest, frame_flags);
5562 } else {
5563 // One pass encode
5564 Pass0Encode(cpi, size, dest, frame_flags);
5565 }
5566
5567 if (!cm->error_resilient_mode)
5568 cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
5569
5570 // No frame encoded, or frame was dropped, release scaled references.
5571 if ((*size == 0) && (frame_is_intra_only(cm) == 0)) {
5572 release_scaled_references(cpi);
5573 }
5574
5575 if (*size > 0) {
5576 cpi->droppable = !frame_is_reference(cpi);
5577 }
5578
Yaowu Xuf883b422016-08-30 14:01:10 -07005579 aom_usec_timer_mark(&cmptimer);
5580 cpi->time_compress_data += aom_usec_timer_elapsed(&cmptimer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005581
5582 if (cpi->b_calculate_psnr && oxcf->pass != 1 && cm->show_frame)
5583 generate_psnr_packet(cpi);
5584
5585#if CONFIG_INTERNAL_STATS
5586 if (oxcf->pass != 1) {
5587 compute_internal_stats(cpi);
5588 cpi->bytes += (int)(*size);
5589 }
5590#endif // CONFIG_INTERNAL_STATS
5591
Yaowu Xuf883b422016-08-30 14:01:10 -07005592 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005593
5594 return 0;
5595}
5596
Yaowu Xuf883b422016-08-30 14:01:10 -07005597int av1_get_preview_raw_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *dest) {
5598 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005599 if (!cm->show_frame) {
5600 return -1;
5601 } else {
5602 int ret;
5603 if (cm->frame_to_show) {
5604 *dest = *cm->frame_to_show;
5605 dest->y_width = cm->width;
5606 dest->y_height = cm->height;
5607 dest->uv_width = cm->width >> cm->subsampling_x;
5608 dest->uv_height = cm->height >> cm->subsampling_y;
5609 ret = 0;
5610 } else {
5611 ret = -1;
5612 }
Yaowu Xuf883b422016-08-30 14:01:10 -07005613 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005614 return ret;
5615 }
5616}
5617
Yaowu Xuf883b422016-08-30 14:01:10 -07005618int av1_get_last_show_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005619 if (cpi->last_show_frame_buf_idx == INVALID_IDX) return -1;
5620
5621 *frame =
5622 cpi->common.buffer_pool->frame_bufs[cpi->last_show_frame_buf_idx].buf;
5623 return 0;
5624}
5625
Yaowu Xuf883b422016-08-30 14:01:10 -07005626int av1_set_internal_size(AV1_COMP *cpi, AOM_SCALING horiz_mode,
5627 AOM_SCALING vert_mode) {
5628 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005629 int hr = 0, hs = 0, vr = 0, vs = 0;
5630
5631 if (horiz_mode > ONETWO || vert_mode > ONETWO) return -1;
5632
5633 Scale2Ratio(horiz_mode, &hr, &hs);
5634 Scale2Ratio(vert_mode, &vr, &vs);
5635
5636 // always go to the next whole number
5637 cm->width = (hs - 1 + cpi->oxcf.width * hr) / hs;
5638 cm->height = (vs - 1 + cpi->oxcf.height * vr) / vs;
5639 assert(cm->width <= cpi->initial_width);
5640 assert(cm->height <= cpi->initial_height);
5641
5642 update_frame_size(cpi);
5643
5644 return 0;
5645}
5646
Yaowu Xuf883b422016-08-30 14:01:10 -07005647int av1_set_size_literal(AV1_COMP *cpi, unsigned int width,
5648 unsigned int height) {
5649 AV1_COMMON *cm = &cpi->common;
5650#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005651 check_initial_width(cpi, cm->use_highbitdepth, 1, 1);
5652#else
5653 check_initial_width(cpi, 1, 1);
Yaowu Xuf883b422016-08-30 14:01:10 -07005654#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005655
5656 if (width) {
5657 cm->width = width;
5658 if (cm->width > cpi->initial_width) {
5659 cm->width = cpi->initial_width;
5660 printf("Warning: Desired width too large, changed to %d\n", cm->width);
5661 }
5662 }
5663
5664 if (height) {
5665 cm->height = height;
5666 if (cm->height > cpi->initial_height) {
5667 cm->height = cpi->initial_height;
5668 printf("Warning: Desired height too large, changed to %d\n", cm->height);
5669 }
5670 }
5671 assert(cm->width <= cpi->initial_width);
5672 assert(cm->height <= cpi->initial_height);
5673
5674 update_frame_size(cpi);
5675
5676 return 0;
5677}
5678
Yaowu Xuf883b422016-08-30 14:01:10 -07005679int av1_get_quantizer(AV1_COMP *cpi) { return cpi->common.base_qindex; }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005680
Yaowu Xuf883b422016-08-30 14:01:10 -07005681void av1_apply_encoding_flags(AV1_COMP *cpi, aom_enc_frame_flags_t flags) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005682 if (flags &
Yaowu Xuf883b422016-08-30 14:01:10 -07005683 (AOM_EFLAG_NO_REF_LAST | AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF)) {
5684 int ref = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005685
Yaowu Xuf883b422016-08-30 14:01:10 -07005686 if (flags & AOM_EFLAG_NO_REF_LAST) {
5687 ref ^= AOM_LAST_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005688#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005689 ref ^= AOM_LAST2_FLAG;
5690 ref ^= AOM_LAST3_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005691#endif // CONFIG_EXT_REFS
5692 }
5693
Yaowu Xuf883b422016-08-30 14:01:10 -07005694 if (flags & AOM_EFLAG_NO_REF_GF) ref ^= AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005695
Yaowu Xuf883b422016-08-30 14:01:10 -07005696 if (flags & AOM_EFLAG_NO_REF_ARF) ref ^= AOM_ALT_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005697
Yaowu Xuf883b422016-08-30 14:01:10 -07005698 av1_use_as_reference(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005699 }
5700
5701 if (flags &
Yaowu Xuf883b422016-08-30 14:01:10 -07005702 (AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF |
5703 AOM_EFLAG_FORCE_GF | AOM_EFLAG_FORCE_ARF)) {
5704 int upd = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005705
Yaowu Xuf883b422016-08-30 14:01:10 -07005706 if (flags & AOM_EFLAG_NO_UPD_LAST) {
5707 upd ^= AOM_LAST_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005708#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005709 upd ^= AOM_LAST2_FLAG;
5710 upd ^= AOM_LAST3_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005711#endif // CONFIG_EXT_REFS
5712 }
5713
Yaowu Xuf883b422016-08-30 14:01:10 -07005714 if (flags & AOM_EFLAG_NO_UPD_GF) upd ^= AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005715
Yaowu Xuf883b422016-08-30 14:01:10 -07005716 if (flags & AOM_EFLAG_NO_UPD_ARF) upd ^= AOM_ALT_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005717
Yaowu Xuf883b422016-08-30 14:01:10 -07005718 av1_update_reference(cpi, upd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005719 }
5720
Yaowu Xuf883b422016-08-30 14:01:10 -07005721 if (flags & AOM_EFLAG_NO_UPD_ENTROPY) {
5722 av1_update_entropy(cpi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005723 }
5724}