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


12 13
#include "vpx/vpx_codec.h"
#include "vpx/internal/vpx_codec_internal.h"
John Koleszar's avatar
John Koleszar committed
14
#include "vpx_version.h"
15
#include "vp9/encoder/onyx_int.h"
16
#include "vpx/vp8e.h"
17 18
#include "vp9/encoder/firstpass.h"
#include "vp9/common/onyx.h"
John Koleszar's avatar
John Koleszar committed
19 20 21 22 23 24 25 26
#include <stdlib.h>
#include <string.h>

/* This value is a sentinel for determining whether the user has set a mode
 * directly through the deprecated VP8E_SET_ENCODING_MODE control.
 */
#define NO_MODE_SET 255

John Koleszar's avatar
John Koleszar committed
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
struct vp8_extracfg {
  struct vpx_codec_pkt_list *pkt_list;
  vp8e_encoding_mode      encoding_mode;               /** best, good, realtime            */
  int                         cpu_used;                    /** available cpu percentage in 1/16*/
  unsigned int                enable_auto_alt_ref;           /** if encoder decides to uses alternate reference frame */
  unsigned int                noise_sensitivity;
  unsigned int                Sharpness;
  unsigned int                static_thresh;
  unsigned int                token_partitions;
  unsigned int                arnr_max_frames;    /* alt_ref Noise Reduction Max Frame Count */
  unsigned int                arnr_strength;    /* alt_ref Noise Reduction Strength */
  unsigned int                arnr_type;        /* alt_ref filter type */
  unsigned int                experimental;
  vp8e_tuning                 tuning;
  unsigned int                cq_level;         /* constrained quality level */
  unsigned int                rc_max_intra_bitrate_pct;
John Koleszar's avatar
John Koleszar committed
43 44 45

};

John Koleszar's avatar
John Koleszar committed
46 47 48
struct extraconfig_map {
  int                 usage;
  struct vp8_extracfg cfg;
John Koleszar's avatar
John Koleszar committed
49 50
};

John Koleszar's avatar
John Koleszar committed
51 52 53
static const struct extraconfig_map extracfg_map[] = {
  {
    0,
John Koleszar's avatar
John Koleszar committed
54
    {
John Koleszar's avatar
John Koleszar committed
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
      NULL,
      VP8_BEST_QUALITY_ENCODING,  /* Encoding Mode */
      0,                          /* cpu_used      */
      0,                          /* enable_auto_alt_ref */
      0,                          /* noise_sensitivity */
      0,                          /* Sharpness */
      0,                          /* static_thresh */
      VP8_ONE_TOKENPARTITION,     /* token_partitions */
      0,                          /* arnr_max_frames */
      3,                          /* arnr_strength */
      3,                          /* arnr_type*/
      0,                          /* experimental mode */
      0,                          /* tuning*/
      10,                         /* cq_level */
      0,                          /* rc_max_intra_bitrate_pct */
John Koleszar's avatar
John Koleszar committed
70
    }
John Koleszar's avatar
John Koleszar committed
71
  }
John Koleszar's avatar
John Koleszar committed
72 73
};

John Koleszar's avatar
John Koleszar committed
74 75 76 77
struct vpx_codec_alg_priv {
  vpx_codec_priv_t        base;
  vpx_codec_enc_cfg_t     cfg;
  struct vp8_extracfg     vp8_cfg;
78
  VP9_CONFIG              oxcf;
79
  VP9_PTR             cpi;
John Koleszar's avatar
John Koleszar committed
80 81 82 83 84 85 86 87
  unsigned char          *cx_data;
  unsigned int            cx_data_sz;
  vpx_image_t             preview_img;
  unsigned int            next_frame_flag;
  vp8_postproc_cfg_t      preview_ppcfg;
  vpx_codec_pkt_list_decl(64) pkt_list;              // changed to accomendate the maximum number of lagged frames allowed
  int                         deprecated_mode;
  unsigned int                fixed_kf_cntr;
John Koleszar's avatar
John Koleszar committed
88 89 90 91 92
};


static vpx_codec_err_t
update_error_state(vpx_codec_alg_priv_t                 *ctx,
John Koleszar's avatar
John Koleszar committed
93 94
                   const struct vpx_internal_error_info *error) {
  vpx_codec_err_t res;
John Koleszar's avatar
John Koleszar committed
95

John Koleszar's avatar
John Koleszar committed
96 97 98 99
  if ((res = error->error_code))
    ctx->base.err_detail = error->has_detail
                           ? error->detail
                           : NULL;
John Koleszar's avatar
John Koleszar committed
100

John Koleszar's avatar
John Koleszar committed
101
  return res;
John Koleszar's avatar
John Koleszar committed
102 103 104
}


105
#undef ERROR
John Koleszar's avatar
John Koleszar committed
106
#define ERROR(str) do {\
John Koleszar's avatar
John Koleszar committed
107 108 109
    ctx->base.err_detail = str;\
    return VPX_CODEC_INVALID_PARAM;\
  } while(0)
John Koleszar's avatar
John Koleszar committed
110 111

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

116
#define RANGE_CHECK_HI(p,memb,hi) do {\
John Koleszar's avatar
John Koleszar committed
117 118 119
    if(!((p)->memb <= (hi))) \
      ERROR(#memb " out of range [.."#hi"]");\
  } while(0)
120

John Koleszar's avatar
John Koleszar committed
121
#define RANGE_CHECK_LO(p,memb,lo) do {\
John Koleszar's avatar
John Koleszar committed
122 123 124
    if(!((p)->memb >= (lo))) \
      ERROR(#memb " out of range ["#lo"..]");\
  } while(0)
John Koleszar's avatar
John Koleszar committed
125 126

#define RANGE_CHECK_BOOL(p,memb) do {\
John Koleszar's avatar
John Koleszar committed
127 128
    if(!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean");\
  } while(0)
John Koleszar's avatar
John Koleszar committed
129 130 131

static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t      *ctx,
                                       const vpx_codec_enc_cfg_t *cfg,
John Koleszar's avatar
John Koleszar committed
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
                                       const struct vp8_extracfg *vp8_cfg) {
  RANGE_CHECK(cfg, g_w,                   1, 16383); /* 14 bits available */
  RANGE_CHECK(cfg, g_h,                   1, 16383); /* 14 bits available */
  RANGE_CHECK(cfg, g_timebase.den,        1, 1000000000);
  RANGE_CHECK(cfg, g_timebase.num,        1, cfg->g_timebase.den);
  RANGE_CHECK_HI(cfg, g_profile,          3);
  RANGE_CHECK_HI(cfg, rc_max_quantizer,   63);
  RANGE_CHECK_HI(cfg, rc_min_quantizer,   cfg->rc_max_quantizer);
  RANGE_CHECK_HI(cfg, g_threads,          64);
  RANGE_CHECK_HI(cfg, g_lag_in_frames,    MAX_LAG_BUFFERS);
  RANGE_CHECK(cfg, rc_end_usage,          VPX_VBR, VPX_CQ);
  RANGE_CHECK_HI(cfg, rc_undershoot_pct,  1000);
  RANGE_CHECK_HI(cfg, rc_overshoot_pct,   1000);
  RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
  RANGE_CHECK(cfg, kf_mode,               VPX_KF_DISABLED, VPX_KF_AUTO);
  // RANGE_CHECK_BOOL(cfg,                 g_delete_firstpassfile);
  RANGE_CHECK_BOOL(cfg,                   rc_resize_allowed);
  RANGE_CHECK_HI(cfg, rc_dropframe_thresh,   100);
  RANGE_CHECK_HI(cfg, rc_resize_up_thresh,   100);
  RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100);
  RANGE_CHECK(cfg,        g_pass,         VPX_RC_ONE_PASS, VPX_RC_LAST_PASS);

  /* VP8 does not support a lower bound on the keyframe interval in
   * automatic keyframe placement mode.
   */
  if (cfg->kf_mode != VPX_KF_DISABLED && cfg->kf_min_dist != cfg->kf_max_dist
      && cfg->kf_min_dist > 0)
    ERROR("kf_min_dist not supported in auto mode, use 0 "
          "or kf_max_dist instead.");

  RANGE_CHECK_BOOL(vp8_cfg,               enable_auto_alt_ref);
  RANGE_CHECK(vp8_cfg, cpu_used,           -16, 16);

  RANGE_CHECK(vp8_cfg, encoding_mode,      VP8_BEST_QUALITY_ENCODING, VP8_REAL_TIME_ENCODING);
  RANGE_CHECK_HI(vp8_cfg, noise_sensitivity,  6);

  RANGE_CHECK(vp8_cfg, token_partitions,   VP8_ONE_TOKENPARTITION, VP8_EIGHT_TOKENPARTITION);
  RANGE_CHECK_HI(vp8_cfg, Sharpness,       7);
  RANGE_CHECK(vp8_cfg, arnr_max_frames, 0, 15);
  RANGE_CHECK_HI(vp8_cfg, arnr_strength,   6);
  RANGE_CHECK(vp8_cfg, arnr_type,       1, 3);
  RANGE_CHECK(vp8_cfg, cq_level, 0, 63);

  if (cfg->g_pass == VPX_RC_LAST_PASS) {
    size_t           packet_sz = sizeof(FIRSTPASS_STATS);
    int              n_packets = cfg->rc_twopass_stats_in.sz / packet_sz;
    FIRSTPASS_STATS *stats;

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

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

    if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)
      ERROR("rc_twopass_stats_in requires at least two packets.");

    stats = (void *)((char *)cfg->rc_twopass_stats_in.buf
                     + (n_packets - 1) * packet_sz);

    if ((int)(stats->count + 0.5) != n_packets - 1)
      ERROR("rc_twopass_stats_in missing EOS stats packet");
  }

  return VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
197 198 199 200
}


static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
John Koleszar's avatar
John Koleszar committed
201 202
                                    const vpx_image_t    *img) {
  switch (img->fmt) {
James Zern's avatar
James Zern committed
203 204 205 206
    case VPX_IMG_FMT_YV12:
    case VPX_IMG_FMT_I420:
    case VPX_IMG_FMT_VPXI420:
    case VPX_IMG_FMT_VPXYV12:
John Koleszar's avatar
John Koleszar committed
207
      break;
John Koleszar's avatar
John Koleszar committed
208
    default:
John Koleszar's avatar
John Koleszar committed
209 210
      ERROR("Invalid image format. Only YV12 and I420 images are supported");
  }
John Koleszar's avatar
John Koleszar committed
211

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

John Koleszar's avatar
John Koleszar committed
215
  return VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
216 217 218
}


219
static vpx_codec_err_t set_vp8e_config(VP9_CONFIG *oxcf,
John Koleszar's avatar
John Koleszar committed
220
                                       vpx_codec_enc_cfg_t cfg,
John Koleszar's avatar
John Koleszar committed
221 222 223
                                       struct vp8_extracfg vp8_cfg) {
  oxcf->Version               = cfg.g_profile;
  oxcf->Version              |= vp8_cfg.experimental ? 0x4 : 0;
John Koleszar's avatar
John Koleszar committed
224

John Koleszar's avatar
John Koleszar committed
225 226 227 228
  oxcf->Width                 = cfg.g_w;
  oxcf->Height                = cfg.g_h;
  /* guess a frame rate if out of whack, use 30 */
  oxcf->frame_rate             = (double)(cfg.g_timebase.den) / (double)(cfg.g_timebase.num);
John Koleszar's avatar
John Koleszar committed
229

John Koleszar's avatar
John Koleszar committed
230 231 232
  if (oxcf->frame_rate > 180) {
    oxcf->frame_rate = 30;
  }
John Koleszar's avatar
John Koleszar committed
233

John Koleszar's avatar
John Koleszar committed
234
  switch (cfg.g_pass) {
John Koleszar's avatar
John Koleszar committed
235
    case VPX_RC_ONE_PASS:
John Koleszar's avatar
John Koleszar committed
236 237
      oxcf->Mode = MODE_BESTQUALITY;
      break;
John Koleszar's avatar
John Koleszar committed
238
    case VPX_RC_FIRST_PASS:
John Koleszar's avatar
John Koleszar committed
239 240
      oxcf->Mode = MODE_FIRSTPASS;
      break;
John Koleszar's avatar
John Koleszar committed
241
    case VPX_RC_LAST_PASS:
John Koleszar's avatar
John Koleszar committed
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
      oxcf->Mode = MODE_SECONDPASS_BEST;
      break;
  }

  if (cfg.g_pass == VPX_RC_FIRST_PASS) {
    oxcf->allow_lag              = 0;
    oxcf->lag_in_frames           = 0;
  } else {
    oxcf->allow_lag              = (cfg.g_lag_in_frames) > 0;
    oxcf->lag_in_frames           = cfg.g_lag_in_frames;
  }

  // VBR only supported for now.
  // CBR code has been deprectated for experimental phase.
  // CQ mode not yet tested
  oxcf->end_usage          = USAGE_LOCAL_FILE_PLAYBACK;
  /*if (cfg.rc_end_usage == VPX_CQ)
      oxcf->end_usage      = USAGE_CONSTRAINED_QUALITY;
  else
      oxcf->end_usage      = USAGE_LOCAL_FILE_PLAYBACK;*/

  oxcf->target_bandwidth       = cfg.rc_target_bitrate;
  oxcf->rc_max_intra_bitrate_pct = vp8_cfg.rc_max_intra_bitrate_pct;

  oxcf->best_allowed_q          = cfg.rc_min_quantizer;
  oxcf->worst_allowed_q         = cfg.rc_max_quantizer;
  oxcf->cq_level                = vp8_cfg.cq_level;
  oxcf->fixed_q = -1;

  oxcf->under_shoot_pct         = cfg.rc_undershoot_pct;
  oxcf->over_shoot_pct          = cfg.rc_overshoot_pct;

  oxcf->maximum_buffer_size     = cfg.rc_buf_sz;
  oxcf->starting_buffer_level   = cfg.rc_buf_initial_sz;
  oxcf->optimal_buffer_level    = cfg.rc_buf_optimal_sz;

  oxcf->two_pass_vbrbias        = cfg.rc_2pass_vbr_bias_pct;
  oxcf->two_pass_vbrmin_section  = cfg.rc_2pass_vbr_minsection_pct;
  oxcf->two_pass_vbrmax_section  = cfg.rc_2pass_vbr_maxsection_pct;

  oxcf->auto_key               = cfg.kf_mode == VPX_KF_AUTO
                                 && cfg.kf_min_dist != cfg.kf_max_dist;
  // oxcf->kf_min_dist         = cfg.kf_min_dis;
  oxcf->key_freq               = cfg.kf_max_dist;

  // oxcf->delete_first_pass_file = cfg.g_delete_firstpassfile;
  // strcpy(oxcf->first_pass_file, cfg.g_firstpass_file);

  oxcf->cpu_used               =  vp8_cfg.cpu_used;
  oxcf->encode_breakout        =  vp8_cfg.static_thresh;
  oxcf->play_alternate         =  vp8_cfg.enable_auto_alt_ref;
  oxcf->noise_sensitivity      =  vp8_cfg.noise_sensitivity;
  oxcf->Sharpness             =  vp8_cfg.Sharpness;

  oxcf->two_pass_stats_in        =  cfg.rc_twopass_stats_in;
  oxcf->output_pkt_list         =  vp8_cfg.pkt_list;

  oxcf->arnr_max_frames = vp8_cfg.arnr_max_frames;
  oxcf->arnr_strength =  vp8_cfg.arnr_strength;
  oxcf->arnr_type =      vp8_cfg.arnr_type;

  oxcf->tuning = vp8_cfg.tuning;
John Koleszar's avatar
John Koleszar committed
304

Hui Su's avatar
Hui Su committed
305
#if CONFIG_LOSSLESS
John Koleszar's avatar
John Koleszar committed
306
  oxcf->lossless = cfg.lossless;
Hui Su's avatar
Hui Su committed
307 308
#endif

John Koleszar's avatar
John Koleszar committed
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
  /*
      printf("Current VP8 Settings: \n");
      printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
      printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity);
      printf("Sharpness: %d\n",    oxcf->Sharpness);
      printf("cpu_used: %d\n",  oxcf->cpu_used);
      printf("Mode: %d\n",     oxcf->Mode);
      printf("delete_first_pass_file: %d\n",  oxcf->delete_first_pass_file);
      printf("auto_key: %d\n",  oxcf->auto_key);
      printf("key_freq: %d\n", oxcf->key_freq);
      printf("end_usage: %d\n", oxcf->end_usage);
      printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct);
      printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct);
      printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level);
      printf("optimal_buffer_level: %d\n",  oxcf->optimal_buffer_level);
      printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size);
      printf("fixed_q: %d\n",  oxcf->fixed_q);
      printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q);
      printf("best_allowed_q: %d\n", oxcf->best_allowed_q);
      printf("two_pass_vbrbias: %d\n",  oxcf->two_pass_vbrbias);
      printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section);
      printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section);
      printf("allow_lag: %d\n", oxcf->allow_lag);
      printf("lag_in_frames: %d\n", oxcf->lag_in_frames);
      printf("play_alternate: %d\n", oxcf->play_alternate);
      printf("Version: %d\n", oxcf->Version);
      printf("encode_breakout: %d\n", oxcf->encode_breakout);
  */
  return VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
338 339 340
}

static vpx_codec_err_t vp8e_set_config(vpx_codec_alg_priv_t       *ctx,
John Koleszar's avatar
John Koleszar committed
341 342
                                       const vpx_codec_enc_cfg_t  *cfg) {
  vpx_codec_err_t res;
John Koleszar's avatar
John Koleszar committed
343

John Koleszar's avatar
John Koleszar committed
344 345
  if ((cfg->g_w != ctx->cfg.g_w) || (cfg->g_h != ctx->cfg.g_h))
    ERROR("Cannot change width or height after initialization");
John Koleszar's avatar
John Koleszar committed
346

John Koleszar's avatar
John Koleszar committed
347 348 349 350 351 352 353
  /* Prevent increasing lag_in_frames. This check is stricter than it needs
   * to be -- the limit is not increasing past the first lag_in_frames
   * value, but we don't track the initial config, only the last successful
   * config.
   */
  if ((cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames))
    ERROR("Cannot increase lag_in_frames");
John Koleszar's avatar
John Koleszar committed
354

John Koleszar's avatar
John Koleszar committed
355
  res = validate_config(ctx, cfg, &ctx->vp8_cfg);
John Koleszar's avatar
John Koleszar committed
356

John Koleszar's avatar
John Koleszar committed
357 358 359
  if (!res) {
    ctx->cfg = *cfg;
    set_vp8e_config(&ctx->oxcf, ctx->cfg, ctx->vp8_cfg);
360
    vp9_change_config(ctx->cpi, &ctx->oxcf);
John Koleszar's avatar
John Koleszar committed
361
  }
John Koleszar's avatar
John Koleszar committed
362

John Koleszar's avatar
John Koleszar committed
363
  return res;
John Koleszar's avatar
John Koleszar committed
364 365 366
}


367
int vp9_reverse_trans(int q);
John Koleszar's avatar
John Koleszar committed
368 369 370 371


static vpx_codec_err_t get_param(vpx_codec_alg_priv_t *ctx,
                                 int                   ctrl_id,
John Koleszar's avatar
John Koleszar committed
372 373
                                 va_list               args) {
  void *arg = va_arg(args, void *);
John Koleszar's avatar
John Koleszar committed
374 375 376

#define MAP(id, var) case id: *(RECAST(id, arg)) = var; break

John Koleszar's avatar
John Koleszar committed
377 378
  if (!arg)
    return VPX_CODEC_INVALID_PARAM;
John Koleszar's avatar
John Koleszar committed
379

John Koleszar's avatar
John Koleszar committed
380
  switch (ctrl_id) {
381
      MAP(VP8E_GET_LAST_QUANTIZER, vp9_get_quantizer(ctx->cpi));
382 383
      MAP(VP8E_GET_LAST_QUANTIZER_64,
          vp9_reverse_trans(vp9_get_quantizer(ctx->cpi)));
John Koleszar's avatar
John Koleszar committed
384
  }
John Koleszar's avatar
John Koleszar committed
385

John Koleszar's avatar
John Koleszar committed
386
  return VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
387 388 389 390 391 392
#undef MAP
}


static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx,
                                 int                   ctrl_id,
John Koleszar's avatar
John Koleszar committed
393 394 395
                                 va_list               args) {
  vpx_codec_err_t     res  = VPX_CODEC_OK;
  struct vp8_extracfg xcfg = ctx->vp8_cfg;
John Koleszar's avatar
John Koleszar committed
396 397 398

#define MAP(id, var) case id: var = CAST(id, args); break;

John Koleszar's avatar
John Koleszar committed
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
  switch (ctrl_id) {
      MAP(VP8E_SET_ENCODING_MODE,         ctx->deprecated_mode);
      MAP(VP8E_SET_CPUUSED,               xcfg.cpu_used);
      MAP(VP8E_SET_ENABLEAUTOALTREF,      xcfg.enable_auto_alt_ref);
      MAP(VP8E_SET_NOISE_SENSITIVITY,     xcfg.noise_sensitivity);
      MAP(VP8E_SET_SHARPNESS,             xcfg.Sharpness);
      MAP(VP8E_SET_STATIC_THRESHOLD,      xcfg.static_thresh);
      MAP(VP8E_SET_TOKEN_PARTITIONS,      xcfg.token_partitions);

      MAP(VP8E_SET_ARNR_MAXFRAMES,        xcfg.arnr_max_frames);
      MAP(VP8E_SET_ARNR_STRENGTH,        xcfg.arnr_strength);
      MAP(VP8E_SET_ARNR_TYPE,        xcfg.arnr_type);
      MAP(VP8E_SET_TUNING,                xcfg.tuning);
      MAP(VP8E_SET_CQ_LEVEL,              xcfg.cq_level);
      MAP(VP8E_SET_MAX_INTRA_BITRATE_PCT, xcfg.rc_max_intra_bitrate_pct);

  }

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

  if (!res) {
    ctx->vp8_cfg = xcfg;
    set_vp8e_config(&ctx->oxcf, ctx->cfg, ctx->vp8_cfg);
422
    vp9_change_config(ctx->cpi, &ctx->oxcf);
John Koleszar's avatar
John Koleszar committed
423 424 425
  }

  return res;
John Koleszar's avatar
John Koleszar committed
426 427
#undef MAP
}
428 429 430


static vpx_codec_err_t vp8e_common_init(vpx_codec_ctx_t *ctx,
John Koleszar's avatar
John Koleszar committed
431 432 433 434 435
                                        int              experimental) {
  vpx_codec_err_t        res = VPX_DEC_OK;
  struct vpx_codec_alg_priv *priv;
  vpx_codec_enc_cfg_t       *cfg;
  unsigned int               i;
John Koleszar's avatar
John Koleszar committed
436

437
  VP9_PTR optr;
John Koleszar's avatar
John Koleszar committed
438

John Koleszar's avatar
John Koleszar committed
439 440
  if (!ctx->priv) {
    priv = calloc(1, sizeof(struct vpx_codec_alg_priv));
John Koleszar's avatar
John Koleszar committed
441

John Koleszar's avatar
John Koleszar committed
442 443 444
    if (!priv) {
      return VPX_CODEC_MEM_ERROR;
    }
445

John Koleszar's avatar
John Koleszar committed
446 447 448 449 450 451 452 453 454 455 456 457 458
    ctx->priv = &priv->base;
    ctx->priv->sz = sizeof(*ctx->priv);
    ctx->priv->iface = ctx->iface;
    ctx->priv->alg_priv = priv;
    ctx->priv->init_flags = ctx->init_flags;

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

John Koleszar's avatar
John Koleszar committed
460
    cfg =  &ctx->priv->alg_priv->cfg;
John Koleszar's avatar
John Koleszar committed
461

John Koleszar's avatar
John Koleszar committed
462 463 464 465 466 467 468
    /* Select the extra vp6 configuration table based on the current
     * usage value. If the current usage value isn't found, use the
     * values for usage case 0.
     */
    for (i = 0;
         extracfg_map[i].usage && extracfg_map[i].usage != cfg->g_usage;
         i++);
John Koleszar's avatar
John Koleszar committed
469

John Koleszar's avatar
John Koleszar committed
470 471 472
    priv->vp8_cfg = extracfg_map[i].cfg;
    priv->vp8_cfg.pkt_list = &priv->pkt_list.head;
    priv->vp8_cfg.experimental = experimental;
John Koleszar's avatar
John Koleszar committed
473

John Koleszar's avatar
John Koleszar committed
474
    priv->cx_data_sz = priv->cfg.g_w * priv->cfg.g_h * 3 / 2 * 2;
John Koleszar's avatar
John Koleszar committed
475

John Koleszar's avatar
John Koleszar committed
476
    if (priv->cx_data_sz < 4096) priv->cx_data_sz = 4096;
John Koleszar's avatar
John Koleszar committed
477

John Koleszar's avatar
John Koleszar committed
478
    priv->cx_data = malloc(priv->cx_data_sz);
John Koleszar's avatar
John Koleszar committed
479

John Koleszar's avatar
John Koleszar committed
480 481 482
    if (!priv->cx_data) {
      return VPX_CODEC_MEM_ERROR;
    }
John Koleszar's avatar
John Koleszar committed
483

John Koleszar's avatar
John Koleszar committed
484
    priv->deprecated_mode = NO_MODE_SET;
John Koleszar's avatar
John Koleszar committed
485

486
    vp9_initialize_enc();
John Koleszar's avatar
John Koleszar committed
487

John Koleszar's avatar
John Koleszar committed
488
    res = validate_config(priv, &priv->cfg, &priv->vp8_cfg);
John Koleszar's avatar
John Koleszar committed
489

John Koleszar's avatar
John Koleszar committed
490 491 492 493
    if (!res) {
      set_vp8e_config(&ctx->priv->alg_priv->oxcf,
                      ctx->priv->alg_priv->cfg,
                      ctx->priv->alg_priv->vp8_cfg);
494
      optr = vp9_create_compressor(&ctx->priv->alg_priv->oxcf);
495

John Koleszar's avatar
John Koleszar committed
496 497 498 499
      if (!optr)
        res = VPX_CODEC_MEM_ERROR;
      else
        ctx->priv->alg_priv->cpi = optr;
John Koleszar's avatar
John Koleszar committed
500
    }
John Koleszar's avatar
John Koleszar committed
501
  }
John Koleszar's avatar
John Koleszar committed
502

John Koleszar's avatar
John Koleszar committed
503
  return res;
John Koleszar's avatar
John Koleszar committed
504 505
}

506

John Koleszar's avatar
John Koleszar committed
507 508
static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx) {
  return vp8e_common_init(ctx, 0);
509 510 511 512
}


#if CONFIG_EXPERIMENTAL
John Koleszar's avatar
John Koleszar committed
513 514
static vpx_codec_err_t vp8e_exp_init(vpx_codec_ctx_t *ctx) {
  return vp8e_common_init(ctx, 1);
515 516 517 518
}
#endif


John Koleszar's avatar
John Koleszar committed
519
static vpx_codec_err_t vp8e_destroy(vpx_codec_alg_priv_t *ctx) {
John Koleszar's avatar
John Koleszar committed
520

John Koleszar's avatar
John Koleszar committed
521
  free(ctx->cx_data);
522
  vp9_remove_compressor(&ctx->cpi);
John Koleszar's avatar
John Koleszar committed
523 524
  free(ctx);
  return VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
525 526 527
}

static vpx_codec_err_t image2yuvconfig(const vpx_image_t   *img,
John Koleszar's avatar
John Koleszar committed
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
                                       YV12_BUFFER_CONFIG  *yv12) {
  vpx_codec_err_t        res = VPX_CODEC_OK;
  yv12->y_buffer = img->planes[VPX_PLANE_Y];
  yv12->u_buffer = img->planes[VPX_PLANE_U];
  yv12->v_buffer = img->planes[VPX_PLANE_V];

  yv12->y_width  = img->d_w;
  yv12->y_height = img->d_h;
  yv12->uv_width = (1 + yv12->y_width) / 2;
  yv12->uv_height = (1 + yv12->y_height) / 2;

  yv12->y_stride = img->stride[VPX_PLANE_Y];
  yv12->uv_stride = img->stride[VPX_PLANE_U];

  yv12->border  = (img->stride[VPX_PLANE_Y] - img->w) / 2;
  yv12->clrtype = (img->fmt == VPX_IMG_FMT_VPXI420 || img->fmt == VPX_IMG_FMT_VPXYV12); // REG_YUV = 0
  return res;
John Koleszar's avatar
John Koleszar committed
545 546 547 548
}

static void pick_quickcompress_mode(vpx_codec_alg_priv_t  *ctx,
                                    unsigned long          duration,
John Koleszar's avatar
John Koleszar committed
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566
                                    unsigned long          deadline) {
  unsigned int new_qc;

  /* Use best quality mode if no deadline is given. */
  if (deadline)
    new_qc = MODE_GOODQUALITY;
  else
    new_qc = MODE_BESTQUALITY;

  if (ctx->cfg.g_pass == VPX_RC_FIRST_PASS)
    new_qc = MODE_FIRSTPASS;
  else if (ctx->cfg.g_pass == VPX_RC_LAST_PASS)
    new_qc = (new_qc == MODE_BESTQUALITY)
             ? MODE_SECONDPASS_BEST
             : MODE_SECONDPASS;

  if (ctx->oxcf.Mode != new_qc) {
    ctx->oxcf.Mode = new_qc;
567
    vp9_change_config(ctx->cpi, &ctx->oxcf);
John Koleszar's avatar
John Koleszar committed
568
  }
John Koleszar's avatar
John Koleszar committed
569 570 571 572 573 574 575 576
}


static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t  *ctx,
                                   const vpx_image_t     *img,
                                   vpx_codec_pts_t        pts,
                                   unsigned long          duration,
                                   vpx_enc_frame_flags_t  flags,
John Koleszar's avatar
John Koleszar committed
577 578
                                   unsigned long          deadline) {
  vpx_codec_err_t res = VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
579

John Koleszar's avatar
John Koleszar committed
580 581
  if (img)
    res = validate_img(ctx, img);
John Koleszar's avatar
John Koleszar committed
582

John Koleszar's avatar
John Koleszar committed
583 584
  pick_quickcompress_mode(ctx, duration, deadline);
  vpx_codec_pkt_list_init(&ctx->pkt_list);
John Koleszar's avatar
John Koleszar committed
585

John Koleszar's avatar
John Koleszar committed
586 587 588 589 590 591
  /* Handle Flags */
  if (((flags & VP8_EFLAG_NO_UPD_GF) && (flags & VP8_EFLAG_FORCE_GF))
      || ((flags & VP8_EFLAG_NO_UPD_ARF) && (flags & VP8_EFLAG_FORCE_ARF))) {
    ctx->base.err_detail = "Conflicting flags.";
    return VPX_CODEC_INVALID_PARAM;
  }
John Koleszar's avatar
John Koleszar committed
592

John Koleszar's avatar
John Koleszar committed
593 594 595
  if (flags & (VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF
               | VP8_EFLAG_NO_REF_ARF)) {
    int ref = 7;
John Koleszar's avatar
John Koleszar committed
596

John Koleszar's avatar
John Koleszar committed
597
    if (flags & VP8_EFLAG_NO_REF_LAST)
598
      ref ^= VP9_LAST_FLAG;
John Koleszar's avatar
John Koleszar committed
599

John Koleszar's avatar
John Koleszar committed
600
    if (flags & VP8_EFLAG_NO_REF_GF)
601
      ref ^= VP9_GOLD_FLAG;
John Koleszar's avatar
John Koleszar committed
602

John Koleszar's avatar
John Koleszar committed
603
    if (flags & VP8_EFLAG_NO_REF_ARF)
604
      ref ^= VP9_ALT_FLAG;
John Koleszar's avatar
John Koleszar committed
605

606
    vp9_use_as_reference(ctx->cpi, ref);
John Koleszar's avatar
John Koleszar committed
607
  }
John Koleszar's avatar
John Koleszar committed
608

John Koleszar's avatar
John Koleszar committed
609 610 611 612
  if (flags & (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF
               | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_FORCE_GF
               | VP8_EFLAG_FORCE_ARF)) {
    int upd = 7;
John Koleszar's avatar
John Koleszar committed
613

John Koleszar's avatar
John Koleszar committed
614
    if (flags & VP8_EFLAG_NO_UPD_LAST)
615
      upd ^= VP9_LAST_FLAG;
John Koleszar's avatar
John Koleszar committed
616

John Koleszar's avatar
John Koleszar committed
617
    if (flags & VP8_EFLAG_NO_UPD_GF)
618
      upd ^= VP9_GOLD_FLAG;
John Koleszar's avatar
John Koleszar committed
619

John Koleszar's avatar
John Koleszar committed
620
    if (flags & VP8_EFLAG_NO_UPD_ARF)
621
      upd ^= VP9_ALT_FLAG;
John Koleszar's avatar
John Koleszar committed
622

623
    vp9_update_reference(ctx->cpi, upd);
John Koleszar's avatar
John Koleszar committed
624
  }
John Koleszar's avatar
John Koleszar committed
625

John Koleszar's avatar
John Koleszar committed
626
  if (flags & VP8_EFLAG_NO_UPD_ENTROPY) {
627
    vp9_update_entropy(ctx->cpi, 0);
John Koleszar's avatar
John Koleszar committed
628
  }
John Koleszar's avatar
John Koleszar committed
629

John Koleszar's avatar
John Koleszar committed
630 631 632 633 634 635
  /* Handle fixed keyframe intervals */
  if (ctx->cfg.kf_mode == VPX_KF_AUTO
      && ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) {
    if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) {
      flags |= VPX_EFLAG_FORCE_KF;
      ctx->fixed_kf_cntr = 1;
John Koleszar's avatar
John Koleszar committed
636
    }
John Koleszar's avatar
John Koleszar committed
637
  }
John Koleszar's avatar
John Koleszar committed
638

John Koleszar's avatar
John Koleszar committed
639 640 641 642 643 644 645
  /* Initialize the encoder instance on the first frame*/
  if (!res && ctx->cpi) {
    unsigned int lib_flags;
    YV12_BUFFER_CONFIG sd;
    int64_t dst_time_stamp, dst_end_time_stamp;
    unsigned long size, cx_data_sz;
    unsigned char *cx_data;
John Koleszar's avatar
John Koleszar committed
646

John Koleszar's avatar
John Koleszar committed
647 648
    /* Set up internal flags */
    if (ctx->base.init_flags & VPX_CODEC_USE_PSNR)
649
      ((VP9_COMP *)ctx->cpi)->b_calculate_psnr = 1;
John Koleszar's avatar
John Koleszar committed
650

John Koleszar's avatar
John Koleszar committed
651
    // if (ctx->base.init_flags & VPX_CODEC_USE_OUTPUT_PARTITION)
652
    //    ((VP9_COMP *)ctx->cpi)->output_partition = 1;
653

John Koleszar's avatar
John Koleszar committed
654 655
    /* Convert API flags to internal codec lib flags */
    lib_flags = (flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
John Koleszar's avatar
John Koleszar committed
656

John Koleszar's avatar
John Koleszar committed
657 658 659
    /* vp8 use 10,000,000 ticks/second as time stamp */
    dst_time_stamp    = pts * 10000000 * ctx->cfg.g_timebase.num / ctx->cfg.g_timebase.den;
    dst_end_time_stamp = (pts + duration) * 10000000 * ctx->cfg.g_timebase.num / ctx->cfg.g_timebase.den;
John Koleszar's avatar
John Koleszar committed
660

John Koleszar's avatar
John Koleszar committed
661 662
    if (img != NULL) {
      res = image2yuvconfig(img, &sd);
John Koleszar's avatar
John Koleszar committed
663

664
      if (vp9_receive_raw_frame(ctx->cpi, ctx->next_frame_flag | lib_flags,
John Koleszar's avatar
John Koleszar committed
665
                                &sd, dst_time_stamp, dst_end_time_stamp)) {
666
        VP9_COMP *cpi = (VP9_COMP *)ctx->cpi;
John Koleszar's avatar
John Koleszar committed
667 668 669 670 671 672
        res = update_error_state(ctx, &cpi->common.error);
      }

      /* reset for next frame */
      ctx->next_frame_flag = 0;
    }
John Koleszar's avatar
John Koleszar committed
673

John Koleszar's avatar
John Koleszar committed
674 675 676 677
    cx_data = ctx->cx_data;
    cx_data_sz = ctx->cx_data_sz;
    lib_flags = 0;

678 679 680 681
    while (cx_data_sz >= ctx->cx_data_sz / 2 &&
           -1 != vp9_get_compressed_data(ctx->cpi, &lib_flags, &size,
                                         cx_data, &dst_time_stamp,
                                         &dst_end_time_stamp, !img)) {
John Koleszar's avatar
John Koleszar committed
682 683 684
      if (size) {
        vpx_codec_pts_t    round, delta;
        vpx_codec_cx_pkt_t pkt;
685
        VP9_COMP *cpi = (VP9_COMP *)ctx->cpi;
John Koleszar's avatar
John Koleszar committed
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712

        /* Add the frame packet to the list of returned packets. */
        round = 1000000 * ctx->cfg.g_timebase.num / 2 - 1;
        delta = (dst_end_time_stamp - dst_time_stamp);
        pkt.kind = VPX_CODEC_CX_FRAME_PKT;
        pkt.data.frame.pts =
          (dst_time_stamp * ctx->cfg.g_timebase.den + round)
          / ctx->cfg.g_timebase.num / 10000000;
        pkt.data.frame.duration =
          (delta * ctx->cfg.g_timebase.den + round)
          / ctx->cfg.g_timebase.num / 10000000;
        pkt.data.frame.flags = lib_flags << 16;

        if (lib_flags & FRAMEFLAGS_KEY)
          pkt.data.frame.flags |= VPX_FRAME_IS_KEY;

        if (!cpi->common.show_frame) {
          pkt.data.frame.flags |= VPX_FRAME_IS_INVISIBLE;

          // This timestamp should be as close as possible to the
          // prior PTS so that if a decoder uses pts to schedule when
          // to do this, we start right after last frame was decoded.
          // Invisible frames have no duration.
          pkt.data.frame.pts = ((cpi->last_time_stamp_seen
                                 * ctx->cfg.g_timebase.den + round)
                                / ctx->cfg.g_timebase.num / 10000000) + 1;
          pkt.data.frame.duration = 0;
John Koleszar's avatar
John Koleszar committed
713 714
        }

John Koleszar's avatar
John Koleszar committed
715 716
        if (cpi->droppable)
          pkt.data.frame.flags |= VPX_FRAME_IS_DROPPABLE;
John Koleszar's avatar
John Koleszar committed
717

John Koleszar's avatar
John Koleszar committed
718
        /*if (cpi->output_partition)
John Koleszar's avatar
John Koleszar committed
719
        {
John Koleszar's avatar
John Koleszar committed
720 721 722 723 724 725
            int i;
            const int num_partitions = 1;

            pkt.data.frame.flags |= VPX_FRAME_IS_FRAGMENT;

            for (i = 0; i < num_partitions; ++i)
John Koleszar's avatar
John Koleszar committed
726
            {
John Koleszar's avatar
John Koleszar committed
727 728 729 730 731 732 733 734 735
                pkt.data.frame.buf = cx_data;
                pkt.data.frame.sz = cpi->partition_sz[i];
                pkt.data.frame.partition_id = i;
                // don't set the fragment bit for the last partition
                if (i == (num_partitions - 1))
                    pkt.data.frame.flags &= ~VPX_FRAME_IS_FRAGMENT;
                vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
                cx_data += cpi->partition_sz[i];
                cx_data_sz -= cpi->partition_sz[i];
John Koleszar's avatar
John Koleszar committed
736 737
            }
        }
John Koleszar's avatar
John Koleszar committed
738 739 740 741 742 743 744 745 746 747 748 749
        else*/
        {
          pkt.data.frame.buf = cx_data;
          pkt.data.frame.sz  = size;
          pkt.data.frame.partition_id = -1;
          vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
          cx_data += size;
          cx_data_sz -= size;
        }

        // printf("timestamp: %lld, duration: %d\n", pkt->data.frame.pts, pkt->data.frame.duration);
      }
John Koleszar's avatar
John Koleszar committed
750
    }
John Koleszar's avatar
John Koleszar committed
751
  }
John Koleszar's avatar
John Koleszar committed
752

John Koleszar's avatar
John Koleszar committed
753
  return res;
John Koleszar's avatar
John Koleszar committed
754 755 756 757
}


static const vpx_codec_cx_pkt_t *vp8e_get_cxdata(vpx_codec_alg_priv_t  *ctx,
John Koleszar's avatar
John Koleszar committed
758 759
                                                 vpx_codec_iter_t      *iter) {
  return vpx_codec_pkt_list_get(&ctx->pkt_list.head, iter);
John Koleszar's avatar
John Koleszar committed
760 761 762
}

static vpx_codec_err_t vp8e_set_reference(vpx_codec_alg_priv_t *ctx,
John Koleszar's avatar
John Koleszar committed
763 764 765
                                          int ctr_id,
                                          va_list args) {
  vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
John Koleszar's avatar
John Koleszar committed
766

John Koleszar's avatar
John Koleszar committed
767 768 769
  if (data) {
    vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
    YV12_BUFFER_CONFIG sd;
John Koleszar's avatar
John Koleszar committed
770

John Koleszar's avatar
John Koleszar committed
771
    image2yuvconfig(&frame->img, &sd);
772
    vp9_set_reference_enc(ctx->cpi, frame->frame_type, &sd);
John Koleszar's avatar
John Koleszar committed
773 774 775
    return VPX_CODEC_OK;
  } else
    return VPX_CODEC_INVALID_PARAM;
John Koleszar's avatar
John Koleszar committed
776 777 778 779

}

static vpx_codec_err_t vp8e_get_reference(vpx_codec_alg_priv_t *ctx,
John Koleszar's avatar
John Koleszar committed
780 781
                                          int ctr_id,
                                          va_list args) {
John Koleszar's avatar
John Koleszar committed
782

John Koleszar's avatar
John Koleszar committed
783
  vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
John Koleszar's avatar
John Koleszar committed
784

John Koleszar's avatar
John Koleszar committed
785 786 787
  if (data) {
    vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
    YV12_BUFFER_CONFIG sd;
John Koleszar's avatar
John Koleszar committed
788

John Koleszar's avatar
John Koleszar committed
789
    image2yuvconfig(&frame->img, &sd);
790
    vp9_get_reference_enc(ctx->cpi, frame->frame_type, &sd);
John Koleszar's avatar
John Koleszar committed
791 792 793
    return VPX_CODEC_OK;
  } else
    return VPX_CODEC_INVALID_PARAM;
John Koleszar's avatar
John Koleszar committed
794 795 796
}

static vpx_codec_err_t vp8e_set_previewpp(vpx_codec_alg_priv_t *ctx,
John Koleszar's avatar
John Koleszar committed
797 798
                                          int ctr_id,
                                          va_list args) {
799
#if CONFIG_POSTPROC
John Koleszar's avatar
John Koleszar committed
800 801
  vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *);
  (void)ctr_id;
John Koleszar's avatar
John Koleszar committed
802

John Koleszar's avatar
John Koleszar committed
803 804 805 806 807
  if (data) {
    ctx->preview_ppcfg = *((vp8_postproc_cfg_t *)data);
    return VPX_CODEC_OK;
  } else
    return VPX_CODEC_INVALID_PARAM;
808
#else
John Koleszar's avatar
John Koleszar committed
809 810 811 812
  (void)ctx;
  (void)ctr_id;
  (void)args;
  return VPX_CODEC_INCAPABLE;
813
#endif
John Koleszar's avatar
John Koleszar committed
814 815 816
}


John Koleszar's avatar
John Koleszar committed
817
static vpx_image_t *vp8e_get_preview(vpx_codec_alg_priv_t *ctx) {
John Koleszar's avatar
John Koleszar committed
818

John Koleszar's avatar
John Koleszar committed
819
  YV12_BUFFER_CONFIG sd;
820
  vp9_ppflags_t flags = {0};
John Koleszar's avatar
John Koleszar committed
821

John Koleszar's avatar
John Koleszar committed
822 823 824 825 826
  if (ctx->preview_ppcfg.post_proc_flag) {
    flags.post_proc_flag        = ctx->preview_ppcfg.post_proc_flag;
    flags.deblocking_level      = ctx->preview_ppcfg.deblocking_level;
    flags.noise_level           = ctx->preview_ppcfg.noise_level;
  }
827

828
  if (0 == vp9_get_preview_raw_frame(ctx->cpi, &sd, &flags)) {
John Koleszar's avatar
John Koleszar committed
829

John Koleszar's avatar
John Koleszar committed
830 831
    /*
    vpx_img_wrap(&ctx->preview_img, VPX_IMG_FMT_YV12,
John Koleszar's avatar
John Koleszar committed
832 833
        sd.y_width + 2*VP9BORDERINPIXELS,
        sd.y_height + 2*VP9BORDERINPIXELS,
John Koleszar's avatar
John Koleszar committed
834 835 836
        1,
        sd.buffer_alloc);
    vpx_img_set_rect(&ctx->preview_img,
John Koleszar's avatar
John Koleszar committed
837
        VP9BORDERINPIXELS, VP9BORDERINPIXELS,
John Koleszar's avatar
John Koleszar committed
838 839 840 841 842 843 844 845 846 847
        sd.y_width, sd.y_height);
        */

    ctx->preview_img.bps = 12;
    ctx->preview_img.planes[VPX_PLANE_Y] = sd.y_buffer;
    ctx->preview_img.planes[VPX_PLANE_U] = sd.u_buffer;
    ctx->preview_img.planes[VPX_PLANE_V] = sd.v_buffer;

    if (sd.clrtype == REG_YUV)
      ctx->preview_img.fmt = VPX_IMG_FMT_I420;
John Koleszar's avatar
John Koleszar committed
848
    else
John Koleszar's avatar
John Koleszar committed
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864
      ctx->preview_img.fmt = VPX_IMG_FMT_VPXI420;

    ctx->preview_img.x_chroma_shift = 1;
    ctx->preview_img.y_chroma_shift = 1;

    ctx->preview_img.d_w = sd.y_width;
    ctx->preview_img.d_h = sd.y_height;
    ctx->preview_img.stride[VPX_PLANE_Y] = sd.y_stride;
    ctx->preview_img.stride[VPX_PLANE_U] = sd.uv_stride;
    ctx->preview_img.stride[VPX_PLANE_V] = sd.uv_stride;
    ctx->preview_img.w   = sd.y_width;
    ctx->preview_img.h   = sd.y_height;

    return &ctx->preview_img;
  } else
    return NULL;
John Koleszar's avatar
John Koleszar committed
865 866 867
}

static vpx_codec_err_t vp8e_update_entropy(vpx_codec_alg_priv_t *ctx,
John Koleszar's avatar
John Koleszar committed
868 869 870
                                           int ctr_id,
                                           va_list args) {
  int update = va_arg(args, int);
871
  vp9_update_entropy(ctx->cpi, update);
John Koleszar's avatar
John Koleszar committed
872
  return VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
873 874 875 876

}

static vpx_codec_err_t vp8e_update_reference(vpx_codec_alg_priv_t *ctx,
John Koleszar's avatar
John Koleszar committed
877 878 879
                                             int ctr_id,
                                             va_list args) {
  int update = va_arg(args, int);
880
  vp9_update_reference(ctx->cpi, update);
John Koleszar's avatar
John Koleszar committed
881
  return VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
882 883 884
}

static vpx_codec_err_t vp8e_use_reference(vpx_codec_alg_priv_t *ctx,
John Koleszar's avatar
John Koleszar committed
885 886 887
                                          int ctr_id,
                                          va_list args) {
  int reference_flag = va_arg(args, int);
888
  vp9_use_as_reference(ctx->cpi, reference_flag);
John Koleszar's avatar
John Koleszar committed
889
  return VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
890 891 892 893
}

static vpx_codec_err_t vp8e_set_roi_map(vpx_codec_alg_priv_t *ctx,
                                        int ctr_id,
John Koleszar's avatar
John Koleszar committed
894 895
                                        va_list args) {
  vpx_roi_map_t *data = va_arg(args, vpx_roi_map_t *);
John Koleszar's avatar
John Koleszar committed
896

John Koleszar's avatar
John Koleszar committed
897 898
  if (data) {
    vpx_roi_map_t *roi = (vpx_roi_map_t *)data;
John Koleszar's avatar
John Koleszar committed
899

900 901
    if (!vp9_set_roimap(ctx->cpi, roi->roi_map, roi->rows, roi->cols,
                        roi->delta_q, roi->delta_lf, roi->static_threshold))
John Koleszar's avatar
John Koleszar committed
902
      return VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
903
    else
John Koleszar's avatar
John Koleszar committed
904 905 906
      return VPX_CODEC_INVALID_PARAM;
  } else
    return VPX_CODEC_INVALID_PARAM;
John Koleszar's avatar
John Koleszar committed
907 908 909 910
}


static vpx_codec_err_t vp8e_set_activemap(vpx_codec_alg_priv_t *ctx,
John Koleszar's avatar
John Koleszar committed
911 912 913
                                          int ctr_id,
                                          va_list args) {
  vpx_active_map_t *data = va_arg(args, vpx_active_map_t *);
John Koleszar's avatar
John Koleszar committed
914

John Koleszar's avatar
John Koleszar committed
915
  if (data) {
John Koleszar's avatar
John Koleszar committed
916

John Koleszar's avatar
John Koleszar committed
917
    vpx_active_map_t *map = (vpx_active_map_t *)data;
John Koleszar's avatar
John Koleszar committed
918

919
    if (!vp9_set_active_map(ctx->cpi, map->active_map, map->rows, map->cols))
John Koleszar's avatar
John Koleszar committed
920
      return VPX_CODEC_OK;
John Koleszar's avatar
John Koleszar committed
921
    else
John Koleszar's avatar
John Koleszar committed
922 923 924
      return VPX_CODEC_INVALID_PARAM;
  } else
    return VPX_CODEC_INVALID_PARAM;
John Koleszar's avatar
John Koleszar committed
925 926 927
}

static vpx_codec_err_t vp8e_set_scalemode(vpx_codec_alg_priv_t *ctx,
John Koleszar's avatar
John Koleszar committed
928 929 930 931 932 933 934 935
                                          int ctr_id,
                                          va_list args) {

  vpx_scaling_mode_t *data =  va_arg(args, vpx_scaling_mode_t *);

  if (data) {
    int res;
    vpx_scaling_mode_t scalemode = *(vpx_scaling_mode_t *)data;
936 937
    res = vp9_set_internal_size(ctx->cpi, scalemode.h_scaling_mode,
                                scalemode.v_scaling_mode);
John Koleszar's avatar
John Koleszar committed
938 939 940 941 942 943 944 945 946

    if (!res) {
      /*force next frame a key frame to effect scaling mode */
      ctx->next_frame_flag |= FRAMEFLAGS_KEY;
      return VPX_CODEC_OK;
    } else
      return VPX_CODEC_INVALID_PARAM;
  } else
    return VPX_CODEC_INVALID_PARAM;
John Koleszar's avatar
John Koleszar committed
947 948 949
}


John Koleszar's avatar
John Koleszar committed
950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975
static vpx_codec_ctrl_fn_map_t vp8e_ctf_maps[] = {
  {VP8_SET_REFERENCE,                 vp8e_set_reference},
  {VP8_COPY_REFERENCE,                vp8e_get_reference},
  {VP8_SET_POSTPROC,                  vp8e_set_previewpp},
  {VP8E_UPD_ENTROPY,                  vp8e_update_entropy},
  {VP8E_UPD_REFERENCE,                vp8e_update_reference},
  {VP8E_USE_REFERENCE,                vp8e_use_reference},
  {VP8E_SET_ROI_MAP,                  vp8e_set_roi_map},
  {VP8E_SET_ACTIVEMAP,                vp8e_set_activemap},
  {VP8E_SET_SCALEMODE,                vp8e_set_scalemode},
  {VP8E_SET_ENCODING_MODE,            set_param},
  {VP8E_SET_CPUUSED,                  set_param},
  {VP8E_SET_NOISE_SENSITIVITY,        set_param},
  {VP8E_SET_ENABLEAUTOALTREF,         set_param},
  {VP8E_SET_SHARPNESS,                set_param},
  {VP8E_SET_STATIC_THRESHOLD,         set_param},
  {VP8E_SET_TOKEN_PARTITIONS,         set_param},
  {VP8E_GET_LAST_QUANTIZER,           get_param},
  {VP8E_GET_LAST_QUANTIZER_64,        get_param},
  {VP8E_SET_ARNR_MAXFRAMES,           set_param},
  {VP8E_SET_ARNR_STRENGTH,           set_param},
  {VP8E_SET_ARNR_TYPE,           set_param},
  {VP8E_SET_TUNING,                   set_param},
  {VP8E_SET_CQ_LEVEL,                 set_param},
  {VP8E_SET_MAX_INTRA_BITRATE_PCT,    set_param},
  { -1, NULL},
John Koleszar's avatar
John Koleszar committed
976 977
};

John Koleszar's avatar
John Koleszar committed
978 979
static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] = {
  {
John Koleszar's avatar
John Koleszar committed
980 981
    0,
    {
John Koleszar's avatar
John Koleszar committed
982 983 984
      0,                  /* g_usage */
      0,                  /* g_threads */
      0,                  /* g_profile */
John Koleszar's avatar
John Koleszar committed
985

John Koleszar's avatar
John Koleszar committed
986 987 988
      320,                /* g_width */
      240,                /* g_height */
      {1, 30},            /* g_timebase */
John Koleszar's avatar
John Koleszar committed
989

John Koleszar's avatar
John Koleszar committed
990
      0,                  /* g_error_resilient */
John Koleszar's avatar
John Koleszar committed
991

John Koleszar's avatar
John Koleszar committed
992
      VPX_RC_ONE_PASS,    /* g_pass */
John Koleszar's avatar
John Koleszar committed
993

John Koleszar's avatar
John Koleszar committed
994
      0,                  /* g_lag_in_frames */
John Koleszar's avatar
John Koleszar committed
995

John Koleszar's avatar
John Koleszar committed
996 997 998 999
      0,                  /* rc_dropframe_thresh */
      0,                  /* rc_resize_allowed */
      60,                 /* rc_resize_down_thresold */
      30,                 /* rc_resize_up_thresold */
John Koleszar's avatar
John Koleszar committed
1000

John Koleszar's avatar
John Koleszar committed
1001
      VPX_VBR,            /* rc_end_usage */
John Koleszar's avatar
John Koleszar committed
1002
#if VPX_ENCODER_ABI_VERSION > (1 + VPX_CODEC_ABI_VERSION)
John Koleszar's avatar
John Koleszar committed
1003
      {0},                /* rc_twopass_stats_in */
John Koleszar's avatar
John Koleszar committed
1004
#endif
John Koleszar's avatar
John Koleszar committed
1005 1006 1007 1008 1009
      256,                /* rc_target_bandwidth */
      4,                  /* rc_min_quantizer */
      63,                 /* rc_max_quantizer */
      100,                /* rc_undershoot_pct */
      100,                /* rc_overshoot_pct */
John Koleszar's avatar
John Koleszar committed
1010

John Koleszar's avatar
John Koleszar committed
1011 1012 1013
      6000,               /* rc_max_buffer_size */
      4000,               /* rc_buffer_initial_size; */
      5000,               /* rc_buffer_optimal_size; */
John Koleszar's avatar
John Koleszar committed
1014

John Koleszar's avatar
John Koleszar committed
1015 1016 1017
      50,                 /* rc_two_pass_vbrbias  */
      0,                  /* rc_two_pass_vbrmin_section */
      400,                /* rc_two_pass_vbrmax_section */
John Koleszar's avatar
John Koleszar committed
1018

John Koleszar's avatar
John Koleszar committed
1019 1020 1021 1022
      /* keyframing settings (kf) */
      VPX_KF_AUTO,        /* g_kfmode*/
      0,                  /* kf_min_dist */
      9999,               /* kf_max_dist */
John Koleszar's avatar
John Koleszar committed
1023 1024

#if VPX_ENCODER_ABI_VERSION == (1 + VPX_CODEC_ABI_VERSION)
John Koleszar's avatar
John Koleszar committed
1025 1026
      1,                  /* g_delete_first_pass_file */
      "vp8.fpf"           /* first pass filename */
John Koleszar's avatar
John Koleszar committed
1027
#endif
John Koleszar's avatar
John Koleszar committed
1028 1029 1030
    }
  },
  { -1, {NOT_IMPLEMENTED}}
John Koleszar's avatar
John Koleszar committed
1031 1032 1033 1034 1035 1036
};


#ifndef VERSION_STRING
#define VERSION_STRING
#endif
John Koleszar's avatar
John Koleszar committed
1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
CODEC_INTERFACE(vpx_codec_vp8_cx) = {
  "WebM Project VP8 Encoder" VERSION_STRING,
  VPX_CODEC_INTERNAL_ABI_VERSION,
  VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR |
  VPX_CODEC_CAP_OUTPUT_PARTITION,
  /* vpx_codec_caps_t          caps; */
  vp8e_init,          /* vpx_codec_init_fn_t       init; */
  vp8e_destroy,       /* vpx_codec_destroy_fn_t    destroy; */
  vp8e_ctf_maps,      /* vpx_codec_ctrl_fn_map_t  *ctrl_maps; */
  NOT_IMPLEMENTED,    /* vpx_codec_get_mmap_fn_t   get_mmap; */
  NOT_IMPLEMENTED,    /* vpx_codec_set_mmap_fn_t   set_mmap; */
  {
    NOT_IMPLEMENTED,    /* vpx_codec_peek_si_fn_t    peek_si; */
    NOT_IMPLEMENTED,    /* vpx_codec_get_si_fn_t     get_si; */
    NOT_IMPLEMENTED,    /* vpx_codec_decode_fn_t     decode; */
    NOT_IMPLEMENTED,    /* vpx_codec_frame_get_fn_t  frame_get; */
  },
  {
    vp8e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t    peek_si; */
    vp8e_encode,        /* vpx_codec_encode_fn_t      encode; */
    vp8e_get_cxdata,    /* vpx_codec_get_cx_data_fn_t   frame_get; */
    vp8e_set_config,
    NOT_IMPLEMENTED,
    vp8e_get_preview,
  } /* encoder functions */
John Koleszar's avatar
John Koleszar committed
1062 1063 1064
};


1065
#if CONFIG_EXPERIMENTAL
Jim Bankoski's avatar
Jim Bankoski committed
1066 1067

CODEC_INTERFACE(vpx_codec_vp8x_cx) = {
John Koleszar's avatar
John Koleszar committed
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
  "VP8 Experimental Encoder" VERSION_STRING,
  VPX_CODEC_INTERNAL_ABI_VERSION,
  VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR,
  /* vpx_codec_caps_t          caps; */
  vp8e_exp_init,      /* vpx_codec_init_fn_t       init; */
  vp8e_destroy,       /* vpx_codec_destroy_fn_t    destroy; */
  vp8e_ctf_maps,      /* vpx_codec_ctrl_fn_map_t  *ctrl_maps; */
  NOT_IMPLEMENTED,    /* vpx_codec_get_mmap_fn_t   get_mmap; */
  NOT_IMPLEMENTED,    /* vpx_codec_set_mmap_fn_t   set_mmap; */
  {
    NOT_IMPLEMENTED,    /* vpx_codec_peek_si_fn_t    peek_si; */
    NOT_IMPLEMENTED,    /* vpx_codec_get_si_fn_t     get_si; */
    NOT_IMPLEMENTED,    /* vpx_codec_decode_fn_t     decode; */
    NOT_IMPLEMENTED,    /* vpx_codec_frame_get_fn_t  frame_get; */
  },
  {
    vp8e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t    peek_si; */
    vp8e_encode,        /* vpx_codec_encode_fn_t      encode; */
    vp8e_get_cxdata,    /* vpx_codec_get_cx_data_fn_t   frame_get; */
    vp8e_set_config,
    NOT_IMPLEMENTED,
    vp8e_get_preview,
  } /* encoder functions */