av1_cx_iface.c 57.5 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
4
5
6
7
8
9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Jingning Han's avatar
Jingning Han committed
10
11
12
13
14
 */

#include <stdlib.h>
#include <string.h>

Yaowu Xu's avatar
Yaowu Xu committed
15
16
17
#include "./aom_config.h"
#include "aom/aom_encoder.h"
#include "aom_ports/aom_once.h"
18
#include "aom_ports/system_state.h"
Yaowu Xu's avatar
Yaowu Xu committed
19
20
#include "aom/internal/aom_codec_internal.h"
#include "./aom_version.h"
21
#include "av1/encoder/encoder.h"
Yaowu Xu's avatar
Yaowu Xu committed
22
#include "aom/aomcx.h"
23
#include "av1/encoder/firstpass.h"
Yaowu Xu's avatar
Yaowu Xu committed
24
#include "av1/av1_iface_common.h"
Jingning Han's avatar
Jingning Han committed
25

Yaowu Xu's avatar
Yaowu Xu committed
26
struct av1_extracfg {
27
28
  int cpu_used;  // available cpu percentage in 1/16
  unsigned int enable_auto_alt_ref;
29
#if CONFIG_EXT_REFS
30
  unsigned int enable_auto_bwd_ref;
31
#endif  // CONFIG_EXT_REFS
32
33
34
35
36
  unsigned int noise_sensitivity;
  unsigned int sharpness;
  unsigned int static_thresh;
  unsigned int tile_columns;
  unsigned int tile_rows;
37
38
39
#if CONFIG_DEPENDENT_HORZTILES
  unsigned int dependent_horz_tiles;
#endif
40
#if CONFIG_LOOPFILTERING_ACROSS_TILES
41
  unsigned int loop_filter_across_tiles_enabled;
42
#endif  // CONFIG_LOOPFILTERING_ACROSS_TILES
43
44
45
46
  unsigned int arnr_max_frames;
  unsigned int arnr_strength;
  unsigned int min_gf_interval;
  unsigned int max_gf_interval;
Yaowu Xu's avatar
Yaowu Xu committed
47
  aom_tune_metric tuning;
48
49
50
51
52
  unsigned int cq_level;  // constrained quality level
  unsigned int rc_max_intra_bitrate_pct;
  unsigned int rc_max_inter_bitrate_pct;
  unsigned int gf_cbr_boost_pct;
  unsigned int lossless;
53
54
55
56
#if CONFIG_AOM_QM
  unsigned int enable_qm;
  unsigned int qm_min;
  unsigned int qm_max;
57
58
59
60
#endif
#if CONFIG_TILE_GROUPS
  unsigned int num_tg;
  unsigned int mtu_size;
61
62
63
#endif
#if CONFIG_TEMPMV_SIGNALING
  unsigned int disable_tempmv;
64
#endif
65
66
  unsigned int frame_parallel_decoding_mode;
  AQ_MODE aq_mode;
Fangwen Fu's avatar
Fangwen Fu committed
67
68
69
#if CONFIG_EXT_DELTA_Q
  DELTAQ_MODE deltaq_mode;
#endif
70
  unsigned int frame_periodic_boost;
Yaowu Xu's avatar
Yaowu Xu committed
71
72
73
  aom_bit_depth_t bit_depth;
  aom_tune_content content;
  aom_color_space_t color_space;
74
75
76
77
#if CONFIG_COLORSPACE_HEADERS
  aom_transfer_function_t transfer_function;
  aom_chroma_sample_position_t chroma_sample_position;
#endif
78
79
80
  int color_range;
  int render_width;
  int render_height;
Yaowu Xu's avatar
Yaowu Xu committed
81
  aom_superblock_size_t superblock_size;
82
83
84
#if CONFIG_ANS && ANS_MAX_SYMBOLS
  int ans_window_size_log2;
#endif
85
86
87
#if CONFIG_EXT_TILE
  unsigned int tile_encoding_mode;
#endif  // CONFIG_EXT_TILE
Yunqing Wang's avatar
Yunqing Wang committed
88
89

  unsigned int motion_vector_unit_test;
Jingning Han's avatar
Jingning Han committed
90
91
};

Yaowu Xu's avatar
Yaowu Xu committed
92
static struct av1_extracfg default_extra_cfg = {
93
94
  0,  // cpu_used
  1,  // enable_auto_alt_ref
95
#if CONFIG_EXT_REFS
96
  0,    // enable_auto_bwd_ref
97
#endif  // CONFIG_EXT_REFS
98
99
100
  0,    // noise_sensitivity
  0,    // sharpness
  0,    // static_thresh
101
#if CONFIG_EXT_TILE
102
103
  UINT_MAX,  // tile_columns
  UINT_MAX,  // tile_rows
104
#else
105
106
  0,  // tile_columns
  0,  // tile_rows
107
#endif  // CONFIG_EXT_TILE
108
#if CONFIG_DEPENDENT_HORZTILES
109
  0,  // Dependent Horizontal tiles
110
#endif
111
#if CONFIG_LOOPFILTERING_ACROSS_TILES
112
  1,              // loop_filter_across_tiles_enabled
113
#endif            // CONFIG_LOOPFILTERING_ACROSS_TILES
114
115
116
117
  7,              // arnr_max_frames
  5,              // arnr_strength
  0,              // min_gf_interval; 0 -> default decision
  0,              // max_gf_interval; 0 -> default decision
Yaowu Xu's avatar
Yaowu Xu committed
118
  AOM_TUNE_PSNR,  // tuning
119
120
121
122
123
124
125
126
127
  10,             // cq_level
  0,              // rc_max_intra_bitrate_pct
  0,              // rc_max_inter_bitrate_pct
  0,              // gf_cbr_boost_pct
  0,              // lossless
#if CONFIG_AOM_QM
  0,                 // enable_qm
  DEFAULT_QM_FIRST,  // qm_min
  DEFAULT_QM_LAST,   // qm_max
128
129
130
131
#endif
#if CONFIG_TILE_GROUPS
  1,  // max number of tile groups
  0,  // mtu_size
132
133
134
#endif
#if CONFIG_TEMPMV_SIGNALING
  0,  // disable temporal mv prediction
135
#endif
Fangwen Fu's avatar
Fangwen Fu committed
136
137
138
139
140
  1,      // frame_parallel_decoding_mode
  NO_AQ,  // aq_mode
#if CONFIG_EXT_DELTA_Q
  NO_DELTA_Q,  // deltaq_mode
#endif
141
142
143
144
145
146
147
148
  CONFIG_XIPHRC,        // frame_periodic_delta_q
  AOM_BITS_8,           // Bit depth
  AOM_CONTENT_DEFAULT,  // content
  AOM_CS_UNKNOWN,       // color space
#if CONFIG_COLORSPACE_HEADERS
  AOM_TF_UNKNOWN,   // transfer function
  AOM_CSP_UNKNOWN,  // chroma sample position
#endif
149
150
151
152
153
154
155
  0,                            // color range
  0,                            // render width
  0,                            // render height
  AOM_SUPERBLOCK_SIZE_DYNAMIC,  // superblock_size
#if CONFIG_ANS && ANS_MAX_SYMBOLS
  23,  // ans_window_size_log2
#endif
156
157
158
#if CONFIG_EXT_TILE
  0,    // Tile encoding mode is TILE_NORMAL by default.
#endif  // CONFIG_EXT_TILE
Yunqing Wang's avatar
Yunqing Wang committed
159
160

  0,  // motion_vector_unit_test
Jingning Han's avatar
Jingning Han committed
161
162
};

Yaowu Xu's avatar
Yaowu Xu committed
163
164
165
166
167
168
struct aom_codec_alg_priv {
  aom_codec_priv_t base;
  aom_codec_enc_cfg_t cfg;
  struct av1_extracfg extra_cfg;
  AV1EncoderConfig oxcf;
  AV1_COMP *cpi;
169
170
171
172
173
174
  unsigned char *cx_data;
  size_t cx_data_sz;
  unsigned char *pending_cx_data;
  size_t pending_cx_data_sz;
  int pending_frame_count;
  size_t pending_frame_sizes[8];
Yaowu Xu's avatar
Yaowu Xu committed
175
176
177
178
  aom_image_t preview_img;
  aom_enc_frame_flags_t next_frame_flags;
  aom_postproc_cfg_t preview_ppcfg;
  aom_codec_pkt_list_decl(256) pkt_list;
179
  unsigned int fixed_kf_cntr;
Jingning Han's avatar
Jingning Han committed
180
  // BufferPool that holds all reference frames.
181
  BufferPool *buffer_pool;
Jingning Han's avatar
Jingning Han committed
182
183
};

Yaowu Xu's avatar
Yaowu Xu committed
184
185
186
static aom_codec_err_t update_error_state(
    aom_codec_alg_priv_t *ctx, const struct aom_internal_error_info *error) {
  const aom_codec_err_t res = error->error_code;
Jingning Han's avatar
Jingning Han committed
187

Yaowu Xu's avatar
Yaowu Xu committed
188
  if (res != AOM_CODEC_OK)
Jingning Han's avatar
Jingning Han committed
189
190
191
192
193
194
    ctx->base.err_detail = error->has_detail ? error->detail : NULL;

  return res;
}

#undef ERROR
195
196
197
#define ERROR(str)                  \
  do {                              \
    ctx->base.err_detail = str;     \
Yaowu Xu's avatar
Yaowu Xu committed
198
    return AOM_CODEC_INVALID_PARAM; \
Jingning Han's avatar
Jingning Han committed
199
200
  } while (0)

201
202
203
204
#define RANGE_CHECK(p, memb, lo, hi)                   \
  do {                                                 \
    if (!((p)->memb >= (lo) && (p)->memb <= (hi)))     \
      ERROR(#memb " out of range [" #lo ".." #hi "]"); \
Jingning Han's avatar
Jingning Han committed
205
206
  } while (0)

207
208
209
#define RANGE_CHECK_HI(p, memb, hi)                                     \
  do {                                                                  \
    if (!((p)->memb <= (hi))) ERROR(#memb " out of range [.." #hi "]"); \
Jingning Han's avatar
Jingning Han committed
210
211
  } while (0)

212
213
214
#define RANGE_CHECK_LO(p, memb, lo)                                     \
  do {                                                                  \
    if (!((p)->memb >= (lo))) ERROR(#memb " out of range [" #lo "..]"); \
Jingning Han's avatar
Jingning Han committed
215
216
  } while (0)

217
218
219
#define RANGE_CHECK_BOOL(p, memb)                                     \
  do {                                                                \
    if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean"); \
Jingning Han's avatar
Jingning Han committed
220
221
  } while (0)

Yaowu Xu's avatar
Yaowu Xu committed
222
223
224
static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
                                       const aom_codec_enc_cfg_t *cfg,
                                       const struct av1_extracfg *extra_cfg) {
225
226
227
228
229
230
231
232
  RANGE_CHECK(cfg, g_w, 1, 65535);  // 16 bits available
  RANGE_CHECK(cfg, g_h, 1, 65535);  // 16 bits available
  RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000);
  RANGE_CHECK(cfg, g_timebase.num, 1, cfg->g_timebase.den);
  RANGE_CHECK_HI(cfg, g_profile, 3);

  RANGE_CHECK_HI(cfg, rc_max_quantizer, 63);
  RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer);
Jingning Han's avatar
Jingning Han committed
233
  RANGE_CHECK_BOOL(extra_cfg, lossless);
234
  RANGE_CHECK(extra_cfg, aq_mode, 0, AQ_MODE_COUNT - 1);
Fangwen Fu's avatar
Fangwen Fu committed
235
236
237
#if CONFIG_EXT_DELTA_Q
  RANGE_CHECK(extra_cfg, deltaq_mode, 0, DELTAQ_MODE_COUNT - 1);
#endif
238
  RANGE_CHECK_HI(extra_cfg, frame_periodic_boost, 1);
239
240
  RANGE_CHECK_HI(cfg, g_threads, 64);
  RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS);
Yaowu Xu's avatar
Yaowu Xu committed
241
  RANGE_CHECK(cfg, rc_end_usage, AOM_VBR, AOM_Q);
242
243
  RANGE_CHECK_HI(cfg, rc_undershoot_pct, 100);
  RANGE_CHECK_HI(cfg, rc_overshoot_pct, 100);
Jingning Han's avatar
Jingning Han committed
244
  RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
Yaowu Xu's avatar
Yaowu Xu committed
245
  RANGE_CHECK(cfg, kf_mode, AOM_KF_DISABLED, AOM_KF_AUTO);
246
247
248
  RANGE_CHECK_BOOL(cfg, rc_resize_allowed);
  RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100);
  RANGE_CHECK_HI(cfg, rc_resize_up_thresh, 100);
Jingning Han's avatar
Jingning Han committed
249
  RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100);
Yaowu Xu's avatar
Yaowu Xu committed
250
  RANGE_CHECK(cfg, g_pass, AOM_RC_ONE_PASS, AOM_RC_LAST_PASS);
251
252
  RANGE_CHECK_HI(extra_cfg, min_gf_interval, MAX_LAG_BUFFERS - 1);
  RANGE_CHECK_HI(extra_cfg, max_gf_interval, MAX_LAG_BUFFERS - 1);
Jingning Han's avatar
Jingning Han committed
253
254
255
256
257
  if (extra_cfg->max_gf_interval > 0) {
    RANGE_CHECK(extra_cfg, max_gf_interval, 2, (MAX_LAG_BUFFERS - 1));
  }
  if (extra_cfg->min_gf_interval > 0 && extra_cfg->max_gf_interval > 0) {
    RANGE_CHECK(extra_cfg, max_gf_interval, extra_cfg->min_gf_interval,
258
                (MAX_LAG_BUFFERS - 1));
Jingning Han's avatar
Jingning Han committed
259
260
261
  }

  if (cfg->rc_resize_allowed == 1) {
262
263
    RANGE_CHECK_HI(cfg, rc_scaled_width, cfg->g_w);
    RANGE_CHECK_HI(cfg, rc_scaled_height, cfg->g_h);
Jingning Han's avatar
Jingning Han committed
264
265
  }

Yaowu Xu's avatar
Yaowu Xu committed
266
  // AV1 does not support a lower bound on the keyframe interval in
Jingning Han's avatar
Jingning Han committed
267
  // automatic keyframe placement mode.
Yaowu Xu's avatar
Yaowu Xu committed
268
  if (cfg->kf_mode != AOM_KF_DISABLED && cfg->kf_min_dist != cfg->kf_max_dist &&
Jingning Han's avatar
Jingning Han committed
269
      cfg->kf_min_dist > 0)
270
271
272
    ERROR(
        "kf_min_dist not supported in auto mode, use 0 "
        "or kf_max_dist instead.");
Jingning Han's avatar
Jingning Han committed
273

Yunqing Wang's avatar
Yunqing Wang committed
274
  RANGE_CHECK_HI(extra_cfg, motion_vector_unit_test, 2);
275
  RANGE_CHECK_HI(extra_cfg, enable_auto_alt_ref, 2);
276
#if CONFIG_EXT_REFS
277
  RANGE_CHECK_HI(extra_cfg, enable_auto_bwd_ref, 2);
278
#endif  // CONFIG_EXT_REFS
279
  RANGE_CHECK(extra_cfg, cpu_used, 0, 8);
Jingning Han's avatar
Jingning Han committed
280
  RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6);
Yaowu Xu's avatar
Yaowu Xu committed
281
282
  RANGE_CHECK(extra_cfg, superblock_size, AOM_SUPERBLOCK_SIZE_64X64,
              AOM_SUPERBLOCK_SIZE_DYNAMIC);
283
#if CONFIG_EXT_TILE
284
285
286
// TODO(any): Waring. If CONFIG_EXT_TILE is true, tile_columns really
// means tile_width, and tile_rows really means tile_hight. The interface
// should be sanitized.
287
#if CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
288
  if (extra_cfg->superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
289
290
291
292
293
294
295
296
297
298
299
300
    if (extra_cfg->tile_columns != UINT_MAX)
      RANGE_CHECK(extra_cfg, tile_columns, 1, 32);
    if (extra_cfg->tile_rows != UINT_MAX)
      RANGE_CHECK(extra_cfg, tile_rows, 1, 32);
  } else
#endif  // CONFIG_EXT_PARTITION
  {
    if (extra_cfg->tile_columns != UINT_MAX)
      RANGE_CHECK(extra_cfg, tile_columns, 1, 64);
    if (extra_cfg->tile_rows != UINT_MAX)
      RANGE_CHECK(extra_cfg, tile_rows, 1, 64);
  }
301
  RANGE_CHECK_HI(extra_cfg, tile_encoding_mode, 1);
302
#else
303
304
  RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
  RANGE_CHECK_HI(extra_cfg, tile_rows, 2);
305
#endif  // CONFIG_EXT_TILE
306
307
308
#if CONFIG_DEPENDENT_HORZTILES
  RANGE_CHECK_HI(extra_cfg, dependent_horz_tiles, 1);
#endif
309
#if CONFIG_LOOPFILTERING_ACROSS_TILES
310
  RANGE_CHECK_HI(extra_cfg, loop_filter_across_tiles_enabled, 1);
311
#endif  // CONFIG_LOOPFILTERING_ACROSS_TILES
Jingning Han's avatar
Jingning Han committed
312
  RANGE_CHECK_HI(extra_cfg, sharpness, 7);
313
  RANGE_CHECK_HI(extra_cfg, arnr_max_frames, 15);
Jingning Han's avatar
Jingning Han committed
314
  RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);
315
  RANGE_CHECK_HI(extra_cfg, cq_level, 63);
Yaowu Xu's avatar
Yaowu Xu committed
316
  RANGE_CHECK(cfg, g_bit_depth, AOM_BITS_8, AOM_BITS_12);
Jingning Han's avatar
Jingning Han committed
317
  RANGE_CHECK(cfg, g_input_bit_depth, 8, 12);
Yaowu Xu's avatar
Yaowu Xu committed
318
  RANGE_CHECK(extra_cfg, content, AOM_CONTENT_DEFAULT, AOM_CONTENT_INVALID - 1);
Jingning Han's avatar
Jingning Han committed
319

Yaowu Xu's avatar
Yaowu Xu committed
320
321
322
  // TODO(yaowu): remove this when ssim tuning is implemented for av1
  if (extra_cfg->tuning == AOM_TUNE_SSIM)
    ERROR("Option --tune=ssim is not currently supported in AV1.");
Jingning Han's avatar
Jingning Han committed
323

Yaowu Xu's avatar
Yaowu Xu committed
324
  if (cfg->g_pass == AOM_RC_LAST_PASS) {
325
#if !CONFIG_XIPHRC
Jingning Han's avatar
Jingning Han committed
326
327
328
    const size_t packet_sz = sizeof(FIRSTPASS_STATS);
    const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
    const FIRSTPASS_STATS *stats;
329
#endif
Jingning Han's avatar
Jingning Han committed
330
331
332
333

    if (cfg->rc_twopass_stats_in.buf == NULL)
      ERROR("rc_twopass_stats_in.buf not set.");

334
#if !CONFIG_XIPHRC
Jingning Han's avatar
Jingning Han committed
335
336
337
    if (cfg->rc_twopass_stats_in.sz % packet_sz)
      ERROR("rc_twopass_stats_in.sz indicates truncated packet.");

Yunqing Wang's avatar
Yunqing Wang committed
338
339
    if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)
      ERROR("rc_twopass_stats_in requires at least two packets.");
Jingning Han's avatar
Jingning Han committed
340

Yunqing Wang's avatar
Yunqing Wang committed
341
342
    stats =
        (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1;
Jingning Han's avatar
Jingning Han committed
343

Yunqing Wang's avatar
Yunqing Wang committed
344
345
    if ((int)(stats->count + 0.5) != n_packets - 1)
      ERROR("rc_twopass_stats_in missing EOS stats packet");
346
#endif
Jingning Han's avatar
Jingning Han committed
347
348
  }

349
#if !CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
350
351
352
353
354
  if (cfg->g_profile > (unsigned int)PROFILE_1) {
    ERROR("Profile > 1 not supported in this build configuration");
  }
#endif
  if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
Yaowu Xu's avatar
Yaowu Xu committed
355
      cfg->g_bit_depth > AOM_BITS_8) {
Jingning Han's avatar
Jingning Han committed
356
357
    ERROR("Codec high bit-depth not supported in profile < 2");
  }
358
  if (cfg->g_profile <= (unsigned int)PROFILE_1 && cfg->g_input_bit_depth > 8) {
Jingning Han's avatar
Jingning Han committed
359
360
361
    ERROR("Source high bit-depth not supported in profile < 2");
  }
  if (cfg->g_profile > (unsigned int)PROFILE_1 &&
Yaowu Xu's avatar
Yaowu Xu committed
362
      cfg->g_bit_depth == AOM_BITS_8) {
Jingning Han's avatar
Jingning Han committed
363
364
    ERROR("Codec bit-depth 8 not supported in profile > 1");
  }
365
366
367
368
369
370
#if CONFIG_COLORSPACE_HEADERS
  RANGE_CHECK(extra_cfg, color_space, AOM_CS_UNKNOWN, AOM_CS_ICTCP);
  RANGE_CHECK(extra_cfg, transfer_function, AOM_TF_UNKNOWN, AOM_TF_HLG);
  RANGE_CHECK(extra_cfg, chroma_sample_position, AOM_CSP_UNKNOWN,
              AOM_CSP_COLOCATED);
#else
Yaowu Xu's avatar
Yaowu Xu committed
371
  RANGE_CHECK(extra_cfg, color_space, AOM_CS_UNKNOWN, AOM_CS_SRGB);
372
#endif
373
  RANGE_CHECK(extra_cfg, color_range, 0, 1);
374
375
376
#if CONFIG_ANS && ANS_MAX_SYMBOLS
  RANGE_CHECK(extra_cfg, ans_window_size_log2, 8, 23);
#endif
Yaowu Xu's avatar
Yaowu Xu committed
377
  return AOM_CODEC_OK;
Jingning Han's avatar
Jingning Han committed
378
379
}

Yaowu Xu's avatar
Yaowu Xu committed
380
381
static aom_codec_err_t validate_img(aom_codec_alg_priv_t *ctx,
                                    const aom_image_t *img) {
Jingning Han's avatar
Jingning Han committed
382
  switch (img->fmt) {
Yaowu Xu's avatar
Yaowu Xu committed
383
384
385
386
387
388
    case AOM_IMG_FMT_YV12:
    case AOM_IMG_FMT_I420:
    case AOM_IMG_FMT_I42016: break;
    case AOM_IMG_FMT_I422:
    case AOM_IMG_FMT_I444:
    case AOM_IMG_FMT_I440:
Jingning Han's avatar
Jingning Han committed
389
      if (ctx->cfg.g_profile != (unsigned int)PROFILE_1) {
390
391
392
        ERROR(
            "Invalid image format. I422, I444, I440 images are "
            "not supported in profile.");
Jingning Han's avatar
Jingning Han committed
393
394
      }
      break;
Yaowu Xu's avatar
Yaowu Xu committed
395
396
397
    case AOM_IMG_FMT_I42216:
    case AOM_IMG_FMT_I44416:
    case AOM_IMG_FMT_I44016:
Jingning Han's avatar
Jingning Han committed
398
399
      if (ctx->cfg.g_profile != (unsigned int)PROFILE_1 &&
          ctx->cfg.g_profile != (unsigned int)PROFILE_3) {
400
401
402
        ERROR(
            "Invalid image format. 16-bit I422, I444, I440 images are "
            "not supported in profile.");
Jingning Han's avatar
Jingning Han committed
403
404
405
      }
      break;
    default:
406
407
408
      ERROR(
          "Invalid image format. Only YV12, I420, I422, I444 images are "
          "supported.");
Jingning Han's avatar
Jingning Han committed
409
410
411
412
413
414
      break;
  }

  if (img->d_w != ctx->cfg.g_w || img->d_h != ctx->cfg.g_h)
    ERROR("Image size must match encoder init configuration size");

Yaowu Xu's avatar
Yaowu Xu committed
415
  return AOM_CODEC_OK;
Jingning Han's avatar
Jingning Han committed
416
417
}

Yaowu Xu's avatar
Yaowu Xu committed
418
static int get_image_bps(const aom_image_t *img) {
Jingning Han's avatar
Jingning Han committed
419
  switch (img->fmt) {
Yaowu Xu's avatar
Yaowu Xu committed
420
421
422
423
424
425
426
427
428
    case AOM_IMG_FMT_YV12:
    case AOM_IMG_FMT_I420: return 12;
    case AOM_IMG_FMT_I422: return 16;
    case AOM_IMG_FMT_I444: return 24;
    case AOM_IMG_FMT_I440: return 16;
    case AOM_IMG_FMT_I42016: return 24;
    case AOM_IMG_FMT_I42216: return 32;
    case AOM_IMG_FMT_I44416: return 48;
    case AOM_IMG_FMT_I44016: return 32;
Jingning Han's avatar
Jingning Han committed
429
430
431
432
433
    default: assert(0 && "Invalid image format"); break;
  }
  return 0;
}

Yaowu Xu's avatar
Yaowu Xu committed
434
435
436
437
static aom_codec_err_t set_encoder_config(
    AV1EncoderConfig *oxcf, const aom_codec_enc_cfg_t *cfg,
    const struct av1_extracfg *extra_cfg) {
  const int is_vbr = cfg->rc_end_usage == AOM_VBR;
Jingning Han's avatar
Jingning Han committed
438
439
  oxcf->profile = cfg->g_profile;
  oxcf->max_threads = (int)cfg->g_threads;
440
441
  oxcf->width = cfg->g_w;
  oxcf->height = cfg->g_h;
Jingning Han's avatar
Jingning Han committed
442
443
444
445
  oxcf->bit_depth = cfg->g_bit_depth;
  oxcf->input_bit_depth = cfg->g_input_bit_depth;
  // guess a frame rate if out of whack, use 30
  oxcf->init_framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num;
446
  if (oxcf->init_framerate > 180) oxcf->init_framerate = 30;
Jingning Han's avatar
Jingning Han committed
447
448
449
450

  oxcf->mode = GOOD;

  switch (cfg->g_pass) {
Yaowu Xu's avatar
Yaowu Xu committed
451
452
453
    case AOM_RC_ONE_PASS: oxcf->pass = 0; break;
    case AOM_RC_FIRST_PASS: oxcf->pass = 1; break;
    case AOM_RC_LAST_PASS: oxcf->pass = 2; break;
Jingning Han's avatar
Jingning Han committed
454
455
  }

456
  oxcf->lag_in_frames =
Yaowu Xu's avatar
Yaowu Xu committed
457
      cfg->g_pass == AOM_RC_FIRST_PASS ? 0 : cfg->g_lag_in_frames;
Jingning Han's avatar
Jingning Han committed
458
459
460
461
462
463
464
465
466
  oxcf->rc_mode = cfg->rc_end_usage;

  // Convert target bandwidth from Kbit/s to Bit/s
  oxcf->target_bandwidth = 1000 * cfg->rc_target_bitrate;
  oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct;
  oxcf->rc_max_inter_bitrate_pct = extra_cfg->rc_max_inter_bitrate_pct;
  oxcf->gf_cbr_boost_pct = extra_cfg->gf_cbr_boost_pct;

  oxcf->best_allowed_q =
Yaowu Xu's avatar
Yaowu Xu committed
467
      extra_cfg->lossless ? 0 : av1_quantizer_to_qindex(cfg->rc_min_quantizer);
Jingning Han's avatar
Jingning Han committed
468
  oxcf->worst_allowed_q =
Yaowu Xu's avatar
Yaowu Xu committed
469
470
      extra_cfg->lossless ? 0 : av1_quantizer_to_qindex(cfg->rc_max_quantizer);
  oxcf->cq_level = av1_quantizer_to_qindex(extra_cfg->cq_level);
Jingning Han's avatar
Jingning Han committed
471
472
  oxcf->fixed_q = -1;

473
474
475
476
477
478
#if CONFIG_AOM_QM
  oxcf->using_qm = extra_cfg->enable_qm;
  oxcf->qm_minlevel = extra_cfg->qm_min;
  oxcf->qm_maxlevel = extra_cfg->qm_max;
#endif

479
480
481
482
483
#if CONFIG_TILE_GROUPS
  oxcf->num_tile_groups = extra_cfg->num_tg;
  oxcf->mtu = extra_cfg->mtu_size;
#endif

484
485
486
#if CONFIG_TEMPMV_SIGNALING
  oxcf->disable_tempmv = extra_cfg->disable_tempmv;
#endif
487
488
  oxcf->under_shoot_pct = cfg->rc_undershoot_pct;
  oxcf->over_shoot_pct = cfg->rc_overshoot_pct;
Jingning Han's avatar
Jingning Han committed
489

490
  oxcf->scaled_frame_width = cfg->rc_scaled_width;
Jingning Han's avatar
Jingning Han committed
491
492
493
  oxcf->scaled_frame_height = cfg->rc_scaled_height;
  if (cfg->rc_resize_allowed == 1) {
    oxcf->resize_mode =
494
495
496
        (oxcf->scaled_frame_width == 0 || oxcf->scaled_frame_height == 0)
            ? RESIZE_DYNAMIC
            : RESIZE_FIXED;
Jingning Han's avatar
Jingning Han committed
497
498
499
500
  } else {
    oxcf->resize_mode = RESIZE_NONE;
  }

501
502
503
504
505
506
507
508
509
510
  // Initialize to input resolution if not specified.
  if (oxcf->resize_mode != RESIZE_FIXED) {
    oxcf->scaled_frame_width = oxcf->width;
    oxcf->scaled_frame_height = oxcf->height;
  }

#if CONFIG_FRAME_SUPERRES
  oxcf->superres_enabled = 1;  // TODO(afergs): Check the config
#endif                         // CONFIG_FRAME_SUPERRES

511
  oxcf->maximum_buffer_size_ms = is_vbr ? 240000 : cfg->rc_buf_sz;
Jingning Han's avatar
Jingning Han committed
512
  oxcf->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz;
513
  oxcf->optimal_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_optimal_sz;
Jingning Han's avatar
Jingning Han committed
514

515
  oxcf->drop_frames_water_mark = cfg->rc_dropframe_thresh;
Jingning Han's avatar
Jingning Han committed
516

517
518
519
  oxcf->two_pass_vbrbias = cfg->rc_2pass_vbr_bias_pct;
  oxcf->two_pass_vbrmin_section = cfg->rc_2pass_vbr_minsection_pct;
  oxcf->two_pass_vbrmax_section = cfg->rc_2pass_vbr_maxsection_pct;
Jingning Han's avatar
Jingning Han committed
520

521
  oxcf->auto_key =
Yaowu Xu's avatar
Yaowu Xu committed
522
      cfg->kf_mode == AOM_KF_AUTO && cfg->kf_min_dist != cfg->kf_max_dist;
Jingning Han's avatar
Jingning Han committed
523

524
  oxcf->key_freq = cfg->kf_max_dist;
Jingning Han's avatar
Jingning Han committed
525

526
  oxcf->speed = extra_cfg->cpu_used;
527
  oxcf->enable_auto_arf = extra_cfg->enable_auto_alt_ref;
528
#if CONFIG_EXT_REFS
529
  oxcf->enable_auto_brf = extra_cfg->enable_auto_bwd_ref;
530
#endif  // CONFIG_EXT_REFS
531
532
  oxcf->noise_sensitivity = extra_cfg->noise_sensitivity;
  oxcf->sharpness = extra_cfg->sharpness;
Jingning Han's avatar
Jingning Han committed
533

534
  oxcf->two_pass_stats_in = cfg->rc_twopass_stats_in;
Jingning Han's avatar
Jingning Han committed
535
536

#if CONFIG_FP_MB_STATS
537
  oxcf->firstpass_mb_stats_in = cfg->rc_firstpass_mb_stats_in;
Jingning Han's avatar
Jingning Han committed
538
539
540
#endif

  oxcf->color_space = extra_cfg->color_space;
541
542
543
544
#if CONFIG_COLORSPACE_HEADERS
  oxcf->transfer_function = extra_cfg->transfer_function;
  oxcf->chroma_sample_position = extra_cfg->chroma_sample_position;
#endif
545
  oxcf->color_range = extra_cfg->color_range;
546
  oxcf->render_width = extra_cfg->render_width;
547
  oxcf->render_height = extra_cfg->render_height;
Jingning Han's avatar
Jingning Han committed
548
  oxcf->arnr_max_frames = extra_cfg->arnr_max_frames;
549
  oxcf->arnr_strength = extra_cfg->arnr_strength;
Jingning Han's avatar
Jingning Han committed
550
551
552
553
554
555
  oxcf->min_gf_interval = extra_cfg->min_gf_interval;
  oxcf->max_gf_interval = extra_cfg->max_gf_interval;

  oxcf->tuning = extra_cfg->tuning;
  oxcf->content = extra_cfg->content;

556
557
558
#if CONFIG_EXT_PARTITION
  oxcf->superblock_size = extra_cfg->superblock_size;
#endif  // CONFIG_EXT_PARTITION
559
560
561
#if CONFIG_ANS && ANS_MAX_SYMBOLS
  oxcf->ans_window_size_log2 = extra_cfg->ans_window_size_log2;
#endif  // CONFIG_ANS && ANS_MAX_SYMBOLS
562
563
564
565
566

#if CONFIG_EXT_TILE
  {
#if CONFIG_EXT_PARTITION
    const unsigned int max =
Yaowu Xu's avatar
Yaowu Xu committed
567
        extra_cfg->superblock_size == AOM_SUPERBLOCK_SIZE_64X64 ? 64 : 32;
568
569
570
#else
    const unsigned int max = 64;
#endif  // CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
571
572
    oxcf->tile_columns = AOMMIN(extra_cfg->tile_columns, max);
    oxcf->tile_rows = AOMMIN(extra_cfg->tile_rows, max);
573
    oxcf->tile_encoding_mode = extra_cfg->tile_encoding_mode;
574
575
  }
#else
Jingning Han's avatar
Jingning Han committed
576
  oxcf->tile_columns = extra_cfg->tile_columns;
577
  oxcf->tile_rows = extra_cfg->tile_rows;
578
#endif  // CONFIG_EXT_TILE
579
580
581
#if CONFIG_DEPENDENT_HORZTILES
  oxcf->dependent_horz_tiles = extra_cfg->dependent_horz_tiles;
#endif
582
#if CONFIG_LOOPFILTERING_ACROSS_TILES
583
584
  oxcf->loop_filter_across_tiles_enabled =
      extra_cfg->loop_filter_across_tiles_enabled;
585
#endif  // CONFIG_LOOPFILTERING_ACROSS_TILES
586
  oxcf->error_resilient_mode = cfg->g_error_resilient;
Jingning Han's avatar
Jingning Han committed
587
588
589
  oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode;

  oxcf->aq_mode = extra_cfg->aq_mode;
Fangwen Fu's avatar
Fangwen Fu committed
590
591
592
#if CONFIG_EXT_DELTA_Q
  oxcf->deltaq_mode = extra_cfg->deltaq_mode;
#endif
Jingning Han's avatar
Jingning Han committed
593

594
  oxcf->frame_periodic_boost = extra_cfg->frame_periodic_boost;
Jingning Han's avatar
Jingning Han committed
595

Yunqing Wang's avatar
Yunqing Wang committed
596
  oxcf->motion_vector_unit_test = extra_cfg->motion_vector_unit_test;
Jingning Han's avatar
Jingning Han committed
597
  /*
Yaowu Xu's avatar
Yaowu Xu committed
598
  printf("Current AV1 Settings: \n");
Jingning Han's avatar
Jingning Han committed
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
  printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
  printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity);
  printf("sharpness: %d\n",    oxcf->sharpness);
  printf("cpu_used: %d\n",  oxcf->cpu_used);
  printf("Mode: %d\n",     oxcf->mode);
  printf("auto_key: %d\n",  oxcf->auto_key);
  printf("key_freq: %d\n", oxcf->key_freq);
  printf("end_usage: %d\n", oxcf->end_usage);
  printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct);
  printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct);
  printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level);
  printf("optimal_buffer_level: %d\n",  oxcf->optimal_buffer_level);
  printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size);
  printf("fixed_q: %d\n",  oxcf->fixed_q);
  printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q);
  printf("best_allowed_q: %d\n", oxcf->best_allowed_q);
  printf("allow_spatial_resampling: %d\n", oxcf->allow_spatial_resampling);
  printf("scaled_frame_width: %d\n", oxcf->scaled_frame_width);
  printf("scaled_frame_height: %d\n", oxcf->scaled_frame_height);
  printf("two_pass_vbrbias: %d\n",  oxcf->two_pass_vbrbias);
  printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section);
  printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section);
  printf("lag_in_frames: %d\n", oxcf->lag_in_frames);
  printf("enable_auto_arf: %d\n", oxcf->enable_auto_arf);
  printf("Version: %d\n", oxcf->Version);
  printf("error resilient: %d\n", oxcf->error_resilient_mode);
  printf("frame parallel detokenization: %d\n",
         oxcf->frame_parallel_decoding_mode);
  */
Yaowu Xu's avatar
Yaowu Xu committed
628
  return AOM_CODEC_OK;
Jingning Han's avatar
Jingning Han committed
629
630
}

Yaowu Xu's avatar
Yaowu Xu committed
631
632
633
static aom_codec_err_t encoder_set_config(aom_codec_alg_priv_t *ctx,
                                          const aom_codec_enc_cfg_t *cfg) {
  aom_codec_err_t res;
Jingning Han's avatar
Jingning Han committed
634
635
636
  int force_key = 0;

  if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h) {
Yaowu Xu's avatar
Yaowu Xu committed
637
    if (cfg->g_lag_in_frames > 1 || cfg->g_pass != AOM_RC_ONE_PASS)
Jingning Han's avatar
Jingning Han committed
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
      ERROR("Cannot change width or height after initialization");
    if (!valid_ref_frame_size(ctx->cfg.g_w, ctx->cfg.g_h, cfg->g_w, cfg->g_h) ||
        (ctx->cpi->initial_width && (int)cfg->g_w > ctx->cpi->initial_width) ||
        (ctx->cpi->initial_height && (int)cfg->g_h > ctx->cpi->initial_height))
      force_key = 1;
  }

  // Prevent increasing lag_in_frames. This check is stricter than it needs
  // to be -- the limit is not increasing past the first lag_in_frames
  // value, but we don't track the initial config, only the last successful
  // config.
  if (cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames)
    ERROR("Cannot increase lag_in_frames");

  res = validate_config(ctx, cfg, &ctx->extra_cfg);

Yaowu Xu's avatar
Yaowu Xu committed
654
  if (res == AOM_CODEC_OK) {
Jingning Han's avatar
Jingning Han committed
655
656
657
658
    ctx->cfg = *cfg;
    set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
    // On profile change, request a key frame
    force_key |= ctx->cpi->common.profile != ctx->oxcf.profile;
Yaowu Xu's avatar
Yaowu Xu committed
659
    av1_change_config(ctx->cpi, &ctx->oxcf);
Jingning Han's avatar
Jingning Han committed
660
661
  }

Yaowu Xu's avatar
Yaowu Xu committed
662
  if (force_key) ctx->next_frame_flags |= AOM_EFLAG_FORCE_KF;
Jingning Han's avatar
Jingning Han committed
663
664
665
666

  return res;
}

Yaowu Xu's avatar
Yaowu Xu committed
667
static aom_codec_err_t ctrl_get_quantizer(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
668
669
                                          va_list args) {
  int *const arg = va_arg(args, int *);
Yaowu Xu's avatar
Yaowu Xu committed
670
671
672
  if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
  *arg = av1_get_quantizer(ctx->cpi);
  return AOM_CODEC_OK;
Jingning Han's avatar
Jingning Han committed
673
674
}

Yaowu Xu's avatar
Yaowu Xu committed
675
static aom_codec_err_t ctrl_get_quantizer64(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
676
677
                                            va_list args) {
  int *const arg = va_arg(args, int *);
Yaowu Xu's avatar
Yaowu Xu committed
678
679
680
  if (arg == NULL) return AOM_CODEC_INVALID_PARAM;
  *arg = av1_qindex_to_quantizer(av1_get_quantizer(ctx->cpi));
  return AOM_CODEC_OK;
Jingning Han's avatar
Jingning Han committed
681
682
}

Yaowu Xu's avatar
Yaowu Xu committed
683
684
685
686
static aom_codec_err_t update_extra_cfg(aom_codec_alg_priv_t *ctx,
                                        const struct av1_extracfg *extra_cfg) {
  const aom_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg);
  if (res == AOM_CODEC_OK) {
Jingning Han's avatar
Jingning Han committed
687
688
    ctx->extra_cfg = *extra_cfg;
    set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
Yaowu Xu's avatar
Yaowu Xu committed
689
    av1_change_config(ctx->cpi, &ctx->oxcf);
Jingning Han's avatar
Jingning Han committed
690
691
692
693
  }
  return res;
}

Yaowu Xu's avatar
Yaowu Xu committed
694
static aom_codec_err_t ctrl_set_cpuused(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
695
                                        va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
696
697
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.cpu_used = CAST(AOME_SET_CPUUSED, args);
Jingning Han's avatar
Jingning Han committed
698
699
700
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
701
static aom_codec_err_t ctrl_set_enable_auto_alt_ref(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
702
                                                    va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
703
704
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.enable_auto_alt_ref = CAST(AOME_SET_ENABLEAUTOALTREF, args);
Jingning Han's avatar
Jingning Han committed
705
706
707
  return update_extra_cfg(ctx, &extra_cfg);
}

708
#if CONFIG_EXT_REFS
Yaowu Xu's avatar
Yaowu Xu committed
709
static aom_codec_err_t ctrl_set_enable_auto_bwd_ref(aom_codec_alg_priv_t *ctx,
710
                                                    va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
711
712
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.enable_auto_bwd_ref = CAST(AOME_SET_ENABLEAUTOBWDREF, args);
713
714
  return update_extra_cfg(ctx, &extra_cfg);
}
715
#endif  // CONFIG_EXT_REFS
716

Yaowu Xu's avatar
Yaowu Xu committed
717
static aom_codec_err_t ctrl_set_noise_sensitivity(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
718
                                                  va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
719
720
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.noise_sensitivity = CAST(AV1E_SET_NOISE_SENSITIVITY, args);
Jingning Han's avatar
Jingning Han committed
721
722
723
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
724
static aom_codec_err_t ctrl_set_sharpness(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
725
                                          va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
726
727
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.sharpness = CAST(AOME_SET_SHARPNESS, args);
Jingning Han's avatar
Jingning Han committed
728
729
730
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
731
static aom_codec_err_t ctrl_set_static_thresh(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
732
                                              va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
733
734
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.static_thresh = CAST(AOME_SET_STATIC_THRESHOLD, args);
Jingning Han's avatar
Jingning Han committed
735
736
737
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
738
static aom_codec_err_t ctrl_set_tile_columns(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
739
                                             va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
740
741
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.tile_columns = CAST(AV1E_SET_TILE_COLUMNS, args);
Jingning Han's avatar
Jingning Han committed
742
743
744
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
745
static aom_codec_err_t ctrl_set_tile_rows(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
746
                                          va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
747
748
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.tile_rows = CAST(AV1E_SET_TILE_ROWS, args);
Jingning Han's avatar
Jingning Han committed
749
750
  return update_extra_cfg(ctx, &extra_cfg);
}
751
752
753
754
755
756
757
758
#if CONFIG_DEPENDENT_HORZTILES
static aom_codec_err_t ctrl_set_tile_dependent_rows(aom_codec_alg_priv_t *ctx,
                                                    va_list args) {
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.dependent_horz_tiles = CAST(AV1E_SET_TILE_DEPENDENT_ROWS, args);
  return update_extra_cfg(ctx, &extra_cfg);
}
#endif
759
#if CONFIG_LOOPFILTERING_ACROSS_TILES
760
761
762
763
764
765
766
static aom_codec_err_t ctrl_set_tile_loopfilter(aom_codec_alg_priv_t *ctx,
                                                va_list args) {
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.loop_filter_across_tiles_enabled =
      CAST(AV1E_SET_TILE_LOOPFILTER, args);
  return update_extra_cfg(ctx, &extra_cfg);
}
767
#endif  // CONFIG_LOOPFILTERING_ACROSS_TILES
768

Yaowu Xu's avatar
Yaowu Xu committed
769
static aom_codec_err_t ctrl_set_arnr_max_frames(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
770
                                                va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
771
772
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.arnr_max_frames = CAST(AOME_SET_ARNR_MAXFRAMES, args);
Jingning Han's avatar
Jingning Han committed
773
774
775
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
776
static aom_codec_err_t ctrl_set_arnr_strength(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
777
                                              va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
778
779
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.arnr_strength = CAST(AOME_SET_ARNR_STRENGTH, args);
Jingning Han's avatar
Jingning Han committed
780
781
782
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
783
static aom_codec_err_t ctrl_set_tuning(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
784
                                       va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
785
786
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.tuning = CAST(AOME_SET_TUNING, args);
Jingning Han's avatar
Jingning Han committed
787
788
789
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
790
static aom_codec_err_t ctrl_set_cq_level(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
791
                                         va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
792
793
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.cq_level = CAST(AOME_SET_CQ_LEVEL, args);
Jingning Han's avatar
Jingning Han committed
794
795
796
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
797
798
799
static aom_codec_err_t ctrl_set_rc_max_intra_bitrate_pct(
    aom_codec_alg_priv_t *ctx, va_list args) {
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
Jingning Han's avatar
Jingning Han committed
800
  extra_cfg.rc_max_intra_bitrate_pct =
Yaowu Xu's avatar
Yaowu Xu committed
801
      CAST(AOME_SET_MAX_INTRA_BITRATE_PCT, args);
Jingning Han's avatar
Jingning Han committed
802
803
804
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
805
806
807
static aom_codec_err_t ctrl_set_rc_max_inter_bitrate_pct(
    aom_codec_alg_priv_t *ctx, va_list args) {
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
Jingning Han's avatar
Jingning Han committed
808
  extra_cfg.rc_max_inter_bitrate_pct =
Yaowu Xu's avatar
Yaowu Xu committed
809
      CAST(AOME_SET_MAX_INTER_BITRATE_PCT, args);
Jingning Han's avatar
Jingning Han committed
810
811
812
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
813
static aom_codec_err_t ctrl_set_rc_gf_cbr_boost_pct(aom_codec_alg_priv_t *ctx,
814
                                                    va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
815
816
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.gf_cbr_boost_pct = CAST(AV1E_SET_GF_CBR_BOOST_PCT, args);
Jingning Han's avatar
Jingning Han committed
817
818
819
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
820
static aom_codec_err_t ctrl_set_lossless(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
821
                                         va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
822
823
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.lossless = CAST(AV1E_SET_LOSSLESS, args);
Jingning Han's avatar
Jingning Han committed
824
825
826
  return update_extra_cfg(ctx, &extra_cfg);
}

827
#if CONFIG_AOM_QM
Yaowu Xu's avatar
Yaowu Xu committed
828
static aom_codec_err_t ctrl_set_enable_qm(aom_codec_alg_priv_t *ctx,
829
                                          va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
830
831
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.enable_qm = CAST(AV1E_SET_ENABLE_QM, args);
832
833
834
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
835
static aom_codec_err_t ctrl_set_qm_min(aom_codec_alg_priv_t *ctx,
836
                                       va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
837
838
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.qm_min = CAST(AV1E_SET_QM_MIN, args);
839
840
841
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
842
static aom_codec_err_t ctrl_set_qm_max(aom_codec_alg_priv_t *ctx,
843
                                       va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
844
845
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.qm_max = CAST(AV1E_SET_QM_MAX, args);
846
847
848
849
  return update_extra_cfg(ctx, &extra_cfg);
}
#endif

850
851
852
853
854
855
856
857
858
859
860
861
862
863
#if CONFIG_TILE_GROUPS
static aom_codec_err_t ctrl_set_num_tg(aom_codec_alg_priv_t *ctx,
                                       va_list args) {
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.num_tg = CAST(AV1E_SET_NUM_TG, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

static aom_codec_err_t ctrl_set_mtu(aom_codec_alg_priv_t *ctx, va_list args) {
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.mtu_size = CAST(AV1E_SET_MTU, args);
  return update_extra_cfg(ctx, &extra_cfg);
}
#endif
864
865
866
867
868
869
870
871
#if CONFIG_TEMPMV_SIGNALING
static aom_codec_err_t ctrl_set_disable_tempmv(aom_codec_alg_priv_t *ctx,
                                               va_list args) {
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.disable_tempmv = CAST(AV1E_SET_DISABLE_TEMPMV, args);
  return update_extra_cfg(ctx, &extra_cfg);
}
#endif
Yaowu Xu's avatar
Yaowu Xu committed
872
873
874
static aom_codec_err_t ctrl_set_frame_parallel_decoding_mode(
    aom_codec_alg_priv_t *ctx, va_list args) {
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
Jingning Han's avatar
Jingning Han committed
875
  extra_cfg.frame_parallel_decoding_mode =
Yaowu Xu's avatar
Yaowu Xu committed
876
      CAST(AV1E_SET_FRAME_PARALLEL_DECODING, args);
Jingning Han's avatar
Jingning Han committed
877
878
879
  return update_extra_cfg(ctx, &extra_cfg);
}

880
881
882
883
884
885
886
887
888
#if CONFIG_EXT_TILE
static aom_codec_err_t ctrl_set_tile_encoding_mode(aom_codec_alg_priv_t *ctx,
                                                   va_list args) {
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.tile_encoding_mode = CAST(AV1E_SET_TILE_ENCODING_MODE, args);
  return update_extra_cfg(ctx, &extra_cfg);
}
#endif  // CONFIG_EXT_TILE

Yaowu Xu's avatar
Yaowu Xu committed
889
static aom_codec_err_t ctrl_set_aq_mode(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
890
                                        va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
891
892
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.aq_mode = CAST(AV1E_SET_AQ_MODE, args);
Jingning Han's avatar
Jingning Han committed
893
894
895
  return update_extra_cfg(ctx, &extra_cfg);
}

Fangwen Fu's avatar
Fangwen Fu committed
896
897
898
899
900
901
902
903
#if CONFIG_EXT_DELTA_Q
static aom_codec_err_t ctrl_set_deltaq_mode(aom_codec_alg_priv_t *ctx,
                                            va_list args) {
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.deltaq_mode = CAST(AV1E_SET_DELTAQ_MODE, args);
  return update_extra_cfg(ctx, &extra_cfg);
}
#endif
Yaowu Xu's avatar
Yaowu Xu committed
904
static aom_codec_err_t ctrl_set_min_gf_interval(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
905
                                                va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
906
907
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.min_gf_interval = CAST(AV1E_SET_MIN_GF_INTERVAL, args);
Jingning Han's avatar
Jingning Han committed
908
909
910
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
911
static aom_codec_err_t ctrl_set_max_gf_interval(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
912
                                                va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
913
914
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.max_gf_interval = CAST(AV1E_SET_MAX_GF_INTERVAL, args);
Jingning Han's avatar
Jingning Han committed
915
916
917
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
918
static aom_codec_err_t ctrl_set_frame_periodic_boost(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
919
                                                     va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
920
921
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.frame_periodic_boost = CAST(AV1E_SET_FRAME_PERIODIC_BOOST, args);
Jingning Han's avatar
Jingning Han committed
922
923
924
  return update_extra_cfg(ctx, &extra_cfg);
}

Yunqing Wang's avatar
Yunqing Wang committed
925
926
927
928
929
930
931
932
static aom_codec_err_t ctrl_enable_motion_vector_unit_test(
    aom_codec_alg_priv_t *ctx, va_list args) {
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.motion_vector_unit_test =
      CAST(AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
933
934
935
static aom_codec_err_t encoder_init(aom_codec_ctx_t *ctx,
                                    aom_codec_priv_enc_mr_cfg_t *data) {
  aom_codec_err_t res = AOM_CODEC_OK;
Jingning Han's avatar
Jingning Han committed
936
937
938
  (void)data;

  if (ctx->priv == NULL) {
Yaowu Xu's avatar
Yaowu Xu committed
939
940
    aom_codec_alg_priv_t *const priv = aom_calloc(1, sizeof(*priv));
    if (priv == NULL) return AOM_CODEC_MEM_ERROR;
Jingning Han's avatar
Jingning Han committed
941

Yaowu Xu's avatar
Yaowu Xu committed
942
    ctx->priv = (aom_codec_priv_t *)priv;
Jingning Han's avatar
Jingning Han committed
943
944
    ctx->priv->init_flags = ctx->init_flags;
    ctx->priv->enc.total_encoders = 1;
Yaowu Xu's avatar
Yaowu Xu committed
945
946
    priv->buffer_pool = (BufferPool *)aom_calloc(1, sizeof(BufferPool));
    if (priv->buffer_pool == NULL) return AOM_CODEC_MEM_ERROR;
Jingning Han's avatar
Jingning Han committed
947
948
949

#if CONFIG_MULTITHREAD
    if (pthread_mutex_init(&priv->buffer_pool->pool_mutex, NULL)) {
Yaowu Xu's avatar
Yaowu Xu committed
950
      return AOM_CODEC_MEM_ERROR;
Jingning Han's avatar
Jingning Han committed
951
952
953
954
955
956
957
958
959
960
    }
#endif

    if (ctx->config.enc) {
      // Update the reference to the config structure to an internal copy.
      priv->cfg = *ctx->config.enc;
      ctx->config.enc = &priv->cfg;
    }

    priv->extra_cfg = default_extra_cfg;
Yaowu Xu's avatar
Yaowu Xu committed
961
    once(av1_initialize_enc);
Jingning Han's avatar
Jingning Han committed
962
963
964

    res = validate_config(priv, &priv->cfg, &priv->extra_cfg);

Yaowu Xu's avatar
Yaowu Xu committed
965
    if (res == AOM_CODEC_OK) {
Jingning Han's avatar
Jingning Han committed
966
      set_encoder_config(&priv->oxcf, &priv->cfg, &priv->extra_cfg);
967
#if CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
968
      priv->oxcf.use_highbitdepth =
Yaowu Xu's avatar
Yaowu Xu committed
969
          (ctx->init_flags & AOM_CODEC_USE_HIGHBITDEPTH) ? 1 : 0;
Jingning Han's avatar
Jingning Han committed
970
#endif
Yaowu Xu's avatar
Yaowu Xu committed
971
      priv->cpi = av1_create_compressor(&priv->oxcf, priv->buffer_pool);
Jingning Han's avatar
Jingning Han committed
972
      if (priv->cpi == NULL)
Yaowu Xu's avatar
Yaowu Xu committed
973
        res = AOM_CODEC_MEM_ERROR;
Jingning Han's avatar
Jingning Han committed
974
975
976
977
978
979
980
981
      else
        priv->cpi->output_pkt_list = &priv->pkt_list.head;
    }
  }

  return res;
}

Yaowu Xu's avatar
Yaowu Xu committed
982
static aom_codec_err_t encoder_destroy(aom_codec_alg_priv_t *ctx) {
Jingning Han's avatar
Jingning Han committed
983
  free(ctx->cx_data);
Yaowu Xu's avatar
Yaowu Xu committed
984
  av1_remove_compressor(ctx->cpi);
Jingning Han's avatar
Jingning Han committed
985
986
987
#if CONFIG_MULTITHREAD
  pthread_mutex_destroy(&ctx->buffer_pool->pool_mutex);
#endif
Yaowu Xu's avatar
Yaowu Xu committed
988
989
990
  aom_free(ctx->buffer_pool);
  aom_free(ctx);
  return AOM_CODEC_OK;
Jingning Han's avatar
Jingning Han committed
991
992
}

Yaowu Xu's avatar
Yaowu Xu committed
993
static void pick_quickcompress_mode(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
994
                                    unsigned long deadline) {
995
  MODE new_mode = GOOD;
Jingning Han's avatar
Jingning Han committed
996
997

  switch (ctx->cfg.g_pass) {
Yaowu Xu's avatar
Yaowu Xu committed
998
    case AOM_RC_ONE_PASS:
999
1000
      switch (deadline) {
        default: new_mode = GOOD; break;
For faster browsing, not all history is shown. View entire blame