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
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
    /*
    vpx_img_wrap(&ctx->preview_img, VPX_IMG_FMT_YV12,
        sd.y_width + 2*VP8BORDERINPIXELS,
        sd.y_height + 2*VP8BORDERINPIXELS,
        1,
        sd.buffer_alloc);
    vpx_img_set_rect(&ctx->preview_img,
        VP8BORDERINPIXELS, VP8BORDERINPIXELS,
        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