1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 4233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Use of this source code is governed by a BSD-style license 5233d2500723e5594f3e7c70896ffeeef32b9c950ywan * that can be found in the LICENSE file in the root of the source 6233d2500723e5594f3e7c70896ffeeef32b9c950ywan * tree. An additional intellectual property rights grant can be found 7233d2500723e5594f3e7c70896ffeeef32b9c950ywan * in the file PATENTS. All contributing project authors may 8233d2500723e5594f3e7c70896ffeeef32b9c950ywan * be found in the AUTHORS file in the root of the source tree. 9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 10233d2500723e5594f3e7c70896ffeeef32b9c950ywan 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdlib.h> 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <string.h> 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx/vpx_codec.h" 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx/internal/vpx_codec_internal.h" 16233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./vpx_version.h" 17233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_onyx_int.h" 18233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx/vp8cx.h" 19233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_firstpass.h" 20233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/vp9_iface_common.h" 21233d2500723e5594f3e7c70896ffeeef32b9c950ywan 22233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct vp9_extracfg { 23233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct vpx_codec_pkt_list *pkt_list; 24233d2500723e5594f3e7c70896ffeeef32b9c950ywan int cpu_used; // available cpu percentage in 1/16 25233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int enable_auto_alt_ref; 26233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int noise_sensitivity; 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int sharpness; 28233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int static_thresh; 29233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int tile_columns; 30233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int tile_rows; 31233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int arnr_max_frames; 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int arnr_strength; 33233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int arnr_type; 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp8e_tuning tuning; 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int cq_level; // constrained quality level 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int rc_max_intra_bitrate_pct; 37233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int lossless; 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int frame_parallel_decoding_mode; 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan AQ_MODE aq_mode; 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int frame_periodic_boost; 41233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan 43233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct extraconfig_map { 44233d2500723e5594f3e7c70896ffeeef32b9c950ywan int usage; 45233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct vp9_extracfg cfg; 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan 48233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic const struct extraconfig_map extracfg_map[] = { 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, 51233d2500723e5594f3e7c70896ffeeef32b9c950ywan { // NOLINT 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan NULL, 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, // cpu_used 54233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1, // enable_auto_alt_ref 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, // noise_sensitivity 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, // sharpness 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, // static_thresh 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, // tile_columns 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, // tile_rows 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan 7, // arnr_max_frames 61233d2500723e5594f3e7c70896ffeeef32b9c950ywan 5, // arnr_strength 62233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3, // arnr_type 63233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP8_TUNE_PSNR, // tuning 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan 10, // cq_level 65233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, // rc_max_intra_bitrate_pct 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, // lossless 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, // frame_parallel_decoding_mode 68233d2500723e5594f3e7c70896ffeeef32b9c950ywan NO_AQ, // aq_mode 69233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, // frame_periodic_delta_q 70233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 73233d2500723e5594f3e7c70896ffeeef32b9c950ywan 74233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct vpx_codec_alg_priv { 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_priv_t base; 76233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_enc_cfg_t cfg; 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct vp9_extracfg extra_cfg; 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_CONFIG oxcf; 79233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMP *cpi; 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char *cx_data; 81233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t cx_data_sz; 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char *pending_cx_data; 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t pending_cx_data_sz; 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan int pending_frame_count; 85233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t pending_frame_sizes[8]; 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t pending_frame_magnitude; 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_image_t preview_img; 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp8_postproc_cfg_t preview_ppcfg; 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_pkt_list_decl(64) pkt_list; 90233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int fixed_kf_cntr; 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 92233d2500723e5594f3e7c70896ffeeef32b9c950ywan 93233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic VP9_REFFRAME ref_frame_to_vp9_reframe(vpx_ref_frame_type_t frame) { 94233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (frame) { 95233d2500723e5594f3e7c70896ffeeef32b9c950ywan case VP8_LAST_FRAME: 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VP9_LAST_FLAG; 97233d2500723e5594f3e7c70896ffeeef32b9c950ywan case VP8_GOLD_FRAME: 98233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VP9_GOLD_FLAG; 99233d2500723e5594f3e7c70896ffeeef32b9c950ywan case VP8_ALTR_FRAME: 100233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VP9_ALT_FLAG; 101233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 102233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(0 && "Invalid Reference Frame"); 103233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VP9_LAST_FLAG; 104233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 105233d2500723e5594f3e7c70896ffeeef32b9c950ywan 106233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx, 107233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct vpx_internal_error_info *error) { 108233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_err_t res = error->error_code; 109233d2500723e5594f3e7c70896ffeeef32b9c950ywan 110233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (res != VPX_CODEC_OK) 111233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->base.err_detail = error->has_detail ? error->detail : NULL; 112233d2500723e5594f3e7c70896ffeeef32b9c950ywan 113233d2500723e5594f3e7c70896ffeeef32b9c950ywan return res; 114233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 115233d2500723e5594f3e7c70896ffeeef32b9c950ywan 116233d2500723e5594f3e7c70896ffeeef32b9c950ywan 117233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef ERROR 118233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ERROR(str) do {\ 119233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->base.err_detail = str;\ 120233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM;\ 121233d2500723e5594f3e7c70896ffeeef32b9c950ywan } while (0) 122233d2500723e5594f3e7c70896ffeeef32b9c950ywan 123233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define RANGE_CHECK(p, memb, lo, hi) do {\ 124233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!(((p)->memb == lo || (p)->memb > (lo)) && (p)->memb <= hi)) \ 125233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR(#memb " out of range ["#lo".."#hi"]");\ 126233d2500723e5594f3e7c70896ffeeef32b9c950ywan } while (0) 127233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define RANGE_CHECK_HI(p, memb, hi) do {\ 129233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!((p)->memb <= (hi))) \ 130233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR(#memb " out of range [.."#hi"]");\ 131233d2500723e5594f3e7c70896ffeeef32b9c950ywan } while (0) 132233d2500723e5594f3e7c70896ffeeef32b9c950ywan 133233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define RANGE_CHECK_LO(p, memb, lo) do {\ 134233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!((p)->memb >= (lo))) \ 135233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR(#memb " out of range ["#lo"..]");\ 136233d2500723e5594f3e7c70896ffeeef32b9c950ywan } while (0) 137233d2500723e5594f3e7c70896ffeeef32b9c950ywan 138233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define RANGE_CHECK_BOOL(p, memb) do {\ 139233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!!((p)->memb) != (p)->memb) ERROR(#memb " expected boolean");\ 140233d2500723e5594f3e7c70896ffeeef32b9c950ywan } while (0) 141233d2500723e5594f3e7c70896ffeeef32b9c950ywan 142233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, 143233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_enc_cfg_t *cfg, 144233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct vp9_extracfg *extra_cfg) { 145233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(cfg, g_w, 1, 65535); // 16 bits available 146233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(cfg, g_h, 1, 65535); // 16 bits available 147233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000); 148233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(cfg, g_timebase.num, 1, cfg->g_timebase.den); 149233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(cfg, g_profile, 3); 150233d2500723e5594f3e7c70896ffeeef32b9c950ywan 151233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(cfg, rc_max_quantizer, 63); 152233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer); 153233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_BOOL(extra_cfg, lossless); 154233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(extra_cfg, aq_mode, 0, AQ_MODE_COUNT - 1); 155233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(extra_cfg, frame_periodic_boost, 0, 1); 156233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(cfg, g_threads, 64); 157233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(cfg, g_lag_in_frames, MAX_LAG_BUFFERS); 158233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(cfg, rc_end_usage, VPX_VBR, VPX_Q); 159233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(cfg, rc_undershoot_pct, 1000); 160233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(cfg, rc_overshoot_pct, 1000); 161233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100); 162233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(cfg, kf_mode, VPX_KF_DISABLED, VPX_KF_AUTO); 163233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_BOOL(cfg, rc_resize_allowed); 164233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(cfg, rc_dropframe_thresh, 100); 165233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(cfg, rc_resize_up_thresh, 100); 166233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100); 167233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(cfg, g_pass, VPX_RC_ONE_PASS, VPX_RC_LAST_PASS); 168233d2500723e5594f3e7c70896ffeeef32b9c950ywan 169233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(cfg, ss_number_layers, 1, VPX_SS_MAX_LAYERS); 170233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(cfg, ts_number_layers, 1, VPX_TS_MAX_LAYERS); 171233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cfg->ts_number_layers > 1) { 172233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int i; 173233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 1; i < cfg->ts_number_layers; ++i) 174233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cfg->ts_target_bitrate[i] < cfg->ts_target_bitrate[i - 1]) 175233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("ts_target_bitrate entries are not increasing"); 176233d2500723e5594f3e7c70896ffeeef32b9c950ywan 177233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(cfg, ts_rate_decimator[cfg->ts_number_layers - 1], 1, 1); 178233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = cfg->ts_number_layers - 2; i > 0; --i) 179233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cfg->ts_rate_decimator[i - 1] != 2 * cfg->ts_rate_decimator[i]) 180233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("ts_rate_decimator factors are not powers of 2"); 181233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 182233d2500723e5594f3e7c70896ffeeef32b9c950ywan 183233d2500723e5594f3e7c70896ffeeef32b9c950ywan // VP8 does not support a lower bound on the keyframe interval in 184233d2500723e5594f3e7c70896ffeeef32b9c950ywan // automatic keyframe placement mode. 185233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cfg->kf_mode != VPX_KF_DISABLED && 186233d2500723e5594f3e7c70896ffeeef32b9c950ywan cfg->kf_min_dist != cfg->kf_max_dist && 187233d2500723e5594f3e7c70896ffeeef32b9c950ywan cfg->kf_min_dist > 0) 188233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("kf_min_dist not supported in auto mode, use 0 " 189233d2500723e5594f3e7c70896ffeeef32b9c950ywan "or kf_max_dist instead."); 190233d2500723e5594f3e7c70896ffeeef32b9c950ywan 191233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_BOOL(extra_cfg, enable_auto_alt_ref); 192233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(extra_cfg, cpu_used, -16, 16); 193233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(extra_cfg, noise_sensitivity, 6); 194233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(extra_cfg, tile_columns, 0, 6); 195233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(extra_cfg, tile_rows, 0, 2); 196233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(extra_cfg, sharpness, 7); 197233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(extra_cfg, arnr_max_frames, 0, 15); 198233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK_HI(extra_cfg, arnr_strength, 6); 199233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(extra_cfg, arnr_type, 1, 3); 200233d2500723e5594f3e7c70896ffeeef32b9c950ywan RANGE_CHECK(extra_cfg, cq_level, 0, 63); 201233d2500723e5594f3e7c70896ffeeef32b9c950ywan 202233d2500723e5594f3e7c70896ffeeef32b9c950ywan // TODO(yaowu): remove this when ssim tuning is implemented for vp9 203233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (extra_cfg->tuning == VP8_TUNE_SSIM) 204233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("Option --tune=ssim is not currently supported in VP9."); 205233d2500723e5594f3e7c70896ffeeef32b9c950ywan 206233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cfg->g_pass == VPX_RC_LAST_PASS) { 207233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t packet_sz = sizeof(FIRSTPASS_STATS); 208233d2500723e5594f3e7c70896ffeeef32b9c950ywan int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz); 209233d2500723e5594f3e7c70896ffeeef32b9c950ywan const FIRSTPASS_STATS *stats; 210233d2500723e5594f3e7c70896ffeeef32b9c950ywan 211233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cfg->rc_twopass_stats_in.buf == NULL) 212233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("rc_twopass_stats_in.buf not set."); 213233d2500723e5594f3e7c70896ffeeef32b9c950ywan 214233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cfg->rc_twopass_stats_in.sz % packet_sz) 215233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("rc_twopass_stats_in.sz indicates truncated packet."); 216233d2500723e5594f3e7c70896ffeeef32b9c950ywan 217233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cfg->ss_number_layers > 1) { 218233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 219233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int n_packets_per_layer[VPX_SS_MAX_LAYERS] = {0}; 220233d2500723e5594f3e7c70896ffeeef32b9c950ywan 221233d2500723e5594f3e7c70896ffeeef32b9c950ywan stats = cfg->rc_twopass_stats_in.buf; 222233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < n_packets; ++i) { 223233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int layer_id = (int)stats[i].spatial_layer_id; 224233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (layer_id >= 0 && layer_id < (int)cfg->ss_number_layers) { 225233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++n_packets_per_layer[layer_id]; 226233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 227233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 228233d2500723e5594f3e7c70896ffeeef32b9c950ywan 229233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < (int)cfg->ss_number_layers; ++i) { 230233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int layer_id; 231233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (n_packets_per_layer[i] < 2) { 232233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("rc_twopass_stats_in requires at least two packets for each " 233233d2500723e5594f3e7c70896ffeeef32b9c950ywan "layer."); 234233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 235233d2500723e5594f3e7c70896ffeeef32b9c950ywan 236233d2500723e5594f3e7c70896ffeeef32b9c950ywan stats = (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + 237233d2500723e5594f3e7c70896ffeeef32b9c950ywan n_packets - cfg->ss_number_layers + i; 238233d2500723e5594f3e7c70896ffeeef32b9c950ywan layer_id = (int)stats->spatial_layer_id; 239233d2500723e5594f3e7c70896ffeeef32b9c950ywan 240233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (layer_id >= cfg->ss_number_layers 241233d2500723e5594f3e7c70896ffeeef32b9c950ywan ||(int)(stats->count + 0.5) != n_packets_per_layer[layer_id] - 1) 242233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("rc_twopass_stats_in missing EOS stats packet"); 243233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 244233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 245233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz) 246233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("rc_twopass_stats_in requires at least two packets."); 247233d2500723e5594f3e7c70896ffeeef32b9c950ywan 248233d2500723e5594f3e7c70896ffeeef32b9c950ywan stats = 249233d2500723e5594f3e7c70896ffeeef32b9c950ywan (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1; 250233d2500723e5594f3e7c70896ffeeef32b9c950ywan 251233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((int)(stats->count + 0.5) != n_packets - 1) 252233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("rc_twopass_stats_in missing EOS stats packet"); 253233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 254233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 255233d2500723e5594f3e7c70896ffeeef32b9c950ywan 256233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 257233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 258233d2500723e5594f3e7c70896ffeeef32b9c950ywan 259233d2500723e5594f3e7c70896ffeeef32b9c950ywan 260233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx, 261233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_image_t *img) { 262233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (img->fmt) { 263233d2500723e5594f3e7c70896ffeeef32b9c950ywan case VPX_IMG_FMT_YV12: 264233d2500723e5594f3e7c70896ffeeef32b9c950ywan case VPX_IMG_FMT_I420: 265233d2500723e5594f3e7c70896ffeeef32b9c950ywan case VPX_IMG_FMT_I422: 266233d2500723e5594f3e7c70896ffeeef32b9c950ywan case VPX_IMG_FMT_I444: 267233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 268233d2500723e5594f3e7c70896ffeeef32b9c950ywan default: 269233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("Invalid image format. Only YV12, I420, I422, I444 images are " 270233d2500723e5594f3e7c70896ffeeef32b9c950ywan "supported."); 271233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 272233d2500723e5594f3e7c70896ffeeef32b9c950ywan 273233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (img->d_w != ctx->cfg.g_w || img->d_h != ctx->cfg.g_h) 274233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("Image size must match encoder init configuration size"); 275233d2500723e5594f3e7c70896ffeeef32b9c950ywan 276233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 277233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 278233d2500723e5594f3e7c70896ffeeef32b9c950ywan 279233d2500723e5594f3e7c70896ffeeef32b9c950ywan 280233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t set_vp9e_config(VP9_CONFIG *oxcf, 281233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_enc_cfg_t *cfg, 282233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct vp9_extracfg *extra_cfg) { 283233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->version = cfg->g_profile; 284233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->width = cfg->g_w; 285233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->height = cfg->g_h; 286233d2500723e5594f3e7c70896ffeeef32b9c950ywan // guess a frame rate if out of whack, use 30 287233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num; 288233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (oxcf->framerate > 180) 289233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->framerate = 30; 290233d2500723e5594f3e7c70896ffeeef32b9c950ywan 291233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (cfg->g_pass) { 292233d2500723e5594f3e7c70896ffeeef32b9c950ywan case VPX_RC_ONE_PASS: 293233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->mode = MODE_GOODQUALITY; 294233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 295233d2500723e5594f3e7c70896ffeeef32b9c950ywan case VPX_RC_FIRST_PASS: 296233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->mode = MODE_FIRSTPASS; 297233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 298233d2500723e5594f3e7c70896ffeeef32b9c950ywan case VPX_RC_LAST_PASS: 299233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->mode = MODE_SECONDPASS_BEST; 300233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 301233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 302233d2500723e5594f3e7c70896ffeeef32b9c950ywan 303233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->lag_in_frames = cfg->g_pass == VPX_RC_FIRST_PASS ? 0 304233d2500723e5594f3e7c70896ffeeef32b9c950ywan : cfg->g_lag_in_frames; 305233d2500723e5594f3e7c70896ffeeef32b9c950ywan 306233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->end_usage = USAGE_LOCAL_FILE_PLAYBACK; 307233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cfg->rc_end_usage == VPX_CQ) 308233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->end_usage = USAGE_CONSTRAINED_QUALITY; 309233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (cfg->rc_end_usage == VPX_Q) 310233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->end_usage = USAGE_CONSTANT_QUALITY; 311233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (cfg->rc_end_usage == VPX_CBR) 312233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->end_usage = USAGE_STREAM_FROM_SERVER; 313233d2500723e5594f3e7c70896ffeeef32b9c950ywan 314233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->target_bandwidth = cfg->rc_target_bitrate; 315233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct; 316233d2500723e5594f3e7c70896ffeeef32b9c950ywan 317233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->best_allowed_q = cfg->rc_min_quantizer; 318233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->worst_allowed_q = cfg->rc_max_quantizer; 319233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->cq_level = extra_cfg->cq_level; 320233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->fixed_q = -1; 321233d2500723e5594f3e7c70896ffeeef32b9c950ywan 322233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->under_shoot_pct = cfg->rc_undershoot_pct; 323233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->over_shoot_pct = cfg->rc_overshoot_pct; 324233d2500723e5594f3e7c70896ffeeef32b9c950ywan 325233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->maximum_buffer_size = cfg->rc_buf_sz; 326233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->starting_buffer_level = cfg->rc_buf_initial_sz; 327233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->optimal_buffer_level = cfg->rc_buf_optimal_sz; 328233d2500723e5594f3e7c70896ffeeef32b9c950ywan 329233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->drop_frames_water_mark = cfg->rc_dropframe_thresh; 330233d2500723e5594f3e7c70896ffeeef32b9c950ywan 331233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->two_pass_vbrbias = cfg->rc_2pass_vbr_bias_pct; 332233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->two_pass_vbrmin_section = cfg->rc_2pass_vbr_minsection_pct; 333233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->two_pass_vbrmax_section = cfg->rc_2pass_vbr_maxsection_pct; 334233d2500723e5594f3e7c70896ffeeef32b9c950ywan 335233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->auto_key = cfg->kf_mode == VPX_KF_AUTO && 336233d2500723e5594f3e7c70896ffeeef32b9c950ywan cfg->kf_min_dist != cfg->kf_max_dist; 337233d2500723e5594f3e7c70896ffeeef32b9c950ywan 338233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->key_freq = cfg->kf_max_dist; 339233d2500723e5594f3e7c70896ffeeef32b9c950ywan 340233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->cpu_used = extra_cfg->cpu_used; 341233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->encode_breakout = extra_cfg->static_thresh; 342233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->play_alternate = extra_cfg->enable_auto_alt_ref; 343233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->noise_sensitivity = extra_cfg->noise_sensitivity; 344233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->sharpness = extra_cfg->sharpness; 345233d2500723e5594f3e7c70896ffeeef32b9c950ywan 346233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->two_pass_stats_in = cfg->rc_twopass_stats_in; 347233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->output_pkt_list = extra_cfg->pkt_list; 348233d2500723e5594f3e7c70896ffeeef32b9c950ywan 349233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->arnr_max_frames = extra_cfg->arnr_max_frames; 350233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->arnr_strength = extra_cfg->arnr_strength; 351233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->arnr_type = extra_cfg->arnr_type; 352233d2500723e5594f3e7c70896ffeeef32b9c950ywan 353233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->tuning = extra_cfg->tuning; 354233d2500723e5594f3e7c70896ffeeef32b9c950ywan 355233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->tile_columns = extra_cfg->tile_columns; 356233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->tile_rows = extra_cfg->tile_rows; 357233d2500723e5594f3e7c70896ffeeef32b9c950ywan 358233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->lossless = extra_cfg->lossless; 359233d2500723e5594f3e7c70896ffeeef32b9c950ywan 360233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->error_resilient_mode = cfg->g_error_resilient; 361233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode; 362233d2500723e5594f3e7c70896ffeeef32b9c950ywan 363233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->aq_mode = extra_cfg->aq_mode; 364233d2500723e5594f3e7c70896ffeeef32b9c950ywan 365233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->frame_periodic_boost = extra_cfg->frame_periodic_boost; 366233d2500723e5594f3e7c70896ffeeef32b9c950ywan 367233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->ss_number_layers = cfg->ss_number_layers; 368233d2500723e5594f3e7c70896ffeeef32b9c950ywan 369233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (oxcf->ss_number_layers > 1) { 370233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_copy(oxcf->ss_target_bitrate, cfg->ss_target_bitrate); 371233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (oxcf->ss_number_layers == 1) { 372233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->ss_target_bitrate[0] = (int)oxcf->target_bandwidth; 373233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 374233d2500723e5594f3e7c70896ffeeef32b9c950ywan 375233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->ts_number_layers = cfg->ts_number_layers; 376233d2500723e5594f3e7c70896ffeeef32b9c950ywan 377233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (oxcf->ts_number_layers > 1) { 378233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_copy(oxcf->ts_target_bitrate, cfg->ts_target_bitrate); 379233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_copy(oxcf->ts_rate_decimator, cfg->ts_rate_decimator); 380233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (oxcf->ts_number_layers == 1) { 381233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->ts_target_bitrate[0] = (int)oxcf->target_bandwidth; 382233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->ts_rate_decimator[0] = 1; 383233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 384233d2500723e5594f3e7c70896ffeeef32b9c950ywan 385233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* 386233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("Current VP9 Settings: \n"); 387233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("target_bandwidth: %d\n", oxcf->target_bandwidth); 388233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("noise_sensitivity: %d\n", oxcf->noise_sensitivity); 389233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("sharpness: %d\n", oxcf->sharpness); 390233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("cpu_used: %d\n", oxcf->cpu_used); 391233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("Mode: %d\n", oxcf->mode); 392233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("auto_key: %d\n", oxcf->auto_key); 393233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("key_freq: %d\n", oxcf->key_freq); 394233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("end_usage: %d\n", oxcf->end_usage); 395233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct); 396233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct); 397233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level); 398233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("optimal_buffer_level: %d\n", oxcf->optimal_buffer_level); 399233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size); 400233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("fixed_q: %d\n", oxcf->fixed_q); 401233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q); 402233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("best_allowed_q: %d\n", oxcf->best_allowed_q); 403233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("two_pass_vbrbias: %d\n", oxcf->two_pass_vbrbias); 404233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section); 405233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section); 406233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("lag_in_frames: %d\n", oxcf->lag_in_frames); 407233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("play_alternate: %d\n", oxcf->play_alternate); 408233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("Version: %d\n", oxcf->Version); 409233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("encode_breakout: %d\n", oxcf->encode_breakout); 410233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("error resilient: %d\n", oxcf->error_resilient_mode); 411233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("frame parallel detokenization: %d\n", 412233d2500723e5594f3e7c70896ffeeef32b9c950ywan oxcf->frame_parallel_decoding_mode); 413233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 414233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 415233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 416233d2500723e5594f3e7c70896ffeeef32b9c950ywan 417233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_set_config(vpx_codec_alg_priv_t *ctx, 418233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_enc_cfg_t *cfg) { 419233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_err_t res; 420233d2500723e5594f3e7c70896ffeeef32b9c950ywan 421233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h) 422233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("Cannot change width or height after initialization"); 423233d2500723e5594f3e7c70896ffeeef32b9c950ywan 424233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Prevent increasing lag_in_frames. This check is stricter than it needs 425233d2500723e5594f3e7c70896ffeeef32b9c950ywan // to be -- the limit is not increasing past the first lag_in_frames 426233d2500723e5594f3e7c70896ffeeef32b9c950ywan // value, but we don't track the initial config, only the last successful 427233d2500723e5594f3e7c70896ffeeef32b9c950ywan // config. 428233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames) 429233d2500723e5594f3e7c70896ffeeef32b9c950ywan ERROR("Cannot increase lag_in_frames"); 430233d2500723e5594f3e7c70896ffeeef32b9c950ywan 431233d2500723e5594f3e7c70896ffeeef32b9c950ywan res = validate_config(ctx, cfg, &ctx->extra_cfg); 432233d2500723e5594f3e7c70896ffeeef32b9c950ywan 433233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (res == VPX_CODEC_OK) { 434233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->cfg = *cfg; 435233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_vp9e_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg); 436233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_change_config(ctx->cpi, &ctx->oxcf); 437233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 438233d2500723e5594f3e7c70896ffeeef32b9c950ywan 439233d2500723e5594f3e7c70896ffeeef32b9c950ywan return res; 440233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 441233d2500723e5594f3e7c70896ffeeef32b9c950ywan 442233d2500723e5594f3e7c70896ffeeef32b9c950ywan 443233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_reverse_trans(int q); 444233d2500723e5594f3e7c70896ffeeef32b9c950ywan 445233d2500723e5594f3e7c70896ffeeef32b9c950ywan 446233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t get_param(vpx_codec_alg_priv_t *ctx, int ctrl_id, 447233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list args) { 448233d2500723e5594f3e7c70896ffeeef32b9c950ywan void *arg = va_arg(args, void *); 449233d2500723e5594f3e7c70896ffeeef32b9c950ywan 450233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define MAP(id, var) case id: *(RECAST(id, arg)) = var; break 451233d2500723e5594f3e7c70896ffeeef32b9c950ywan 452233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (arg == NULL) 453233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 454233d2500723e5594f3e7c70896ffeeef32b9c950ywan 455233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (ctrl_id) { 456233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP8E_GET_LAST_QUANTIZER, vp9_get_quantizer(ctx->cpi)); 457233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP8E_GET_LAST_QUANTIZER_64, 458233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_reverse_trans(vp9_get_quantizer(ctx->cpi))); 459233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 460233d2500723e5594f3e7c70896ffeeef32b9c950ywan 461233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 462233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef MAP 463233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 464233d2500723e5594f3e7c70896ffeeef32b9c950ywan 465233d2500723e5594f3e7c70896ffeeef32b9c950ywan 466233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx, int ctrl_id, 467233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list args) { 468233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_err_t res = VPX_CODEC_OK; 469233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct vp9_extracfg extra_cfg = ctx->extra_cfg; 470233d2500723e5594f3e7c70896ffeeef32b9c950ywan 471233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define MAP(id, var) case id: var = CAST(id, args); break; 472233d2500723e5594f3e7c70896ffeeef32b9c950ywan 473233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (ctrl_id) { 474233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP8E_SET_CPUUSED, extra_cfg.cpu_used); 475233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP8E_SET_ENABLEAUTOALTREF, extra_cfg.enable_auto_alt_ref); 476233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP8E_SET_NOISE_SENSITIVITY, extra_cfg.noise_sensitivity); 477233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP8E_SET_SHARPNESS, extra_cfg.sharpness); 478233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP8E_SET_STATIC_THRESHOLD, extra_cfg.static_thresh); 479233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP9E_SET_TILE_COLUMNS, extra_cfg.tile_columns); 480233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP9E_SET_TILE_ROWS, extra_cfg.tile_rows); 481233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP8E_SET_ARNR_MAXFRAMES, extra_cfg.arnr_max_frames); 482233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP8E_SET_ARNR_STRENGTH, extra_cfg.arnr_strength); 483233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP8E_SET_ARNR_TYPE, extra_cfg.arnr_type); 484233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP8E_SET_TUNING, extra_cfg.tuning); 485233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP8E_SET_CQ_LEVEL, extra_cfg.cq_level); 486233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP8E_SET_MAX_INTRA_BITRATE_PCT, extra_cfg.rc_max_intra_bitrate_pct); 487233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP9E_SET_LOSSLESS, extra_cfg.lossless); 488233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP9E_SET_FRAME_PARALLEL_DECODING, 489233d2500723e5594f3e7c70896ffeeef32b9c950ywan extra_cfg.frame_parallel_decoding_mode); 490233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP9E_SET_AQ_MODE, extra_cfg.aq_mode); 491233d2500723e5594f3e7c70896ffeeef32b9c950ywan MAP(VP9E_SET_FRAME_PERIODIC_BOOST, extra_cfg.frame_periodic_boost); 492233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 493233d2500723e5594f3e7c70896ffeeef32b9c950ywan 494233d2500723e5594f3e7c70896ffeeef32b9c950ywan res = validate_config(ctx, &ctx->cfg, &extra_cfg); 495233d2500723e5594f3e7c70896ffeeef32b9c950ywan 496233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (res == VPX_CODEC_OK) { 497233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->extra_cfg = extra_cfg; 498233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_vp9e_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg); 499233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_change_config(ctx->cpi, &ctx->oxcf); 500233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 501233d2500723e5594f3e7c70896ffeeef32b9c950ywan 502233d2500723e5594f3e7c70896ffeeef32b9c950ywan return res; 503233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef MAP 504233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 505233d2500723e5594f3e7c70896ffeeef32b9c950ywan 506233d2500723e5594f3e7c70896ffeeef32b9c950ywan 507233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_common_init(vpx_codec_ctx_t *ctx) { 508233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_err_t res = VPX_CODEC_OK; 509233d2500723e5594f3e7c70896ffeeef32b9c950ywan 510233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->priv == NULL) { 511233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 512233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_enc_cfg_t *cfg; 513233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct vpx_codec_alg_priv *priv = calloc(1, sizeof(*priv)); 514233d2500723e5594f3e7c70896ffeeef32b9c950ywan 515233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (priv == NULL) return VPX_CODEC_MEM_ERROR; 516233d2500723e5594f3e7c70896ffeeef32b9c950ywan 517233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->priv = &priv->base; 518233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->priv->sz = sizeof(*ctx->priv); 519233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->priv->iface = ctx->iface; 520233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->priv->alg_priv = priv; 521233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->priv->init_flags = ctx->init_flags; 522233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->priv->enc.total_encoders = 1; 523233d2500723e5594f3e7c70896ffeeef32b9c950ywan 524233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->config.enc) { 525233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Update the reference to the config structure to an 526233d2500723e5594f3e7c70896ffeeef32b9c950ywan // internal copy. 527233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->priv->alg_priv->cfg = *ctx->config.enc; 528233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->config.enc = &ctx->priv->alg_priv->cfg; 529233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 530233d2500723e5594f3e7c70896ffeeef32b9c950ywan 531233d2500723e5594f3e7c70896ffeeef32b9c950ywan cfg = &ctx->priv->alg_priv->cfg; 532233d2500723e5594f3e7c70896ffeeef32b9c950ywan 533233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Select the extra vp6 configuration table based on the current 534233d2500723e5594f3e7c70896ffeeef32b9c950ywan // usage value. If the current usage value isn't found, use the 535233d2500723e5594f3e7c70896ffeeef32b9c950ywan // values for usage case 0. 536233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; 537233d2500723e5594f3e7c70896ffeeef32b9c950ywan extracfg_map[i].usage && extracfg_map[i].usage != cfg->g_usage; 538233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++i) {} 539233d2500723e5594f3e7c70896ffeeef32b9c950ywan 540233d2500723e5594f3e7c70896ffeeef32b9c950ywan priv->extra_cfg = extracfg_map[i].cfg; 541233d2500723e5594f3e7c70896ffeeef32b9c950ywan priv->extra_cfg.pkt_list = &priv->pkt_list.head; 542233d2500723e5594f3e7c70896ffeeef32b9c950ywan 543233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Maximum buffer size approximated based on having multiple ARF. 544233d2500723e5594f3e7c70896ffeeef32b9c950ywan priv->cx_data_sz = priv->cfg.g_w * priv->cfg.g_h * 3 / 2 * 8; 545233d2500723e5594f3e7c70896ffeeef32b9c950ywan 546233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (priv->cx_data_sz < 4096) priv->cx_data_sz = 4096; 547233d2500723e5594f3e7c70896ffeeef32b9c950ywan 548233d2500723e5594f3e7c70896ffeeef32b9c950ywan priv->cx_data = (unsigned char *)malloc(priv->cx_data_sz); 549233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (priv->cx_data == NULL) 550233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_MEM_ERROR; 551233d2500723e5594f3e7c70896ffeeef32b9c950ywan 552233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_initialize_enc(); 553233d2500723e5594f3e7c70896ffeeef32b9c950ywan 554233d2500723e5594f3e7c70896ffeeef32b9c950ywan res = validate_config(priv, &priv->cfg, &priv->extra_cfg); 555233d2500723e5594f3e7c70896ffeeef32b9c950ywan 556233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (res == VPX_CODEC_OK) { 557233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMP *cpi; 558233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_vp9e_config(&ctx->priv->alg_priv->oxcf, 559233d2500723e5594f3e7c70896ffeeef32b9c950ywan &ctx->priv->alg_priv->cfg, 560233d2500723e5594f3e7c70896ffeeef32b9c950ywan &ctx->priv->alg_priv->extra_cfg); 561233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi = vp9_create_compressor(&ctx->priv->alg_priv->oxcf); 562233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi == NULL) 563233d2500723e5594f3e7c70896ffeeef32b9c950ywan res = VPX_CODEC_MEM_ERROR; 564233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 565233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->priv->alg_priv->cpi = cpi; 566233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 567233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 568233d2500723e5594f3e7c70896ffeeef32b9c950ywan 569233d2500723e5594f3e7c70896ffeeef32b9c950ywan return res; 570233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 571233d2500723e5594f3e7c70896ffeeef32b9c950ywan 572233d2500723e5594f3e7c70896ffeeef32b9c950ywan 573233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_init(vpx_codec_ctx_t *ctx, 574233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_priv_enc_mr_cfg_t *data) { 575233d2500723e5594f3e7c70896ffeeef32b9c950ywan return vp9e_common_init(ctx); 576233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 577233d2500723e5594f3e7c70896ffeeef32b9c950ywan 578233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_destroy(vpx_codec_alg_priv_t *ctx) { 579233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(ctx->cx_data); 580233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_remove_compressor(ctx->cpi); 581233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(ctx); 582233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 583233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 584233d2500723e5594f3e7c70896ffeeef32b9c950ywan 585233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx, 586233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned long duration, 587233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned long deadline) { 588233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Use best quality mode if no deadline is given. 589233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE new_qc = MODE_BESTQUALITY; 590233d2500723e5594f3e7c70896ffeeef32b9c950ywan 591233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (deadline) { 592233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Convert duration parameter from stream timebase to microseconds 593233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint64_t duration_us = (uint64_t)duration * 1000000 * 594233d2500723e5594f3e7c70896ffeeef32b9c950ywan (uint64_t)ctx->cfg.g_timebase.num / 595233d2500723e5594f3e7c70896ffeeef32b9c950ywan (uint64_t)ctx->cfg.g_timebase.den; 596233d2500723e5594f3e7c70896ffeeef32b9c950ywan 597233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If the deadline is more that the duration this frame is to be shown, 598233d2500723e5594f3e7c70896ffeeef32b9c950ywan // use good quality mode. Otherwise use realtime mode. 599233d2500723e5594f3e7c70896ffeeef32b9c950ywan new_qc = (deadline > duration_us) ? MODE_GOODQUALITY : MODE_REALTIME; 600233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 601233d2500723e5594f3e7c70896ffeeef32b9c950ywan 602233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->cfg.g_pass == VPX_RC_FIRST_PASS) 603233d2500723e5594f3e7c70896ffeeef32b9c950ywan new_qc = MODE_FIRSTPASS; 604233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (ctx->cfg.g_pass == VPX_RC_LAST_PASS) 605233d2500723e5594f3e7c70896ffeeef32b9c950ywan new_qc = (new_qc == MODE_BESTQUALITY) ? MODE_SECONDPASS_BEST 606233d2500723e5594f3e7c70896ffeeef32b9c950ywan : MODE_SECONDPASS; 607233d2500723e5594f3e7c70896ffeeef32b9c950ywan 608233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->oxcf.mode != new_qc) { 609233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->oxcf.mode = new_qc; 610233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_change_config(ctx->cpi, &ctx->oxcf); 611233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 612233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 613233d2500723e5594f3e7c70896ffeeef32b9c950ywan 614233d2500723e5594f3e7c70896ffeeef32b9c950ywan 615233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int write_superframe_index(vpx_codec_alg_priv_t *ctx) { 616233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint8_t marker = 0xc0; 617233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int mask; 618233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mag, index_sz; 619233d2500723e5594f3e7c70896ffeeef32b9c950ywan 620233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(ctx->pending_frame_count); 621233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(ctx->pending_frame_count <= 8); 622233d2500723e5594f3e7c70896ffeeef32b9c950ywan 623233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Add the number of frames to the marker byte 624233d2500723e5594f3e7c70896ffeeef32b9c950ywan marker |= ctx->pending_frame_count - 1; 625233d2500723e5594f3e7c70896ffeeef32b9c950ywan 626233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Choose the magnitude 627233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (mag = 0, mask = 0xff; mag < 4; mag++) { 628233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->pending_frame_magnitude < mask) 629233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 630233d2500723e5594f3e7c70896ffeeef32b9c950ywan mask <<= 8; 631233d2500723e5594f3e7c70896ffeeef32b9c950ywan mask |= 0xff; 632233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 633233d2500723e5594f3e7c70896ffeeef32b9c950ywan marker |= mag << 3; 634233d2500723e5594f3e7c70896ffeeef32b9c950ywan 635233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Write the index 636233d2500723e5594f3e7c70896ffeeef32b9c950ywan index_sz = 2 + (mag + 1) * ctx->pending_frame_count; 637233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz) { 638233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint8_t *x = ctx->pending_cx_data + ctx->pending_cx_data_sz; 639233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, j; 640233d2500723e5594f3e7c70896ffeeef32b9c950ywan 641233d2500723e5594f3e7c70896ffeeef32b9c950ywan *x++ = marker; 642233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < ctx->pending_frame_count; i++) { 643233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int this_sz = (unsigned int)ctx->pending_frame_sizes[i]; 644233d2500723e5594f3e7c70896ffeeef32b9c950ywan 645233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j <= mag; j++) { 646233d2500723e5594f3e7c70896ffeeef32b9c950ywan *x++ = this_sz & 0xff; 647233d2500723e5594f3e7c70896ffeeef32b9c950ywan this_sz >>= 8; 648233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 649233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 650233d2500723e5594f3e7c70896ffeeef32b9c950ywan *x++ = marker; 651233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->pending_cx_data_sz += index_sz; 652233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 653233d2500723e5594f3e7c70896ffeeef32b9c950ywan return index_sz; 654233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 655233d2500723e5594f3e7c70896ffeeef32b9c950ywan 656233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_encode(vpx_codec_alg_priv_t *ctx, 657233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_image_t *img, 658233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_pts_t pts, 659233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned long duration, 660233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_enc_frame_flags_t flags, 661233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned long deadline) { 662233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_err_t res = VPX_CODEC_OK; 663233d2500723e5594f3e7c70896ffeeef32b9c950ywan 664233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (img) 665233d2500723e5594f3e7c70896ffeeef32b9c950ywan res = validate_img(ctx, img); 666233d2500723e5594f3e7c70896ffeeef32b9c950ywan 667233d2500723e5594f3e7c70896ffeeef32b9c950ywan pick_quickcompress_mode(ctx, duration, deadline); 668233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_pkt_list_init(&ctx->pkt_list); 669233d2500723e5594f3e7c70896ffeeef32b9c950ywan 670233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Handle Flags 671233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (((flags & VP8_EFLAG_NO_UPD_GF) && (flags & VP8_EFLAG_FORCE_GF)) || 672233d2500723e5594f3e7c70896ffeeef32b9c950ywan ((flags & VP8_EFLAG_NO_UPD_ARF) && (flags & VP8_EFLAG_FORCE_ARF))) { 673233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->base.err_detail = "Conflicting flags."; 674233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 675233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 676233d2500723e5594f3e7c70896ffeeef32b9c950ywan 677233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (flags & (VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF | 678233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP8_EFLAG_NO_REF_ARF)) { 679233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ref = 7; 680233d2500723e5594f3e7c70896ffeeef32b9c950ywan 681233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (flags & VP8_EFLAG_NO_REF_LAST) 682233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref ^= VP9_LAST_FLAG; 683233d2500723e5594f3e7c70896ffeeef32b9c950ywan 684233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (flags & VP8_EFLAG_NO_REF_GF) 685233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref ^= VP9_GOLD_FLAG; 686233d2500723e5594f3e7c70896ffeeef32b9c950ywan 687233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (flags & VP8_EFLAG_NO_REF_ARF) 688233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref ^= VP9_ALT_FLAG; 689233d2500723e5594f3e7c70896ffeeef32b9c950ywan 690233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_use_as_reference(ctx->cpi, ref); 691233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 692233d2500723e5594f3e7c70896ffeeef32b9c950ywan 693233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (flags & (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | 694233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_FORCE_GF | 695233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP8_EFLAG_FORCE_ARF)) { 696233d2500723e5594f3e7c70896ffeeef32b9c950ywan int upd = 7; 697233d2500723e5594f3e7c70896ffeeef32b9c950ywan 698233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (flags & VP8_EFLAG_NO_UPD_LAST) 699233d2500723e5594f3e7c70896ffeeef32b9c950ywan upd ^= VP9_LAST_FLAG; 700233d2500723e5594f3e7c70896ffeeef32b9c950ywan 701233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (flags & VP8_EFLAG_NO_UPD_GF) 702233d2500723e5594f3e7c70896ffeeef32b9c950ywan upd ^= VP9_GOLD_FLAG; 703233d2500723e5594f3e7c70896ffeeef32b9c950ywan 704233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (flags & VP8_EFLAG_NO_UPD_ARF) 705233d2500723e5594f3e7c70896ffeeef32b9c950ywan upd ^= VP9_ALT_FLAG; 706233d2500723e5594f3e7c70896ffeeef32b9c950ywan 707233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_update_reference(ctx->cpi, upd); 708233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 709233d2500723e5594f3e7c70896ffeeef32b9c950ywan 710233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (flags & VP8_EFLAG_NO_UPD_ENTROPY) { 711233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_update_entropy(ctx->cpi, 0); 712233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 713233d2500723e5594f3e7c70896ffeeef32b9c950ywan 714233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Handle fixed keyframe intervals 715233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->cfg.kf_mode == VPX_KF_AUTO && 716233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) { 717233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) { 718233d2500723e5594f3e7c70896ffeeef32b9c950ywan flags |= VPX_EFLAG_FORCE_KF; 719233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->fixed_kf_cntr = 1; 720233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 721233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 722233d2500723e5594f3e7c70896ffeeef32b9c950ywan 723233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Initialize the encoder instance on the first frame. 724233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (res == VPX_CODEC_OK && ctx->cpi != NULL) { 725233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int lib_flags; 726233d2500723e5594f3e7c70896ffeeef32b9c950ywan YV12_BUFFER_CONFIG sd; 727233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t dst_time_stamp, dst_end_time_stamp; 728233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t size, cx_data_sz; 729233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char *cx_data; 730233d2500723e5594f3e7c70896ffeeef32b9c950ywan 731233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Set up internal flags 732233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->base.init_flags & VPX_CODEC_USE_PSNR) 733233d2500723e5594f3e7c70896ffeeef32b9c950ywan ((VP9_COMP *)ctx->cpi)->b_calculate_psnr = 1; 734233d2500723e5594f3e7c70896ffeeef32b9c950ywan 735233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Convert API flags to internal codec lib flags 736233d2500723e5594f3e7c70896ffeeef32b9c950ywan lib_flags = (flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0; 737233d2500723e5594f3e7c70896ffeeef32b9c950ywan 738233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* vp9 use 10,000,000 ticks/second as time stamp */ 739233d2500723e5594f3e7c70896ffeeef32b9c950ywan dst_time_stamp = (pts * 10000000 * ctx->cfg.g_timebase.num) 740233d2500723e5594f3e7c70896ffeeef32b9c950ywan / ctx->cfg.g_timebase.den; 741233d2500723e5594f3e7c70896ffeeef32b9c950ywan dst_end_time_stamp = (pts + duration) * 10000000 * ctx->cfg.g_timebase.num / 742233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->cfg.g_timebase.den; 743233d2500723e5594f3e7c70896ffeeef32b9c950ywan 744233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (img != NULL) { 745233d2500723e5594f3e7c70896ffeeef32b9c950ywan res = image2yuvconfig(img, &sd); 746233d2500723e5594f3e7c70896ffeeef32b9c950ywan 747233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (vp9_receive_raw_frame(ctx->cpi, lib_flags, 748233d2500723e5594f3e7c70896ffeeef32b9c950ywan &sd, dst_time_stamp, dst_end_time_stamp)) { 749233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMP *cpi = (VP9_COMP *)ctx->cpi; 750233d2500723e5594f3e7c70896ffeeef32b9c950ywan res = update_error_state(ctx, &cpi->common.error); 751233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 752233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 753233d2500723e5594f3e7c70896ffeeef32b9c950ywan 754233d2500723e5594f3e7c70896ffeeef32b9c950ywan cx_data = ctx->cx_data; 755233d2500723e5594f3e7c70896ffeeef32b9c950ywan cx_data_sz = ctx->cx_data_sz; 756233d2500723e5594f3e7c70896ffeeef32b9c950ywan lib_flags = 0; 757233d2500723e5594f3e7c70896ffeeef32b9c950ywan 758233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Any pending invisible frames? */ 759233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->pending_cx_data) { 760233d2500723e5594f3e7c70896ffeeef32b9c950ywan memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz); 761233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->pending_cx_data = cx_data; 762233d2500723e5594f3e7c70896ffeeef32b9c950ywan cx_data += ctx->pending_cx_data_sz; 763233d2500723e5594f3e7c70896ffeeef32b9c950ywan cx_data_sz -= ctx->pending_cx_data_sz; 764233d2500723e5594f3e7c70896ffeeef32b9c950ywan 765233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* TODO: this is a minimal check, the underlying codec doesn't respect 766233d2500723e5594f3e7c70896ffeeef32b9c950ywan * the buffer size anyway. 767233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 768233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cx_data_sz < ctx->cx_data_sz / 2) { 769233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->base.err_detail = "Compressed data buffer too small"; 770233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_ERROR; 771233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 772233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 773233d2500723e5594f3e7c70896ffeeef32b9c950ywan 774233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (cx_data_sz >= ctx->cx_data_sz / 2 && 775233d2500723e5594f3e7c70896ffeeef32b9c950ywan -1 != vp9_get_compressed_data(ctx->cpi, &lib_flags, &size, 776233d2500723e5594f3e7c70896ffeeef32b9c950ywan cx_data, &dst_time_stamp, 777233d2500723e5594f3e7c70896ffeeef32b9c950ywan &dst_end_time_stamp, !img)) { 778233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (size) { 779233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_pts_t round, delta; 780233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_cx_pkt_t pkt; 781233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi; 782233d2500723e5594f3e7c70896ffeeef32b9c950ywan 783233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Pack invisible frames with the next visible frame 784233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->common.show_frame == 0) { 785233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->pending_cx_data == 0) 786233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->pending_cx_data = cx_data; 787233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->pending_cx_data_sz += size; 788233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->pending_frame_sizes[ctx->pending_frame_count++] = size; 789233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->pending_frame_magnitude |= size; 790233d2500723e5594f3e7c70896ffeeef32b9c950ywan cx_data += size; 791233d2500723e5594f3e7c70896ffeeef32b9c950ywan cx_data_sz -= size; 792233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 793233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 794233d2500723e5594f3e7c70896ffeeef32b9c950ywan 795233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Add the frame packet to the list of returned packets. 796233d2500723e5594f3e7c70896ffeeef32b9c950ywan round = (vpx_codec_pts_t)1000000 * ctx->cfg.g_timebase.num / 2 - 1; 797233d2500723e5594f3e7c70896ffeeef32b9c950ywan delta = (dst_end_time_stamp - dst_time_stamp); 798233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.kind = VPX_CODEC_CX_FRAME_PKT; 799233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.data.frame.pts = 800233d2500723e5594f3e7c70896ffeeef32b9c950ywan (dst_time_stamp * ctx->cfg.g_timebase.den + round) 801233d2500723e5594f3e7c70896ffeeef32b9c950ywan / ctx->cfg.g_timebase.num / 10000000; 802233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.data.frame.duration = (unsigned long) 803233d2500723e5594f3e7c70896ffeeef32b9c950ywan ((delta * ctx->cfg.g_timebase.den + round) 804233d2500723e5594f3e7c70896ffeeef32b9c950ywan / ctx->cfg.g_timebase.num / 10000000); 805233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.data.frame.flags = lib_flags << 16; 806233d2500723e5594f3e7c70896ffeeef32b9c950ywan 807233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (lib_flags & FRAMEFLAGS_KEY) 808233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.data.frame.flags |= VPX_FRAME_IS_KEY; 809233d2500723e5594f3e7c70896ffeeef32b9c950ywan 810233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->common.show_frame == 0) { 811233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.data.frame.flags |= VPX_FRAME_IS_INVISIBLE; 812233d2500723e5594f3e7c70896ffeeef32b9c950ywan 813233d2500723e5594f3e7c70896ffeeef32b9c950ywan // This timestamp should be as close as possible to the 814233d2500723e5594f3e7c70896ffeeef32b9c950ywan // prior PTS so that if a decoder uses pts to schedule when 815233d2500723e5594f3e7c70896ffeeef32b9c950ywan // to do this, we start right after last frame was decoded. 816233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Invisible frames have no duration. 817233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.data.frame.pts = ((cpi->last_time_stamp_seen 818233d2500723e5594f3e7c70896ffeeef32b9c950ywan * ctx->cfg.g_timebase.den + round) 819233d2500723e5594f3e7c70896ffeeef32b9c950ywan / ctx->cfg.g_timebase.num / 10000000) + 1; 820233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.data.frame.duration = 0; 821233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 822233d2500723e5594f3e7c70896ffeeef32b9c950ywan 823233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->droppable) 824233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.data.frame.flags |= VPX_FRAME_IS_DROPPABLE; 825233d2500723e5594f3e7c70896ffeeef32b9c950ywan 826233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->pending_cx_data) { 827233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->pending_frame_sizes[ctx->pending_frame_count++] = size; 828233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->pending_frame_magnitude |= size; 829233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->pending_cx_data_sz += size; 830233d2500723e5594f3e7c70896ffeeef32b9c950ywan size += write_superframe_index(ctx); 831233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.data.frame.buf = ctx->pending_cx_data; 832233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.data.frame.sz = ctx->pending_cx_data_sz; 833233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->pending_cx_data = NULL; 834233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->pending_cx_data_sz = 0; 835233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->pending_frame_count = 0; 836233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->pending_frame_magnitude = 0; 837233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 838233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.data.frame.buf = cx_data; 839233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.data.frame.sz = size; 840233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 841233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt.data.frame.partition_id = -1; 842233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt); 843233d2500723e5594f3e7c70896ffeeef32b9c950ywan cx_data += size; 844233d2500723e5594f3e7c70896ffeeef32b9c950ywan cx_data_sz -= size; 845233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 846233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 847233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 848233d2500723e5594f3e7c70896ffeeef32b9c950ywan 849233d2500723e5594f3e7c70896ffeeef32b9c950ywan return res; 850233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 851233d2500723e5594f3e7c70896ffeeef32b9c950ywan 852233d2500723e5594f3e7c70896ffeeef32b9c950ywan 853233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic const vpx_codec_cx_pkt_t *vp9e_get_cxdata(vpx_codec_alg_priv_t *ctx, 854233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_iter_t *iter) { 855233d2500723e5594f3e7c70896ffeeef32b9c950ywan return vpx_codec_pkt_list_get(&ctx->pkt_list.head, iter); 856233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 857233d2500723e5594f3e7c70896ffeeef32b9c950ywan 858233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_set_reference(vpx_codec_alg_priv_t *ctx, 859233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctr_id, 860233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list args) { 861233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *); 862233d2500723e5594f3e7c70896ffeeef32b9c950ywan 863233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (frame != NULL) { 864233d2500723e5594f3e7c70896ffeeef32b9c950ywan YV12_BUFFER_CONFIG sd; 865233d2500723e5594f3e7c70896ffeeef32b9c950ywan 866233d2500723e5594f3e7c70896ffeeef32b9c950ywan image2yuvconfig(&frame->img, &sd); 867233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_set_reference_enc(ctx->cpi, ref_frame_to_vp9_reframe(frame->frame_type), 868233d2500723e5594f3e7c70896ffeeef32b9c950ywan &sd); 869233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 870233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 871233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 872233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 873233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 874233d2500723e5594f3e7c70896ffeeef32b9c950ywan 875233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_copy_reference(vpx_codec_alg_priv_t *ctx, 876233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctr_id, 877233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list args) { 878233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *); 879233d2500723e5594f3e7c70896ffeeef32b9c950ywan 880233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (frame != NULL) { 881233d2500723e5594f3e7c70896ffeeef32b9c950ywan YV12_BUFFER_CONFIG sd; 882233d2500723e5594f3e7c70896ffeeef32b9c950ywan 883233d2500723e5594f3e7c70896ffeeef32b9c950ywan image2yuvconfig(&frame->img, &sd); 884233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_copy_reference_enc(ctx->cpi, 885233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_frame_to_vp9_reframe(frame->frame_type), &sd); 886233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 887233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 888233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 889233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 890233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 891233d2500723e5594f3e7c70896ffeeef32b9c950ywan 892233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t get_reference(vpx_codec_alg_priv_t *ctx, 893233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctr_id, 894233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list args) { 895233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_ref_frame_t *frame = va_arg(args, vp9_ref_frame_t *); 896233d2500723e5594f3e7c70896ffeeef32b9c950ywan 897233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (frame != NULL) { 898233d2500723e5594f3e7c70896ffeeef32b9c950ywan YV12_BUFFER_CONFIG* fb; 899233d2500723e5594f3e7c70896ffeeef32b9c950ywan 900233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_get_reference_enc(ctx->cpi, frame->idx, &fb); 901233d2500723e5594f3e7c70896ffeeef32b9c950ywan yuvconfig2image(&frame->img, fb, NULL); 902233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 903233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 904233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 905233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 906233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 907233d2500723e5594f3e7c70896ffeeef32b9c950ywan 908233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_set_previewpp(vpx_codec_alg_priv_t *ctx, 909233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctr_id, 910233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list args) { 911233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if CONFIG_VP9_POSTPROC 912233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp8_postproc_cfg_t *config = va_arg(args, vp8_postproc_cfg_t *); 913233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void)ctr_id; 914233d2500723e5594f3e7c70896ffeeef32b9c950ywan 915233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (config != NULL) { 916233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->preview_ppcfg = *config; 917233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 918233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 919233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 920233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 921233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else 922233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void)ctx; 923233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void)ctr_id; 924233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void)args; 925233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INCAPABLE; 926233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 927233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 928233d2500723e5594f3e7c70896ffeeef32b9c950ywan 929233d2500723e5594f3e7c70896ffeeef32b9c950ywan 930233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_image_t *vp9e_get_preview(vpx_codec_alg_priv_t *ctx) { 931233d2500723e5594f3e7c70896ffeeef32b9c950ywan YV12_BUFFER_CONFIG sd; 932233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_ppflags_t flags = {0}; 933233d2500723e5594f3e7c70896ffeeef32b9c950ywan 934233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->preview_ppcfg.post_proc_flag) { 935233d2500723e5594f3e7c70896ffeeef32b9c950ywan flags.post_proc_flag = ctx->preview_ppcfg.post_proc_flag; 936233d2500723e5594f3e7c70896ffeeef32b9c950ywan flags.deblocking_level = ctx->preview_ppcfg.deblocking_level; 937233d2500723e5594f3e7c70896ffeeef32b9c950ywan flags.noise_level = ctx->preview_ppcfg.noise_level; 938233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 939233d2500723e5594f3e7c70896ffeeef32b9c950ywan 940233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (vp9_get_preview_raw_frame(ctx->cpi, &sd, &flags) == 0) { 941233d2500723e5594f3e7c70896ffeeef32b9c950ywan yuvconfig2image(&ctx->preview_img, &sd, NULL); 942233d2500723e5594f3e7c70896ffeeef32b9c950ywan return &ctx->preview_img; 943233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 944233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NULL; 945233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 946233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 947233d2500723e5594f3e7c70896ffeeef32b9c950ywan 948233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_update_entropy(vpx_codec_alg_priv_t *ctx, 949233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctr_id, 950233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list args) { 951233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int update = va_arg(args, int); 952233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_update_entropy(ctx->cpi, update); 953233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 954233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 955233d2500723e5594f3e7c70896ffeeef32b9c950ywan 956233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_update_reference(vpx_codec_alg_priv_t *ctx, 957233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctr_id, 958233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list args) { 959233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int ref_frame_flags = va_arg(args, int); 960233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_update_reference(ctx->cpi, ref_frame_flags); 961233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 962233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 963233d2500723e5594f3e7c70896ffeeef32b9c950ywan 964233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_use_reference(vpx_codec_alg_priv_t *ctx, 965233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctr_id, 966233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list args) { 967233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int reference_flag = va_arg(args, int); 968233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_use_as_reference(ctx->cpi, reference_flag); 969233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 970233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 971233d2500723e5594f3e7c70896ffeeef32b9c950ywan 972233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_set_roi_map(vpx_codec_alg_priv_t *ctx, 973233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctr_id, 974233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list args) { 975233d2500723e5594f3e7c70896ffeeef32b9c950ywan // TODO(yaowu): Need to re-implement and test for VP9. 976233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 977233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 978233d2500723e5594f3e7c70896ffeeef32b9c950ywan 979233d2500723e5594f3e7c70896ffeeef32b9c950ywan 980233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_set_activemap(vpx_codec_alg_priv_t *ctx, 981233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctr_id, 982233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list args) { 983233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_active_map_t *const map = va_arg(args, vpx_active_map_t *); 984233d2500723e5594f3e7c70896ffeeef32b9c950ywan 985233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (map) { 986233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!vp9_set_active_map(ctx->cpi, map->active_map, map->rows, map->cols)) 987233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 988233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 989233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 990233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 991233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 992233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 993233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 994233d2500723e5594f3e7c70896ffeeef32b9c950ywan 995233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_set_scalemode(vpx_codec_alg_priv_t *ctx, 996233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctr_id, va_list args) { 997233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_scaling_mode_t *const mode = va_arg(args, vpx_scaling_mode_t *); 998233d2500723e5594f3e7c70896ffeeef32b9c950ywan 999233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mode) { 1000233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int res = vp9_set_internal_size(ctx->cpi, 1001233d2500723e5594f3e7c70896ffeeef32b9c950ywan (VPX_SCALING)mode->h_scaling_mode, 1002233d2500723e5594f3e7c70896ffeeef32b9c950ywan (VPX_SCALING)mode->v_scaling_mode); 1003233d2500723e5594f3e7c70896ffeeef32b9c950ywan return (res == 0) ? VPX_CODEC_OK : VPX_CODEC_INVALID_PARAM; 1004233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1005233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 1006233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1007233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1008233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1009233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_set_svc(vpx_codec_alg_priv_t *ctx, int ctr_id, 1010233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list args) { 1011233d2500723e5594f3e7c70896ffeeef32b9c950ywan int data = va_arg(args, int); 1012233d2500723e5594f3e7c70896ffeeef32b9c950ywan const vpx_codec_enc_cfg_t *cfg = &ctx->cfg; 1013233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_set_svc(ctx->cpi, data); 1014233d2500723e5594f3e7c70896ffeeef32b9c950ywan // CBR or two pass mode for SVC with both temporal and spatial layers 1015233d2500723e5594f3e7c70896ffeeef32b9c950ywan // not yet supported. 1016233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (data == 1 && 1017233d2500723e5594f3e7c70896ffeeef32b9c950ywan (cfg->rc_end_usage == VPX_CBR || 1018233d2500723e5594f3e7c70896ffeeef32b9c950ywan cfg->g_pass == VPX_RC_FIRST_PASS || 1019233d2500723e5594f3e7c70896ffeeef32b9c950ywan cfg->g_pass == VPX_RC_LAST_PASS) && 1020233d2500723e5594f3e7c70896ffeeef32b9c950ywan cfg->ss_number_layers > 1 && 1021233d2500723e5594f3e7c70896ffeeef32b9c950ywan cfg->ts_number_layers > 1) { 1022233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 1023233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1024233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 1025233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1026233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1027233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_set_svc_layer_id(vpx_codec_alg_priv_t *ctx, 1028233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctr_id, 1029233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list args) { 1030233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_svc_layer_id_t *const data = va_arg(args, vpx_svc_layer_id_t *); 1031233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi; 1032233d2500723e5594f3e7c70896ffeeef32b9c950ywan SVC *const svc = &cpi->svc; 1033233d2500723e5594f3e7c70896ffeeef32b9c950ywan svc->spatial_layer_id = data->spatial_layer_id; 1034233d2500723e5594f3e7c70896ffeeef32b9c950ywan svc->temporal_layer_id = data->temporal_layer_id; 1035233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Checks on valid layer_id input. 1036233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (svc->temporal_layer_id < 0 || 1037233d2500723e5594f3e7c70896ffeeef32b9c950ywan svc->temporal_layer_id >= (int)ctx->cfg.ts_number_layers) { 1038233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 1039233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1040233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (svc->spatial_layer_id < 0 || 1041233d2500723e5594f3e7c70896ffeeef32b9c950ywan svc->spatial_layer_id >= (int)ctx->cfg.ss_number_layers) { 1042233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 1043233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1044233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 1045233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1046233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1047233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_err_t vp9e_set_svc_parameters(vpx_codec_alg_priv_t *ctx, 1048233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctr_id, va_list args) { 1049233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMP *const cpi = ctx->cpi; 1050233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_svc_parameters_t *const params = va_arg(args, vpx_svc_parameters_t *); 1051233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1052233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (params == NULL) 1053233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 1054233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1055233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->svc.spatial_layer_id = params->spatial_layer; 1056233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->svc.temporal_layer_id = params->temporal_layer; 1057233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1058233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->lst_fb_idx = params->lst_fb_idx; 1059233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->gld_fb_idx = params->gld_fb_idx; 1060233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->alt_fb_idx = params->alt_fb_idx; 1061233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1062233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (vp9_set_size_literal(ctx->cpi, params->width, params->height) != 0) 1063233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_INVALID_PARAM; 1064233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1065233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->cfg.rc_max_quantizer = params->max_quantizer; 1066233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->cfg.rc_min_quantizer = params->min_quantizer; 1067233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1068233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_vp9e_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg); 1069233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_change_config(ctx->cpi, &ctx->oxcf); 1070233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1071233d2500723e5594f3e7c70896ffeeef32b9c950ywan return VPX_CODEC_OK; 1072233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1073233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1074233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_ctrl_fn_map_t vp9e_ctf_maps[] = { 1075233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8_SET_REFERENCE, vp9e_set_reference}, 1076233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8_COPY_REFERENCE, vp9e_copy_reference}, 1077233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8_SET_POSTPROC, vp9e_set_previewpp}, 1078233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_UPD_ENTROPY, vp9e_update_entropy}, 1079233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_UPD_REFERENCE, vp9e_update_reference}, 1080233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_USE_REFERENCE, vp9e_use_reference}, 1081233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_ROI_MAP, vp9e_set_roi_map}, 1082233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_ACTIVEMAP, vp9e_set_activemap}, 1083233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_SCALEMODE, vp9e_set_scalemode}, 1084233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_CPUUSED, set_param}, 1085233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_NOISE_SENSITIVITY, set_param}, 1086233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_ENABLEAUTOALTREF, set_param}, 1087233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_SHARPNESS, set_param}, 1088233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_STATIC_THRESHOLD, set_param}, 1089233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP9E_SET_TILE_COLUMNS, set_param}, 1090233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP9E_SET_TILE_ROWS, set_param}, 1091233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_GET_LAST_QUANTIZER, get_param}, 1092233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_GET_LAST_QUANTIZER_64, get_param}, 1093233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_ARNR_MAXFRAMES, set_param}, 1094233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_ARNR_STRENGTH, set_param}, 1095233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_ARNR_TYPE, set_param}, 1096233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_TUNING, set_param}, 1097233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_CQ_LEVEL, set_param}, 1098233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP8E_SET_MAX_INTRA_BITRATE_PCT, set_param}, 1099233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP9E_SET_LOSSLESS, set_param}, 1100233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP9E_SET_FRAME_PARALLEL_DECODING, set_param}, 1101233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP9E_SET_AQ_MODE, set_param}, 1102233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP9E_SET_FRAME_PERIODIC_BOOST, set_param}, 1103233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP9_GET_REFERENCE, get_reference}, 1104233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP9E_SET_SVC, vp9e_set_svc}, 1105233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP9E_SET_SVC_PARAMETERS, vp9e_set_svc_parameters}, 1106233d2500723e5594f3e7c70896ffeeef32b9c950ywan {VP9E_SET_SVC_LAYER_ID, vp9e_set_svc_layer_id}, 1107233d2500723e5594f3e7c70896ffeeef32b9c950ywan { -1, NULL}, 1108233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 1109233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1110233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic vpx_codec_enc_cfg_map_t vp9e_usage_cfg_map[] = { 1111233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 1112233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, 1113233d2500723e5594f3e7c70896ffeeef32b9c950ywan { // NOLINT 1114233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, /* g_usage */ 1115233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, /* g_threads */ 1116233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, /* g_profile */ 1117233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1118233d2500723e5594f3e7c70896ffeeef32b9c950ywan 320, /* g_width */ 1119233d2500723e5594f3e7c70896ffeeef32b9c950ywan 240, /* g_height */ 1120233d2500723e5594f3e7c70896ffeeef32b9c950ywan {1, 30}, /* g_timebase */ 1121233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1122233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, /* g_error_resilient */ 1123233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1124233d2500723e5594f3e7c70896ffeeef32b9c950ywan VPX_RC_ONE_PASS, /* g_pass */ 1125233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1126233d2500723e5594f3e7c70896ffeeef32b9c950ywan 25, /* g_lag_in_frames */ 1127233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1128233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, /* rc_dropframe_thresh */ 1129233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, /* rc_resize_allowed */ 1130233d2500723e5594f3e7c70896ffeeef32b9c950ywan 60, /* rc_resize_down_thresold */ 1131233d2500723e5594f3e7c70896ffeeef32b9c950ywan 30, /* rc_resize_up_thresold */ 1132233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1133233d2500723e5594f3e7c70896ffeeef32b9c950ywan VPX_VBR, /* rc_end_usage */ 1134233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if VPX_ENCODER_ABI_VERSION > (1 + VPX_CODEC_ABI_VERSION) 1135233d2500723e5594f3e7c70896ffeeef32b9c950ywan {0}, /* rc_twopass_stats_in */ 1136233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 1137233d2500723e5594f3e7c70896ffeeef32b9c950ywan 256, /* rc_target_bandwidth */ 1138233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, /* rc_min_quantizer */ 1139233d2500723e5594f3e7c70896ffeeef32b9c950ywan 63, /* rc_max_quantizer */ 1140233d2500723e5594f3e7c70896ffeeef32b9c950ywan 100, /* rc_undershoot_pct */ 1141233d2500723e5594f3e7c70896ffeeef32b9c950ywan 100, /* rc_overshoot_pct */ 1142233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1143233d2500723e5594f3e7c70896ffeeef32b9c950ywan 6000, /* rc_max_buffer_size */ 1144233d2500723e5594f3e7c70896ffeeef32b9c950ywan 4000, /* rc_buffer_initial_size; */ 1145233d2500723e5594f3e7c70896ffeeef32b9c950ywan 5000, /* rc_buffer_optimal_size; */ 1146233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1147233d2500723e5594f3e7c70896ffeeef32b9c950ywan 50, /* rc_two_pass_vbrbias */ 1148233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, /* rc_two_pass_vbrmin_section */ 1149233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2000, /* rc_two_pass_vbrmax_section */ 1150233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1151233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* keyframing settings (kf) */ 1152233d2500723e5594f3e7c70896ffeeef32b9c950ywan VPX_KF_AUTO, /* g_kfmode*/ 1153233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, /* kf_min_dist */ 1154233d2500723e5594f3e7c70896ffeeef32b9c950ywan 9999, /* kf_max_dist */ 1155233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1156233d2500723e5594f3e7c70896ffeeef32b9c950ywan VPX_SS_DEFAULT_LAYERS, /* ss_number_layers */ 1157233d2500723e5594f3e7c70896ffeeef32b9c950ywan {0}, /* ss_target_bitrate */ 1158233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1, /* ts_number_layers */ 1159233d2500723e5594f3e7c70896ffeeef32b9c950ywan {0}, /* ts_target_bitrate */ 1160233d2500723e5594f3e7c70896ffeeef32b9c950ywan {0}, /* ts_rate_decimator */ 1161233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0, /* ts_periodicity */ 1162233d2500723e5594f3e7c70896ffeeef32b9c950ywan {0}, /* ts_layer_id */ 1163233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if VPX_ENCODER_ABI_VERSION == (1 + VPX_CODEC_ABI_VERSION) 1164233d2500723e5594f3e7c70896ffeeef32b9c950ywan "vp8.fpf" /* first pass filename */ 1165233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 1166233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1167233d2500723e5594f3e7c70896ffeeef32b9c950ywan }, 1168233d2500723e5594f3e7c70896ffeeef32b9c950ywan { -1, {NOT_IMPLEMENTED}} 1169233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 1170233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1171233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1172233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifndef VERSION_STRING 1173233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define VERSION_STRING 1174233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 1175233d2500723e5594f3e7c70896ffeeef32b9c950ywanCODEC_INTERFACE(vpx_codec_vp9_cx) = { 1176233d2500723e5594f3e7c70896ffeeef32b9c950ywan "WebM Project VP9 Encoder" VERSION_STRING, 1177233d2500723e5594f3e7c70896ffeeef32b9c950ywan VPX_CODEC_INTERNAL_ABI_VERSION, 1178233d2500723e5594f3e7c70896ffeeef32b9c950ywan VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR, 1179233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* vpx_codec_caps_t caps; */ 1180233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9e_init, /* vpx_codec_init_fn_t init; */ 1181233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9e_destroy, /* vpx_codec_destroy_fn_t destroy; */ 1182233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9e_ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */ 1183233d2500723e5594f3e7c70896ffeeef32b9c950ywan NOT_IMPLEMENTED, /* vpx_codec_get_mmap_fn_t get_mmap; */ 1184233d2500723e5594f3e7c70896ffeeef32b9c950ywan NOT_IMPLEMENTED, /* vpx_codec_set_mmap_fn_t set_mmap; */ 1185233d2500723e5594f3e7c70896ffeeef32b9c950ywan { // NOLINT 1186233d2500723e5594f3e7c70896ffeeef32b9c950ywan NOT_IMPLEMENTED, /* vpx_codec_peek_si_fn_t peek_si; */ 1187233d2500723e5594f3e7c70896ffeeef32b9c950ywan NOT_IMPLEMENTED, /* vpx_codec_get_si_fn_t get_si; */ 1188233d2500723e5594f3e7c70896ffeeef32b9c950ywan NOT_IMPLEMENTED, /* vpx_codec_decode_fn_t decode; */ 1189233d2500723e5594f3e7c70896ffeeef32b9c950ywan NOT_IMPLEMENTED, /* vpx_codec_frame_get_fn_t frame_get; */ 1190233d2500723e5594f3e7c70896ffeeef32b9c950ywan }, 1191233d2500723e5594f3e7c70896ffeeef32b9c950ywan { // NOLINT 1192233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t peek_si; */ 1193233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9e_encode, /* vpx_codec_encode_fn_t encode; */ 1194233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9e_get_cxdata, /* vpx_codec_get_cx_data_fn_t frame_get; */ 1195233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9e_set_config, 1196233d2500723e5594f3e7c70896ffeeef32b9c950ywan NOT_IMPLEMENTED, 1197233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9e_get_preview, 1198233d2500723e5594f3e7c70896ffeeef32b9c950ywan } /* encoder functions */ 1199233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 1200