Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / libvpx / source / libvpx / vp9 / vp9_cx_iface.c
1 /*
2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  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.
9  */
10
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "./vpx_config.h"
15 #include "vpx/vpx_codec.h"
16 #include "vpx/internal/vpx_codec_internal.h"
17 #include "./vpx_version.h"
18 #include "vp9/encoder/vp9_encoder.h"
19 #include "vpx/vp8cx.h"
20 #include "vp9/encoder/vp9_firstpass.h"
21 #include "vp9/vp9_iface_common.h"
22
23 struct vp9_extracfg {
24   int                         cpu_used;  // available cpu percentage in 1/16
25   unsigned int                enable_auto_alt_ref;
26   unsigned int                noise_sensitivity;
27   unsigned int                sharpness;
28   unsigned int                static_thresh;
29   unsigned int                tile_columns;
30   unsigned int                tile_rows;
31   unsigned int                arnr_max_frames;
32   unsigned int                arnr_strength;
33   vp8e_tuning                 tuning;
34   unsigned int                cq_level;  // constrained quality level
35   unsigned int                rc_max_intra_bitrate_pct;
36   unsigned int                lossless;
37   unsigned int                frame_parallel_decoding_mode;
38   AQ_MODE                     aq_mode;
39   unsigned int                frame_periodic_boost;
40   vpx_bit_depth_t             bit_depth;
41   vp9e_tune_content           content;
42 };
43
44 static struct vp9_extracfg default_extra_cfg = {
45   0,                          // cpu_used
46   1,                          // enable_auto_alt_ref
47   0,                          // noise_sensitivity
48   0,                          // sharpness
49   0,                          // static_thresh
50   0,                          // tile_columns
51   0,                          // tile_rows
52   7,                          // arnr_max_frames
53   5,                          // arnr_strength
54   VP8_TUNE_PSNR,              // tuning
55   10,                         // cq_level
56   0,                          // rc_max_intra_bitrate_pct
57   0,                          // lossless
58   0,                          // frame_parallel_decoding_mode
59   NO_AQ,                      // aq_mode
60   0,                          // frame_periodic_delta_q
61   VPX_BITS_8,                 // Bit depth
62   VP9E_CONTENT_DEFAULT        // content
63 };
64
65 struct vpx_codec_alg_priv {
66   vpx_codec_priv_t        base;
67   vpx_codec_enc_cfg_t     cfg;
68   struct vp9_extracfg     extra_cfg;
69   VP9EncoderConfig        oxcf;
70   VP9_COMP               *cpi;
71   unsigned char          *cx_data;
72   size_t                  cx_data_sz;
73   unsigned char          *pending_cx_data;
74   size_t                  pending_cx_data_sz;
75   int                     pending_frame_count;
76   size_t                  pending_frame_sizes[8];
77   size_t                  pending_frame_magnitude;
78   vpx_image_t             preview_img;
79   vp8_postproc_cfg_t      preview_ppcfg;
80   vpx_codec_pkt_list_decl(256) pkt_list;
81   unsigned int                 fixed_kf_cntr;
82 };
83
84 static VP9_REFFRAME ref_frame_to_vp9_reframe(vpx_ref_frame_type_t frame) {
85   switch (frame) {
86     case VP8_LAST_FRAME:
87       return VP9_LAST_FLAG;
88     case VP8_GOLD_FRAME:
89       return VP9_GOLD_FLAG;
90     case VP8_ALTR_FRAME:
91       return VP9_ALT_FLAG;
92   }
93   assert(0 && "Invalid Reference Frame");
94   return VP9_LAST_FLAG;
95 }
96
97 static vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx,
98     const struct vpx_internal_error_info *error) {
99   const vpx_codec_err_t res = error->error_code;
100
101   if (res != VPX_CODEC_OK)
102     ctx->base.err_detail = error->has_detail ? error->detail : NULL;
103
104   return res;
105 }
106
107
108 #undef ERROR
109 #define ERROR(str) do {\
110     ctx->base.err_detail = str;\
111     return VPX_CODEC_INVALID_PARAM;\
112   } while (0)
113
114 #define RANGE_CHECK(p, memb, lo, hi) do {\
115     if (!(((p)->memb == lo || (p)->memb > (lo)) && (p)->memb <= hi)) \
116       ERROR(#memb " out of range ["#lo".."#hi"]");\
117   } while (0)
118
119 #define RANGE_CHECK_HI(p, memb, hi) do {\
120     if (!((p)->memb <= (hi))) \
121       ERROR(#memb " out of range [.."#hi"]");\
122   } while (0)
123
124 #define RANGE_CHECK_LO(p, memb, lo) do {\
125     if (!((p)->memb >= (lo))) \
126       ERROR(#memb " out of range ["#lo"..]");\
127   } while (0)
128
129 #define RANGE_CHECK_BOOL(p, memb) do {\
130     if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean");\
131   } while (0)
132
133 static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
134                                        const vpx_codec_enc_cfg_t *cfg,
135                                        const struct vp9_extracfg *extra_cfg) {
136   RANGE_CHECK(cfg, g_w,                   1, 65535);  // 16 bits available
137   RANGE_CHECK(cfg, g_h,                   1, 65535);  // 16 bits available
138   RANGE_CHECK(cfg, g_timebase.den,        1, 1000000000);
139   RANGE_CHECK(cfg, g_timebase.num,        1, cfg->g_timebase.den);
140   RANGE_CHECK_HI(cfg, g_profile,          3);
141
142   RANGE_CHECK_HI(cfg, rc_max_quantizer,   63);
143   RANGE_CHECK_HI(cfg, rc_min_quantizer,   cfg->rc_max_quantizer);
144   RANGE_CHECK_BOOL(extra_cfg, lossless);
145   RANGE_CHECK(extra_cfg, aq_mode,           0, AQ_MODE_COUNT - 1);
146   RANGE_CHECK(extra_cfg, frame_periodic_boost, 0, 1);
147   RANGE_CHECK_HI(cfg, g_threads,          64);
148   RANGE_CHECK_HI(cfg, g_lag_in_frames,    MAX_LAG_BUFFERS);
149   RANGE_CHECK(cfg, rc_end_usage,          VPX_VBR, VPX_Q);
150   RANGE_CHECK_HI(cfg, rc_undershoot_pct,  1000);
151   RANGE_CHECK_HI(cfg, rc_overshoot_pct,   1000);
152   RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100);
153   RANGE_CHECK(cfg, kf_mode,               VPX_KF_DISABLED, VPX_KF_AUTO);
154   RANGE_CHECK_BOOL(cfg,                   rc_resize_allowed);
155   RANGE_CHECK_HI(cfg, rc_dropframe_thresh,   100);
156   RANGE_CHECK_HI(cfg, rc_resize_up_thresh,   100);
157   RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100);
158   RANGE_CHECK(cfg,        g_pass,         VPX_RC_ONE_PASS, VPX_RC_LAST_PASS);
159
160   if (cfg->rc_resize_allowed == 1) {
161     RANGE_CHECK(cfg, rc_scaled_width, 1, cfg->g_w);
162     RANGE_CHECK(cfg, rc_scaled_height, 1, cfg->g_h);
163   }
164
165   RANGE_CHECK(cfg, ss_number_layers, 1, VPX_SS_MAX_LAYERS);
166   RANGE_CHECK(cfg, ts_number_layers, 1, VPX_TS_MAX_LAYERS);
167
168   if (cfg->ts_number_layers > 1) {
169     unsigned int i;
170     for (i = 1; i < cfg->ts_number_layers; ++i)
171       if (cfg->ts_target_bitrate[i] < cfg->ts_target_bitrate[i - 1])
172         ERROR("ts_target_bitrate entries are not increasing");
173
174     RANGE_CHECK(cfg, ts_rate_decimator[cfg->ts_number_layers - 1], 1, 1);
175     for (i = cfg->ts_number_layers - 2; i > 0; --i)
176       if (cfg->ts_rate_decimator[i - 1] != 2 * cfg->ts_rate_decimator[i])
177         ERROR("ts_rate_decimator factors are not powers of 2");
178   }
179
180 #if CONFIG_SPATIAL_SVC
181
182   if ((cfg->ss_number_layers > 1 || cfg->ts_number_layers > 1) &&
183       cfg->g_pass == VPX_RC_LAST_PASS) {
184     unsigned int i, alt_ref_sum = 0;
185     for (i = 0; i < cfg->ss_number_layers; ++i) {
186       if (cfg->ss_enable_auto_alt_ref[i])
187         ++alt_ref_sum;
188     }
189     if (alt_ref_sum > REF_FRAMES - cfg->ss_number_layers)
190       ERROR("Not enough ref buffers for svc alt ref frames");
191     if (cfg->ss_number_layers * cfg->ts_number_layers > 3 &&
192         cfg->g_error_resilient == 0)
193     ERROR("Multiple frame context are not supported for more than 3 layers");
194   }
195 #endif
196
197   // VP9 does not support a lower bound on the keyframe interval in
198   // automatic keyframe placement mode.
199   if (cfg->kf_mode != VPX_KF_DISABLED &&
200       cfg->kf_min_dist != cfg->kf_max_dist &&
201       cfg->kf_min_dist > 0)
202     ERROR("kf_min_dist not supported in auto mode, use 0 "
203           "or kf_max_dist instead.");
204
205   RANGE_CHECK_BOOL(extra_cfg,  enable_auto_alt_ref);
206   RANGE_CHECK(extra_cfg, cpu_used, -16, 16);
207   RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6);
208   RANGE_CHECK(extra_cfg, tile_columns, 0, 6);
209   RANGE_CHECK(extra_cfg, tile_rows, 0, 2);
210   RANGE_CHECK_HI(extra_cfg, sharpness, 7);
211   RANGE_CHECK(extra_cfg, arnr_max_frames, 0, 15);
212   RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);
213   RANGE_CHECK(extra_cfg, cq_level, 0, 63);
214   RANGE_CHECK(cfg, g_bit_depth, VPX_BITS_8, VPX_BITS_12);
215   RANGE_CHECK(cfg, g_input_bit_depth, 8, 12);
216   RANGE_CHECK(extra_cfg, content,
217               VP9E_CONTENT_DEFAULT, VP9E_CONTENT_INVALID - 1);
218
219   // TODO(yaowu): remove this when ssim tuning is implemented for vp9
220   if (extra_cfg->tuning == VP8_TUNE_SSIM)
221       ERROR("Option --tune=ssim is not currently supported in VP9.");
222
223   if (cfg->g_pass == VPX_RC_LAST_PASS) {
224     const size_t packet_sz = sizeof(FIRSTPASS_STATS);
225     const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz);
226     const FIRSTPASS_STATS *stats;
227
228     if (cfg->rc_twopass_stats_in.buf == NULL)
229       ERROR("rc_twopass_stats_in.buf not set.");
230
231     if (cfg->rc_twopass_stats_in.sz % packet_sz)
232       ERROR("rc_twopass_stats_in.sz indicates truncated packet.");
233
234     if (cfg->ss_number_layers > 1 || cfg->ts_number_layers > 1) {
235       int i;
236       unsigned int n_packets_per_layer[VPX_SS_MAX_LAYERS] = {0};
237
238       stats = cfg->rc_twopass_stats_in.buf;
239       for (i = 0; i < n_packets; ++i) {
240         const int layer_id = (int)stats[i].spatial_layer_id;
241         if (layer_id >= 0 && layer_id < (int)cfg->ss_number_layers) {
242           ++n_packets_per_layer[layer_id];
243         }
244       }
245
246       for (i = 0; i < (int)cfg->ss_number_layers; ++i) {
247         unsigned int layer_id;
248         if (n_packets_per_layer[i] < 2) {
249           ERROR("rc_twopass_stats_in requires at least two packets for each "
250                 "layer.");
251         }
252
253         stats = (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf +
254                 n_packets - cfg->ss_number_layers + i;
255         layer_id = (int)stats->spatial_layer_id;
256
257         if (layer_id >= cfg->ss_number_layers
258             ||(unsigned int)(stats->count + 0.5) !=
259                n_packets_per_layer[layer_id] - 1)
260           ERROR("rc_twopass_stats_in missing EOS stats packet");
261       }
262     } else {
263       if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)
264         ERROR("rc_twopass_stats_in requires at least two packets.");
265
266       stats =
267           (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1;
268
269       if ((int)(stats->count + 0.5) != n_packets - 1)
270         ERROR("rc_twopass_stats_in missing EOS stats packet");
271     }
272   }
273
274 #if !CONFIG_VP9_HIGHBITDEPTH
275   if (cfg->g_profile > (unsigned int)PROFILE_1) {
276     ERROR("Profile > 1 not supported in this build configuration");
277   }
278 #endif
279   if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
280       cfg->g_bit_depth > VPX_BITS_8) {
281     ERROR("Codec high bit-depth not supported in profile < 2");
282   }
283   if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
284       cfg->g_input_bit_depth > 8) {
285     ERROR("Source high bit-depth not supported in profile < 2");
286   }
287   if (cfg->g_profile > (unsigned int)PROFILE_1 &&
288       cfg->g_bit_depth == VPX_BITS_8) {
289     ERROR("Codec bit-depth 8 not supported in profile > 1");
290   }
291
292   return VPX_CODEC_OK;
293 }
294
295 static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
296                                     const vpx_image_t *img) {
297   switch (img->fmt) {
298     case VPX_IMG_FMT_YV12:
299     case VPX_IMG_FMT_I420:
300     case VPX_IMG_FMT_I42016:
301       break;
302     case VPX_IMG_FMT_I422:
303     case VPX_IMG_FMT_I444:
304     case VPX_IMG_FMT_I440:
305       if (ctx->cfg.g_profile != (unsigned int)PROFILE_1) {
306         ERROR("Invalid image format. I422, I444, I440 images are "
307               "not supported in profile.");
308       }
309       break;
310     case VPX_IMG_FMT_I42216:
311     case VPX_IMG_FMT_I44416:
312     case VPX_IMG_FMT_I44016:
313       if (ctx->cfg.g_profile != (unsigned int)PROFILE_1 &&
314           ctx->cfg.g_profile != (unsigned int)PROFILE_3) {
315         ERROR("Invalid image format. 16-bit I422, I444, I440 images are "
316               "not supported in profile.");
317       }
318       break;
319     default:
320       ERROR("Invalid image format. Only YV12, I420, I422, I444 images are "
321             "supported.");
322       break;
323   }
324
325   if (img->d_w != ctx->cfg.g_w || img->d_h != ctx->cfg.g_h)
326     ERROR("Image size must match encoder init configuration size");
327
328   return VPX_CODEC_OK;
329 }
330
331 static int get_image_bps(const vpx_image_t *img) {
332   switch (img->fmt) {
333     case VPX_IMG_FMT_YV12:
334     case VPX_IMG_FMT_I420: return 12;
335     case VPX_IMG_FMT_I422: return 16;
336     case VPX_IMG_FMT_I444: return 24;
337     case VPX_IMG_FMT_I440: return 16;
338     case VPX_IMG_FMT_I42016: return 24;
339     case VPX_IMG_FMT_I42216: return 32;
340     case VPX_IMG_FMT_I44416: return 48;
341     case VPX_IMG_FMT_I44016: return 32;
342     default: assert(0 && "Invalid image format"); break;
343   }
344   return 0;
345 }
346
347 static vpx_codec_err_t set_encoder_config(
348     VP9EncoderConfig *oxcf,
349     const vpx_codec_enc_cfg_t *cfg,
350     const struct vp9_extracfg *extra_cfg) {
351   const int is_vbr = cfg->rc_end_usage == VPX_VBR;
352   oxcf->profile = cfg->g_profile;
353   oxcf->width   = cfg->g_w;
354   oxcf->height  = cfg->g_h;
355   oxcf->bit_depth = cfg->g_bit_depth;
356   oxcf->input_bit_depth = cfg->g_input_bit_depth;
357   // guess a frame rate if out of whack, use 30
358   oxcf->init_framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num;
359   if (oxcf->init_framerate > 180)
360     oxcf->init_framerate = 30;
361
362   oxcf->mode = GOOD;
363
364   switch (cfg->g_pass) {
365     case VPX_RC_ONE_PASS:
366       oxcf->pass = 0;
367       break;
368     case VPX_RC_FIRST_PASS:
369       oxcf->pass = 1;
370       break;
371     case VPX_RC_LAST_PASS:
372       oxcf->pass = 2;
373       break;
374   }
375
376   oxcf->lag_in_frames = cfg->g_pass == VPX_RC_FIRST_PASS ? 0
377                                                          : cfg->g_lag_in_frames;
378   oxcf->rc_mode = cfg->rc_end_usage;
379
380   // Convert target bandwidth from Kbit/s to Bit/s
381   oxcf->target_bandwidth = 1000 * cfg->rc_target_bitrate;
382   oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct;
383
384   oxcf->best_allowed_q =
385       extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_min_quantizer);
386   oxcf->worst_allowed_q =
387       extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_max_quantizer);
388   oxcf->cq_level        = vp9_quantizer_to_qindex(extra_cfg->cq_level);
389   oxcf->fixed_q = -1;
390
391   oxcf->under_shoot_pct         = cfg->rc_undershoot_pct;
392   oxcf->over_shoot_pct          = cfg->rc_overshoot_pct;
393
394   oxcf->allow_spatial_resampling = cfg->rc_resize_allowed;
395   oxcf->scaled_frame_width       = cfg->rc_scaled_width;
396   oxcf->scaled_frame_height      = cfg->rc_scaled_height;
397
398   oxcf->maximum_buffer_size_ms   = is_vbr ? 240000 : cfg->rc_buf_sz;
399   oxcf->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz;
400   oxcf->optimal_buffer_level_ms  = is_vbr ? 60000 : cfg->rc_buf_optimal_sz;
401
402   oxcf->drop_frames_water_mark   = cfg->rc_dropframe_thresh;
403
404   oxcf->two_pass_vbrbias         = cfg->rc_2pass_vbr_bias_pct;
405   oxcf->two_pass_vbrmin_section  = cfg->rc_2pass_vbr_minsection_pct;
406   oxcf->two_pass_vbrmax_section  = cfg->rc_2pass_vbr_maxsection_pct;
407
408   oxcf->auto_key               = cfg->kf_mode == VPX_KF_AUTO &&
409                                  cfg->kf_min_dist != cfg->kf_max_dist;
410
411   oxcf->key_freq               = cfg->kf_max_dist;
412
413   oxcf->speed                  =  abs(extra_cfg->cpu_used);
414   oxcf->encode_breakout        =  extra_cfg->static_thresh;
415   oxcf->play_alternate         =  extra_cfg->enable_auto_alt_ref;
416   oxcf->noise_sensitivity      =  extra_cfg->noise_sensitivity;
417   oxcf->sharpness              =  extra_cfg->sharpness;
418
419   oxcf->two_pass_stats_in      =  cfg->rc_twopass_stats_in;
420
421 #if CONFIG_FP_MB_STATS
422   oxcf->firstpass_mb_stats_in  = cfg->rc_firstpass_mb_stats_in;
423 #endif
424
425   oxcf->arnr_max_frames = extra_cfg->arnr_max_frames;
426   oxcf->arnr_strength   = extra_cfg->arnr_strength;
427
428   oxcf->tuning = extra_cfg->tuning;
429   oxcf->content = extra_cfg->content;
430
431   oxcf->tile_columns = extra_cfg->tile_columns;
432   oxcf->tile_rows    = extra_cfg->tile_rows;
433
434   oxcf->error_resilient_mode         = cfg->g_error_resilient;
435   oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode;
436
437   oxcf->aq_mode = extra_cfg->aq_mode;
438
439   oxcf->frame_periodic_boost =  extra_cfg->frame_periodic_boost;
440
441   oxcf->ss_number_layers = cfg->ss_number_layers;
442
443   if (oxcf->ss_number_layers > 1) {
444     int i;
445     for (i = 0; i < VPX_SS_MAX_LAYERS; ++i) {
446       oxcf->ss_target_bitrate[i] =  1000 * cfg->ss_target_bitrate[i];
447 #if CONFIG_SPATIAL_SVC
448       oxcf->ss_play_alternate[i] =  cfg->ss_enable_auto_alt_ref[i];
449 #endif
450     }
451   } else if (oxcf->ss_number_layers == 1) {
452     oxcf->ss_target_bitrate[0] = (int)oxcf->target_bandwidth;
453 #if CONFIG_SPATIAL_SVC
454     oxcf->ss_play_alternate[0] = extra_cfg->enable_auto_alt_ref;
455 #endif
456   }
457
458   oxcf->ts_number_layers = cfg->ts_number_layers;
459
460   if (oxcf->ts_number_layers > 1) {
461     int i;
462     for (i = 0; i < VPX_TS_MAX_LAYERS; ++i) {
463       oxcf->ts_target_bitrate[i] = 1000 * cfg->ts_target_bitrate[i];
464       oxcf->ts_rate_decimator[i] = cfg->ts_rate_decimator[i];
465     }
466   } else if (oxcf->ts_number_layers == 1) {
467     oxcf->ts_target_bitrate[0] = (int)oxcf->target_bandwidth;
468     oxcf->ts_rate_decimator[0] = 1;
469   }
470
471   /*
472   printf("Current VP9 Settings: \n");
473   printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
474   printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity);
475   printf("sharpness: %d\n",    oxcf->sharpness);
476   printf("cpu_used: %d\n",  oxcf->cpu_used);
477   printf("Mode: %d\n",     oxcf->mode);
478   printf("auto_key: %d\n",  oxcf->auto_key);
479   printf("key_freq: %d\n", oxcf->key_freq);
480   printf("end_usage: %d\n", oxcf->end_usage);
481   printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct);
482   printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct);
483   printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level);
484   printf("optimal_buffer_level: %d\n",  oxcf->optimal_buffer_level);
485   printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size);
486   printf("fixed_q: %d\n",  oxcf->fixed_q);
487   printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q);
488   printf("best_allowed_q: %d\n", oxcf->best_allowed_q);
489   printf("allow_spatial_resampling: %d\n", oxcf->allow_spatial_resampling);
490   printf("scaled_frame_width: %d\n", oxcf->scaled_frame_width);
491   printf("scaled_frame_height: %d\n", oxcf->scaled_frame_height);
492   printf("two_pass_vbrbias: %d\n",  oxcf->two_pass_vbrbias);
493   printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section);
494   printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section);
495   printf("lag_in_frames: %d\n", oxcf->lag_in_frames);
496   printf("play_alternate: %d\n", oxcf->play_alternate);
497   printf("Version: %d\n", oxcf->Version);
498   printf("encode_breakout: %d\n", oxcf->encode_breakout);
499   printf("error resilient: %d\n", oxcf->error_resilient_mode);
500   printf("frame parallel detokenization: %d\n",
501          oxcf->frame_parallel_decoding_mode);
502   */
503   return VPX_CODEC_OK;
504 }
505
506 static vpx_codec_err_t encoder_set_config(vpx_codec_alg_priv_t *ctx,
507                                           const vpx_codec_enc_cfg_t  *cfg) {
508   vpx_codec_err_t res;
509
510   if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h)
511     ERROR("Cannot change width or height after initialization");
512
513   // Prevent increasing lag_in_frames. This check is stricter than it needs
514   // to be -- the limit is not increasing past the first lag_in_frames
515   // value, but we don't track the initial config, only the last successful
516   // config.
517   if (cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames)
518     ERROR("Cannot increase lag_in_frames");
519
520   res = validate_config(ctx, cfg, &ctx->extra_cfg);
521
522   if (res == VPX_CODEC_OK) {
523     ctx->cfg = *cfg;
524     set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
525     vp9_change_config(ctx->cpi, &ctx->oxcf);
526   }
527
528   return res;
529 }
530
531 static vpx_codec_err_t ctrl_get_quantizer(vpx_codec_alg_priv_t *ctx,
532                                           va_list args) {
533   int *const arg = va_arg(args, int *);
534   if (arg == NULL)
535     return VPX_CODEC_INVALID_PARAM;
536   *arg = vp9_get_quantizer(ctx->cpi);
537   return VPX_CODEC_OK;
538 }
539
540 static vpx_codec_err_t ctrl_get_quantizer64(vpx_codec_alg_priv_t *ctx,
541                                             va_list args) {
542   int *const arg = va_arg(args, int *);
543   if (arg == NULL)
544     return VPX_CODEC_INVALID_PARAM;
545   *arg = vp9_qindex_to_quantizer(vp9_get_quantizer(ctx->cpi));
546   return VPX_CODEC_OK;
547 }
548
549 static vpx_codec_err_t update_extra_cfg(vpx_codec_alg_priv_t *ctx,
550                                         const struct vp9_extracfg *extra_cfg) {
551   const vpx_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg);
552   if (res == VPX_CODEC_OK) {
553     ctx->extra_cfg = *extra_cfg;
554     set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg);
555     vp9_change_config(ctx->cpi, &ctx->oxcf);
556   }
557   return res;
558 }
559
560 static vpx_codec_err_t ctrl_set_cpuused(vpx_codec_alg_priv_t *ctx,
561                                         va_list args) {
562   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
563   extra_cfg.cpu_used = CAST(VP8E_SET_CPUUSED, args);
564   return update_extra_cfg(ctx, &extra_cfg);
565 }
566
567 static vpx_codec_err_t ctrl_set_enable_auto_alt_ref(vpx_codec_alg_priv_t *ctx,
568                                                     va_list args) {
569   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
570   extra_cfg.enable_auto_alt_ref = CAST(VP8E_SET_ENABLEAUTOALTREF, args);
571   return update_extra_cfg(ctx, &extra_cfg);
572 }
573
574 static vpx_codec_err_t ctrl_set_noise_sensitivity(vpx_codec_alg_priv_t *ctx,
575                                                   va_list args) {
576   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
577   extra_cfg.noise_sensitivity = CAST(VP9E_SET_NOISE_SENSITIVITY, args);
578   return update_extra_cfg(ctx, &extra_cfg);
579 }
580
581 static vpx_codec_err_t ctrl_set_sharpness(vpx_codec_alg_priv_t *ctx,
582                                           va_list args) {
583   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
584   extra_cfg.sharpness = CAST(VP8E_SET_SHARPNESS, args);
585   return update_extra_cfg(ctx, &extra_cfg);
586 }
587
588 static vpx_codec_err_t ctrl_set_static_thresh(vpx_codec_alg_priv_t *ctx,
589                                               va_list args) {
590   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
591   extra_cfg.static_thresh = CAST(VP8E_SET_STATIC_THRESHOLD, args);
592   return update_extra_cfg(ctx, &extra_cfg);
593 }
594
595 static vpx_codec_err_t ctrl_set_tile_columns(vpx_codec_alg_priv_t *ctx,
596                                              va_list args) {
597   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
598   extra_cfg.tile_columns = CAST(VP9E_SET_TILE_COLUMNS, args);
599   return update_extra_cfg(ctx, &extra_cfg);
600 }
601
602 static vpx_codec_err_t ctrl_set_tile_rows(vpx_codec_alg_priv_t *ctx,
603                                           va_list args) {
604   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
605   extra_cfg.tile_rows = CAST(VP9E_SET_TILE_ROWS, args);
606   return update_extra_cfg(ctx, &extra_cfg);
607 }
608
609 static vpx_codec_err_t ctrl_set_arnr_max_frames(vpx_codec_alg_priv_t *ctx,
610                                                 va_list args) {
611   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
612   extra_cfg.arnr_max_frames = CAST(VP8E_SET_ARNR_MAXFRAMES, args);
613   return update_extra_cfg(ctx, &extra_cfg);
614 }
615
616 static vpx_codec_err_t ctrl_set_arnr_strength(vpx_codec_alg_priv_t *ctx,
617                                               va_list args) {
618   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
619   extra_cfg.arnr_strength = CAST(VP8E_SET_ARNR_STRENGTH, args);
620   return update_extra_cfg(ctx, &extra_cfg);
621 }
622
623 static vpx_codec_err_t ctrl_set_arnr_type(vpx_codec_alg_priv_t *ctx,
624                                           va_list args) {
625   (void)ctx;
626   (void)args;
627   return VPX_CODEC_OK;
628 }
629
630 static vpx_codec_err_t ctrl_set_tuning(vpx_codec_alg_priv_t *ctx,
631                                        va_list args) {
632   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
633   extra_cfg.tuning = CAST(VP8E_SET_TUNING, args);
634   return update_extra_cfg(ctx, &extra_cfg);
635 }
636
637 static vpx_codec_err_t ctrl_set_cq_level(vpx_codec_alg_priv_t *ctx,
638                                          va_list args) {
639   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
640   extra_cfg.cq_level = CAST(VP8E_SET_CQ_LEVEL, args);
641   return update_extra_cfg(ctx, &extra_cfg);
642 }
643
644 static vpx_codec_err_t ctrl_set_rc_max_intra_bitrate_pct(
645     vpx_codec_alg_priv_t *ctx, va_list args) {
646   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
647   extra_cfg.rc_max_intra_bitrate_pct =
648       CAST(VP8E_SET_MAX_INTRA_BITRATE_PCT, args);
649   return update_extra_cfg(ctx, &extra_cfg);
650 }
651
652 static vpx_codec_err_t ctrl_set_lossless(vpx_codec_alg_priv_t *ctx,
653                                          va_list args) {
654   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
655   extra_cfg.lossless = CAST(VP9E_SET_LOSSLESS, args);
656   return update_extra_cfg(ctx, &extra_cfg);
657 }
658
659 static vpx_codec_err_t ctrl_set_frame_parallel_decoding_mode(
660     vpx_codec_alg_priv_t *ctx, va_list args) {
661   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
662   extra_cfg.frame_parallel_decoding_mode =
663       CAST(VP9E_SET_FRAME_PARALLEL_DECODING, args);
664   return update_extra_cfg(ctx, &extra_cfg);
665 }
666
667 static vpx_codec_err_t ctrl_set_aq_mode(vpx_codec_alg_priv_t *ctx,
668                                         va_list args) {
669   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
670   extra_cfg.aq_mode = CAST(VP9E_SET_AQ_MODE, args);
671   return update_extra_cfg(ctx, &extra_cfg);
672 }
673
674 static vpx_codec_err_t ctrl_set_frame_periodic_boost(vpx_codec_alg_priv_t *ctx,
675                                                      va_list args) {
676   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
677   extra_cfg.frame_periodic_boost = CAST(VP9E_SET_FRAME_PERIODIC_BOOST, args);
678   return update_extra_cfg(ctx, &extra_cfg);
679 }
680
681 static vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx,
682                                     vpx_codec_priv_enc_mr_cfg_t *data) {
683   vpx_codec_err_t res = VPX_CODEC_OK;
684   (void)data;
685
686   if (ctx->priv == NULL) {
687     vpx_codec_alg_priv_t *const priv = vpx_calloc(1, sizeof(*priv));
688     if (priv == NULL)
689       return VPX_CODEC_MEM_ERROR;
690
691     ctx->priv = (vpx_codec_priv_t *)priv;
692     ctx->priv->init_flags = ctx->init_flags;
693     ctx->priv->enc.total_encoders = 1;
694
695     if (ctx->config.enc) {
696       // Update the reference to the config structure to an internal copy.
697       priv->cfg = *ctx->config.enc;
698       ctx->config.enc = &priv->cfg;
699     }
700
701     priv->extra_cfg = default_extra_cfg;
702     vp9_initialize_enc();
703
704     res = validate_config(priv, &priv->cfg, &priv->extra_cfg);
705
706     if (res == VPX_CODEC_OK) {
707       set_encoder_config(&priv->oxcf, &priv->cfg, &priv->extra_cfg);
708 #if CONFIG_VP9_HIGHBITDEPTH
709       priv->oxcf.use_highbitdepth =
710           (ctx->init_flags & VPX_CODEC_USE_HIGHBITDEPTH) ? 1 : 0;
711 #endif
712       priv->cpi = vp9_create_compressor(&priv->oxcf);
713       if (priv->cpi == NULL)
714         res = VPX_CODEC_MEM_ERROR;
715       else
716         priv->cpi->output_pkt_list = &priv->pkt_list.head;
717     }
718   }
719
720   return res;
721 }
722
723 static vpx_codec_err_t encoder_destroy(vpx_codec_alg_priv_t *ctx) {
724   free(ctx->cx_data);
725   vp9_remove_compressor(ctx->cpi);
726   vpx_free(ctx);
727   return VPX_CODEC_OK;
728 }
729
730 static void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx,
731                                     unsigned long duration,
732                                     unsigned long deadline) {
733   MODE new_mode = BEST;
734
735   switch (ctx->cfg.g_pass) {
736     case VPX_RC_ONE_PASS:
737       if (deadline > 0) {
738         const vpx_codec_enc_cfg_t *const cfg = &ctx->cfg;
739
740         // Convert duration parameter from stream timebase to microseconds.
741         const uint64_t duration_us = (uint64_t)duration * 1000000 *
742            (uint64_t)cfg->g_timebase.num /(uint64_t)cfg->g_timebase.den;
743
744         // If the deadline is more that the duration this frame is to be shown,
745         // use good quality mode. Otherwise use realtime mode.
746         new_mode = (deadline > duration_us) ? GOOD : REALTIME;
747       } else {
748         new_mode = BEST;
749       }
750       break;
751     case VPX_RC_FIRST_PASS:
752       break;
753     case VPX_RC_LAST_PASS:
754       new_mode = deadline > 0 ? GOOD : BEST;
755       break;
756   }
757
758   if (ctx->oxcf.mode != new_mode) {
759     ctx->oxcf.mode = new_mode;
760     vp9_change_config(ctx->cpi, &ctx->oxcf);
761   }
762 }
763
764 // Turn on to test if supplemental superframe data breaks decoding
765 // #define TEST_SUPPLEMENTAL_SUPERFRAME_DATA
766 static int write_superframe_index(vpx_codec_alg_priv_t *ctx) {
767   uint8_t marker = 0xc0;
768   unsigned int mask;
769   int mag, index_sz;
770
771   assert(ctx->pending_frame_count);
772   assert(ctx->pending_frame_count <= 8);
773
774   // Add the number of frames to the marker byte
775   marker |= ctx->pending_frame_count - 1;
776
777   // Choose the magnitude
778   for (mag = 0, mask = 0xff; mag < 4; mag++) {
779     if (ctx->pending_frame_magnitude < mask)
780       break;
781     mask <<= 8;
782     mask |= 0xff;
783   }
784   marker |= mag << 3;
785
786   // Write the index
787   index_sz = 2 + (mag + 1) * ctx->pending_frame_count;
788   if (ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz) {
789     uint8_t *x = ctx->pending_cx_data + ctx->pending_cx_data_sz;
790     int i, j;
791 #ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA
792     uint8_t marker_test = 0xc0;
793     int mag_test = 2;     // 1 - 4
794     int frames_test = 4;  // 1 - 8
795     int index_sz_test = 2 + mag_test * frames_test;
796     marker_test |= frames_test - 1;
797     marker_test |= (mag_test - 1) << 3;
798     *x++ = marker_test;
799     for (i = 0; i < mag_test * frames_test; ++i)
800       *x++ = 0;  // fill up with arbitrary data
801     *x++ = marker_test;
802     ctx->pending_cx_data_sz += index_sz_test;
803     printf("Added supplemental superframe data\n");
804 #endif
805
806     *x++ = marker;
807     for (i = 0; i < ctx->pending_frame_count; i++) {
808       unsigned int this_sz = (unsigned int)ctx->pending_frame_sizes[i];
809
810       for (j = 0; j <= mag; j++) {
811         *x++ = this_sz & 0xff;
812         this_sz >>= 8;
813       }
814     }
815     *x++ = marker;
816     ctx->pending_cx_data_sz += index_sz;
817 #ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA
818     index_sz += index_sz_test;
819 #endif
820   }
821   return index_sz;
822 }
823
824 // vp9 uses 10,000,000 ticks/second as time stamp
825 #define TICKS_PER_SEC 10000000LL
826
827 static int64_t timebase_units_to_ticks(const vpx_rational_t *timebase,
828                                        int64_t n) {
829   return n * TICKS_PER_SEC * timebase->num / timebase->den;
830 }
831
832 static int64_t ticks_to_timebase_units(const vpx_rational_t *timebase,
833                                        int64_t n) {
834   const int64_t round = TICKS_PER_SEC * timebase->num / 2 - 1;
835   return (n * timebase->den + round) / timebase->num / TICKS_PER_SEC;
836 }
837
838 static vpx_codec_frame_flags_t get_frame_pkt_flags(const VP9_COMP *cpi,
839                                                    unsigned int lib_flags) {
840   vpx_codec_frame_flags_t flags = lib_flags << 16;
841
842   if (lib_flags & FRAMEFLAGS_KEY
843 #if CONFIG_SPATIAL_SVC
844       || (is_two_pass_svc(cpi) && cpi->svc.layer_context[0].is_key_frame)
845 #endif
846         )
847     flags |= VPX_FRAME_IS_KEY;
848
849   if (cpi->droppable)
850     flags |= VPX_FRAME_IS_DROPPABLE;
851
852   return flags;
853 }
854
855 static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t  *ctx,
856                                       const vpx_image_t *img,
857                                       vpx_codec_pts_t pts,
858                                       unsigned long duration,
859                                       vpx_enc_frame_flags_t flags,
860                                       unsigned long deadline) {
861   vpx_codec_err_t res = VPX_CODEC_OK;
862   VP9_COMP *const cpi = ctx->cpi;
863   const vpx_rational_t *const timebase = &ctx->cfg.g_timebase;
864
865   if (img != NULL) {
866     res = validate_img(ctx, img);
867     // TODO(jzern) the checks related to cpi's validity should be treated as a
868     // failure condition, encoder setup is done fully in init() currently.
869     if (res == VPX_CODEC_OK && cpi != NULL && ctx->cx_data == NULL) {
870       // There's no codec control for multiple alt-refs so check the encoder
871       // instance for its status to determine the compressed data size.
872       ctx->cx_data_sz = ctx->cfg.g_w * ctx->cfg.g_h *
873                         get_image_bps(img) / 8 *
874                         (cpi->multi_arf_allowed ? 8 : 2);
875       if (ctx->cx_data_sz < 4096) ctx->cx_data_sz = 4096;
876
877       ctx->cx_data = (unsigned char *)malloc(ctx->cx_data_sz);
878       if (ctx->cx_data == NULL) {
879         return VPX_CODEC_MEM_ERROR;
880       }
881     }
882   }
883
884   pick_quickcompress_mode(ctx, duration, deadline);
885   vpx_codec_pkt_list_init(&ctx->pkt_list);
886
887   // Handle Flags
888   if (((flags & VP8_EFLAG_NO_UPD_GF) && (flags & VP8_EFLAG_FORCE_GF)) ||
889        ((flags & VP8_EFLAG_NO_UPD_ARF) && (flags & VP8_EFLAG_FORCE_ARF))) {
890     ctx->base.err_detail = "Conflicting flags.";
891     return VPX_CODEC_INVALID_PARAM;
892   }
893
894   vp9_apply_encoding_flags(cpi, flags);
895
896   // Handle fixed keyframe intervals
897   if (ctx->cfg.kf_mode == VPX_KF_AUTO &&
898       ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) {
899     if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) {
900       flags |= VPX_EFLAG_FORCE_KF;
901       ctx->fixed_kf_cntr = 1;
902     }
903   }
904
905   // Initialize the encoder instance on the first frame.
906   if (res == VPX_CODEC_OK && cpi != NULL) {
907     unsigned int lib_flags = 0;
908     YV12_BUFFER_CONFIG sd;
909     int64_t dst_time_stamp = timebase_units_to_ticks(timebase, pts);
910     int64_t dst_end_time_stamp =
911         timebase_units_to_ticks(timebase, pts + duration);
912     size_t size, cx_data_sz;
913     unsigned char *cx_data;
914
915     // Set up internal flags
916     if (ctx->base.init_flags & VPX_CODEC_USE_PSNR)
917       cpi->b_calculate_psnr = 1;
918
919     if (img != NULL) {
920       res = image2yuvconfig(img, &sd);
921
922       // Store the original flags in to the frame buffer. Will extract the
923       // key frame flag when we actually encode this frame.
924       if (vp9_receive_raw_frame(cpi, flags,
925                                 &sd, dst_time_stamp, dst_end_time_stamp)) {
926         res = update_error_state(ctx, &cpi->common.error);
927       }
928     }
929
930     cx_data = ctx->cx_data;
931     cx_data_sz = ctx->cx_data_sz;
932
933     /* Any pending invisible frames? */
934     if (ctx->pending_cx_data) {
935       memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz);
936       ctx->pending_cx_data = cx_data;
937       cx_data += ctx->pending_cx_data_sz;
938       cx_data_sz -= ctx->pending_cx_data_sz;
939
940       /* TODO: this is a minimal check, the underlying codec doesn't respect
941        * the buffer size anyway.
942        */
943       if (cx_data_sz < ctx->cx_data_sz / 2) {
944         ctx->base.err_detail = "Compressed data buffer too small";
945         return VPX_CODEC_ERROR;
946       }
947     }
948
949     while (cx_data_sz >= ctx->cx_data_sz / 2 &&
950            -1 != vp9_get_compressed_data(cpi, &lib_flags, &size,
951                                          cx_data, &dst_time_stamp,
952                                          &dst_end_time_stamp, !img)) {
953       if (size) {
954         vpx_codec_cx_pkt_t pkt;
955
956 #if CONFIG_SPATIAL_SVC
957         if (is_two_pass_svc(cpi))
958           cpi->svc.layer_context[cpi->svc.spatial_layer_id].layer_size += size;
959 #endif
960
961         // Pack invisible frames with the next visible frame
962         if (!cpi->common.show_frame
963 #if CONFIG_SPATIAL_SVC
964             || (is_two_pass_svc(cpi) &&
965                 cpi->svc.spatial_layer_id < cpi->svc.number_spatial_layers - 1)
966 #endif
967             ) {
968           if (ctx->pending_cx_data == 0)
969             ctx->pending_cx_data = cx_data;
970           ctx->pending_cx_data_sz += size;
971           ctx->pending_frame_sizes[ctx->pending_frame_count++] = size;
972           ctx->pending_frame_magnitude |= size;
973           cx_data += size;
974           cx_data_sz -= size;
975           continue;
976         }
977
978         // Add the frame packet to the list of returned packets.
979         pkt.kind = VPX_CODEC_CX_FRAME_PKT;
980         pkt.data.frame.pts = ticks_to_timebase_units(timebase, dst_time_stamp);
981         pkt.data.frame.duration =
982            (unsigned long)ticks_to_timebase_units(timebase,
983                dst_end_time_stamp - dst_time_stamp);
984         pkt.data.frame.flags = get_frame_pkt_flags(cpi, lib_flags);
985
986         if (ctx->pending_cx_data) {
987           ctx->pending_frame_sizes[ctx->pending_frame_count++] = size;
988           ctx->pending_frame_magnitude |= size;
989           ctx->pending_cx_data_sz += size;
990           size += write_superframe_index(ctx);
991           pkt.data.frame.buf = ctx->pending_cx_data;
992           pkt.data.frame.sz  = ctx->pending_cx_data_sz;
993           ctx->pending_cx_data = NULL;
994           ctx->pending_cx_data_sz = 0;
995           ctx->pending_frame_count = 0;
996           ctx->pending_frame_magnitude = 0;
997         } else {
998           pkt.data.frame.buf = cx_data;
999           pkt.data.frame.sz  = size;
1000         }
1001         pkt.data.frame.partition_id = -1;
1002         vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
1003         cx_data += size;
1004         cx_data_sz -= size;
1005 #if CONFIG_SPATIAL_SVC
1006         if (is_two_pass_svc(cpi)) {
1007           vpx_codec_cx_pkt_t pkt_sizes, pkt_psnr;
1008           int i;
1009           vp9_zero(pkt_sizes);
1010           vp9_zero(pkt_psnr);
1011           pkt_sizes.kind = VPX_CODEC_SPATIAL_SVC_LAYER_SIZES;
1012           pkt_psnr.kind = VPX_CODEC_SPATIAL_SVC_LAYER_PSNR;
1013           for (i = 0; i < cpi->svc.number_spatial_layers; ++i) {
1014             LAYER_CONTEXT *lc = &cpi->svc.layer_context[i];
1015             pkt_sizes.data.layer_sizes[i] = lc->layer_size;
1016             pkt_psnr.data.layer_psnr[i] = lc->psnr_pkt;
1017             lc->layer_size = 0;
1018           }
1019           vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt_sizes);
1020           vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt_psnr);
1021         }
1022 #endif
1023       }
1024     }
1025   }
1026
1027   return res;
1028 }
1029
1030 static const vpx_codec_cx_pkt_t *encoder_get_cxdata(vpx_codec_alg_priv_t *ctx,
1031                                                     vpx_codec_iter_t *iter) {
1032   return vpx_codec_pkt_list_get(&ctx->pkt_list.head, iter);
1033 }
1034
1035 static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx,
1036                                           va_list args) {
1037   vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *);
1038
1039   if (frame != NULL) {
1040     YV12_BUFFER_CONFIG sd;
1041
1042     image2yuvconfig(&frame->img, &sd);
1043     vp9_set_reference_enc(ctx->cpi, ref_frame_to_vp9_reframe(frame->frame_type),
1044                           &sd);
1045     return VPX_CODEC_OK;
1046   } else {
1047     return VPX_CODEC_INVALID_PARAM;
1048   }
1049 }
1050
1051 static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx,
1052                                            va_list args) {
1053   vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *);
1054
1055   if (frame != NULL) {
1056     YV12_BUFFER_CONFIG sd;
1057
1058     image2yuvconfig(&frame->img, &sd);
1059     vp9_copy_reference_enc(ctx->cpi,
1060                            ref_frame_to_vp9_reframe(frame->frame_type), &sd);
1061     return VPX_CODEC_OK;
1062   } else {
1063     return VPX_CODEC_INVALID_PARAM;
1064   }
1065 }
1066
1067 static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx,
1068                                           va_list args) {
1069   vp9_ref_frame_t *const frame = va_arg(args, vp9_ref_frame_t *);
1070
1071   if (frame != NULL) {
1072     YV12_BUFFER_CONFIG *fb = get_ref_frame(&ctx->cpi->common, frame->idx);
1073     if (fb == NULL) return VPX_CODEC_ERROR;
1074
1075     yuvconfig2image(&frame->img, fb, NULL);
1076     return VPX_CODEC_OK;
1077   } else {
1078     return VPX_CODEC_INVALID_PARAM;
1079   }
1080 }
1081
1082 static vpx_codec_err_t ctrl_set_previewpp(vpx_codec_alg_priv_t *ctx,
1083                                           va_list args) {
1084 #if CONFIG_VP9_POSTPROC
1085   vp8_postproc_cfg_t *config = va_arg(args, vp8_postproc_cfg_t *);
1086   if (config != NULL) {
1087     ctx->preview_ppcfg = *config;
1088     return VPX_CODEC_OK;
1089   } else {
1090     return VPX_CODEC_INVALID_PARAM;
1091   }
1092 #else
1093   (void)ctx;
1094   (void)args;
1095   return VPX_CODEC_INCAPABLE;
1096 #endif
1097 }
1098
1099
1100 static vpx_image_t *encoder_get_preview(vpx_codec_alg_priv_t *ctx) {
1101   YV12_BUFFER_CONFIG sd;
1102   vp9_ppflags_t flags;
1103   vp9_zero(flags);
1104
1105   if (ctx->preview_ppcfg.post_proc_flag) {
1106     flags.post_proc_flag   = ctx->preview_ppcfg.post_proc_flag;
1107     flags.deblocking_level = ctx->preview_ppcfg.deblocking_level;
1108     flags.noise_level      = ctx->preview_ppcfg.noise_level;
1109   }
1110
1111   if (vp9_get_preview_raw_frame(ctx->cpi, &sd, &flags) == 0) {
1112     yuvconfig2image(&ctx->preview_img, &sd, NULL);
1113     return &ctx->preview_img;
1114   } else {
1115     return NULL;
1116   }
1117 }
1118
1119 static vpx_codec_err_t ctrl_update_entropy(vpx_codec_alg_priv_t *ctx,
1120                                            va_list args) {
1121   const int update = va_arg(args, int);
1122
1123   vp9_update_entropy(ctx->cpi, update);
1124   return VPX_CODEC_OK;
1125 }
1126
1127 static vpx_codec_err_t ctrl_update_reference(vpx_codec_alg_priv_t *ctx,
1128                                              va_list args) {
1129   const int ref_frame_flags = va_arg(args, int);
1130
1131   vp9_update_reference(ctx->cpi, ref_frame_flags);
1132   return VPX_CODEC_OK;
1133 }
1134
1135 static vpx_codec_err_t ctrl_use_reference(vpx_codec_alg_priv_t *ctx,
1136                                           va_list args) {
1137   const int reference_flag = va_arg(args, int);
1138
1139   vp9_use_as_reference(ctx->cpi, reference_flag);
1140   return VPX_CODEC_OK;
1141 }
1142
1143 static vpx_codec_err_t ctrl_set_roi_map(vpx_codec_alg_priv_t *ctx,
1144                                         va_list args) {
1145   (void)ctx;
1146   (void)args;
1147
1148   // TODO(yaowu): Need to re-implement and test for VP9.
1149   return VPX_CODEC_INVALID_PARAM;
1150 }
1151
1152
1153 static vpx_codec_err_t ctrl_set_active_map(vpx_codec_alg_priv_t *ctx,
1154                                            va_list args) {
1155   vpx_active_map_t *const map = va_arg(args, vpx_active_map_t *);
1156
1157   if (map) {
1158     if (!vp9_set_active_map(ctx->cpi, map->active_map,
1159                             (int)map->rows, (int)map->cols))
1160       return VPX_CODEC_OK;
1161     else
1162       return VPX_CODEC_INVALID_PARAM;
1163   } else {
1164     return VPX_CODEC_INVALID_PARAM;
1165   }
1166 }
1167
1168 static vpx_codec_err_t ctrl_set_scale_mode(vpx_codec_alg_priv_t *ctx,
1169                                            va_list args) {
1170   vpx_scaling_mode_t *const mode = va_arg(args, vpx_scaling_mode_t *);
1171
1172   if (mode) {
1173     const int res = vp9_set_internal_size(ctx->cpi,
1174                                           (VPX_SCALING)mode->h_scaling_mode,
1175                                           (VPX_SCALING)mode->v_scaling_mode);
1176     return (res == 0) ? VPX_CODEC_OK : VPX_CODEC_INVALID_PARAM;
1177   } else {
1178     return VPX_CODEC_INVALID_PARAM;
1179   }
1180 }
1181
1182 static vpx_codec_err_t ctrl_set_svc(vpx_codec_alg_priv_t *ctx, va_list args) {
1183   int data = va_arg(args, int);
1184   const vpx_codec_enc_cfg_t *cfg = &ctx->cfg;
1185
1186   vp9_set_svc(ctx->cpi, data);
1187   // CBR or two pass mode for SVC with both temporal and spatial layers
1188   // not yet supported.
1189   if (data == 1 &&
1190       (cfg->rc_end_usage == VPX_CBR ||
1191        cfg->g_pass == VPX_RC_FIRST_PASS ||
1192        cfg->g_pass == VPX_RC_LAST_PASS) &&
1193       cfg->ss_number_layers > 1 &&
1194       cfg->ts_number_layers > 1) {
1195     return VPX_CODEC_INVALID_PARAM;
1196   }
1197   return VPX_CODEC_OK;
1198 }
1199
1200 static vpx_codec_err_t ctrl_set_svc_layer_id(vpx_codec_alg_priv_t *ctx,
1201                                              va_list args) {
1202   vpx_svc_layer_id_t *const data = va_arg(args, vpx_svc_layer_id_t *);
1203   VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi;
1204   SVC *const svc = &cpi->svc;
1205
1206   svc->spatial_layer_id = data->spatial_layer_id;
1207   svc->temporal_layer_id = data->temporal_layer_id;
1208   // Checks on valid layer_id input.
1209   if (svc->temporal_layer_id < 0 ||
1210       svc->temporal_layer_id >= (int)ctx->cfg.ts_number_layers) {
1211     return VPX_CODEC_INVALID_PARAM;
1212   }
1213   if (svc->spatial_layer_id < 0 ||
1214       svc->spatial_layer_id >= (int)ctx->cfg.ss_number_layers) {
1215     return VPX_CODEC_INVALID_PARAM;
1216   }
1217   return VPX_CODEC_OK;
1218 }
1219
1220 static vpx_codec_err_t ctrl_set_svc_parameters(vpx_codec_alg_priv_t *ctx,
1221                                                va_list args) {
1222   VP9_COMP *const cpi = ctx->cpi;
1223   vpx_svc_extra_cfg_t *const params = va_arg(args, vpx_svc_extra_cfg_t *);
1224   int i;
1225
1226   for (i = 0; i < cpi->svc.number_spatial_layers; ++i) {
1227     LAYER_CONTEXT *lc = &cpi->svc.layer_context[i];
1228
1229     lc->max_q = params->max_quantizers[i];
1230     lc->min_q = params->min_quantizers[i];
1231     lc->scaling_factor_num = params->scaling_factor_num[i];
1232     lc->scaling_factor_den = params->scaling_factor_den[i];
1233   }
1234
1235   return VPX_CODEC_OK;
1236 }
1237
1238 static vpx_codec_err_t ctrl_set_tune_content(vpx_codec_alg_priv_t *ctx,
1239                                              va_list args) {
1240   struct vp9_extracfg extra_cfg = ctx->extra_cfg;
1241   extra_cfg.content = CAST(VP9E_SET_TUNE_CONTENT, args);
1242   return update_extra_cfg(ctx, &extra_cfg);
1243 }
1244
1245 static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
1246   {VP8_COPY_REFERENCE,                ctrl_copy_reference},
1247   {VP8E_UPD_ENTROPY,                  ctrl_update_entropy},
1248   {VP8E_UPD_REFERENCE,                ctrl_update_reference},
1249   {VP8E_USE_REFERENCE,                ctrl_use_reference},
1250
1251   // Setters
1252   {VP8_SET_REFERENCE,                 ctrl_set_reference},
1253   {VP8_SET_POSTPROC,                  ctrl_set_previewpp},
1254   {VP8E_SET_ROI_MAP,                  ctrl_set_roi_map},
1255   {VP8E_SET_ACTIVEMAP,                ctrl_set_active_map},
1256   {VP8E_SET_SCALEMODE,                ctrl_set_scale_mode},
1257   {VP8E_SET_CPUUSED,                  ctrl_set_cpuused},
1258   {VP8E_SET_ENABLEAUTOALTREF,         ctrl_set_enable_auto_alt_ref},
1259   {VP8E_SET_SHARPNESS,                ctrl_set_sharpness},
1260   {VP8E_SET_STATIC_THRESHOLD,         ctrl_set_static_thresh},
1261   {VP9E_SET_TILE_COLUMNS,             ctrl_set_tile_columns},
1262   {VP9E_SET_TILE_ROWS,                ctrl_set_tile_rows},
1263   {VP8E_SET_ARNR_MAXFRAMES,           ctrl_set_arnr_max_frames},
1264   {VP8E_SET_ARNR_STRENGTH,            ctrl_set_arnr_strength},
1265   {VP8E_SET_ARNR_TYPE,                ctrl_set_arnr_type},
1266   {VP8E_SET_TUNING,                   ctrl_set_tuning},
1267   {VP8E_SET_CQ_LEVEL,                 ctrl_set_cq_level},
1268   {VP8E_SET_MAX_INTRA_BITRATE_PCT,    ctrl_set_rc_max_intra_bitrate_pct},
1269   {VP9E_SET_LOSSLESS,                 ctrl_set_lossless},
1270   {VP9E_SET_FRAME_PARALLEL_DECODING,  ctrl_set_frame_parallel_decoding_mode},
1271   {VP9E_SET_AQ_MODE,                  ctrl_set_aq_mode},
1272   {VP9E_SET_FRAME_PERIODIC_BOOST,     ctrl_set_frame_periodic_boost},
1273   {VP9E_SET_SVC,                      ctrl_set_svc},
1274   {VP9E_SET_SVC_PARAMETERS,           ctrl_set_svc_parameters},
1275   {VP9E_SET_SVC_LAYER_ID,             ctrl_set_svc_layer_id},
1276   {VP9E_SET_TUNE_CONTENT,             ctrl_set_tune_content},
1277   {VP9E_SET_NOISE_SENSITIVITY,        ctrl_set_noise_sensitivity},
1278
1279   // Getters
1280   {VP8E_GET_LAST_QUANTIZER,           ctrl_get_quantizer},
1281   {VP8E_GET_LAST_QUANTIZER_64,        ctrl_get_quantizer64},
1282   {VP9_GET_REFERENCE,                 ctrl_get_reference},
1283
1284   { -1, NULL},
1285 };
1286
1287 static vpx_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
1288   {
1289     0,
1290     {  // NOLINT
1291       0,                  // g_usage
1292       0,                  // g_threads
1293       0,                  // g_profile
1294
1295       320,                // g_width
1296       240,                // g_height
1297       VPX_BITS_8,         // g_bit_depth
1298       8,                  // g_input_bit_depth
1299
1300       {1, 30},            // g_timebase
1301
1302       0,                  // g_error_resilient
1303
1304       VPX_RC_ONE_PASS,    // g_pass
1305
1306       25,                 // g_lag_in_frames
1307
1308       0,                  // rc_dropframe_thresh
1309       0,                  // rc_resize_allowed
1310       1,                  // rc_scaled_width
1311       1,                  // rc_scaled_height
1312       60,                 // rc_resize_down_thresold
1313       30,                 // rc_resize_up_thresold
1314
1315       VPX_VBR,            // rc_end_usage
1316 #if VPX_ENCODER_ABI_VERSION > (1 + VPX_CODEC_ABI_VERSION)
1317       {NULL, 0},          // rc_twopass_stats_in
1318       {NULL, 0},          // rc_firstpass_mb_stats_in
1319 #endif
1320       256,                // rc_target_bandwidth
1321       0,                  // rc_min_quantizer
1322       63,                 // rc_max_quantizer
1323       100,                // rc_undershoot_pct
1324       100,                // rc_overshoot_pct
1325
1326       6000,               // rc_max_buffer_size
1327       4000,               // rc_buffer_initial_size
1328       5000,               // rc_buffer_optimal_size
1329
1330       50,                 // rc_two_pass_vbrbias
1331       0,                  // rc_two_pass_vbrmin_section
1332       2000,               // rc_two_pass_vbrmax_section
1333
1334       // keyframing settings (kf)
1335       VPX_KF_AUTO,        // g_kfmode
1336       0,                  // kf_min_dist
1337       9999,               // kf_max_dist
1338
1339       VPX_SS_DEFAULT_LAYERS,  // ss_number_layers
1340       {0},
1341       {0},                    // ss_target_bitrate
1342       1,                      // ts_number_layers
1343       {0},                    // ts_target_bitrate
1344       {0},                    // ts_rate_decimator
1345       0,                      // ts_periodicity
1346       {0},                    // ts_layer_id
1347 #if VPX_ENCODER_ABI_VERSION == (1 + VPX_CODEC_ABI_VERSION)
1348       "vp8.fpf"           // first pass filename
1349 #endif
1350     }
1351   },
1352 };
1353
1354 #ifndef VERSION_STRING
1355 #define VERSION_STRING
1356 #endif
1357 CODEC_INTERFACE(vpx_codec_vp9_cx) = {
1358   "WebM Project VP9 Encoder" VERSION_STRING,
1359   VPX_CODEC_INTERNAL_ABI_VERSION,
1360 #if CONFIG_VP9_HIGHBITDEPTH
1361   VPX_CODEC_CAP_HIGHBITDEPTH |
1362 #endif
1363   VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR,  // vpx_codec_caps_t
1364   encoder_init,       // vpx_codec_init_fn_t
1365   encoder_destroy,    // vpx_codec_destroy_fn_t
1366   encoder_ctrl_maps,  // vpx_codec_ctrl_fn_map_t
1367   {  // NOLINT
1368     NULL,  // vpx_codec_peek_si_fn_t
1369     NULL,  // vpx_codec_get_si_fn_t
1370     NULL,  // vpx_codec_decode_fn_t
1371     NULL,  // vpx_codec_frame_get_fn_t
1372     NULL   // vpx_codec_set_fb_fn_t
1373   },
1374   {  // NOLINT
1375     1,                      // 1 cfg map
1376     encoder_usage_cfg_map,  // vpx_codec_enc_cfg_map_t
1377     encoder_encode,         // vpx_codec_encode_fn_t
1378     encoder_get_cxdata,     // vpx_codec_get_cx_data_fn_t
1379     encoder_set_config,     // vpx_codec_enc_config_set_fn_t
1380     NULL,        // vpx_codec_get_global_headers_fn_t
1381     encoder_get_preview,    // vpx_codec_get_preview_frame_fn_t
1382     NULL         // vpx_codec_enc_mr_get_mem_loc_fn_t
1383   }
1384 };