Skip to content
Snippets Groups Projects
Commit f37b1cb1 authored by Tomasz Figa's avatar Tomasz Figa Committed by ChromeOS Commit Bot
Browse files

Rockchip: Implement keyframe requests correctly

Currently, when rk_vepu_update_param() is called with keyframe request
the codingType field in EncoderParameters structure is set to intra
frame. However, every frame, frame counter is evaluated and this field
is overwritten with frame type determined automatically, which results
in ignoring keyframe requests.

To fix this, store keyframe request flag in a separate field and then
use it as additional factor for code determining frame type for next
frame.

BUG=chrome-os-partner:37203
TEST=video_encode_accelerator_unittest (after 4fc28962e2da8b3f278b952c55fefe10487db952); apprtc

Change-Id: I8acd8c5bfa6aded4b2139082b26b773828fc0dc8
Reviewed-on: https://chromium-review.googlesource.com/251970


Reviewed-by: default avatarWu-cheng Li <wuchengli@chromium.org>
Commit-Queue: Tomasz Figa <tfiga@chromium.org>
Tested-by: default avatarTomasz Figa <tfiga@chromium.org>
parent b08f100b
Branches
Tags
No related merge requests found
...@@ -422,11 +422,8 @@ static int ioctl_s_ext_ctrls_locked(struct encoder_context *ctx, int fd, ...@@ -422,11 +422,8 @@ static int ioctl_s_ext_ctrls_locked(struct encoder_context *ctx, int fd,
switch (ext_ctrls->controls[i].id) { switch (ext_ctrls->controls[i].id) {
case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE: case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
if (ext_ctrls->controls[i].value == if (ext_ctrls->controls[i].value ==
V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED) V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME)
break;
runtime_param_ptr->keyframe_request = true; runtime_param_ptr->keyframe_request = true;
runtime_param_ptr->keyframe_value = (ext_ctrls->controls[i].value ==
V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME);
break; break;
case V4L2_CID_MPEG_VIDEO_BITRATE: case V4L2_CID_MPEG_VIDEO_BITRATE:
runtime_param_ptr->bitrate = ext_ctrls->controls[i].value; runtime_param_ptr->bitrate = ext_ctrls->controls[i].value;
......
...@@ -39,7 +39,6 @@ struct rk_vepu_runtime_param { ...@@ -39,7 +39,6 @@ struct rk_vepu_runtime_param {
int32_t framerate_denom; int32_t framerate_denom;
int32_t bitrate; /* bits per second */ int32_t bitrate; /* bits per second */
bool keyframe_request; /* have keyframe request */ bool keyframe_request; /* have keyframe request */
bool keyframe_value; /* keyframe */
}; };
/** /**
......
...@@ -129,8 +129,7 @@ static void rk_vp8_encoder_setconfig(struct rk_vp8_encoder *enc, ...@@ -129,8 +129,7 @@ static void rk_vp8_encoder_setconfig(struct rk_vp8_encoder *enc,
enc->cmdl.frameCntTotal = 0; enc->cmdl.frameCntTotal = 0;
if (param->keyframe_request) { if (param->keyframe_request) {
enc->encIn.codingType = enc->cmdl.keyframeRequest = true;
param->keyframe_value ? VP8ENC_INTRA_FRAME : VP8ENC_PREDICTED_FRAME;
} }
} }
...@@ -213,26 +212,23 @@ static int rk_vp8_encoder_before_encode(struct rk_vp8_encoder *enc) { ...@@ -213,26 +212,23 @@ static int rk_vp8_encoder_before_encode(struct rk_vp8_encoder *enc) {
return -1; return -1;
} }
/* Select frame type */ /* Code keyframe according to intra period counter
if ((cml->intraPicRate != 0) && (enc->intraPeriodCnt >= cml->intraPicRate)) * or if requested by client. */
if (cml->keyframeRequest ||
(cml->intraPicRate != 0 &&
enc->intraPeriodCnt >= cml->intraPicRate)) {
enc->encIn.codingType = VP8ENC_INTRA_FRAME; enc->encIn.codingType = VP8ENC_INTRA_FRAME;
else
enc->encIn.codingType = VP8ENC_PREDICTED_FRAME;
if (enc->encIn.codingType == VP8ENC_INTRA_FRAME)
enc->intraPeriodCnt = 0; enc->intraPeriodCnt = 0;
cml->keyframeRequest = false;
} else {
enc->encIn.codingType = VP8ENC_PREDICTED_FRAME;
}
/* This applies for PREDICTED frames only. By default always predict /* This applies for PREDICTED frames only. By default always predict
* from the previous frame only. */ * from the previous frame only. */
enc->encIn.ipf = VP8ENC_REFERENCE_AND_REFRESH; enc->encIn.ipf = VP8ENC_REFERENCE_AND_REFRESH;
enc->encIn.grf = enc->encIn.arf = VP8ENC_REFERENCE; enc->encIn.grf = enc->encIn.arf = VP8ENC_REFERENCE;
/* Force odd frames to be coded as droppable. */
if (cml->droppable && cml->frameCnt & 1) {
enc->encIn.codingType = VP8ENC_PREDICTED_FRAME;
enc->encIn.ipf = enc->encIn.grf = enc->encIn.arf = VP8ENC_REFERENCE;
}
/* Encode one frame */ /* Encode one frame */
ret = VP8EncStrmEncode(enc->encoder, &enc->encIn, &cml->encOut, cml); ret = VP8EncStrmEncode(enc->encoder, &enc->encIn, &cml->encOut, cml);
if (ret < 0) { if (ret < 0) {
...@@ -602,8 +598,6 @@ void SetDefaultParameter(EncoderParameters* cml) { ...@@ -602,8 +598,6 @@ void SetDefaultParameter(EncoderParameters* cml) {
cml->intra16Favor = 0; cml->intra16Favor = 0;
/* Penalty value for intra mode in intra/inter */ /* Penalty value for intra mode in intra/inter */
cml->intraPenalty = 0; cml->intraPenalty = 0;
/* Code all odd frames as droppable */
cml->droppable = 0;
} }
void PrintTitle(EncoderParameters* cml) { void PrintTitle(EncoderParameters* cml) {
......
...@@ -385,7 +385,6 @@ typedef struct ...@@ -385,7 +385,6 @@ typedef struct
int32_t printPsnr; int32_t printPsnr;
int32_t mvOutput; int32_t mvOutput;
int32_t droppable;
int32_t intra16Favor; int32_t intra16Favor;
int32_t intraPenalty; int32_t intraPenalty;
...@@ -402,6 +401,7 @@ typedef struct ...@@ -402,6 +401,7 @@ typedef struct
ma_s ma; /* Calculate moving average of bitrate */ ma_s ma; /* Calculate moving average of bitrate */
uint32_t psnrSum; /* Calculate average PSNR over encoded frames */ uint32_t psnrSum; /* Calculate average PSNR over encoded frames */
uint32_t psnrCnt; uint32_t psnrCnt;
uint32_t keyframeRequest;
int32_t frameCnt; /* Frame counter of input file */ int32_t frameCnt; /* Frame counter of input file */
uint64_t frameCntTotal; /* Frame counter of all frames */ uint64_t frameCntTotal; /* Frame counter of all frames */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment