blob: 9fa9ecca1d08fc5e71bd4e4b4338f6aa6034ab9e [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu9c01aa12016-09-01 14:32:49 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu9c01aa12016-09-01 14:32:49 -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 */
Yaowu Xuc27fc142016-08-22 16:08:15 -070011#include <stdlib.h>
12#include <string.h>
13
Yaowu Xuf883b422016-08-30 14:01:10 -070014#include "./aom_config.h"
15#include "aom/aom_encoder.h"
16#include "aom_ports/aom_once.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070017#include "aom_ports/system_state.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070018#include "aom/internal/aom_codec_internal.h"
19#include "./aom_version.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070020#include "av1/encoder/encoder.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070021#include "aom/aomcx.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070022#include "av1/encoder/firstpass.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070023#include "av1/av1_iface_common.h"
Soo-Chul Han38427e82017-09-27 15:06:13 -040024#include "av1/encoder/bitstream.h"
25#include "aom_ports/mem_ops.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070026
Luc Trudeaub5e845b2017-08-03 10:04:25 -040027#define MAG_SIZE (4)
28#define MAX_INDEX_SIZE (256)
29
Soo-Chul Hanf8589862018-01-24 03:13:14 +000030#if CONFIG_SCALABILITY
31#define MAX_NUM_ENHANCEMENT_LAYERS 128
32#endif
33
Yaowu Xuf883b422016-08-30 14:01:10 -070034struct av1_extracfg {
Yaowu Xuc27fc142016-08-22 16:08:15 -070035 int cpu_used; // available cpu percentage in 1/16
Jingning Hanb49c6ae2017-11-27 18:14:05 -080036 int dev_sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070037 unsigned int enable_auto_alt_ref;
Yaowu Xuc27fc142016-08-22 16:08:15 -070038 unsigned int enable_auto_bwd_ref;
Yaowu Xuc27fc142016-08-22 16:08:15 -070039 unsigned int noise_sensitivity;
40 unsigned int sharpness;
41 unsigned int static_thresh;
Dominic Symesf58f1112017-09-25 12:47:40 +020042 unsigned int tile_columns; // log2 number of tile columns
43 unsigned int tile_rows; // log2 number of tile rows
Fangwen Fu7b9f2b32017-01-17 14:01:52 -080044#if CONFIG_DEPENDENT_HORZTILES
45 unsigned int dependent_horz_tiles;
46#endif
Ryan Lei9b02b0e2017-01-30 15:52:20 -080047#if CONFIG_LOOPFILTERING_ACROSS_TILES
Lei7bb501d2017-12-13 15:10:34 -080048#if CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
49 unsigned int loop_filter_across_tiles_v_enabled;
50 unsigned int loop_filter_across_tiles_h_enabled;
51#else
Ryan Lei7386eda2016-12-08 21:08:31 -080052 unsigned int loop_filter_across_tiles_enabled;
Lei7bb501d2017-12-13 15:10:34 -080053#endif // CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
Ryan Lei9b02b0e2017-01-30 15:52:20 -080054#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Yaowu Xuc27fc142016-08-22 16:08:15 -070055 unsigned int arnr_max_frames;
56 unsigned int arnr_strength;
57 unsigned int min_gf_interval;
58 unsigned int max_gf_interval;
Yaowu Xuf883b422016-08-30 14:01:10 -070059 aom_tune_metric tuning;
Yaowu Xuc27fc142016-08-22 16:08:15 -070060 unsigned int cq_level; // constrained quality level
61 unsigned int rc_max_intra_bitrate_pct;
62 unsigned int rc_max_inter_bitrate_pct;
63 unsigned int gf_cbr_boost_pct;
64 unsigned int lossless;
Steinar Midtskogene44c6222017-11-09 13:22:09 +010065 unsigned int enable_cdef;
Sebastien Alaiwan1ed20242018-02-20 14:47:18 +010066 unsigned int enable_restoration;
Yaowu Xuc27fc142016-08-22 16:08:15 -070067 unsigned int enable_qm;
Yaowu Xuf7a12422018-01-31 15:29:20 -080068#if CONFIG_AOM_QM_EXT
69 unsigned int qm_y;
70 unsigned int qm_u;
71 unsigned int qm_v;
72#endif // CONFIG_AOM_QM_EXT
Yaowu Xuc27fc142016-08-22 16:08:15 -070073 unsigned int qm_min;
74 unsigned int qm_max;
Yushin Chod808bfc2017-08-10 15:54:36 -070075#if CONFIG_DIST_8X8
76 unsigned int enable_dist_8x8;
77#endif
Thomas Daviesaf6df172016-11-09 14:04:18 +000078 unsigned int num_tg;
79 unsigned int mtu_size;
Andrey Norkin28e9ce22018-01-08 10:11:21 -080080#if CONFIG_TIMING_INFO_IN_SEQ_HEADERS
81 aom_timing_info_t timing_info;
82#endif
Fangwen Fu8d164de2016-12-14 13:40:54 -080083 unsigned int disable_tempmv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070084 unsigned int frame_parallel_decoding_mode;
Jingning Hana446f552018-02-22 15:42:12 -080085 int use_dual_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -070086 AQ_MODE aq_mode;
Fangwen Fu6160df22017-04-24 09:45:51 -070087#if CONFIG_EXT_DELTA_Q
88 DELTAQ_MODE deltaq_mode;
89#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070090 unsigned int frame_periodic_boost;
Yaowu Xuf883b422016-08-30 14:01:10 -070091 aom_bit_depth_t bit_depth;
92 aom_tune_content content;
Andrey Norkin9e694632017-12-21 18:50:57 -080093 aom_color_primaries_t color_primaries;
94 aom_transfer_characteristics_t transfer_characteristics;
95 aom_matrix_coefficients_t matrix_coefficients;
anorkin76fb1262017-03-22 15:12:12 -070096 aom_chroma_sample_position_t chroma_sample_position;
Yaowu Xuc27fc142016-08-22 16:08:15 -070097 int color_range;
98 int render_width;
99 int render_height;
Yaowu Xuf883b422016-08-30 14:01:10 -0700100 aom_superblock_size_t superblock_size;
Yunqing Wangd8cd55f2017-02-27 12:16:00 -0800101#if CONFIG_EXT_TILE
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700102 unsigned int single_tile_decoding;
Yunqing Wangd8cd55f2017-02-27 12:16:00 -0800103#endif // CONFIG_EXT_TILE
Yunqing Wangff4fa062017-04-21 10:56:08 -0700104
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800105#if CONFIG_FILM_GRAIN
106 int film_grain_test_vector;
107#endif
Yunqing Wangff4fa062017-04-21 10:56:08 -0700108 unsigned int motion_vector_unit_test;
Hui Su1cb1c002018-02-05 18:21:20 -0800109#if CONFIG_CDF_UPDATE_MODE
110 unsigned int cdf_update_mode;
111#endif // CONFIG_CDF_UPDATE_MODE
Cheng Chene0c918a2018-02-22 19:38:31 -0800112#if CONFIG_JNT_COMP
113 int use_jnt_comp;
114#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700115};
116
Yaowu Xuf883b422016-08-30 14:01:10 -0700117static struct av1_extracfg default_extra_cfg = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700118 0, // cpu_used
Jingning Hanb49c6ae2017-11-27 18:14:05 -0800119 0, // dev_sf
Yaowu Xuc27fc142016-08-22 16:08:15 -0700120 1, // enable_auto_alt_ref
Sebastien Alaiwan365e6442017-10-16 11:35:00 +0200121 0, // enable_auto_bwd_ref
122 0, // noise_sensitivity
123 0, // sharpness
124 0, // static_thresh
125 0, // tile_columns
126 0, // tile_rows
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800127#if CONFIG_DEPENDENT_HORZTILES
anorkin76fb1262017-03-22 15:12:12 -0700128 0, // Dependent Horizontal tiles
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800129#endif
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800130#if CONFIG_LOOPFILTERING_ACROSS_TILES
Lei7bb501d2017-12-13 15:10:34 -0800131#if CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
132 1, // loop_filter_across_tiles_v_enabled
133 1, // loop_filter_across_tiles_h_enabled
134#else
135 1, // loop_filter_across_tiles_enabled
136#endif // CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800137#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Yaowu Xuc27fc142016-08-22 16:08:15 -0700138 7, // arnr_max_frames
139 5, // arnr_strength
140 0, // min_gf_interval; 0 -> default decision
141 0, // max_gf_interval; 0 -> default decision
Yaowu Xuf883b422016-08-30 14:01:10 -0700142 AOM_TUNE_PSNR, // tuning
Yaowu Xuc27fc142016-08-22 16:08:15 -0700143 10, // cq_level
144 0, // rc_max_intra_bitrate_pct
145 0, // rc_max_inter_bitrate_pct
146 0, // gf_cbr_boost_pct
147 0, // lossless
Frederic Barbier1aeee2e2017-11-10 17:54:22 +0100148 1, // enable_cdef
Sebastien Alaiwan1ed20242018-02-20 14:47:18 +0100149 1, // enable_restoration
Yaowu Xubfed7382018-02-25 20:18:14 -0800150 0, // enable_qm
Yaowu Xuf7a12422018-01-31 15:29:20 -0800151#if CONFIG_AOM_QM_EXT
152 DEFAULT_QM_Y, // qm_y
153 DEFAULT_QM_U, // qm_u
154 DEFAULT_QM_V, // qm_v
155#endif // CONFIG_AOM_QM_EXT
Yaowu Xuc27fc142016-08-22 16:08:15 -0700156 DEFAULT_QM_FIRST, // qm_min
157 DEFAULT_QM_LAST, // qm_max
Yushin Chod808bfc2017-08-10 15:54:36 -0700158#if CONFIG_DIST_8X8
159 0,
160#endif
Thomas Daviesaf6df172016-11-09 14:04:18 +0000161 1, // max number of tile groups
162 0, // mtu_size
Andrey Norkin28e9ce22018-01-08 10:11:21 -0800163#if CONFIG_TIMING_INFO_IN_SEQ_HEADERS
164 AOM_TIMING_UNSPECIFIED, // No picture timing signaling in bitstream
165#endif
Frederic Barbier98c16fa2018-02-07 10:22:51 +0100166 0, // disable temporal mv prediction
Fangwen Fu6160df22017-04-24 09:45:51 -0700167 1, // frame_parallel_decoding_mode
Jingning Hana446f552018-02-22 15:42:12 -0800168 1, // enable dual filter
Fangwen Fu6160df22017-04-24 09:45:51 -0700169 NO_AQ, // aq_mode
170#if CONFIG_EXT_DELTA_Q
171 NO_DELTA_Q, // deltaq_mode
172#endif
Debargha Mukherjee103991e2018-02-26 13:40:31 -0800173 0, // frame_periodic_delta_q
174 AOM_BITS_8, // Bit depth
175 AOM_CONTENT_DEFAULT, // content
176 AOM_CICP_CP_UNSPECIFIED, // CICP color space
177 AOM_CICP_TC_UNSPECIFIED, // CICP transfer characteristics
178 AOM_CICP_MC_UNSPECIFIED, // CICP matrix coefficients
Tom Finegan01d43e12017-08-17 09:21:42 -0700179 AOM_CSP_UNKNOWN, // chroma sample position
Alex Converseeb780e72016-12-13 12:46:41 -0800180 0, // color range
181 0, // render width
182 0, // render height
183 AOM_SUPERBLOCK_SIZE_DYNAMIC, // superblock_size
Yunqing Wangd8cd55f2017-02-27 12:16:00 -0800184#if CONFIG_EXT_TILE
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700185 0, // Single tile decoding is off by default.
Yunqing Wangd8cd55f2017-02-27 12:16:00 -0800186#endif // CONFIG_EXT_TILE
Yunqing Wangff4fa062017-04-21 10:56:08 -0700187
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800188#if CONFIG_FILM_GRAIN
189 0,
190#endif
Yunqing Wangff4fa062017-04-21 10:56:08 -0700191 0, // motion_vector_unit_test
Hui Su1cb1c002018-02-05 18:21:20 -0800192#if CONFIG_CDF_UPDATE_MODE
193 1, // CDF update mode
194#endif // CONFIG_CDF_UPDATE_MODE
Cheng Chene0c918a2018-02-22 19:38:31 -0800195#if CONFIG_JNT_COMP
196 1,
197#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700198};
199
Yaowu Xuf883b422016-08-30 14:01:10 -0700200struct aom_codec_alg_priv {
201 aom_codec_priv_t base;
202 aom_codec_enc_cfg_t cfg;
203 struct av1_extracfg extra_cfg;
204 AV1EncoderConfig oxcf;
205 AV1_COMP *cpi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700206 unsigned char *cx_data;
207 size_t cx_data_sz;
208 unsigned char *pending_cx_data;
209 size_t pending_cx_data_sz;
210 int pending_frame_count;
211 size_t pending_frame_sizes[8];
Yaowu Xuf883b422016-08-30 14:01:10 -0700212 aom_image_t preview_img;
213 aom_enc_frame_flags_t next_frame_flags;
214 aom_postproc_cfg_t preview_ppcfg;
215 aom_codec_pkt_list_decl(256) pkt_list;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700216 unsigned int fixed_kf_cntr;
217 // BufferPool that holds all reference frames.
218 BufferPool *buffer_pool;
219};
220
Yaowu Xuf883b422016-08-30 14:01:10 -0700221static aom_codec_err_t update_error_state(
222 aom_codec_alg_priv_t *ctx, const struct aom_internal_error_info *error) {
223 const aom_codec_err_t res = error->error_code;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700224
Yaowu Xuf883b422016-08-30 14:01:10 -0700225 if (res != AOM_CODEC_OK)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700226 ctx->base.err_detail = error->has_detail ? error->detail : NULL;
227
228 return res;
229}
230
231#undef ERROR
232#define ERROR(str) \
233 do { \
234 ctx->base.err_detail = str; \
Yaowu Xuf883b422016-08-30 14:01:10 -0700235 return AOM_CODEC_INVALID_PARAM; \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700236 } while (0)
237
Urvang Joshicd8ab902016-10-28 12:32:06 -0700238#define RANGE_CHECK(p, memb, lo, hi) \
239 do { \
240 if (!((p)->memb >= (lo) && (p)->memb <= (hi))) \
241 ERROR(#memb " out of range [" #lo ".." #hi "]"); \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700242 } while (0)
243
244#define RANGE_CHECK_HI(p, memb, hi) \
245 do { \
246 if (!((p)->memb <= (hi))) ERROR(#memb " out of range [.." #hi "]"); \
247 } while (0)
248
249#define RANGE_CHECK_LO(p, memb, lo) \
250 do { \
251 if (!((p)->memb >= (lo))) ERROR(#memb " out of range [" #lo "..]"); \
252 } while (0)
253
254#define RANGE_CHECK_BOOL(p, memb) \
255 do { \
256 if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean"); \
257 } while (0)
258
Yaowu Xuf883b422016-08-30 14:01:10 -0700259static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
260 const aom_codec_enc_cfg_t *cfg,
261 const struct av1_extracfg *extra_cfg) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700262 RANGE_CHECK(cfg, g_w, 1, 65535); // 16 bits available
263 RANGE_CHECK(cfg, g_h, 1, 65535); // 16 bits available
264 RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000);
265 RANGE_CHECK(cfg, g_timebase.num, 1, cfg->g_timebase.den);
Debargha Mukherjeef9a50ea2018-01-09 22:28:20 -0800266 RANGE_CHECK_HI(cfg, g_profile, MAX_PROFILES - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700267
268 RANGE_CHECK_HI(cfg, rc_max_quantizer, 63);
269 RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer);
270 RANGE_CHECK_BOOL(extra_cfg, lossless);
Rupert Swarbrick98cab1a2017-08-09 11:41:01 +0100271 RANGE_CHECK_HI(extra_cfg, aq_mode, AQ_MODE_COUNT - 1);
Fangwen Fu6160df22017-04-24 09:45:51 -0700272#if CONFIG_EXT_DELTA_Q
Rupert Swarbrick98cab1a2017-08-09 11:41:01 +0100273 RANGE_CHECK_HI(extra_cfg, deltaq_mode, DELTAQ_MODE_COUNT - 1);
Fangwen Fu6160df22017-04-24 09:45:51 -0700274#endif
Urvang Joshicd8ab902016-10-28 12:32:06 -0700275 RANGE_CHECK_HI(extra_cfg, frame_periodic_boost, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700276 RANGE_CHECK_HI(cfg, g_threads, 64);
277 RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS);
Yaowu Xuf883b422016-08-30 14:01:10 -0700278 RANGE_CHECK(cfg, rc_end_usage, AOM_VBR, AOM_Q);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700279 RANGE_CHECK_HI(cfg, rc_undershoot_pct, 100);
280 RANGE_CHECK_HI(cfg, rc_overshoot_pct, 100);
281 RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
Yaowu Xuf883b422016-08-30 14:01:10 -0700282 RANGE_CHECK(cfg, kf_mode, AOM_KF_DISABLED, AOM_KF_AUTO);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700283 RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100);
Yaowu Xuf883b422016-08-30 14:01:10 -0700284 RANGE_CHECK(cfg, g_pass, AOM_RC_ONE_PASS, AOM_RC_LAST_PASS);
Urvang Joshicd8ab902016-10-28 12:32:06 -0700285 RANGE_CHECK_HI(extra_cfg, min_gf_interval, MAX_LAG_BUFFERS - 1);
286 RANGE_CHECK_HI(extra_cfg, max_gf_interval, MAX_LAG_BUFFERS - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700287 if (extra_cfg->max_gf_interval > 0) {
288 RANGE_CHECK(extra_cfg, max_gf_interval, 2, (MAX_LAG_BUFFERS - 1));
289 }
290 if (extra_cfg->min_gf_interval > 0 && extra_cfg->max_gf_interval > 0) {
291 RANGE_CHECK(extra_cfg, max_gf_interval, extra_cfg->min_gf_interval,
292 (MAX_LAG_BUFFERS - 1));
293 }
294
Debargha Mukherjee7166f222017-09-05 21:32:42 -0700295 RANGE_CHECK_HI(cfg, rc_resize_mode, RESIZE_MODES - 1);
Urvang Joshide71d142017-10-05 12:12:15 -0700296 RANGE_CHECK(cfg, rc_resize_denominator, SCALE_NUMERATOR,
297 SCALE_NUMERATOR << 1);
298 RANGE_CHECK(cfg, rc_resize_kf_denominator, SCALE_NUMERATOR,
299 SCALE_NUMERATOR << 1);
Debargha Mukherjee7166f222017-09-05 21:32:42 -0700300 RANGE_CHECK_HI(cfg, rc_superres_mode, SUPERRES_MODES - 1);
Urvang Joshide71d142017-10-05 12:12:15 -0700301 RANGE_CHECK(cfg, rc_superres_denominator, SCALE_NUMERATOR,
302 SCALE_NUMERATOR << 1);
303 RANGE_CHECK(cfg, rc_superres_kf_denominator, SCALE_NUMERATOR,
304 SCALE_NUMERATOR << 1);
Debargha Mukherjee7166f222017-09-05 21:32:42 -0700305 RANGE_CHECK(cfg, rc_superres_qthresh, 1, 63);
306 RANGE_CHECK(cfg, rc_superres_kf_qthresh, 1, 63);
Hui Su1cb1c002018-02-05 18:21:20 -0800307#if CONFIG_CDF_UPDATE_MODE
Hui Su483a8452018-02-26 12:28:48 -0800308 RANGE_CHECK_HI(extra_cfg, cdf_update_mode, 2);
Hui Su1cb1c002018-02-05 18:21:20 -0800309#endif // CONFIG_CDF_UPDATE_MODE
Fergus Simpsonc4e78942017-04-10 14:59:00 -0700310
Yaowu Xuf883b422016-08-30 14:01:10 -0700311 // AV1 does not support a lower bound on the keyframe interval in
Yaowu Xuc27fc142016-08-22 16:08:15 -0700312 // automatic keyframe placement mode.
Yaowu Xuf883b422016-08-30 14:01:10 -0700313 if (cfg->kf_mode != AOM_KF_DISABLED && cfg->kf_min_dist != cfg->kf_max_dist &&
Yaowu Xuc27fc142016-08-22 16:08:15 -0700314 cfg->kf_min_dist > 0)
315 ERROR(
316 "kf_min_dist not supported in auto mode, use 0 "
317 "or kf_max_dist instead.");
318
Yunqing Wangff4fa062017-04-21 10:56:08 -0700319 RANGE_CHECK_HI(extra_cfg, motion_vector_unit_test, 2);
Urvang Joshicd8ab902016-10-28 12:32:06 -0700320 RANGE_CHECK_HI(extra_cfg, enable_auto_alt_ref, 2);
Urvang Joshicd8ab902016-10-28 12:32:06 -0700321 RANGE_CHECK_HI(extra_cfg, enable_auto_bwd_ref, 2);
Alex Converse561d0af2017-03-23 12:58:04 -0700322 RANGE_CHECK(extra_cfg, cpu_used, 0, 8);
Jingning Hanb49c6ae2017-11-27 18:14:05 -0800323 RANGE_CHECK(extra_cfg, dev_sf, 0, UINT8_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700324 RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6);
Yaowu Xuf883b422016-08-30 14:01:10 -0700325 RANGE_CHECK(extra_cfg, superblock_size, AOM_SUPERBLOCK_SIZE_64X64,
326 AOM_SUPERBLOCK_SIZE_DYNAMIC);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700327#if CONFIG_EXT_TILE
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700328 RANGE_CHECK_HI(cfg, large_scale_tile, 1);
329 RANGE_CHECK_HI(extra_cfg, single_tile_decoding, 1);
330
331 if (cfg->large_scale_tile) {
Yunqing Wang13a8f282018-02-23 16:44:38 -0800332// TODO(any): Warning. If CONFIG_EXT_TILE is true, tile_columns really
Yaowu Xuc27fc142016-08-22 16:08:15 -0700333// means tile_width, and tile_rows really means tile_hight. The interface
334// should be sanitized.
335#if CONFIG_EXT_PARTITION
Yunqing Wang13a8f282018-02-23 16:44:38 -0800336 // While cfg->large_scale_tile = 1, only allow AOM_SUPERBLOCK_SIZE_64X64 and
337 // AOM_SUPERBLOCK_SIZE_128X128 for superblock_size. If superblock_size =
338 // AOM_SUPERBLOCK_SIZE_DYNAMIC(default), hard set it to
339 // AOM_SUPERBLOCK_SIZE_64X64(default value in large_scale_tile) in
340 // set_encoder_config().
341 if (extra_cfg->superblock_size == AOM_SUPERBLOCK_SIZE_128X128) {
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700342 if (extra_cfg->tile_columns != 0)
343 RANGE_CHECK(extra_cfg, tile_columns, 1, 32);
344 if (extra_cfg->tile_rows != 0) RANGE_CHECK(extra_cfg, tile_rows, 1, 32);
345 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700346#endif // CONFIG_EXT_PARTITION
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700347 if (extra_cfg->tile_columns != 0)
348 RANGE_CHECK(extra_cfg, tile_columns, 1, 64);
349 if (extra_cfg->tile_rows != 0) RANGE_CHECK(extra_cfg, tile_rows, 1, 64);
350#if CONFIG_EXT_PARTITION
351 }
352#endif // CONFIG_EXT_PARTITION
353 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700354#endif // CONFIG_EXT_TILE
Dominic Symesdb5d66f2017-08-18 18:11:34 +0200355#if CONFIG_MAX_TILE
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700356 RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
Dominic Symesdb5d66f2017-08-18 18:11:34 +0200357 RANGE_CHECK_HI(extra_cfg, tile_rows, 6);
358#else // CONFIG_MAX_TILE
359 RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
360 RANGE_CHECK_HI(extra_cfg, tile_rows, 2);
361#endif // CONFIG_MAX_TILE
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700362#if CONFIG_EXT_TILE
363 }
364#endif // CONFIG_EXT_TILE
Debargha Mukherjeef340fec2018-01-10 18:12:22 -0800365 RANGE_CHECK_HI(cfg, monochrome, 1);
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700366
Yunqing Wangd512e6d2017-11-08 17:20:59 -0800367#if CONFIG_EXT_TILE
368 if (cfg->large_scale_tile && extra_cfg->aq_mode)
369 ERROR(
370 "Adaptive quantization are not supported in large scale tile "
371 "coding.");
372#endif // CONFIG_EXT_TILE
373
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800374#if CONFIG_DEPENDENT_HORZTILES
375 RANGE_CHECK_HI(extra_cfg, dependent_horz_tiles, 1);
376#endif
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800377#if CONFIG_LOOPFILTERING_ACROSS_TILES
Lei7bb501d2017-12-13 15:10:34 -0800378#if CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
379 RANGE_CHECK_HI(extra_cfg, loop_filter_across_tiles_v_enabled, 1);
380 RANGE_CHECK_HI(extra_cfg, loop_filter_across_tiles_h_enabled, 1);
381#else
Ryan Lei7386eda2016-12-08 21:08:31 -0800382 RANGE_CHECK_HI(extra_cfg, loop_filter_across_tiles_enabled, 1);
Lei7bb501d2017-12-13 15:10:34 -0800383#endif // CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800384#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Yaowu Xuc27fc142016-08-22 16:08:15 -0700385 RANGE_CHECK_HI(extra_cfg, sharpness, 7);
Urvang Joshicd8ab902016-10-28 12:32:06 -0700386 RANGE_CHECK_HI(extra_cfg, arnr_max_frames, 15);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700387 RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);
Urvang Joshicd8ab902016-10-28 12:32:06 -0700388 RANGE_CHECK_HI(extra_cfg, cq_level, 63);
Yaowu Xuf883b422016-08-30 14:01:10 -0700389 RANGE_CHECK(cfg, g_bit_depth, AOM_BITS_8, AOM_BITS_12);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700390 RANGE_CHECK(cfg, g_input_bit_depth, 8, 12);
Yaowu Xuf883b422016-08-30 14:01:10 -0700391 RANGE_CHECK(extra_cfg, content, AOM_CONTENT_DEFAULT, AOM_CONTENT_INVALID - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700392
Yaowu Xuf883b422016-08-30 14:01:10 -0700393 // TODO(yaowu): remove this when ssim tuning is implemented for av1
394 if (extra_cfg->tuning == AOM_TUNE_SSIM)
395 ERROR("Option --tune=ssim is not currently supported in AV1.");
Yaowu Xuc27fc142016-08-22 16:08:15 -0700396
Yaowu Xuf883b422016-08-30 14:01:10 -0700397 if (cfg->g_pass == AOM_RC_LAST_PASS) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700398 const size_t packet_sz = sizeof(FIRSTPASS_STATS);
399 const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
400 const FIRSTPASS_STATS *stats;
401
402 if (cfg->rc_twopass_stats_in.buf == NULL)
403 ERROR("rc_twopass_stats_in.buf not set.");
404
405 if (cfg->rc_twopass_stats_in.sz % packet_sz)
406 ERROR("rc_twopass_stats_in.sz indicates truncated packet.");
407
408 if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)
409 ERROR("rc_twopass_stats_in requires at least two packets.");
410
411 stats =
412 (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1;
413
414 if ((int)(stats->count + 0.5) != n_packets - 1)
415 ERROR("rc_twopass_stats_in missing EOS stats packet");
416 }
417
Yaowu Xuc27fc142016-08-22 16:08:15 -0700418 if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
Debargha Mukherjeef9a50ea2018-01-09 22:28:20 -0800419 cfg->g_bit_depth > AOM_BITS_10) {
420 ERROR("Codec bit-depth 12 not supported in profile < 2");
Yaowu Xuc27fc142016-08-22 16:08:15 -0700421 }
Debargha Mukherjeef9a50ea2018-01-09 22:28:20 -0800422 if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
423 cfg->g_input_bit_depth > 10) {
424 ERROR("Source bit-depth 12 not supported in profile < 2");
Yaowu Xuc27fc142016-08-22 16:08:15 -0700425 }
Andrey Norkin9e694632017-12-21 18:50:57 -0800426
Andrey Norkin9e694632017-12-21 18:50:57 -0800427 RANGE_CHECK(extra_cfg, color_primaries, AOM_CICP_CP_BT_709,
428 AOM_CICP_CP_EBU_3213); // Need to check range more precisely to
429 // check for reserved values?
430 RANGE_CHECK(extra_cfg, transfer_characteristics, AOM_CICP_TC_BT_709,
431 AOM_CICP_TC_HLG);
432 RANGE_CHECK(extra_cfg, matrix_coefficients, AOM_CICP_MC_BT_709,
433 AOM_CICP_MC_ICTCP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700434 RANGE_CHECK(extra_cfg, color_range, 0, 1);
Tom Fineganc7bf4fb2017-10-26 08:46:33 -0700435
436#if CONFIG_DIST_8X8
437 RANGE_CHECK(extra_cfg, tuning, AOM_TUNE_PSNR, AOM_TUNE_DAALA_DIST);
438#else
439 RANGE_CHECK(extra_cfg, tuning, AOM_TUNE_PSNR, AOM_TUNE_SSIM);
440#endif
441
Andrey Norkin28e9ce22018-01-08 10:11:21 -0800442#if CONFIG_TIMING_INFO_IN_SEQ_HEADERS
443 RANGE_CHECK(extra_cfg, timing_info, AOM_TIMING_UNSPECIFIED, AOM_TIMING_EQUAL);
444#endif
445
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800446#if CONFIG_FILM_GRAIN
447 RANGE_CHECK(extra_cfg, film_grain_test_vector, 0, 16);
448#endif
449
Yushin Chob70615b2018-01-08 11:34:40 -0800450 if (extra_cfg->lossless) {
451 if (extra_cfg->aq_mode != 0)
452 ERROR("Only --aq_mode=0 can be used with --lossless=1.");
453#if CONFIG_DIST_8X8
454 if (extra_cfg->enable_dist_8x8)
455 ERROR("dist-8x8 cannot be used with lossless compression.");
456#endif
457 }
458
Yaowu Xuf883b422016-08-30 14:01:10 -0700459 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700460}
461
Yaowu Xuf883b422016-08-30 14:01:10 -0700462static aom_codec_err_t validate_img(aom_codec_alg_priv_t *ctx,
463 const aom_image_t *img) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700464 switch (img->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700465 case AOM_IMG_FMT_YV12:
466 case AOM_IMG_FMT_I420:
467 case AOM_IMG_FMT_I42016: break;
Yaowu Xuf883b422016-08-30 14:01:10 -0700468 case AOM_IMG_FMT_I444:
Yaowu Xuf883b422016-08-30 14:01:10 -0700469 case AOM_IMG_FMT_I44416:
Debargha Mukherjeef9a50ea2018-01-09 22:28:20 -0800470 if (ctx->cfg.g_profile == (unsigned int)PROFILE_0) {
471 ERROR("Invalid image format. I444 images not supported in profile.");
Yaowu Xuc27fc142016-08-22 16:08:15 -0700472 }
473 break;
Debargha Mukherjeef9a50ea2018-01-09 22:28:20 -0800474 case AOM_IMG_FMT_I422:
475 case AOM_IMG_FMT_I42216:
476 if (ctx->cfg.g_profile != (unsigned int)PROFILE_2) {
477 ERROR("Invalid image format. I422 images not supported in profile.");
478 }
479 break;
480 case AOM_IMG_FMT_I440:
481 case AOM_IMG_FMT_I44016:
Yaowu Xuc27fc142016-08-22 16:08:15 -0700482 default:
483 ERROR(
484 "Invalid image format. Only YV12, I420, I422, I444 images are "
485 "supported.");
486 break;
487 }
488
489 if (img->d_w != ctx->cfg.g_w || img->d_h != ctx->cfg.g_h)
490 ERROR("Image size must match encoder init configuration size");
491
Yaowu Xuf883b422016-08-30 14:01:10 -0700492 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700493}
494
Yaowu Xuf883b422016-08-30 14:01:10 -0700495static int get_image_bps(const aom_image_t *img) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700496 switch (img->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700497 case AOM_IMG_FMT_YV12:
498 case AOM_IMG_FMT_I420: return 12;
499 case AOM_IMG_FMT_I422: return 16;
500 case AOM_IMG_FMT_I444: return 24;
501 case AOM_IMG_FMT_I440: return 16;
502 case AOM_IMG_FMT_I42016: return 24;
503 case AOM_IMG_FMT_I42216: return 32;
504 case AOM_IMG_FMT_I44416: return 48;
505 case AOM_IMG_FMT_I44016: return 32;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700506 default: assert(0 && "Invalid image format"); break;
507 }
508 return 0;
509}
510
Yaowu Xuf883b422016-08-30 14:01:10 -0700511static aom_codec_err_t set_encoder_config(
512 AV1EncoderConfig *oxcf, const aom_codec_enc_cfg_t *cfg,
513 const struct av1_extracfg *extra_cfg) {
514 const int is_vbr = cfg->rc_end_usage == AOM_VBR;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700515 oxcf->profile = cfg->g_profile;
516 oxcf->max_threads = (int)cfg->g_threads;
517 oxcf->width = cfg->g_w;
518 oxcf->height = cfg->g_h;
519 oxcf->bit_depth = cfg->g_bit_depth;
520 oxcf->input_bit_depth = cfg->g_input_bit_depth;
521 // guess a frame rate if out of whack, use 30
522 oxcf->init_framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num;
Andrey Norkin28e9ce22018-01-08 10:11:21 -0800523#if CONFIG_TIMING_INFO_IN_SEQ_HEADERS
524 if (extra_cfg->timing_info == AOM_TIMING_EQUAL) {
525 oxcf->timing_info_present = 1;
526 oxcf->num_units_in_tick = cfg->g_timebase.num;
527 oxcf->time_scale = cfg->g_timebase.den;
528 oxcf->equal_picture_interval = 1;
529 oxcf->num_ticks_per_picture = 1;
530 } else {
531 oxcf->timing_info_present = 0;
532 }
533 if (oxcf->init_framerate > 180) {
534 oxcf->init_framerate = 30;
535 oxcf->timing_info_present = 0;
536 }
537#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700538 if (oxcf->init_framerate > 180) oxcf->init_framerate = 30;
539
Andrey Norkin28e9ce22018-01-08 10:11:21 -0800540#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700541 oxcf->mode = GOOD;
Maxym Dmytrychenkocc6e0e12018-02-05 16:35:37 +0100542 oxcf->cfg = &cfg->cfg;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700543
544 switch (cfg->g_pass) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700545 case AOM_RC_ONE_PASS: oxcf->pass = 0; break;
546 case AOM_RC_FIRST_PASS: oxcf->pass = 1; break;
547 case AOM_RC_LAST_PASS: oxcf->pass = 2; break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700548 }
549
550 oxcf->lag_in_frames =
Yaowu Xuf883b422016-08-30 14:01:10 -0700551 cfg->g_pass == AOM_RC_FIRST_PASS ? 0 : cfg->g_lag_in_frames;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700552 oxcf->rc_mode = cfg->rc_end_usage;
553
554 // Convert target bandwidth from Kbit/s to Bit/s
555 oxcf->target_bandwidth = 1000 * cfg->rc_target_bitrate;
556 oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct;
557 oxcf->rc_max_inter_bitrate_pct = extra_cfg->rc_max_inter_bitrate_pct;
558 oxcf->gf_cbr_boost_pct = extra_cfg->gf_cbr_boost_pct;
559
560 oxcf->best_allowed_q =
Yaowu Xuf883b422016-08-30 14:01:10 -0700561 extra_cfg->lossless ? 0 : av1_quantizer_to_qindex(cfg->rc_min_quantizer);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700562 oxcf->worst_allowed_q =
Yaowu Xuf883b422016-08-30 14:01:10 -0700563 extra_cfg->lossless ? 0 : av1_quantizer_to_qindex(cfg->rc_max_quantizer);
564 oxcf->cq_level = av1_quantizer_to_qindex(extra_cfg->cq_level);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700565 oxcf->fixed_q = -1;
566
Steinar Midtskogene44c6222017-11-09 13:22:09 +0100567 oxcf->using_cdef = extra_cfg->enable_cdef;
Sebastien Alaiwan1ed20242018-02-20 14:47:18 +0100568 oxcf->using_restoration = extra_cfg->enable_restoration;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700569 oxcf->using_qm = extra_cfg->enable_qm;
Yaowu Xuf7a12422018-01-31 15:29:20 -0800570#if CONFIG_AOM_QM_EXT
571 oxcf->qm_y = extra_cfg->qm_y;
572 oxcf->qm_u = extra_cfg->qm_u;
573 oxcf->qm_v = extra_cfg->qm_v;
574#endif // CONFIG_AOM_QM_EXT
Yaowu Xuc27fc142016-08-22 16:08:15 -0700575 oxcf->qm_minlevel = extra_cfg->qm_min;
576 oxcf->qm_maxlevel = extra_cfg->qm_max;
Yushin Chod808bfc2017-08-10 15:54:36 -0700577#if CONFIG_DIST_8X8
578 oxcf->using_dist_8x8 = extra_cfg->enable_dist_8x8;
579 if (extra_cfg->tuning == AOM_TUNE_CDEF_DIST ||
580 extra_cfg->tuning == AOM_TUNE_DAALA_DIST)
581 oxcf->using_dist_8x8 = 1;
582#endif
Thomas Daviesaf6df172016-11-09 14:04:18 +0000583 oxcf->num_tile_groups = extra_cfg->num_tg;
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700584#if CONFIG_EXT_TILE
585 // In large-scale tile encoding mode, num_tile_groups is always 1.
586 if (cfg->large_scale_tile) oxcf->num_tile_groups = 1;
587#endif // CONFIG_EXT_TILE
Thomas Daviesaf6df172016-11-09 14:04:18 +0000588 oxcf->mtu = extra_cfg->mtu_size;
Thomas Daviesaf6df172016-11-09 14:04:18 +0000589
Fangwen Fu8d164de2016-12-14 13:40:54 -0800590 oxcf->disable_tempmv = extra_cfg->disable_tempmv;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700591 oxcf->under_shoot_pct = cfg->rc_undershoot_pct;
592 oxcf->over_shoot_pct = cfg->rc_overshoot_pct;
593
Debargha Mukherjee29e40a62017-06-14 09:37:12 -0700594 oxcf->resize_mode = (RESIZE_MODE)cfg->rc_resize_mode;
Urvang Joshide71d142017-10-05 12:12:15 -0700595 oxcf->resize_scale_denominator = (uint8_t)cfg->rc_resize_denominator;
596 oxcf->resize_kf_scale_denominator = (uint8_t)cfg->rc_resize_kf_denominator;
Debargha Mukherjee29e40a62017-06-14 09:37:12 -0700597 if (oxcf->resize_mode == RESIZE_FIXED &&
Urvang Joshide71d142017-10-05 12:12:15 -0700598 oxcf->resize_scale_denominator == SCALE_NUMERATOR &&
599 oxcf->resize_kf_scale_denominator == SCALE_NUMERATOR)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700600 oxcf->resize_mode = RESIZE_NONE;
Fergus Simpson3502d082017-04-10 12:25:07 -0700601
Fergus Simpsonc4e78942017-04-10 14:59:00 -0700602 oxcf->superres_mode = (SUPERRES_MODE)cfg->rc_superres_mode;
Urvang Joshide71d142017-10-05 12:12:15 -0700603 oxcf->superres_scale_denominator = (uint8_t)cfg->rc_superres_denominator;
604 oxcf->superres_kf_scale_denominator =
605 (uint8_t)cfg->rc_superres_kf_denominator;
Debargha Mukherjee7166f222017-09-05 21:32:42 -0700606 oxcf->superres_qthresh =
607 extra_cfg->lossless ? 255
608 : av1_quantizer_to_qindex(cfg->rc_superres_qthresh);
609 oxcf->superres_kf_qthresh =
610 extra_cfg->lossless
611 ? 255
612 : av1_quantizer_to_qindex(cfg->rc_superres_kf_qthresh);
Fergus Simpsonc4e78942017-04-10 14:59:00 -0700613 if (oxcf->superres_mode == SUPERRES_FIXED &&
Urvang Joshide71d142017-10-05 12:12:15 -0700614 oxcf->superres_scale_denominator == SCALE_NUMERATOR &&
615 oxcf->superres_kf_scale_denominator == SCALE_NUMERATOR)
Fergus Simpsonc4e78942017-04-10 14:59:00 -0700616 oxcf->superres_mode = SUPERRES_NONE;
Debargha Mukherjee7166f222017-09-05 21:32:42 -0700617 if (oxcf->superres_mode == SUPERRES_QTHRESH &&
618 oxcf->superres_qthresh == 255 && oxcf->superres_kf_qthresh == 255)
619 oxcf->superres_mode = SUPERRES_NONE;
Fergus Simpson3502d082017-04-10 12:25:07 -0700620
Yaowu Xuc27fc142016-08-22 16:08:15 -0700621 oxcf->maximum_buffer_size_ms = is_vbr ? 240000 : cfg->rc_buf_sz;
622 oxcf->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz;
623 oxcf->optimal_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_optimal_sz;
624
625 oxcf->drop_frames_water_mark = cfg->rc_dropframe_thresh;
626
627 oxcf->two_pass_vbrbias = cfg->rc_2pass_vbr_bias_pct;
628 oxcf->two_pass_vbrmin_section = cfg->rc_2pass_vbr_minsection_pct;
629 oxcf->two_pass_vbrmax_section = cfg->rc_2pass_vbr_maxsection_pct;
630
631 oxcf->auto_key =
Yaowu Xuf883b422016-08-30 14:01:10 -0700632 cfg->kf_mode == AOM_KF_AUTO && cfg->kf_min_dist != cfg->kf_max_dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700633
634 oxcf->key_freq = cfg->kf_max_dist;
635
Alex Converse561d0af2017-03-23 12:58:04 -0700636 oxcf->speed = extra_cfg->cpu_used;
Jingning Hanb49c6ae2017-11-27 18:14:05 -0800637 oxcf->dev_sf = extra_cfg->dev_sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700638 oxcf->enable_auto_arf = extra_cfg->enable_auto_alt_ref;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700639 oxcf->enable_auto_brf = extra_cfg->enable_auto_bwd_ref;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700640 oxcf->noise_sensitivity = extra_cfg->noise_sensitivity;
641 oxcf->sharpness = extra_cfg->sharpness;
642
643 oxcf->two_pass_stats_in = cfg->rc_twopass_stats_in;
644
645#if CONFIG_FP_MB_STATS
646 oxcf->firstpass_mb_stats_in = cfg->rc_firstpass_mb_stats_in;
647#endif
648
Andrey Norkin9e694632017-12-21 18:50:57 -0800649 oxcf->color_primaries = extra_cfg->color_primaries;
650 oxcf->transfer_characteristics = extra_cfg->transfer_characteristics;
651 oxcf->matrix_coefficients = extra_cfg->matrix_coefficients;
anorkin76fb1262017-03-22 15:12:12 -0700652 oxcf->chroma_sample_position = extra_cfg->chroma_sample_position;
Tom Finegan01d43e12017-08-17 09:21:42 -0700653
Yaowu Xuc27fc142016-08-22 16:08:15 -0700654 oxcf->color_range = extra_cfg->color_range;
655 oxcf->render_width = extra_cfg->render_width;
656 oxcf->render_height = extra_cfg->render_height;
657 oxcf->arnr_max_frames = extra_cfg->arnr_max_frames;
Debargha Mukherjee6141cc82017-10-23 17:12:22 -0700658 // Adjust g_lag_in_frames down if not needed
659 oxcf->lag_in_frames =
660 AOMMIN(MAX_GF_INTERVAL + oxcf->arnr_max_frames / 2, oxcf->lag_in_frames);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700661 oxcf->arnr_strength = extra_cfg->arnr_strength;
662 oxcf->min_gf_interval = extra_cfg->min_gf_interval;
663 oxcf->max_gf_interval = extra_cfg->max_gf_interval;
664
665 oxcf->tuning = extra_cfg->tuning;
666 oxcf->content = extra_cfg->content;
667
Hui Su1cb1c002018-02-05 18:21:20 -0800668#if CONFIG_CDF_UPDATE_MODE
669 oxcf->cdf_update_mode = (uint8_t)extra_cfg->cdf_update_mode;
670#endif // CONFIG_CDF_UPDATE_MODE
671
Yaowu Xuc27fc142016-08-22 16:08:15 -0700672#if CONFIG_EXT_PARTITION
673 oxcf->superblock_size = extra_cfg->superblock_size;
674#endif // CONFIG_EXT_PARTITION
675
Andrey Norkin6f1c2f72018-01-15 20:08:52 -0800676#if CONFIG_FILM_GRAIN
677 oxcf->film_grain_test_vector = extra_cfg->film_grain_test_vector;
678#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700679#if CONFIG_EXT_TILE
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700680 oxcf->large_scale_tile = cfg->large_scale_tile;
681 oxcf->single_tile_decoding =
682 (oxcf->large_scale_tile) ? extra_cfg->single_tile_decoding : 0;
683 if (oxcf->large_scale_tile) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700684#if CONFIG_EXT_PARTITION
Yunqing Wang13a8f282018-02-23 16:44:38 -0800685 // superblock_size can only be AOM_SUPERBLOCK_SIZE_64X64 or
686 // AOM_SUPERBLOCK_SIZE_128X128 while oxcf->large_scale_tile = 1;
687 if (extra_cfg->superblock_size != AOM_SUPERBLOCK_SIZE_64X64 &&
688 extra_cfg->superblock_size != AOM_SUPERBLOCK_SIZE_128X128)
689 oxcf->superblock_size = AOM_SUPERBLOCK_SIZE_64X64;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700690 const unsigned int max =
Yunqing Wang13a8f282018-02-23 16:44:38 -0800691 oxcf->superblock_size == AOM_SUPERBLOCK_SIZE_64X64 ? 64 : 32;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700692#else
693 const unsigned int max = 64;
694#endif // CONFIG_EXT_PARTITION
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700695 // If tile size is not set, set it to the default value.
696 const unsigned int tc =
697 (!extra_cfg->tile_columns) ? UINT_MAX : extra_cfg->tile_columns;
698 const unsigned int tr =
699 (!extra_cfg->tile_rows) ? UINT_MAX : extra_cfg->tile_rows;
700
701 oxcf->tile_columns = AOMMIN(tc, max);
702 oxcf->tile_rows = AOMMIN(tr, max);
703 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700704#endif // CONFIG_EXT_TILE
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700705 oxcf->tile_columns = extra_cfg->tile_columns;
706 oxcf->tile_rows = extra_cfg->tile_rows;
707#if CONFIG_EXT_TILE
708 }
709#endif // CONFIG_EXT_TILE
Debargha Mukherjeef340fec2018-01-10 18:12:22 -0800710 oxcf->monochrome = cfg->monochrome;
Jingning Hana446f552018-02-22 15:42:12 -0800711 oxcf->enable_dual_filter = extra_cfg->use_dual_filter;
Cheng Chene0c918a2018-02-22 19:38:31 -0800712#if CONFIG_JNT_COMP
713 oxcf->enable_jnt_comp = extra_cfg->use_jnt_comp;
714#endif
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700715
Dominic Symesf58f1112017-09-25 12:47:40 +0200716#if CONFIG_MAX_TILE
Dominic Symes26ad0b22017-10-01 16:35:13 +0200717 oxcf->tile_width_count = AOMMIN(cfg->tile_width_count, MAX_TILE_COLS);
718 oxcf->tile_height_count = AOMMIN(cfg->tile_height_count, MAX_TILE_ROWS);
719 for (int i = 0; i < oxcf->tile_width_count; i++) {
720 oxcf->tile_widths[i] = AOMMAX(cfg->tile_widths[i], 1);
721 }
722 for (int i = 0; i < oxcf->tile_height_count; i++) {
723 oxcf->tile_heights[i] = AOMMAX(cfg->tile_heights[i], 1);
724 }
Dominic Symesf58f1112017-09-25 12:47:40 +0200725#endif
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800726#if CONFIG_DEPENDENT_HORZTILES
Yunqing Wangeeb08a92017-07-07 21:25:18 -0700727 oxcf->dependent_horz_tiles =
728#if CONFIG_EXT_TILE
729 (cfg->large_scale_tile) ? 0 :
730#endif // CONFIG_EXT_TILE
731 extra_cfg->dependent_horz_tiles;
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800732#endif
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800733#if CONFIG_LOOPFILTERING_ACROSS_TILES
Lei7bb501d2017-12-13 15:10:34 -0800734#if CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
735 oxcf->loop_filter_across_tiles_v_enabled =
736 extra_cfg->loop_filter_across_tiles_v_enabled;
737 oxcf->loop_filter_across_tiles_h_enabled =
738 extra_cfg->loop_filter_across_tiles_h_enabled;
739#else
Ryan Lei7386eda2016-12-08 21:08:31 -0800740 oxcf->loop_filter_across_tiles_enabled =
741 extra_cfg->loop_filter_across_tiles_enabled;
Lei7bb501d2017-12-13 15:10:34 -0800742#endif // CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800743#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Yaowu Xuc27fc142016-08-22 16:08:15 -0700744 oxcf->error_resilient_mode = cfg->g_error_resilient;
745 oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode;
746
747 oxcf->aq_mode = extra_cfg->aq_mode;
Fangwen Fu6160df22017-04-24 09:45:51 -0700748#if CONFIG_EXT_DELTA_Q
749 oxcf->deltaq_mode = extra_cfg->deltaq_mode;
750#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700751
752 oxcf->frame_periodic_boost = extra_cfg->frame_periodic_boost;
Yunqing Wangff4fa062017-04-21 10:56:08 -0700753 oxcf->motion_vector_unit_test = extra_cfg->motion_vector_unit_test;
Yaowu Xuf883b422016-08-30 14:01:10 -0700754 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700755}
756
Yaowu Xuf883b422016-08-30 14:01:10 -0700757static aom_codec_err_t encoder_set_config(aom_codec_alg_priv_t *ctx,
758 const aom_codec_enc_cfg_t *cfg) {
759 aom_codec_err_t res;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700760 int force_key = 0;
761
762 if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700763 if (cfg->g_lag_in_frames > 1 || cfg->g_pass != AOM_RC_ONE_PASS)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700764 ERROR("Cannot change width or height after initialization");
765 if (!valid_ref_frame_size(ctx->cfg.g_w, ctx->cfg.g_h, cfg->g_w, cfg->g_h) ||
766 (ctx->cpi->initial_width && (int)cfg->g_w > ctx->cpi->initial_width) ||
767 (ctx->cpi->initial_height && (int)cfg->g_h > ctx->cpi->initial_height))
768 force_key = 1;
769 }
770
771 // Prevent increasing lag_in_frames. This check is stricter than it needs
772 // to be -- the limit is not increasing past the first lag_in_frames
773 // value, but we don't track the initial config, only the last successful
774 // config.
775 if (cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames)
776 ERROR("Cannot increase lag_in_frames");
777
778 res = validate_config(ctx, cfg, &ctx->extra_cfg);
779
Yaowu Xuf883b422016-08-30 14:01:10 -0700780 if (res == AOM_CODEC_OK) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700781 ctx->cfg = *cfg;
782 set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
783 // On profile change, request a key frame
784 force_key |= ctx->cpi->common.profile != ctx->oxcf.profile;
Yaowu Xuf883b422016-08-30 14:01:10 -0700785 av1_change_config(ctx->cpi, &ctx->oxcf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700786 }
787
Yaowu Xuf883b422016-08-30 14:01:10 -0700788 if (force_key) ctx->next_frame_flags |= AOM_EFLAG_FORCE_KF;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700789
790 return res;
791}
792
Yaowu Xuf883b422016-08-30 14:01:10 -0700793static aom_codec_err_t ctrl_get_quantizer(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700794 va_list args) {
795 int *const arg = va_arg(args, int *);
Yaowu Xuf883b422016-08-30 14:01:10 -0700796 if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
797 *arg = av1_get_quantizer(ctx->cpi);
798 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700799}
800
Yaowu Xuf883b422016-08-30 14:01:10 -0700801static aom_codec_err_t ctrl_get_quantizer64(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700802 va_list args) {
803 int *const arg = va_arg(args, int *);
Yaowu Xuf883b422016-08-30 14:01:10 -0700804 if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
805 *arg = av1_qindex_to_quantizer(av1_get_quantizer(ctx->cpi));
806 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700807}
808
Yaowu Xuf883b422016-08-30 14:01:10 -0700809static aom_codec_err_t update_extra_cfg(aom_codec_alg_priv_t *ctx,
810 const struct av1_extracfg *extra_cfg) {
811 const aom_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg);
812 if (res == AOM_CODEC_OK) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700813 ctx->extra_cfg = *extra_cfg;
814 set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
Yaowu Xuf883b422016-08-30 14:01:10 -0700815 av1_change_config(ctx->cpi, &ctx->oxcf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700816 }
817 return res;
818}
819
Yaowu Xuf883b422016-08-30 14:01:10 -0700820static aom_codec_err_t ctrl_set_cpuused(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700821 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700822 struct av1_extracfg extra_cfg = ctx->extra_cfg;
823 extra_cfg.cpu_used = CAST(AOME_SET_CPUUSED, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700824 return update_extra_cfg(ctx, &extra_cfg);
825}
826
Jingning Hanb49c6ae2017-11-27 18:14:05 -0800827static aom_codec_err_t ctrl_set_devsf(aom_codec_alg_priv_t *ctx, va_list args) {
828 struct av1_extracfg extra_cfg = ctx->extra_cfg;
829 extra_cfg.dev_sf = CAST(AOME_SET_DEVSF, args);
830 return update_extra_cfg(ctx, &extra_cfg);
831}
832
Yaowu Xuf883b422016-08-30 14:01:10 -0700833static aom_codec_err_t ctrl_set_enable_auto_alt_ref(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700834 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700835 struct av1_extracfg extra_cfg = ctx->extra_cfg;
836 extra_cfg.enable_auto_alt_ref = CAST(AOME_SET_ENABLEAUTOALTREF, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700837 return update_extra_cfg(ctx, &extra_cfg);
838}
839
Yaowu Xuf883b422016-08-30 14:01:10 -0700840static aom_codec_err_t ctrl_set_enable_auto_bwd_ref(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700841 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700842 struct av1_extracfg extra_cfg = ctx->extra_cfg;
843 extra_cfg.enable_auto_bwd_ref = CAST(AOME_SET_ENABLEAUTOBWDREF, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700844 return update_extra_cfg(ctx, &extra_cfg);
845}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700846
Yaowu Xuf883b422016-08-30 14:01:10 -0700847static aom_codec_err_t ctrl_set_noise_sensitivity(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700848 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700849 struct av1_extracfg extra_cfg = ctx->extra_cfg;
850 extra_cfg.noise_sensitivity = CAST(AV1E_SET_NOISE_SENSITIVITY, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700851 return update_extra_cfg(ctx, &extra_cfg);
852}
853
Yaowu Xuf883b422016-08-30 14:01:10 -0700854static aom_codec_err_t ctrl_set_sharpness(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700855 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700856 struct av1_extracfg extra_cfg = ctx->extra_cfg;
857 extra_cfg.sharpness = CAST(AOME_SET_SHARPNESS, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700858 return update_extra_cfg(ctx, &extra_cfg);
859}
860
Yaowu Xuf883b422016-08-30 14:01:10 -0700861static aom_codec_err_t ctrl_set_static_thresh(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700862 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700863 struct av1_extracfg extra_cfg = ctx->extra_cfg;
864 extra_cfg.static_thresh = CAST(AOME_SET_STATIC_THRESHOLD, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700865 return update_extra_cfg(ctx, &extra_cfg);
866}
867
Yaowu Xuf883b422016-08-30 14:01:10 -0700868static aom_codec_err_t ctrl_set_tile_columns(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700869 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700870 struct av1_extracfg extra_cfg = ctx->extra_cfg;
871 extra_cfg.tile_columns = CAST(AV1E_SET_TILE_COLUMNS, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700872 return update_extra_cfg(ctx, &extra_cfg);
873}
874
Yaowu Xuf883b422016-08-30 14:01:10 -0700875static aom_codec_err_t ctrl_set_tile_rows(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700876 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700877 struct av1_extracfg extra_cfg = ctx->extra_cfg;
878 extra_cfg.tile_rows = CAST(AV1E_SET_TILE_ROWS, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700879 return update_extra_cfg(ctx, &extra_cfg);
880}
Dominic Symesf58f1112017-09-25 12:47:40 +0200881
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800882#if CONFIG_DEPENDENT_HORZTILES
883static aom_codec_err_t ctrl_set_tile_dependent_rows(aom_codec_alg_priv_t *ctx,
884 va_list args) {
885 struct av1_extracfg extra_cfg = ctx->extra_cfg;
886 extra_cfg.dependent_horz_tiles = CAST(AV1E_SET_TILE_DEPENDENT_ROWS, args);
887 return update_extra_cfg(ctx, &extra_cfg);
888}
889#endif
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800890#if CONFIG_LOOPFILTERING_ACROSS_TILES
Lei7bb501d2017-12-13 15:10:34 -0800891#if CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
892static aom_codec_err_t ctrl_set_tile_loopfilter_v(aom_codec_alg_priv_t *ctx,
893 va_list args) {
894 struct av1_extracfg extra_cfg = ctx->extra_cfg;
895 extra_cfg.loop_filter_across_tiles_v_enabled =
896 CAST(AV1E_SET_TILE_LOOPFILTER_V, args);
897 return update_extra_cfg(ctx, &extra_cfg);
898}
899static aom_codec_err_t ctrl_set_tile_loopfilter_h(aom_codec_alg_priv_t *ctx,
900 va_list args) {
901 struct av1_extracfg extra_cfg = ctx->extra_cfg;
902 extra_cfg.loop_filter_across_tiles_h_enabled =
903 CAST(AV1E_SET_TILE_LOOPFILTER_H, args);
904 return update_extra_cfg(ctx, &extra_cfg);
905}
906#else
Ryan Lei7386eda2016-12-08 21:08:31 -0800907static aom_codec_err_t ctrl_set_tile_loopfilter(aom_codec_alg_priv_t *ctx,
908 va_list args) {
909 struct av1_extracfg extra_cfg = ctx->extra_cfg;
910 extra_cfg.loop_filter_across_tiles_enabled =
911 CAST(AV1E_SET_TILE_LOOPFILTER, args);
912 return update_extra_cfg(ctx, &extra_cfg);
913}
Lei7bb501d2017-12-13 15:10:34 -0800914#endif // CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800915#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Ryan Lei7386eda2016-12-08 21:08:31 -0800916
Yaowu Xuf883b422016-08-30 14:01:10 -0700917static aom_codec_err_t ctrl_set_arnr_max_frames(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700918 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700919 struct av1_extracfg extra_cfg = ctx->extra_cfg;
920 extra_cfg.arnr_max_frames = CAST(AOME_SET_ARNR_MAXFRAMES, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700921 return update_extra_cfg(ctx, &extra_cfg);
922}
923
Yaowu Xuf883b422016-08-30 14:01:10 -0700924static aom_codec_err_t ctrl_set_arnr_strength(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700925 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700926 struct av1_extracfg extra_cfg = ctx->extra_cfg;
927 extra_cfg.arnr_strength = CAST(AOME_SET_ARNR_STRENGTH, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700928 return update_extra_cfg(ctx, &extra_cfg);
929}
930
Yaowu Xuf883b422016-08-30 14:01:10 -0700931static aom_codec_err_t ctrl_set_tuning(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700932 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700933 struct av1_extracfg extra_cfg = ctx->extra_cfg;
934 extra_cfg.tuning = CAST(AOME_SET_TUNING, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700935 return update_extra_cfg(ctx, &extra_cfg);
936}
937
Yaowu Xuf883b422016-08-30 14:01:10 -0700938static aom_codec_err_t ctrl_set_cq_level(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700939 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700940 struct av1_extracfg extra_cfg = ctx->extra_cfg;
941 extra_cfg.cq_level = CAST(AOME_SET_CQ_LEVEL, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700942 return update_extra_cfg(ctx, &extra_cfg);
943}
944
Yaowu Xuf883b422016-08-30 14:01:10 -0700945static aom_codec_err_t ctrl_set_rc_max_intra_bitrate_pct(
946 aom_codec_alg_priv_t *ctx, va_list args) {
947 struct av1_extracfg extra_cfg = ctx->extra_cfg;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700948 extra_cfg.rc_max_intra_bitrate_pct =
Yaowu Xuf883b422016-08-30 14:01:10 -0700949 CAST(AOME_SET_MAX_INTRA_BITRATE_PCT, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700950 return update_extra_cfg(ctx, &extra_cfg);
951}
952
Yaowu Xuf883b422016-08-30 14:01:10 -0700953static aom_codec_err_t ctrl_set_rc_max_inter_bitrate_pct(
954 aom_codec_alg_priv_t *ctx, va_list args) {
955 struct av1_extracfg extra_cfg = ctx->extra_cfg;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700956 extra_cfg.rc_max_inter_bitrate_pct =
Yaowu Xuf883b422016-08-30 14:01:10 -0700957 CAST(AOME_SET_MAX_INTER_BITRATE_PCT, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700958 return update_extra_cfg(ctx, &extra_cfg);
959}
960
Yaowu Xuf883b422016-08-30 14:01:10 -0700961static aom_codec_err_t ctrl_set_rc_gf_cbr_boost_pct(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700962 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700963 struct av1_extracfg extra_cfg = ctx->extra_cfg;
964 extra_cfg.gf_cbr_boost_pct = CAST(AV1E_SET_GF_CBR_BOOST_PCT, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700965 return update_extra_cfg(ctx, &extra_cfg);
966}
967
Yaowu Xuf883b422016-08-30 14:01:10 -0700968static aom_codec_err_t ctrl_set_lossless(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700969 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700970 struct av1_extracfg extra_cfg = ctx->extra_cfg;
971 extra_cfg.lossless = CAST(AV1E_SET_LOSSLESS, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700972 return update_extra_cfg(ctx, &extra_cfg);
973}
974
Steinar Midtskogene44c6222017-11-09 13:22:09 +0100975static aom_codec_err_t ctrl_set_enable_cdef(aom_codec_alg_priv_t *ctx,
976 va_list args) {
977 struct av1_extracfg extra_cfg = ctx->extra_cfg;
978 extra_cfg.enable_cdef = CAST(AV1E_SET_ENABLE_CDEF, args);
979 return update_extra_cfg(ctx, &extra_cfg);
980}
Steinar Midtskogene44c6222017-11-09 13:22:09 +0100981
Sebastien Alaiwan1ed20242018-02-20 14:47:18 +0100982static aom_codec_err_t ctrl_set_enable_restoration(aom_codec_alg_priv_t *ctx,
983 va_list args) {
984 struct av1_extracfg extra_cfg = ctx->extra_cfg;
985 extra_cfg.enable_restoration = CAST(AV1E_SET_ENABLE_RESTORATION, args);
986 return update_extra_cfg(ctx, &extra_cfg);
987}
988
Yaowu Xuf883b422016-08-30 14:01:10 -0700989static aom_codec_err_t ctrl_set_enable_qm(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700990 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700991 struct av1_extracfg extra_cfg = ctx->extra_cfg;
992 extra_cfg.enable_qm = CAST(AV1E_SET_ENABLE_QM, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700993 return update_extra_cfg(ctx, &extra_cfg);
994}
Yaowu Xuf7a12422018-01-31 15:29:20 -0800995#if CONFIG_AOM_QM_EXT
996static aom_codec_err_t ctrl_set_qm_y(aom_codec_alg_priv_t *ctx, va_list args) {
997 struct av1_extracfg extra_cfg = ctx->extra_cfg;
998 extra_cfg.qm_y = CAST(AV1E_SET_QM_Y, args);
999 return update_extra_cfg(ctx, &extra_cfg);
1000}
1001static aom_codec_err_t ctrl_set_qm_u(aom_codec_alg_priv_t *ctx, va_list args) {
1002 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1003 extra_cfg.qm_u = CAST(AV1E_SET_QM_U, args);
1004 return update_extra_cfg(ctx, &extra_cfg);
1005}
1006static aom_codec_err_t ctrl_set_qm_v(aom_codec_alg_priv_t *ctx, va_list args) {
1007 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1008 extra_cfg.qm_v = CAST(AV1E_SET_QM_V, args);
1009 return update_extra_cfg(ctx, &extra_cfg);
1010}
1011#endif // CONFIG_AOM_QM_EXT
Yaowu Xuc27fc142016-08-22 16:08:15 -07001012
Yaowu Xuf883b422016-08-30 14:01:10 -07001013static aom_codec_err_t ctrl_set_qm_min(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001014 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001015 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1016 extra_cfg.qm_min = CAST(AV1E_SET_QM_MIN, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001017 return update_extra_cfg(ctx, &extra_cfg);
1018}
1019
Yaowu Xuf883b422016-08-30 14:01:10 -07001020static aom_codec_err_t ctrl_set_qm_max(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001021 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001022 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1023 extra_cfg.qm_max = CAST(AV1E_SET_QM_MAX, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001024 return update_extra_cfg(ctx, &extra_cfg);
1025}
Yushin Chod808bfc2017-08-10 15:54:36 -07001026#if CONFIG_DIST_8X8
1027static aom_codec_err_t ctrl_set_enable_dist_8x8(aom_codec_alg_priv_t *ctx,
1028 va_list args) {
1029 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1030 extra_cfg.enable_dist_8x8 = CAST(AV1E_SET_ENABLE_DIST_8X8, args);
1031 return update_extra_cfg(ctx, &extra_cfg);
1032}
1033#endif
Thomas Daviesaf6df172016-11-09 14:04:18 +00001034static aom_codec_err_t ctrl_set_num_tg(aom_codec_alg_priv_t *ctx,
1035 va_list args) {
1036 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1037 extra_cfg.num_tg = CAST(AV1E_SET_NUM_TG, args);
1038 return update_extra_cfg(ctx, &extra_cfg);
1039}
1040
1041static aom_codec_err_t ctrl_set_mtu(aom_codec_alg_priv_t *ctx, va_list args) {
1042 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1043 extra_cfg.mtu_size = CAST(AV1E_SET_MTU, args);
1044 return update_extra_cfg(ctx, &extra_cfg);
1045}
Andrey Norkin28e9ce22018-01-08 10:11:21 -08001046#if CONFIG_TIMING_INFO_IN_SEQ_HEADERS
1047static aom_codec_err_t ctrl_set_timing_info(aom_codec_alg_priv_t *ctx,
1048 va_list args) {
1049 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1050 extra_cfg.timing_info = CAST(AV1E_SET_TIMING_INFO, args);
1051 return update_extra_cfg(ctx, &extra_cfg);
1052}
1053#endif
Fangwen Fu8d164de2016-12-14 13:40:54 -08001054static aom_codec_err_t ctrl_set_disable_tempmv(aom_codec_alg_priv_t *ctx,
1055 va_list args) {
1056 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1057 extra_cfg.disable_tempmv = CAST(AV1E_SET_DISABLE_TEMPMV, args);
1058 return update_extra_cfg(ctx, &extra_cfg);
1059}
Jingning Hana446f552018-02-22 15:42:12 -08001060
1061static aom_codec_err_t ctrl_set_enable_df(aom_codec_alg_priv_t *ctx,
1062 va_list args) {
1063 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1064 extra_cfg.use_dual_filter = CAST(AV1E_SET_ENABLE_DF, args);
1065 return update_extra_cfg(ctx, &extra_cfg);
1066}
1067
Cheng Chene0c918a2018-02-22 19:38:31 -08001068#if CONFIG_JNT_COMP
1069static aom_codec_err_t ctrl_set_enable_jnt_comp(aom_codec_alg_priv_t *ctx,
1070 va_list args) {
1071 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1072 extra_cfg.use_jnt_comp = CAST(AV1E_SET_ENABLE_JNT_COMP, args);
1073 return update_extra_cfg(ctx, &extra_cfg);
1074}
1075#endif
1076
Yaowu Xuf883b422016-08-30 14:01:10 -07001077static aom_codec_err_t ctrl_set_frame_parallel_decoding_mode(
1078 aom_codec_alg_priv_t *ctx, va_list args) {
1079 struct av1_extracfg extra_cfg = ctx->extra_cfg;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001080 extra_cfg.frame_parallel_decoding_mode =
Yaowu Xuf883b422016-08-30 14:01:10 -07001081 CAST(AV1E_SET_FRAME_PARALLEL_DECODING, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001082 return update_extra_cfg(ctx, &extra_cfg);
1083}
1084
Yunqing Wangd8cd55f2017-02-27 12:16:00 -08001085#if CONFIG_EXT_TILE
Yunqing Wangeeb08a92017-07-07 21:25:18 -07001086static aom_codec_err_t ctrl_set_single_tile_decoding(aom_codec_alg_priv_t *ctx,
1087 va_list args) {
Yunqing Wangd8cd55f2017-02-27 12:16:00 -08001088 struct av1_extracfg extra_cfg = ctx->extra_cfg;
Yunqing Wangeeb08a92017-07-07 21:25:18 -07001089 extra_cfg.single_tile_decoding = CAST(AV1E_SET_SINGLE_TILE_DECODING, args);
Yunqing Wangd8cd55f2017-02-27 12:16:00 -08001090 return update_extra_cfg(ctx, &extra_cfg);
1091}
1092#endif // CONFIG_EXT_TILE
1093
Yaowu Xuf883b422016-08-30 14:01:10 -07001094static aom_codec_err_t ctrl_set_aq_mode(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001095 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001096 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1097 extra_cfg.aq_mode = CAST(AV1E_SET_AQ_MODE, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001098 return update_extra_cfg(ctx, &extra_cfg);
1099}
1100
Andrey Norkin6f1c2f72018-01-15 20:08:52 -08001101#if CONFIG_FILM_GRAIN
1102static aom_codec_err_t ctrl_set_film_grain_test_vector(
1103 aom_codec_alg_priv_t *ctx, va_list args) {
1104 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1105 extra_cfg.film_grain_test_vector =
1106 CAST(AV1E_SET_FILM_GRAIN_TEST_VECTOR, args);
1107 return update_extra_cfg(ctx, &extra_cfg);
1108}
1109#endif
1110
Fangwen Fu6160df22017-04-24 09:45:51 -07001111#if CONFIG_EXT_DELTA_Q
1112static aom_codec_err_t ctrl_set_deltaq_mode(aom_codec_alg_priv_t *ctx,
1113 va_list args) {
1114 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1115 extra_cfg.deltaq_mode = CAST(AV1E_SET_DELTAQ_MODE, args);
1116 return update_extra_cfg(ctx, &extra_cfg);
1117}
1118#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001119static aom_codec_err_t ctrl_set_min_gf_interval(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001120 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001121 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1122 extra_cfg.min_gf_interval = CAST(AV1E_SET_MIN_GF_INTERVAL, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001123 return update_extra_cfg(ctx, &extra_cfg);
1124}
1125
Yaowu Xuf883b422016-08-30 14:01:10 -07001126static aom_codec_err_t ctrl_set_max_gf_interval(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001127 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001128 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1129 extra_cfg.max_gf_interval = CAST(AV1E_SET_MAX_GF_INTERVAL, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001130 return update_extra_cfg(ctx, &extra_cfg);
1131}
1132
Yaowu Xuf883b422016-08-30 14:01:10 -07001133static aom_codec_err_t ctrl_set_frame_periodic_boost(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001134 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001135 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1136 extra_cfg.frame_periodic_boost = CAST(AV1E_SET_FRAME_PERIODIC_BOOST, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001137 return update_extra_cfg(ctx, &extra_cfg);
1138}
1139
Yunqing Wangff4fa062017-04-21 10:56:08 -07001140static aom_codec_err_t ctrl_enable_motion_vector_unit_test(
1141 aom_codec_alg_priv_t *ctx, va_list args) {
1142 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1143 extra_cfg.motion_vector_unit_test =
1144 CAST(AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, args);
1145 return update_extra_cfg(ctx, &extra_cfg);
1146}
1147
Yaowu Xuf883b422016-08-30 14:01:10 -07001148static aom_codec_err_t encoder_init(aom_codec_ctx_t *ctx,
1149 aom_codec_priv_enc_mr_cfg_t *data) {
1150 aom_codec_err_t res = AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001151 (void)data;
1152
1153 if (ctx->priv == NULL) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001154 aom_codec_alg_priv_t *const priv = aom_calloc(1, sizeof(*priv));
1155 if (priv == NULL) return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001156
Yaowu Xuf883b422016-08-30 14:01:10 -07001157 ctx->priv = (aom_codec_priv_t *)priv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001158 ctx->priv->init_flags = ctx->init_flags;
1159 ctx->priv->enc.total_encoders = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07001160 priv->buffer_pool = (BufferPool *)aom_calloc(1, sizeof(BufferPool));
1161 if (priv->buffer_pool == NULL) return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001162
1163#if CONFIG_MULTITHREAD
1164 if (pthread_mutex_init(&priv->buffer_pool->pool_mutex, NULL)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001165 return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001166 }
1167#endif
1168
1169 if (ctx->config.enc) {
1170 // Update the reference to the config structure to an internal copy.
1171 priv->cfg = *ctx->config.enc;
1172 ctx->config.enc = &priv->cfg;
1173 }
1174
1175 priv->extra_cfg = default_extra_cfg;
Yaowu Xuf883b422016-08-30 14:01:10 -07001176 once(av1_initialize_enc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001177
1178 res = validate_config(priv, &priv->cfg, &priv->extra_cfg);
1179
Yaowu Xuf883b422016-08-30 14:01:10 -07001180 if (res == AOM_CODEC_OK) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001181 set_encoder_config(&priv->oxcf, &priv->cfg, &priv->extra_cfg);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001182 priv->oxcf.use_highbitdepth =
Yaowu Xuf883b422016-08-30 14:01:10 -07001183 (ctx->init_flags & AOM_CODEC_USE_HIGHBITDEPTH) ? 1 : 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07001184 priv->cpi = av1_create_compressor(&priv->oxcf, priv->buffer_pool);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001185 if (priv->cpi == NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07001186 res = AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001187 else
1188 priv->cpi->output_pkt_list = &priv->pkt_list.head;
1189 }
1190 }
1191
1192 return res;
1193}
1194
Yaowu Xuf883b422016-08-30 14:01:10 -07001195static aom_codec_err_t encoder_destroy(aom_codec_alg_priv_t *ctx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001196 free(ctx->cx_data);
Yaowu Xuf883b422016-08-30 14:01:10 -07001197 av1_remove_compressor(ctx->cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001198#if CONFIG_MULTITHREAD
1199 pthread_mutex_destroy(&ctx->buffer_pool->pool_mutex);
1200#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001201 aom_free(ctx->buffer_pool);
1202 aom_free(ctx);
1203 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001204}
1205
Yaowu Xuc27fc142016-08-22 16:08:15 -07001206// Turn on to test if supplemental superframe data breaks decoding
Sebastien Alaiwanf7b67562017-06-21 16:50:55 +02001207#define TEST_SUPPLEMENTAL_SUPERFRAME_DATA 0
1208
Yaowu Xuf883b422016-08-30 14:01:10 -07001209// av1 uses 10,000,000 ticks/second as time stamp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001210#define TICKS_PER_SEC 10000000LL
1211
Yaowu Xuf883b422016-08-30 14:01:10 -07001212static int64_t timebase_units_to_ticks(const aom_rational_t *timebase,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001213 int64_t n) {
1214 return n * TICKS_PER_SEC * timebase->num / timebase->den;
1215}
1216
Yaowu Xuf883b422016-08-30 14:01:10 -07001217static int64_t ticks_to_timebase_units(const aom_rational_t *timebase,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001218 int64_t n) {
1219 const int64_t round = TICKS_PER_SEC * timebase->num / 2 - 1;
1220 return (n * timebase->den + round) / timebase->num / TICKS_PER_SEC;
1221}
1222
Yaowu Xuf883b422016-08-30 14:01:10 -07001223static aom_codec_frame_flags_t get_frame_pkt_flags(const AV1_COMP *cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001224 unsigned int lib_flags) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001225 aom_codec_frame_flags_t flags = lib_flags << 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001226
Yaowu Xuf883b422016-08-30 14:01:10 -07001227 if (lib_flags & FRAMEFLAGS_KEY) flags |= AOM_FRAME_IS_KEY;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001228
Yaowu Xuf883b422016-08-30 14:01:10 -07001229 if (cpi->droppable) flags |= AOM_FRAME_IS_DROPPABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001230
1231 return flags;
1232}
1233
Yaowu Xuf883b422016-08-30 14:01:10 -07001234static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
1235 const aom_image_t *img,
1236 aom_codec_pts_t pts,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001237 unsigned long duration,
Sean DuBois47cc2552018-01-23 07:44:16 +00001238 aom_enc_frame_flags_t enc_flags) {
Ralph Giles19944292017-04-18 13:46:56 -07001239 const size_t kMinCompressedSize = 8192;
Yaowu Xuf883b422016-08-30 14:01:10 -07001240 volatile aom_codec_err_t res = AOM_CODEC_OK;
Yaowu Xuf883b422016-08-30 14:01:10 -07001241 AV1_COMP *const cpi = ctx->cpi;
1242 const aom_rational_t *const timebase = &ctx->cfg.g_timebase;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001243
Yaowu Xuf883b422016-08-30 14:01:10 -07001244 if (cpi == NULL) return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001245
1246 if (img != NULL) {
1247 res = validate_img(ctx, img);
1248 // TODO(jzern) the checks related to cpi's validity should be treated as a
1249 // failure condition, encoder setup is done fully in init() currently.
Yaowu Xuf883b422016-08-30 14:01:10 -07001250 if (res == AOM_CODEC_OK) {
Sebastien Alaiwan62fc41a2017-06-19 11:02:20 +02001251 size_t data_sz = ALIGN_POWER_OF_TWO(ctx->cfg.g_w, 5) *
1252 ALIGN_POWER_OF_TWO(ctx->cfg.g_h, 5) * get_image_bps(img);
Yaowu Xu416b0d92016-07-11 11:38:53 -07001253 if (data_sz < kMinCompressedSize) data_sz = kMinCompressedSize;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001254 if (ctx->cx_data == NULL || ctx->cx_data_sz < data_sz) {
1255 ctx->cx_data_sz = data_sz;
1256 free(ctx->cx_data);
1257 ctx->cx_data = (unsigned char *)malloc(ctx->cx_data_sz);
1258 if (ctx->cx_data == NULL) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001259 return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001260 }
1261 }
1262 }
1263 }
1264
Sean DuBois47cc2552018-01-23 07:44:16 +00001265 if (ctx->oxcf.mode != GOOD) {
1266 ctx->oxcf.mode = GOOD;
1267 av1_change_config(ctx->cpi, &ctx->oxcf);
1268 }
1269
Yaowu Xuf883b422016-08-30 14:01:10 -07001270 aom_codec_pkt_list_init(&ctx->pkt_list);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001271
Sebastien Alaiwan62fc41a2017-06-19 11:02:20 +02001272 volatile aom_enc_frame_flags_t flags = enc_flags;
1273
Yaowu Xuc27fc142016-08-22 16:08:15 -07001274 if (setjmp(cpi->common.error.jmp)) {
1275 cpi->common.error.setjmp = 0;
1276 res = update_error_state(ctx, &cpi->common.error);
Yaowu Xuf883b422016-08-30 14:01:10 -07001277 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07001278 return res;
1279 }
1280 cpi->common.error.setjmp = 1;
1281
Yunqing Wang9a50fec2017-11-02 17:02:00 -07001282 // Note(yunqing): While applying encoding flags, always start from enabling
1283 // all, and then modifying according to the flags. Previous frame's flags are
1284 // overwritten.
Yaowu Xuf883b422016-08-30 14:01:10 -07001285 av1_apply_encoding_flags(cpi, flags);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001286
1287 // Handle fixed keyframe intervals
Yaowu Xuf883b422016-08-30 14:01:10 -07001288 if (ctx->cfg.kf_mode == AOM_KF_AUTO &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07001289 ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) {
1290 if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001291 flags |= AOM_EFLAG_FORCE_KF;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001292 ctx->fixed_kf_cntr = 1;
1293 }
1294 }
1295
Yaowu Xuf883b422016-08-30 14:01:10 -07001296 if (res == AOM_CODEC_OK) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001297 int64_t dst_time_stamp = timebase_units_to_ticks(timebase, pts);
1298 int64_t dst_end_time_stamp =
1299 timebase_units_to_ticks(timebase, pts + duration);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001300
1301 // Set up internal flags
Yaowu Xuf883b422016-08-30 14:01:10 -07001302 if (ctx->base.init_flags & AOM_CODEC_USE_PSNR) cpi->b_calculate_psnr = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001303
1304 if (img != NULL) {
Sebastien Alaiwan62fc41a2017-06-19 11:02:20 +02001305 YV12_BUFFER_CONFIG sd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001306 res = image2yuvconfig(img, &sd);
1307
1308 // Store the original flags in to the frame buffer. Will extract the
1309 // key frame flag when we actually encode this frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07001310 if (av1_receive_raw_frame(cpi, flags | ctx->next_frame_flags, &sd,
1311 dst_time_stamp, dst_end_time_stamp)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001312 res = update_error_state(ctx, &cpi->common.error);
1313 }
1314 ctx->next_frame_flags = 0;
1315 }
1316
Sebastien Alaiwan62fc41a2017-06-19 11:02:20 +02001317 unsigned char *cx_data = ctx->cx_data;
1318 size_t cx_data_sz = ctx->cx_data_sz;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001319
1320 /* Any pending invisible frames? */
1321 if (ctx->pending_cx_data) {
1322 memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz);
1323 ctx->pending_cx_data = cx_data;
1324 cx_data += ctx->pending_cx_data_sz;
1325 cx_data_sz -= ctx->pending_cx_data_sz;
1326
1327 /* TODO: this is a minimal check, the underlying codec doesn't respect
1328 * the buffer size anyway.
1329 */
1330 if (cx_data_sz < ctx->cx_data_sz / 2) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001331 aom_internal_error(&cpi->common.error, AOM_CODEC_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001332 "Compressed data buffer too small");
Yaowu Xuf883b422016-08-30 14:01:10 -07001333 return AOM_CODEC_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001334 }
1335 }
1336
Luc Trudeaub5e845b2017-08-03 10:04:25 -04001337 size_t frame_size = 0;
Sebastien Alaiwan62fc41a2017-06-19 11:02:20 +02001338 unsigned int lib_flags = 0;
Luc Trudeaub5e845b2017-08-03 10:04:25 -04001339 int is_frame_visible = 0;
1340 int index_size = 0;
1341 // invisible frames get packed with the next visible frame
1342 while (cx_data_sz - index_size >= ctx->cx_data_sz / 2 &&
1343 !is_frame_visible &&
Sebastien Alaiwan918c3c12017-06-19 11:32:10 +02001344 -1 != av1_get_compressed_data(cpi, &lib_flags, &frame_size, cx_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07001345 &dst_time_stamp, &dst_end_time_stamp,
1346 !img)) {
David Barker5e70a112017-10-03 14:28:17 +01001347 if (cpi->common.seq_params.frame_id_numbers_present_flag) {
Debargha Mukherjee778023d2017-09-26 17:50:27 -07001348 if (cpi->common.invalid_delta_frame_id_minus1) {
1349 ctx->base.err_detail = "Invalid delta_frame_id_minus1";
1350 return AOM_CODEC_ERROR;
1351 }
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01001352 }
Luc Trudeaub5e845b2017-08-03 10:04:25 -04001353 if (frame_size) {
1354 if (ctx->pending_cx_data == 0) ctx->pending_cx_data = cx_data;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001355
Luc Trudeaub5e845b2017-08-03 10:04:25 -04001356 ctx->pending_frame_sizes[ctx->pending_frame_count++] = frame_size;
1357 ctx->pending_cx_data_sz += frame_size;
Sebastien Alaiwane4d6f9b2017-06-21 12:17:46 +02001358
Luc Trudeaub5e845b2017-08-03 10:04:25 -04001359 cx_data += frame_size;
1360 cx_data_sz -= frame_size;
Sebastien Alaiwan493fd882017-06-21 12:33:55 +02001361
Luc Trudeaub5e845b2017-08-03 10:04:25 -04001362 index_size = MAG_SIZE * (ctx->pending_frame_count - 1) + 2;
Sebastien Alaiwan493fd882017-06-21 12:33:55 +02001363
Luc Trudeaub5e845b2017-08-03 10:04:25 -04001364 is_frame_visible = cpi->common.show_frame;
1365 }
1366 }
1367 if (is_frame_visible) {
Sebastien Alaiwane4d6f9b2017-06-21 12:17:46 +02001368 // Add the frame packet to the list of returned packets.
1369 aom_codec_cx_pkt_t pkt;
1370
1371 pkt.kind = AOM_CODEC_CX_FRAME_PKT;
Sebastien Alaiwan493fd882017-06-21 12:33:55 +02001372
1373 pkt.data.frame.buf = ctx->pending_cx_data;
1374 pkt.data.frame.sz = ctx->pending_cx_data_sz;
1375 pkt.data.frame.partition_id = -1;
1376
Soo-Chul Hanf8589862018-01-24 03:13:14 +00001377 int write_temporal_delimiter = 1;
1378#if CONFIG_SCALABILITY
1379 // only write OBU_TD if base layer
1380 write_temporal_delimiter = !cpi->common.enhancement_layer_id;
1381#endif // CONFIG_SCALABILITY
1382 if (write_temporal_delimiter) {
1383 // move data PRE_OBU_SIZE_BYTES + 1 bytes and insert OBU_TD preceded by
1384 // optional 4 byte size
1385 uint32_t obu_size = 1;
Tom Fineganf2d40f62018-02-01 11:52:49 -08001386#if CONFIG_OBU_SIZING
1387 const size_t length_field_size = aom_uleb_size_in_bytes(obu_size);
1388#else
1389 const size_t length_field_size = PRE_OBU_SIZE_BYTES;
1390#endif
Soo-Chul Hanf8589862018-01-24 03:13:14 +00001391 if (ctx->pending_cx_data) {
Tom Fineganf2d40f62018-02-01 11:52:49 -08001392 const size_t obu_header_size = length_field_size + 1;
1393 memmove(ctx->pending_cx_data + obu_header_size, ctx->pending_cx_data,
Soo-Chul Hanf8589862018-01-24 03:13:14 +00001394 ctx->pending_cx_data_sz);
1395 }
1396 obu_size = write_obu_header(
1397 OBU_TEMPORAL_DELIMITER, 0,
Tom Fineganf2d40f62018-02-01 11:52:49 -08001398 (uint8_t *)(ctx->pending_cx_data + length_field_size));
Tom Finegan41150ad2018-01-23 11:42:55 -08001399#if CONFIG_OBU_SIZING
Soo-Chul Hanf8589862018-01-24 03:13:14 +00001400 // OBUs are preceded by an unsigned leb128 coded unsigned integer padded
1401 // to PRE_OBU_SIZE_BYTES bytes.
1402 if (write_uleb_obu_size(obu_size, ctx->pending_cx_data) != AOM_CODEC_OK)
1403 return AOM_CODEC_ERROR;
Tom Finegan41150ad2018-01-23 11:42:55 -08001404#else
Soo-Chul Hanf8589862018-01-24 03:13:14 +00001405 mem_put_le32(ctx->pending_cx_data, obu_size);
Tom Finegan41150ad2018-01-23 11:42:55 -08001406#endif // CONFIG_OBU_SIZING
Tom Fineganf2d40f62018-02-01 11:52:49 -08001407 pkt.data.frame.sz += obu_size + length_field_size;
Soo-Chul Hanf8589862018-01-24 03:13:14 +00001408 }
Soo-Chul Han38427e82017-09-27 15:06:13 -04001409
Sebastien Alaiwane4d6f9b2017-06-21 12:17:46 +02001410 pkt.data.frame.pts = ticks_to_timebase_units(timebase, dst_time_stamp);
Sebastien Alaiwan493fd882017-06-21 12:33:55 +02001411 pkt.data.frame.flags = get_frame_pkt_flags(cpi, lib_flags);
Sebastien Alaiwane4d6f9b2017-06-21 12:17:46 +02001412 pkt.data.frame.duration = (uint32_t)ticks_to_timebase_units(
1413 timebase, dst_end_time_stamp - dst_time_stamp);
Sebastien Alaiwane4d6f9b2017-06-21 12:17:46 +02001414
1415 aom_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
1416
Sebastien Alaiwan493fd882017-06-21 12:33:55 +02001417 ctx->pending_cx_data = NULL;
1418 ctx->pending_cx_data_sz = 0;
1419 ctx->pending_frame_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001420 }
1421 }
1422
1423 cpi->common.error.setjmp = 0;
1424 return res;
1425}
1426
Yaowu Xuf883b422016-08-30 14:01:10 -07001427static const aom_codec_cx_pkt_t *encoder_get_cxdata(aom_codec_alg_priv_t *ctx,
1428 aom_codec_iter_t *iter) {
1429 return aom_codec_pkt_list_get(&ctx->pkt_list.head, iter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001430}
1431
Yaowu Xuf883b422016-08-30 14:01:10 -07001432static aom_codec_err_t ctrl_set_reference(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001433 va_list args) {
Thomas Daede497d1952017-08-08 17:33:06 -07001434 av1_ref_frame_t *const frame = va_arg(args, av1_ref_frame_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001435
1436 if (frame != NULL) {
1437 YV12_BUFFER_CONFIG sd;
1438
1439 image2yuvconfig(&frame->img, &sd);
Thomas Daede497d1952017-08-08 17:33:06 -07001440 av1_set_reference_enc(ctx->cpi, frame->idx, &sd);
Yaowu Xuf883b422016-08-30 14:01:10 -07001441 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001442 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001443 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001444 }
1445}
1446
Yaowu Xuf883b422016-08-30 14:01:10 -07001447static aom_codec_err_t ctrl_copy_reference(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001448 va_list args) {
Thomas Daede497d1952017-08-08 17:33:06 -07001449 av1_ref_frame_t *const frame = va_arg(args, av1_ref_frame_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001450
1451 if (frame != NULL) {
1452 YV12_BUFFER_CONFIG sd;
1453
1454 image2yuvconfig(&frame->img, &sd);
Thomas Daede497d1952017-08-08 17:33:06 -07001455 av1_copy_reference_enc(ctx->cpi, frame->idx, &sd);
Yaowu Xuf883b422016-08-30 14:01:10 -07001456 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001457 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001458 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001459 }
1460}
1461
Yaowu Xuf883b422016-08-30 14:01:10 -07001462static aom_codec_err_t ctrl_get_reference(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001463 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001464 av1_ref_frame_t *const frame = va_arg(args, av1_ref_frame_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001465
1466 if (frame != NULL) {
1467 YV12_BUFFER_CONFIG *fb = get_ref_frame(&ctx->cpi->common, frame->idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07001468 if (fb == NULL) return AOM_CODEC_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001469
1470 yuvconfig2image(&frame->img, fb, NULL);
Yaowu Xuf883b422016-08-30 14:01:10 -07001471 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001472 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001473 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001474 }
1475}
1476
Yaowu Xuf883b422016-08-30 14:01:10 -07001477static aom_codec_err_t ctrl_get_new_frame_image(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001478 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001479 aom_image_t *const new_img = va_arg(args, aom_image_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001480
1481 if (new_img != NULL) {
1482 YV12_BUFFER_CONFIG new_frame;
1483
Yaowu Xuf883b422016-08-30 14:01:10 -07001484 if (av1_get_last_show_frame(ctx->cpi, &new_frame) == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001485 yuvconfig2image(new_img, &new_frame, NULL);
Yaowu Xuf883b422016-08-30 14:01:10 -07001486 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001487 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001488 return AOM_CODEC_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001489 }
1490 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001491 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001492 }
1493}
1494
Yaowu Xuf883b422016-08-30 14:01:10 -07001495static aom_codec_err_t ctrl_set_previewpp(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001496 va_list args) {
1497 (void)ctx;
1498 (void)args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001499 return AOM_CODEC_INCAPABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001500}
1501
Yaowu Xuf883b422016-08-30 14:01:10 -07001502static aom_image_t *encoder_get_preview(aom_codec_alg_priv_t *ctx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001503 YV12_BUFFER_CONFIG sd;
1504
Yaowu Xuf883b422016-08-30 14:01:10 -07001505 if (av1_get_preview_raw_frame(ctx->cpi, &sd) == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001506 yuvconfig2image(&ctx->preview_img, &sd, NULL);
1507 return &ctx->preview_img;
1508 } else {
1509 return NULL;
1510 }
1511}
1512
Yaowu Xuf883b422016-08-30 14:01:10 -07001513static aom_codec_err_t ctrl_use_reference(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001514 va_list args) {
1515 const int reference_flag = va_arg(args, int);
1516
Yaowu Xuf883b422016-08-30 14:01:10 -07001517 av1_use_as_reference(ctx->cpi, reference_flag);
1518 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001519}
1520
Yaowu Xuf883b422016-08-30 14:01:10 -07001521static aom_codec_err_t ctrl_set_roi_map(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001522 va_list args) {
1523 (void)ctx;
1524 (void)args;
1525
Yaowu Xuf883b422016-08-30 14:01:10 -07001526 // TODO(yaowu): Need to re-implement and test for AV1.
1527 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001528}
1529
Yaowu Xuf883b422016-08-30 14:01:10 -07001530static aom_codec_err_t ctrl_set_active_map(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001531 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001532 aom_active_map_t *const map = va_arg(args, aom_active_map_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001533
1534 if (map) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001535 if (!av1_set_active_map(ctx->cpi, map->active_map, (int)map->rows,
1536 (int)map->cols))
1537 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001538 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001539 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001540 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001541 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001542 }
1543}
1544
Yaowu Xuf883b422016-08-30 14:01:10 -07001545static aom_codec_err_t ctrl_get_active_map(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001546 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001547 aom_active_map_t *const map = va_arg(args, aom_active_map_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001548
1549 if (map) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001550 if (!av1_get_active_map(ctx->cpi, map->active_map, (int)map->rows,
1551 (int)map->cols))
1552 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001553 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001554 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001555 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001556 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001557 }
1558}
1559
Yaowu Xuf883b422016-08-30 14:01:10 -07001560static aom_codec_err_t ctrl_set_scale_mode(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001561 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001562 aom_scaling_mode_t *const mode = va_arg(args, aom_scaling_mode_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001563
1564 if (mode) {
1565 const int res =
Yaowu Xuf883b422016-08-30 14:01:10 -07001566 av1_set_internal_size(ctx->cpi, (AOM_SCALING)mode->h_scaling_mode,
1567 (AOM_SCALING)mode->v_scaling_mode);
1568 return (res == 0) ? AOM_CODEC_OK : AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001569 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001570 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001571 }
1572}
1573
Soo-Chul Hanf8589862018-01-24 03:13:14 +00001574static aom_codec_err_t ctrl_set_enhancement_layer_id(aom_codec_alg_priv_t *ctx,
1575 va_list args) {
1576#if CONFIG_SCALABILITY
1577 const int enhancement_layer_id = va_arg(args, int);
1578 if (enhancement_layer_id > MAX_NUM_ENHANCEMENT_LAYERS)
1579 return AOM_CODEC_INVALID_PARAM;
1580 ctx->cpi->common.enhancement_layer_id = enhancement_layer_id;
1581 return AOM_CODEC_OK;
1582#else
1583 (void)ctx;
1584 (void)args;
1585 return AOM_CODEC_UNSUP_FEATURE;
1586#endif
1587}
1588
1589static aom_codec_err_t ctrl_set_number_spatial_layers(aom_codec_alg_priv_t *ctx,
1590 va_list args) {
1591#if CONFIG_SCALABILITY
1592 const int number_spatial_layers = va_arg(args, int);
1593 if (number_spatial_layers > MAX_NUM_ENHANCEMENT_LAYERS)
1594 return AOM_CODEC_INVALID_PARAM;
1595 ctx->cpi->common.enhancement_layers_cnt = number_spatial_layers - 1;
1596 return AOM_CODEC_OK;
1597#else
1598 (void)ctx;
1599 (void)args;
1600 return AOM_CODEC_UNSUP_FEATURE;
1601#endif
1602}
1603
Yaowu Xuf883b422016-08-30 14:01:10 -07001604static aom_codec_err_t ctrl_set_tune_content(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001605 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001606 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1607 extra_cfg.content = CAST(AV1E_SET_TUNE_CONTENT, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001608 return update_extra_cfg(ctx, &extra_cfg);
1609}
1610
Hui Su1cb1c002018-02-05 18:21:20 -08001611#if CONFIG_CDF_UPDATE_MODE
1612static aom_codec_err_t ctrl_set_cdf_update_mode(aom_codec_alg_priv_t *ctx,
1613 va_list args) {
1614 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1615 extra_cfg.cdf_update_mode = CAST(AV1E_SET_CDF_UPDATE_MODE, args);
1616 return update_extra_cfg(ctx, &extra_cfg);
1617}
1618#endif // CONFIG_CDF_UPDATE_MODE
1619
Andrey Norkin9e694632017-12-21 18:50:57 -08001620static aom_codec_err_t ctrl_set_color_primaries(aom_codec_alg_priv_t *ctx,
1621 va_list args) {
1622 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1623 extra_cfg.color_primaries = CAST(AV1E_SET_COLOR_PRIMARIES, args);
1624 return update_extra_cfg(ctx, &extra_cfg);
1625}
1626
1627static aom_codec_err_t ctrl_set_transfer_characteristics(
1628 aom_codec_alg_priv_t *ctx, va_list args) {
1629 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1630 extra_cfg.transfer_characteristics =
1631 CAST(AV1E_SET_TRANSFER_CHARACTERISTICS, args);
1632 return update_extra_cfg(ctx, &extra_cfg);
1633}
1634
1635static aom_codec_err_t ctrl_set_matrix_coefficients(aom_codec_alg_priv_t *ctx,
1636 va_list args) {
1637 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1638 extra_cfg.matrix_coefficients = CAST(AV1E_SET_MATRIX_COEFFICIENTS, args);
1639 return update_extra_cfg(ctx, &extra_cfg);
1640}
anorkin76fb1262017-03-22 15:12:12 -07001641
1642static aom_codec_err_t ctrl_set_chroma_sample_position(
1643 aom_codec_alg_priv_t *ctx, va_list args) {
1644 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1645 extra_cfg.chroma_sample_position =
1646 CAST(AV1E_SET_CHROMA_SAMPLE_POSITION, args);
1647 return update_extra_cfg(ctx, &extra_cfg);
Tom Finegan01d43e12017-08-17 09:21:42 -07001648}
anorkin76fb1262017-03-22 15:12:12 -07001649
Yaowu Xuf883b422016-08-30 14:01:10 -07001650static aom_codec_err_t ctrl_set_color_range(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001651 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001652 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1653 extra_cfg.color_range = CAST(AV1E_SET_COLOR_RANGE, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001654 return update_extra_cfg(ctx, &extra_cfg);
1655}
1656
Yaowu Xuf883b422016-08-30 14:01:10 -07001657static aom_codec_err_t ctrl_set_render_size(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001658 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001659 struct av1_extracfg extra_cfg = ctx->extra_cfg;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001660 int *const render_size = va_arg(args, int *);
1661 extra_cfg.render_width = render_size[0];
1662 extra_cfg.render_height = render_size[1];
1663 return update_extra_cfg(ctx, &extra_cfg);
1664}
1665
Yaowu Xuf883b422016-08-30 14:01:10 -07001666static aom_codec_err_t ctrl_set_superblock_size(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001667 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001668 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1669 extra_cfg.superblock_size = CAST(AV1E_SET_SUPERBLOCK_SIZE, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001670 return update_extra_cfg(ctx, &extra_cfg);
1671}
1672
Yaowu Xuf883b422016-08-30 14:01:10 -07001673static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
Thomas Daede497d1952017-08-08 17:33:06 -07001674 { AV1_COPY_REFERENCE, ctrl_copy_reference },
Yaowu Xuf883b422016-08-30 14:01:10 -07001675 { AOME_USE_REFERENCE, ctrl_use_reference },
Yaowu Xuc27fc142016-08-22 16:08:15 -07001676
1677 // Setters
Thomas Daede497d1952017-08-08 17:33:06 -07001678 { AV1_SET_REFERENCE, ctrl_set_reference },
Yaowu Xuf883b422016-08-30 14:01:10 -07001679 { AOM_SET_POSTPROC, ctrl_set_previewpp },
1680 { AOME_SET_ROI_MAP, ctrl_set_roi_map },
1681 { AOME_SET_ACTIVEMAP, ctrl_set_active_map },
1682 { AOME_SET_SCALEMODE, ctrl_set_scale_mode },
Soo-Chul Hanf8589862018-01-24 03:13:14 +00001683 { AOME_SET_ENHANCEMENT_LAYER_ID, ctrl_set_enhancement_layer_id },
Yaowu Xuf883b422016-08-30 14:01:10 -07001684 { AOME_SET_CPUUSED, ctrl_set_cpuused },
Jingning Hanb49c6ae2017-11-27 18:14:05 -08001685 { AOME_SET_DEVSF, ctrl_set_devsf },
Yaowu Xuf883b422016-08-30 14:01:10 -07001686 { AOME_SET_ENABLEAUTOALTREF, ctrl_set_enable_auto_alt_ref },
Yaowu Xuf883b422016-08-30 14:01:10 -07001687 { AOME_SET_ENABLEAUTOBWDREF, ctrl_set_enable_auto_bwd_ref },
Yaowu Xuf883b422016-08-30 14:01:10 -07001688 { AOME_SET_SHARPNESS, ctrl_set_sharpness },
1689 { AOME_SET_STATIC_THRESHOLD, ctrl_set_static_thresh },
1690 { AV1E_SET_TILE_COLUMNS, ctrl_set_tile_columns },
1691 { AV1E_SET_TILE_ROWS, ctrl_set_tile_rows },
Fangwen Fu7b9f2b32017-01-17 14:01:52 -08001692#if CONFIG_DEPENDENT_HORZTILES
1693 { AV1E_SET_TILE_DEPENDENT_ROWS, ctrl_set_tile_dependent_rows },
1694#endif
Ryan Lei9b02b0e2017-01-30 15:52:20 -08001695#if CONFIG_LOOPFILTERING_ACROSS_TILES
Lei7bb501d2017-12-13 15:10:34 -08001696#if CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
1697 { AV1E_SET_TILE_LOOPFILTER_V, ctrl_set_tile_loopfilter_v },
1698 { AV1E_SET_TILE_LOOPFILTER_H, ctrl_set_tile_loopfilter_h },
1699#else
Ryan Lei7386eda2016-12-08 21:08:31 -08001700 { AV1E_SET_TILE_LOOPFILTER, ctrl_set_tile_loopfilter },
Lei7bb501d2017-12-13 15:10:34 -08001701#endif // CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
Ryan Lei9b02b0e2017-01-30 15:52:20 -08001702#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Yaowu Xuf883b422016-08-30 14:01:10 -07001703 { AOME_SET_ARNR_MAXFRAMES, ctrl_set_arnr_max_frames },
1704 { AOME_SET_ARNR_STRENGTH, ctrl_set_arnr_strength },
Yaowu Xuf883b422016-08-30 14:01:10 -07001705 { AOME_SET_TUNING, ctrl_set_tuning },
1706 { AOME_SET_CQ_LEVEL, ctrl_set_cq_level },
1707 { AOME_SET_MAX_INTRA_BITRATE_PCT, ctrl_set_rc_max_intra_bitrate_pct },
Soo-Chul Hanf8589862018-01-24 03:13:14 +00001708 { AOME_SET_NUMBER_SPATIAL_LAYERS, ctrl_set_number_spatial_layers },
Yaowu Xuf883b422016-08-30 14:01:10 -07001709 { AV1E_SET_MAX_INTER_BITRATE_PCT, ctrl_set_rc_max_inter_bitrate_pct },
1710 { AV1E_SET_GF_CBR_BOOST_PCT, ctrl_set_rc_gf_cbr_boost_pct },
1711 { AV1E_SET_LOSSLESS, ctrl_set_lossless },
Steinar Midtskogene44c6222017-11-09 13:22:09 +01001712 { AV1E_SET_ENABLE_CDEF, ctrl_set_enable_cdef },
Sebastien Alaiwan1ed20242018-02-20 14:47:18 +01001713 { AV1E_SET_ENABLE_RESTORATION, ctrl_set_enable_restoration },
Yaowu Xuf883b422016-08-30 14:01:10 -07001714 { AV1E_SET_ENABLE_QM, ctrl_set_enable_qm },
Yaowu Xuf7a12422018-01-31 15:29:20 -08001715#if CONFIG_AOM_QM_EXT
1716 { AV1E_SET_QM_Y, ctrl_set_qm_y },
1717 { AV1E_SET_QM_U, ctrl_set_qm_u },
1718 { AV1E_SET_QM_V, ctrl_set_qm_v },
1719#endif // CONFIG_AOM_QM_EXT
Yaowu Xuf883b422016-08-30 14:01:10 -07001720 { AV1E_SET_QM_MIN, ctrl_set_qm_min },
1721 { AV1E_SET_QM_MAX, ctrl_set_qm_max },
Yushin Chod808bfc2017-08-10 15:54:36 -07001722#if CONFIG_DIST_8X8
1723 { AV1E_SET_ENABLE_DIST_8X8, ctrl_set_enable_dist_8x8 },
1724#endif
Thomas Daviesaf6df172016-11-09 14:04:18 +00001725 { AV1E_SET_NUM_TG, ctrl_set_num_tg },
1726 { AV1E_SET_MTU, ctrl_set_mtu },
Andrey Norkin28e9ce22018-01-08 10:11:21 -08001727#if CONFIG_TIMING_INFO_IN_SEQ_HEADERS
1728 { AV1E_SET_TIMING_INFO, ctrl_set_timing_info },
1729#endif
Fangwen Fu8d164de2016-12-14 13:40:54 -08001730 { AV1E_SET_DISABLE_TEMPMV, ctrl_set_disable_tempmv },
Yaowu Xuf883b422016-08-30 14:01:10 -07001731 { AV1E_SET_FRAME_PARALLEL_DECODING, ctrl_set_frame_parallel_decoding_mode },
Jingning Hana446f552018-02-22 15:42:12 -08001732 { AV1E_SET_ENABLE_DF, ctrl_set_enable_df },
Cheng Chene0c918a2018-02-22 19:38:31 -08001733#if CONFIG_JNT_COMP
1734 { AV1E_SET_ENABLE_JNT_COMP, ctrl_set_enable_jnt_comp },
1735#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001736 { AV1E_SET_AQ_MODE, ctrl_set_aq_mode },
Fangwen Fu6160df22017-04-24 09:45:51 -07001737#if CONFIG_EXT_DELTA_Q
1738 { AV1E_SET_DELTAQ_MODE, ctrl_set_deltaq_mode },
1739#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001740 { AV1E_SET_FRAME_PERIODIC_BOOST, ctrl_set_frame_periodic_boost },
1741 { AV1E_SET_TUNE_CONTENT, ctrl_set_tune_content },
Hui Su1cb1c002018-02-05 18:21:20 -08001742#if CONFIG_CDF_UPDATE_MODE
1743 { AV1E_SET_CDF_UPDATE_MODE, ctrl_set_cdf_update_mode },
1744#endif // CONFIG_CDF_UPDATE_MODE
Andrey Norkin9e694632017-12-21 18:50:57 -08001745 { AV1E_SET_COLOR_PRIMARIES, ctrl_set_color_primaries },
1746 { AV1E_SET_TRANSFER_CHARACTERISTICS, ctrl_set_transfer_characteristics },
1747 { AV1E_SET_MATRIX_COEFFICIENTS, ctrl_set_matrix_coefficients },
anorkin76fb1262017-03-22 15:12:12 -07001748 { AV1E_SET_CHROMA_SAMPLE_POSITION, ctrl_set_chroma_sample_position },
Yaowu Xuf883b422016-08-30 14:01:10 -07001749 { AV1E_SET_COLOR_RANGE, ctrl_set_color_range },
1750 { AV1E_SET_NOISE_SENSITIVITY, ctrl_set_noise_sensitivity },
1751 { AV1E_SET_MIN_GF_INTERVAL, ctrl_set_min_gf_interval },
1752 { AV1E_SET_MAX_GF_INTERVAL, ctrl_set_max_gf_interval },
1753 { AV1E_SET_RENDER_SIZE, ctrl_set_render_size },
1754 { AV1E_SET_SUPERBLOCK_SIZE, ctrl_set_superblock_size },
Yunqing Wangd8cd55f2017-02-27 12:16:00 -08001755#if CONFIG_EXT_TILE
Yunqing Wangeeb08a92017-07-07 21:25:18 -07001756 { AV1E_SET_SINGLE_TILE_DECODING, ctrl_set_single_tile_decoding },
Yunqing Wangd8cd55f2017-02-27 12:16:00 -08001757#endif // CONFIG_EXT_TILE
Andrey Norkin6f1c2f72018-01-15 20:08:52 -08001758#if CONFIG_FILM_GRAIN
1759 { AV1E_SET_FILM_GRAIN_TEST_VECTOR, ctrl_set_film_grain_test_vector },
1760#endif // CONFIG_FILM_GRAIN
1761
Yunqing Wangff4fa062017-04-21 10:56:08 -07001762 { AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test },
Yaowu Xuc27fc142016-08-22 16:08:15 -07001763
1764 // Getters
Yaowu Xuf883b422016-08-30 14:01:10 -07001765 { AOME_GET_LAST_QUANTIZER, ctrl_get_quantizer },
1766 { AOME_GET_LAST_QUANTIZER_64, ctrl_get_quantizer64 },
1767 { AV1_GET_REFERENCE, ctrl_get_reference },
1768 { AV1E_GET_ACTIVEMAP, ctrl_get_active_map },
1769 { AV1_GET_NEW_FRAME_IMAGE, ctrl_get_new_frame_image },
Yaowu Xuc27fc142016-08-22 16:08:15 -07001770
1771 { -1, NULL },
1772};
1773
Yaowu Xuf883b422016-08-30 14:01:10 -07001774static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001775 { 0,
1776 {
1777 // NOLINT
1778 0, // g_usage
1779 8, // g_threads
1780 0, // g_profile
1781
1782 320, // g_width
1783 240, // g_height
Yaowu Xuf883b422016-08-30 14:01:10 -07001784 AOM_BITS_8, // g_bit_depth
Yaowu Xuc27fc142016-08-22 16:08:15 -07001785 8, // g_input_bit_depth
1786
1787 { 1, 30 }, // g_timebase
1788
1789 0, // g_error_resilient
1790
Yaowu Xuf883b422016-08-30 14:01:10 -07001791 AOM_RC_ONE_PASS, // g_pass
Yaowu Xuc27fc142016-08-22 16:08:15 -07001792
Urvang Joshic04cec22017-10-23 09:16:06 -07001793 19, // g_lag_in_frames
Yaowu Xuc27fc142016-08-22 16:08:15 -07001794
Urvang Joshide71d142017-10-05 12:12:15 -07001795 0, // rc_dropframe_thresh
1796 RESIZE_NONE, // rc_resize_mode
1797 SCALE_NUMERATOR, // rc_resize_denominator
1798 SCALE_NUMERATOR, // rc_resize_kf_denominator
Yaowu Xuc27fc142016-08-22 16:08:15 -07001799
Urvang Joshide71d142017-10-05 12:12:15 -07001800 0, // rc_superres_mode
1801 SCALE_NUMERATOR, // rc_superres_denominator
1802 SCALE_NUMERATOR, // rc_superres_kf_denominator
1803 63, // rc_superres_qthresh
1804 63, // rc_superres_kf_qthresh
Fergus Simpsonc4e78942017-04-10 14:59:00 -07001805
Yaowu Xuf883b422016-08-30 14:01:10 -07001806 AOM_VBR, // rc_end_usage
Yaowu Xuc27fc142016-08-22 16:08:15 -07001807 { NULL, 0 }, // rc_twopass_stats_in
1808 { NULL, 0 }, // rc_firstpass_mb_stats_in
1809 256, // rc_target_bandwidth
1810 0, // rc_min_quantizer
1811 63, // rc_max_quantizer
1812 25, // rc_undershoot_pct
1813 25, // rc_overshoot_pct
1814
1815 6000, // rc_max_buffer_size
1816 4000, // rc_buffer_initial_size
1817 5000, // rc_buffer_optimal_size
1818
1819 50, // rc_two_pass_vbrbias
1820 0, // rc_two_pass_vbrmin_section
1821 2000, // rc_two_pass_vbrmax_section
1822
1823 // keyframing settings (kf)
Maxym Dmytrychenkocc6e0e12018-02-05 16:35:37 +01001824 AOM_KF_AUTO, // g_kfmode
1825 0, // kf_min_dist
1826 9999, // kf_max_dist
1827 0, // large_scale_tile
1828 0, // monochrome
1829 0, // tile_width_count
1830 0, // tile_height_count
1831 { 0 }, // tile_widths
1832 { 0 }, // tile_heights
1833 { CONFIG_EXT_PARTITION }, // config file
Yaowu Xuc27fc142016-08-22 16:08:15 -07001834 } },
1835};
1836
1837#ifndef VERSION_STRING
1838#define VERSION_STRING
1839#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001840CODEC_INTERFACE(aom_codec_av1_cx) = {
1841 "AOMedia Project AV1 Encoder" VERSION_STRING,
1842 AOM_CODEC_INTERNAL_ABI_VERSION,
Yaowu Xud3e7c682017-12-21 14:08:25 -08001843 AOM_CODEC_CAP_HIGHBITDEPTH | AOM_CODEC_CAP_ENCODER |
1844 AOM_CODEC_CAP_PSNR, // aom_codec_caps_t
1845 encoder_init, // aom_codec_init_fn_t
1846 encoder_destroy, // aom_codec_destroy_fn_t
1847 encoder_ctrl_maps, // aom_codec_ctrl_fn_map_t
Yaowu Xuc27fc142016-08-22 16:08:15 -07001848 {
1849 // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07001850 NULL, // aom_codec_peek_si_fn_t
1851 NULL, // aom_codec_get_si_fn_t
1852 NULL, // aom_codec_decode_fn_t
1853 NULL, // aom_codec_frame_get_fn_t
1854 NULL // aom_codec_set_fb_fn_t
Yaowu Xuc27fc142016-08-22 16:08:15 -07001855 },
1856 {
1857 // NOLINT
1858 1, // 1 cfg map
Yaowu Xuf883b422016-08-30 14:01:10 -07001859 encoder_usage_cfg_map, // aom_codec_enc_cfg_map_t
1860 encoder_encode, // aom_codec_encode_fn_t
1861 encoder_get_cxdata, // aom_codec_get_cx_data_fn_t
1862 encoder_set_config, // aom_codec_enc_config_set_fn_t
1863 NULL, // aom_codec_get_global_headers_fn_t
1864 encoder_get_preview, // aom_codec_get_preview_frame_fn_t
1865 NULL // aom_codec_enc_mr_get_mem_loc_fn_t
Yaowu Xuc27fc142016-08-22 16:08:15 -07001866 }
1867};