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_encoder.h" 16 #include "vpx_ports/vpx_once.h" 17 #include "vpx_ports/system_state.h" 18 #include "vpx/internal/vpx_codec_internal.h" 19 #include "./vpx_version.h" 20 #include "vp9/encoder/vp9_encoder.h" 21 #include "vpx/vp8cx.h" 22 #include "vp9/encoder/vp9_firstpass.h" 23 #include "vp9/vp9_iface_common.h" 24 25 struct vp9_extracfg { 26 int cpu_used; // available cpu percentage in 1/16 27 unsigned int enable_auto_alt_ref; 28 unsigned int noise_sensitivity; 29 unsigned int sharpness; 30 unsigned int static_thresh; 31 unsigned int tile_columns; 32 unsigned int tile_rows; 33 unsigned int arnr_max_frames; 34 unsigned int arnr_strength; 35 unsigned int min_gf_interval; 36 unsigned int max_gf_interval; 37 vp8e_tuning tuning; 38 unsigned int cq_level; // constrained quality level 39 unsigned int rc_max_intra_bitrate_pct; 40 unsigned int rc_max_inter_bitrate_pct; 41 unsigned int gf_cbr_boost_pct; 42 unsigned int lossless; 43 unsigned int target_level; 44 unsigned int frame_parallel_decoding_mode; 45 AQ_MODE aq_mode; 46 int alt_ref_aq; 47 unsigned int frame_periodic_boost; 48 vpx_bit_depth_t bit_depth; 49 vp9e_tune_content content; 50 vpx_color_space_t color_space; 51 vpx_color_range_t color_range; 52 int render_width; 53 int render_height; 54 unsigned int row_mt; 55 unsigned int motion_vector_unit_test; 56 }; 57 58 static struct vp9_extracfg default_extra_cfg = { 59 0, // cpu_used 60 1, // enable_auto_alt_ref 61 0, // noise_sensitivity 62 0, // sharpness 63 0, // static_thresh 64 6, // tile_columns 65 0, // tile_rows 66 7, // arnr_max_frames 67 5, // arnr_strength 68 0, // min_gf_interval; 0 -> default decision 69 0, // max_gf_interval; 0 -> default decision 70 VP8_TUNE_PSNR, // tuning 71 10, // cq_level 72 0, // rc_max_intra_bitrate_pct 73 0, // rc_max_inter_bitrate_pct 74 0, // gf_cbr_boost_pct 75 0, // lossless 76 255, // target_level 77 1, // frame_parallel_decoding_mode 78 NO_AQ, // aq_mode 79 0, // alt_ref_aq 80 0, // frame_periodic_delta_q 81 VPX_BITS_8, // Bit depth 82 VP9E_CONTENT_DEFAULT, // content 83 VPX_CS_UNKNOWN, // color space 84 0, // color range 85 0, // render width 86 0, // render height 87 0, // row_mt 88 0, // motion_vector_unit_test 89 }; 90 91 struct vpx_codec_alg_priv { 92 vpx_codec_priv_t base; 93 vpx_codec_enc_cfg_t cfg; 94 struct vp9_extracfg extra_cfg; 95 VP9EncoderConfig oxcf; 96 VP9_COMP *cpi; 97 unsigned char *cx_data; 98 size_t cx_data_sz; 99 unsigned char *pending_cx_data; 100 size_t pending_cx_data_sz; 101 int pending_frame_count; 102 size_t pending_frame_sizes[8]; 103 size_t pending_frame_magnitude; 104 vpx_image_t preview_img; 105 vpx_enc_frame_flags_t next_frame_flags; 106 vp8_postproc_cfg_t preview_ppcfg; 107 vpx_codec_pkt_list_decl(256) pkt_list; 108 unsigned int fixed_kf_cntr; 109 vpx_codec_priv_output_cx_pkt_cb_pair_t output_cx_pkt_cb; 110 // BufferPool that holds all reference frames. 111 BufferPool *buffer_pool; 112 }; 113 114 static vpx_codec_err_t update_error_state( 115 vpx_codec_alg_priv_t *ctx, const struct vpx_internal_error_info *error) { 116 const vpx_codec_err_t res = error->error_code; 117 118 if (res != VPX_CODEC_OK) 119 ctx->base.err_detail = error->has_detail ? error->detail : NULL; 120 121 return res; 122 } 123 124 #undef ERROR 125 #define ERROR(str) \ 126 do { \ 127 ctx->base.err_detail = str; \ 128 return VPX_CODEC_INVALID_PARAM; \ 129 } while (0) 130 131 #define RANGE_CHECK(p, memb, lo, hi) \ 132 do { \ 133 if (!(((p)->memb == lo || (p)->memb > (lo)) && (p)->memb <= hi)) \ 134 ERROR(#memb " out of range [" #lo ".." #hi "]"); \ 135 } while (0) 136 137 #define RANGE_CHECK_HI(p, memb, hi) \ 138 do { \ 139 if (!((p)->memb <= (hi))) ERROR(#memb " out of range [.." #hi "]"); \ 140 } while (0) 141 142 #define RANGE_CHECK_LO(p, memb, lo) \ 143 do { \ 144 if (!((p)->memb >= (lo))) ERROR(#memb " out of range [" #lo "..]"); \ 145 } while (0) 146 147 #define RANGE_CHECK_BOOL(p, memb) \ 148 do { \ 149 if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean"); \ 150 } while (0) 151 152 static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, 153 const vpx_codec_enc_cfg_t *cfg, 154 const struct vp9_extracfg *extra_cfg) { 155 RANGE_CHECK(cfg, g_w, 1, 65535); // 16 bits available 156 RANGE_CHECK(cfg, g_h, 1, 65535); // 16 bits available 157 RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000); 158 RANGE_CHECK(cfg, g_timebase.num, 1, 1000000000); 159 RANGE_CHECK_HI(cfg, g_profile, 3); 160 161 RANGE_CHECK_HI(cfg, rc_max_quantizer, 63); 162 RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer); 163 RANGE_CHECK_BOOL(extra_cfg, lossless); 164 RANGE_CHECK_BOOL(extra_cfg, frame_parallel_decoding_mode); 165 RANGE_CHECK(extra_cfg, aq_mode, 0, AQ_MODE_COUNT - 2); 166 RANGE_CHECK(extra_cfg, alt_ref_aq, 0, 1); 167 RANGE_CHECK(extra_cfg, frame_periodic_boost, 0, 1); 168 RANGE_CHECK_HI(cfg, g_threads, 64); 169 RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS); 170 RANGE_CHECK(cfg, rc_end_usage, VPX_VBR, VPX_Q); 171 RANGE_CHECK_HI(cfg, rc_undershoot_pct, 100); 172 RANGE_CHECK_HI(cfg, rc_overshoot_pct, 100); 173 RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100); 174 RANGE_CHECK(cfg, kf_mode, VPX_KF_DISABLED, VPX_KF_AUTO); 175 RANGE_CHECK_BOOL(cfg, rc_resize_allowed); 176 RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100); 177 RANGE_CHECK_HI(cfg, rc_resize_up_thresh, 100); 178 RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100); 179 RANGE_CHECK(cfg, g_pass, VPX_RC_ONE_PASS, VPX_RC_LAST_PASS); 180 RANGE_CHECK(extra_cfg, min_gf_interval, 0, (MAX_LAG_BUFFERS - 1)); 181 RANGE_CHECK(extra_cfg, max_gf_interval, 0, (MAX_LAG_BUFFERS - 1)); 182 if (extra_cfg->max_gf_interval > 0) { 183 RANGE_CHECK(extra_cfg, max_gf_interval, 2, (MAX_LAG_BUFFERS - 1)); 184 } 185 if (extra_cfg->min_gf_interval > 0 && extra_cfg->max_gf_interval > 0) { 186 RANGE_CHECK(extra_cfg, max_gf_interval, extra_cfg->min_gf_interval, 187 (MAX_LAG_BUFFERS - 1)); 188 } 189 190 if (cfg->rc_resize_allowed == 1) { 191 RANGE_CHECK(cfg, rc_scaled_width, 0, cfg->g_w); 192 RANGE_CHECK(cfg, rc_scaled_height, 0, cfg->g_h); 193 } 194 195 RANGE_CHECK(cfg, ss_number_layers, 1, VPX_SS_MAX_LAYERS); 196 RANGE_CHECK(cfg, ts_number_layers, 1, VPX_TS_MAX_LAYERS); 197 198 { 199 unsigned int level = extra_cfg->target_level; 200 if (level != LEVEL_1 && level != LEVEL_1_1 && level != LEVEL_2 && 201 level != LEVEL_2_1 && level != LEVEL_3 && level != LEVEL_3_1 && 202 level != LEVEL_4 && level != LEVEL_4_1 && level != LEVEL_5 && 203 level != LEVEL_5_1 && level != LEVEL_5_2 && level != LEVEL_6 && 204 level != LEVEL_6_1 && level != LEVEL_6_2 && level != LEVEL_UNKNOWN && 205 level != LEVEL_MAX) 206 ERROR("target_level is invalid"); 207 } 208 209 if (cfg->ss_number_layers * cfg->ts_number_layers > VPX_MAX_LAYERS) 210 ERROR("ss_number_layers * ts_number_layers is out of range"); 211 if (cfg->ts_number_layers > 1) { 212 unsigned int sl, tl; 213 for (sl = 1; sl < cfg->ss_number_layers; ++sl) { 214 for (tl = 1; tl < cfg->ts_number_layers; ++tl) { 215 const int layer = LAYER_IDS_TO_IDX(sl, tl, cfg->ts_number_layers); 216 if (cfg->layer_target_bitrate[layer] < 217 cfg->layer_target_bitrate[layer - 1]) 218 ERROR("ts_target_bitrate entries are not increasing"); 219 } 220 } 221 222 RANGE_CHECK(cfg, ts_rate_decimator[cfg->ts_number_layers - 1], 1, 1); 223 for (tl = cfg->ts_number_layers - 2; tl > 0; --tl) 224 if (cfg->ts_rate_decimator[tl - 1] != 2 * cfg->ts_rate_decimator[tl]) 225 ERROR("ts_rate_decimator factors are not powers of 2"); 226 } 227 228 #if CONFIG_SPATIAL_SVC 229 230 if ((cfg->ss_number_layers > 1 || cfg->ts_number_layers > 1) && 231 cfg->g_pass == VPX_RC_LAST_PASS) { 232 unsigned int i, alt_ref_sum = 0; 233 for (i = 0; i < cfg->ss_number_layers; ++i) { 234 if (cfg->ss_enable_auto_alt_ref[i]) ++alt_ref_sum; 235 } 236 if (alt_ref_sum > REF_FRAMES - cfg->ss_number_layers) 237 ERROR("Not enough ref buffers for svc alt ref frames"); 238 if (cfg->ss_number_layers * cfg->ts_number_layers > 3 && 239 cfg->g_error_resilient == 0) 240 ERROR("Multiple frame context are not supported for more than 3 layers"); 241 } 242 #endif 243 244 // VP9 does not support a lower bound on the keyframe interval in 245 // automatic keyframe placement mode. 246 if (cfg->kf_mode != VPX_KF_DISABLED && cfg->kf_min_dist != cfg->kf_max_dist && 247 cfg->kf_min_dist > 0) 248 ERROR( 249 "kf_min_dist not supported in auto mode, use 0 " 250 "or kf_max_dist instead."); 251 252 RANGE_CHECK(extra_cfg, row_mt, 0, 1); 253 RANGE_CHECK(extra_cfg, motion_vector_unit_test, 0, 2); 254 RANGE_CHECK(extra_cfg, enable_auto_alt_ref, 0, 2); 255 RANGE_CHECK(extra_cfg, cpu_used, -8, 8); 256 RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6); 257 RANGE_CHECK(extra_cfg, tile_columns, 0, 6); 258 RANGE_CHECK(extra_cfg, tile_rows, 0, 2); 259 RANGE_CHECK_HI(extra_cfg, sharpness, 7); 260 RANGE_CHECK(extra_cfg, arnr_max_frames, 0, 15); 261 RANGE_CHECK_HI(extra_cfg, arnr_strength, 6); 262 RANGE_CHECK(extra_cfg, cq_level, 0, 63); 263 RANGE_CHECK(cfg, g_bit_depth, VPX_BITS_8, VPX_BITS_12); 264 RANGE_CHECK(cfg, g_input_bit_depth, 8, 12); 265 RANGE_CHECK(extra_cfg, content, VP9E_CONTENT_DEFAULT, 266 VP9E_CONTENT_INVALID - 1); 267 268 // TODO(yaowu): remove this when ssim tuning is implemented for vp9 269 if (extra_cfg->tuning == VP8_TUNE_SSIM) 270 ERROR("Option --tune=ssim is not currently supported in VP9."); 271 272 if (cfg->g_pass == VPX_RC_LAST_PASS) { 273 const size_t packet_sz = sizeof(FIRSTPASS_STATS); 274 const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz); 275 const FIRSTPASS_STATS *stats; 276 277 if (cfg->rc_twopass_stats_in.buf == NULL) 278 ERROR("rc_twopass_stats_in.buf not set."); 279 280 if (cfg->rc_twopass_stats_in.sz % packet_sz) 281 ERROR("rc_twopass_stats_in.sz indicates truncated packet."); 282 283 if (cfg->ss_number_layers > 1 || cfg->ts_number_layers > 1) { 284 int i; 285 unsigned int n_packets_per_layer[VPX_SS_MAX_LAYERS] = { 0 }; 286 287 stats = cfg->rc_twopass_stats_in.buf; 288 for (i = 0; i < n_packets; ++i) { 289 const int layer_id = (int)stats[i].spatial_layer_id; 290 if (layer_id >= 0 && layer_id < (int)cfg->ss_number_layers) { 291 ++n_packets_per_layer[layer_id]; 292 } 293 } 294 295 for (i = 0; i < (int)cfg->ss_number_layers; ++i) { 296 unsigned int layer_id; 297 if (n_packets_per_layer[i] < 2) { 298 ERROR( 299 "rc_twopass_stats_in requires at least two packets for each " 300 "layer."); 301 } 302 303 stats = (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + 304 n_packets - cfg->ss_number_layers + i; 305 layer_id = (int)stats->spatial_layer_id; 306 307 if (layer_id >= cfg->ss_number_layers || 308 (unsigned int)(stats->count + 0.5) != 309 n_packets_per_layer[layer_id] - 1) 310 ERROR("rc_twopass_stats_in missing EOS stats packet"); 311 } 312 } else { 313 if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz) 314 ERROR("rc_twopass_stats_in requires at least two packets."); 315 316 stats = 317 (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1; 318 319 if ((int)(stats->count + 0.5) != n_packets - 1) 320 ERROR("rc_twopass_stats_in missing EOS stats packet"); 321 } 322 } 323 324 #if !CONFIG_VP9_HIGHBITDEPTH 325 if (cfg->g_profile > (unsigned int)PROFILE_1) { 326 ERROR("Profile > 1 not supported in this build configuration"); 327 } 328 #endif 329 if (cfg->g_profile <= (unsigned int)PROFILE_1 && 330 cfg->g_bit_depth > VPX_BITS_8) { 331 ERROR("Codec high bit-depth not supported in profile < 2"); 332 } 333 if (cfg->g_profile <= (unsigned int)PROFILE_1 && cfg->g_input_bit_depth > 8) { 334 ERROR("Source high bit-depth not supported in profile < 2"); 335 } 336 if (cfg->g_profile > (unsigned int)PROFILE_1 && 337 cfg->g_bit_depth == VPX_BITS_8) { 338 ERROR("Codec bit-depth 8 not supported in profile > 1"); 339 } 340 RANGE_CHECK(extra_cfg, color_space, VPX_CS_UNKNOWN, VPX_CS_SRGB); 341 RANGE_CHECK(extra_cfg, color_range, VPX_CR_STUDIO_RANGE, VPX_CR_FULL_RANGE); 342 return VPX_CODEC_OK; 343 } 344 345 static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx, 346 const vpx_image_t *img) { 347 switch (img->fmt) { 348 case VPX_IMG_FMT_YV12: 349 case VPX_IMG_FMT_I420: 350 case VPX_IMG_FMT_I42016: break; 351 case VPX_IMG_FMT_I422: 352 case VPX_IMG_FMT_I444: 353 case VPX_IMG_FMT_I440: 354 if (ctx->cfg.g_profile != (unsigned int)PROFILE_1) { 355 ERROR( 356 "Invalid image format. I422, I444, I440 images are " 357 "not supported in profile."); 358 } 359 break; 360 case VPX_IMG_FMT_I42216: 361 case VPX_IMG_FMT_I44416: 362 case VPX_IMG_FMT_I44016: 363 if (ctx->cfg.g_profile != (unsigned int)PROFILE_1 && 364 ctx->cfg.g_profile != (unsigned int)PROFILE_3) { 365 ERROR( 366 "Invalid image format. 16-bit I422, I444, I440 images are " 367 "not supported in profile."); 368 } 369 break; 370 default: 371 ERROR( 372 "Invalid image format. Only YV12, I420, I422, I444 images are " 373 "supported."); 374 break; 375 } 376 377 if (img->d_w != ctx->cfg.g_w || img->d_h != ctx->cfg.g_h) 378 ERROR("Image size must match encoder init configuration size"); 379 380 return VPX_CODEC_OK; 381 } 382 383 static int get_image_bps(const vpx_image_t *img) { 384 switch (img->fmt) { 385 case VPX_IMG_FMT_YV12: 386 case VPX_IMG_FMT_I420: return 12; 387 case VPX_IMG_FMT_I422: return 16; 388 case VPX_IMG_FMT_I444: return 24; 389 case VPX_IMG_FMT_I440: return 16; 390 case VPX_IMG_FMT_I42016: return 24; 391 case VPX_IMG_FMT_I42216: return 32; 392 case VPX_IMG_FMT_I44416: return 48; 393 case VPX_IMG_FMT_I44016: return 32; 394 default: assert(0 && "Invalid image format"); break; 395 } 396 return 0; 397 } 398 399 // Modify the encoder config for the target level. 400 static void config_target_level(VP9EncoderConfig *oxcf) { 401 double max_average_bitrate; // in bits per second 402 int max_over_shoot_pct; 403 const int target_level_index = get_level_index(oxcf->target_level); 404 405 vpx_clear_system_state(); 406 assert(target_level_index >= 0); 407 assert(target_level_index < VP9_LEVELS); 408 409 // Maximum target bit-rate is level_limit * 80%. 410 max_average_bitrate = 411 vp9_level_defs[target_level_index].average_bitrate * 800.0; 412 if ((double)oxcf->target_bandwidth > max_average_bitrate) 413 oxcf->target_bandwidth = (int64_t)(max_average_bitrate); 414 if (oxcf->ss_number_layers == 1 && oxcf->pass != 0) 415 oxcf->ss_target_bitrate[0] = (int)oxcf->target_bandwidth; 416 417 // Adjust max over-shoot percentage. 418 max_over_shoot_pct = 419 (int)((max_average_bitrate * 1.10 - (double)oxcf->target_bandwidth) * 420 100 / (double)(oxcf->target_bandwidth)); 421 if (oxcf->over_shoot_pct > max_over_shoot_pct) 422 oxcf->over_shoot_pct = max_over_shoot_pct; 423 424 // Adjust worst allowed quantizer. 425 oxcf->worst_allowed_q = vp9_quantizer_to_qindex(63); 426 427 // Adjust minimum art-ref distance. 428 if (oxcf->min_gf_interval < 429 (int)vp9_level_defs[target_level_index].min_altref_distance) 430 oxcf->min_gf_interval = 431 (int)vp9_level_defs[target_level_index].min_altref_distance; 432 433 // Adjust maximum column tiles. 434 if (vp9_level_defs[target_level_index].max_col_tiles < 435 (1 << oxcf->tile_columns)) { 436 while (oxcf->tile_columns > 0 && 437 vp9_level_defs[target_level_index].max_col_tiles < 438 (1 << oxcf->tile_columns)) 439 --oxcf->tile_columns; 440 } 441 } 442 443 static vpx_codec_err_t set_encoder_config( 444 VP9EncoderConfig *oxcf, const vpx_codec_enc_cfg_t *cfg, 445 const struct vp9_extracfg *extra_cfg) { 446 const int is_vbr = cfg->rc_end_usage == VPX_VBR; 447 int sl, tl; 448 oxcf->profile = cfg->g_profile; 449 oxcf->max_threads = (int)cfg->g_threads; 450 oxcf->width = cfg->g_w; 451 oxcf->height = cfg->g_h; 452 oxcf->bit_depth = cfg->g_bit_depth; 453 oxcf->input_bit_depth = cfg->g_input_bit_depth; 454 // guess a frame rate if out of whack, use 30 455 oxcf->init_framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num; 456 if (oxcf->init_framerate > 180) oxcf->init_framerate = 30; 457 458 oxcf->mode = GOOD; 459 460 switch (cfg->g_pass) { 461 case VPX_RC_ONE_PASS: oxcf->pass = 0; break; 462 case VPX_RC_FIRST_PASS: oxcf->pass = 1; break; 463 case VPX_RC_LAST_PASS: oxcf->pass = 2; break; 464 } 465 466 oxcf->lag_in_frames = 467 cfg->g_pass == VPX_RC_FIRST_PASS ? 0 : cfg->g_lag_in_frames; 468 oxcf->rc_mode = cfg->rc_end_usage; 469 470 // Convert target bandwidth from Kbit/s to Bit/s 471 oxcf->target_bandwidth = 1000 * cfg->rc_target_bitrate; 472 oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct; 473 oxcf->rc_max_inter_bitrate_pct = extra_cfg->rc_max_inter_bitrate_pct; 474 oxcf->gf_cbr_boost_pct = extra_cfg->gf_cbr_boost_pct; 475 476 oxcf->best_allowed_q = 477 extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_min_quantizer); 478 oxcf->worst_allowed_q = 479 extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_max_quantizer); 480 oxcf->cq_level = vp9_quantizer_to_qindex(extra_cfg->cq_level); 481 oxcf->fixed_q = -1; 482 483 oxcf->under_shoot_pct = cfg->rc_undershoot_pct; 484 oxcf->over_shoot_pct = cfg->rc_overshoot_pct; 485 486 oxcf->scaled_frame_width = cfg->rc_scaled_width; 487 oxcf->scaled_frame_height = cfg->rc_scaled_height; 488 if (cfg->rc_resize_allowed == 1) { 489 oxcf->resize_mode = 490 (oxcf->scaled_frame_width == 0 || oxcf->scaled_frame_height == 0) 491 ? RESIZE_DYNAMIC 492 : RESIZE_FIXED; 493 } else { 494 oxcf->resize_mode = RESIZE_NONE; 495 } 496 497 oxcf->maximum_buffer_size_ms = is_vbr ? 240000 : cfg->rc_buf_sz; 498 oxcf->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz; 499 oxcf->optimal_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_optimal_sz; 500 501 oxcf->drop_frames_water_mark = cfg->rc_dropframe_thresh; 502 503 oxcf->two_pass_vbrbias = cfg->rc_2pass_vbr_bias_pct; 504 oxcf->two_pass_vbrmin_section = cfg->rc_2pass_vbr_minsection_pct; 505 oxcf->two_pass_vbrmax_section = cfg->rc_2pass_vbr_maxsection_pct; 506 507 oxcf->auto_key = 508 cfg->kf_mode == VPX_KF_AUTO && cfg->kf_min_dist != cfg->kf_max_dist; 509 510 oxcf->key_freq = cfg->kf_max_dist; 511 512 oxcf->speed = abs(extra_cfg->cpu_used); 513 oxcf->encode_breakout = extra_cfg->static_thresh; 514 oxcf->enable_auto_arf = extra_cfg->enable_auto_alt_ref; 515 oxcf->noise_sensitivity = extra_cfg->noise_sensitivity; 516 oxcf->sharpness = extra_cfg->sharpness; 517 518 oxcf->two_pass_stats_in = cfg->rc_twopass_stats_in; 519 520 #if CONFIG_FP_MB_STATS 521 oxcf->firstpass_mb_stats_in = cfg->rc_firstpass_mb_stats_in; 522 #endif 523 524 oxcf->color_space = extra_cfg->color_space; 525 oxcf->color_range = extra_cfg->color_range; 526 oxcf->render_width = extra_cfg->render_width; 527 oxcf->render_height = extra_cfg->render_height; 528 oxcf->arnr_max_frames = extra_cfg->arnr_max_frames; 529 oxcf->arnr_strength = extra_cfg->arnr_strength; 530 oxcf->min_gf_interval = extra_cfg->min_gf_interval; 531 oxcf->max_gf_interval = extra_cfg->max_gf_interval; 532 533 oxcf->tuning = extra_cfg->tuning; 534 oxcf->content = extra_cfg->content; 535 536 oxcf->tile_columns = extra_cfg->tile_columns; 537 538 // TODO(yunqing): The dependencies between row tiles cause error in multi- 539 // threaded encoding. For now, tile_rows is forced to be 0 in this case. 540 // The further fix can be done by adding synchronizations after a tile row 541 // is encoded. But this will hurt multi-threaded encoder performance. So, 542 // it is recommended to use tile-rows=0 while encoding with threads > 1. 543 if (oxcf->max_threads > 1 && oxcf->tile_columns > 0) 544 oxcf->tile_rows = 0; 545 else 546 oxcf->tile_rows = extra_cfg->tile_rows; 547 548 oxcf->error_resilient_mode = cfg->g_error_resilient; 549 oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode; 550 551 oxcf->aq_mode = extra_cfg->aq_mode; 552 oxcf->alt_ref_aq = extra_cfg->alt_ref_aq; 553 554 oxcf->frame_periodic_boost = extra_cfg->frame_periodic_boost; 555 556 oxcf->ss_number_layers = cfg->ss_number_layers; 557 oxcf->ts_number_layers = cfg->ts_number_layers; 558 oxcf->temporal_layering_mode = 559 (enum vp9e_temporal_layering_mode)cfg->temporal_layering_mode; 560 561 oxcf->target_level = extra_cfg->target_level; 562 563 oxcf->row_mt = extra_cfg->row_mt; 564 oxcf->motion_vector_unit_test = extra_cfg->motion_vector_unit_test; 565 566 for (sl = 0; sl < oxcf->ss_number_layers; ++sl) { 567 #if CONFIG_SPATIAL_SVC 568 oxcf->ss_enable_auto_arf[sl] = cfg->ss_enable_auto_alt_ref[sl]; 569 #endif 570 for (tl = 0; tl < oxcf->ts_number_layers; ++tl) { 571 oxcf->layer_target_bitrate[sl * oxcf->ts_number_layers + tl] = 572 1000 * cfg->layer_target_bitrate[sl * oxcf->ts_number_layers + tl]; 573 } 574 } 575 if (oxcf->ss_number_layers == 1 && oxcf->pass != 0) { 576 oxcf->ss_target_bitrate[0] = (int)oxcf->target_bandwidth; 577 #if CONFIG_SPATIAL_SVC 578 oxcf->ss_enable_auto_arf[0] = extra_cfg->enable_auto_alt_ref; 579 #endif 580 } 581 if (oxcf->ts_number_layers > 1) { 582 for (tl = 0; tl < VPX_TS_MAX_LAYERS; ++tl) { 583 oxcf->ts_rate_decimator[tl] = 584 cfg->ts_rate_decimator[tl] ? cfg->ts_rate_decimator[tl] : 1; 585 } 586 } else if (oxcf->ts_number_layers == 1) { 587 oxcf->ts_rate_decimator[0] = 1; 588 } 589 590 if (get_level_index(oxcf->target_level) >= 0) config_target_level(oxcf); 591 /* 592 printf("Current VP9 Settings: \n"); 593 printf("target_bandwidth: %d\n", oxcf->target_bandwidth); 594 printf("target_level: %d\n", oxcf->target_level); 595 printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity); 596 printf("sharpness: %d\n", oxcf->sharpness); 597 printf("cpu_used: %d\n", oxcf->cpu_used); 598 printf("Mode: %d\n", oxcf->mode); 599 printf("auto_key: %d\n", oxcf->auto_key); 600 printf("key_freq: %d\n", oxcf->key_freq); 601 printf("end_usage: %d\n", oxcf->end_usage); 602 printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct); 603 printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct); 604 printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level); 605 printf("optimal_buffer_level: %d\n", oxcf->optimal_buffer_level); 606 printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size); 607 printf("fixed_q: %d\n", oxcf->fixed_q); 608 printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q); 609 printf("best_allowed_q: %d\n", oxcf->best_allowed_q); 610 printf("allow_spatial_resampling: %d\n", oxcf->allow_spatial_resampling); 611 printf("scaled_frame_width: %d\n", oxcf->scaled_frame_width); 612 printf("scaled_frame_height: %d\n", oxcf->scaled_frame_height); 613 printf("two_pass_vbrbias: %d\n", oxcf->two_pass_vbrbias); 614 printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section); 615 printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section); 616 printf("lag_in_frames: %d\n", oxcf->lag_in_frames); 617 printf("enable_auto_arf: %d\n", oxcf->enable_auto_arf); 618 printf("Version: %d\n", oxcf->Version); 619 printf("encode_breakout: %d\n", oxcf->encode_breakout); 620 printf("error resilient: %d\n", oxcf->error_resilient_mode); 621 printf("frame parallel detokenization: %d\n", 622 oxcf->frame_parallel_decoding_mode); 623 */ 624 return VPX_CODEC_OK; 625 } 626 627 static vpx_codec_err_t encoder_set_config(vpx_codec_alg_priv_t *ctx, 628 const vpx_codec_enc_cfg_t *cfg) { 629 vpx_codec_err_t res; 630 int force_key = 0; 631 632 if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h) { 633 if (cfg->g_lag_in_frames > 1 || cfg->g_pass != VPX_RC_ONE_PASS) 634 ERROR("Cannot change width or height after initialization"); 635 if (!valid_ref_frame_size(ctx->cfg.g_w, ctx->cfg.g_h, cfg->g_w, cfg->g_h) || 636 (ctx->cpi->initial_width && (int)cfg->g_w > ctx->cpi->initial_width) || 637 (ctx->cpi->initial_height && (int)cfg->g_h > ctx->cpi->initial_height)) 638 force_key = 1; 639 } 640 641 // Prevent increasing lag_in_frames. This check is stricter than it needs 642 // to be -- the limit is not increasing past the first lag_in_frames 643 // value, but we don't track the initial config, only the last successful 644 // config. 645 if (cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames) 646 ERROR("Cannot increase lag_in_frames"); 647 648 res = validate_config(ctx, cfg, &ctx->extra_cfg); 649 650 if (res == VPX_CODEC_OK) { 651 ctx->cfg = *cfg; 652 set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg); 653 // On profile change, request a key frame 654 force_key |= ctx->cpi->common.profile != ctx->oxcf.profile; 655 vp9_change_config(ctx->cpi, &ctx->oxcf); 656 } 657 658 if (force_key) ctx->next_frame_flags |= VPX_EFLAG_FORCE_KF; 659 660 return res; 661 } 662 663 static vpx_codec_err_t ctrl_get_quantizer(vpx_codec_alg_priv_t *ctx, 664 va_list args) { 665 int *const arg = va_arg(args, int *); 666 if (arg == NULL) return VPX_CODEC_INVALID_PARAM; 667 *arg = vp9_get_quantizer(ctx->cpi); 668 return VPX_CODEC_OK; 669 } 670 671 static vpx_codec_err_t ctrl_get_quantizer64(vpx_codec_alg_priv_t *ctx, 672 va_list args) { 673 int *const arg = va_arg(args, int *); 674 if (arg == NULL) return VPX_CODEC_INVALID_PARAM; 675 *arg = vp9_qindex_to_quantizer(vp9_get_quantizer(ctx->cpi)); 676 return VPX_CODEC_OK; 677 } 678 679 static vpx_codec_err_t update_extra_cfg(vpx_codec_alg_priv_t *ctx, 680 const struct vp9_extracfg *extra_cfg) { 681 const vpx_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg); 682 if (res == VPX_CODEC_OK) { 683 ctx->extra_cfg = *extra_cfg; 684 set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg); 685 vp9_change_config(ctx->cpi, &ctx->oxcf); 686 } 687 return res; 688 } 689 690 static vpx_codec_err_t ctrl_set_cpuused(vpx_codec_alg_priv_t *ctx, 691 va_list args) { 692 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 693 extra_cfg.cpu_used = CAST(VP8E_SET_CPUUSED, args); 694 return update_extra_cfg(ctx, &extra_cfg); 695 } 696 697 static vpx_codec_err_t ctrl_set_enable_auto_alt_ref(vpx_codec_alg_priv_t *ctx, 698 va_list args) { 699 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 700 extra_cfg.enable_auto_alt_ref = CAST(VP8E_SET_ENABLEAUTOALTREF, args); 701 return update_extra_cfg(ctx, &extra_cfg); 702 } 703 704 static vpx_codec_err_t ctrl_set_noise_sensitivity(vpx_codec_alg_priv_t *ctx, 705 va_list args) { 706 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 707 extra_cfg.noise_sensitivity = CAST(VP9E_SET_NOISE_SENSITIVITY, args); 708 return update_extra_cfg(ctx, &extra_cfg); 709 } 710 711 static vpx_codec_err_t ctrl_set_sharpness(vpx_codec_alg_priv_t *ctx, 712 va_list args) { 713 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 714 extra_cfg.sharpness = CAST(VP8E_SET_SHARPNESS, args); 715 return update_extra_cfg(ctx, &extra_cfg); 716 } 717 718 static vpx_codec_err_t ctrl_set_static_thresh(vpx_codec_alg_priv_t *ctx, 719 va_list args) { 720 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 721 extra_cfg.static_thresh = CAST(VP8E_SET_STATIC_THRESHOLD, args); 722 return update_extra_cfg(ctx, &extra_cfg); 723 } 724 725 static vpx_codec_err_t ctrl_set_tile_columns(vpx_codec_alg_priv_t *ctx, 726 va_list args) { 727 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 728 extra_cfg.tile_columns = CAST(VP9E_SET_TILE_COLUMNS, args); 729 return update_extra_cfg(ctx, &extra_cfg); 730 } 731 732 static vpx_codec_err_t ctrl_set_tile_rows(vpx_codec_alg_priv_t *ctx, 733 va_list args) { 734 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 735 extra_cfg.tile_rows = CAST(VP9E_SET_TILE_ROWS, args); 736 return update_extra_cfg(ctx, &extra_cfg); 737 } 738 739 static vpx_codec_err_t ctrl_set_arnr_max_frames(vpx_codec_alg_priv_t *ctx, 740 va_list args) { 741 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 742 extra_cfg.arnr_max_frames = CAST(VP8E_SET_ARNR_MAXFRAMES, args); 743 return update_extra_cfg(ctx, &extra_cfg); 744 } 745 746 static vpx_codec_err_t ctrl_set_arnr_strength(vpx_codec_alg_priv_t *ctx, 747 va_list args) { 748 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 749 extra_cfg.arnr_strength = CAST(VP8E_SET_ARNR_STRENGTH, args); 750 return update_extra_cfg(ctx, &extra_cfg); 751 } 752 753 static vpx_codec_err_t ctrl_set_arnr_type(vpx_codec_alg_priv_t *ctx, 754 va_list args) { 755 (void)ctx; 756 (void)args; 757 return VPX_CODEC_OK; 758 } 759 760 static vpx_codec_err_t ctrl_set_tuning(vpx_codec_alg_priv_t *ctx, 761 va_list args) { 762 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 763 extra_cfg.tuning = CAST(VP8E_SET_TUNING, args); 764 return update_extra_cfg(ctx, &extra_cfg); 765 } 766 767 static vpx_codec_err_t ctrl_set_cq_level(vpx_codec_alg_priv_t *ctx, 768 va_list args) { 769 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 770 extra_cfg.cq_level = CAST(VP8E_SET_CQ_LEVEL, args); 771 return update_extra_cfg(ctx, &extra_cfg); 772 } 773 774 static vpx_codec_err_t ctrl_set_rc_max_intra_bitrate_pct( 775 vpx_codec_alg_priv_t *ctx, va_list args) { 776 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 777 extra_cfg.rc_max_intra_bitrate_pct = 778 CAST(VP8E_SET_MAX_INTRA_BITRATE_PCT, args); 779 return update_extra_cfg(ctx, &extra_cfg); 780 } 781 782 static vpx_codec_err_t ctrl_set_rc_max_inter_bitrate_pct( 783 vpx_codec_alg_priv_t *ctx, va_list args) { 784 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 785 extra_cfg.rc_max_inter_bitrate_pct = 786 CAST(VP8E_SET_MAX_INTER_BITRATE_PCT, args); 787 return update_extra_cfg(ctx, &extra_cfg); 788 } 789 790 static vpx_codec_err_t ctrl_set_rc_gf_cbr_boost_pct(vpx_codec_alg_priv_t *ctx, 791 va_list args) { 792 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 793 extra_cfg.gf_cbr_boost_pct = CAST(VP9E_SET_GF_CBR_BOOST_PCT, args); 794 return update_extra_cfg(ctx, &extra_cfg); 795 } 796 797 static vpx_codec_err_t ctrl_set_lossless(vpx_codec_alg_priv_t *ctx, 798 va_list args) { 799 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 800 extra_cfg.lossless = CAST(VP9E_SET_LOSSLESS, args); 801 return update_extra_cfg(ctx, &extra_cfg); 802 } 803 804 static vpx_codec_err_t ctrl_set_frame_parallel_decoding_mode( 805 vpx_codec_alg_priv_t *ctx, va_list args) { 806 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 807 extra_cfg.frame_parallel_decoding_mode = 808 CAST(VP9E_SET_FRAME_PARALLEL_DECODING, args); 809 return update_extra_cfg(ctx, &extra_cfg); 810 } 811 812 static vpx_codec_err_t ctrl_set_aq_mode(vpx_codec_alg_priv_t *ctx, 813 va_list args) { 814 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 815 extra_cfg.aq_mode = CAST(VP9E_SET_AQ_MODE, args); 816 return update_extra_cfg(ctx, &extra_cfg); 817 } 818 819 static vpx_codec_err_t ctrl_set_alt_ref_aq(vpx_codec_alg_priv_t *ctx, 820 va_list args) { 821 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 822 extra_cfg.alt_ref_aq = CAST(VP9E_SET_ALT_REF_AQ, args); 823 return update_extra_cfg(ctx, &extra_cfg); 824 } 825 826 static vpx_codec_err_t ctrl_set_min_gf_interval(vpx_codec_alg_priv_t *ctx, 827 va_list args) { 828 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 829 extra_cfg.min_gf_interval = CAST(VP9E_SET_MIN_GF_INTERVAL, args); 830 return update_extra_cfg(ctx, &extra_cfg); 831 } 832 833 static vpx_codec_err_t ctrl_set_max_gf_interval(vpx_codec_alg_priv_t *ctx, 834 va_list args) { 835 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 836 extra_cfg.max_gf_interval = CAST(VP9E_SET_MAX_GF_INTERVAL, args); 837 return update_extra_cfg(ctx, &extra_cfg); 838 } 839 840 static vpx_codec_err_t ctrl_set_frame_periodic_boost(vpx_codec_alg_priv_t *ctx, 841 va_list args) { 842 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 843 extra_cfg.frame_periodic_boost = CAST(VP9E_SET_FRAME_PERIODIC_BOOST, args); 844 return update_extra_cfg(ctx, &extra_cfg); 845 } 846 847 static vpx_codec_err_t ctrl_set_target_level(vpx_codec_alg_priv_t *ctx, 848 va_list args) { 849 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 850 extra_cfg.target_level = CAST(VP9E_SET_TARGET_LEVEL, args); 851 return update_extra_cfg(ctx, &extra_cfg); 852 } 853 854 static vpx_codec_err_t ctrl_set_row_mt(vpx_codec_alg_priv_t *ctx, 855 va_list args) { 856 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 857 extra_cfg.row_mt = CAST(VP9E_SET_ROW_MT, args); 858 return update_extra_cfg(ctx, &extra_cfg); 859 } 860 861 static vpx_codec_err_t ctrl_enable_motion_vector_unit_test( 862 vpx_codec_alg_priv_t *ctx, va_list args) { 863 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 864 extra_cfg.motion_vector_unit_test = 865 CAST(VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, args); 866 return update_extra_cfg(ctx, &extra_cfg); 867 } 868 869 static vpx_codec_err_t ctrl_get_level(vpx_codec_alg_priv_t *ctx, va_list args) { 870 int *const arg = va_arg(args, int *); 871 if (arg == NULL) return VPX_CODEC_INVALID_PARAM; 872 *arg = (int)vp9_get_level(&ctx->cpi->level_info.level_spec); 873 return VPX_CODEC_OK; 874 } 875 876 static vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx, 877 vpx_codec_priv_enc_mr_cfg_t *data) { 878 vpx_codec_err_t res = VPX_CODEC_OK; 879 (void)data; 880 881 if (ctx->priv == NULL) { 882 vpx_codec_alg_priv_t *const priv = vpx_calloc(1, sizeof(*priv)); 883 if (priv == NULL) return VPX_CODEC_MEM_ERROR; 884 885 ctx->priv = (vpx_codec_priv_t *)priv; 886 ctx->priv->init_flags = ctx->init_flags; 887 ctx->priv->enc.total_encoders = 1; 888 priv->buffer_pool = (BufferPool *)vpx_calloc(1, sizeof(BufferPool)); 889 if (priv->buffer_pool == NULL) return VPX_CODEC_MEM_ERROR; 890 891 #if CONFIG_MULTITHREAD 892 if (pthread_mutex_init(&priv->buffer_pool->pool_mutex, NULL)) { 893 return VPX_CODEC_MEM_ERROR; 894 } 895 #endif 896 897 if (ctx->config.enc) { 898 // Update the reference to the config structure to an internal copy. 899 priv->cfg = *ctx->config.enc; 900 ctx->config.enc = &priv->cfg; 901 } 902 903 priv->extra_cfg = default_extra_cfg; 904 once(vp9_initialize_enc); 905 906 res = validate_config(priv, &priv->cfg, &priv->extra_cfg); 907 908 if (res == VPX_CODEC_OK) { 909 set_encoder_config(&priv->oxcf, &priv->cfg, &priv->extra_cfg); 910 #if CONFIG_VP9_HIGHBITDEPTH 911 priv->oxcf.use_highbitdepth = 912 (ctx->init_flags & VPX_CODEC_USE_HIGHBITDEPTH) ? 1 : 0; 913 #endif 914 priv->cpi = vp9_create_compressor(&priv->oxcf, priv->buffer_pool); 915 if (priv->cpi == NULL) 916 res = VPX_CODEC_MEM_ERROR; 917 else 918 priv->cpi->output_pkt_list = &priv->pkt_list.head; 919 } 920 } 921 922 return res; 923 } 924 925 static vpx_codec_err_t encoder_destroy(vpx_codec_alg_priv_t *ctx) { 926 free(ctx->cx_data); 927 vp9_remove_compressor(ctx->cpi); 928 #if CONFIG_MULTITHREAD 929 pthread_mutex_destroy(&ctx->buffer_pool->pool_mutex); 930 #endif 931 vpx_free(ctx->buffer_pool); 932 vpx_free(ctx); 933 return VPX_CODEC_OK; 934 } 935 936 static void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx, 937 unsigned long duration, 938 unsigned long deadline) { 939 MODE new_mode = BEST; 940 941 switch (ctx->cfg.g_pass) { 942 case VPX_RC_ONE_PASS: 943 if (deadline > 0) { 944 const vpx_codec_enc_cfg_t *const cfg = &ctx->cfg; 945 946 // Convert duration parameter from stream timebase to microseconds. 947 const uint64_t duration_us = (uint64_t)duration * 1000000 * 948 (uint64_t)cfg->g_timebase.num / 949 (uint64_t)cfg->g_timebase.den; 950 951 // If the deadline is more that the duration this frame is to be shown, 952 // use good quality mode. Otherwise use realtime mode. 953 new_mode = (deadline > duration_us) ? GOOD : REALTIME; 954 } else { 955 new_mode = BEST; 956 } 957 break; 958 case VPX_RC_FIRST_PASS: break; 959 case VPX_RC_LAST_PASS: new_mode = deadline > 0 ? GOOD : BEST; break; 960 } 961 962 if (deadline == VPX_DL_REALTIME) { 963 ctx->oxcf.pass = 0; 964 new_mode = REALTIME; 965 } 966 967 if (ctx->oxcf.mode != new_mode) { 968 ctx->oxcf.mode = new_mode; 969 vp9_change_config(ctx->cpi, &ctx->oxcf); 970 } 971 } 972 973 // Turn on to test if supplemental superframe data breaks decoding 974 // #define TEST_SUPPLEMENTAL_SUPERFRAME_DATA 975 static int write_superframe_index(vpx_codec_alg_priv_t *ctx) { 976 uint8_t marker = 0xc0; 977 unsigned int mask; 978 int mag, index_sz; 979 980 assert(ctx->pending_frame_count); 981 assert(ctx->pending_frame_count <= 8); 982 983 // Add the number of frames to the marker byte 984 marker |= ctx->pending_frame_count - 1; 985 986 // Choose the magnitude 987 for (mag = 0, mask = 0xff; mag < 4; mag++) { 988 if (ctx->pending_frame_magnitude < mask) break; 989 mask <<= 8; 990 mask |= 0xff; 991 } 992 marker |= mag << 3; 993 994 // Write the index 995 index_sz = 2 + (mag + 1) * ctx->pending_frame_count; 996 if (ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz) { 997 uint8_t *x = ctx->pending_cx_data + ctx->pending_cx_data_sz; 998 int i, j; 999 #ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA 1000 uint8_t marker_test = 0xc0; 1001 int mag_test = 2; // 1 - 4 1002 int frames_test = 4; // 1 - 8 1003 int index_sz_test = 2 + mag_test * frames_test; 1004 marker_test |= frames_test - 1; 1005 marker_test |= (mag_test - 1) << 3; 1006 *x++ = marker_test; 1007 for (i = 0; i < mag_test * frames_test; ++i) 1008 *x++ = 0; // fill up with arbitrary data 1009 *x++ = marker_test; 1010 ctx->pending_cx_data_sz += index_sz_test; 1011 printf("Added supplemental superframe data\n"); 1012 #endif 1013 1014 *x++ = marker; 1015 for (i = 0; i < ctx->pending_frame_count; i++) { 1016 unsigned int this_sz = (unsigned int)ctx->pending_frame_sizes[i]; 1017 1018 for (j = 0; j <= mag; j++) { 1019 *x++ = this_sz & 0xff; 1020 this_sz >>= 8; 1021 } 1022 } 1023 *x++ = marker; 1024 ctx->pending_cx_data_sz += index_sz; 1025 #ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA 1026 index_sz += index_sz_test; 1027 #endif 1028 } 1029 return index_sz; 1030 } 1031 1032 static int64_t timebase_units_to_ticks(const vpx_rational_t *timebase, 1033 int64_t n) { 1034 return n * TICKS_PER_SEC * timebase->num / timebase->den; 1035 } 1036 1037 static int64_t ticks_to_timebase_units(const vpx_rational_t *timebase, 1038 int64_t n) { 1039 const int64_t round = (int64_t)TICKS_PER_SEC * timebase->num / 2 - 1; 1040 return (n * timebase->den + round) / timebase->num / TICKS_PER_SEC; 1041 } 1042 1043 static vpx_codec_frame_flags_t get_frame_pkt_flags(const VP9_COMP *cpi, 1044 unsigned int lib_flags) { 1045 vpx_codec_frame_flags_t flags = lib_flags << 16; 1046 1047 if (lib_flags & FRAMEFLAGS_KEY || 1048 (cpi->use_svc && 1049 cpi->svc 1050 .layer_context[cpi->svc.spatial_layer_id * 1051 cpi->svc.number_temporal_layers + 1052 cpi->svc.temporal_layer_id] 1053 .is_key_frame)) 1054 flags |= VPX_FRAME_IS_KEY; 1055 1056 if (cpi->droppable) flags |= VPX_FRAME_IS_DROPPABLE; 1057 1058 return flags; 1059 } 1060 1061 const size_t kMinCompressedSize = 8192; 1062 static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, 1063 const vpx_image_t *img, 1064 vpx_codec_pts_t pts, 1065 unsigned long duration, 1066 vpx_enc_frame_flags_t enc_flags, 1067 unsigned long deadline) { 1068 volatile vpx_codec_err_t res = VPX_CODEC_OK; 1069 volatile vpx_enc_frame_flags_t flags = enc_flags; 1070 VP9_COMP *const cpi = ctx->cpi; 1071 const vpx_rational_t *const timebase = &ctx->cfg.g_timebase; 1072 size_t data_sz; 1073 1074 if (cpi == NULL) return VPX_CODEC_INVALID_PARAM; 1075 1076 if (cpi->oxcf.pass == 2 && cpi->level_constraint.level_index >= 0 && 1077 !cpi->level_constraint.rc_config_updated) { 1078 SVC *const svc = &cpi->svc; 1079 const int is_two_pass_svc = 1080 (svc->number_spatial_layers > 1) || (svc->number_temporal_layers > 1); 1081 const VP9EncoderConfig *const oxcf = &cpi->oxcf; 1082 TWO_PASS *const twopass = &cpi->twopass; 1083 FIRSTPASS_STATS *stats = &twopass->total_stats; 1084 if (is_two_pass_svc) { 1085 const double frame_rate = 10000000.0 * stats->count / stats->duration; 1086 vp9_update_spatial_layer_framerate(cpi, frame_rate); 1087 twopass->bits_left = 1088 (int64_t)(stats->duration * 1089 svc->layer_context[svc->spatial_layer_id].target_bandwidth / 1090 10000000.0); 1091 } else { 1092 twopass->bits_left = 1093 (int64_t)(stats->duration * oxcf->target_bandwidth / 10000000.0); 1094 } 1095 cpi->level_constraint.rc_config_updated = 1; 1096 } 1097 1098 if (img != NULL) { 1099 res = validate_img(ctx, img); 1100 if (res == VPX_CODEC_OK) { 1101 // There's no codec control for multiple alt-refs so check the encoder 1102 // instance for its status to determine the compressed data size. 1103 data_sz = ctx->cfg.g_w * ctx->cfg.g_h * get_image_bps(img) / 8 * 1104 (cpi->multi_arf_allowed ? 8 : 2); 1105 if (data_sz < kMinCompressedSize) data_sz = kMinCompressedSize; 1106 if (ctx->cx_data == NULL || ctx->cx_data_sz < data_sz) { 1107 ctx->cx_data_sz = data_sz; 1108 free(ctx->cx_data); 1109 ctx->cx_data = (unsigned char *)malloc(ctx->cx_data_sz); 1110 if (ctx->cx_data == NULL) { 1111 return VPX_CODEC_MEM_ERROR; 1112 } 1113 } 1114 } 1115 } 1116 1117 pick_quickcompress_mode(ctx, duration, deadline); 1118 vpx_codec_pkt_list_init(&ctx->pkt_list); 1119 1120 // Handle Flags 1121 if (((flags & VP8_EFLAG_NO_UPD_GF) && (flags & VP8_EFLAG_FORCE_GF)) || 1122 ((flags & VP8_EFLAG_NO_UPD_ARF) && (flags & VP8_EFLAG_FORCE_ARF))) { 1123 ctx->base.err_detail = "Conflicting flags."; 1124 return VPX_CODEC_INVALID_PARAM; 1125 } 1126 1127 if (setjmp(cpi->common.error.jmp)) { 1128 cpi->common.error.setjmp = 0; 1129 res = update_error_state(ctx, &cpi->common.error); 1130 vpx_clear_system_state(); 1131 return res; 1132 } 1133 cpi->common.error.setjmp = 1; 1134 1135 if (res == VPX_CODEC_OK) vp9_apply_encoding_flags(cpi, flags); 1136 1137 // Handle fixed keyframe intervals 1138 if (ctx->cfg.kf_mode == VPX_KF_AUTO && 1139 ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) { 1140 if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) { 1141 flags |= VPX_EFLAG_FORCE_KF; 1142 ctx->fixed_kf_cntr = 1; 1143 } 1144 } 1145 1146 if (res == VPX_CODEC_OK) { 1147 unsigned int lib_flags = 0; 1148 YV12_BUFFER_CONFIG sd; 1149 int64_t dst_time_stamp = timebase_units_to_ticks(timebase, pts); 1150 int64_t dst_end_time_stamp = 1151 timebase_units_to_ticks(timebase, pts + duration); 1152 size_t size, cx_data_sz; 1153 unsigned char *cx_data; 1154 1155 // Set up internal flags 1156 if (ctx->base.init_flags & VPX_CODEC_USE_PSNR) cpi->b_calculate_psnr = 1; 1157 1158 if (img != NULL) { 1159 res = image2yuvconfig(img, &sd); 1160 1161 // Store the original flags in to the frame buffer. Will extract the 1162 // key frame flag when we actually encode this frame. 1163 if (vp9_receive_raw_frame(cpi, flags | ctx->next_frame_flags, &sd, 1164 dst_time_stamp, dst_end_time_stamp)) { 1165 res = update_error_state(ctx, &cpi->common.error); 1166 } 1167 ctx->next_frame_flags = 0; 1168 } 1169 1170 cx_data = ctx->cx_data; 1171 cx_data_sz = ctx->cx_data_sz; 1172 1173 /* Any pending invisible frames? */ 1174 if (ctx->pending_cx_data) { 1175 memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz); 1176 ctx->pending_cx_data = cx_data; 1177 cx_data += ctx->pending_cx_data_sz; 1178 cx_data_sz -= ctx->pending_cx_data_sz; 1179 1180 /* TODO: this is a minimal check, the underlying codec doesn't respect 1181 * the buffer size anyway. 1182 */ 1183 if (cx_data_sz < ctx->cx_data_sz / 2) { 1184 vpx_internal_error(&cpi->common.error, VPX_CODEC_ERROR, 1185 "Compressed data buffer too small"); 1186 return VPX_CODEC_ERROR; 1187 } 1188 } 1189 1190 while (cx_data_sz >= ctx->cx_data_sz / 2 && 1191 -1 != vp9_get_compressed_data(cpi, &lib_flags, &size, cx_data, 1192 &dst_time_stamp, &dst_end_time_stamp, 1193 !img)) { 1194 if (size) { 1195 vpx_codec_cx_pkt_t pkt; 1196 1197 #if CONFIG_SPATIAL_SVC 1198 if (cpi->use_svc) 1199 cpi->svc 1200 .layer_context[cpi->svc.spatial_layer_id * 1201 cpi->svc.number_temporal_layers] 1202 .layer_size += size; 1203 #endif 1204 1205 // Pack invisible frames with the next visible frame 1206 if (!cpi->common.show_frame || 1207 (cpi->use_svc && 1208 cpi->svc.spatial_layer_id < cpi->svc.number_spatial_layers - 1)) { 1209 if (ctx->pending_cx_data == 0) ctx->pending_cx_data = cx_data; 1210 ctx->pending_cx_data_sz += size; 1211 ctx->pending_frame_sizes[ctx->pending_frame_count++] = size; 1212 ctx->pending_frame_magnitude |= size; 1213 cx_data += size; 1214 cx_data_sz -= size; 1215 1216 if (ctx->output_cx_pkt_cb.output_cx_pkt) { 1217 pkt.kind = VPX_CODEC_CX_FRAME_PKT; 1218 pkt.data.frame.pts = 1219 ticks_to_timebase_units(timebase, dst_time_stamp); 1220 pkt.data.frame.duration = (unsigned long)ticks_to_timebase_units( 1221 timebase, dst_end_time_stamp - dst_time_stamp); 1222 pkt.data.frame.flags = get_frame_pkt_flags(cpi, lib_flags); 1223 pkt.data.frame.buf = ctx->pending_cx_data; 1224 pkt.data.frame.sz = size; 1225 ctx->pending_cx_data = NULL; 1226 ctx->pending_cx_data_sz = 0; 1227 ctx->pending_frame_count = 0; 1228 ctx->pending_frame_magnitude = 0; 1229 ctx->output_cx_pkt_cb.output_cx_pkt( 1230 &pkt, ctx->output_cx_pkt_cb.user_priv); 1231 } 1232 continue; 1233 } 1234 1235 // Add the frame packet to the list of returned packets. 1236 pkt.kind = VPX_CODEC_CX_FRAME_PKT; 1237 pkt.data.frame.pts = ticks_to_timebase_units(timebase, dst_time_stamp); 1238 pkt.data.frame.duration = (unsigned long)ticks_to_timebase_units( 1239 timebase, dst_end_time_stamp - dst_time_stamp); 1240 pkt.data.frame.flags = get_frame_pkt_flags(cpi, lib_flags); 1241 1242 if (ctx->pending_cx_data) { 1243 ctx->pending_frame_sizes[ctx->pending_frame_count++] = size; 1244 ctx->pending_frame_magnitude |= size; 1245 ctx->pending_cx_data_sz += size; 1246 // write the superframe only for the case when 1247 if (!ctx->output_cx_pkt_cb.output_cx_pkt) 1248 size += write_superframe_index(ctx); 1249 pkt.data.frame.buf = ctx->pending_cx_data; 1250 pkt.data.frame.sz = ctx->pending_cx_data_sz; 1251 ctx->pending_cx_data = NULL; 1252 ctx->pending_cx_data_sz = 0; 1253 ctx->pending_frame_count = 0; 1254 ctx->pending_frame_magnitude = 0; 1255 } else { 1256 pkt.data.frame.buf = cx_data; 1257 pkt.data.frame.sz = size; 1258 } 1259 pkt.data.frame.partition_id = -1; 1260 1261 if (ctx->output_cx_pkt_cb.output_cx_pkt) 1262 ctx->output_cx_pkt_cb.output_cx_pkt(&pkt, 1263 ctx->output_cx_pkt_cb.user_priv); 1264 else 1265 vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt); 1266 1267 cx_data += size; 1268 cx_data_sz -= size; 1269 #if VPX_ENCODER_ABI_VERSION > (5 + VPX_CODEC_ABI_VERSION) 1270 #if CONFIG_SPATIAL_SVC 1271 if (cpi->use_svc && !ctx->output_cx_pkt_cb.output_cx_pkt) { 1272 vpx_codec_cx_pkt_t pkt_sizes, pkt_psnr; 1273 int sl; 1274 vp9_zero(pkt_sizes); 1275 vp9_zero(pkt_psnr); 1276 pkt_sizes.kind = VPX_CODEC_SPATIAL_SVC_LAYER_SIZES; 1277 pkt_psnr.kind = VPX_CODEC_SPATIAL_SVC_LAYER_PSNR; 1278 for (sl = 0; sl < cpi->svc.number_spatial_layers; ++sl) { 1279 LAYER_CONTEXT *lc = 1280 &cpi->svc.layer_context[sl * cpi->svc.number_temporal_layers]; 1281 pkt_sizes.data.layer_sizes[sl] = lc->layer_size; 1282 pkt_psnr.data.layer_psnr[sl] = lc->psnr_pkt; 1283 lc->layer_size = 0; 1284 } 1285 1286 vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt_sizes); 1287 1288 vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt_psnr); 1289 } 1290 #endif 1291 #endif 1292 if (is_one_pass_cbr_svc(cpi) && 1293 (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)) { 1294 // Encoded all spatial layers; exit loop. 1295 break; 1296 } 1297 } 1298 } 1299 } 1300 1301 cpi->common.error.setjmp = 0; 1302 return res; 1303 } 1304 1305 static const vpx_codec_cx_pkt_t *encoder_get_cxdata(vpx_codec_alg_priv_t *ctx, 1306 vpx_codec_iter_t *iter) { 1307 return vpx_codec_pkt_list_get(&ctx->pkt_list.head, iter); 1308 } 1309 1310 static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx, 1311 va_list args) { 1312 vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *); 1313 1314 if (frame != NULL) { 1315 YV12_BUFFER_CONFIG sd; 1316 1317 image2yuvconfig(&frame->img, &sd); 1318 vp9_set_reference_enc(ctx->cpi, ref_frame_to_vp9_reframe(frame->frame_type), 1319 &sd); 1320 return VPX_CODEC_OK; 1321 } else { 1322 return VPX_CODEC_INVALID_PARAM; 1323 } 1324 } 1325 1326 static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx, 1327 va_list args) { 1328 vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *); 1329 1330 if (frame != NULL) { 1331 YV12_BUFFER_CONFIG sd; 1332 1333 image2yuvconfig(&frame->img, &sd); 1334 vp9_copy_reference_enc(ctx->cpi, 1335 ref_frame_to_vp9_reframe(frame->frame_type), &sd); 1336 return VPX_CODEC_OK; 1337 } else { 1338 return VPX_CODEC_INVALID_PARAM; 1339 } 1340 } 1341 1342 static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx, 1343 va_list args) { 1344 vp9_ref_frame_t *const frame = va_arg(args, vp9_ref_frame_t *); 1345 1346 if (frame != NULL) { 1347 YV12_BUFFER_CONFIG *fb = get_ref_frame(&ctx->cpi->common, frame->idx); 1348 if (fb == NULL) return VPX_CODEC_ERROR; 1349 1350 yuvconfig2image(&frame->img, fb, NULL); 1351 return VPX_CODEC_OK; 1352 } else { 1353 return VPX_CODEC_INVALID_PARAM; 1354 } 1355 } 1356 1357 static vpx_codec_err_t ctrl_set_previewpp(vpx_codec_alg_priv_t *ctx, 1358 va_list args) { 1359 #if CONFIG_VP9_POSTPROC 1360 vp8_postproc_cfg_t *config = va_arg(args, vp8_postproc_cfg_t *); 1361 if (config != NULL) { 1362 ctx->preview_ppcfg = *config; 1363 return VPX_CODEC_OK; 1364 } else { 1365 return VPX_CODEC_INVALID_PARAM; 1366 } 1367 #else 1368 (void)ctx; 1369 (void)args; 1370 return VPX_CODEC_INCAPABLE; 1371 #endif 1372 } 1373 1374 static vpx_image_t *encoder_get_preview(vpx_codec_alg_priv_t *ctx) { 1375 YV12_BUFFER_CONFIG sd; 1376 vp9_ppflags_t flags; 1377 vp9_zero(flags); 1378 1379 if (ctx->preview_ppcfg.post_proc_flag) { 1380 flags.post_proc_flag = ctx->preview_ppcfg.post_proc_flag; 1381 flags.deblocking_level = ctx->preview_ppcfg.deblocking_level; 1382 flags.noise_level = ctx->preview_ppcfg.noise_level; 1383 } 1384 1385 if (vp9_get_preview_raw_frame(ctx->cpi, &sd, &flags) == 0) { 1386 yuvconfig2image(&ctx->preview_img, &sd, NULL); 1387 return &ctx->preview_img; 1388 } else { 1389 return NULL; 1390 } 1391 } 1392 1393 static vpx_codec_err_t ctrl_set_roi_map(vpx_codec_alg_priv_t *ctx, 1394 va_list args) { 1395 (void)ctx; 1396 (void)args; 1397 1398 // TODO(yaowu): Need to re-implement and test for VP9. 1399 return VPX_CODEC_INVALID_PARAM; 1400 } 1401 1402 static vpx_codec_err_t ctrl_set_active_map(vpx_codec_alg_priv_t *ctx, 1403 va_list args) { 1404 vpx_active_map_t *const map = va_arg(args, vpx_active_map_t *); 1405 1406 if (map) { 1407 if (!vp9_set_active_map(ctx->cpi, map->active_map, (int)map->rows, 1408 (int)map->cols)) 1409 return VPX_CODEC_OK; 1410 else 1411 return VPX_CODEC_INVALID_PARAM; 1412 } else { 1413 return VPX_CODEC_INVALID_PARAM; 1414 } 1415 } 1416 1417 static vpx_codec_err_t ctrl_get_active_map(vpx_codec_alg_priv_t *ctx, 1418 va_list args) { 1419 vpx_active_map_t *const map = va_arg(args, vpx_active_map_t *); 1420 1421 if (map) { 1422 if (!vp9_get_active_map(ctx->cpi, map->active_map, (int)map->rows, 1423 (int)map->cols)) 1424 return VPX_CODEC_OK; 1425 else 1426 return VPX_CODEC_INVALID_PARAM; 1427 } else { 1428 return VPX_CODEC_INVALID_PARAM; 1429 } 1430 } 1431 1432 static vpx_codec_err_t ctrl_set_scale_mode(vpx_codec_alg_priv_t *ctx, 1433 va_list args) { 1434 vpx_scaling_mode_t *const mode = va_arg(args, vpx_scaling_mode_t *); 1435 1436 if (mode) { 1437 const int res = 1438 vp9_set_internal_size(ctx->cpi, (VPX_SCALING)mode->h_scaling_mode, 1439 (VPX_SCALING)mode->v_scaling_mode); 1440 return (res == 0) ? VPX_CODEC_OK : VPX_CODEC_INVALID_PARAM; 1441 } else { 1442 return VPX_CODEC_INVALID_PARAM; 1443 } 1444 } 1445 1446 static vpx_codec_err_t ctrl_set_svc(vpx_codec_alg_priv_t *ctx, va_list args) { 1447 int data = va_arg(args, int); 1448 const vpx_codec_enc_cfg_t *cfg = &ctx->cfg; 1449 // Both one-pass and two-pass RC are supported now. 1450 // User setting this has to make sure of the following. 1451 // In two-pass setting: either (but not both) 1452 // cfg->ss_number_layers > 1, or cfg->ts_number_layers > 1 1453 // In one-pass setting: 1454 // either or both cfg->ss_number_layers > 1, or cfg->ts_number_layers > 1 1455 1456 vp9_set_svc(ctx->cpi, data); 1457 1458 if (data == 1 && 1459 (cfg->g_pass == VPX_RC_FIRST_PASS || cfg->g_pass == VPX_RC_LAST_PASS) && 1460 cfg->ss_number_layers > 1 && cfg->ts_number_layers > 1) { 1461 return VPX_CODEC_INVALID_PARAM; 1462 } 1463 1464 vp9_set_row_mt(ctx->cpi); 1465 1466 return VPX_CODEC_OK; 1467 } 1468 1469 static vpx_codec_err_t ctrl_set_svc_layer_id(vpx_codec_alg_priv_t *ctx, 1470 va_list args) { 1471 vpx_svc_layer_id_t *const data = va_arg(args, vpx_svc_layer_id_t *); 1472 VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi; 1473 SVC *const svc = &cpi->svc; 1474 1475 svc->first_spatial_layer_to_encode = data->spatial_layer_id; 1476 svc->spatial_layer_to_encode = data->spatial_layer_id; 1477 svc->temporal_layer_id = data->temporal_layer_id; 1478 // Checks on valid layer_id input. 1479 if (svc->temporal_layer_id < 0 || 1480 svc->temporal_layer_id >= (int)ctx->cfg.ts_number_layers) { 1481 return VPX_CODEC_INVALID_PARAM; 1482 } 1483 if (svc->first_spatial_layer_to_encode < 0 || 1484 svc->first_spatial_layer_to_encode >= (int)ctx->cfg.ss_number_layers) { 1485 return VPX_CODEC_INVALID_PARAM; 1486 } 1487 // First spatial layer to encode not implemented for two-pass. 1488 if (is_two_pass_svc(cpi) && svc->first_spatial_layer_to_encode > 0) 1489 return VPX_CODEC_INVALID_PARAM; 1490 return VPX_CODEC_OK; 1491 } 1492 1493 static vpx_codec_err_t ctrl_get_svc_layer_id(vpx_codec_alg_priv_t *ctx, 1494 va_list args) { 1495 vpx_svc_layer_id_t *data = va_arg(args, vpx_svc_layer_id_t *); 1496 VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi; 1497 SVC *const svc = &cpi->svc; 1498 1499 data->spatial_layer_id = svc->spatial_layer_id; 1500 data->temporal_layer_id = svc->temporal_layer_id; 1501 1502 return VPX_CODEC_OK; 1503 } 1504 1505 static vpx_codec_err_t ctrl_set_svc_parameters(vpx_codec_alg_priv_t *ctx, 1506 va_list args) { 1507 VP9_COMP *const cpi = ctx->cpi; 1508 vpx_svc_extra_cfg_t *const params = va_arg(args, vpx_svc_extra_cfg_t *); 1509 int sl, tl; 1510 1511 // Number of temporal layers and number of spatial layers have to be set 1512 // properly before calling this control function. 1513 for (sl = 0; sl < cpi->svc.number_spatial_layers; ++sl) { 1514 for (tl = 0; tl < cpi->svc.number_temporal_layers; ++tl) { 1515 const int layer = 1516 LAYER_IDS_TO_IDX(sl, tl, cpi->svc.number_temporal_layers); 1517 LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer]; 1518 lc->max_q = params->max_quantizers[layer]; 1519 lc->min_q = params->min_quantizers[layer]; 1520 lc->scaling_factor_num = params->scaling_factor_num[sl]; 1521 lc->scaling_factor_den = params->scaling_factor_den[sl]; 1522 lc->speed = params->speed_per_layer[sl]; 1523 } 1524 } 1525 1526 return VPX_CODEC_OK; 1527 } 1528 1529 static vpx_codec_err_t ctrl_set_svc_ref_frame_config(vpx_codec_alg_priv_t *ctx, 1530 va_list args) { 1531 VP9_COMP *const cpi = ctx->cpi; 1532 vpx_svc_ref_frame_config_t *data = va_arg(args, vpx_svc_ref_frame_config_t *); 1533 int sl; 1534 for (sl = 0; sl < cpi->svc.number_spatial_layers; ++sl) { 1535 cpi->svc.ext_frame_flags[sl] = data->frame_flags[sl]; 1536 cpi->svc.ext_lst_fb_idx[sl] = data->lst_fb_idx[sl]; 1537 cpi->svc.ext_gld_fb_idx[sl] = data->gld_fb_idx[sl]; 1538 cpi->svc.ext_alt_fb_idx[sl] = data->alt_fb_idx[sl]; 1539 } 1540 return VPX_CODEC_OK; 1541 } 1542 1543 static vpx_codec_err_t ctrl_register_cx_callback(vpx_codec_alg_priv_t *ctx, 1544 va_list args) { 1545 vpx_codec_priv_output_cx_pkt_cb_pair_t *cbp = 1546 (vpx_codec_priv_output_cx_pkt_cb_pair_t *)va_arg(args, void *); 1547 ctx->output_cx_pkt_cb.output_cx_pkt = cbp->output_cx_pkt; 1548 ctx->output_cx_pkt_cb.user_priv = cbp->user_priv; 1549 1550 return VPX_CODEC_OK; 1551 } 1552 1553 static vpx_codec_err_t ctrl_set_tune_content(vpx_codec_alg_priv_t *ctx, 1554 va_list args) { 1555 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 1556 extra_cfg.content = CAST(VP9E_SET_TUNE_CONTENT, args); 1557 return update_extra_cfg(ctx, &extra_cfg); 1558 } 1559 1560 static vpx_codec_err_t ctrl_set_color_space(vpx_codec_alg_priv_t *ctx, 1561 va_list args) { 1562 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 1563 extra_cfg.color_space = CAST(VP9E_SET_COLOR_SPACE, args); 1564 return update_extra_cfg(ctx, &extra_cfg); 1565 } 1566 1567 static vpx_codec_err_t ctrl_set_color_range(vpx_codec_alg_priv_t *ctx, 1568 va_list args) { 1569 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 1570 extra_cfg.color_range = CAST(VP9E_SET_COLOR_RANGE, args); 1571 return update_extra_cfg(ctx, &extra_cfg); 1572 } 1573 1574 static vpx_codec_err_t ctrl_set_render_size(vpx_codec_alg_priv_t *ctx, 1575 va_list args) { 1576 struct vp9_extracfg extra_cfg = ctx->extra_cfg; 1577 int *const render_size = va_arg(args, int *); 1578 extra_cfg.render_width = render_size[0]; 1579 extra_cfg.render_height = render_size[1]; 1580 return update_extra_cfg(ctx, &extra_cfg); 1581 } 1582 1583 static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { 1584 { VP8_COPY_REFERENCE, ctrl_copy_reference }, 1585 1586 // Setters 1587 { VP8_SET_REFERENCE, ctrl_set_reference }, 1588 { VP8_SET_POSTPROC, ctrl_set_previewpp }, 1589 { VP8E_SET_ROI_MAP, ctrl_set_roi_map }, 1590 { VP8E_SET_ACTIVEMAP, ctrl_set_active_map }, 1591 { VP8E_SET_SCALEMODE, ctrl_set_scale_mode }, 1592 { VP8E_SET_CPUUSED, ctrl_set_cpuused }, 1593 { VP8E_SET_ENABLEAUTOALTREF, ctrl_set_enable_auto_alt_ref }, 1594 { VP8E_SET_SHARPNESS, ctrl_set_sharpness }, 1595 { VP8E_SET_STATIC_THRESHOLD, ctrl_set_static_thresh }, 1596 { VP9E_SET_TILE_COLUMNS, ctrl_set_tile_columns }, 1597 { VP9E_SET_TILE_ROWS, ctrl_set_tile_rows }, 1598 { VP8E_SET_ARNR_MAXFRAMES, ctrl_set_arnr_max_frames }, 1599 { VP8E_SET_ARNR_STRENGTH, ctrl_set_arnr_strength }, 1600 { VP8E_SET_ARNR_TYPE, ctrl_set_arnr_type }, 1601 { VP8E_SET_TUNING, ctrl_set_tuning }, 1602 { VP8E_SET_CQ_LEVEL, ctrl_set_cq_level }, 1603 { VP8E_SET_MAX_INTRA_BITRATE_PCT, ctrl_set_rc_max_intra_bitrate_pct }, 1604 { VP9E_SET_MAX_INTER_BITRATE_PCT, ctrl_set_rc_max_inter_bitrate_pct }, 1605 { VP9E_SET_GF_CBR_BOOST_PCT, ctrl_set_rc_gf_cbr_boost_pct }, 1606 { VP9E_SET_LOSSLESS, ctrl_set_lossless }, 1607 { VP9E_SET_FRAME_PARALLEL_DECODING, ctrl_set_frame_parallel_decoding_mode }, 1608 { VP9E_SET_AQ_MODE, ctrl_set_aq_mode }, 1609 { VP9E_SET_ALT_REF_AQ, ctrl_set_alt_ref_aq }, 1610 { VP9E_SET_FRAME_PERIODIC_BOOST, ctrl_set_frame_periodic_boost }, 1611 { VP9E_SET_SVC, ctrl_set_svc }, 1612 { VP9E_SET_SVC_PARAMETERS, ctrl_set_svc_parameters }, 1613 { VP9E_REGISTER_CX_CALLBACK, ctrl_register_cx_callback }, 1614 { VP9E_SET_SVC_LAYER_ID, ctrl_set_svc_layer_id }, 1615 { VP9E_SET_TUNE_CONTENT, ctrl_set_tune_content }, 1616 { VP9E_SET_COLOR_SPACE, ctrl_set_color_space }, 1617 { VP9E_SET_COLOR_RANGE, ctrl_set_color_range }, 1618 { VP9E_SET_NOISE_SENSITIVITY, ctrl_set_noise_sensitivity }, 1619 { VP9E_SET_MIN_GF_INTERVAL, ctrl_set_min_gf_interval }, 1620 { VP9E_SET_MAX_GF_INTERVAL, ctrl_set_max_gf_interval }, 1621 { VP9E_SET_SVC_REF_FRAME_CONFIG, ctrl_set_svc_ref_frame_config }, 1622 { VP9E_SET_RENDER_SIZE, ctrl_set_render_size }, 1623 { VP9E_SET_TARGET_LEVEL, ctrl_set_target_level }, 1624 { VP9E_SET_ROW_MT, ctrl_set_row_mt }, 1625 { VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test }, 1626 1627 // Getters 1628 { VP8E_GET_LAST_QUANTIZER, ctrl_get_quantizer }, 1629 { VP8E_GET_LAST_QUANTIZER_64, ctrl_get_quantizer64 }, 1630 { VP9_GET_REFERENCE, ctrl_get_reference }, 1631 { VP9E_GET_SVC_LAYER_ID, ctrl_get_svc_layer_id }, 1632 { VP9E_GET_ACTIVEMAP, ctrl_get_active_map }, 1633 { VP9E_GET_LEVEL, ctrl_get_level }, 1634 1635 { -1, NULL }, 1636 }; 1637 1638 static vpx_codec_enc_cfg_map_t encoder_usage_cfg_map[] = { 1639 { 0, 1640 { 1641 // NOLINT 1642 0, // g_usage 1643 8, // g_threads 1644 0, // g_profile 1645 1646 320, // g_width 1647 240, // g_height 1648 VPX_BITS_8, // g_bit_depth 1649 8, // g_input_bit_depth 1650 1651 { 1, 30 }, // g_timebase 1652 1653 0, // g_error_resilient 1654 1655 VPX_RC_ONE_PASS, // g_pass 1656 1657 25, // g_lag_in_frames 1658 1659 0, // rc_dropframe_thresh 1660 0, // rc_resize_allowed 1661 0, // rc_scaled_width 1662 0, // rc_scaled_height 1663 60, // rc_resize_down_thresold 1664 30, // rc_resize_up_thresold 1665 1666 VPX_VBR, // rc_end_usage 1667 { NULL, 0 }, // rc_twopass_stats_in 1668 { NULL, 0 }, // rc_firstpass_mb_stats_in 1669 256, // rc_target_bandwidth 1670 0, // rc_min_quantizer 1671 63, // rc_max_quantizer 1672 25, // rc_undershoot_pct 1673 25, // rc_overshoot_pct 1674 1675 6000, // rc_max_buffer_size 1676 4000, // rc_buffer_initial_size 1677 5000, // rc_buffer_optimal_size 1678 1679 50, // rc_two_pass_vbrbias 1680 0, // rc_two_pass_vbrmin_section 1681 2000, // rc_two_pass_vbrmax_section 1682 1683 // keyframing settings (kf) 1684 VPX_KF_AUTO, // g_kfmode 1685 0, // kf_min_dist 1686 128, // kf_max_dist 1687 1688 VPX_SS_DEFAULT_LAYERS, // ss_number_layers 1689 { 0 }, 1690 { 0 }, // ss_target_bitrate 1691 1, // ts_number_layers 1692 { 0 }, // ts_target_bitrate 1693 { 0 }, // ts_rate_decimator 1694 0, // ts_periodicity 1695 { 0 }, // ts_layer_id 1696 { 0 }, // layer_taget_bitrate 1697 0 // temporal_layering_mode 1698 } }, 1699 }; 1700 1701 #ifndef VERSION_STRING 1702 #define VERSION_STRING 1703 #endif 1704 CODEC_INTERFACE(vpx_codec_vp9_cx) = { 1705 "WebM Project VP9 Encoder" VERSION_STRING, 1706 VPX_CODEC_INTERNAL_ABI_VERSION, 1707 #if CONFIG_VP9_HIGHBITDEPTH 1708 VPX_CODEC_CAP_HIGHBITDEPTH | 1709 #endif 1710 VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR, // vpx_codec_caps_t 1711 encoder_init, // vpx_codec_init_fn_t 1712 encoder_destroy, // vpx_codec_destroy_fn_t 1713 encoder_ctrl_maps, // vpx_codec_ctrl_fn_map_t 1714 { 1715 // NOLINT 1716 NULL, // vpx_codec_peek_si_fn_t 1717 NULL, // vpx_codec_get_si_fn_t 1718 NULL, // vpx_codec_decode_fn_t 1719 NULL, // vpx_codec_frame_get_fn_t 1720 NULL // vpx_codec_set_fb_fn_t 1721 }, 1722 { 1723 // NOLINT 1724 1, // 1 cfg map 1725 encoder_usage_cfg_map, // vpx_codec_enc_cfg_map_t 1726 encoder_encode, // vpx_codec_encode_fn_t 1727 encoder_get_cxdata, // vpx_codec_get_cx_data_fn_t 1728 encoder_set_config, // vpx_codec_enc_config_set_fn_t 1729 NULL, // vpx_codec_get_global_headers_fn_t 1730 encoder_get_preview, // vpx_codec_get_preview_frame_fn_t 1731 NULL // vpx_codec_enc_mr_get_mem_loc_fn_t 1732 } 1733 }; 1734