From f6e383a6523772e70ee3e6f615872940652fc882 Mon Sep 17 00:00:00 2001 From: Tomasz Figa <tfiga@chromium.org> Date: Wed, 25 Feb 2015 14:09:48 +0900 Subject: [PATCH] Rockchip: Do not reset rate control if no parameters changed Current code always resets rate control algorithm whenever rk_vp8_encoder_setconfig() is called. However the function can be also used to request a keyframe. In addition, it might be possible to call this function with the same parameters as already set, which would cause rate control to be reset unnecessarily. To fix the problem, this patch modifies the code to perform the reset only if bit rate or frame rate actually changed. To achieve this the internal API is slightly modified to avoid accessing private parameters (outRateDenom, outRateNum and encStatus of internal vp8Instance_s struct) from external code (e.g. rk_vpu8_encoder_setconfig()) and explicitly convey the dependence of VP8EncSetRateCtrl() on these private parameters, which are now explicitly given to this function. BUG=chrome-os-partner:37204 TEST=video_encode_accelerator_unittest (after 4fc28962e2da8b3f278b952c55fefe10487db952);apprtc Change-Id: Iff4787f6ac55a0324e63b80d272dfd04aadd084c Reviewed-on: https://chromium-review.googlesource.com/253252 Reviewed-by: Wu-cheng Li <wuchengli@chromium.org> Commit-Queue: Tomasz Figa <tfiga@chromium.org> Tested-by: Tomasz Figa <tfiga@chromium.org> --- libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.c | 40 +++++++++++-------- libv4l-rockchip/libvpu/vp8_enc/vp8encapi.c | 8 +++- libv4l-rockchip/libvpu/vp8_enc/vp8encapi.h | 3 ++ 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.c b/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.c index c14df08..f13b2bd 100644 --- a/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.c +++ b/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.c @@ -102,31 +102,37 @@ static void rk_vp8_encoder_setconfig(struct rk_vp8_encoder *enc, struct rk_vepu_runtime_param *param) { int ret; - vp8Instance_s *pEncInst = (vp8Instance_s *)enc->encoder; VP8EncRateCtrl rc; - pEncInst->encStatus = VP8ENCSTAT_INIT; + bool reset = false; + VP8EncGetRateCtrl(enc->encoder, &rc); - if (param->bitrate != 0) { - rc.bitPerSecond = param->bitrate; - rc.pictureRc = ENCHW_YES; - rc.qpHdr = -1; - } - if (param->framerate_denom != 0 && param->framerate_numer != 0) { - pEncInst->rateControl.outRateNum = param->framerate_numer; - pEncInst->rateControl.outRateDenom = param->framerate_denom; - enc->cmdl.outputRateDenom = param->framerate_denom; + if (param->framerate_denom != 0 && param->framerate_numer != 0 && + (param->framerate_denom != rc.outRateDenom || + param->framerate_numer != rc.outRateNum)) { + rc.outRateNum = param->framerate_numer; + rc.outRateDenom = param->framerate_denom; enc->cmdl.outputRateNumer = param->framerate_numer; + enc->cmdl.outputRateDenom = param->framerate_denom; + reset = true; } - ret = VP8EncSetRateCtrl(enc->encoder, &rc); - if (ret < 0) { - VPU_PLG_ERR("failed to set rate control\n"); + if (param->bitrate != 0 && param->bitrate != rc.bitPerSecond) { + rc.bitPerSecond = param->bitrate; + rc.pictureRc = ENCHW_YES; + rc.qpHdr = -1; + reset = true; } - VPU_PLG_INF("Reset bitrate calculation parameters\n"); - enc->cmdl.streamSize = 0; - enc->cmdl.frameCntTotal = 0; + if (reset) { + VPU_PLG_INF("Reset bitrate calculation parameters\n"); + enc->cmdl.streamSize = 0; + enc->cmdl.frameCntTotal = 0; + ret = VP8EncSetRateCtrl(enc->encoder, &rc); + if (ret < 0) { + VPU_PLG_ERR("failed to set rate control\n"); + } + } if (param->keyframe_request) { enc->cmdl.keyframeRequest = true; diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.c b/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.c index 53c5f77..a967d05 100644 --- a/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.c +++ b/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.c @@ -385,8 +385,12 @@ VP8EncRet VP8EncSetRateCtrl(VP8EncInst inst, rc_tmp.intraPictureRate = pRateCtrl->intraPictureRate; rc_tmp.goldenPictureRate = pRateCtrl->goldenPictureRate; rc_tmp.altrefPictureRate = pRateCtrl->altrefPictureRate; + rc_tmp.outRateNum = pRateCtrl->outRateNum; + rc_tmp.outRateDenom = pRateCtrl->outRateDenom; - VP8InitRc(&rc_tmp, pEncInst->encStatus == VP8ENCSTAT_INIT); + pEncInst->encStatus = VP8ENCSTAT_INIT; + + VP8InitRc(&rc_tmp, true); /* Set final values into instance */ pEncInst->rateControl = rc_tmp; @@ -433,6 +437,8 @@ VP8EncRet VP8EncGetRateCtrl(VP8EncInst inst, VP8EncRateCtrl* pRateCtrl) { pRateCtrl->intraPictureRate = pEncInst->rateControl.intraPictureRate; pRateCtrl->goldenPictureRate = pEncInst->rateControl.goldenPictureRate; pRateCtrl->altrefPictureRate = pEncInst->rateControl.altrefPictureRate; + pRateCtrl->outRateNum = pEncInst->rateControl.outRateNum; + pRateCtrl->outRateDenom = pEncInst->rateControl.outRateDenom; VPU_PLG_DBG("VP8EncGetRateCtrl: OK\n"); return VP8ENC_OK; diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.h b/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.h index 7d5ce70..5c11f3c 100644 --- a/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.h +++ b/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.h @@ -222,6 +222,9 @@ typedef struct uint32_t altrefPictureRate; /* The distance of two altref pictures, [0..300] * This will force periodical altref pictures. * 0=disabled. */ + uint32_t outRateNum; /* Numerator of frame rate fraction defined + * as frames per second. [1..] */ + uint32_t outRateDenom; /* Denominator of frame rate fraction. [1..] */ } VP8EncRateCtrl; /* Encoder input structure */ -- GitLab