vp9_cx_iface.c 59.6 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9 10
 */

11 12
#include <stdlib.h>
#include <string.h>
John Koleszar's avatar
John Koleszar committed
13

14
#include "./vpx_config.h"
15
#include "vpx/vpx_encoder.h"
16
#include "vpx_ports/vpx_once.h"
James Zern's avatar
James Zern committed
17
#include "vpx_ports/system_state.h"
18
#include "vpx/internal/vpx_codec_internal.h"
19
#include "./vpx_version.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
20
#include "vp9/encoder/vp9_encoder.h"
John Koleszar's avatar
John Koleszar committed
21
#include "vpx/vp8cx.h"
22
#include "vp9/encoder/vp9_firstpass.h"
John Koleszar's avatar
John Koleszar committed
23
#include "vp9/vp9_iface_common.h"
John Koleszar's avatar
John Koleszar committed
24

25
struct vp9_extracfg {
26
  int                         cpu_used;  // available cpu percentage in 1/16
27
  unsigned int                enable_auto_alt_ref;
John Koleszar's avatar
John Koleszar committed
28
  unsigned int                noise_sensitivity;
29
  unsigned int                sharpness;
John Koleszar's avatar
John Koleszar committed
30
  unsigned int                static_thresh;
31
  unsigned int                tile_columns;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
32
  unsigned int                tile_rows;
33 34
  unsigned int                arnr_max_frames;
  unsigned int                arnr_strength;
35 36
  unsigned int                min_gf_interval;
  unsigned int                max_gf_interval;
John Koleszar's avatar
John Koleszar committed
37
  vp8e_tuning                 tuning;
38
  unsigned int                cq_level;  // constrained quality level
John Koleszar's avatar
John Koleszar committed
39
  unsigned int                rc_max_intra_bitrate_pct;
40
  unsigned int                rc_max_inter_bitrate_pct;
41
  unsigned int                gf_cbr_boost_pct;
John Koleszar's avatar
John Koleszar committed
42
  unsigned int                lossless;
43
  unsigned int                target_level;
44
  unsigned int                frame_parallel_decoding_mode;
45
  AQ_MODE                     aq_mode;
46
  unsigned int                frame_periodic_boost;
47
  vpx_bit_depth_t             bit_depth;
48
  vp9e_tune_content           content;
49
  vpx_color_space_t           color_space;
50
  vpx_color_range_t           color_range;
51 52
  int                         render_width;
  int                         render_height;
John Koleszar's avatar
John Koleszar committed
53 54
};

55 56 57 58 59 60
static struct vp9_extracfg default_extra_cfg = {
  0,                          // cpu_used
  1,                          // enable_auto_alt_ref
  0,                          // noise_sensitivity
  0,                          // sharpness
  0,                          // static_thresh
61
  6,                          // tile_columns
62 63 64
  0,                          // tile_rows
  7,                          // arnr_max_frames
  5,                          // arnr_strength
65 66
  0,                          // min_gf_interval; 0 -> default decision
  0,                          // max_gf_interval; 0 -> default decision
67 68 69
  VP8_TUNE_PSNR,              // tuning
  10,                         // cq_level
  0,                          // rc_max_intra_bitrate_pct
70
  0,                          // rc_max_inter_bitrate_pct
71
  0,                          // gf_cbr_boost_pct
72
  0,                          // lossless
73
  255,                        // target_level
74
  1,                          // frame_parallel_decoding_mode
75 76
  NO_AQ,                      // aq_mode
  0,                          // frame_periodic_delta_q
77
  VPX_BITS_8,                 // Bit depth
78 79
  VP9E_CONTENT_DEFAULT,       // content
  VPX_CS_UNKNOWN,             // color space
80
  0,                          // color range
81 82
  0,                          // render width
  0,                          // render height
John Koleszar's avatar
John Koleszar committed
83 84
};

John Koleszar's avatar
John Koleszar committed
85 86 87
struct vpx_codec_alg_priv {
  vpx_codec_priv_t        base;
  vpx_codec_enc_cfg_t     cfg;
88
  struct vp9_extracfg     extra_cfg;
89
  VP9EncoderConfig        oxcf;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
90
  VP9_COMP               *cpi;
John Koleszar's avatar
John Koleszar committed
91
  unsigned char          *cx_data;
92
  size_t                  cx_data_sz;
93
  unsigned char          *pending_cx_data;
94
  size_t                  pending_cx_data_sz;
John Koleszar's avatar
John Koleszar committed
95
  int                     pending_frame_count;
96 97
  size_t                  pending_frame_sizes[8];
  size_t                  pending_frame_magnitude;
John Koleszar's avatar
John Koleszar committed
98
  vpx_image_t             preview_img;
99
  vpx_enc_frame_flags_t   next_frame_flags;
John Koleszar's avatar
John Koleszar committed
100
  vp8_postproc_cfg_t      preview_ppcfg;
101
  vpx_codec_pkt_list_decl(256) pkt_list;
102
  unsigned int                 fixed_kf_cntr;
103
  vpx_codec_priv_output_cx_pkt_cb_pair_t output_cx_pkt_cb;
104 105
  // BufferPool that holds all reference frames.
  BufferPool              *buffer_pool;
John Koleszar's avatar
John Koleszar committed
106 107
};

108
static VP9_REFFRAME ref_frame_to_vp9_reframe(vpx_ref_frame_type_t frame) {
109 110 111 112 113 114 115 116
  switch (frame) {
    case VP8_LAST_FRAME:
      return VP9_LAST_FLAG;
    case VP8_GOLD_FRAME:
      return VP9_GOLD_FLAG;
    case VP8_ALTR_FRAME:
      return VP9_ALT_FLAG;
  }
James Zern's avatar
James Zern committed
117
  assert(0 && "Invalid Reference Frame");
118 119
  return VP9_LAST_FLAG;
}
John Koleszar's avatar
John Koleszar committed
120

121 122 123
static vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx,
    const struct vpx_internal_error_info *error) {
  const vpx_codec_err_t res = error->error_code;
John Koleszar's avatar
John Koleszar committed
124

125 126
  if (res != VPX_CODEC_OK)
    ctx->base.err_detail = error->has_detail ? error->detail : NULL;
John Koleszar's avatar
John Koleszar committed
127

John Koleszar's avatar
John Koleszar committed
128
  return res;
John Koleszar's avatar
John Koleszar committed
129 130 131
}


132
#undef ERROR
John Koleszar's avatar
John Koleszar committed
133
#define ERROR(str) do {\
John Koleszar's avatar
John Koleszar committed
134 135
    ctx->base.err_detail = str;\
    return VPX_CODEC_INVALID_PARAM;\
136
  } while (0)
John Koleszar's avatar
John Koleszar committed
137

138 139
#define RANGE_CHECK(p, memb, lo, hi) do {\
    if (!(((p)->memb == lo || (p)->memb > (lo)) && (p)->memb <= hi)) \
John Koleszar's avatar
John Koleszar committed
140
      ERROR(#memb " out of range ["#lo".."#hi"]");\
141
  } while (0)
John Koleszar's avatar
John Koleszar committed
142

143 144
#define RANGE_CHECK_HI(p, memb, hi) do {\
    if (!((p)->memb <= (hi))) \
John Koleszar's avatar
John Koleszar committed
145
      ERROR(#memb " out of range [.."#hi"]");\
146
  } while (0)
147

148 149
#define RANGE_CHECK_LO(p, memb, lo) do {\
    if (!((p)->memb >= (lo))) \
John Koleszar's avatar
John Koleszar committed
150
      ERROR(#memb " out of range ["#lo"..]");\
151
  } while (0)
John Koleszar's avatar
John Koleszar committed
152

153 154 155
#define RANGE_CHECK_BOOL(p, memb) do {\
    if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean");\
  } while (0)
John Koleszar's avatar
John Koleszar committed
156

157
static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
John Koleszar's avatar
John Koleszar committed
158
                                       const vpx_codec_enc_cfg_t *cfg,
159
                                       const struct vp9_extracfg *extra_cfg) {
160 161
  RANGE_CHECK(cfg, g_w,                   1, 65535);  // 16 bits available
  RANGE_CHECK(cfg, g_h,                   1, 65535);  // 16 bits available
John Koleszar's avatar
John Koleszar committed
162
  RANGE_CHECK(cfg, g_timebase.den,        1, 1000000000);
163
  RANGE_CHECK(cfg, g_timebase.num,        1, 1000000000);
John Koleszar's avatar
John Koleszar committed
164
  RANGE_CHECK_HI(cfg, g_profile,          3);
John Koleszar's avatar
John Koleszar committed
165

John Koleszar's avatar
John Koleszar committed
166 167
  RANGE_CHECK_HI(cfg, rc_max_quantizer,   63);
  RANGE_CHECK_HI(cfg, rc_min_quantizer,   cfg->rc_max_quantizer);
168 169
  RANGE_CHECK_BOOL(extra_cfg, lossless);
  RANGE_CHECK(extra_cfg, aq_mode,           0, AQ_MODE_COUNT - 1);
170
  RANGE_CHECK(extra_cfg, frame_periodic_boost, 0, 1);
John Koleszar's avatar
John Koleszar committed
171 172
  RANGE_CHECK_HI(cfg, g_threads,          64);
  RANGE_CHECK_HI(cfg, g_lag_in_frames,    MAX_LAG_BUFFERS);
173
  RANGE_CHECK(cfg, rc_end_usage,          VPX_VBR, VPX_Q);
174 175
  RANGE_CHECK_HI(cfg, rc_undershoot_pct,  100);
  RANGE_CHECK_HI(cfg, rc_overshoot_pct,   100);
John Koleszar's avatar
John Koleszar committed
176 177 178 179 180 181 182
  RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
  RANGE_CHECK(cfg, kf_mode,               VPX_KF_DISABLED, VPX_KF_AUTO);
  RANGE_CHECK_BOOL(cfg,                   rc_resize_allowed);
  RANGE_CHECK_HI(cfg, rc_dropframe_thresh,   100);
  RANGE_CHECK_HI(cfg, rc_resize_up_thresh,   100);
  RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100);
  RANGE_CHECK(cfg,        g_pass,         VPX_RC_ONE_PASS, VPX_RC_LAST_PASS);
183 184
  RANGE_CHECK(extra_cfg, min_gf_interval, 0, (MAX_LAG_BUFFERS - 1));
  RANGE_CHECK(extra_cfg, max_gf_interval, 0, (MAX_LAG_BUFFERS - 1));
185 186 187
  if (extra_cfg->max_gf_interval > 0) {
    RANGE_CHECK(extra_cfg, max_gf_interval, 2, (MAX_LAG_BUFFERS - 1));
  }
188 189
  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,
190
      (MAX_LAG_BUFFERS - 1));
191
  }
John Koleszar's avatar
John Koleszar committed
192

193
  if (cfg->rc_resize_allowed == 1) {
194 195
    RANGE_CHECK(cfg, rc_scaled_width, 0, cfg->g_w);
    RANGE_CHECK(cfg, rc_scaled_height, 0, cfg->g_h);
196 197
  }

198
  RANGE_CHECK(cfg, ss_number_layers, 1, VPX_SS_MAX_LAYERS);
199
  RANGE_CHECK(cfg, ts_number_layers, 1, VPX_TS_MAX_LAYERS);
200

201 202 203 204 205 206 207 208 209 210 211
  {
    unsigned int level = extra_cfg->target_level;
    if (level != LEVEL_1 && level != LEVEL_1_1 && level != LEVEL_2 &&
        level != LEVEL_2_1 && level != LEVEL_3 && level != LEVEL_3_1 &&
        level != LEVEL_4 && level != LEVEL_4_1 && level != LEVEL_5 &&
        level != LEVEL_5_1 && level != LEVEL_5_2 && level != LEVEL_6 &&
        level != LEVEL_6_1 && level != LEVEL_6_2 &&
        level != LEVEL_UNKNOWN && level != LEVEL_NOT_CARE)
    ERROR("target_level is invalid");
  }

212 213
  if (cfg->ss_number_layers * cfg->ts_number_layers > VPX_MAX_LAYERS)
    ERROR("ss_number_layers * ts_number_layers is out of range");
214
  if (cfg->ts_number_layers > 1) {
215 216 217 218 219 220 221
    unsigned int sl, tl;
    for (sl = 1; sl < cfg->ss_number_layers; ++sl) {
      for (tl = 1; tl < cfg->ts_number_layers; ++tl) {
        const int layer =
            LAYER_IDS_TO_IDX(sl, tl, cfg->ts_number_layers);
        if (cfg->layer_target_bitrate[layer] <
            cfg->layer_target_bitrate[layer - 1])
222
        ERROR("ts_target_bitrate entries are not increasing");
223 224
      }
    }
225 226

    RANGE_CHECK(cfg, ts_rate_decimator[cfg->ts_number_layers - 1], 1, 1);
227 228
    for (tl = cfg->ts_number_layers - 2; tl > 0; --tl)
      if (cfg->ts_rate_decimator[tl - 1] != 2 * cfg->ts_rate_decimator[tl])
229 230 231
        ERROR("ts_rate_decimator factors are not powers of 2");
  }

232 233 234 235 236 237 238 239 240
#if CONFIG_SPATIAL_SVC

  if ((cfg->ss_number_layers > 1 || cfg->ts_number_layers > 1) &&
      cfg->g_pass == VPX_RC_LAST_PASS) {
    unsigned int i, alt_ref_sum = 0;
    for (i = 0; i < cfg->ss_number_layers; ++i) {
      if (cfg->ss_enable_auto_alt_ref[i])
        ++alt_ref_sum;
    }
241
    if (alt_ref_sum > REF_FRAMES - cfg->ss_number_layers)
242
      ERROR("Not enough ref buffers for svc alt ref frames");
243
    if (cfg->ss_number_layers * cfg->ts_number_layers > 3 &&
244
        cfg->g_error_resilient == 0)
245
    ERROR("Multiple frame context are not supported for more than 3 layers");
246 247 248
  }
#endif

249
  // VP9 does not support a lower bound on the keyframe interval in
250 251 252 253
  // automatic keyframe placement mode.
  if (cfg->kf_mode != VPX_KF_DISABLED &&
      cfg->kf_min_dist != cfg->kf_max_dist &&
      cfg->kf_min_dist > 0)
John Koleszar's avatar
John Koleszar committed
254 255 256
    ERROR("kf_min_dist not supported in auto mode, use 0 "
          "or kf_max_dist instead.");

257
  RANGE_CHECK(extra_cfg, enable_auto_alt_ref, 0, 2);
258
  RANGE_CHECK(extra_cfg, cpu_used, -8, 8);
259 260 261 262 263 264 265
  RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6);
  RANGE_CHECK(extra_cfg, tile_columns, 0, 6);
  RANGE_CHECK(extra_cfg, tile_rows, 0, 2);
  RANGE_CHECK_HI(extra_cfg, sharpness, 7);
  RANGE_CHECK(extra_cfg, arnr_max_frames, 0, 15);
  RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);
  RANGE_CHECK(extra_cfg, cq_level, 0, 63);
266 267
  RANGE_CHECK(cfg, g_bit_depth, VPX_BITS_8, VPX_BITS_12);
  RANGE_CHECK(cfg, g_input_bit_depth, 8, 12);
268 269
  RANGE_CHECK(extra_cfg, content,
              VP9E_CONTENT_DEFAULT, VP9E_CONTENT_INVALID - 1);
John Koleszar's avatar
John Koleszar committed
270

Yaowu Xu's avatar
Yaowu Xu committed
271
  // TODO(yaowu): remove this when ssim tuning is implemented for vp9
272
  if (extra_cfg->tuning == VP8_TUNE_SSIM)
Yaowu Xu's avatar
Yaowu Xu committed
273 274
      ERROR("Option --tune=ssim is not currently supported in VP9.");

John Koleszar's avatar
John Koleszar committed
275
  if (cfg->g_pass == VPX_RC_LAST_PASS) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
276 277
    const size_t packet_sz = sizeof(FIRSTPASS_STATS);
    const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
278
    const FIRSTPASS_STATS *stats;
John Koleszar's avatar
John Koleszar committed
279

Adrian Grange's avatar
Adrian Grange committed
280
    if (cfg->rc_twopass_stats_in.buf == NULL)
John Koleszar's avatar
John Koleszar committed
281 282 283 284 285
      ERROR("rc_twopass_stats_in.buf not set.");

    if (cfg->rc_twopass_stats_in.sz % packet_sz)
      ERROR("rc_twopass_stats_in.sz indicates truncated packet.");

286
    if (cfg->ss_number_layers > 1 || cfg->ts_number_layers > 1) {
287 288 289 290 291
      int i;
      unsigned int n_packets_per_layer[VPX_SS_MAX_LAYERS] = {0};

      stats = cfg->rc_twopass_stats_in.buf;
      for (i = 0; i < n_packets; ++i) {
292
        const int layer_id = (int)stats[i].spatial_layer_id;
293 294 295 296 297 298 299 300 301 302 303
        if (layer_id >= 0 && layer_id < (int)cfg->ss_number_layers) {
          ++n_packets_per_layer[layer_id];
        }
      }

      for (i = 0; i < (int)cfg->ss_number_layers; ++i) {
        unsigned int layer_id;
        if (n_packets_per_layer[i] < 2) {
          ERROR("rc_twopass_stats_in requires at least two packets for each "
                "layer.");
        }
John Koleszar's avatar
John Koleszar committed
304

305 306
        stats = (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf +
                n_packets - cfg->ss_number_layers + i;
307
        layer_id = (int)stats->spatial_layer_id;
John Koleszar's avatar
John Koleszar committed
308

309
        if (layer_id >= cfg->ss_number_layers
310 311
            ||(unsigned int)(stats->count + 0.5) !=
               n_packets_per_layer[layer_id] - 1)
312 313 314 315 316 317 318 319 320 321 322 323
          ERROR("rc_twopass_stats_in missing EOS stats packet");
      }
    } else {
      if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)
        ERROR("rc_twopass_stats_in requires at least two packets.");

      stats =
          (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1;

      if ((int)(stats->count + 0.5) != n_packets - 1)
        ERROR("rc_twopass_stats_in missing EOS stats packet");
    }
John Koleszar's avatar
John Koleszar committed
324
  }
325

326
#if !CONFIG_VP9_HIGHBITDEPTH
Deb Mukherjee's avatar
Deb Mukherjee committed
327
  if (cfg->g_profile > (unsigned int)PROFILE_1) {
328
    ERROR("Profile > 1 not supported in this build configuration");
Deb Mukherjee's avatar
Deb Mukherjee committed
329
  }
330
#endif
331
  if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
Deb Mukherjee's avatar
Deb Mukherjee committed
332
      cfg->g_bit_depth > VPX_BITS_8) {
333
    ERROR("Codec high bit-depth not supported in profile < 2");
Deb Mukherjee's avatar
Deb Mukherjee committed
334 335 336 337 338
  }
  if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
      cfg->g_input_bit_depth > 8) {
    ERROR("Source high bit-depth not supported in profile < 2");
  }
339
  if (cfg->g_profile > (unsigned int)PROFILE_1 &&
Deb Mukherjee's avatar
Deb Mukherjee committed
340
      cfg->g_bit_depth == VPX_BITS_8) {
341
    ERROR("Codec bit-depth 8 not supported in profile > 1");
Deb Mukherjee's avatar
Deb Mukherjee committed
342
  }
343
  RANGE_CHECK(extra_cfg, color_space, VPX_CS_UNKNOWN, VPX_CS_SRGB);
344 345
  RANGE_CHECK(extra_cfg, color_range,
              VPX_CR_STUDIO_RANGE, VPX_CR_FULL_RANGE);
John Koleszar's avatar
John Koleszar committed
346
  return VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
347 348 349
}

static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
350
                                    const vpx_image_t *img) {
John Koleszar's avatar
John Koleszar committed
351
  switch (img->fmt) {
James Zern's avatar
James Zern committed
352 353
    case VPX_IMG_FMT_YV12:
    case VPX_IMG_FMT_I420:
Deb Mukherjee's avatar
Deb Mukherjee committed
354 355
    case VPX_IMG_FMT_I42016:
      break;
356 357
    case VPX_IMG_FMT_I422:
    case VPX_IMG_FMT_I444:
Deb Mukherjee's avatar
Deb Mukherjee committed
358
    case VPX_IMG_FMT_I440:
Deb Mukherjee's avatar
Deb Mukherjee committed
359
      if (ctx->cfg.g_profile != (unsigned int)PROFILE_1) {
Deb Mukherjee's avatar
Deb Mukherjee committed
360
        ERROR("Invalid image format. I422, I444, I440 images are "
Deb Mukherjee's avatar
Deb Mukherjee committed
361 362 363 364 365
              "not supported in profile.");
      }
      break;
    case VPX_IMG_FMT_I42216:
    case VPX_IMG_FMT_I44416:
Deb Mukherjee's avatar
Deb Mukherjee committed
366
    case VPX_IMG_FMT_I44016:
Deb Mukherjee's avatar
Deb Mukherjee committed
367 368
      if (ctx->cfg.g_profile != (unsigned int)PROFILE_1 &&
          ctx->cfg.g_profile != (unsigned int)PROFILE_3) {
Deb Mukherjee's avatar
Deb Mukherjee committed
369
        ERROR("Invalid image format. 16-bit I422, I444, I440 images are "
Deb Mukherjee's avatar
Deb Mukherjee committed
370 371
              "not supported in profile.");
      }
John Koleszar's avatar
John Koleszar committed
372
      break;
John Koleszar's avatar
John Koleszar committed
373
    default:
374 375
      ERROR("Invalid image format. Only YV12, I420, I422, I444 images are "
            "supported.");
376
      break;
John Koleszar's avatar
John Koleszar committed
377
  }
John Koleszar's avatar
John Koleszar committed
378

379
  if (img->d_w != ctx->cfg.g_w || img->d_h != ctx->cfg.g_h)
John Koleszar's avatar
John Koleszar committed
380
    ERROR("Image size must match encoder init configuration size");
John Koleszar's avatar
John Koleszar committed
381

John Koleszar's avatar
John Koleszar committed
382
  return VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
383 384
}

385 386 387 388 389 390
static int get_image_bps(const vpx_image_t *img) {
  switch (img->fmt) {
    case VPX_IMG_FMT_YV12:
    case VPX_IMG_FMT_I420: return 12;
    case VPX_IMG_FMT_I422: return 16;
    case VPX_IMG_FMT_I444: return 24;
Deb Mukherjee's avatar
Deb Mukherjee committed
391
    case VPX_IMG_FMT_I440: return 16;
392 393 394
    case VPX_IMG_FMT_I42016: return 24;
    case VPX_IMG_FMT_I42216: return 32;
    case VPX_IMG_FMT_I44416: return 48;
Deb Mukherjee's avatar
Deb Mukherjee committed
395
    case VPX_IMG_FMT_I44016: return 32;
396
    default: assert(0 && "Invalid image format"); break;
397 398 399
  }
  return 0;
}
John Koleszar's avatar
John Koleszar committed
400

401
static vpx_codec_err_t set_encoder_config(
Yaowu Xu's avatar
Yaowu Xu committed
402 403 404
  VP9EncoderConfig *oxcf,
  const vpx_codec_enc_cfg_t *cfg,
  const struct vp9_extracfg *extra_cfg) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
405
  const int is_vbr = cfg->rc_end_usage == VPX_VBR;
406
  int sl, tl;
407
  oxcf->profile = cfg->g_profile;
408
  oxcf->max_threads = (int)cfg->g_threads;
409 410
  oxcf->width   = cfg->g_w;
  oxcf->height  = cfg->g_h;
Deb Mukherjee's avatar
Deb Mukherjee committed
411
  oxcf->bit_depth = cfg->g_bit_depth;
412
  oxcf->input_bit_depth = cfg->g_input_bit_depth;
413
  // guess a frame rate if out of whack, use 30
414 415 416
  oxcf->init_framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num;
  if (oxcf->init_framerate > 180)
    oxcf->init_framerate = 30;
John Koleszar's avatar
John Koleszar committed
417

418
  oxcf->mode = GOOD;
419

420
  switch (cfg->g_pass) {
John Koleszar's avatar
John Koleszar committed
421
    case VPX_RC_ONE_PASS:
422
      oxcf->pass = 0;
John Koleszar's avatar
John Koleszar committed
423
      break;
John Koleszar's avatar
John Koleszar committed
424
    case VPX_RC_FIRST_PASS:
425
      oxcf->pass = 1;
John Koleszar's avatar
John Koleszar committed
426
      break;
John Koleszar's avatar
John Koleszar committed
427
    case VPX_RC_LAST_PASS:
428
      oxcf->pass = 2;
John Koleszar's avatar
John Koleszar committed
429 430 431
      break;
  }

432 433
  oxcf->lag_in_frames = cfg->g_pass == VPX_RC_FIRST_PASS ? 0
                                                         : cfg->g_lag_in_frames;
434
  oxcf->rc_mode = cfg->rc_end_usage;
435

436 437
  // Convert target bandwidth from Kbit/s to Bit/s
  oxcf->target_bandwidth = 1000 * cfg->rc_target_bitrate;
438
  oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct;
439
  oxcf->rc_max_inter_bitrate_pct = extra_cfg->rc_max_inter_bitrate_pct;
440
  oxcf->gf_cbr_boost_pct = extra_cfg->gf_cbr_boost_pct;
John Koleszar's avatar
John Koleszar committed
441

442 443 444 445
  oxcf->best_allowed_q =
      extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_min_quantizer);
  oxcf->worst_allowed_q =
      extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_max_quantizer);
446
  oxcf->cq_level        = vp9_quantizer_to_qindex(extra_cfg->cq_level);
John Koleszar's avatar
John Koleszar committed
447 448
  oxcf->fixed_q = -1;

449 450 451
  oxcf->under_shoot_pct         = cfg->rc_undershoot_pct;
  oxcf->over_shoot_pct          = cfg->rc_overshoot_pct;

452 453 454 455 456 457 458 459 460
  oxcf->scaled_frame_width  = cfg->rc_scaled_width;
  oxcf->scaled_frame_height = cfg->rc_scaled_height;
  if (cfg->rc_resize_allowed == 1) {
    oxcf->resize_mode =
        (oxcf->scaled_frame_width == 0 || oxcf->scaled_frame_height == 0) ?
            RESIZE_DYNAMIC : RESIZE_FIXED;
  } else {
    oxcf->resize_mode = RESIZE_NONE;
  }
461

Dmitry Kovalev's avatar
Dmitry Kovalev committed
462 463 464
  oxcf->maximum_buffer_size_ms   = is_vbr ? 240000 : cfg->rc_buf_sz;
  oxcf->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz;
  oxcf->optimal_buffer_level_ms  = is_vbr ? 60000 : cfg->rc_buf_optimal_sz;
John Koleszar's avatar
John Koleszar committed
465

466
  oxcf->drop_frames_water_mark   = cfg->rc_dropframe_thresh;
John Koleszar's avatar
John Koleszar committed
467

468 469 470
  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;
471

472 473
  oxcf->auto_key               = cfg->kf_mode == VPX_KF_AUTO &&
                                 cfg->kf_min_dist != cfg->kf_max_dist;
John Koleszar's avatar
John Koleszar committed
474

475
  oxcf->key_freq               = cfg->kf_max_dist;
John Koleszar's avatar
John Koleszar committed
476

477
  oxcf->speed                  =  abs(extra_cfg->cpu_used);
478
  oxcf->encode_breakout        =  extra_cfg->static_thresh;
479
  oxcf->enable_auto_arf        =  extra_cfg->enable_auto_alt_ref;
480 481
  oxcf->noise_sensitivity      =  extra_cfg->noise_sensitivity;
  oxcf->sharpness              =  extra_cfg->sharpness;
John Koleszar's avatar
John Koleszar committed
482

483
  oxcf->two_pass_stats_in      =  cfg->rc_twopass_stats_in;
John Koleszar's avatar
John Koleszar committed
484

485 486 487 488
#if CONFIG_FP_MB_STATS
  oxcf->firstpass_mb_stats_in  = cfg->rc_firstpass_mb_stats_in;
#endif

489
  oxcf->color_space = extra_cfg->color_space;
490
  oxcf->color_range = extra_cfg->color_range;
491 492
  oxcf->render_width  = extra_cfg->render_width;
  oxcf->render_height = extra_cfg->render_height;
493 494
  oxcf->arnr_max_frames = extra_cfg->arnr_max_frames;
  oxcf->arnr_strength   = extra_cfg->arnr_strength;
495 496
  oxcf->min_gf_interval = extra_cfg->min_gf_interval;
  oxcf->max_gf_interval = extra_cfg->max_gf_interval;
John Koleszar's avatar
John Koleszar committed
497

498
  oxcf->tuning = extra_cfg->tuning;
499
  oxcf->content = extra_cfg->content;
John Koleszar's avatar
John Koleszar committed
500

501
  oxcf->tile_columns = extra_cfg->tile_columns;
502

503 504 505 506 507
  // TODO(yunqing): The dependencies between row tiles cause error in multi-
  // threaded encoding. For now, tile_rows is forced to be 0 in this case.
  // The further fix can be done by adding synchronizations after a tile row
  // is encoded. But this will hurt multi-threaded encoder performance. So,
  // it is recommended to use tile-rows=0 while encoding with threads > 1.
508 509 510 511
  if (oxcf->max_threads > 1 && oxcf->tile_columns > 0)
    oxcf->tile_rows  = 0;
  else
    oxcf->tile_rows  = extra_cfg->tile_rows;
512

513 514
  oxcf->error_resilient_mode         = cfg->g_error_resilient;
  oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode;
515

516
  oxcf->aq_mode = extra_cfg->aq_mode;
517

518 519
  oxcf->frame_periodic_boost =  extra_cfg->frame_periodic_boost;

520
  oxcf->ss_number_layers = cfg->ss_number_layers;
521 522 523
  oxcf->ts_number_layers = cfg->ts_number_layers;
  oxcf->temporal_layering_mode = (enum vp9e_temporal_layering_mode)
      cfg->temporal_layering_mode;
524

525 526
  oxcf->target_level = extra_cfg->target_level;

527
  for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
528
#if CONFIG_SPATIAL_SVC
529
    oxcf->ss_enable_auto_arf[sl] = cfg->ss_enable_auto_alt_ref[sl];
530
#endif
531 532 533
    for (tl = 0; tl < oxcf->ts_number_layers; ++tl) {
      oxcf->layer_target_bitrate[sl * oxcf->ts_number_layers + tl] =
          1000 * cfg->layer_target_bitrate[sl * oxcf->ts_number_layers + tl];
534
    }
535 536
  }
  if (oxcf->ss_number_layers == 1 && oxcf->pass != 0) {
Paul Wilkins's avatar
Paul Wilkins committed
537
    oxcf->ss_target_bitrate[0] = (int)oxcf->target_bandwidth;
538
#if CONFIG_SPATIAL_SVC
539
    oxcf->ss_enable_auto_arf[0] = extra_cfg->enable_auto_alt_ref;
540
#endif
541
  }
542
  if (oxcf->ts_number_layers > 1) {
543 544 545
    for (tl = 0; tl < VPX_TS_MAX_LAYERS; ++tl) {
      oxcf->ts_rate_decimator[tl] = cfg->ts_rate_decimator[tl] ?
          cfg->ts_rate_decimator[tl] : 1;
546
    }
547 548 549
  } else if (oxcf->ts_number_layers == 1) {
    oxcf->ts_rate_decimator[0] = 1;
  }
John Koleszar's avatar
John Koleszar committed
550
  /*
551 552
  printf("Current VP9 Settings: \n");
  printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
553
  printf("target_level: %d\n", oxcf->target_level);
554
  printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity);
555
  printf("sharpness: %d\n",    oxcf->sharpness);
556
  printf("cpu_used: %d\n",  oxcf->cpu_used);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
557
  printf("Mode: %d\n",     oxcf->mode);
558 559 560 561 562 563 564 565 566 567 568
  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);
569 570 571
  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);
572 573 574 575
  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);
576
  printf("enable_auto_arf: %d\n", oxcf->enable_auto_arf);
577 578 579
  printf("Version: %d\n", oxcf->Version);
  printf("encode_breakout: %d\n", oxcf->encode_breakout);
  printf("error resilient: %d\n", oxcf->error_resilient_mode);
580 581
  printf("frame parallel detokenization: %d\n",
         oxcf->frame_parallel_decoding_mode);
John Koleszar's avatar
John Koleszar committed
582 583
  */
  return VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
584 585
}

586 587
static vpx_codec_err_t encoder_set_config(vpx_codec_alg_priv_t *ctx,
                                          const vpx_codec_enc_cfg_t  *cfg) {
John Koleszar's avatar
John Koleszar committed
588
  vpx_codec_err_t res;
589 590 591 592 593
  int force_key = 0;

  if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h) {
    if (cfg->g_lag_in_frames > 1 || cfg->g_pass != VPX_RC_ONE_PASS)
      ERROR("Cannot change width or height after initialization");
594 595
    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) ||
596 597 598
        (ctx->cpi->initial_height && (int)cfg->g_h > ctx->cpi->initial_height))
      force_key = 1;
  }
John Koleszar's avatar
John Koleszar committed
599

600 601 602 603 604
  // 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)
John Koleszar's avatar
John Koleszar committed
605
    ERROR("Cannot increase lag_in_frames");
John Koleszar's avatar
John Koleszar committed
606

607
  res = validate_config(ctx, cfg, &ctx->extra_cfg);
John Koleszar's avatar
John Koleszar committed
608

Adrian Grange's avatar
Adrian Grange committed
609
  if (res == VPX_CODEC_OK) {
John Koleszar's avatar
John Koleszar committed
610
    ctx->cfg = *cfg;
611
    set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
612 613
    // On profile change, request a key frame
    force_key |= ctx->cpi->common.profile != ctx->oxcf.profile;
614
    vp9_change_config(ctx->cpi, &ctx->oxcf);
John Koleszar's avatar
John Koleszar committed
615
  }
John Koleszar's avatar
John Koleszar committed
616

617 618 619
  if (force_key)
    ctx->next_frame_flags |= VPX_EFLAG_FORCE_KF;

John Koleszar's avatar
John Koleszar committed
620
  return res;
John Koleszar's avatar
John Koleszar committed
621 622
}

623 624 625 626 627 628 629 630
static vpx_codec_err_t ctrl_get_quantizer(vpx_codec_alg_priv_t *ctx,
                                          va_list args) {
  int *const arg = va_arg(args, int *);
  if (arg == NULL)
    return VPX_CODEC_INVALID_PARAM;
  *arg = vp9_get_quantizer(ctx->cpi);
  return VPX_CODEC_OK;
}
John Koleszar's avatar
John Koleszar committed
631

632 633 634
static vpx_codec_err_t ctrl_get_quantizer64(vpx_codec_alg_priv_t *ctx,
                                            va_list args) {
  int *const arg = va_arg(args, int *);
635 636
  if (arg == NULL)
    return VPX_CODEC_INVALID_PARAM;
637 638 639
  *arg = vp9_qindex_to_quantizer(vp9_get_quantizer(ctx->cpi));
  return VPX_CODEC_OK;
}
John Koleszar's avatar
John Koleszar committed
640

641 642 643 644 645 646 647
static vpx_codec_err_t update_extra_cfg(vpx_codec_alg_priv_t *ctx,
                                        const struct vp9_extracfg *extra_cfg) {
  const vpx_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg);
  if (res == VPX_CODEC_OK) {
    ctx->extra_cfg = *extra_cfg;
    set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
    vp9_change_config(ctx->cpi, &ctx->oxcf);
John Koleszar's avatar
John Koleszar committed
648
  }
649 650
  return res;
}
John Koleszar's avatar
John Koleszar committed
651

652 653 654 655 656
static vpx_codec_err_t ctrl_set_cpuused(vpx_codec_alg_priv_t *ctx,
                                        va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.cpu_used = CAST(VP8E_SET_CPUUSED, args);
  return update_extra_cfg(ctx, &extra_cfg);
John Koleszar's avatar
John Koleszar committed
657 658
}

659 660 661 662 663 664
static vpx_codec_err_t ctrl_set_enable_auto_alt_ref(vpx_codec_alg_priv_t *ctx,
                                                    va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.enable_auto_alt_ref = CAST(VP8E_SET_ENABLEAUTOALTREF, args);
  return update_extra_cfg(ctx, &extra_cfg);
}
John Koleszar's avatar
John Koleszar committed
665

666 667
static vpx_codec_err_t ctrl_set_noise_sensitivity(vpx_codec_alg_priv_t *ctx,
                                                  va_list args) {
668
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
669
  extra_cfg.noise_sensitivity = CAST(VP9E_SET_NOISE_SENSITIVITY, args);
670 671
  return update_extra_cfg(ctx, &extra_cfg);
}
John Koleszar's avatar
John Koleszar committed
672

673 674 675 676 677 678
static vpx_codec_err_t ctrl_set_sharpness(vpx_codec_alg_priv_t *ctx,
                                          va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.sharpness = CAST(VP8E_SET_SHARPNESS, args);
  return update_extra_cfg(ctx, &extra_cfg);
}
John Koleszar's avatar
John Koleszar committed
679

680 681 682 683 684 685
static vpx_codec_err_t ctrl_set_static_thresh(vpx_codec_alg_priv_t *ctx,
                                              va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.static_thresh = CAST(VP8E_SET_STATIC_THRESHOLD, args);
  return update_extra_cfg(ctx, &extra_cfg);
}
John Koleszar's avatar
John Koleszar committed
686

687 688 689 690 691 692
static vpx_codec_err_t ctrl_set_tile_columns(vpx_codec_alg_priv_t *ctx,
                                             va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.tile_columns = CAST(VP9E_SET_TILE_COLUMNS, args);
  return update_extra_cfg(ctx, &extra_cfg);
}
John Koleszar's avatar
John Koleszar committed
693

694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716
static vpx_codec_err_t ctrl_set_tile_rows(vpx_codec_alg_priv_t *ctx,
                                          va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.tile_rows = CAST(VP9E_SET_TILE_ROWS, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

static vpx_codec_err_t ctrl_set_arnr_max_frames(vpx_codec_alg_priv_t *ctx,
                                                va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.arnr_max_frames = CAST(VP8E_SET_ARNR_MAXFRAMES, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

static vpx_codec_err_t ctrl_set_arnr_strength(vpx_codec_alg_priv_t *ctx,
                                              va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.arnr_strength = CAST(VP8E_SET_ARNR_STRENGTH, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

static vpx_codec_err_t ctrl_set_arnr_type(vpx_codec_alg_priv_t *ctx,
                                          va_list args) {
717 718 719
  (void)ctx;
  (void)args;
  return VPX_CODEC_OK;
720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
}

static vpx_codec_err_t ctrl_set_tuning(vpx_codec_alg_priv_t *ctx,
                                       va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.tuning = CAST(VP8E_SET_TUNING, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

static vpx_codec_err_t ctrl_set_cq_level(vpx_codec_alg_priv_t *ctx,
                                         va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.cq_level = CAST(VP8E_SET_CQ_LEVEL, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

static vpx_codec_err_t ctrl_set_rc_max_intra_bitrate_pct(
    vpx_codec_alg_priv_t *ctx, va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.rc_max_intra_bitrate_pct =
      CAST(VP8E_SET_MAX_INTRA_BITRATE_PCT, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

744 745 746 747 748 749 750 751
static vpx_codec_err_t ctrl_set_rc_max_inter_bitrate_pct(
    vpx_codec_alg_priv_t *ctx, va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.rc_max_inter_bitrate_pct =
      CAST(VP8E_SET_MAX_INTER_BITRATE_PCT, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

752 753 754 755
static vpx_codec_err_t ctrl_set_rc_gf_cbr_boost_pct(
    vpx_codec_alg_priv_t *ctx, va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.gf_cbr_boost_pct =
756
      CAST(VP9E_SET_GF_CBR_BOOST_PCT, args);
757 758 759
  return update_extra_cfg(ctx, &extra_cfg);
}

760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781
static vpx_codec_err_t ctrl_set_lossless(vpx_codec_alg_priv_t *ctx,
                                         va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.lossless = CAST(VP9E_SET_LOSSLESS, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

static vpx_codec_err_t ctrl_set_frame_parallel_decoding_mode(
    vpx_codec_alg_priv_t *ctx, va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.frame_parallel_decoding_mode =
      CAST(VP9E_SET_FRAME_PARALLEL_DECODING, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

static vpx_codec_err_t ctrl_set_aq_mode(vpx_codec_alg_priv_t *ctx,
                                        va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.aq_mode = CAST(VP9E_SET_AQ_MODE, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

782 783 784 785 786 787 788 789 790 791 792 793 794 795
static vpx_codec_err_t ctrl_set_min_gf_interval(vpx_codec_alg_priv_t *ctx,
                                                va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.min_gf_interval = CAST(VP9E_SET_MIN_GF_INTERVAL, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

static vpx_codec_err_t ctrl_set_max_gf_interval(vpx_codec_alg_priv_t *ctx,
                                                va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.max_gf_interval = CAST(VP9E_SET_MAX_GF_INTERVAL, args);
  return update_extra_cfg(ctx, &extra_cfg);
}

796 797 798 799 800
static vpx_codec_err_t ctrl_set_frame_periodic_boost(vpx_codec_alg_priv_t *ctx,
                                                     va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
  extra_cfg.frame_periodic_boost = CAST(VP9E_SET_FRAME_PERIODIC_BOOST, args);
  return update_extra_cfg(ctx, &extra_cfg);
John Koleszar's avatar
John Koleszar committed
801
}
802

803 804 805
static vpx_codec_err_t ctrl_set_target_level(vpx_codec_alg_priv_t *ctx,
                                             va_list args) {
  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
806
  extra_cfg.target_level = CAST(VP9E_SET_TARGET_LEVEL, args);
807 808 809
  return update_extra_cfg(ctx, &extra_cfg);
}

810 811
static vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx,
                                    vpx_codec_priv_enc_mr_cfg_t *data) {
812
  vpx_codec_err_t res = VPX_CODEC_OK;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
813
  (void)data;
John Koleszar's avatar
John Koleszar committed
814

Adrian Grange's avatar
Adrian Grange committed
815
  if (ctx->priv == NULL) {
816 817
    vpx_codec_alg_priv_t *const priv = vpx_calloc(1, sizeof(*priv));
    if (priv == NULL)
818
      return VPX_CODEC_MEM_ERROR;
819

820
    ctx->priv = (vpx_codec_priv_t *)priv;
John Koleszar's avatar
John Koleszar committed
821
    ctx->priv->init_flags = ctx->init_flags;
John Koleszar's avatar
John Koleszar committed
822
    ctx->priv->enc.total_encoders = 1;
823 824 825 826
    priv->buffer_pool =
        (BufferPool *)vpx_calloc(1, sizeof(BufferPool));
    if (priv->buffer_pool == NULL)
      return VPX_CODEC_MEM_ERROR;
John Koleszar's avatar
John Koleszar committed
827

Yaowu Xu's avatar
Yaowu Xu committed
828 829 830 831 832 833
#if CONFIG_MULTITHREAD
    if (pthread_mutex_init(&priv->buffer_pool->pool_mutex, NULL)) {
      return VPX_CODEC_MEM_ERROR;
    }
#endif

John Koleszar's avatar
John Koleszar committed
834
    if (ctx->config.enc) {
835
      // Update the reference to the config structure to an internal copy.
836 837
      priv->cfg = *ctx->config.enc;
      ctx->config.enc = &priv->cfg;
John Koleszar's avatar
John Koleszar committed
838
    }
839