av1_cx_iface.c 58 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
  }

266
267
268
269
270
271
#if CONFIG_FRAME_SUPERRES
  RANGE_CHECK_HI(cfg, rc_superres_mode, SUPERRES_DYNAMIC);
  RANGE_CHECK(cfg, rc_superres_numerator, SUPERRES_SCALE_DENOMINATOR / 2,
              SUPERRES_SCALE_DENOMINATOR);
#endif  // CONFIG_FRAME_SUPERRES

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

Yunqing Wang's avatar
Yunqing Wang committed
280
  RANGE_CHECK_HI(extra_cfg, motion_vector_unit_test, 2);
281
  RANGE_CHECK_HI(extra_cfg, enable_auto_alt_ref, 2);
282
#if CONFIG_EXT_REFS
283
  RANGE_CHECK_HI(extra_cfg, enable_auto_bwd_ref, 2);
284
#endif  // CONFIG_EXT_REFS
285
  RANGE_CHECK(extra_cfg, cpu_used, 0, 8);
Jingning Han's avatar
Jingning Han committed
286
  RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6);
Yaowu Xu's avatar
Yaowu Xu committed
287
288
  RANGE_CHECK(extra_cfg, superblock_size, AOM_SUPERBLOCK_SIZE_64X64,
              AOM_SUPERBLOCK_SIZE_DYNAMIC);
289
#if CONFIG_EXT_TILE
290
291
292
// 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.
293
#if CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
294
  if (extra_cfg->superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
295
296
297
298
299
300
301
302
303
304
305
306
    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);
  }
307
  RANGE_CHECK_HI(extra_cfg, tile_encoding_mode, 1);
308
#else
309
310
  RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
  RANGE_CHECK_HI(extra_cfg, tile_rows, 2);
311
#endif  // CONFIG_EXT_TILE
312
313
314
#if CONFIG_DEPENDENT_HORZTILES
  RANGE_CHECK_HI(extra_cfg, dependent_horz_tiles, 1);
#endif
315
#if CONFIG_LOOPFILTERING_ACROSS_TILES
316
  RANGE_CHECK_HI(extra_cfg, loop_filter_across_tiles_enabled, 1);
317
#endif  // CONFIG_LOOPFILTERING_ACROSS_TILES
Jingning Han's avatar
Jingning Han committed
318
  RANGE_CHECK_HI(extra_cfg, sharpness, 7);
319
  RANGE_CHECK_HI(extra_cfg, arnr_max_frames, 15);
Jingning Han's avatar
Jingning Han committed
320
  RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);
321
  RANGE_CHECK_HI(extra_cfg, cq_level, 63);
Yaowu Xu's avatar
Yaowu Xu committed
322
  RANGE_CHECK(cfg, g_bit_depth, AOM_BITS_8, AOM_BITS_12);
Jingning Han's avatar
Jingning Han committed
323
  RANGE_CHECK(cfg, g_input_bit_depth, 8, 12);
Yaowu Xu's avatar
Yaowu Xu committed
324
  RANGE_CHECK(extra_cfg, content, AOM_CONTENT_DEFAULT, AOM_CONTENT_INVALID - 1);
Jingning Han's avatar
Jingning Han committed
325

Yaowu Xu's avatar
Yaowu Xu committed
326
327
328
  // 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
329

Yaowu Xu's avatar
Yaowu Xu committed
330
  if (cfg->g_pass == AOM_RC_LAST_PASS) {
331
#if !CONFIG_XIPHRC
Jingning Han's avatar
Jingning Han committed
332
333
334
    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;
335
#endif
Jingning Han's avatar
Jingning Han committed
336
337
338
339

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

340
#if !CONFIG_XIPHRC
Jingning Han's avatar
Jingning Han committed
341
342
343
    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
344
345
    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
346

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

Yunqing Wang's avatar
Yunqing Wang committed
350
351
    if ((int)(stats->count + 0.5) != n_packets - 1)
      ERROR("rc_twopass_stats_in missing EOS stats packet");
352
#endif
Jingning Han's avatar
Jingning Han committed
353
354
  }

355
#if !CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
356
357
358
359
360
  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
361
      cfg->g_bit_depth > AOM_BITS_8) {
Jingning Han's avatar
Jingning Han committed
362
363
    ERROR("Codec high bit-depth not supported in profile < 2");
  }
364
  if (cfg->g_profile <= (unsigned int)PROFILE_1 && cfg->g_input_bit_depth > 8) {
Jingning Han's avatar
Jingning Han committed
365
366
367
    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
368
      cfg->g_bit_depth == AOM_BITS_8) {
Jingning Han's avatar
Jingning Han committed
369
370
    ERROR("Codec bit-depth 8 not supported in profile > 1");
  }
371
372
373
374
375
376
#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
377
  RANGE_CHECK(extra_cfg, color_space, AOM_CS_UNKNOWN, AOM_CS_SRGB);
378
#endif
379
  RANGE_CHECK(extra_cfg, color_range, 0, 1);
380
381
382
#if CONFIG_ANS && ANS_MAX_SYMBOLS
  RANGE_CHECK(extra_cfg, ans_window_size_log2, 8, 23);
#endif
Yaowu Xu's avatar
Yaowu Xu committed
383
  return AOM_CODEC_OK;
Jingning Han's avatar
Jingning Han committed
384
385
}

Yaowu Xu's avatar
Yaowu Xu committed
386
387
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
388
  switch (img->fmt) {
Yaowu Xu's avatar
Yaowu Xu committed
389
390
391
392
393
394
    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
395
      if (ctx->cfg.g_profile != (unsigned int)PROFILE_1) {
396
397
398
        ERROR(
            "Invalid image format. I422, I444, I440 images are "
            "not supported in profile.");
Jingning Han's avatar
Jingning Han committed
399
400
      }
      break;
Yaowu Xu's avatar
Yaowu Xu committed
401
402
403
    case AOM_IMG_FMT_I42216:
    case AOM_IMG_FMT_I44416:
    case AOM_IMG_FMT_I44016:
Jingning Han's avatar
Jingning Han committed
404
405
      if (ctx->cfg.g_profile != (unsigned int)PROFILE_1 &&
          ctx->cfg.g_profile != (unsigned int)PROFILE_3) {
406
407
408
        ERROR(
            "Invalid image format. 16-bit I422, I444, I440 images are "
            "not supported in profile.");
Jingning Han's avatar
Jingning Han committed
409
410
411
      }
      break;
    default:
412
413
414
      ERROR(
          "Invalid image format. Only YV12, I420, I422, I444 images are "
          "supported.");
Jingning Han's avatar
Jingning Han committed
415
416
417
418
419
420
      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
421
  return AOM_CODEC_OK;
Jingning Han's avatar
Jingning Han committed
422
423
}

Yaowu Xu's avatar
Yaowu Xu committed
424
static int get_image_bps(const aom_image_t *img) {
Jingning Han's avatar
Jingning Han committed
425
  switch (img->fmt) {
Yaowu Xu's avatar
Yaowu Xu committed
426
427
428
429
430
431
432
433
434
    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
435
436
437
438
439
    default: assert(0 && "Invalid image format"); break;
  }
  return 0;
}

Yaowu Xu's avatar
Yaowu Xu committed
440
441
442
443
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
444
445
  oxcf->profile = cfg->g_profile;
  oxcf->max_threads = (int)cfg->g_threads;
446
447
  oxcf->width = cfg->g_w;
  oxcf->height = cfg->g_h;
Jingning Han's avatar
Jingning Han committed
448
449
450
451
  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;
452
  if (oxcf->init_framerate > 180) oxcf->init_framerate = 30;
Jingning Han's avatar
Jingning Han committed
453
454
455
456

  oxcf->mode = GOOD;

  switch (cfg->g_pass) {
Yaowu Xu's avatar
Yaowu Xu committed
457
458
459
    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
460
461
  }

462
  oxcf->lag_in_frames =
Yaowu Xu's avatar
Yaowu Xu committed
463
      cfg->g_pass == AOM_RC_FIRST_PASS ? 0 : cfg->g_lag_in_frames;
Jingning Han's avatar
Jingning Han committed
464
465
466
467
468
469
470
471
472
  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
473
      extra_cfg->lossless ? 0 : av1_quantizer_to_qindex(cfg->rc_min_quantizer);
Jingning Han's avatar
Jingning Han committed
474
  oxcf->worst_allowed_q =
Yaowu Xu's avatar
Yaowu Xu committed
475
476
      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
477
478
  oxcf->fixed_q = -1;

479
480
481
482
483
484
#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

485
486
487
488
489
#if CONFIG_TILE_GROUPS
  oxcf->num_tile_groups = extra_cfg->num_tg;
  oxcf->mtu = extra_cfg->mtu_size;
#endif

490
491
492
#if CONFIG_TEMPMV_SIGNALING
  oxcf->disable_tempmv = extra_cfg->disable_tempmv;
#endif
493
494
  oxcf->under_shoot_pct = cfg->rc_undershoot_pct;
  oxcf->over_shoot_pct = cfg->rc_overshoot_pct;
Jingning Han's avatar
Jingning Han committed
495

496
  oxcf->scaled_frame_width = cfg->rc_scaled_width;
Jingning Han's avatar
Jingning Han committed
497
498
499
  oxcf->scaled_frame_height = cfg->rc_scaled_height;
  if (cfg->rc_resize_allowed == 1) {
    oxcf->resize_mode =
500
501
502
        (oxcf->scaled_frame_width == 0 || oxcf->scaled_frame_height == 0)
            ? RESIZE_DYNAMIC
            : RESIZE_FIXED;
Jingning Han's avatar
Jingning Han committed
503
504
505
506
  } else {
    oxcf->resize_mode = RESIZE_NONE;
  }

507
508
509
510
511
512
513
  // 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
514
515
516
517
518
519
  oxcf->superres_mode = (SUPERRES_MODE)cfg->rc_superres_mode;
  oxcf->superres_scale_numerator = (uint8_t)cfg->rc_superres_numerator;
  if (oxcf->superres_mode == SUPERRES_FIXED &&
      oxcf->superres_scale_numerator == SUPERRES_SCALE_DENOMINATOR)
    oxcf->superres_mode = SUPERRES_NONE;
#endif  // CONFIG_FRAME_SUPERRES
520

521
  oxcf->maximum_buffer_size_ms = is_vbr ? 240000 : cfg->rc_buf_sz;
Jingning Han's avatar
Jingning Han committed
522
  oxcf->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz;
523
  oxcf->optimal_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_optimal_sz;
Jingning Han's avatar
Jingning Han committed
524

525
  oxcf->drop_frames_water_mark = cfg->rc_dropframe_thresh;
Jingning Han's avatar
Jingning Han committed
526

527
528
529
  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
530

531
  oxcf->auto_key =
Yaowu Xu's avatar
Yaowu Xu committed
532
      cfg->kf_mode == AOM_KF_AUTO && cfg->kf_min_dist != cfg->kf_max_dist;
Jingning Han's avatar
Jingning Han committed
533

534
  oxcf->key_freq = cfg->kf_max_dist;
Jingning Han's avatar
Jingning Han committed
535

536
  oxcf->speed = extra_cfg->cpu_used;
537
  oxcf->enable_auto_arf = extra_cfg->enable_auto_alt_ref;
538
#if CONFIG_EXT_REFS
539
  oxcf->enable_auto_brf = extra_cfg->enable_auto_bwd_ref;
540
#endif  // CONFIG_EXT_REFS
541
542
  oxcf->noise_sensitivity = extra_cfg->noise_sensitivity;
  oxcf->sharpness = extra_cfg->sharpness;
Jingning Han's avatar
Jingning Han committed
543

544
  oxcf->two_pass_stats_in = cfg->rc_twopass_stats_in;
Jingning Han's avatar
Jingning Han committed
545
546

#if CONFIG_FP_MB_STATS
547
  oxcf->firstpass_mb_stats_in = cfg->rc_firstpass_mb_stats_in;
Jingning Han's avatar
Jingning Han committed
548
549
550
#endif

  oxcf->color_space = extra_cfg->color_space;
551
552
553
554
#if CONFIG_COLORSPACE_HEADERS
  oxcf->transfer_function = extra_cfg->transfer_function;
  oxcf->chroma_sample_position = extra_cfg->chroma_sample_position;
#endif
555
  oxcf->color_range = extra_cfg->color_range;
556
  oxcf->render_width = extra_cfg->render_width;
557
  oxcf->render_height = extra_cfg->render_height;
Jingning Han's avatar
Jingning Han committed
558
  oxcf->arnr_max_frames = extra_cfg->arnr_max_frames;
559
  oxcf->arnr_strength = extra_cfg->arnr_strength;
Jingning Han's avatar
Jingning Han committed
560
561
562
563
564
565
  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;

566
567
568
#if CONFIG_EXT_PARTITION
  oxcf->superblock_size = extra_cfg->superblock_size;
#endif  // CONFIG_EXT_PARTITION
569
570
571
#if CONFIG_ANS && ANS_MAX_SYMBOLS
  oxcf->ans_window_size_log2 = extra_cfg->ans_window_size_log2;
#endif  // CONFIG_ANS && ANS_MAX_SYMBOLS
572
573
574
575
576

#if CONFIG_EXT_TILE
  {
#if CONFIG_EXT_PARTITION
    const unsigned int max =
Yaowu Xu's avatar
Yaowu Xu committed
577
        extra_cfg->superblock_size == AOM_SUPERBLOCK_SIZE_64X64 ? 64 : 32;
578
579
580
#else
    const unsigned int max = 64;
#endif  // CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
581
582
    oxcf->tile_columns = AOMMIN(extra_cfg->tile_columns, max);
    oxcf->tile_rows = AOMMIN(extra_cfg->tile_rows, max);
583
    oxcf->tile_encoding_mode = extra_cfg->tile_encoding_mode;
584
585
  }
#else
Jingning Han's avatar
Jingning Han committed
586
  oxcf->tile_columns = extra_cfg->tile_columns;
587
  oxcf->tile_rows = extra_cfg->tile_rows;
588
#endif  // CONFIG_EXT_TILE
589
590
591
#if CONFIG_DEPENDENT_HORZTILES
  oxcf->dependent_horz_tiles = extra_cfg->dependent_horz_tiles;
#endif
592
#if CONFIG_LOOPFILTERING_ACROSS_TILES
593
594
  oxcf->loop_filter_across_tiles_enabled =
      extra_cfg->loop_filter_across_tiles_enabled;
595
#endif  // CONFIG_LOOPFILTERING_ACROSS_TILES
596
  oxcf->error_resilient_mode = cfg->g_error_resilient;
Jingning Han's avatar
Jingning Han committed
597
598
599
  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
600
601
602
#if CONFIG_EXT_DELTA_Q
  oxcf->deltaq_mode = extra_cfg->deltaq_mode;
#endif
Jingning Han's avatar
Jingning Han committed
603

604
  oxcf->frame_periodic_boost = extra_cfg->frame_periodic_boost;
Jingning Han's avatar
Jingning Han committed
605

Yunqing Wang's avatar
Yunqing Wang committed
606
  oxcf->motion_vector_unit_test = extra_cfg->motion_vector_unit_test;
Jingning Han's avatar
Jingning Han committed
607
  /*
Yaowu Xu's avatar
Yaowu Xu committed
608
  printf("Current AV1 Settings: \n");
Jingning Han's avatar
Jingning Han committed
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
  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
638
  return AOM_CODEC_OK;
Jingning Han's avatar
Jingning Han committed
639
640
}

Yaowu Xu's avatar
Yaowu Xu committed
641
642
643
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
644
645
646
  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
647
    if (cfg->g_lag_in_frames > 1 || cfg->g_pass != AOM_RC_ONE_PASS)
Jingning Han's avatar
Jingning Han committed
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
      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
664
  if (res == AOM_CODEC_OK) {
Jingning Han's avatar
Jingning Han committed
665
666
667
668
    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
669
    av1_change_config(ctx->cpi, &ctx->oxcf);
Jingning Han's avatar
Jingning Han committed
670
671
  }

Yaowu Xu's avatar
Yaowu Xu committed
672
  if (force_key) ctx->next_frame_flags |= AOM_EFLAG_FORCE_KF;
Jingning Han's avatar
Jingning Han committed
673
674
675
676

  return res;
}

Yaowu Xu's avatar
Yaowu Xu committed
677
static aom_codec_err_t ctrl_get_quantizer(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
678
679
                                          va_list args) {
  int *const arg = va_arg(args, int *);
Yaowu Xu's avatar
Yaowu Xu committed
680
681
682
  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
683
684
}

Yaowu Xu's avatar
Yaowu Xu committed
685
static aom_codec_err_t ctrl_get_quantizer64(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
686
687
                                            va_list args) {
  int *const arg = va_arg(args, int *);
Yaowu Xu's avatar
Yaowu Xu committed
688
689
690
  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
691
692
}

Yaowu Xu's avatar
Yaowu Xu committed
693
694
695
696
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
697
698
    ctx->extra_cfg = *extra_cfg;
    set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
Yaowu Xu's avatar
Yaowu Xu committed
699
    av1_change_config(ctx->cpi, &ctx->oxcf);
Jingning Han's avatar
Jingning Han committed
700
701
702
703
  }
  return res;
}

Yaowu Xu's avatar
Yaowu Xu committed
704
static aom_codec_err_t ctrl_set_cpuused(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
705
                                        va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
706
707
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.cpu_used = CAST(AOME_SET_CPUUSED, args);
Jingning Han's avatar
Jingning Han committed
708
709
710
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
711
static aom_codec_err_t ctrl_set_enable_auto_alt_ref(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
712
                                                    va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
713
714
  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
715
716
717
  return update_extra_cfg(ctx, &extra_cfg);
}

718
#if CONFIG_EXT_REFS
Yaowu Xu's avatar
Yaowu Xu committed
719
static aom_codec_err_t ctrl_set_enable_auto_bwd_ref(aom_codec_alg_priv_t *ctx,
720
                                                    va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
721
722
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.enable_auto_bwd_ref = CAST(AOME_SET_ENABLEAUTOBWDREF, args);
723
724
  return update_extra_cfg(ctx, &extra_cfg);
}
725
#endif  // CONFIG_EXT_REFS
726

Yaowu Xu's avatar
Yaowu Xu committed
727
static aom_codec_err_t ctrl_set_noise_sensitivity(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
728
                                                  va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
729
730
  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
731
732
733
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
734
static aom_codec_err_t ctrl_set_sharpness(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
735
                                          va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
736
737
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.sharpness = CAST(AOME_SET_SHARPNESS, args);
Jingning Han's avatar
Jingning Han committed
738
739
740
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
741
static aom_codec_err_t ctrl_set_static_thresh(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
742
                                              va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
743
744
  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
745
746
747
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
748
static aom_codec_err_t ctrl_set_tile_columns(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
749
                                             va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
750
751
  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
752
753
754
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
755
static aom_codec_err_t ctrl_set_tile_rows(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
756
                                          va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
757
758
  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
759
760
  return update_extra_cfg(ctx, &extra_cfg);
}
761
762
763
764
765
766
767
768
#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
769
#if CONFIG_LOOPFILTERING_ACROSS_TILES
770
771
772
773
774
775
776
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);
}
777
#endif  // CONFIG_LOOPFILTERING_ACROSS_TILES
778

Yaowu Xu's avatar
Yaowu Xu committed
779
static aom_codec_err_t ctrl_set_arnr_max_frames(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
780
                                                va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
781
782
  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
783
784
785
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
786
static aom_codec_err_t ctrl_set_arnr_strength(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
787
                                              va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
788
789
  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
790
791
792
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
793
static aom_codec_err_t ctrl_set_tuning(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
794
                                       va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
795
796
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.tuning = CAST(AOME_SET_TUNING, args);
Jingning Han's avatar
Jingning Han committed
797
798
799
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
800
static aom_codec_err_t ctrl_set_cq_level(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
801
                                         va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
802
803
  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
804
805
806
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
807
808
809
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
810
  extra_cfg.rc_max_intra_bitrate_pct =
Yaowu Xu's avatar
Yaowu Xu committed
811
      CAST(AOME_SET_MAX_INTRA_BITRATE_PCT, args);
Jingning Han's avatar
Jingning Han committed
812
813
814
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
815
816
817
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
818
  extra_cfg.rc_max_inter_bitrate_pct =
Yaowu Xu's avatar
Yaowu Xu committed
819
      CAST(AOME_SET_MAX_INTER_BITRATE_PCT, args);
Jingning Han's avatar
Jingning Han committed
820
821
822
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
823
static aom_codec_err_t ctrl_set_rc_gf_cbr_boost_pct(aom_codec_alg_priv_t *ctx,
824
                                                    va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
825
826
  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
827
828
829
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
830
static aom_codec_err_t ctrl_set_lossless(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
831
                                         va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
832
833
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.lossless = CAST(AV1E_SET_LOSSLESS, args);
Jingning Han's avatar
Jingning Han committed
834
835
836
  return update_extra_cfg(ctx, &extra_cfg);
}

837
#if CONFIG_AOM_QM
Yaowu Xu's avatar
Yaowu Xu committed
838
static aom_codec_err_t ctrl_set_enable_qm(aom_codec_alg_priv_t *ctx,
839
                                          va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
840
841
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.enable_qm = CAST(AV1E_SET_ENABLE_QM, args);
842
843
844
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
845
static aom_codec_err_t ctrl_set_qm_min(aom_codec_alg_priv_t *ctx,
846
                                       va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
847
848
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.qm_min = CAST(AV1E_SET_QM_MIN, args);
849
850
851
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
852
static aom_codec_err_t ctrl_set_qm_max(aom_codec_alg_priv_t *ctx,
853
                                       va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
854
855
  struct av1_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.qm_max = CAST(AV1E_SET_QM_MAX, args);
856
857
858
859
  return update_extra_cfg(ctx, &extra_cfg);
}
#endif

860
861
862
863
864
865
866
867
868
869
870
871
872
873
#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
874
875
876
877
878
879
880
881
#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
882
883
884
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
885
  extra_cfg.frame_parallel_decoding_mode =
Yaowu Xu's avatar
Yaowu Xu committed
886
      CAST(AV1E_SET_FRAME_PARALLEL_DECODING, args);
Jingning Han's avatar
Jingning Han committed
887
888
889
  return update_extra_cfg(ctx, &extra_cfg);
}

890
891
892
893
894
895
896
897
898
#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
899
static aom_codec_err_t ctrl_set_aq_mode(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
900
                                        va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
901
902
  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
903
904
905
  return update_extra_cfg(ctx, &extra_cfg);
}

Fangwen Fu's avatar
Fangwen Fu committed
906
907
908
909
910
911
912
913
#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
914
static aom_codec_err_t ctrl_set_min_gf_interval(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
915
                                                va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
916
917
  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
918
919
920
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
921
static aom_codec_err_t ctrl_set_max_gf_interval(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
922
                                                va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
923
924
  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
925
926
927
  return update_extra_cfg(ctx, &extra_cfg);
}

Yaowu Xu's avatar
Yaowu Xu committed
928
static aom_codec_err_t ctrl_set_frame_periodic_boost(aom_codec_alg_priv_t *ctx,
Jingning Han's avatar
Jingning Han committed
929
                                                     va_list args) {
Yaowu Xu's avatar
Yaowu Xu committed
930
931
  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
932
933
934
  return update_extra_cfg(ctx, &extra_cfg);
}

Yunqing Wang's avatar
Yunqing Wang committed
935
936
937
938
939
940
941
942
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
943
944
945
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
946
947
948
  (void)data;

  if (ctx->priv == NULL) {
Yaowu Xu's avatar
Yaowu Xu committed
949
950
    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
951

Yaowu Xu's avatar
Yaowu Xu committed
952
    ctx->priv = (aom_codec_priv_t *)priv;
Jingning Han's avatar
Jingning Han committed
953
954
    ctx->priv->init_flags = ctx->init_flags;
    ctx->priv->enc.total_encoders = 1;
Yaowu Xu's avatar
Yaowu Xu committed
955
956
    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
957
958
959

#if CONFIG_MULTITHREAD
    if (pthread_mutex_init(&priv->buffer_pool->pool_mutex, NULL)) {
Yaowu Xu's avatar
Yaowu Xu committed
960
      return AOM_CODEC_MEM_ERROR;
Jingning Han's avatar
Jingning Han committed
961
962
963
964
965
966
967
968
969
970
    }
#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
971
    once(av1_initialize_enc);
Jingning Han's avatar
Jingning Han committed
972
973
974

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

Yaowu Xu's avatar
Yaowu Xu committed
975
    if (res == AOM_CODEC_OK) {
Jingning Han's avatar
Jingning Han committed
976
      set_encoder_config(&priv->oxcf, &priv->cfg, &priv->extra_cfg);
977
#if CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
978
      priv->oxcf.use_highbitdepth =
Yaowu Xu's avatar
Yaowu Xu committed
979
          (ctx->init_flags & AOM_CODEC_USE_HIGHBITDEPTH) ? 1 : 0;
Jingning Han's avatar
Jingning Han committed
980
#endif
Yaowu Xu's avatar
Yaowu Xu committed
981
      priv->cpi = av1_create_compressor(&priv->oxcf, priv->buffer_pool);
Jingning Han's avatar
Jingning Han committed
982
      if (priv->cpi == NULL)
Yaowu Xu's avatar
Yaowu Xu committed
983
        res = AOM_CODEC_MEM_ERROR;
Jingning Han's avatar
Jingning Han committed
984
985
986
987
988
989
990
991
      else
        priv->cpi->output_pkt_list = &priv->pkt_list.head;
    }
  }

  return res;
}

Yaowu Xu's avatar
Yaowu Xu committed
992
static aom_codec_err_t encoder_destroy(aom_codec_alg_priv_t *ctx) {
Jingning Han's avatar
Jingning Han committed
993
  free(ctx->cx_data);
Yaowu Xu's avatar
Yaowu Xu committed
994
  av1_remove_compressor(ctx->cpi);
Jingning Han's avatar
Jingning Han committed
995
996
997
#if CONFIG_MULTITHREAD
  pthread_mutex_destroy(&ctx->buffer_pool->pool_mutex);
#endif
Yaowu Xu's avatar
Yaowu Xu committed
998
999
1000
  aom_free(ctx->buffer_pool);
  aom_free(ctx);
  return AOM_CODEC_OK;
For faster browsing, not all history is shown. View entire blame