#include "third_party/googletest/src/include/gtest/gtest.h"
#include "vp9/simple_encode.h"
#include "vpx/vpx_ext_ratectrl.h"
+#include "vpx/vpx_tpl.h"
#include "vpx_dsp/vpx_dsp_common.h"
namespace {
return VPX_RC_OK;
}
+vpx_rc_status_t rc_send_tpl_gop_stats(vpx_rc_model_t rate_ctrl_model,
+ const VpxTplGopStats *tpl_gop_stats) {
+ const ToyRateCtrl *toy_rate_ctrl =
+ static_cast<ToyRateCtrl *>(rate_ctrl_model);
+ EXPECT_EQ(toy_rate_ctrl->magic_number, kModelMagicNumber);
+ EXPECT_GT(tpl_gop_stats->size, 0);
+
+ for (int i = 0; i < tpl_gop_stats->size; ++i) {
+ EXPECT_GT(tpl_gop_stats->frame_stats_list[i].num_blocks, 0);
+ }
+ return VPX_RC_OK;
+}
+
vpx_rc_status_t rc_get_encodeframe_decision(
vpx_rc_model_t rate_ctrl_model,
const vpx_rc_encodeframe_info_t *encode_frame_info,
::libvpx_test::Encoder *encoder) override {
if (video->frame() == 0) {
vpx_rc_funcs_t rc_funcs;
+ memset(&rc_funcs, 0, sizeof(rc_funcs));
rc_funcs.rc_type = VPX_RC_QP;
rc_funcs.create_model = rc_create_model;
rc_funcs.send_firstpass_stats = rc_send_firstpass_stats;
encoder->Control(VP9E_SET_MAX_GF_INTERVAL, kDefaultMaxGfInterval);
vpx_rc_funcs_t rc_funcs;
+ memset(&rc_funcs, 0, sizeof(rc_funcs));
rc_funcs.rc_type = VPX_RC_GOP_QP;
rc_funcs.create_model = rc_create_model_gop;
rc_funcs.send_firstpass_stats = rc_send_firstpass_stats_gop;
+ rc_funcs.send_tpl_gop_stats = rc_send_tpl_gop_stats;
rc_funcs.get_encodeframe_decision = rc_get_encodeframe_decision_gop;
rc_funcs.get_gop_decision = rc_get_gop_decision;
rc_funcs.update_encodeframe_result = rc_update_encodeframe_result_gop;
encoder->Control(VP9E_SET_TARGET_LEVEL, vp9::LEVEL_AUTO);
vpx_rc_funcs_t rc_funcs;
+ memset(&rc_funcs, 0, sizeof(rc_funcs));
rc_funcs.rc_type = VPX_RC_GOP_QP;
rc_funcs.create_model = rc_create_model_gop_short;
rc_funcs.send_firstpass_stats = rc_send_firstpass_stats_gop_short;
encoder->Control(VP9E_SET_TARGET_LEVEL, vp9::LEVEL_AUTO);
vpx_rc_funcs_t rc_funcs;
+ memset(&rc_funcs, 0, sizeof(rc_funcs));
rc_funcs.rc_type = VPX_RC_GOP_QP;
rc_funcs.create_model = rc_create_model_gop_short;
rc_funcs.send_firstpass_stats = rc_send_firstpass_stats_gop_short;
encoder->Control(VP9E_SET_TARGET_LEVEL, vp9::LEVEL_AUTO);
vpx_rc_funcs_t rc_funcs;
+ memset(&rc_funcs, 0, sizeof(rc_funcs));
rc_funcs.rc_type = VPX_RC_GOP_QP;
rc_funcs.create_model = rc_create_model_gop_short;
rc_funcs.send_firstpass_stats = rc_send_firstpass_stats_gop_short;
::libvpx_test::Encoder *encoder) override {
if (video->frame() == 0) {
vpx_rc_funcs_t rc_funcs;
+ memset(&rc_funcs, 0, sizeof(rc_funcs));
rc_funcs.rc_type = VPX_RC_GOP_QP_RDMULT;
rc_funcs.create_model = rc_create_model_gop_short;
rc_funcs.send_firstpass_stats = rc_send_firstpass_stats_gop_short;
return VPX_CODEC_OK;
}
+vpx_codec_err_t vp9_extrc_send_tpl_stats(EXT_RATECTRL *ext_ratectrl,
+ const VpxTplGopStats *tpl_gop_stats) {
+ if (ext_ratectrl == NULL) {
+ return VPX_CODEC_INVALID_PARAM;
+ }
+ if (ext_ratectrl->ready && ext_ratectrl->funcs.send_tpl_gop_stats != NULL) {
+ vpx_rc_status_t rc_status = ext_ratectrl->funcs.send_tpl_gop_stats(
+ ext_ratectrl->model, tpl_gop_stats);
+ if (rc_status == VPX_RC_ERROR) {
+ return VPX_CODEC_ERROR;
+ }
+ }
+ return VPX_CODEC_OK;
+}
+
static int extrc_get_frame_type(FRAME_UPDATE_TYPE update_type) {
// TODO(angiebird): Add unit test to make sure this function behaves like
// get_frame_type_from_update_type()
#define VPX_VP9_ENCODER_VP9_EXT_RATECTRL_H_
#include "vpx/vpx_ext_ratectrl.h"
+#include "vpx/vpx_tpl.h"
#include "vp9/encoder/vp9_firstpass.h"
typedef struct EXT_RATECTRL {
vpx_codec_err_t vp9_extrc_send_firstpass_stats(
EXT_RATECTRL *ext_ratectrl, const FIRST_PASS_INFO *first_pass_info);
+vpx_codec_err_t vp9_extrc_send_tpl_stats(EXT_RATECTRL *ext_ratectrl,
+ const VpxTplGopStats *tpl_gop_stats);
+
vpx_codec_err_t vp9_extrc_get_encodeframe_decision(
EXT_RATECTRL *ext_ratectrl, int show_index, int coding_index, int gop_index,
FRAME_UPDATE_TYPE update_type, int gop_size, int use_alt_ref,
// Qmode.
trim_tpl_stats(&cpi->common.error, &cpi->tpl_gop_stats, extended_frame_count);
+ if (cpi->ext_ratectrl.ready) {
+ const vpx_codec_err_t codec_status =
+ vp9_extrc_send_tpl_stats(&cpi->ext_ratectrl, &cpi->tpl_gop_stats);
+ if (codec_status != VPX_CODEC_OK) {
+ vpx_internal_error(&cpi->common.error, codec_status,
+ "vp9_extrc_send_tpl_stats() failed");
+ }
+ }
+
#if CONFIG_NON_GREEDY_MV
cpi->tpl_ready = 1;
#if DUMP_TPL_STATS
#endif
#include "./vpx_integer.h"
+#include "vpx/vpx_tpl.h"
/*!\brief Current ABI version number
*
* types, removing or reassigning enums, adding/removing/rearranging
* fields to structures.
*/
-#define VPX_EXT_RATECTRL_ABI_VERSION (6)
+#define VPX_EXT_RATECTRL_ABI_VERSION (7)
/*!\brief The control type of the inference API.
* In VPX_RC_QP mode, the external rate control model determines the
vpx_rc_model_t rate_ctrl_model,
const vpx_rc_firstpass_stats_t *first_pass_stats);
+/*!\brief Send TPL stats for the current GOP to the external rate control model
+ * callback prototype
+ *
+ * This callback is invoked by the encoder to send TPL stats for the GOP to the
+ * external rate control model.
+ *
+ * \param[in] rate_ctrl_model rate control model
+ * \param[in] tpl_gop_stats TPL stats for current GOP
+ */
+typedef vpx_rc_status_t (*vpx_rc_send_tpl_gop_stats_cb_fn_t)(
+ vpx_rc_model_t rate_ctrl_model, const VpxTplGopStats *tpl_gop_stats);
+
/*!\brief Receive encode frame decision callback prototype
*
* This callback is invoked by the encoder to receive encode frame decision from
*/
vpx_rc_send_firstpass_stats_cb_fn_t send_firstpass_stats;
/*!
+ * Send TPL stats for current GOP to the external rate control model.
+ */
+ vpx_rc_send_tpl_gop_stats_cb_fn_t send_tpl_gop_stats;
+ /*!
* Get encodeframe decision from the external rate control model.
*/
vpx_rc_get_encodeframe_decision_cb_fn_t get_encodeframe_decision;
#include <stdio.h>
#include "./vpx_integer.h"
+#include "vpx/vpx_codec.h"
#ifdef __cplusplus
extern "C" {