blob: 29b641b772b8c2297d4c88a43325e450e1077e43 [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 */
11
12#include <stdlib.h>
13#include <string.h>
14
Yaowu Xuf883b422016-08-30 14:01:10 -070015#include "./aom_config.h"
16#include "aom/aom_encoder.h"
17#include "aom_ports/aom_once.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070018#include "aom_ports/system_state.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070019#include "aom/internal/aom_codec_internal.h"
20#include "./aom_version.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021#include "av1/encoder/encoder.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070022#include "aom/aomcx.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070023#include "av1/encoder/firstpass.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070024#include "av1/av1_iface_common.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070025
Yaowu Xuf883b422016-08-30 14:01:10 -070026struct av1_extracfg {
Yaowu Xuc27fc142016-08-22 16:08:15 -070027 int cpu_used; // available cpu percentage in 1/16
28 unsigned int enable_auto_alt_ref;
29#if CONFIG_EXT_REFS
30 unsigned int enable_auto_bwd_ref;
31#endif // CONFIG_EXT_REFS
32 unsigned int noise_sensitivity;
33 unsigned int sharpness;
34 unsigned int static_thresh;
35 unsigned int tile_columns;
36 unsigned int tile_rows;
Fangwen Fu7b9f2b32017-01-17 14:01:52 -080037#if CONFIG_DEPENDENT_HORZTILES
38 unsigned int dependent_horz_tiles;
39#endif
Ryan Lei9b02b0e2017-01-30 15:52:20 -080040#if CONFIG_LOOPFILTERING_ACROSS_TILES
Ryan Lei7386eda2016-12-08 21:08:31 -080041 unsigned int loop_filter_across_tiles_enabled;
Ryan Lei9b02b0e2017-01-30 15:52:20 -080042#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Yaowu Xuc27fc142016-08-22 16:08:15 -070043 unsigned int arnr_max_frames;
44 unsigned int arnr_strength;
45 unsigned int min_gf_interval;
46 unsigned int max_gf_interval;
Yaowu Xuf883b422016-08-30 14:01:10 -070047 aom_tune_metric tuning;
Yaowu Xuc27fc142016-08-22 16:08:15 -070048 unsigned int cq_level; // constrained quality level
49 unsigned int rc_max_intra_bitrate_pct;
50 unsigned int rc_max_inter_bitrate_pct;
51 unsigned int gf_cbr_boost_pct;
52 unsigned int lossless;
53#if CONFIG_AOM_QM
54 unsigned int enable_qm;
55 unsigned int qm_min;
56 unsigned int qm_max;
57#endif
Thomas Daviesaf6df172016-11-09 14:04:18 +000058#if CONFIG_TILE_GROUPS
59 unsigned int num_tg;
60 unsigned int mtu_size;
61#endif
Fangwen Fu8d164de2016-12-14 13:40:54 -080062#if CONFIG_TEMPMV_SIGNALING
63 unsigned int disable_tempmv;
64#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070065 unsigned int frame_parallel_decoding_mode;
66 AQ_MODE aq_mode;
67 unsigned int frame_periodic_boost;
Yaowu Xuf883b422016-08-30 14:01:10 -070068 aom_bit_depth_t bit_depth;
69 aom_tune_content content;
70 aom_color_space_t color_space;
Yaowu Xuc27fc142016-08-22 16:08:15 -070071 int color_range;
72 int render_width;
73 int render_height;
Yaowu Xuf883b422016-08-30 14:01:10 -070074 aom_superblock_size_t superblock_size;
Alex Converseeb780e72016-12-13 12:46:41 -080075#if CONFIG_ANS && ANS_MAX_SYMBOLS
76 int ans_window_size_log2;
77#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070078};
79
Yaowu Xuf883b422016-08-30 14:01:10 -070080static struct av1_extracfg default_extra_cfg = {
Yaowu Xuc27fc142016-08-22 16:08:15 -070081 0, // cpu_used
82 1, // enable_auto_alt_ref
83#if CONFIG_EXT_REFS
84 0, // enable_auto_bwd_ref
85#endif // CONFIG_EXT_REFS
86 0, // noise_sensitivity
87 0, // sharpness
88 0, // static_thresh
89#if CONFIG_EXT_TILE
90 UINT_MAX, // tile_columns
91 UINT_MAX, // tile_rows
92#else
93 0, // tile_columns
94 0, // tile_rows
Ryan Lei7386eda2016-12-08 21:08:31 -080095#endif // CONFIG_EXT_TILE
Fangwen Fu7b9f2b32017-01-17 14:01:52 -080096#if CONFIG_DEPENDENT_HORZTILES
97 0, // Depdendent Horizontal tiles
98#endif
Ryan Lei9b02b0e2017-01-30 15:52:20 -080099#if CONFIG_LOOPFILTERING_ACROSS_TILES
Ryan Leiad67d792017-02-02 17:53:19 -0800100 1, // loop_filter_across_tiles_enabled
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800101#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Yaowu Xuc27fc142016-08-22 16:08:15 -0700102 7, // arnr_max_frames
103 5, // arnr_strength
104 0, // min_gf_interval; 0 -> default decision
105 0, // max_gf_interval; 0 -> default decision
Yaowu Xuf883b422016-08-30 14:01:10 -0700106 AOM_TUNE_PSNR, // tuning
Yaowu Xuc27fc142016-08-22 16:08:15 -0700107 10, // cq_level
108 0, // rc_max_intra_bitrate_pct
109 0, // rc_max_inter_bitrate_pct
110 0, // gf_cbr_boost_pct
111 0, // lossless
112#if CONFIG_AOM_QM
113 0, // enable_qm
114 DEFAULT_QM_FIRST, // qm_min
115 DEFAULT_QM_LAST, // qm_max
116#endif
Thomas Daviesaf6df172016-11-09 14:04:18 +0000117#if CONFIG_TILE_GROUPS
118 1, // max number of tile groups
119 0, // mtu_size
120#endif
Fangwen Fu8d164de2016-12-14 13:40:54 -0800121#if CONFIG_TEMPMV_SIGNALING
122 0, // disable temporal mv prediction
123#endif
Alex Converseeb780e72016-12-13 12:46:41 -0800124 1, // frame_parallel_decoding_mode
125 NO_AQ, // aq_mode
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +0000126 CONFIG_XIPHRC, // frame_periodic_delta_q
Alex Converseeb780e72016-12-13 12:46:41 -0800127 AOM_BITS_8, // Bit depth
128 AOM_CONTENT_DEFAULT, // content
129 AOM_CS_UNKNOWN, // color space
130 0, // color range
131 0, // render width
132 0, // render height
133 AOM_SUPERBLOCK_SIZE_DYNAMIC, // superblock_size
134#if CONFIG_ANS && ANS_MAX_SYMBOLS
135 23, // ans_window_size_log2
136#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700137};
138
Yaowu Xuf883b422016-08-30 14:01:10 -0700139struct aom_codec_alg_priv {
140 aom_codec_priv_t base;
141 aom_codec_enc_cfg_t cfg;
142 struct av1_extracfg extra_cfg;
143 AV1EncoderConfig oxcf;
144 AV1_COMP *cpi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700145 unsigned char *cx_data;
146 size_t cx_data_sz;
147 unsigned char *pending_cx_data;
148 size_t pending_cx_data_sz;
149 int pending_frame_count;
150 size_t pending_frame_sizes[8];
Yaowu Xuf883b422016-08-30 14:01:10 -0700151 aom_image_t preview_img;
152 aom_enc_frame_flags_t next_frame_flags;
153 aom_postproc_cfg_t preview_ppcfg;
154 aom_codec_pkt_list_decl(256) pkt_list;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700155 unsigned int fixed_kf_cntr;
156 // BufferPool that holds all reference frames.
157 BufferPool *buffer_pool;
158};
159
Yaowu Xuf883b422016-08-30 14:01:10 -0700160static aom_codec_err_t update_error_state(
161 aom_codec_alg_priv_t *ctx, const struct aom_internal_error_info *error) {
162 const aom_codec_err_t res = error->error_code;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700163
Yaowu Xuf883b422016-08-30 14:01:10 -0700164 if (res != AOM_CODEC_OK)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700165 ctx->base.err_detail = error->has_detail ? error->detail : NULL;
166
167 return res;
168}
169
170#undef ERROR
171#define ERROR(str) \
172 do { \
173 ctx->base.err_detail = str; \
Yaowu Xuf883b422016-08-30 14:01:10 -0700174 return AOM_CODEC_INVALID_PARAM; \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700175 } while (0)
176
Urvang Joshicd8ab902016-10-28 12:32:06 -0700177#define RANGE_CHECK(p, memb, lo, hi) \
178 do { \
179 if (!((p)->memb >= (lo) && (p)->memb <= (hi))) \
180 ERROR(#memb " out of range [" #lo ".." #hi "]"); \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700181 } while (0)
182
183#define RANGE_CHECK_HI(p, memb, hi) \
184 do { \
185 if (!((p)->memb <= (hi))) ERROR(#memb " out of range [.." #hi "]"); \
186 } while (0)
187
188#define RANGE_CHECK_LO(p, memb, lo) \
189 do { \
190 if (!((p)->memb >= (lo))) ERROR(#memb " out of range [" #lo "..]"); \
191 } while (0)
192
193#define RANGE_CHECK_BOOL(p, memb) \
194 do { \
195 if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean"); \
196 } while (0)
197
Yaowu Xuf883b422016-08-30 14:01:10 -0700198static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
199 const aom_codec_enc_cfg_t *cfg,
200 const struct av1_extracfg *extra_cfg) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700201 RANGE_CHECK(cfg, g_w, 1, 65535); // 16 bits available
202 RANGE_CHECK(cfg, g_h, 1, 65535); // 16 bits available
203 RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000);
204 RANGE_CHECK(cfg, g_timebase.num, 1, cfg->g_timebase.den);
205 RANGE_CHECK_HI(cfg, g_profile, 3);
206
207 RANGE_CHECK_HI(cfg, rc_max_quantizer, 63);
208 RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer);
209 RANGE_CHECK_BOOL(extra_cfg, lossless);
210 RANGE_CHECK(extra_cfg, aq_mode, 0, AQ_MODE_COUNT - 1);
Urvang Joshicd8ab902016-10-28 12:32:06 -0700211 RANGE_CHECK_HI(extra_cfg, frame_periodic_boost, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700212 RANGE_CHECK_HI(cfg, g_threads, 64);
213 RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS);
Yaowu Xuf883b422016-08-30 14:01:10 -0700214 RANGE_CHECK(cfg, rc_end_usage, AOM_VBR, AOM_Q);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700215 RANGE_CHECK_HI(cfg, rc_undershoot_pct, 100);
216 RANGE_CHECK_HI(cfg, rc_overshoot_pct, 100);
217 RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
Yaowu Xuf883b422016-08-30 14:01:10 -0700218 RANGE_CHECK(cfg, kf_mode, AOM_KF_DISABLED, AOM_KF_AUTO);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700219 RANGE_CHECK_BOOL(cfg, rc_resize_allowed);
220 RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100);
221 RANGE_CHECK_HI(cfg, rc_resize_up_thresh, 100);
222 RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100);
Yaowu Xuf883b422016-08-30 14:01:10 -0700223 RANGE_CHECK(cfg, g_pass, AOM_RC_ONE_PASS, AOM_RC_LAST_PASS);
Urvang Joshicd8ab902016-10-28 12:32:06 -0700224 RANGE_CHECK_HI(extra_cfg, min_gf_interval, MAX_LAG_BUFFERS - 1);
225 RANGE_CHECK_HI(extra_cfg, max_gf_interval, MAX_LAG_BUFFERS - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700226 if (extra_cfg->max_gf_interval > 0) {
227 RANGE_CHECK(extra_cfg, max_gf_interval, 2, (MAX_LAG_BUFFERS - 1));
228 }
229 if (extra_cfg->min_gf_interval > 0 && extra_cfg->max_gf_interval > 0) {
230 RANGE_CHECK(extra_cfg, max_gf_interval, extra_cfg->min_gf_interval,
231 (MAX_LAG_BUFFERS - 1));
232 }
233
234 if (cfg->rc_resize_allowed == 1) {
Urvang Joshicd8ab902016-10-28 12:32:06 -0700235 RANGE_CHECK_HI(cfg, rc_scaled_width, cfg->g_w);
236 RANGE_CHECK_HI(cfg, rc_scaled_height, cfg->g_h);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700237 }
238
Yaowu Xuf883b422016-08-30 14:01:10 -0700239 // AV1 does not support a lower bound on the keyframe interval in
Yaowu Xuc27fc142016-08-22 16:08:15 -0700240 // automatic keyframe placement mode.
Yaowu Xuf883b422016-08-30 14:01:10 -0700241 if (cfg->kf_mode != AOM_KF_DISABLED && cfg->kf_min_dist != cfg->kf_max_dist &&
Yaowu Xuc27fc142016-08-22 16:08:15 -0700242 cfg->kf_min_dist > 0)
243 ERROR(
244 "kf_min_dist not supported in auto mode, use 0 "
245 "or kf_max_dist instead.");
246
Urvang Joshicd8ab902016-10-28 12:32:06 -0700247 RANGE_CHECK_HI(extra_cfg, enable_auto_alt_ref, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700248#if CONFIG_EXT_REFS
Urvang Joshicd8ab902016-10-28 12:32:06 -0700249 RANGE_CHECK_HI(extra_cfg, enable_auto_bwd_ref, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700250#endif // CONFIG_EXT_REFS
Alex Converse561d0af2017-03-23 12:58:04 -0700251 RANGE_CHECK(extra_cfg, cpu_used, 0, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700252 RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6);
Yaowu Xuf883b422016-08-30 14:01:10 -0700253 RANGE_CHECK(extra_cfg, superblock_size, AOM_SUPERBLOCK_SIZE_64X64,
254 AOM_SUPERBLOCK_SIZE_DYNAMIC);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700255#if CONFIG_EXT_TILE
256// TODO(any): Waring. If CONFIG_EXT_TILE is true, tile_columns really
257// means tile_width, and tile_rows really means tile_hight. The interface
258// should be sanitized.
259#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -0700260 if (extra_cfg->superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700261 if (extra_cfg->tile_columns != UINT_MAX)
262 RANGE_CHECK(extra_cfg, tile_columns, 1, 32);
263 if (extra_cfg->tile_rows != UINT_MAX)
264 RANGE_CHECK(extra_cfg, tile_rows, 1, 32);
265 } else
266#endif // CONFIG_EXT_PARTITION
267 {
268 if (extra_cfg->tile_columns != UINT_MAX)
269 RANGE_CHECK(extra_cfg, tile_columns, 1, 64);
270 if (extra_cfg->tile_rows != UINT_MAX)
271 RANGE_CHECK(extra_cfg, tile_rows, 1, 64);
272 }
273#else
Urvang Joshicd8ab902016-10-28 12:32:06 -0700274 RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
275 RANGE_CHECK_HI(extra_cfg, tile_rows, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700276#endif // CONFIG_EXT_TILE
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800277#if CONFIG_DEPENDENT_HORZTILES
278 RANGE_CHECK_HI(extra_cfg, dependent_horz_tiles, 1);
279#endif
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800280#if CONFIG_LOOPFILTERING_ACROSS_TILES
Ryan Lei7386eda2016-12-08 21:08:31 -0800281 RANGE_CHECK_HI(extra_cfg, loop_filter_across_tiles_enabled, 1);
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800282#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Yaowu Xuc27fc142016-08-22 16:08:15 -0700283 RANGE_CHECK_HI(extra_cfg, sharpness, 7);
Urvang Joshicd8ab902016-10-28 12:32:06 -0700284 RANGE_CHECK_HI(extra_cfg, arnr_max_frames, 15);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700285 RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);
Urvang Joshicd8ab902016-10-28 12:32:06 -0700286 RANGE_CHECK_HI(extra_cfg, cq_level, 63);
Yaowu Xuf883b422016-08-30 14:01:10 -0700287 RANGE_CHECK(cfg, g_bit_depth, AOM_BITS_8, AOM_BITS_12);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700288 RANGE_CHECK(cfg, g_input_bit_depth, 8, 12);
Yaowu Xuf883b422016-08-30 14:01:10 -0700289 RANGE_CHECK(extra_cfg, content, AOM_CONTENT_DEFAULT, AOM_CONTENT_INVALID - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700290
Yaowu Xuf883b422016-08-30 14:01:10 -0700291 // TODO(yaowu): remove this when ssim tuning is implemented for av1
292 if (extra_cfg->tuning == AOM_TUNE_SSIM)
293 ERROR("Option --tune=ssim is not currently supported in AV1.");
Yaowu Xuc27fc142016-08-22 16:08:15 -0700294
Yaowu Xuf883b422016-08-30 14:01:10 -0700295 if (cfg->g_pass == AOM_RC_LAST_PASS) {
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +0000296#if !CONFIG_XIPHRC
Yaowu Xuc27fc142016-08-22 16:08:15 -0700297 const size_t packet_sz = sizeof(FIRSTPASS_STATS);
298 const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
299 const FIRSTPASS_STATS *stats;
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +0000300#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700301
302 if (cfg->rc_twopass_stats_in.buf == NULL)
303 ERROR("rc_twopass_stats_in.buf not set.");
304
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +0000305#if !CONFIG_XIPHRC
Yaowu Xuc27fc142016-08-22 16:08:15 -0700306 if (cfg->rc_twopass_stats_in.sz % packet_sz)
307 ERROR("rc_twopass_stats_in.sz indicates truncated packet.");
308
309 if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)
310 ERROR("rc_twopass_stats_in requires at least two packets.");
311
312 stats =
313 (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1;
314
315 if ((int)(stats->count + 0.5) != n_packets - 1)
316 ERROR("rc_twopass_stats_in missing EOS stats packet");
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +0000317#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700318 }
319
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200320#if !CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700321 if (cfg->g_profile > (unsigned int)PROFILE_1) {
322 ERROR("Profile > 1 not supported in this build configuration");
323 }
324#endif
325 if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
Yaowu Xuf883b422016-08-30 14:01:10 -0700326 cfg->g_bit_depth > AOM_BITS_8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700327 ERROR("Codec high bit-depth not supported in profile < 2");
328 }
329 if (cfg->g_profile <= (unsigned int)PROFILE_1 && cfg->g_input_bit_depth > 8) {
330 ERROR("Source high bit-depth not supported in profile < 2");
331 }
332 if (cfg->g_profile > (unsigned int)PROFILE_1 &&
Yaowu Xuf883b422016-08-30 14:01:10 -0700333 cfg->g_bit_depth == AOM_BITS_8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700334 ERROR("Codec bit-depth 8 not supported in profile > 1");
335 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700336 RANGE_CHECK(extra_cfg, color_space, AOM_CS_UNKNOWN, AOM_CS_SRGB);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700337 RANGE_CHECK(extra_cfg, color_range, 0, 1);
Alex Converseeb780e72016-12-13 12:46:41 -0800338#if CONFIG_ANS && ANS_MAX_SYMBOLS
339 RANGE_CHECK(extra_cfg, ans_window_size_log2, 8, 23);
340#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700341 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700342}
343
Yaowu Xuf883b422016-08-30 14:01:10 -0700344static aom_codec_err_t validate_img(aom_codec_alg_priv_t *ctx,
345 const aom_image_t *img) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700346 switch (img->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700347 case AOM_IMG_FMT_YV12:
348 case AOM_IMG_FMT_I420:
349 case AOM_IMG_FMT_I42016: break;
350 case AOM_IMG_FMT_I422:
351 case AOM_IMG_FMT_I444:
352 case AOM_IMG_FMT_I440:
Yaowu Xuc27fc142016-08-22 16:08:15 -0700353 if (ctx->cfg.g_profile != (unsigned int)PROFILE_1) {
354 ERROR(
355 "Invalid image format. I422, I444, I440 images are "
356 "not supported in profile.");
357 }
358 break;
Yaowu Xuf883b422016-08-30 14:01:10 -0700359 case AOM_IMG_FMT_I42216:
360 case AOM_IMG_FMT_I44416:
361 case AOM_IMG_FMT_I44016:
Yaowu Xuc27fc142016-08-22 16:08:15 -0700362 if (ctx->cfg.g_profile != (unsigned int)PROFILE_1 &&
363 ctx->cfg.g_profile != (unsigned int)PROFILE_3) {
364 ERROR(
365 "Invalid image format. 16-bit I422, I444, I440 images are "
366 "not supported in profile.");
367 }
368 break;
369 default:
370 ERROR(
371 "Invalid image format. Only YV12, I420, I422, I444 images are "
372 "supported.");
373 break;
374 }
375
376 if (img->d_w != ctx->cfg.g_w || img->d_h != ctx->cfg.g_h)
377 ERROR("Image size must match encoder init configuration size");
378
Yaowu Xuf883b422016-08-30 14:01:10 -0700379 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700380}
381
Yaowu Xuf883b422016-08-30 14:01:10 -0700382static int get_image_bps(const aom_image_t *img) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700383 switch (img->fmt) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700384 case AOM_IMG_FMT_YV12:
385 case AOM_IMG_FMT_I420: return 12;
386 case AOM_IMG_FMT_I422: return 16;
387 case AOM_IMG_FMT_I444: return 24;
388 case AOM_IMG_FMT_I440: return 16;
389 case AOM_IMG_FMT_I42016: return 24;
390 case AOM_IMG_FMT_I42216: return 32;
391 case AOM_IMG_FMT_I44416: return 48;
392 case AOM_IMG_FMT_I44016: return 32;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700393 default: assert(0 && "Invalid image format"); break;
394 }
395 return 0;
396}
397
Yaowu Xuf883b422016-08-30 14:01:10 -0700398static aom_codec_err_t set_encoder_config(
399 AV1EncoderConfig *oxcf, const aom_codec_enc_cfg_t *cfg,
400 const struct av1_extracfg *extra_cfg) {
401 const int is_vbr = cfg->rc_end_usage == AOM_VBR;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700402 oxcf->profile = cfg->g_profile;
403 oxcf->max_threads = (int)cfg->g_threads;
404 oxcf->width = cfg->g_w;
405 oxcf->height = cfg->g_h;
406 oxcf->bit_depth = cfg->g_bit_depth;
407 oxcf->input_bit_depth = cfg->g_input_bit_depth;
408 // guess a frame rate if out of whack, use 30
409 oxcf->init_framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num;
410 if (oxcf->init_framerate > 180) oxcf->init_framerate = 30;
411
412 oxcf->mode = GOOD;
413
414 switch (cfg->g_pass) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700415 case AOM_RC_ONE_PASS: oxcf->pass = 0; break;
416 case AOM_RC_FIRST_PASS: oxcf->pass = 1; break;
417 case AOM_RC_LAST_PASS: oxcf->pass = 2; break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700418 }
419
420 oxcf->lag_in_frames =
Yaowu Xuf883b422016-08-30 14:01:10 -0700421 cfg->g_pass == AOM_RC_FIRST_PASS ? 0 : cfg->g_lag_in_frames;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700422 oxcf->rc_mode = cfg->rc_end_usage;
423
424 // Convert target bandwidth from Kbit/s to Bit/s
425 oxcf->target_bandwidth = 1000 * cfg->rc_target_bitrate;
426 oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct;
427 oxcf->rc_max_inter_bitrate_pct = extra_cfg->rc_max_inter_bitrate_pct;
428 oxcf->gf_cbr_boost_pct = extra_cfg->gf_cbr_boost_pct;
429
430 oxcf->best_allowed_q =
Yaowu Xuf883b422016-08-30 14:01:10 -0700431 extra_cfg->lossless ? 0 : av1_quantizer_to_qindex(cfg->rc_min_quantizer);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700432 oxcf->worst_allowed_q =
Yaowu Xuf883b422016-08-30 14:01:10 -0700433 extra_cfg->lossless ? 0 : av1_quantizer_to_qindex(cfg->rc_max_quantizer);
434 oxcf->cq_level = av1_quantizer_to_qindex(extra_cfg->cq_level);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700435 oxcf->fixed_q = -1;
436
437#if CONFIG_AOM_QM
438 oxcf->using_qm = extra_cfg->enable_qm;
439 oxcf->qm_minlevel = extra_cfg->qm_min;
440 oxcf->qm_maxlevel = extra_cfg->qm_max;
441#endif
442
Thomas Daviesaf6df172016-11-09 14:04:18 +0000443#if CONFIG_TILE_GROUPS
444 oxcf->num_tile_groups = extra_cfg->num_tg;
445 oxcf->mtu = extra_cfg->mtu_size;
446#endif
447
Fangwen Fu8d164de2016-12-14 13:40:54 -0800448#if CONFIG_TEMPMV_SIGNALING
449 oxcf->disable_tempmv = extra_cfg->disable_tempmv;
450#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700451 oxcf->under_shoot_pct = cfg->rc_undershoot_pct;
452 oxcf->over_shoot_pct = cfg->rc_overshoot_pct;
453
454 oxcf->scaled_frame_width = cfg->rc_scaled_width;
455 oxcf->scaled_frame_height = cfg->rc_scaled_height;
456 if (cfg->rc_resize_allowed == 1) {
457 oxcf->resize_mode =
458 (oxcf->scaled_frame_width == 0 || oxcf->scaled_frame_height == 0)
459 ? RESIZE_DYNAMIC
460 : RESIZE_FIXED;
461 } else {
462 oxcf->resize_mode = RESIZE_NONE;
463 }
464
465 oxcf->maximum_buffer_size_ms = is_vbr ? 240000 : cfg->rc_buf_sz;
466 oxcf->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz;
467 oxcf->optimal_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_optimal_sz;
468
469 oxcf->drop_frames_water_mark = cfg->rc_dropframe_thresh;
470
471 oxcf->two_pass_vbrbias = cfg->rc_2pass_vbr_bias_pct;
472 oxcf->two_pass_vbrmin_section = cfg->rc_2pass_vbr_minsection_pct;
473 oxcf->two_pass_vbrmax_section = cfg->rc_2pass_vbr_maxsection_pct;
474
475 oxcf->auto_key =
Yaowu Xuf883b422016-08-30 14:01:10 -0700476 cfg->kf_mode == AOM_KF_AUTO && cfg->kf_min_dist != cfg->kf_max_dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700477
478 oxcf->key_freq = cfg->kf_max_dist;
479
Alex Converse561d0af2017-03-23 12:58:04 -0700480 oxcf->speed = extra_cfg->cpu_used;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700481 oxcf->enable_auto_arf = extra_cfg->enable_auto_alt_ref;
482#if CONFIG_EXT_REFS
483 oxcf->enable_auto_brf = extra_cfg->enable_auto_bwd_ref;
484#endif // CONFIG_EXT_REFS
485 oxcf->noise_sensitivity = extra_cfg->noise_sensitivity;
486 oxcf->sharpness = extra_cfg->sharpness;
487
488 oxcf->two_pass_stats_in = cfg->rc_twopass_stats_in;
489
490#if CONFIG_FP_MB_STATS
491 oxcf->firstpass_mb_stats_in = cfg->rc_firstpass_mb_stats_in;
492#endif
493
494 oxcf->color_space = extra_cfg->color_space;
495 oxcf->color_range = extra_cfg->color_range;
496 oxcf->render_width = extra_cfg->render_width;
497 oxcf->render_height = extra_cfg->render_height;
498 oxcf->arnr_max_frames = extra_cfg->arnr_max_frames;
499 oxcf->arnr_strength = extra_cfg->arnr_strength;
500 oxcf->min_gf_interval = extra_cfg->min_gf_interval;
501 oxcf->max_gf_interval = extra_cfg->max_gf_interval;
502
503 oxcf->tuning = extra_cfg->tuning;
504 oxcf->content = extra_cfg->content;
505
506#if CONFIG_EXT_PARTITION
507 oxcf->superblock_size = extra_cfg->superblock_size;
508#endif // CONFIG_EXT_PARTITION
Alex Converseeb780e72016-12-13 12:46:41 -0800509#if CONFIG_ANS && ANS_MAX_SYMBOLS
510 oxcf->ans_window_size_log2 = extra_cfg->ans_window_size_log2;
511#endif // CONFIG_ANS && ANS_MAX_SYMBOLS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700512
513#if CONFIG_EXT_TILE
514 {
515#if CONFIG_EXT_PARTITION
516 const unsigned int max =
Yaowu Xuf883b422016-08-30 14:01:10 -0700517 extra_cfg->superblock_size == AOM_SUPERBLOCK_SIZE_64X64 ? 64 : 32;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700518#else
519 const unsigned int max = 64;
520#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -0700521 oxcf->tile_columns = AOMMIN(extra_cfg->tile_columns, max);
522 oxcf->tile_rows = AOMMIN(extra_cfg->tile_rows, max);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700523 }
524#else
525 oxcf->tile_columns = extra_cfg->tile_columns;
526 oxcf->tile_rows = extra_cfg->tile_rows;
527#endif // CONFIG_EXT_TILE
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800528#if CONFIG_DEPENDENT_HORZTILES
529 oxcf->dependent_horz_tiles = extra_cfg->dependent_horz_tiles;
530#endif
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800531#if CONFIG_LOOPFILTERING_ACROSS_TILES
Ryan Lei7386eda2016-12-08 21:08:31 -0800532 oxcf->loop_filter_across_tiles_enabled =
533 extra_cfg->loop_filter_across_tiles_enabled;
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800534#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Yaowu Xuc27fc142016-08-22 16:08:15 -0700535 oxcf->error_resilient_mode = cfg->g_error_resilient;
536 oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode;
537
538 oxcf->aq_mode = extra_cfg->aq_mode;
539
540 oxcf->frame_periodic_boost = extra_cfg->frame_periodic_boost;
541
542 /*
Yaowu Xuf883b422016-08-30 14:01:10 -0700543 printf("Current AV1 Settings: \n");
Yaowu Xuc27fc142016-08-22 16:08:15 -0700544 printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
545 printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity);
546 printf("sharpness: %d\n", oxcf->sharpness);
547 printf("cpu_used: %d\n", oxcf->cpu_used);
548 printf("Mode: %d\n", oxcf->mode);
549 printf("auto_key: %d\n", oxcf->auto_key);
550 printf("key_freq: %d\n", oxcf->key_freq);
551 printf("end_usage: %d\n", oxcf->end_usage);
552 printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct);
553 printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct);
554 printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level);
555 printf("optimal_buffer_level: %d\n", oxcf->optimal_buffer_level);
556 printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size);
557 printf("fixed_q: %d\n", oxcf->fixed_q);
558 printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q);
559 printf("best_allowed_q: %d\n", oxcf->best_allowed_q);
560 printf("allow_spatial_resampling: %d\n", oxcf->allow_spatial_resampling);
561 printf("scaled_frame_width: %d\n", oxcf->scaled_frame_width);
562 printf("scaled_frame_height: %d\n", oxcf->scaled_frame_height);
563 printf("two_pass_vbrbias: %d\n", oxcf->two_pass_vbrbias);
564 printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section);
565 printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section);
566 printf("lag_in_frames: %d\n", oxcf->lag_in_frames);
567 printf("enable_auto_arf: %d\n", oxcf->enable_auto_arf);
568 printf("Version: %d\n", oxcf->Version);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700569 printf("error resilient: %d\n", oxcf->error_resilient_mode);
570 printf("frame parallel detokenization: %d\n",
571 oxcf->frame_parallel_decoding_mode);
572 */
Yaowu Xuf883b422016-08-30 14:01:10 -0700573 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700574}
575
Yaowu Xuf883b422016-08-30 14:01:10 -0700576static aom_codec_err_t encoder_set_config(aom_codec_alg_priv_t *ctx,
577 const aom_codec_enc_cfg_t *cfg) {
578 aom_codec_err_t res;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700579 int force_key = 0;
580
581 if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700582 if (cfg->g_lag_in_frames > 1 || cfg->g_pass != AOM_RC_ONE_PASS)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700583 ERROR("Cannot change width or height after initialization");
584 if (!valid_ref_frame_size(ctx->cfg.g_w, ctx->cfg.g_h, cfg->g_w, cfg->g_h) ||
585 (ctx->cpi->initial_width && (int)cfg->g_w > ctx->cpi->initial_width) ||
586 (ctx->cpi->initial_height && (int)cfg->g_h > ctx->cpi->initial_height))
587 force_key = 1;
588 }
589
590 // Prevent increasing lag_in_frames. This check is stricter than it needs
591 // to be -- the limit is not increasing past the first lag_in_frames
592 // value, but we don't track the initial config, only the last successful
593 // config.
594 if (cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames)
595 ERROR("Cannot increase lag_in_frames");
596
597 res = validate_config(ctx, cfg, &ctx->extra_cfg);
598
Yaowu Xuf883b422016-08-30 14:01:10 -0700599 if (res == AOM_CODEC_OK) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700600 ctx->cfg = *cfg;
601 set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
602 // On profile change, request a key frame
603 force_key |= ctx->cpi->common.profile != ctx->oxcf.profile;
Yaowu Xuf883b422016-08-30 14:01:10 -0700604 av1_change_config(ctx->cpi, &ctx->oxcf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700605 }
606
Yaowu Xuf883b422016-08-30 14:01:10 -0700607 if (force_key) ctx->next_frame_flags |= AOM_EFLAG_FORCE_KF;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700608
609 return res;
610}
611
Yaowu Xuf883b422016-08-30 14:01:10 -0700612static aom_codec_err_t ctrl_get_quantizer(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700613 va_list args) {
614 int *const arg = va_arg(args, int *);
Yaowu Xuf883b422016-08-30 14:01:10 -0700615 if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
616 *arg = av1_get_quantizer(ctx->cpi);
617 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700618}
619
Yaowu Xuf883b422016-08-30 14:01:10 -0700620static aom_codec_err_t ctrl_get_quantizer64(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700621 va_list args) {
622 int *const arg = va_arg(args, int *);
Yaowu Xuf883b422016-08-30 14:01:10 -0700623 if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
624 *arg = av1_qindex_to_quantizer(av1_get_quantizer(ctx->cpi));
625 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700626}
627
Yaowu Xuf883b422016-08-30 14:01:10 -0700628static aom_codec_err_t update_extra_cfg(aom_codec_alg_priv_t *ctx,
629 const struct av1_extracfg *extra_cfg) {
630 const aom_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg);
631 if (res == AOM_CODEC_OK) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700632 ctx->extra_cfg = *extra_cfg;
633 set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
Yaowu Xuf883b422016-08-30 14:01:10 -0700634 av1_change_config(ctx->cpi, &ctx->oxcf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700635 }
636 return res;
637}
638
Yaowu Xuf883b422016-08-30 14:01:10 -0700639static aom_codec_err_t ctrl_set_cpuused(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700640 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700641 struct av1_extracfg extra_cfg = ctx->extra_cfg;
642 extra_cfg.cpu_used = CAST(AOME_SET_CPUUSED, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700643 return update_extra_cfg(ctx, &extra_cfg);
644}
645
Yaowu Xuf883b422016-08-30 14:01:10 -0700646static aom_codec_err_t ctrl_set_enable_auto_alt_ref(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700647 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700648 struct av1_extracfg extra_cfg = ctx->extra_cfg;
649 extra_cfg.enable_auto_alt_ref = CAST(AOME_SET_ENABLEAUTOALTREF, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700650 return update_extra_cfg(ctx, &extra_cfg);
651}
652
653#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -0700654static aom_codec_err_t ctrl_set_enable_auto_bwd_ref(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700655 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700656 struct av1_extracfg extra_cfg = ctx->extra_cfg;
657 extra_cfg.enable_auto_bwd_ref = CAST(AOME_SET_ENABLEAUTOBWDREF, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700658 return update_extra_cfg(ctx, &extra_cfg);
659}
660#endif // CONFIG_EXT_REFS
661
Yaowu Xuf883b422016-08-30 14:01:10 -0700662static aom_codec_err_t ctrl_set_noise_sensitivity(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700663 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700664 struct av1_extracfg extra_cfg = ctx->extra_cfg;
665 extra_cfg.noise_sensitivity = CAST(AV1E_SET_NOISE_SENSITIVITY, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700666 return update_extra_cfg(ctx, &extra_cfg);
667}
668
Yaowu Xuf883b422016-08-30 14:01:10 -0700669static aom_codec_err_t ctrl_set_sharpness(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700670 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700671 struct av1_extracfg extra_cfg = ctx->extra_cfg;
672 extra_cfg.sharpness = CAST(AOME_SET_SHARPNESS, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700673 return update_extra_cfg(ctx, &extra_cfg);
674}
675
Yaowu Xuf883b422016-08-30 14:01:10 -0700676static aom_codec_err_t ctrl_set_static_thresh(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700677 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700678 struct av1_extracfg extra_cfg = ctx->extra_cfg;
679 extra_cfg.static_thresh = CAST(AOME_SET_STATIC_THRESHOLD, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700680 return update_extra_cfg(ctx, &extra_cfg);
681}
682
Yaowu Xuf883b422016-08-30 14:01:10 -0700683static aom_codec_err_t ctrl_set_tile_columns(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700684 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700685 struct av1_extracfg extra_cfg = ctx->extra_cfg;
686 extra_cfg.tile_columns = CAST(AV1E_SET_TILE_COLUMNS, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700687 return update_extra_cfg(ctx, &extra_cfg);
688}
689
Yaowu Xuf883b422016-08-30 14:01:10 -0700690static aom_codec_err_t ctrl_set_tile_rows(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700691 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700692 struct av1_extracfg extra_cfg = ctx->extra_cfg;
693 extra_cfg.tile_rows = CAST(AV1E_SET_TILE_ROWS, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700694 return update_extra_cfg(ctx, &extra_cfg);
695}
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800696#if CONFIG_DEPENDENT_HORZTILES
697static aom_codec_err_t ctrl_set_tile_dependent_rows(aom_codec_alg_priv_t *ctx,
698 va_list args) {
699 struct av1_extracfg extra_cfg = ctx->extra_cfg;
700 extra_cfg.dependent_horz_tiles = CAST(AV1E_SET_TILE_DEPENDENT_ROWS, args);
701 return update_extra_cfg(ctx, &extra_cfg);
702}
703#endif
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800704#if CONFIG_LOOPFILTERING_ACROSS_TILES
Ryan Lei7386eda2016-12-08 21:08:31 -0800705static aom_codec_err_t ctrl_set_tile_loopfilter(aom_codec_alg_priv_t *ctx,
706 va_list args) {
707 struct av1_extracfg extra_cfg = ctx->extra_cfg;
708 extra_cfg.loop_filter_across_tiles_enabled =
709 CAST(AV1E_SET_TILE_LOOPFILTER, args);
710 return update_extra_cfg(ctx, &extra_cfg);
711}
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800712#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Ryan Lei7386eda2016-12-08 21:08:31 -0800713
Yaowu Xuf883b422016-08-30 14:01:10 -0700714static aom_codec_err_t ctrl_set_arnr_max_frames(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700715 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700716 struct av1_extracfg extra_cfg = ctx->extra_cfg;
717 extra_cfg.arnr_max_frames = CAST(AOME_SET_ARNR_MAXFRAMES, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700718 return update_extra_cfg(ctx, &extra_cfg);
719}
720
Yaowu Xuf883b422016-08-30 14:01:10 -0700721static aom_codec_err_t ctrl_set_arnr_strength(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700722 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700723 struct av1_extracfg extra_cfg = ctx->extra_cfg;
724 extra_cfg.arnr_strength = CAST(AOME_SET_ARNR_STRENGTH, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700725 return update_extra_cfg(ctx, &extra_cfg);
726}
727
Yaowu Xuf883b422016-08-30 14:01:10 -0700728static aom_codec_err_t ctrl_set_tuning(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700729 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700730 struct av1_extracfg extra_cfg = ctx->extra_cfg;
731 extra_cfg.tuning = CAST(AOME_SET_TUNING, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700732 return update_extra_cfg(ctx, &extra_cfg);
733}
734
Yaowu Xuf883b422016-08-30 14:01:10 -0700735static aom_codec_err_t ctrl_set_cq_level(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700736 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700737 struct av1_extracfg extra_cfg = ctx->extra_cfg;
738 extra_cfg.cq_level = CAST(AOME_SET_CQ_LEVEL, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700739 return update_extra_cfg(ctx, &extra_cfg);
740}
741
Yaowu Xuf883b422016-08-30 14:01:10 -0700742static aom_codec_err_t ctrl_set_rc_max_intra_bitrate_pct(
743 aom_codec_alg_priv_t *ctx, va_list args) {
744 struct av1_extracfg extra_cfg = ctx->extra_cfg;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700745 extra_cfg.rc_max_intra_bitrate_pct =
Yaowu Xuf883b422016-08-30 14:01:10 -0700746 CAST(AOME_SET_MAX_INTRA_BITRATE_PCT, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700747 return update_extra_cfg(ctx, &extra_cfg);
748}
749
Yaowu Xuf883b422016-08-30 14:01:10 -0700750static aom_codec_err_t ctrl_set_rc_max_inter_bitrate_pct(
751 aom_codec_alg_priv_t *ctx, va_list args) {
752 struct av1_extracfg extra_cfg = ctx->extra_cfg;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700753 extra_cfg.rc_max_inter_bitrate_pct =
Yaowu Xuf883b422016-08-30 14:01:10 -0700754 CAST(AOME_SET_MAX_INTER_BITRATE_PCT, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700755 return update_extra_cfg(ctx, &extra_cfg);
756}
757
Yaowu Xuf883b422016-08-30 14:01:10 -0700758static aom_codec_err_t ctrl_set_rc_gf_cbr_boost_pct(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700759 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700760 struct av1_extracfg extra_cfg = ctx->extra_cfg;
761 extra_cfg.gf_cbr_boost_pct = CAST(AV1E_SET_GF_CBR_BOOST_PCT, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700762 return update_extra_cfg(ctx, &extra_cfg);
763}
764
Yaowu Xuf883b422016-08-30 14:01:10 -0700765static aom_codec_err_t ctrl_set_lossless(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700766 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700767 struct av1_extracfg extra_cfg = ctx->extra_cfg;
768 extra_cfg.lossless = CAST(AV1E_SET_LOSSLESS, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700769 return update_extra_cfg(ctx, &extra_cfg);
770}
771
772#if CONFIG_AOM_QM
Yaowu Xuf883b422016-08-30 14:01:10 -0700773static aom_codec_err_t ctrl_set_enable_qm(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700774 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700775 struct av1_extracfg extra_cfg = ctx->extra_cfg;
776 extra_cfg.enable_qm = CAST(AV1E_SET_ENABLE_QM, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700777 return update_extra_cfg(ctx, &extra_cfg);
778}
779
Yaowu Xuf883b422016-08-30 14:01:10 -0700780static aom_codec_err_t ctrl_set_qm_min(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700781 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700782 struct av1_extracfg extra_cfg = ctx->extra_cfg;
783 extra_cfg.qm_min = CAST(AV1E_SET_QM_MIN, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700784 return update_extra_cfg(ctx, &extra_cfg);
785}
786
Yaowu Xuf883b422016-08-30 14:01:10 -0700787static aom_codec_err_t ctrl_set_qm_max(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700788 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700789 struct av1_extracfg extra_cfg = ctx->extra_cfg;
790 extra_cfg.qm_max = CAST(AV1E_SET_QM_MAX, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700791 return update_extra_cfg(ctx, &extra_cfg);
792}
793#endif
794
Thomas Daviesaf6df172016-11-09 14:04:18 +0000795#if CONFIG_TILE_GROUPS
796static aom_codec_err_t ctrl_set_num_tg(aom_codec_alg_priv_t *ctx,
797 va_list args) {
798 struct av1_extracfg extra_cfg = ctx->extra_cfg;
799 extra_cfg.num_tg = CAST(AV1E_SET_NUM_TG, args);
800 return update_extra_cfg(ctx, &extra_cfg);
801}
802
803static aom_codec_err_t ctrl_set_mtu(aom_codec_alg_priv_t *ctx, va_list args) {
804 struct av1_extracfg extra_cfg = ctx->extra_cfg;
805 extra_cfg.mtu_size = CAST(AV1E_SET_MTU, args);
806 return update_extra_cfg(ctx, &extra_cfg);
807}
808#endif
Fangwen Fu8d164de2016-12-14 13:40:54 -0800809#if CONFIG_TEMPMV_SIGNALING
810static aom_codec_err_t ctrl_set_disable_tempmv(aom_codec_alg_priv_t *ctx,
811 va_list args) {
812 struct av1_extracfg extra_cfg = ctx->extra_cfg;
813 extra_cfg.disable_tempmv = CAST(AV1E_SET_DISABLE_TEMPMV, args);
814 return update_extra_cfg(ctx, &extra_cfg);
815}
816#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700817static aom_codec_err_t ctrl_set_frame_parallel_decoding_mode(
818 aom_codec_alg_priv_t *ctx, va_list args) {
819 struct av1_extracfg extra_cfg = ctx->extra_cfg;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700820 extra_cfg.frame_parallel_decoding_mode =
Yaowu Xuf883b422016-08-30 14:01:10 -0700821 CAST(AV1E_SET_FRAME_PARALLEL_DECODING, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700822 return update_extra_cfg(ctx, &extra_cfg);
823}
824
Yaowu Xuf883b422016-08-30 14:01:10 -0700825static aom_codec_err_t ctrl_set_aq_mode(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700826 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700827 struct av1_extracfg extra_cfg = ctx->extra_cfg;
828 extra_cfg.aq_mode = CAST(AV1E_SET_AQ_MODE, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700829 return update_extra_cfg(ctx, &extra_cfg);
830}
831
Yaowu Xuf883b422016-08-30 14:01:10 -0700832static aom_codec_err_t ctrl_set_min_gf_interval(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700833 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700834 struct av1_extracfg extra_cfg = ctx->extra_cfg;
835 extra_cfg.min_gf_interval = CAST(AV1E_SET_MIN_GF_INTERVAL, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700836 return update_extra_cfg(ctx, &extra_cfg);
837}
838
Yaowu Xuf883b422016-08-30 14:01:10 -0700839static aom_codec_err_t ctrl_set_max_gf_interval(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700840 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700841 struct av1_extracfg extra_cfg = ctx->extra_cfg;
842 extra_cfg.max_gf_interval = CAST(AV1E_SET_MAX_GF_INTERVAL, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700843 return update_extra_cfg(ctx, &extra_cfg);
844}
845
Yaowu Xuf883b422016-08-30 14:01:10 -0700846static aom_codec_err_t ctrl_set_frame_periodic_boost(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700847 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700848 struct av1_extracfg extra_cfg = ctx->extra_cfg;
849 extra_cfg.frame_periodic_boost = CAST(AV1E_SET_FRAME_PERIODIC_BOOST, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700850 return update_extra_cfg(ctx, &extra_cfg);
851}
852
Yaowu Xuf883b422016-08-30 14:01:10 -0700853static aom_codec_err_t encoder_init(aom_codec_ctx_t *ctx,
854 aom_codec_priv_enc_mr_cfg_t *data) {
855 aom_codec_err_t res = AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700856 (void)data;
857
858 if (ctx->priv == NULL) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700859 aom_codec_alg_priv_t *const priv = aom_calloc(1, sizeof(*priv));
860 if (priv == NULL) return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700861
Yaowu Xuf883b422016-08-30 14:01:10 -0700862 ctx->priv = (aom_codec_priv_t *)priv;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700863 ctx->priv->init_flags = ctx->init_flags;
864 ctx->priv->enc.total_encoders = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -0700865 priv->buffer_pool = (BufferPool *)aom_calloc(1, sizeof(BufferPool));
866 if (priv->buffer_pool == NULL) return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700867
868#if CONFIG_MULTITHREAD
869 if (pthread_mutex_init(&priv->buffer_pool->pool_mutex, NULL)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700870 return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700871 }
872#endif
873
874 if (ctx->config.enc) {
875 // Update the reference to the config structure to an internal copy.
876 priv->cfg = *ctx->config.enc;
877 ctx->config.enc = &priv->cfg;
878 }
879
880 priv->extra_cfg = default_extra_cfg;
Yaowu Xuf883b422016-08-30 14:01:10 -0700881 once(av1_initialize_enc);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700882
883 res = validate_config(priv, &priv->cfg, &priv->extra_cfg);
884
Yaowu Xuf883b422016-08-30 14:01:10 -0700885 if (res == AOM_CODEC_OK) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700886 set_encoder_config(&priv->oxcf, &priv->cfg, &priv->extra_cfg);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200887#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700888 priv->oxcf.use_highbitdepth =
Yaowu Xuf883b422016-08-30 14:01:10 -0700889 (ctx->init_flags & AOM_CODEC_USE_HIGHBITDEPTH) ? 1 : 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700890#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700891 priv->cpi = av1_create_compressor(&priv->oxcf, priv->buffer_pool);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700892 if (priv->cpi == NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -0700893 res = AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700894 else
895 priv->cpi->output_pkt_list = &priv->pkt_list.head;
896 }
897 }
898
899 return res;
900}
901
Yaowu Xuf883b422016-08-30 14:01:10 -0700902static aom_codec_err_t encoder_destroy(aom_codec_alg_priv_t *ctx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700903 free(ctx->cx_data);
Yaowu Xuf883b422016-08-30 14:01:10 -0700904 av1_remove_compressor(ctx->cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700905#if CONFIG_MULTITHREAD
906 pthread_mutex_destroy(&ctx->buffer_pool->pool_mutex);
907#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700908 aom_free(ctx->buffer_pool);
909 aom_free(ctx);
910 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700911}
912
Yaowu Xuf883b422016-08-30 14:01:10 -0700913static void pick_quickcompress_mode(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700914 unsigned long deadline) {
Thomas Daede6eca8352017-03-17 14:14:12 -0700915 MODE new_mode = GOOD;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700916
917 switch (ctx->cfg.g_pass) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700918 case AOM_RC_ONE_PASS:
Thomas Daedeac0a3802016-03-01 14:29:47 -0800919 switch (deadline) {
Thomas Daedeac0a3802016-03-01 14:29:47 -0800920 case AOM_DL_REALTIME: new_mode = REALTIME; break;
921 default: new_mode = GOOD; break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700922 }
923 break;
Yaowu Xuf883b422016-08-30 14:01:10 -0700924 case AOM_RC_FIRST_PASS: break;
Thomas Daede6eca8352017-03-17 14:14:12 -0700925 case AOM_RC_LAST_PASS: new_mode = GOOD;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700926 }
927
928 if (ctx->oxcf.mode != new_mode) {
929 ctx->oxcf.mode = new_mode;
Yaowu Xuf883b422016-08-30 14:01:10 -0700930 av1_change_config(ctx->cpi, &ctx->oxcf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700931 }
932}
933
934// Turn on to test if supplemental superframe data breaks decoding
935// #define TEST_SUPPLEMENTAL_SUPERFRAME_DATA
Yaowu Xuf883b422016-08-30 14:01:10 -0700936static int write_superframe_index(aom_codec_alg_priv_t *ctx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700937 uint8_t marker = 0xc0;
938 unsigned int mask;
939 int mag, index_sz;
940 int i;
941 size_t max_frame_sz = 0;
942
943 assert(ctx->pending_frame_count);
944 assert(ctx->pending_frame_count <= 8);
945
946 // Add the number of frames to the marker byte
947 marker |= ctx->pending_frame_count - 1;
948 for (i = 0; i < ctx->pending_frame_count - 1; i++) {
949 const size_t frame_sz = (unsigned int)ctx->pending_frame_sizes[i] - 1;
950 max_frame_sz = frame_sz > max_frame_sz ? frame_sz : max_frame_sz;
951 }
952
953 // Choose the magnitude
954 for (mag = 0, mask = 0xff; mag < 4; mag++) {
955 if (max_frame_sz <= mask) break;
956 mask <<= 8;
957 mask |= 0xff;
958 }
959 marker |= mag << 3;
960
961 // Write the index
962 index_sz = 2 + (mag + 1) * (ctx->pending_frame_count - 1);
963 if (ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz) {
964 uint8_t *x = ctx->pending_cx_data + ctx->pending_cx_data_sz;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700965#ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA
966 uint8_t marker_test = 0xc0;
967 int mag_test = 2; // 1 - 4
968 int frames_test = 4; // 1 - 8
969 int index_sz_test = 2 + mag_test * frames_test;
970 marker_test |= frames_test - 1;
971 marker_test |= (mag_test - 1) << 3;
972 *x++ = marker_test;
973 for (i = 0; i < mag_test * frames_test; ++i)
974 *x++ = 0; // fill up with arbitrary data
975 *x++ = marker_test;
976 ctx->pending_cx_data_sz += index_sz_test;
977 printf("Added supplemental superframe data\n");
978#endif
979
980 *x++ = marker;
981 for (i = 0; i < ctx->pending_frame_count - 1; i++) {
982 unsigned int this_sz;
Urvang Joshi368fbc92016-10-17 16:31:34 -0700983 int j;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700984
985 assert(ctx->pending_frame_sizes[i] > 0);
986 this_sz = (unsigned int)ctx->pending_frame_sizes[i] - 1;
987 for (j = 0; j <= mag; j++) {
988 *x++ = this_sz & 0xff;
989 this_sz >>= 8;
990 }
991 }
992 *x++ = marker;
993 ctx->pending_cx_data_sz += index_sz;
994#ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA
995 index_sz += index_sz_test;
996#endif
997 }
998 return index_sz;
999}
1000
Yaowu Xuf883b422016-08-30 14:01:10 -07001001// av1 uses 10,000,000 ticks/second as time stamp
Yaowu Xuc27fc142016-08-22 16:08:15 -07001002#define TICKS_PER_SEC 10000000LL
1003
Yaowu Xuf883b422016-08-30 14:01:10 -07001004static int64_t timebase_units_to_ticks(const aom_rational_t *timebase,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001005 int64_t n) {
1006 return n * TICKS_PER_SEC * timebase->num / timebase->den;
1007}
1008
Yaowu Xuf883b422016-08-30 14:01:10 -07001009static int64_t ticks_to_timebase_units(const aom_rational_t *timebase,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001010 int64_t n) {
1011 const int64_t round = TICKS_PER_SEC * timebase->num / 2 - 1;
1012 return (n * timebase->den + round) / timebase->num / TICKS_PER_SEC;
1013}
1014
Yaowu Xuf883b422016-08-30 14:01:10 -07001015static aom_codec_frame_flags_t get_frame_pkt_flags(const AV1_COMP *cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001016 unsigned int lib_flags) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001017 aom_codec_frame_flags_t flags = lib_flags << 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001018
Yaowu Xuf883b422016-08-30 14:01:10 -07001019 if (lib_flags & FRAMEFLAGS_KEY) flags |= AOM_FRAME_IS_KEY;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001020
Yaowu Xuf883b422016-08-30 14:01:10 -07001021 if (cpi->droppable) flags |= AOM_FRAME_IS_DROPPABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001022
1023 return flags;
1024}
1025
Yaowu Xu416b0d92016-07-11 11:38:53 -07001026const size_t kMinCompressedSize = 8192;
Yaowu Xuf883b422016-08-30 14:01:10 -07001027static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
1028 const aom_image_t *img,
1029 aom_codec_pts_t pts,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001030 unsigned long duration,
Yaowu Xuf883b422016-08-30 14:01:10 -07001031 aom_enc_frame_flags_t enc_flags,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001032 unsigned long deadline) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001033 volatile aom_codec_err_t res = AOM_CODEC_OK;
1034 volatile aom_enc_frame_flags_t flags = enc_flags;
1035 AV1_COMP *const cpi = ctx->cpi;
1036 const aom_rational_t *const timebase = &ctx->cfg.g_timebase;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001037 size_t data_sz;
1038
Yaowu Xuf883b422016-08-30 14:01:10 -07001039 if (cpi == NULL) return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001040
1041 if (img != NULL) {
1042 res = validate_img(ctx, img);
1043 // TODO(jzern) the checks related to cpi's validity should be treated as a
1044 // failure condition, encoder setup is done fully in init() currently.
Yaowu Xuf883b422016-08-30 14:01:10 -07001045 if (res == AOM_CODEC_OK) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001046#if CONFIG_EXT_REFS
Yaowu Xuabc7d812016-07-12 11:57:51 -07001047 data_sz = ALIGN_POWER_OF_TWO(ctx->cfg.g_w, 5) *
1048 ALIGN_POWER_OF_TWO(ctx->cfg.g_h, 5) * get_image_bps(img);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001049#else
1050 // There's no codec control for multiple alt-refs so check the encoder
1051 // instance for its status to determine the compressed data size.
Yaowu Xuabc7d812016-07-12 11:57:51 -07001052 data_sz = ALIGN_POWER_OF_TWO(ctx->cfg.g_w, 5) *
1053 ALIGN_POWER_OF_TWO(ctx->cfg.g_h, 5) * get_image_bps(img) / 8 *
Yaowu Xuc27fc142016-08-22 16:08:15 -07001054 (cpi->multi_arf_allowed ? 8 : 2);
1055#endif // CONFIG_EXT_REFS
Yaowu Xu416b0d92016-07-11 11:38:53 -07001056 if (data_sz < kMinCompressedSize) data_sz = kMinCompressedSize;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001057 if (ctx->cx_data == NULL || ctx->cx_data_sz < data_sz) {
1058 ctx->cx_data_sz = data_sz;
1059 free(ctx->cx_data);
1060 ctx->cx_data = (unsigned char *)malloc(ctx->cx_data_sz);
1061 if (ctx->cx_data == NULL) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001062 return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001063 }
1064 }
1065 }
1066 }
1067
Thomas Daedeac0a3802016-03-01 14:29:47 -08001068 pick_quickcompress_mode(ctx, deadline);
Yaowu Xuf883b422016-08-30 14:01:10 -07001069 aom_codec_pkt_list_init(&ctx->pkt_list);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001070
1071 // Handle Flags
Yaowu Xuf883b422016-08-30 14:01:10 -07001072 if (((flags & AOM_EFLAG_NO_UPD_GF) && (flags & AOM_EFLAG_FORCE_GF)) ||
1073 ((flags & AOM_EFLAG_NO_UPD_ARF) && (flags & AOM_EFLAG_FORCE_ARF))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001074 ctx->base.err_detail = "Conflicting flags.";
Yaowu Xuf883b422016-08-30 14:01:10 -07001075 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001076 }
1077
1078 if (setjmp(cpi->common.error.jmp)) {
1079 cpi->common.error.setjmp = 0;
1080 res = update_error_state(ctx, &cpi->common.error);
Yaowu Xuf883b422016-08-30 14:01:10 -07001081 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07001082 return res;
1083 }
1084 cpi->common.error.setjmp = 1;
1085
Yaowu Xuf883b422016-08-30 14:01:10 -07001086 av1_apply_encoding_flags(cpi, flags);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001087
1088 // Handle fixed keyframe intervals
Yaowu Xuf883b422016-08-30 14:01:10 -07001089 if (ctx->cfg.kf_mode == AOM_KF_AUTO &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07001090 ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) {
1091 if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001092 flags |= AOM_EFLAG_FORCE_KF;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001093 ctx->fixed_kf_cntr = 1;
1094 }
1095 }
1096
Yaowu Xuf883b422016-08-30 14:01:10 -07001097 if (res == AOM_CODEC_OK) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001098 unsigned int lib_flags = 0;
1099 YV12_BUFFER_CONFIG sd;
1100 int64_t dst_time_stamp = timebase_units_to_ticks(timebase, pts);
1101 int64_t dst_end_time_stamp =
1102 timebase_units_to_ticks(timebase, pts + duration);
1103 size_t size, cx_data_sz;
1104 unsigned char *cx_data;
1105
1106 // Set up internal flags
Yaowu Xuf883b422016-08-30 14:01:10 -07001107 if (ctx->base.init_flags & AOM_CODEC_USE_PSNR) cpi->b_calculate_psnr = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001108
1109 if (img != NULL) {
1110 res = image2yuvconfig(img, &sd);
1111
1112 // Store the original flags in to the frame buffer. Will extract the
1113 // key frame flag when we actually encode this frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07001114 if (av1_receive_raw_frame(cpi, flags | ctx->next_frame_flags, &sd,
1115 dst_time_stamp, dst_end_time_stamp)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001116 res = update_error_state(ctx, &cpi->common.error);
1117 }
1118 ctx->next_frame_flags = 0;
1119 }
1120
1121 cx_data = ctx->cx_data;
1122 cx_data_sz = ctx->cx_data_sz;
1123
1124 /* Any pending invisible frames? */
1125 if (ctx->pending_cx_data) {
1126 memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz);
1127 ctx->pending_cx_data = cx_data;
1128 cx_data += ctx->pending_cx_data_sz;
1129 cx_data_sz -= ctx->pending_cx_data_sz;
1130
1131 /* TODO: this is a minimal check, the underlying codec doesn't respect
1132 * the buffer size anyway.
1133 */
1134 if (cx_data_sz < ctx->cx_data_sz / 2) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001135 aom_internal_error(&cpi->common.error, AOM_CODEC_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001136 "Compressed data buffer too small");
Yaowu Xuf883b422016-08-30 14:01:10 -07001137 return AOM_CODEC_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001138 }
1139 }
1140
1141 while (cx_data_sz >= ctx->cx_data_sz / 2 &&
Yaowu Xuf883b422016-08-30 14:01:10 -07001142 -1 != av1_get_compressed_data(cpi, &lib_flags, &size, cx_data,
1143 &dst_time_stamp, &dst_end_time_stamp,
1144 !img)) {
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01001145#if CONFIG_REFERENCE_BUFFER
1146 if (cpi->common.invalid_delta_frame_id_minus1) {
1147 ctx->base.err_detail = "Invalid delta_frame_id_minus1";
1148 return AOM_CODEC_ERROR;
1149 }
1150#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001151 if (size) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001152 aom_codec_cx_pkt_t pkt;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001153
1154 // Pack invisible frames with the next visible frame
1155 if (!cpi->common.show_frame) {
1156 if (ctx->pending_cx_data == 0) ctx->pending_cx_data = cx_data;
1157 ctx->pending_cx_data_sz += size;
1158 ctx->pending_frame_sizes[ctx->pending_frame_count++] = size;
1159 cx_data += size;
1160 cx_data_sz -= size;
1161
1162 continue;
1163 }
1164
1165 // Add the frame packet to the list of returned packets.
Yaowu Xuf883b422016-08-30 14:01:10 -07001166 pkt.kind = AOM_CODEC_CX_FRAME_PKT;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001167 pkt.data.frame.pts = ticks_to_timebase_units(timebase, dst_time_stamp);
1168 pkt.data.frame.duration = (unsigned long)ticks_to_timebase_units(
1169 timebase, dst_end_time_stamp - dst_time_stamp);
1170 pkt.data.frame.flags = get_frame_pkt_flags(cpi, lib_flags);
1171
1172 if (ctx->pending_cx_data) {
1173 ctx->pending_frame_sizes[ctx->pending_frame_count++] = size;
1174 ctx->pending_cx_data_sz += size;
1175 size += write_superframe_index(ctx);
1176 pkt.data.frame.buf = ctx->pending_cx_data;
1177 pkt.data.frame.sz = ctx->pending_cx_data_sz;
1178 ctx->pending_cx_data = NULL;
1179 ctx->pending_cx_data_sz = 0;
1180 ctx->pending_frame_count = 0;
1181 } else {
1182 pkt.data.frame.buf = cx_data;
1183 pkt.data.frame.sz = size;
1184 }
1185 pkt.data.frame.partition_id = -1;
1186
Yaowu Xuf883b422016-08-30 14:01:10 -07001187 aom_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001188
1189 cx_data += size;
1190 cx_data_sz -= size;
1191 }
1192 }
1193 }
1194
1195 cpi->common.error.setjmp = 0;
1196 return res;
1197}
1198
Yaowu Xuf883b422016-08-30 14:01:10 -07001199static const aom_codec_cx_pkt_t *encoder_get_cxdata(aom_codec_alg_priv_t *ctx,
1200 aom_codec_iter_t *iter) {
1201 return aom_codec_pkt_list_get(&ctx->pkt_list.head, iter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001202}
1203
Yaowu Xuf883b422016-08-30 14:01:10 -07001204static aom_codec_err_t ctrl_set_reference(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001205 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001206 aom_ref_frame_t *const frame = va_arg(args, aom_ref_frame_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001207
1208 if (frame != NULL) {
1209 YV12_BUFFER_CONFIG sd;
1210
1211 image2yuvconfig(&frame->img, &sd);
Yaowu Xuf883b422016-08-30 14:01:10 -07001212 av1_set_reference_enc(ctx->cpi, ref_frame_to_av1_reframe(frame->frame_type),
1213 &sd);
1214 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001215 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001216 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001217 }
1218}
1219
Yaowu Xuf883b422016-08-30 14:01:10 -07001220static aom_codec_err_t ctrl_copy_reference(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001221 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001222 aom_ref_frame_t *const frame = va_arg(args, aom_ref_frame_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001223
1224 if (frame != NULL) {
1225 YV12_BUFFER_CONFIG sd;
1226
1227 image2yuvconfig(&frame->img, &sd);
Yaowu Xuf883b422016-08-30 14:01:10 -07001228 av1_copy_reference_enc(ctx->cpi,
1229 ref_frame_to_av1_reframe(frame->frame_type), &sd);
1230 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001231 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001232 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001233 }
1234}
1235
Yaowu Xuf883b422016-08-30 14:01:10 -07001236static aom_codec_err_t ctrl_get_reference(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001237 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001238 av1_ref_frame_t *const frame = va_arg(args, av1_ref_frame_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001239
1240 if (frame != NULL) {
1241 YV12_BUFFER_CONFIG *fb = get_ref_frame(&ctx->cpi->common, frame->idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07001242 if (fb == NULL) return AOM_CODEC_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001243
1244 yuvconfig2image(&frame->img, fb, NULL);
Yaowu Xuf883b422016-08-30 14:01:10 -07001245 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001246 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001247 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001248 }
1249}
1250
Yaowu Xuf883b422016-08-30 14:01:10 -07001251static aom_codec_err_t ctrl_get_new_frame_image(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001252 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001253 aom_image_t *const new_img = va_arg(args, aom_image_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001254
1255 if (new_img != NULL) {
1256 YV12_BUFFER_CONFIG new_frame;
1257
Yaowu Xuf883b422016-08-30 14:01:10 -07001258 if (av1_get_last_show_frame(ctx->cpi, &new_frame) == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001259 yuvconfig2image(new_img, &new_frame, NULL);
Yaowu Xuf883b422016-08-30 14:01:10 -07001260 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001261 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001262 return AOM_CODEC_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001263 }
1264 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001265 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001266 }
1267}
1268
Yaowu Xuf883b422016-08-30 14:01:10 -07001269static aom_codec_err_t ctrl_set_previewpp(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001270 va_list args) {
1271 (void)ctx;
1272 (void)args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001273 return AOM_CODEC_INCAPABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001274}
1275
Yaowu Xuf883b422016-08-30 14:01:10 -07001276static aom_image_t *encoder_get_preview(aom_codec_alg_priv_t *ctx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001277 YV12_BUFFER_CONFIG sd;
1278
Yaowu Xuf883b422016-08-30 14:01:10 -07001279 if (av1_get_preview_raw_frame(ctx->cpi, &sd) == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001280 yuvconfig2image(&ctx->preview_img, &sd, NULL);
1281 return &ctx->preview_img;
1282 } else {
1283 return NULL;
1284 }
1285}
1286
Yaowu Xuf883b422016-08-30 14:01:10 -07001287static aom_codec_err_t ctrl_use_reference(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001288 va_list args) {
1289 const int reference_flag = va_arg(args, int);
1290
Yaowu Xuf883b422016-08-30 14:01:10 -07001291 av1_use_as_reference(ctx->cpi, reference_flag);
1292 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001293}
1294
Yaowu Xuf883b422016-08-30 14:01:10 -07001295static aom_codec_err_t ctrl_set_roi_map(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001296 va_list args) {
1297 (void)ctx;
1298 (void)args;
1299
Yaowu Xuf883b422016-08-30 14:01:10 -07001300 // TODO(yaowu): Need to re-implement and test for AV1.
1301 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001302}
1303
Yaowu Xuf883b422016-08-30 14:01:10 -07001304static aom_codec_err_t ctrl_set_active_map(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001305 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001306 aom_active_map_t *const map = va_arg(args, aom_active_map_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001307
1308 if (map) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001309 if (!av1_set_active_map(ctx->cpi, map->active_map, (int)map->rows,
1310 (int)map->cols))
1311 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001312 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001313 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001314 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001315 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001316 }
1317}
1318
Yaowu Xuf883b422016-08-30 14:01:10 -07001319static aom_codec_err_t ctrl_get_active_map(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001320 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001321 aom_active_map_t *const map = va_arg(args, aom_active_map_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001322
1323 if (map) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001324 if (!av1_get_active_map(ctx->cpi, map->active_map, (int)map->rows,
1325 (int)map->cols))
1326 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001327 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001328 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001329 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001330 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001331 }
1332}
1333
Yaowu Xuf883b422016-08-30 14:01:10 -07001334static aom_codec_err_t ctrl_set_scale_mode(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001335 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001336 aom_scaling_mode_t *const mode = va_arg(args, aom_scaling_mode_t *);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001337
1338 if (mode) {
1339 const int res =
Yaowu Xuf883b422016-08-30 14:01:10 -07001340 av1_set_internal_size(ctx->cpi, (AOM_SCALING)mode->h_scaling_mode,
1341 (AOM_SCALING)mode->v_scaling_mode);
1342 return (res == 0) ? AOM_CODEC_OK : AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001343 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001344 return AOM_CODEC_INVALID_PARAM;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001345 }
1346}
1347
Yaowu Xuf883b422016-08-30 14:01:10 -07001348static aom_codec_err_t ctrl_set_tune_content(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001349 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001350 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1351 extra_cfg.content = CAST(AV1E_SET_TUNE_CONTENT, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001352 return update_extra_cfg(ctx, &extra_cfg);
1353}
1354
Yaowu Xuf883b422016-08-30 14:01:10 -07001355static aom_codec_err_t ctrl_set_color_space(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001356 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001357 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1358 extra_cfg.color_space = CAST(AV1E_SET_COLOR_SPACE, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001359 return update_extra_cfg(ctx, &extra_cfg);
1360}
1361
Yaowu Xuf883b422016-08-30 14:01:10 -07001362static aom_codec_err_t ctrl_set_color_range(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001363 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001364 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1365 extra_cfg.color_range = CAST(AV1E_SET_COLOR_RANGE, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001366 return update_extra_cfg(ctx, &extra_cfg);
1367}
1368
Yaowu Xuf883b422016-08-30 14:01:10 -07001369static aom_codec_err_t ctrl_set_render_size(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001370 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001371 struct av1_extracfg extra_cfg = ctx->extra_cfg;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001372 int *const render_size = va_arg(args, int *);
1373 extra_cfg.render_width = render_size[0];
1374 extra_cfg.render_height = render_size[1];
1375 return update_extra_cfg(ctx, &extra_cfg);
1376}
1377
Yaowu Xuf883b422016-08-30 14:01:10 -07001378static aom_codec_err_t ctrl_set_superblock_size(aom_codec_alg_priv_t *ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001379 va_list args) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001380 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1381 extra_cfg.superblock_size = CAST(AV1E_SET_SUPERBLOCK_SIZE, args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001382 return update_extra_cfg(ctx, &extra_cfg);
1383}
1384
Alex Converseeb780e72016-12-13 12:46:41 -08001385#if CONFIG_ANS && ANS_MAX_SYMBOLS
1386static aom_codec_err_t ctrl_set_ans_window_size_log2(aom_codec_alg_priv_t *ctx,
1387 va_list args) {
1388 struct av1_extracfg extra_cfg = ctx->extra_cfg;
1389 extra_cfg.ans_window_size_log2 = CAST(AV1E_SET_ANS_WINDOW_SIZE_LOG2, args);
1390 return update_extra_cfg(ctx, &extra_cfg);
1391}
1392#endif
1393
Yaowu Xuf883b422016-08-30 14:01:10 -07001394static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
1395 { AOM_COPY_REFERENCE, ctrl_copy_reference },
1396 { AOME_USE_REFERENCE, ctrl_use_reference },
Yaowu Xuc27fc142016-08-22 16:08:15 -07001397
1398 // Setters
Yaowu Xuf883b422016-08-30 14:01:10 -07001399 { AOM_SET_REFERENCE, ctrl_set_reference },
1400 { AOM_SET_POSTPROC, ctrl_set_previewpp },
1401 { AOME_SET_ROI_MAP, ctrl_set_roi_map },
1402 { AOME_SET_ACTIVEMAP, ctrl_set_active_map },
1403 { AOME_SET_SCALEMODE, ctrl_set_scale_mode },
1404 { AOME_SET_CPUUSED, ctrl_set_cpuused },
1405 { AOME_SET_ENABLEAUTOALTREF, ctrl_set_enable_auto_alt_ref },
Yaowu Xuc27fc142016-08-22 16:08:15 -07001406#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07001407 { AOME_SET_ENABLEAUTOBWDREF, ctrl_set_enable_auto_bwd_ref },
Yaowu Xuc27fc142016-08-22 16:08:15 -07001408#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07001409 { AOME_SET_SHARPNESS, ctrl_set_sharpness },
1410 { AOME_SET_STATIC_THRESHOLD, ctrl_set_static_thresh },
1411 { AV1E_SET_TILE_COLUMNS, ctrl_set_tile_columns },
1412 { AV1E_SET_TILE_ROWS, ctrl_set_tile_rows },
Fangwen Fu7b9f2b32017-01-17 14:01:52 -08001413#if CONFIG_DEPENDENT_HORZTILES
1414 { AV1E_SET_TILE_DEPENDENT_ROWS, ctrl_set_tile_dependent_rows },
1415#endif
Ryan Lei9b02b0e2017-01-30 15:52:20 -08001416#if CONFIG_LOOPFILTERING_ACROSS_TILES
Ryan Lei7386eda2016-12-08 21:08:31 -08001417 { AV1E_SET_TILE_LOOPFILTER, ctrl_set_tile_loopfilter },
Ryan Lei9b02b0e2017-01-30 15:52:20 -08001418#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Yaowu Xuf883b422016-08-30 14:01:10 -07001419 { AOME_SET_ARNR_MAXFRAMES, ctrl_set_arnr_max_frames },
1420 { AOME_SET_ARNR_STRENGTH, ctrl_set_arnr_strength },
Yaowu Xuf883b422016-08-30 14:01:10 -07001421 { AOME_SET_TUNING, ctrl_set_tuning },
1422 { AOME_SET_CQ_LEVEL, ctrl_set_cq_level },
1423 { AOME_SET_MAX_INTRA_BITRATE_PCT, ctrl_set_rc_max_intra_bitrate_pct },
1424 { AV1E_SET_MAX_INTER_BITRATE_PCT, ctrl_set_rc_max_inter_bitrate_pct },
1425 { AV1E_SET_GF_CBR_BOOST_PCT, ctrl_set_rc_gf_cbr_boost_pct },
1426 { AV1E_SET_LOSSLESS, ctrl_set_lossless },
Yaowu Xuc27fc142016-08-22 16:08:15 -07001427#if CONFIG_AOM_QM
Yaowu Xuf883b422016-08-30 14:01:10 -07001428 { AV1E_SET_ENABLE_QM, ctrl_set_enable_qm },
1429 { AV1E_SET_QM_MIN, ctrl_set_qm_min },
1430 { AV1E_SET_QM_MAX, ctrl_set_qm_max },
Yaowu Xuc27fc142016-08-22 16:08:15 -07001431#endif
Thomas Daviesaf6df172016-11-09 14:04:18 +00001432#if CONFIG_TILE_GROUPS
1433 { AV1E_SET_NUM_TG, ctrl_set_num_tg },
1434 { AV1E_SET_MTU, ctrl_set_mtu },
1435#endif
Fangwen Fu8d164de2016-12-14 13:40:54 -08001436#if CONFIG_TEMPMV_SIGNALING
1437 { AV1E_SET_DISABLE_TEMPMV, ctrl_set_disable_tempmv },
1438#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001439 { AV1E_SET_FRAME_PARALLEL_DECODING, ctrl_set_frame_parallel_decoding_mode },
1440 { AV1E_SET_AQ_MODE, ctrl_set_aq_mode },
1441 { AV1E_SET_FRAME_PERIODIC_BOOST, ctrl_set_frame_periodic_boost },
1442 { AV1E_SET_TUNE_CONTENT, ctrl_set_tune_content },
1443 { AV1E_SET_COLOR_SPACE, ctrl_set_color_space },
1444 { AV1E_SET_COLOR_RANGE, ctrl_set_color_range },
1445 { AV1E_SET_NOISE_SENSITIVITY, ctrl_set_noise_sensitivity },
1446 { AV1E_SET_MIN_GF_INTERVAL, ctrl_set_min_gf_interval },
1447 { AV1E_SET_MAX_GF_INTERVAL, ctrl_set_max_gf_interval },
1448 { AV1E_SET_RENDER_SIZE, ctrl_set_render_size },
1449 { AV1E_SET_SUPERBLOCK_SIZE, ctrl_set_superblock_size },
Alex Converseeb780e72016-12-13 12:46:41 -08001450#if CONFIG_ANS && ANS_MAX_SYMBOLS
1451 { AV1E_SET_ANS_WINDOW_SIZE_LOG2, ctrl_set_ans_window_size_log2 },
1452#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001453
1454 // Getters
Yaowu Xuf883b422016-08-30 14:01:10 -07001455 { AOME_GET_LAST_QUANTIZER, ctrl_get_quantizer },
1456 { AOME_GET_LAST_QUANTIZER_64, ctrl_get_quantizer64 },
1457 { AV1_GET_REFERENCE, ctrl_get_reference },
1458 { AV1E_GET_ACTIVEMAP, ctrl_get_active_map },
1459 { AV1_GET_NEW_FRAME_IMAGE, ctrl_get_new_frame_image },
Yaowu Xuc27fc142016-08-22 16:08:15 -07001460
1461 { -1, NULL },
1462};
1463
Yaowu Xuf883b422016-08-30 14:01:10 -07001464static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001465 { 0,
1466 {
1467 // NOLINT
1468 0, // g_usage
1469 8, // g_threads
1470 0, // g_profile
1471
1472 320, // g_width
1473 240, // g_height
Yaowu Xuf883b422016-08-30 14:01:10 -07001474 AOM_BITS_8, // g_bit_depth
Yaowu Xuc27fc142016-08-22 16:08:15 -07001475 8, // g_input_bit_depth
1476
1477 { 1, 30 }, // g_timebase
1478
1479 0, // g_error_resilient
1480
Yaowu Xuf883b422016-08-30 14:01:10 -07001481 AOM_RC_ONE_PASS, // g_pass
Yaowu Xuc27fc142016-08-22 16:08:15 -07001482
1483 25, // g_lag_in_frames
1484
1485 0, // rc_dropframe_thresh
1486 0, // rc_resize_allowed
1487 0, // rc_scaled_width
1488 0, // rc_scaled_height
1489 60, // rc_resize_down_thresold
1490 30, // rc_resize_up_thresold
1491
Yaowu Xuf883b422016-08-30 14:01:10 -07001492 AOM_VBR, // rc_end_usage
Yaowu Xuc27fc142016-08-22 16:08:15 -07001493 { NULL, 0 }, // rc_twopass_stats_in
1494 { NULL, 0 }, // rc_firstpass_mb_stats_in
1495 256, // rc_target_bandwidth
1496 0, // rc_min_quantizer
1497 63, // rc_max_quantizer
1498 25, // rc_undershoot_pct
1499 25, // rc_overshoot_pct
1500
1501 6000, // rc_max_buffer_size
1502 4000, // rc_buffer_initial_size
1503 5000, // rc_buffer_optimal_size
1504
1505 50, // rc_two_pass_vbrbias
1506 0, // rc_two_pass_vbrmin_section
1507 2000, // rc_two_pass_vbrmax_section
1508
1509 // keyframing settings (kf)
Yaowu Xuf883b422016-08-30 14:01:10 -07001510 AOM_KF_AUTO, // g_kfmode
Yaowu Xuc27fc142016-08-22 16:08:15 -07001511 0, // kf_min_dist
1512 9999, // kf_max_dist
1513 } },
1514};
1515
1516#ifndef VERSION_STRING
1517#define VERSION_STRING
1518#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001519CODEC_INTERFACE(aom_codec_av1_cx) = {
1520 "AOMedia Project AV1 Encoder" VERSION_STRING,
1521 AOM_CODEC_INTERNAL_ABI_VERSION,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001522#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07001523 AOM_CODEC_CAP_HIGHBITDEPTH |
Yaowu Xuc27fc142016-08-22 16:08:15 -07001524#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001525 AOM_CODEC_CAP_ENCODER | AOM_CODEC_CAP_PSNR, // aom_codec_caps_t
1526 encoder_init, // aom_codec_init_fn_t
1527 encoder_destroy, // aom_codec_destroy_fn_t
1528 encoder_ctrl_maps, // aom_codec_ctrl_fn_map_t
Yaowu Xuc27fc142016-08-22 16:08:15 -07001529 {
1530 // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07001531 NULL, // aom_codec_peek_si_fn_t
1532 NULL, // aom_codec_get_si_fn_t
1533 NULL, // aom_codec_decode_fn_t
1534 NULL, // aom_codec_frame_get_fn_t
1535 NULL // aom_codec_set_fb_fn_t
Yaowu Xuc27fc142016-08-22 16:08:15 -07001536 },
1537 {
1538 // NOLINT
1539 1, // 1 cfg map
Yaowu Xuf883b422016-08-30 14:01:10 -07001540 encoder_usage_cfg_map, // aom_codec_enc_cfg_map_t
1541 encoder_encode, // aom_codec_encode_fn_t
1542 encoder_get_cxdata, // aom_codec_get_cx_data_fn_t
1543 encoder_set_config, // aom_codec_enc_config_set_fn_t
1544 NULL, // aom_codec_get_global_headers_fn_t
1545 encoder_get_preview, // aom_codec_get_preview_frame_fn_t
1546 NULL // aom_codec_enc_mr_get_mem_loc_fn_t
Yaowu Xuc27fc142016-08-22 16:08:15 -07001547 }
1548};