16fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org/*
26fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
36fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *
46fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  Use of this source code is governed by a BSD-style license
56fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  that can be found in the LICENSE file in the root of the source
66fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  tree. An additional intellectual property rights grant can be found
76fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  in the file PATENTS.  All contributing project authors may
86fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  be found in the AUTHORS file in the root of the source tree.
96fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org */
106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
11ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#include <stdlib.h>
12ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#include <string.h>
136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vpx/vpx_codec.h"
156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vpx/internal/vpx_codec_internal.h"
16ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#include "./vpx_version.h"
17693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com#include "vp9/encoder/vp9_encoder.h"
186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vpx/vp8cx.h"
196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vp9/encoder/vp9_firstpass.h"
203f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org#include "vp9/vp9_iface_common.h"
216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2210a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.orgstruct vp9_extracfg {
236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  struct vpx_codec_pkt_list *pkt_list;
2493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  int                         cpu_used;  // available cpu percentage in 1/16
25ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  unsigned int                enable_auto_alt_ref;
266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned int                noise_sensitivity;
27dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  unsigned int                sharpness;
286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned int                static_thresh;
293f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  unsigned int                tile_columns;
303f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  unsigned int                tile_rows;
31ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  unsigned int                arnr_max_frames;
32ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  unsigned int                arnr_strength;
339a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org  unsigned int                arnr_type;
346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vp8e_tuning                 tuning;
3593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  unsigned int                cq_level;  // constrained quality level
366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned int                rc_max_intra_bitrate_pct;
376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned int                lossless;
383f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  unsigned int                frame_parallel_decoding_mode;
3993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  AQ_MODE                     aq_mode;
4093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  unsigned int                frame_periodic_boost;
41693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  BIT_DEPTH                   bit_depth;
426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org};
436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstruct extraconfig_map {
457765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  unsigned int usage;
4610a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  struct vp9_extracfg cfg;
476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org};
486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstatic const struct extraconfig_map extracfg_map[] = {
506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  {
516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    0,
52ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org    { // NOLINT
536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      NULL,
5493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                          // cpu_used
5593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      1,                          // enable_auto_alt_ref
5693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                          // noise_sensitivity
5793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                          // sharpness
5893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                          // static_thresh
5993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                          // tile_columns
6093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                          // tile_rows
6193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      7,                          // arnr_max_frames
6293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      5,                          // arnr_strength
639a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org      3,                          // arnr_type
6493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      VP8_TUNE_PSNR,              // tuning
6593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      10,                         // cq_level
6693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                          // rc_max_intra_bitrate_pct
6793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                          // lossless
6893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                          // frame_parallel_decoding_mode
6993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      NO_AQ,                      // aq_mode
7093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                          // frame_periodic_delta_q
71693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      BITS_8,                     // Bit depth
726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org};
756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstruct vpx_codec_alg_priv {
776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vpx_codec_priv_t        base;
786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vpx_codec_enc_cfg_t     cfg;
7993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  struct vp9_extracfg     extra_cfg;
80693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  VP9EncoderConfig        oxcf;
8193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  VP9_COMP               *cpi;
826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned char          *cx_data;
83d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  size_t                  cx_data_sz;
846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned char          *pending_cx_data;
85d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  size_t                  pending_cx_data_sz;
863f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  int                     pending_frame_count;
87d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  size_t                  pending_frame_sizes[8];
88d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  size_t                  pending_frame_magnitude;
896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vpx_image_t             preview_img;
906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vp8_postproc_cfg_t      preview_ppcfg;
91ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  vpx_codec_pkt_list_decl(64) pkt_list;
926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned int                fixed_kf_cntr;
936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org};
946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
95ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.orgstatic VP9_REFFRAME ref_frame_to_vp9_reframe(vpx_ref_frame_type_t frame) {
96f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org  switch (frame) {
97f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org    case VP8_LAST_FRAME:
98f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org      return VP9_LAST_FLAG;
99f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org    case VP8_GOLD_FRAME:
100f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org      return VP9_GOLD_FLAG;
101f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org    case VP8_ALTR_FRAME:
102f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org      return VP9_ALT_FLAG;
103f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org  }
104d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  assert(0 && "Invalid Reference Frame");
105f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org  return VP9_LAST_FLAG;
106f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org}
1076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
10893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx,
10993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    const struct vpx_internal_error_info *error) {
11093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const vpx_codec_err_t res = error->error_code;
1116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
11293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (res != VPX_CODEC_OK)
11393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    ctx->base.err_detail = error->has_detail ? error->detail : NULL;
1146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return res;
1166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
1176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#undef ERROR
1206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#define ERROR(str) do {\
1216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ctx->base.err_detail = str;\
1226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return VPX_CODEC_INVALID_PARAM;\
123ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  } while (0)
1246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
125ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#define RANGE_CHECK(p, memb, lo, hi) do {\
126ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org    if (!(((p)->memb == lo || (p)->memb > (lo)) && (p)->memb <= hi)) \
1276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ERROR(#memb " out of range ["#lo".."#hi"]");\
128ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  } while (0)
1296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
130ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#define RANGE_CHECK_HI(p, memb, hi) do {\
131ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org    if (!((p)->memb <= (hi))) \
1326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ERROR(#memb " out of range [.."#hi"]");\
133ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  } while (0)
1346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
135ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#define RANGE_CHECK_LO(p, memb, lo) do {\
136ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org    if (!((p)->memb >= (lo))) \
1376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ERROR(#memb " out of range ["#lo"..]");\
138ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  } while (0)
1396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
140ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#define RANGE_CHECK_BOOL(p, memb) do {\
141ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org    if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean");\
142ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  } while (0)
1436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
14493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
1456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                       const vpx_codec_enc_cfg_t *cfg,
14693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                       const struct vp9_extracfg *extra_cfg) {
14793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK(cfg, g_w,                   1, 65535);  // 16 bits available
14893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK(cfg, g_h,                   1, 65535);  // 16 bits available
1496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK(cfg, g_timebase.den,        1, 1000000000);
1506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK(cfg, g_timebase.num,        1, cfg->g_timebase.den);
1516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK_HI(cfg, g_profile,          3);
1526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK_HI(cfg, rc_max_quantizer,   63);
1546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK_HI(cfg, rc_min_quantizer,   cfg->rc_max_quantizer);
15593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK_BOOL(extra_cfg, lossless);
15693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK(extra_cfg, aq_mode,           0, AQ_MODE_COUNT - 1);
15793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK(extra_cfg, frame_periodic_boost, 0, 1);
1586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK_HI(cfg, g_threads,          64);
1596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK_HI(cfg, g_lag_in_frames,    MAX_LAG_BUFFERS);
160f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org  RANGE_CHECK(cfg, rc_end_usage,          VPX_VBR, VPX_Q);
1616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK_HI(cfg, rc_undershoot_pct,  1000);
1626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK_HI(cfg, rc_overshoot_pct,   1000);
1636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
1646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK(cfg, kf_mode,               VPX_KF_DISABLED, VPX_KF_AUTO);
1656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK_BOOL(cfg,                   rc_resize_allowed);
1666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK_HI(cfg, rc_dropframe_thresh,   100);
1676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK_HI(cfg, rc_resize_up_thresh,   100);
1686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100);
1696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  RANGE_CHECK(cfg,        g_pass,         VPX_RC_ONE_PASS, VPX_RC_LAST_PASS);
1706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
171693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  if (cfg->rc_resize_allowed == 1) {
172693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    RANGE_CHECK(cfg, rc_scaled_width, 1, cfg->g_w);
173693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    RANGE_CHECK(cfg, rc_scaled_height, 1, cfg->g_h);
174693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  }
175693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
17693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK(cfg, ss_number_layers, 1, VPX_SS_MAX_LAYERS);
17776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  RANGE_CHECK(cfg, ts_number_layers, 1, VPX_TS_MAX_LAYERS);
17876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (cfg->ts_number_layers > 1) {
17976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    unsigned int i;
18093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    for (i = 1; i < cfg->ts_number_layers; ++i)
18193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      if (cfg->ts_target_bitrate[i] < cfg->ts_target_bitrate[i - 1])
18276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        ERROR("ts_target_bitrate entries are not increasing");
18393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
18493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    RANGE_CHECK(cfg, ts_rate_decimator[cfg->ts_number_layers - 1], 1, 1);
18593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    for (i = cfg->ts_number_layers - 2; i > 0; --i)
18693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      if (cfg->ts_rate_decimator[i - 1] != 2 * cfg->ts_rate_decimator[i])
18776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        ERROR("ts_rate_decimator factors are not powers of 2");
18876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
18976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
190693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  // VP9 does not support a lower bound on the keyframe interval in
19193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // automatic keyframe placement mode.
19293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (cfg->kf_mode != VPX_KF_DISABLED &&
19393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      cfg->kf_min_dist != cfg->kf_max_dist &&
19493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      cfg->kf_min_dist > 0)
1956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ERROR("kf_min_dist not supported in auto mode, use 0 "
1966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          "or kf_max_dist instead.");
1976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
19893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK_BOOL(extra_cfg,  enable_auto_alt_ref);
19993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK(extra_cfg, cpu_used, -16, 16);
20093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6);
20193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK(extra_cfg, tile_columns, 0, 6);
20293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK(extra_cfg, tile_rows, 0, 2);
20393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK_HI(extra_cfg, sharpness, 7);
20493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK(extra_cfg, arnr_max_frames, 0, 15);
20593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);
2069a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org  RANGE_CHECK(extra_cfg, arnr_type, 1, 3);
20793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RANGE_CHECK(extra_cfg, cq_level, 0, 63);
2086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
209d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // TODO(yaowu): remove this when ssim tuning is implemented for vp9
21093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (extra_cfg->tuning == VP8_TUNE_SSIM)
211d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      ERROR("Option --tune=ssim is not currently supported in VP9.");
212d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
2136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (cfg->g_pass == VPX_RC_LAST_PASS) {
2146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    size_t           packet_sz = sizeof(FIRSTPASS_STATS);
2156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    int              n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
21693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    const FIRSTPASS_STATS *stats;
2176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
21876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (cfg->rc_twopass_stats_in.buf == NULL)
2196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ERROR("rc_twopass_stats_in.buf not set.");
2206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (cfg->rc_twopass_stats_in.sz % packet_sz)
2226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ERROR("rc_twopass_stats_in.sz indicates truncated packet.");
2236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
22493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    if (cfg->ss_number_layers > 1) {
22593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      int i;
22693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      unsigned int n_packets_per_layer[VPX_SS_MAX_LAYERS] = {0};
22793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
22893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      stats = cfg->rc_twopass_stats_in.buf;
22993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      for (i = 0; i < n_packets; ++i) {
23093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        const int layer_id = (int)stats[i].spatial_layer_id;
23193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        if (layer_id >= 0 && layer_id < (int)cfg->ss_number_layers) {
23293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          ++n_packets_per_layer[layer_id];
23393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        }
23493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      }
23593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
23693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      for (i = 0; i < (int)cfg->ss_number_layers; ++i) {
23793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        unsigned int layer_id;
23893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        if (n_packets_per_layer[i] < 2) {
23993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          ERROR("rc_twopass_stats_in requires at least two packets for each "
24093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                "layer.");
24193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        }
24293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
24393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        stats = (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf +
24493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                n_packets - cfg->ss_number_layers + i;
24593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        layer_id = (int)stats->spatial_layer_id;
24693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
24793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        if (layer_id >= cfg->ss_number_layers
2487765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org            ||(unsigned int)(stats->count + 0.5) !=
2497765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org               n_packets_per_layer[layer_id] - 1)
25093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          ERROR("rc_twopass_stats_in missing EOS stats packet");
25193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      }
25293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    } else {
25393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)
25493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        ERROR("rc_twopass_stats_in requires at least two packets.");
2556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
25693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      stats =
25793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1;
2586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
25993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      if ((int)(stats->count + 0.5) != n_packets - 1)
26093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        ERROR("rc_twopass_stats_in missing EOS stats packet");
26193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    }
2626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
263693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
264693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      extra_cfg->bit_depth > BITS_8)
265693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    ERROR("High bit-depth not supported in profile < 2");
266693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  if (cfg->g_profile > (unsigned int)PROFILE_1 &&
267693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      extra_cfg->bit_depth == BITS_8)
268693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    ERROR("Bit-depth 8 not supported in profile > 1");
2696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return VPX_CODEC_OK;
2716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
2726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstatic vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
27593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                    const vpx_image_t *img) {
2766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  switch (img->fmt) {
2776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    case VPX_IMG_FMT_YV12:
2786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    case VPX_IMG_FMT_I420:
27910a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org    case VPX_IMG_FMT_I422:
28010a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org    case VPX_IMG_FMT_I444:
2816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
2826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    default:
28310a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org      ERROR("Invalid image format. Only YV12, I420, I422, I444 images are "
28410a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org            "supported.");
2856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
2866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
28793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (img->d_w != ctx->cfg.g_w || img->d_h != ctx->cfg.g_h)
2886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ERROR("Image size must match encoder init configuration size");
2896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return VPX_CODEC_OK;
2916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
2926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
294693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.comstatic vpx_codec_err_t set_encoder_config(
295693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    VP9EncoderConfig *oxcf,
296693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    const vpx_codec_enc_cfg_t *cfg,
297693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    const struct vp9_extracfg *extra_cfg) {
298693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  oxcf->profile = cfg->g_profile;
29993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->width   = cfg->g_w;
30093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->height  = cfg->g_h;
301693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  oxcf->bit_depth = extra_cfg->bit_depth;
30293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // guess a frame rate if out of whack, use 30
30393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num;
30493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (oxcf->framerate > 180)
30547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    oxcf->framerate = 30;
3066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
30793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  switch (cfg->g_pass) {
3086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    case VPX_RC_ONE_PASS:
309693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      oxcf->mode = ONE_PASS_GOOD;
3106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
3116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    case VPX_RC_FIRST_PASS:
312693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      oxcf->mode = TWO_PASS_FIRST;
3136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
3146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    case VPX_RC_LAST_PASS:
315693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      oxcf->mode = TWO_PASS_SECOND_BEST;
3166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
3176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
3186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
31993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->lag_in_frames = cfg->g_pass == VPX_RC_FIRST_PASS ? 0
32093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                                         : cfg->g_lag_in_frames;
3216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
322693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  oxcf->rc_mode = RC_MODE_VBR;
32393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (cfg->rc_end_usage == VPX_CQ)
324693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    oxcf->rc_mode = RC_MODE_CONSTRAINED_QUALITY;
32593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  else if (cfg->rc_end_usage == VPX_Q)
326693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    oxcf->rc_mode = RC_MODE_CONSTANT_QUALITY;
32793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  else if (cfg->rc_end_usage == VPX_CBR)
328693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    oxcf->rc_mode = RC_MODE_CBR;
3296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
33093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->target_bandwidth         = cfg->rc_target_bitrate;
33193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct;
3326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
333693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  oxcf->best_allowed_q  = vp9_quantizer_to_qindex(cfg->rc_min_quantizer);
334693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  oxcf->worst_allowed_q = vp9_quantizer_to_qindex(cfg->rc_max_quantizer);
335693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  oxcf->cq_level        = vp9_quantizer_to_qindex(extra_cfg->cq_level);
3366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  oxcf->fixed_q = -1;
3376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
33893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->under_shoot_pct         = cfg->rc_undershoot_pct;
33993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->over_shoot_pct          = cfg->rc_overshoot_pct;
34093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
341693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  oxcf->allow_spatial_resampling = cfg->rc_resize_allowed;
342693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  oxcf->scaled_frame_width       = cfg->rc_scaled_width;
343693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  oxcf->scaled_frame_height      = cfg->rc_scaled_height;
344693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
34593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->maximum_buffer_size     = cfg->rc_buf_sz;
34693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->starting_buffer_level   = cfg->rc_buf_initial_sz;
34793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->optimal_buffer_level    = cfg->rc_buf_optimal_sz;
3486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
34993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->drop_frames_water_mark   = cfg->rc_dropframe_thresh;
3506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
35193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->two_pass_vbrbias         = cfg->rc_2pass_vbr_bias_pct;
35293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->two_pass_vbrmin_section  = cfg->rc_2pass_vbr_minsection_pct;
35393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->two_pass_vbrmax_section  = cfg->rc_2pass_vbr_maxsection_pct;
3540e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org
35593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->auto_key               = cfg->kf_mode == VPX_KF_AUTO &&
35693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                 cfg->kf_min_dist != cfg->kf_max_dist;
3576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
35893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->key_freq               = cfg->kf_max_dist;
3596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
360693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  oxcf->speed                  =  clamp(abs(extra_cfg->cpu_used), 0, 7);
36193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->encode_breakout        =  extra_cfg->static_thresh;
36293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->play_alternate         =  extra_cfg->enable_auto_alt_ref;
36393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->noise_sensitivity      =  extra_cfg->noise_sensitivity;
36493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->sharpness              =  extra_cfg->sharpness;
3656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
36693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->two_pass_stats_in      =  cfg->rc_twopass_stats_in;
36793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->output_pkt_list        =  extra_cfg->pkt_list;
3686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
36993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->arnr_max_frames = extra_cfg->arnr_max_frames;
37093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->arnr_strength   = extra_cfg->arnr_strength;
3719a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org  oxcf->arnr_type       = extra_cfg->arnr_type;
3726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
37393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->tuning = extra_cfg->tuning;
3746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
37593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->tile_columns = extra_cfg->tile_columns;
37693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->tile_rows    = extra_cfg->tile_rows;
3773f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org
37893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->lossless = extra_cfg->lossless;
3796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
38093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->error_resilient_mode         = cfg->g_error_resilient;
38193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode;
382f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org
38393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->aq_mode = extra_cfg->aq_mode;
384d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
38593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->frame_periodic_boost =  extra_cfg->frame_periodic_boost;
38693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
38793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->ss_number_layers = cfg->ss_number_layers;
38876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
389411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  if (oxcf->ss_number_layers > 1) {
39093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    vp9_copy(oxcf->ss_target_bitrate, cfg->ss_target_bitrate);
391411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  } else if (oxcf->ss_number_layers == 1) {
392411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    oxcf->ss_target_bitrate[0] = (int)oxcf->target_bandwidth;
393411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  }
394411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org
39593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  oxcf->ts_number_layers = cfg->ts_number_layers;
39676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
39776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (oxcf->ts_number_layers > 1) {
39893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    vp9_copy(oxcf->ts_target_bitrate, cfg->ts_target_bitrate);
39993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    vp9_copy(oxcf->ts_rate_decimator, cfg->ts_rate_decimator);
40076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else if (oxcf->ts_number_layers == 1) {
401411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    oxcf->ts_target_bitrate[0] = (int)oxcf->target_bandwidth;
40276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    oxcf->ts_rate_decimator[0] = 1;
40376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
40476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
4056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /*
4063f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("Current VP9 Settings: \n");
4073f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
4083f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity);
409dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  printf("sharpness: %d\n",    oxcf->sharpness);
4103f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("cpu_used: %d\n",  oxcf->cpu_used);
411dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  printf("Mode: %d\n",     oxcf->mode);
4123f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("auto_key: %d\n",  oxcf->auto_key);
4133f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("key_freq: %d\n", oxcf->key_freq);
4143f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("end_usage: %d\n", oxcf->end_usage);
4153f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct);
4163f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct);
4173f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level);
4183f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("optimal_buffer_level: %d\n",  oxcf->optimal_buffer_level);
4193f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size);
4203f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("fixed_q: %d\n",  oxcf->fixed_q);
4213f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q);
4223f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("best_allowed_q: %d\n", oxcf->best_allowed_q);
423693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  printf("allow_spatial_resampling: %d\n", oxcf->allow_spatial_resampling);
424693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  printf("scaled_frame_width: %d\n", oxcf->scaled_frame_width);
425693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  printf("scaled_frame_height: %d\n", oxcf->scaled_frame_height);
4263f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("two_pass_vbrbias: %d\n",  oxcf->two_pass_vbrbias);
4273f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section);
4283f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section);
4293f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("lag_in_frames: %d\n", oxcf->lag_in_frames);
4303f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("play_alternate: %d\n", oxcf->play_alternate);
4313f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("Version: %d\n", oxcf->Version);
4323f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("encode_breakout: %d\n", oxcf->encode_breakout);
4333f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("error resilient: %d\n", oxcf->error_resilient_mode);
4343f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  printf("frame parallel detokenization: %d\n",
4353f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org         oxcf->frame_parallel_decoding_mode);
4366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  */
4376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return VPX_CODEC_OK;
4386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
4396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
44093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t encoder_set_config(vpx_codec_alg_priv_t *ctx,
44193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                          const vpx_codec_enc_cfg_t  *cfg) {
4426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vpx_codec_err_t res;
4436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
44493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h)
4456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ERROR("Cannot change width or height after initialization");
4466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
44793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Prevent increasing lag_in_frames. This check is stricter than it needs
44893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // to be -- the limit is not increasing past the first lag_in_frames
44993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // value, but we don't track the initial config, only the last successful
45093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // config.
45193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames)
4526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ERROR("Cannot increase lag_in_frames");
4536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
45493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  res = validate_config(ctx, cfg, &ctx->extra_cfg);
4556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
45676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (res == VPX_CODEC_OK) {
4576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ctx->cfg = *cfg;
45893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
4596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    vp9_change_config(ctx->cpi, &ctx->oxcf);
4606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
4616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return res;
4636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
4646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
46593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_get_param(vpx_codec_alg_priv_t *ctx, int ctrl_id,
46693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                 va_list args) {
4676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  void *arg = va_arg(args, void *);
4686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#define MAP(id, var) case id: *(RECAST(id, arg)) = var; break
4706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
47193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (arg == NULL)
47293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    return VPX_CODEC_INVALID_PARAM;
4736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  switch (ctrl_id) {
47593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP8E_GET_LAST_QUANTIZER, vp9_get_quantizer(ctx->cpi));
47693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP8E_GET_LAST_QUANTIZER_64,
477693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com        vp9_qindex_to_quantizer(vp9_get_quantizer(ctx->cpi)));
4786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
4796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return VPX_CODEC_OK;
4816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#undef MAP
4826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
4836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
48593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_set_param(vpx_codec_alg_priv_t *ctx, int ctrl_id,
48693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                      va_list args) {
48793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  vpx_codec_err_t res = VPX_CODEC_OK;
48893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  struct vp9_extracfg extra_cfg = ctx->extra_cfg;
4896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#define MAP(id, var) case id: var = CAST(id, args); break;
4916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  switch (ctrl_id) {
49393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP8E_SET_CPUUSED,                 extra_cfg.cpu_used);
49493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP8E_SET_ENABLEAUTOALTREF,        extra_cfg.enable_auto_alt_ref);
49593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP8E_SET_NOISE_SENSITIVITY,       extra_cfg.noise_sensitivity);
49693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP8E_SET_SHARPNESS,               extra_cfg.sharpness);
49793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP8E_SET_STATIC_THRESHOLD,        extra_cfg.static_thresh);
49893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP9E_SET_TILE_COLUMNS,            extra_cfg.tile_columns);
49993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP9E_SET_TILE_ROWS,               extra_cfg.tile_rows);
50093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP8E_SET_ARNR_MAXFRAMES,          extra_cfg.arnr_max_frames);
50193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP8E_SET_ARNR_STRENGTH,           extra_cfg.arnr_strength);
5029a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org    MAP(VP8E_SET_ARNR_TYPE,               extra_cfg.arnr_type);
50393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP8E_SET_TUNING,                  extra_cfg.tuning);
50493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP8E_SET_CQ_LEVEL,                extra_cfg.cq_level);
50593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP8E_SET_MAX_INTRA_BITRATE_PCT,   extra_cfg.rc_max_intra_bitrate_pct);
50693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP9E_SET_LOSSLESS,                extra_cfg.lossless);
50793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP9E_SET_FRAME_PARALLEL_DECODING,
50893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        extra_cfg.frame_parallel_decoding_mode);
50993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP9E_SET_AQ_MODE,                 extra_cfg.aq_mode);
51093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    MAP(VP9E_SET_FRAME_PERIODIC_BOOST,   extra_cfg.frame_periodic_boost);
5116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
5126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
51393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  res = validate_config(ctx, &ctx->cfg, &extra_cfg);
5146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
51576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (res == VPX_CODEC_OK) {
51693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    ctx->extra_cfg = extra_cfg;
51793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
5186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    vp9_change_config(ctx->cpi, &ctx->oxcf);
5196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
5206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
5216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return res;
5226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#undef MAP
5236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
5246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
525693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.comstatic vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx,
526693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                                    vpx_codec_priv_enc_mr_cfg_t *data) {
52793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  vpx_codec_err_t res = VPX_CODEC_OK;
5286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
52976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (ctx->priv == NULL) {
53093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    int i;
53193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    vpx_codec_enc_cfg_t *cfg;
53293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    struct vpx_codec_alg_priv *priv = calloc(1, sizeof(*priv));
5336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
534693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    if (priv == NULL)
535693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      return VPX_CODEC_MEM_ERROR;
5366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
5376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ctx->priv = &priv->base;
5386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ctx->priv->sz = sizeof(*ctx->priv);
5396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ctx->priv->iface = ctx->iface;
5406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ctx->priv->alg_priv = priv;
5416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ctx->priv->init_flags = ctx->init_flags;
5426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ctx->priv->enc.total_encoders = 1;
5436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
5446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (ctx->config.enc) {
545693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      // Update the reference to the config structure to an internal copy.
5466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ctx->priv->alg_priv->cfg = *ctx->config.enc;
5476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ctx->config.enc = &ctx->priv->alg_priv->cfg;
5486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
5496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
55093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    cfg = &ctx->priv->alg_priv->cfg;
5516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
55293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    // Select the extra vp6 configuration table based on the current
55393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    // usage value. If the current usage value isn't found, use the
55493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    // values for usage case 0.
5556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    for (i = 0;
5566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org         extracfg_map[i].usage && extracfg_map[i].usage != cfg->g_usage;
55793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org         ++i) {}
5586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
55993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    priv->extra_cfg = extracfg_map[i].cfg;
56093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    priv->extra_cfg.pkt_list = &priv->pkt_list.head;
561693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com     // Maximum buffer size approximated based on having multiple ARF.
56210a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org    priv->cx_data_sz = priv->cfg.g_w * priv->cfg.g_h * 3 / 2 * 8;
5636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
564693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    if (priv->cx_data_sz < 4096)
565693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      priv->cx_data_sz = 4096;
5666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
56793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    priv->cx_data = (unsigned char *)malloc(priv->cx_data_sz);
56893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    if (priv->cx_data == NULL)
56993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      return VPX_CODEC_MEM_ERROR;
5706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
5716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    vp9_initialize_enc();
5726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
57393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    res = validate_config(priv, &priv->cfg, &priv->extra_cfg);
5746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
57576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (res == VPX_CODEC_OK) {
57693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      VP9_COMP *cpi;
57793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      set_encoder_config(&ctx->priv->alg_priv->oxcf,
578693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                         &ctx->priv->alg_priv->cfg,
579693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                         &ctx->priv->alg_priv->extra_cfg);
58093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      cpi = vp9_create_compressor(&ctx->priv->alg_priv->oxcf);
58193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      if (cpi == NULL)
5826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        res = VPX_CODEC_MEM_ERROR;
5836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      else
58493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        ctx->priv->alg_priv->cpi = cpi;
5856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
5866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
5876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
5886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return res;
5896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
5906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
59193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t encoder_destroy(vpx_codec_alg_priv_t *ctx) {
5926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  free(ctx->cx_data);
59393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  vp9_remove_compressor(ctx->cpi);
5946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  free(ctx);
5956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return VPX_CODEC_OK;
5966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
5976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
5986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstatic void pick_quickcompress_mode(vpx_codec_alg_priv_t  *ctx,
59993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                    unsigned long duration,
60093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                    unsigned long deadline) {
60193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Use best quality mode if no deadline is given.
602693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  MODE new_qc = ONE_PASS_BEST;
60376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
60476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (deadline) {
60593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    // Convert duration parameter from stream timebase to microseconds
60693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    const uint64_t duration_us = (uint64_t)duration * 1000000 *
60793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                               (uint64_t)ctx->cfg.g_timebase.num /
60893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                               (uint64_t)ctx->cfg.g_timebase.den;
60993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
61093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    // If the deadline is more that the duration this frame is to be shown,
61193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    // use good quality mode. Otherwise use realtime mode.
612693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    new_qc = (deadline > duration_us) ? ONE_PASS_GOOD : REALTIME;
61376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
6146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
6156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (ctx->cfg.g_pass == VPX_RC_FIRST_PASS)
616693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    new_qc = TWO_PASS_FIRST;
6176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  else if (ctx->cfg.g_pass == VPX_RC_LAST_PASS)
618693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    new_qc = (new_qc == ONE_PASS_BEST) ? TWO_PASS_SECOND_BEST
619693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                                          : TWO_PASS_SECOND_GOOD;
6206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
621dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (ctx->oxcf.mode != new_qc) {
622dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    ctx->oxcf.mode = new_qc;
6236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    vp9_change_config(ctx->cpi, &ctx->oxcf);
6246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
6256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
6266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
627693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com// Turn on to test if supplemental superframe data breaks decoding
628693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com// #define TEST_SUPPLEMENTAL_SUPERFRAME_DATA
6293f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.orgstatic int write_superframe_index(vpx_codec_alg_priv_t *ctx) {
6303f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  uint8_t marker = 0xc0;
6319c920af5cd2f78ab30bb06f01f4a4d9d30d5c92bfgalligan@chromium.org  unsigned int mask;
6329c920af5cd2f78ab30bb06f01f4a4d9d30d5c92bfgalligan@chromium.org  int mag, index_sz;
6333f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org
6343f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  assert(ctx->pending_frame_count);
6353f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  assert(ctx->pending_frame_count <= 8);
6363f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org
63793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Add the number of frames to the marker byte
6383f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  marker |= ctx->pending_frame_count - 1;
6393f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org
64093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Choose the magnitude
6413f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  for (mag = 0, mask = 0xff; mag < 4; mag++) {
6423f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org    if (ctx->pending_frame_magnitude < mask)
6433f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org      break;
6443f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org    mask <<= 8;
6453f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org    mask |= 0xff;
6463f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  }
6473f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  marker |= mag << 3;
6483f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org
64993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Write the index
6503f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  index_sz = 2 + (mag + 1) * ctx->pending_frame_count;
6513f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  if (ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz) {
6523f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org    uint8_t *x = ctx->pending_cx_data + ctx->pending_cx_data_sz;
6533f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org    int i, j;
654693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com#ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA
655693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    uint8_t marker_test = 0xc0;
656693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    int mag_test = 2;     // 1 - 4
657693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    int frames_test = 4;  // 1 - 8
658693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    int index_sz_test = 2 + mag_test * frames_test;
659693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    marker_test |= frames_test - 1;
660693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    marker_test |= (mag_test - 1) << 3;
661693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    *x++ = marker_test;
662693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    for (i = 0; i < mag_test * frames_test; ++i)
663693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      *x++ = 0;  // fill up with arbitrary data
664693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    *x++ = marker_test;
665693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    ctx->pending_cx_data_sz += index_sz_test;
666693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    printf("Added supplemental superframe data\n");
667693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com#endif
6683f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org
6693f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org    *x++ = marker;
6703f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org    for (i = 0; i < ctx->pending_frame_count; i++) {
671411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org      unsigned int this_sz = (unsigned int)ctx->pending_frame_sizes[i];
6723f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org
6733f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org      for (j = 0; j <= mag; j++) {
6743f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org        *x++ = this_sz & 0xff;
6753f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org        this_sz >>= 8;
6763f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org      }
6773f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org    }
6783f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org    *x++ = marker;
6793f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org    ctx->pending_cx_data_sz += index_sz;
680693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com#ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA
681693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    index_sz += index_sz_test;
682693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com#endif
6833f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  }
6843f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  return index_sz;
6853f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org}
6863f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org
68793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t  *ctx,
68893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                      const vpx_image_t *img,
68993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                      vpx_codec_pts_t pts,
69093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                      unsigned long duration,
69193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                      vpx_enc_frame_flags_t flags,
69293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                      unsigned long deadline) {
6936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vpx_codec_err_t res = VPX_CODEC_OK;
6946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
6956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (img)
6966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    res = validate_img(ctx, img);
6976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
6986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  pick_quickcompress_mode(ctx, duration, deadline);
6996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vpx_codec_pkt_list_init(&ctx->pkt_list);
7006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
70193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Handle Flags
70293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (((flags & VP8_EFLAG_NO_UPD_GF) && (flags & VP8_EFLAG_FORCE_GF)) ||
70393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org       ((flags & VP8_EFLAG_NO_UPD_ARF) && (flags & VP8_EFLAG_FORCE_ARF))) {
7046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ctx->base.err_detail = "Conflicting flags.";
7056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return VPX_CODEC_INVALID_PARAM;
7066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
7076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
70893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (flags & (VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF |
70993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org               VP8_EFLAG_NO_REF_ARF)) {
7106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    int ref = 7;
7116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (flags & VP8_EFLAG_NO_REF_LAST)
7136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ref ^= VP9_LAST_FLAG;
7146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (flags & VP8_EFLAG_NO_REF_GF)
7166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ref ^= VP9_GOLD_FLAG;
7176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (flags & VP8_EFLAG_NO_REF_ARF)
7196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ref ^= VP9_ALT_FLAG;
7206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    vp9_use_as_reference(ctx->cpi, ref);
7226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
7236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
72493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (flags & (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
72593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org               VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_FORCE_GF |
72693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org               VP8_EFLAG_FORCE_ARF)) {
7276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    int upd = 7;
7286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (flags & VP8_EFLAG_NO_UPD_LAST)
7306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      upd ^= VP9_LAST_FLAG;
7316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (flags & VP8_EFLAG_NO_UPD_GF)
7336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      upd ^= VP9_GOLD_FLAG;
7346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (flags & VP8_EFLAG_NO_UPD_ARF)
7366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      upd ^= VP9_ALT_FLAG;
7376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    vp9_update_reference(ctx->cpi, upd);
7396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
7406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (flags & VP8_EFLAG_NO_UPD_ENTROPY) {
7426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    vp9_update_entropy(ctx->cpi, 0);
7436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
7446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
74593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Handle fixed keyframe intervals
74693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (ctx->cfg.kf_mode == VPX_KF_AUTO &&
74793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) {
7486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) {
7496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      flags |= VPX_EFLAG_FORCE_KF;
7506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ctx->fixed_kf_cntr = 1;
7516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
7526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
7536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
75493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Initialize the encoder instance on the first frame.
75576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (res == VPX_CODEC_OK && ctx->cpi != NULL) {
7566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    unsigned int lib_flags;
7576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    YV12_BUFFER_CONFIG sd;
7586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    int64_t dst_time_stamp, dst_end_time_stamp;
759d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    size_t size, cx_data_sz;
7606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    unsigned char *cx_data;
7616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
76293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    // Set up internal flags
7636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (ctx->base.init_flags & VPX_CODEC_USE_PSNR)
7646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ((VP9_COMP *)ctx->cpi)->b_calculate_psnr = 1;
7656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
76693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    // Convert API flags to internal codec lib flags
7676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    lib_flags = (flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
7686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
76993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    /* vp9 use 10,000,000 ticks/second as time stamp */
77093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    dst_time_stamp = (pts * 10000000 * ctx->cfg.g_timebase.num)
771ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                     / ctx->cfg.g_timebase.den;
772ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org    dst_end_time_stamp = (pts + duration) * 10000000 * ctx->cfg.g_timebase.num /
773ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                         ctx->cfg.g_timebase.den;
7746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (img != NULL) {
7766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      res = image2yuvconfig(img, &sd);
7776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7783f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org      if (vp9_receive_raw_frame(ctx->cpi, lib_flags,
7796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                &sd, dst_time_stamp, dst_end_time_stamp)) {
7806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        VP9_COMP *cpi = (VP9_COMP *)ctx->cpi;
7816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        res = update_error_state(ctx, &cpi->common.error);
7826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      }
7836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
7846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    cx_data = ctx->cx_data;
7866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    cx_data_sz = ctx->cx_data_sz;
7876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    lib_flags = 0;
7886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    /* Any pending invisible frames? */
7906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (ctx->pending_cx_data) {
7916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz);
7926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ctx->pending_cx_data = cx_data;
7936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      cx_data += ctx->pending_cx_data_sz;
7946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      cx_data_sz -= ctx->pending_cx_data_sz;
7956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
7966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      /* TODO: this is a minimal check, the underlying codec doesn't respect
7976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org       * the buffer size anyway.
7986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org       */
7996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      if (cx_data_sz < ctx->cx_data_sz / 2) {
8006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        ctx->base.err_detail = "Compressed data buffer too small";
8016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        return VPX_CODEC_ERROR;
8026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      }
8036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
8046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
8056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    while (cx_data_sz >= ctx->cx_data_sz / 2 &&
8066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org           -1 != vp9_get_compressed_data(ctx->cpi, &lib_flags, &size,
8076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                         cx_data, &dst_time_stamp,
8086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                         &dst_end_time_stamp, !img)) {
8096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      if (size) {
81093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        vpx_codec_pts_t round, delta;
8116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        vpx_codec_cx_pkt_t pkt;
81293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi;
8136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
81493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        // Pack invisible frames with the next visible frame
81576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        if (cpi->common.show_frame == 0) {
81676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org          if (ctx->pending_cx_data == 0)
8176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            ctx->pending_cx_data = cx_data;
8186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          ctx->pending_cx_data_sz += size;
8193f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org          ctx->pending_frame_sizes[ctx->pending_frame_count++] = size;
8203f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org          ctx->pending_frame_magnitude |= size;
8216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          cx_data += size;
8226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          cx_data_sz -= size;
8236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          continue;
8246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        }
8256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
82693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        // Add the frame packet to the list of returned packets.
8277765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org        round = (vpx_codec_pts_t)10000000 * ctx->cfg.g_timebase.num / 2 - 1;
8286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        delta = (dst_end_time_stamp - dst_time_stamp);
8296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        pkt.kind = VPX_CODEC_CX_FRAME_PKT;
8306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        pkt.data.frame.pts =
8316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          (dst_time_stamp * ctx->cfg.g_timebase.den + round)
8326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          / ctx->cfg.g_timebase.num / 10000000;
8336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        pkt.data.frame.duration = (unsigned long)
8346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          ((delta * ctx->cfg.g_timebase.den + round)
8356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          / ctx->cfg.g_timebase.num / 10000000);
8366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        pkt.data.frame.flags = lib_flags << 16;
8376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
8386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        if (lib_flags & FRAMEFLAGS_KEY)
8396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          pkt.data.frame.flags |= VPX_FRAME_IS_KEY;
8406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
84176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        if (cpi->common.show_frame == 0) {
8426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          pkt.data.frame.flags |= VPX_FRAME_IS_INVISIBLE;
8436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
8446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          // This timestamp should be as close as possible to the
8456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          // prior PTS so that if a decoder uses pts to schedule when
8466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          // to do this, we start right after last frame was decoded.
8476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          // Invisible frames have no duration.
8486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          pkt.data.frame.pts = ((cpi->last_time_stamp_seen
8496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                 * ctx->cfg.g_timebase.den + round)
8506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                / ctx->cfg.g_timebase.num / 10000000) + 1;
8516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          pkt.data.frame.duration = 0;
8526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        }
8536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
8546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        if (cpi->droppable)
8556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          pkt.data.frame.flags |= VPX_FRAME_IS_DROPPABLE;
8566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
85793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        if (ctx->pending_cx_data) {
85893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          ctx->pending_frame_sizes[ctx->pending_frame_count++] = size;
85993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          ctx->pending_frame_magnitude |= size;
86093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          ctx->pending_cx_data_sz += size;
86193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          size += write_superframe_index(ctx);
86293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          pkt.data.frame.buf = ctx->pending_cx_data;
86393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          pkt.data.frame.sz  = ctx->pending_cx_data_sz;
86493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          ctx->pending_cx_data = NULL;
86593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          ctx->pending_cx_data_sz = 0;
86693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          ctx->pending_frame_count = 0;
86793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          ctx->pending_frame_magnitude = 0;
86893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        } else {
86993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          pkt.data.frame.buf = cx_data;
87093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org          pkt.data.frame.sz  = size;
8716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        }
87293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        pkt.data.frame.partition_id = -1;
87393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
87493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        cx_data += size;
87593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        cx_data_sz -= size;
8766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      }
8776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
8786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
8796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
8806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return res;
8816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
8826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
88393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic const vpx_codec_cx_pkt_t *encoder_get_cxdata(vpx_codec_alg_priv_t  *ctx,
88493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                                    vpx_codec_iter_t *iter) {
8856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return vpx_codec_pkt_list_get(&ctx->pkt_list.head, iter);
8866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
8876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
88893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx,
88993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                          int ctr_id, va_list args) {
89093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *);
8916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
89276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (frame != NULL) {
8936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    YV12_BUFFER_CONFIG sd;
8946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
8956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    image2yuvconfig(&frame->img, &sd);
896f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org    vp9_set_reference_enc(ctx->cpi, ref_frame_to_vp9_reframe(frame->frame_type),
897f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org                          &sd);
8986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return VPX_CODEC_OK;
899ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  } else {
9006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return VPX_CODEC_INVALID_PARAM;
901ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  }
9026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
9036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
90493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx,
90593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                           int ctr_id, va_list args) {
90693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *);
9076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
90876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (frame != NULL) {
9096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    YV12_BUFFER_CONFIG sd;
9106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
9116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    image2yuvconfig(&frame->img, &sd);
912f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org    vp9_copy_reference_enc(ctx->cpi,
913f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org                           ref_frame_to_vp9_reframe(frame->frame_type), &sd);
9146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return VPX_CODEC_OK;
915ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  } else {
9166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return VPX_CODEC_INVALID_PARAM;
917ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  }
9186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
9196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
92093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx,
92193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                          int ctr_id, va_list args) {
92276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  vp9_ref_frame_t *frame = va_arg(args, vp9_ref_frame_t *);
9233f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org
92476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (frame != NULL) {
9253f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org    YV12_BUFFER_CONFIG* fb;
9263f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org
92776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    vp9_get_reference_enc(ctx->cpi, frame->idx, &fb);
92876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    yuvconfig2image(&frame->img, fb, NULL);
9293f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org    return VPX_CODEC_OK;
9303f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  } else {
9313f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org    return VPX_CODEC_INVALID_PARAM;
9323f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org  }
9333f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org}
9343f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org
93593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_set_previewpp(vpx_codec_alg_priv_t *ctx,
93693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                          int ctr_id, va_list args) {
937f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org#if CONFIG_VP9_POSTPROC
93876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  vp8_postproc_cfg_t *config = va_arg(args, vp8_postproc_cfg_t *);
9396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  (void)ctr_id;
9406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
94176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (config != NULL) {
94276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    ctx->preview_ppcfg = *config;
9436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return VPX_CODEC_OK;
944ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  } else {
9456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return VPX_CODEC_INVALID_PARAM;
946ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  }
9476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#else
9486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  (void)ctx;
9496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  (void)ctr_id;
9506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  (void)args;
9516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return VPX_CODEC_INCAPABLE;
9526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#endif
9536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
9546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
9556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
95693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_image_t *encoder_get_preview(vpx_codec_alg_priv_t *ctx) {
9576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  YV12_BUFFER_CONFIG sd;
9586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vp9_ppflags_t flags = {0};
9596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
9606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (ctx->preview_ppcfg.post_proc_flag) {
96193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    flags.post_proc_flag   = ctx->preview_ppcfg.post_proc_flag;
96293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    flags.deblocking_level = ctx->preview_ppcfg.deblocking_level;
96393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    flags.noise_level      = ctx->preview_ppcfg.noise_level;
9646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
9656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
96693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (vp9_get_preview_raw_frame(ctx->cpi, &sd, &flags) == 0) {
96710a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org    yuvconfig2image(&ctx->preview_img, &sd, NULL);
9686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return &ctx->preview_img;
969ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  } else {
9706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return NULL;
971ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  }
9726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
9736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
97493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_update_entropy(vpx_codec_alg_priv_t *ctx,
97593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                           int ctr_id, va_list args) {
97693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const int update = va_arg(args, int);
9776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vp9_update_entropy(ctx->cpi, update);
9786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return VPX_CODEC_OK;
9796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
9806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
98193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_update_reference(vpx_codec_alg_priv_t *ctx,
98293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                             int ctr_id, va_list args) {
98393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const int ref_frame_flags = va_arg(args, int);
98493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  vp9_update_reference(ctx->cpi, ref_frame_flags);
9856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return VPX_CODEC_OK;
9866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
9876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
98893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_use_reference(vpx_codec_alg_priv_t *ctx,
98993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                          int ctr_id, va_list args) {
99093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const int reference_flag = va_arg(args, int);
9916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vp9_use_as_reference(ctx->cpi, reference_flag);
9926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return VPX_CODEC_OK;
9936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
9946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
99593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_set_roi_map(vpx_codec_alg_priv_t *ctx,
99693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                        int ctr_id, va_list args) {
997ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  // TODO(yaowu): Need to re-implement and test for VP9.
998ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  return VPX_CODEC_INVALID_PARAM;
9996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
10006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
10016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
100293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_set_active_map(vpx_codec_alg_priv_t *ctx,
100393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                           int ctr_id, va_list args) {
100493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  vpx_active_map_t *const map = va_arg(args, vpx_active_map_t *);
100593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
100693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (map) {
10077765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org    if (!vp9_set_active_map(ctx->cpi, map->active_map,
10087765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org                            (int)map->rows, (int)map->cols))
100993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      return VPX_CODEC_OK;
101093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    else
101193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      return VPX_CODEC_INVALID_PARAM;
101293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  } else {
101393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    return VPX_CODEC_INVALID_PARAM;
101493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
10156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
10166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
101793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_set_scale_mode(vpx_codec_alg_priv_t *ctx,
101893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                           int ctr_id, va_list args) {
101993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  vpx_scaling_mode_t *const mode = va_arg(args, vpx_scaling_mode_t *);
10206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
102193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (mode) {
102293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    const int res = vp9_set_internal_size(ctx->cpi,
102393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                          (VPX_SCALING)mode->h_scaling_mode,
102493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                          (VPX_SCALING)mode->v_scaling_mode);
102576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return (res == 0) ? VPX_CODEC_OK : VPX_CODEC_INVALID_PARAM;
1026ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  } else {
10276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return VPX_CODEC_INVALID_PARAM;
1028ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  }
10296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
10306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
103193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_set_svc(vpx_codec_alg_priv_t *ctx, int ctr_id,
1032d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                                    va_list args) {
1033d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  int data = va_arg(args, int);
103493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const vpx_codec_enc_cfg_t *cfg = &ctx->cfg;
1035d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  vp9_set_svc(ctx->cpi, data);
103693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // CBR or two pass mode for SVC with both temporal and spatial layers
103793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // not yet supported.
103876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (data == 1 &&
103993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      (cfg->rc_end_usage == VPX_CBR ||
104093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org       cfg->g_pass == VPX_RC_FIRST_PASS ||
104193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org       cfg->g_pass == VPX_RC_LAST_PASS) &&
104293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      cfg->ss_number_layers > 1 &&
104393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      cfg->ts_number_layers > 1) {
104476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return VPX_CODEC_INVALID_PARAM;
104576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
104676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return VPX_CODEC_OK;
104776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
104876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
104993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_set_svc_layer_id(vpx_codec_alg_priv_t *ctx,
105076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                                             int ctr_id,
105176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                                             va_list args) {
105293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  vpx_svc_layer_id_t *const data = va_arg(args, vpx_svc_layer_id_t *);
105393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi;
105493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  SVC *const svc = &cpi->svc;
105593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  svc->spatial_layer_id = data->spatial_layer_id;
105693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  svc->temporal_layer_id = data->temporal_layer_id;
105776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Checks on valid layer_id input.
105893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (svc->temporal_layer_id < 0 ||
105993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      svc->temporal_layer_id >= (int)ctx->cfg.ts_number_layers) {
106076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return VPX_CODEC_INVALID_PARAM;
106176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
106293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (svc->spatial_layer_id < 0 ||
106393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      svc->spatial_layer_id >= (int)ctx->cfg.ss_number_layers) {
106476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return VPX_CODEC_INVALID_PARAM;
106576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
1066d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  return VPX_CODEC_OK;
1067f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org}
1068f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org
106993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_err_t ctrl_set_svc_parameters(vpx_codec_alg_priv_t *ctx,
1070d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                                               int ctr_id, va_list args) {
107193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  VP9_COMP *const cpi = ctx->cpi;
107293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  vpx_svc_parameters_t *const params = va_arg(args, vpx_svc_parameters_t *);
1073f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org
107493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (params == NULL)
107593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    return VPX_CODEC_INVALID_PARAM;
1076f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org
107776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  cpi->svc.spatial_layer_id = params->spatial_layer;
107876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  cpi->svc.temporal_layer_id = params->temporal_layer;
1079f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org
108076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  cpi->lst_fb_idx = params->lst_fb_idx;
108176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  cpi->gld_fb_idx = params->gld_fb_idx;
108276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  cpi->alt_fb_idx = params->alt_fb_idx;
1083f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org
108476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (vp9_set_size_literal(ctx->cpi, params->width, params->height) != 0)
1085f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org    return VPX_CODEC_INVALID_PARAM;
1086f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org
108776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  ctx->cfg.rc_max_quantizer = params->max_quantizer;
108876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  ctx->cfg.rc_min_quantizer = params->min_quantizer;
1089d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
109093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
1091d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  vp9_change_config(ctx->cpi, &ctx->oxcf);
1092d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
1093f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org  return VPX_CODEC_OK;
1094f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org}
10956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
109693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
109793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8_COPY_REFERENCE,                ctrl_copy_reference},
109893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_UPD_ENTROPY,                  ctrl_update_entropy},
109993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_UPD_REFERENCE,                ctrl_update_reference},
110093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_USE_REFERENCE,                ctrl_use_reference},
110193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
110293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Setters
110393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8_SET_REFERENCE,                 ctrl_set_reference},
110493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8_SET_POSTPROC,                  ctrl_set_previewpp},
110593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_SET_ROI_MAP,                  ctrl_set_roi_map},
110693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_SET_ACTIVEMAP,                ctrl_set_active_map},
110793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_SET_SCALEMODE,                ctrl_set_scale_mode},
110893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_SET_CPUUSED,                  ctrl_set_param},
110993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_SET_NOISE_SENSITIVITY,        ctrl_set_param},
111093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_SET_ENABLEAUTOALTREF,         ctrl_set_param},
111193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_SET_SHARPNESS,                ctrl_set_param},
111293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_SET_STATIC_THRESHOLD,         ctrl_set_param},
111393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP9E_SET_TILE_COLUMNS,             ctrl_set_param},
111493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP9E_SET_TILE_ROWS,                ctrl_set_param},
111593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_SET_ARNR_MAXFRAMES,           ctrl_set_param},
111693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_SET_ARNR_STRENGTH,            ctrl_set_param},
11179a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org  {VP8E_SET_ARNR_TYPE,                ctrl_set_param},
111893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_SET_TUNING,                   ctrl_set_param},
111993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_SET_CQ_LEVEL,                 ctrl_set_param},
112093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_SET_MAX_INTRA_BITRATE_PCT,    ctrl_set_param},
112193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP9E_SET_LOSSLESS,                 ctrl_set_param},
112293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP9E_SET_FRAME_PARALLEL_DECODING,  ctrl_set_param},
112393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP9E_SET_AQ_MODE,                  ctrl_set_param},
112493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP9E_SET_FRAME_PERIODIC_BOOST,     ctrl_set_param},
112593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP9E_SET_SVC,                      ctrl_set_svc},
112693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP9E_SET_SVC_PARAMETERS,           ctrl_set_svc_parameters},
112793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP9E_SET_SVC_LAYER_ID,             ctrl_set_svc_layer_id},
112893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
112993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Getters
113093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_GET_LAST_QUANTIZER,           ctrl_get_param},
113193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP8E_GET_LAST_QUANTIZER_64,        ctrl_get_param},
113293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  {VP9_GET_REFERENCE,                 ctrl_get_reference},
113393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
11346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  { -1, NULL},
11356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org};
11366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
113793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic vpx_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
11386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  {
11396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    0,
1140ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org    {  // NOLINT
114193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                  // g_usage
114293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                  // g_threads
114393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                  // g_profile
11446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
114593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      320,                // g_width
114693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      240,                // g_height
114793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      {1, 30},            // g_timebase
11486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
114993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                  // g_error_resilient
11506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
115193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      VPX_RC_ONE_PASS,    // g_pass
11526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
115393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      25,                 // g_lag_in_frames
11546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
115593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                  // rc_dropframe_thresh
115693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                  // rc_resize_allowed
1157693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      1,                  // rc_scaled_width
1158693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      1,                  // rc_scaled_height
115993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      60,                 // rc_resize_down_thresold
116093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      30,                 // rc_resize_up_thresold
11616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
116293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      VPX_VBR,            // rc_end_usage
11636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#if VPX_ENCODER_ABI_VERSION > (1 + VPX_CODEC_ABI_VERSION)
116493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      {0},                // rc_twopass_stats_in
11656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#endif
116693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      256,                // rc_target_bandwidth
116793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                  // rc_min_quantizer
116893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      63,                 // rc_max_quantizer
116993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      100,                // rc_undershoot_pct
117093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      100,                // rc_overshoot_pct
117193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
117293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      6000,               // rc_max_buffer_size
117393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      4000,               // rc_buffer_initial_size
117493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      5000,               // rc_buffer_optimal_size
117593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
117693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      50,                 // rc_two_pass_vbrbias
117793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                  // rc_two_pass_vbrmin_section
117893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      2000,               // rc_two_pass_vbrmax_section
117993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
118093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      // keyframing settings (kf)
118193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      VPX_KF_AUTO,        // g_kfmode
118293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                  // kf_min_dist
118393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      9999,               // kf_max_dist
118493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
118593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      VPX_SS_DEFAULT_LAYERS,  // ss_number_layers
118693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      {0},                    // ss_target_bitrate
118793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      1,                      // ts_number_layers
118893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      {0},                    // ts_target_bitrate
118993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      {0},                    // ts_rate_decimator
119093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      0,                      // ts_periodicity
119193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      {0},                    // ts_layer_id
11926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#if VPX_ENCODER_ABI_VERSION == (1 + VPX_CODEC_ABI_VERSION)
119393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      "vp8.fpf"           // first pass filename
11946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#endif
11956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
11966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  },
11976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  { -1, {NOT_IMPLEMENTED}}
11986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org};
11996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
12006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#ifndef VERSION_STRING
12016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#define VERSION_STRING
12026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#endif
12036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgCODEC_INTERFACE(vpx_codec_vp9_cx) = {
12046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  "WebM Project VP9 Encoder" VERSION_STRING,
12056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CODEC_INTERNAL_ABI_VERSION,
120693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR,  // vpx_codec_caps_t
120793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  encoder_init,       // vpx_codec_init_fn_t
120893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  encoder_destroy,    // vpx_codec_destroy_fn_t
120993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  encoder_ctrl_maps,  // vpx_codec_ctrl_fn_map_t
121093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  NOT_IMPLEMENTED,    // vpx_codec_get_mmap_fn_t
121193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  NOT_IMPLEMENTED,    // vpx_codec_set_mmap_fn_t
1212ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  {  // NOLINT
121393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    NOT_IMPLEMENTED,  // vpx_codec_peek_si_fn_t
121493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    NOT_IMPLEMENTED,  // vpx_codec_get_si_fn_t
121593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    NOT_IMPLEMENTED,  // vpx_codec_decode_fn_t
121693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    NOT_IMPLEMENTED,  // vpx_codec_frame_get_fn_t
12176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  },
1218ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  {  // NOLINT
121993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    encoder_usage_cfg_map,  // vpx_codec_enc_cfg_map_t
122093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    encoder_encode,         // vpx_codec_encode_fn_t
122193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    encoder_get_cxdata,     // vpx_codec_get_cx_data_fn_t
122293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    encoder_set_config,     // vpx_codec_enc_config_set_fn_t
122393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    NOT_IMPLEMENTED,        // vpx_codec_get_global_headers_fn_t
122493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    encoder_get_preview,    // vpx_codec_get_preview_frame_fn_t
122593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    NOT_IMPLEMENTED ,       // vpx_codec_enc_mr_get_mem_loc_fn_t
122693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
12276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org};
1228