2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
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.
14 #include "vpx/vpx_codec.h"
15 #include "vpx/internal/vpx_codec_internal.h"
16 #include "./vpx_version.h"
17 #include "vp9/encoder/vp9_onyx_int.h"
18 #include "vpx/vp8cx.h"
19 #include "vp9/encoder/vp9_firstpass.h"
20 #include "vp9/vp9_iface_common.h"
23 struct vpx_codec_pkt_list
*pkt_list
;
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 unsigned int arnr_type
;
35 unsigned int cq_level
; /* constrained quality level */
36 unsigned int rc_max_intra_bitrate_pct
;
37 unsigned int lossless
;
38 unsigned int frame_parallel_decoding_mode
;
42 struct extraconfig_map
{
44 struct vp9_extracfg cfg
;
47 static const struct extraconfig_map extracfg_map
[] = {
53 1, /* enable_auto_alt_ref */
54 0, /* noise_sensitivity */
56 0, /* static_thresh */
59 7, /* arnr_max_frames */
60 5, /* arnr_strength */
64 0, /* rc_max_intra_bitrate_pct */
66 0, /* frame_parallel_decoding_mode */
72 struct vpx_codec_alg_priv
{
73 vpx_codec_priv_t base
;
74 vpx_codec_enc_cfg_t cfg
;
75 struct vp9_extracfg vp8_cfg
;
78 unsigned char *cx_data
;
80 unsigned char *pending_cx_data
;
81 size_t pending_cx_data_sz
;
82 int pending_frame_count
;
83 size_t pending_frame_sizes
[8];
84 size_t pending_frame_magnitude
;
85 vpx_image_t preview_img
;
86 vp8_postproc_cfg_t preview_ppcfg
;
87 vpx_codec_pkt_list_decl(64) pkt_list
;
88 unsigned int fixed_kf_cntr
;
91 static VP9_REFFRAME
ref_frame_to_vp9_reframe(vpx_ref_frame_type_t frame
) {
100 assert(0 && "Invalid Reference Frame");
101 return VP9_LAST_FLAG
;
104 static vpx_codec_err_t
105 update_error_state(vpx_codec_alg_priv_t
*ctx
,
106 const struct vpx_internal_error_info
*error
) {
109 if ((res
= error
->error_code
))
110 ctx
->base
.err_detail
= error
->has_detail
119 #define ERROR(str) do {\
120 ctx->base.err_detail = str;\
121 return VPX_CODEC_INVALID_PARAM;\
124 #define RANGE_CHECK(p, memb, lo, hi) do {\
125 if (!(((p)->memb == lo || (p)->memb > (lo)) && (p)->memb <= hi)) \
126 ERROR(#memb " out of range ["#lo".."#hi"]");\
129 #define RANGE_CHECK_HI(p, memb, hi) do {\
130 if (!((p)->memb <= (hi))) \
131 ERROR(#memb " out of range [.."#hi"]");\
134 #define RANGE_CHECK_LO(p, memb, lo) do {\
135 if (!((p)->memb >= (lo))) \
136 ERROR(#memb " out of range ["#lo"..]");\
139 #define RANGE_CHECK_BOOL(p, memb) do {\
140 if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean");\
143 static vpx_codec_err_t
validate_config(vpx_codec_alg_priv_t
*ctx
,
144 const vpx_codec_enc_cfg_t
*cfg
,
145 const struct vp9_extracfg
*vp8_cfg
) {
146 RANGE_CHECK(cfg
, g_w
, 1, 65535); /* 16 bits available */
147 RANGE_CHECK(cfg
, g_h
, 1, 65535); /* 16 bits available */
148 RANGE_CHECK(cfg
, g_timebase
.den
, 1, 1000000000);
149 RANGE_CHECK(cfg
, g_timebase
.num
, 1, cfg
->g_timebase
.den
);
150 RANGE_CHECK_HI(cfg
, g_profile
, 3);
152 RANGE_CHECK_HI(cfg
, rc_max_quantizer
, 63);
153 RANGE_CHECK_HI(cfg
, rc_min_quantizer
, cfg
->rc_max_quantizer
);
154 RANGE_CHECK_BOOL(vp8_cfg
, lossless
);
155 if (vp8_cfg
->lossless
) {
156 RANGE_CHECK_HI(cfg
, rc_max_quantizer
, 0);
157 RANGE_CHECK_HI(cfg
, rc_min_quantizer
, 0);
159 RANGE_CHECK(vp8_cfg
, aq_mode
, 0, AQ_MODE_COUNT
- 1);
161 RANGE_CHECK_HI(cfg
, g_threads
, 64);
162 RANGE_CHECK_HI(cfg
, g_lag_in_frames
, MAX_LAG_BUFFERS
);
163 RANGE_CHECK(cfg
, rc_end_usage
, VPX_VBR
, VPX_Q
);
164 RANGE_CHECK_HI(cfg
, rc_undershoot_pct
, 1000);
165 RANGE_CHECK_HI(cfg
, rc_overshoot_pct
, 1000);
166 RANGE_CHECK_HI(cfg
, rc_2pass_vbr_bias_pct
, 100);
167 RANGE_CHECK(cfg
, kf_mode
, VPX_KF_DISABLED
, VPX_KF_AUTO
);
168 // RANGE_CHECK_BOOL(cfg, g_delete_firstpassfile);
169 RANGE_CHECK_BOOL(cfg
, rc_resize_allowed
);
170 RANGE_CHECK_HI(cfg
, rc_dropframe_thresh
, 100);
171 RANGE_CHECK_HI(cfg
, rc_resize_up_thresh
, 100);
172 RANGE_CHECK_HI(cfg
, rc_resize_down_thresh
, 100);
173 RANGE_CHECK(cfg
, g_pass
, VPX_RC_ONE_PASS
, VPX_RC_LAST_PASS
);
175 RANGE_CHECK(cfg
, ss_number_layers
, 1,
176 VPX_SS_MAX_LAYERS
); /*Spatial layers max */
178 RANGE_CHECK(cfg
, ts_number_layers
, 1, VPX_TS_MAX_LAYERS
);
179 if (cfg
->ts_number_layers
> 1) {
181 for (i
= 1; i
< cfg
->ts_number_layers
; ++i
) {
182 if (cfg
->ts_target_bitrate
[i
] < cfg
->ts_target_bitrate
[i
-1]) {
183 ERROR("ts_target_bitrate entries are not increasing");
186 RANGE_CHECK(cfg
, ts_rate_decimator
[cfg
->ts_number_layers
-1], 1, 1);
187 for (i
= cfg
->ts_number_layers
-2; i
> 0; --i
) {
188 if (cfg
->ts_rate_decimator
[i
-1] != 2*cfg
->ts_rate_decimator
[i
]) {
189 ERROR("ts_rate_decimator factors are not powers of 2");
194 /* VP8 does not support a lower bound on the keyframe interval in
195 * automatic keyframe placement mode.
197 if (cfg
->kf_mode
!= VPX_KF_DISABLED
&& cfg
->kf_min_dist
!= cfg
->kf_max_dist
198 && cfg
->kf_min_dist
> 0)
199 ERROR("kf_min_dist not supported in auto mode, use 0 "
200 "or kf_max_dist instead.");
202 RANGE_CHECK_BOOL(vp8_cfg
, enable_auto_alt_ref
);
203 RANGE_CHECK(vp8_cfg
, cpu_used
, -16, 16);
205 RANGE_CHECK_HI(vp8_cfg
, noise_sensitivity
, 6);
207 RANGE_CHECK(vp8_cfg
, tile_columns
, 0, 6);
208 RANGE_CHECK(vp8_cfg
, tile_rows
, 0, 2);
209 RANGE_CHECK_HI(vp8_cfg
, sharpness
, 7);
210 RANGE_CHECK(vp8_cfg
, arnr_max_frames
, 0, 15);
211 RANGE_CHECK_HI(vp8_cfg
, arnr_strength
, 6);
212 RANGE_CHECK(vp8_cfg
, arnr_type
, 1, 3);
213 RANGE_CHECK(vp8_cfg
, cq_level
, 0, 63);
215 // TODO(yaowu): remove this when ssim tuning is implemented for vp9
216 if (vp8_cfg
->tuning
== VP8_TUNE_SSIM
)
217 ERROR("Option --tune=ssim is not currently supported in VP9.");
219 if (cfg
->g_pass
== VPX_RC_LAST_PASS
) {
220 size_t packet_sz
= sizeof(FIRSTPASS_STATS
);
221 int n_packets
= (int)(cfg
->rc_twopass_stats_in
.sz
/ packet_sz
);
222 FIRSTPASS_STATS
*stats
;
224 if (cfg
->rc_twopass_stats_in
.buf
== NULL
)
225 ERROR("rc_twopass_stats_in.buf not set.");
227 if (cfg
->rc_twopass_stats_in
.sz
% packet_sz
)
228 ERROR("rc_twopass_stats_in.sz indicates truncated packet.");
230 if (cfg
->rc_twopass_stats_in
.sz
< 2 * packet_sz
)
231 ERROR("rc_twopass_stats_in requires at least two packets.");
233 stats
= (void *)((char *)cfg
->rc_twopass_stats_in
.buf
234 + (n_packets
- 1) * packet_sz
);
236 if ((int)(stats
->count
+ 0.5) != n_packets
- 1)
237 ERROR("rc_twopass_stats_in missing EOS stats packet");
244 static vpx_codec_err_t
validate_img(vpx_codec_alg_priv_t
*ctx
,
245 const vpx_image_t
*img
) {
247 case VPX_IMG_FMT_YV12
:
248 case VPX_IMG_FMT_I420
:
249 case VPX_IMG_FMT_I422
:
250 case VPX_IMG_FMT_I444
:
253 ERROR("Invalid image format. Only YV12, I420, I422, I444 images are "
257 if ((img
->d_w
!= ctx
->cfg
.g_w
) || (img
->d_h
!= ctx
->cfg
.g_h
))
258 ERROR("Image size must match encoder init configuration size");
264 static vpx_codec_err_t
set_vp9e_config(VP9_CONFIG
*oxcf
,
265 vpx_codec_enc_cfg_t cfg
,
266 struct vp9_extracfg vp9_cfg
) {
267 oxcf
->version
= cfg
.g_profile
;
268 oxcf
->width
= cfg
.g_w
;
269 oxcf
->height
= cfg
.g_h
;
270 /* guess a frame rate if out of whack, use 30 */
271 oxcf
->framerate
= (double)(cfg
.g_timebase
.den
)
272 / (double)(cfg
.g_timebase
.num
);
274 if (oxcf
->framerate
> 180) {
275 oxcf
->framerate
= 30;
278 switch (cfg
.g_pass
) {
279 case VPX_RC_ONE_PASS
:
280 oxcf
->mode
= MODE_GOODQUALITY
;
282 case VPX_RC_FIRST_PASS
:
283 oxcf
->mode
= MODE_FIRSTPASS
;
285 case VPX_RC_LAST_PASS
:
286 oxcf
->mode
= MODE_SECONDPASS_BEST
;
290 if (cfg
.g_pass
== VPX_RC_FIRST_PASS
) {
291 oxcf
->lag_in_frames
= 0;
293 oxcf
->lag_in_frames
= cfg
.g_lag_in_frames
;
296 oxcf
->end_usage
= USAGE_LOCAL_FILE_PLAYBACK
;
297 if (cfg
.rc_end_usage
== VPX_CQ
)
298 oxcf
->end_usage
= USAGE_CONSTRAINED_QUALITY
;
299 else if (cfg
.rc_end_usage
== VPX_Q
)
300 oxcf
->end_usage
= USAGE_CONSTANT_QUALITY
;
301 else if (cfg
.rc_end_usage
== VPX_CBR
)
302 oxcf
->end_usage
= USAGE_STREAM_FROM_SERVER
;
304 oxcf
->target_bandwidth
= cfg
.rc_target_bitrate
;
305 oxcf
->rc_max_intra_bitrate_pct
= vp9_cfg
.rc_max_intra_bitrate_pct
;
307 oxcf
->best_allowed_q
= cfg
.rc_min_quantizer
;
308 oxcf
->worst_allowed_q
= cfg
.rc_max_quantizer
;
309 oxcf
->cq_level
= vp9_cfg
.cq_level
;
312 oxcf
->under_shoot_pct
= cfg
.rc_undershoot_pct
;
313 oxcf
->over_shoot_pct
= cfg
.rc_overshoot_pct
;
315 oxcf
->maximum_buffer_size
= cfg
.rc_buf_sz
;
316 oxcf
->starting_buffer_level
= cfg
.rc_buf_initial_sz
;
317 oxcf
->optimal_buffer_level
= cfg
.rc_buf_optimal_sz
;
319 oxcf
->drop_frames_water_mark
= cfg
.rc_dropframe_thresh
;
321 oxcf
->two_pass_vbrbias
= cfg
.rc_2pass_vbr_bias_pct
;
322 oxcf
->two_pass_vbrmin_section
= cfg
.rc_2pass_vbr_minsection_pct
;
323 oxcf
->two_pass_vbrmax_section
= cfg
.rc_2pass_vbr_maxsection_pct
;
325 oxcf
->auto_key
= cfg
.kf_mode
== VPX_KF_AUTO
326 && cfg
.kf_min_dist
!= cfg
.kf_max_dist
;
327 // oxcf->kf_min_dist = cfg.kf_min_dis;
328 oxcf
->key_freq
= cfg
.kf_max_dist
;
330 oxcf
->cpu_used
= vp9_cfg
.cpu_used
;
331 oxcf
->encode_breakout
= vp9_cfg
.static_thresh
;
332 oxcf
->play_alternate
= vp9_cfg
.enable_auto_alt_ref
;
333 oxcf
->noise_sensitivity
= vp9_cfg
.noise_sensitivity
;
334 oxcf
->sharpness
= vp9_cfg
.sharpness
;
336 oxcf
->two_pass_stats_in
= cfg
.rc_twopass_stats_in
;
337 oxcf
->output_pkt_list
= vp9_cfg
.pkt_list
;
339 oxcf
->arnr_max_frames
= vp9_cfg
.arnr_max_frames
;
340 oxcf
->arnr_strength
= vp9_cfg
.arnr_strength
;
341 oxcf
->arnr_type
= vp9_cfg
.arnr_type
;
343 oxcf
->tuning
= vp9_cfg
.tuning
;
345 oxcf
->tile_columns
= vp9_cfg
.tile_columns
;
346 oxcf
->tile_rows
= vp9_cfg
.tile_rows
;
348 oxcf
->lossless
= vp9_cfg
.lossless
;
350 oxcf
->error_resilient_mode
= cfg
.g_error_resilient
;
351 oxcf
->frame_parallel_decoding_mode
= vp9_cfg
.frame_parallel_decoding_mode
;
353 oxcf
->aq_mode
= vp9_cfg
.aq_mode
;
355 oxcf
->ss_number_layers
= cfg
.ss_number_layers
;
357 if (oxcf
->ss_number_layers
> 1) {
358 memcpy(oxcf
->ss_target_bitrate
, cfg
.ss_target_bitrate
,
359 sizeof(cfg
.ss_target_bitrate
));
360 } else if (oxcf
->ss_number_layers
== 1) {
361 oxcf
->ss_target_bitrate
[0] = (int)oxcf
->target_bandwidth
;
364 oxcf
->ts_number_layers
= cfg
.ts_number_layers
;
366 if (oxcf
->ts_number_layers
> 1) {
367 memcpy(oxcf
->ts_target_bitrate
, cfg
.ts_target_bitrate
,
368 sizeof(cfg
.ts_target_bitrate
));
369 memcpy(oxcf
->ts_rate_decimator
, cfg
.ts_rate_decimator
,
370 sizeof(cfg
.ts_rate_decimator
));
371 } else if (oxcf
->ts_number_layers
== 1) {
372 oxcf
->ts_target_bitrate
[0] = (int)oxcf
->target_bandwidth
;
373 oxcf
->ts_rate_decimator
[0] = 1;
377 printf("Current VP9 Settings: \n");
378 printf("target_bandwidth: %d\n", oxcf->target_bandwidth);
379 printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity);
380 printf("sharpness: %d\n", oxcf->sharpness);
381 printf("cpu_used: %d\n", oxcf->cpu_used);
382 printf("Mode: %d\n", oxcf->mode);
383 printf("auto_key: %d\n", oxcf->auto_key);
384 printf("key_freq: %d\n", oxcf->key_freq);
385 printf("end_usage: %d\n", oxcf->end_usage);
386 printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct);
387 printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct);
388 printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level);
389 printf("optimal_buffer_level: %d\n", oxcf->optimal_buffer_level);
390 printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size);
391 printf("fixed_q: %d\n", oxcf->fixed_q);
392 printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q);
393 printf("best_allowed_q: %d\n", oxcf->best_allowed_q);
394 printf("two_pass_vbrbias: %d\n", oxcf->two_pass_vbrbias);
395 printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section);
396 printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section);
397 printf("lag_in_frames: %d\n", oxcf->lag_in_frames);
398 printf("play_alternate: %d\n", oxcf->play_alternate);
399 printf("Version: %d\n", oxcf->Version);
400 printf("encode_breakout: %d\n", oxcf->encode_breakout);
401 printf("error resilient: %d\n", oxcf->error_resilient_mode);
402 printf("frame parallel detokenization: %d\n",
403 oxcf->frame_parallel_decoding_mode);
408 static vpx_codec_err_t
vp9e_set_config(vpx_codec_alg_priv_t
*ctx
,
409 const vpx_codec_enc_cfg_t
*cfg
) {
412 if ((cfg
->g_w
!= ctx
->cfg
.g_w
) || (cfg
->g_h
!= ctx
->cfg
.g_h
))
413 ERROR("Cannot change width or height after initialization");
415 /* Prevent increasing lag_in_frames. This check is stricter than it needs
416 * to be -- the limit is not increasing past the first lag_in_frames
417 * value, but we don't track the initial config, only the last successful
420 if ((cfg
->g_lag_in_frames
> ctx
->cfg
.g_lag_in_frames
))
421 ERROR("Cannot increase lag_in_frames");
423 res
= validate_config(ctx
, cfg
, &ctx
->vp8_cfg
);
425 if (res
== VPX_CODEC_OK
) {
427 set_vp9e_config(&ctx
->oxcf
, ctx
->cfg
, ctx
->vp8_cfg
);
428 vp9_change_config(ctx
->cpi
, &ctx
->oxcf
);
435 int vp9_reverse_trans(int q
);
438 static vpx_codec_err_t
get_param(vpx_codec_alg_priv_t
*ctx
,
441 void *arg
= va_arg(args
, void *);
443 #define MAP(id, var) case id: *(RECAST(id, arg)) = var; break
445 if (arg
== NULL
) return VPX_CODEC_INVALID_PARAM
;
448 MAP(VP8E_GET_LAST_QUANTIZER
, vp9_get_quantizer(ctx
->cpi
));
449 MAP(VP8E_GET_LAST_QUANTIZER_64
,
450 vp9_reverse_trans(vp9_get_quantizer(ctx
->cpi
)));
458 static vpx_codec_err_t
set_param(vpx_codec_alg_priv_t
*ctx
,
461 vpx_codec_err_t res
= VPX_CODEC_OK
;
462 struct vp9_extracfg xcfg
= ctx
->vp8_cfg
;
464 #define MAP(id, var) case id: var = CAST(id, args); break;
467 MAP(VP8E_SET_CPUUSED
, xcfg
.cpu_used
);
468 MAP(VP8E_SET_ENABLEAUTOALTREF
, xcfg
.enable_auto_alt_ref
);
469 MAP(VP8E_SET_NOISE_SENSITIVITY
, xcfg
.noise_sensitivity
);
470 MAP(VP8E_SET_SHARPNESS
, xcfg
.sharpness
);
471 MAP(VP8E_SET_STATIC_THRESHOLD
, xcfg
.static_thresh
);
472 MAP(VP9E_SET_TILE_COLUMNS
, xcfg
.tile_columns
);
473 MAP(VP9E_SET_TILE_ROWS
, xcfg
.tile_rows
);
474 MAP(VP8E_SET_ARNR_MAXFRAMES
, xcfg
.arnr_max_frames
);
475 MAP(VP8E_SET_ARNR_STRENGTH
, xcfg
.arnr_strength
);
476 MAP(VP8E_SET_ARNR_TYPE
, xcfg
.arnr_type
);
477 MAP(VP8E_SET_TUNING
, xcfg
.tuning
);
478 MAP(VP8E_SET_CQ_LEVEL
, xcfg
.cq_level
);
479 MAP(VP8E_SET_MAX_INTRA_BITRATE_PCT
, xcfg
.rc_max_intra_bitrate_pct
);
480 MAP(VP9E_SET_LOSSLESS
, xcfg
.lossless
);
481 MAP(VP9E_SET_FRAME_PARALLEL_DECODING
, xcfg
.frame_parallel_decoding_mode
);
482 MAP(VP9E_SET_AQ_MODE
, xcfg
.aq_mode
);
485 res
= validate_config(ctx
, &ctx
->cfg
, &xcfg
);
487 if (res
== VPX_CODEC_OK
) {
489 set_vp9e_config(&ctx
->oxcf
, ctx
->cfg
, ctx
->vp8_cfg
);
490 vp9_change_config(ctx
->cpi
, &ctx
->oxcf
);
498 static vpx_codec_err_t
vp9e_common_init(vpx_codec_ctx_t
*ctx
) {
499 vpx_codec_err_t res
= VPX_CODEC_OK
;
500 struct vpx_codec_alg_priv
*priv
;
501 vpx_codec_enc_cfg_t
*cfg
;
504 if (ctx
->priv
== NULL
) {
505 priv
= calloc(1, sizeof(struct vpx_codec_alg_priv
));
507 if (priv
== NULL
) return VPX_CODEC_MEM_ERROR
;
509 ctx
->priv
= &priv
->base
;
510 ctx
->priv
->sz
= sizeof(*ctx
->priv
);
511 ctx
->priv
->iface
= ctx
->iface
;
512 ctx
->priv
->alg_priv
= priv
;
513 ctx
->priv
->init_flags
= ctx
->init_flags
;
514 ctx
->priv
->enc
.total_encoders
= 1;
516 if (ctx
->config
.enc
) {
517 /* Update the reference to the config structure to an
520 ctx
->priv
->alg_priv
->cfg
= *ctx
->config
.enc
;
521 ctx
->config
.enc
= &ctx
->priv
->alg_priv
->cfg
;
524 cfg
= &ctx
->priv
->alg_priv
->cfg
;
526 /* Select the extra vp6 configuration table based on the current
527 * usage value. If the current usage value isn't found, use the
528 * values for usage case 0.
531 extracfg_map
[i
].usage
&& extracfg_map
[i
].usage
!= cfg
->g_usage
;
534 priv
->vp8_cfg
= extracfg_map
[i
].cfg
;
535 priv
->vp8_cfg
.pkt_list
= &priv
->pkt_list
.head
;
537 // Maximum buffer size approximated based on having multiple ARF.
538 priv
->cx_data_sz
= priv
->cfg
.g_w
* priv
->cfg
.g_h
* 3 / 2 * 8;
540 if (priv
->cx_data_sz
< 4096) priv
->cx_data_sz
= 4096;
542 priv
->cx_data
= malloc(priv
->cx_data_sz
);
544 if (priv
->cx_data
== NULL
) return VPX_CODEC_MEM_ERROR
;
546 vp9_initialize_enc();
548 res
= validate_config(priv
, &priv
->cfg
, &priv
->vp8_cfg
);
550 if (res
== VPX_CODEC_OK
) {
552 set_vp9e_config(&ctx
->priv
->alg_priv
->oxcf
,
553 ctx
->priv
->alg_priv
->cfg
,
554 ctx
->priv
->alg_priv
->vp8_cfg
);
555 cpi
= vp9_create_compressor(&ctx
->priv
->alg_priv
->oxcf
);
557 res
= VPX_CODEC_MEM_ERROR
;
559 ctx
->priv
->alg_priv
->cpi
= cpi
;
567 static vpx_codec_err_t
vp9e_init(vpx_codec_ctx_t
*ctx
,
568 vpx_codec_priv_enc_mr_cfg_t
*data
) {
569 return vp9e_common_init(ctx
);
572 static vpx_codec_err_t
vp9e_destroy(vpx_codec_alg_priv_t
*ctx
) {
574 vp9_remove_compressor(ctx
->cpi
);
579 static void pick_quickcompress_mode(vpx_codec_alg_priv_t
*ctx
,
580 unsigned long duration
,
581 unsigned long deadline
) {
584 /* Use best quality mode if no deadline is given. */
585 new_qc
= MODE_BESTQUALITY
;
588 uint64_t duration_us
;
590 /* Convert duration parameter from stream timebase to microseconds */
591 duration_us
= (uint64_t)duration
* 1000000
592 * (uint64_t)ctx
->cfg
.g_timebase
.num
593 / (uint64_t)ctx
->cfg
.g_timebase
.den
;
595 /* If the deadline is more that the duration this frame is to be shown,
596 * use good quality mode. Otherwise use realtime mode.
598 new_qc
= (deadline
> duration_us
) ? MODE_GOODQUALITY
: MODE_REALTIME
;
601 if (ctx
->cfg
.g_pass
== VPX_RC_FIRST_PASS
)
602 new_qc
= MODE_FIRSTPASS
;
603 else if (ctx
->cfg
.g_pass
== VPX_RC_LAST_PASS
)
604 new_qc
= (new_qc
== MODE_BESTQUALITY
)
605 ? MODE_SECONDPASS_BEST
608 if (ctx
->oxcf
.mode
!= new_qc
) {
609 ctx
->oxcf
.mode
= new_qc
;
610 vp9_change_config(ctx
->cpi
, &ctx
->oxcf
);
615 static int write_superframe_index(vpx_codec_alg_priv_t
*ctx
) {
616 uint8_t marker
= 0xc0;
620 assert(ctx
->pending_frame_count
);
621 assert(ctx
->pending_frame_count
<= 8);
623 /* Add the number of frames to the marker byte */
624 marker
|= ctx
->pending_frame_count
- 1;
626 /* Choose the magnitude */
627 for (mag
= 0, mask
= 0xff; mag
< 4; mag
++) {
628 if (ctx
->pending_frame_magnitude
< mask
)
635 /* Write the index */
636 index_sz
= 2 + (mag
+ 1) * ctx
->pending_frame_count
;
637 if (ctx
->pending_cx_data_sz
+ index_sz
< ctx
->cx_data_sz
) {
638 uint8_t *x
= ctx
->pending_cx_data
+ ctx
->pending_cx_data_sz
;
642 for (i
= 0; i
< ctx
->pending_frame_count
; i
++) {
643 unsigned int this_sz
= (unsigned int)ctx
->pending_frame_sizes
[i
];
645 for (j
= 0; j
<= mag
; j
++) {
646 *x
++ = this_sz
& 0xff;
651 ctx
->pending_cx_data_sz
+= index_sz
;
656 static vpx_codec_err_t
vp9e_encode(vpx_codec_alg_priv_t
*ctx
,
657 const vpx_image_t
*img
,
659 unsigned long duration
,
660 vpx_enc_frame_flags_t flags
,
661 unsigned long deadline
) {
662 vpx_codec_err_t res
= VPX_CODEC_OK
;
665 res
= validate_img(ctx
, img
);
667 pick_quickcompress_mode(ctx
, duration
, deadline
);
668 vpx_codec_pkt_list_init(&ctx
->pkt_list
);
671 if (((flags
& VP8_EFLAG_NO_UPD_GF
) && (flags
& VP8_EFLAG_FORCE_GF
))
672 || ((flags
& VP8_EFLAG_NO_UPD_ARF
) && (flags
& VP8_EFLAG_FORCE_ARF
))) {
673 ctx
->base
.err_detail
= "Conflicting flags.";
674 return VPX_CODEC_INVALID_PARAM
;
677 if (flags
& (VP8_EFLAG_NO_REF_LAST
| VP8_EFLAG_NO_REF_GF
678 | VP8_EFLAG_NO_REF_ARF
)) {
681 if (flags
& VP8_EFLAG_NO_REF_LAST
)
682 ref
^= VP9_LAST_FLAG
;
684 if (flags
& VP8_EFLAG_NO_REF_GF
)
685 ref
^= VP9_GOLD_FLAG
;
687 if (flags
& VP8_EFLAG_NO_REF_ARF
)
690 vp9_use_as_reference(ctx
->cpi
, ref
);
693 if (flags
& (VP8_EFLAG_NO_UPD_LAST
| VP8_EFLAG_NO_UPD_GF
694 | VP8_EFLAG_NO_UPD_ARF
| VP8_EFLAG_FORCE_GF
695 | VP8_EFLAG_FORCE_ARF
)) {
698 if (flags
& VP8_EFLAG_NO_UPD_LAST
)
699 upd
^= VP9_LAST_FLAG
;
701 if (flags
& VP8_EFLAG_NO_UPD_GF
)
702 upd
^= VP9_GOLD_FLAG
;
704 if (flags
& VP8_EFLAG_NO_UPD_ARF
)
707 vp9_update_reference(ctx
->cpi
, upd
);
710 if (flags
& VP8_EFLAG_NO_UPD_ENTROPY
) {
711 vp9_update_entropy(ctx
->cpi
, 0);
714 /* Handle fixed keyframe intervals */
715 if (ctx
->cfg
.kf_mode
== VPX_KF_AUTO
716 && ctx
->cfg
.kf_min_dist
== ctx
->cfg
.kf_max_dist
) {
717 if (++ctx
->fixed_kf_cntr
> ctx
->cfg
.kf_min_dist
) {
718 flags
|= VPX_EFLAG_FORCE_KF
;
719 ctx
->fixed_kf_cntr
= 1;
723 /* Initialize the encoder instance on the first frame. */
724 if (res
== VPX_CODEC_OK
&& ctx
->cpi
!= NULL
) {
725 unsigned int lib_flags
;
726 YV12_BUFFER_CONFIG sd
;
727 int64_t dst_time_stamp
, dst_end_time_stamp
;
728 size_t size
, cx_data_sz
;
729 unsigned char *cx_data
;
731 /* Set up internal flags */
732 if (ctx
->base
.init_flags
& VPX_CODEC_USE_PSNR
)
733 ((VP9_COMP
*)ctx
->cpi
)->b_calculate_psnr
= 1;
735 /* Convert API flags to internal codec lib flags */
736 lib_flags
= (flags
& VPX_EFLAG_FORCE_KF
) ? FRAMEFLAGS_KEY
: 0;
738 /* vp8 use 10,000,000 ticks/second as time stamp */
739 dst_time_stamp
= pts
* 10000000 * ctx
->cfg
.g_timebase
.num
740 / ctx
->cfg
.g_timebase
.den
;
741 dst_end_time_stamp
= (pts
+ duration
) * 10000000 * ctx
->cfg
.g_timebase
.num
/
742 ctx
->cfg
.g_timebase
.den
;
745 res
= image2yuvconfig(img
, &sd
);
747 if (vp9_receive_raw_frame(ctx
->cpi
, lib_flags
,
748 &sd
, dst_time_stamp
, dst_end_time_stamp
)) {
749 VP9_COMP
*cpi
= (VP9_COMP
*)ctx
->cpi
;
750 res
= update_error_state(ctx
, &cpi
->common
.error
);
754 cx_data
= ctx
->cx_data
;
755 cx_data_sz
= ctx
->cx_data_sz
;
758 /* Any pending invisible frames? */
759 if (ctx
->pending_cx_data
) {
760 memmove(cx_data
, ctx
->pending_cx_data
, ctx
->pending_cx_data_sz
);
761 ctx
->pending_cx_data
= cx_data
;
762 cx_data
+= ctx
->pending_cx_data_sz
;
763 cx_data_sz
-= ctx
->pending_cx_data_sz
;
765 /* TODO: this is a minimal check, the underlying codec doesn't respect
766 * the buffer size anyway.
768 if (cx_data_sz
< ctx
->cx_data_sz
/ 2) {
769 ctx
->base
.err_detail
= "Compressed data buffer too small";
770 return VPX_CODEC_ERROR
;
774 while (cx_data_sz
>= ctx
->cx_data_sz
/ 2 &&
775 -1 != vp9_get_compressed_data(ctx
->cpi
, &lib_flags
, &size
,
776 cx_data
, &dst_time_stamp
,
777 &dst_end_time_stamp
, !img
)) {
779 vpx_codec_pts_t round
, delta
;
780 vpx_codec_cx_pkt_t pkt
;
781 VP9_COMP
*cpi
= (VP9_COMP
*)ctx
->cpi
;
783 /* Pack invisible frames with the next visible frame */
784 if (cpi
->common
.show_frame
== 0) {
785 if (ctx
->pending_cx_data
== 0)
786 ctx
->pending_cx_data
= cx_data
;
787 ctx
->pending_cx_data_sz
+= size
;
788 ctx
->pending_frame_sizes
[ctx
->pending_frame_count
++] = size
;
789 ctx
->pending_frame_magnitude
|= size
;
795 /* Add the frame packet to the list of returned packets. */
796 round
= (vpx_codec_pts_t
)1000000 * ctx
->cfg
.g_timebase
.num
/ 2 - 1;
797 delta
= (dst_end_time_stamp
- dst_time_stamp
);
798 pkt
.kind
= VPX_CODEC_CX_FRAME_PKT
;
800 (dst_time_stamp
* ctx
->cfg
.g_timebase
.den
+ round
)
801 / ctx
->cfg
.g_timebase
.num
/ 10000000;
802 pkt
.data
.frame
.duration
= (unsigned long)
803 ((delta
* ctx
->cfg
.g_timebase
.den
+ round
)
804 / ctx
->cfg
.g_timebase
.num
/ 10000000);
805 pkt
.data
.frame
.flags
= lib_flags
<< 16;
807 if (lib_flags
& FRAMEFLAGS_KEY
)
808 pkt
.data
.frame
.flags
|= VPX_FRAME_IS_KEY
;
810 if (cpi
->common
.show_frame
== 0) {
811 pkt
.data
.frame
.flags
|= VPX_FRAME_IS_INVISIBLE
;
813 // This timestamp should be as close as possible to the
814 // prior PTS so that if a decoder uses pts to schedule when
815 // to do this, we start right after last frame was decoded.
816 // Invisible frames have no duration.
817 pkt
.data
.frame
.pts
= ((cpi
->last_time_stamp_seen
818 * ctx
->cfg
.g_timebase
.den
+ round
)
819 / ctx
->cfg
.g_timebase
.num
/ 10000000) + 1;
820 pkt
.data
.frame
.duration
= 0;
824 pkt
.data
.frame
.flags
|= VPX_FRAME_IS_DROPPABLE
;
826 /*if (cpi->output_partition)
829 const int num_partitions = 1;
831 pkt.data.frame.flags |= VPX_FRAME_IS_FRAGMENT;
833 for (i = 0; i < num_partitions; ++i)
835 pkt.data.frame.buf = cx_data;
836 pkt.data.frame.sz = cpi->partition_sz[i];
837 pkt.data.frame.partition_id = i;
838 // don't set the fragment bit for the last partition
839 if (i == (num_partitions - 1))
840 pkt.data.frame.flags &= ~VPX_FRAME_IS_FRAGMENT;
841 vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
842 cx_data += cpi->partition_sz[i];
843 cx_data_sz -= cpi->partition_sz[i];
848 if (ctx
->pending_cx_data
) {
849 ctx
->pending_frame_sizes
[ctx
->pending_frame_count
++] = size
;
850 ctx
->pending_frame_magnitude
|= size
;
851 ctx
->pending_cx_data_sz
+= size
;
852 size
+= write_superframe_index(ctx
);
853 pkt
.data
.frame
.buf
= ctx
->pending_cx_data
;
854 pkt
.data
.frame
.sz
= ctx
->pending_cx_data_sz
;
855 ctx
->pending_cx_data
= NULL
;
856 ctx
->pending_cx_data_sz
= 0;
857 ctx
->pending_frame_count
= 0;
858 ctx
->pending_frame_magnitude
= 0;
860 pkt
.data
.frame
.buf
= cx_data
;
861 pkt
.data
.frame
.sz
= size
;
863 pkt
.data
.frame
.partition_id
= -1;
864 vpx_codec_pkt_list_add(&ctx
->pkt_list
.head
, &pkt
);
876 static const vpx_codec_cx_pkt_t
*vp9e_get_cxdata(vpx_codec_alg_priv_t
*ctx
,
877 vpx_codec_iter_t
*iter
) {
878 return vpx_codec_pkt_list_get(&ctx
->pkt_list
.head
, iter
);
881 static vpx_codec_err_t
vp9e_set_reference(vpx_codec_alg_priv_t
*ctx
,
884 vpx_ref_frame_t
*frame
= va_arg(args
, vpx_ref_frame_t
*);
887 YV12_BUFFER_CONFIG sd
;
889 image2yuvconfig(&frame
->img
, &sd
);
890 vp9_set_reference_enc(ctx
->cpi
, ref_frame_to_vp9_reframe(frame
->frame_type
),
894 return VPX_CODEC_INVALID_PARAM
;
898 static vpx_codec_err_t
vp9e_copy_reference(vpx_codec_alg_priv_t
*ctx
,
901 vpx_ref_frame_t
*frame
= va_arg(args
, vpx_ref_frame_t
*);
904 YV12_BUFFER_CONFIG sd
;
906 image2yuvconfig(&frame
->img
, &sd
);
907 vp9_copy_reference_enc(ctx
->cpi
,
908 ref_frame_to_vp9_reframe(frame
->frame_type
), &sd
);
911 return VPX_CODEC_INVALID_PARAM
;
915 static vpx_codec_err_t
get_reference(vpx_codec_alg_priv_t
*ctx
,
918 vp9_ref_frame_t
*frame
= va_arg(args
, vp9_ref_frame_t
*);
921 YV12_BUFFER_CONFIG
* fb
;
923 vp9_get_reference_enc(ctx
->cpi
, frame
->idx
, &fb
);
924 yuvconfig2image(&frame
->img
, fb
, NULL
);
927 return VPX_CODEC_INVALID_PARAM
;
931 static vpx_codec_err_t
vp9e_set_previewpp(vpx_codec_alg_priv_t
*ctx
,
934 #if CONFIG_VP9_POSTPROC
935 vp8_postproc_cfg_t
*config
= va_arg(args
, vp8_postproc_cfg_t
*);
938 if (config
!= NULL
) {
939 ctx
->preview_ppcfg
= *config
;
942 return VPX_CODEC_INVALID_PARAM
;
948 return VPX_CODEC_INCAPABLE
;
953 static vpx_image_t
*vp9e_get_preview(vpx_codec_alg_priv_t
*ctx
) {
954 YV12_BUFFER_CONFIG sd
;
955 vp9_ppflags_t flags
= {0};
957 if (ctx
->preview_ppcfg
.post_proc_flag
) {
958 flags
.post_proc_flag
= ctx
->preview_ppcfg
.post_proc_flag
;
959 flags
.deblocking_level
= ctx
->preview_ppcfg
.deblocking_level
;
960 flags
.noise_level
= ctx
->preview_ppcfg
.noise_level
;
963 if (0 == vp9_get_preview_raw_frame(ctx
->cpi
, &sd
, &flags
)) {
964 yuvconfig2image(&ctx
->preview_img
, &sd
, NULL
);
965 return &ctx
->preview_img
;
971 static vpx_codec_err_t
vp9e_update_entropy(vpx_codec_alg_priv_t
*ctx
,
974 int update
= va_arg(args
, int);
975 vp9_update_entropy(ctx
->cpi
, update
);
979 static vpx_codec_err_t
vp9e_update_reference(vpx_codec_alg_priv_t
*ctx
,
982 int update
= va_arg(args
, int);
983 vp9_update_reference(ctx
->cpi
, update
);
987 static vpx_codec_err_t
vp9e_use_reference(vpx_codec_alg_priv_t
*ctx
,
990 int reference_flag
= va_arg(args
, int);
991 vp9_use_as_reference(ctx
->cpi
, reference_flag
);
995 static vpx_codec_err_t
vp9e_set_roi_map(vpx_codec_alg_priv_t
*ctx
,
998 // TODO(yaowu): Need to re-implement and test for VP9.
999 return VPX_CODEC_INVALID_PARAM
;
1003 static vpx_codec_err_t
vp9e_set_activemap(vpx_codec_alg_priv_t
*ctx
,
1006 vpx_active_map_t
*data
= va_arg(args
, vpx_active_map_t
*);
1009 vpx_active_map_t
*map
= (vpx_active_map_t
*)data
;
1010 if (!vp9_set_active_map(ctx
->cpi
, map
->active_map
, map
->rows
, map
->cols
))
1011 return VPX_CODEC_OK
;
1013 return VPX_CODEC_INVALID_PARAM
;
1015 return VPX_CODEC_INVALID_PARAM
;
1019 static vpx_codec_err_t
vp9e_set_scalemode(vpx_codec_alg_priv_t
*ctx
,
1022 vpx_scaling_mode_t
*scalemode
= va_arg(args
, vpx_scaling_mode_t
*);
1024 if (scalemode
!= NULL
) {
1026 res
= vp9_set_internal_size(ctx
->cpi
,
1027 (VPX_SCALING
)scalemode
->h_scaling_mode
,
1028 (VPX_SCALING
)scalemode
->v_scaling_mode
);
1029 return (res
== 0) ? VPX_CODEC_OK
: VPX_CODEC_INVALID_PARAM
;
1031 return VPX_CODEC_INVALID_PARAM
;
1035 static vpx_codec_err_t
vp9e_set_svc(vpx_codec_alg_priv_t
*ctx
, int ctr_id
,
1037 int data
= va_arg(args
, int);
1038 vp9_set_svc(ctx
->cpi
, data
);
1039 // CBR mode for SVC with both temporal and spatial layers not yet supported.
1041 ctx
->cfg
.rc_end_usage
== VPX_CBR
&&
1042 ctx
->cfg
.ss_number_layers
> 1 &&
1043 ctx
->cfg
.ts_number_layers
> 1) {
1044 return VPX_CODEC_INVALID_PARAM
;
1046 return VPX_CODEC_OK
;
1049 static vpx_codec_err_t
vp9e_set_svc_layer_id(vpx_codec_alg_priv_t
*ctx
,
1052 vpx_svc_layer_id_t
*data
= va_arg(args
, vpx_svc_layer_id_t
*);
1053 VP9_COMP
*cpi
= (VP9_COMP
*)ctx
->cpi
;
1054 cpi
->svc
.spatial_layer_id
= data
->spatial_layer_id
;
1055 cpi
->svc
.temporal_layer_id
= data
->temporal_layer_id
;
1056 // Checks on valid layer_id input.
1057 if (cpi
->svc
.temporal_layer_id
< 0 ||
1058 cpi
->svc
.temporal_layer_id
>= (int)ctx
->cfg
.ts_number_layers
) {
1059 return VPX_CODEC_INVALID_PARAM
;
1061 if (cpi
->svc
.spatial_layer_id
< 0 ||
1062 cpi
->svc
.spatial_layer_id
>= (int)ctx
->cfg
.ss_number_layers
) {
1063 return VPX_CODEC_INVALID_PARAM
;
1065 return VPX_CODEC_OK
;
1068 static vpx_codec_err_t
vp9e_set_svc_parameters(vpx_codec_alg_priv_t
*ctx
,
1069 int ctr_id
, va_list args
) {
1070 VP9_COMP
*cpi
= (VP9_COMP
*)ctx
->cpi
;
1071 vpx_svc_parameters_t
*params
= va_arg(args
, vpx_svc_parameters_t
*);
1073 if (params
== NULL
) return VPX_CODEC_INVALID_PARAM
;
1075 cpi
->svc
.spatial_layer_id
= params
->spatial_layer
;
1076 cpi
->svc
.temporal_layer_id
= params
->temporal_layer
;
1078 cpi
->lst_fb_idx
= params
->lst_fb_idx
;
1079 cpi
->gld_fb_idx
= params
->gld_fb_idx
;
1080 cpi
->alt_fb_idx
= params
->alt_fb_idx
;
1082 if (vp9_set_size_literal(ctx
->cpi
, params
->width
, params
->height
) != 0)
1083 return VPX_CODEC_INVALID_PARAM
;
1085 ctx
->cfg
.rc_max_quantizer
= params
->max_quantizer
;
1086 ctx
->cfg
.rc_min_quantizer
= params
->min_quantizer
;
1088 set_vp9e_config(&ctx
->oxcf
, ctx
->cfg
, ctx
->vp8_cfg
);
1089 vp9_change_config(ctx
->cpi
, &ctx
->oxcf
);
1091 return VPX_CODEC_OK
;
1094 static vpx_codec_ctrl_fn_map_t vp9e_ctf_maps
[] = {
1095 {VP8_SET_REFERENCE
, vp9e_set_reference
},
1096 {VP8_COPY_REFERENCE
, vp9e_copy_reference
},
1097 {VP8_SET_POSTPROC
, vp9e_set_previewpp
},
1098 {VP8E_UPD_ENTROPY
, vp9e_update_entropy
},
1099 {VP8E_UPD_REFERENCE
, vp9e_update_reference
},
1100 {VP8E_USE_REFERENCE
, vp9e_use_reference
},
1101 {VP8E_SET_ROI_MAP
, vp9e_set_roi_map
},
1102 {VP8E_SET_ACTIVEMAP
, vp9e_set_activemap
},
1103 {VP8E_SET_SCALEMODE
, vp9e_set_scalemode
},
1104 {VP8E_SET_CPUUSED
, set_param
},
1105 {VP8E_SET_NOISE_SENSITIVITY
, set_param
},
1106 {VP8E_SET_ENABLEAUTOALTREF
, set_param
},
1107 {VP8E_SET_SHARPNESS
, set_param
},
1108 {VP8E_SET_STATIC_THRESHOLD
, set_param
},
1109 {VP9E_SET_TILE_COLUMNS
, set_param
},
1110 {VP9E_SET_TILE_ROWS
, set_param
},
1111 {VP8E_GET_LAST_QUANTIZER
, get_param
},
1112 {VP8E_GET_LAST_QUANTIZER_64
, get_param
},
1113 {VP8E_SET_ARNR_MAXFRAMES
, set_param
},
1114 {VP8E_SET_ARNR_STRENGTH
, set_param
},
1115 {VP8E_SET_ARNR_TYPE
, set_param
},
1116 {VP8E_SET_TUNING
, set_param
},
1117 {VP8E_SET_CQ_LEVEL
, set_param
},
1118 {VP8E_SET_MAX_INTRA_BITRATE_PCT
, set_param
},
1119 {VP9E_SET_LOSSLESS
, set_param
},
1120 {VP9E_SET_FRAME_PARALLEL_DECODING
, set_param
},
1121 {VP9E_SET_AQ_MODE
, set_param
},
1122 {VP9_GET_REFERENCE
, get_reference
},
1123 {VP9E_SET_SVC
, vp9e_set_svc
},
1124 {VP9E_SET_SVC_PARAMETERS
, vp9e_set_svc_parameters
},
1125 {VP9E_SET_SVC_LAYER_ID
, vp9e_set_svc_layer_id
},
1129 static vpx_codec_enc_cfg_map_t vp9e_usage_cfg_map
[] = {
1139 {1, 30}, /* g_timebase */
1141 0, /* g_error_resilient */
1143 VPX_RC_ONE_PASS
, /* g_pass */
1145 25, /* g_lag_in_frames */
1147 0, /* rc_dropframe_thresh */
1148 0, /* rc_resize_allowed */
1149 60, /* rc_resize_down_thresold */
1150 30, /* rc_resize_up_thresold */
1152 VPX_VBR
, /* rc_end_usage */
1153 #if VPX_ENCODER_ABI_VERSION > (1 + VPX_CODEC_ABI_VERSION)
1154 {0}, /* rc_twopass_stats_in */
1156 256, /* rc_target_bandwidth */
1157 0, /* rc_min_quantizer */
1158 63, /* rc_max_quantizer */
1159 100, /* rc_undershoot_pct */
1160 100, /* rc_overshoot_pct */
1162 6000, /* rc_max_buffer_size */
1163 4000, /* rc_buffer_initial_size; */
1164 5000, /* rc_buffer_optimal_size; */
1166 50, /* rc_two_pass_vbrbias */
1167 0, /* rc_two_pass_vbrmin_section */
1168 2000, /* rc_two_pass_vbrmax_section */
1170 /* keyframing settings (kf) */
1171 VPX_KF_AUTO
, /* g_kfmode*/
1172 0, /* kf_min_dist */
1173 9999, /* kf_max_dist */
1175 VPX_SS_DEFAULT_LAYERS
, /* ss_number_layers */
1176 {0}, /* ss_target_bitrate */
1177 1, /* ts_number_layers */
1178 {0}, /* ts_target_bitrate */
1179 {0}, /* ts_rate_decimator */
1180 0, /* ts_periodicity */
1181 {0}, /* ts_layer_id */
1182 #if VPX_ENCODER_ABI_VERSION == (1 + VPX_CODEC_ABI_VERSION)
1183 "vp8.fpf" /* first pass filename */
1187 { -1, {NOT_IMPLEMENTED
}}
1191 #ifndef VERSION_STRING
1192 #define VERSION_STRING
1194 CODEC_INTERFACE(vpx_codec_vp9_cx
) = {
1195 "WebM Project VP9 Encoder" VERSION_STRING
,
1196 VPX_CODEC_INTERNAL_ABI_VERSION
,
1197 VPX_CODEC_CAP_ENCODER
| VPX_CODEC_CAP_PSNR
|
1198 VPX_CODEC_CAP_OUTPUT_PARTITION
,
1199 /* vpx_codec_caps_t caps; */
1200 vp9e_init
, /* vpx_codec_init_fn_t init; */
1201 vp9e_destroy
, /* vpx_codec_destroy_fn_t destroy; */
1202 vp9e_ctf_maps
, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */
1203 NOT_IMPLEMENTED
, /* vpx_codec_get_mmap_fn_t get_mmap; */
1204 NOT_IMPLEMENTED
, /* vpx_codec_set_mmap_fn_t set_mmap; */
1206 NOT_IMPLEMENTED
, /* vpx_codec_peek_si_fn_t peek_si; */
1207 NOT_IMPLEMENTED
, /* vpx_codec_get_si_fn_t get_si; */
1208 NOT_IMPLEMENTED
, /* vpx_codec_decode_fn_t decode; */
1209 NOT_IMPLEMENTED
, /* vpx_codec_frame_get_fn_t frame_get; */
1212 vp9e_usage_cfg_map
, /* vpx_codec_enc_cfg_map_t peek_si; */
1213 vp9e_encode
, /* vpx_codec_encode_fn_t encode; */
1214 vp9e_get_cxdata
, /* vpx_codec_get_cx_data_fn_t frame_get; */
1218 } /* encoder functions */