mirror of https://gitee.com/openkylin/linux.git
media: venus: venc: set correctly GOP size and number of B-frames
This change fixes the calculation of B-frames and GOP size by adopt v4l2 controls with the firmware interface expectations. Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> [hans.verkuil@cisco.com: fixed two small checkpatch comments] Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
parent
fdda01090c
commit
8fc58186bb
|
@ -652,8 +652,13 @@ static int venc_set_properties(struct venus_inst *inst)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* IDR periodicity, n:
|
||||||
|
* n = 0 - only the first I-frame is IDR frame
|
||||||
|
* n = 1 - all I-frames will be IDR frames
|
||||||
|
* n > 1 - every n-th I-frame will be IDR frame
|
||||||
|
*/
|
||||||
ptype = HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD;
|
ptype = HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD;
|
||||||
idrp.idr_period = ctr->gop_size;
|
idrp.idr_period = 0;
|
||||||
ret = hfi_session_set_property(inst, ptype, &idrp);
|
ret = hfi_session_set_property(inst, ptype, &idrp);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -667,10 +672,6 @@ static int venc_set_properties(struct venus_inst *inst)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* intra_period = pframes + bframes + 1 */
|
|
||||||
if (!ctr->num_p_frames)
|
|
||||||
ctr->num_p_frames = 2 * 15 - 1,
|
|
||||||
|
|
||||||
ptype = HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD;
|
ptype = HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD;
|
||||||
intra_period.pframes = ctr->num_p_frames;
|
intra_period.pframes = ctr->num_p_frames;
|
||||||
intra_period.bframes = ctr->num_b_frames;
|
intra_period.bframes = ctr->num_b_frames;
|
||||||
|
@ -767,6 +768,10 @@ static int venc_init_session(struct venus_inst *inst)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto deinit;
|
goto deinit;
|
||||||
|
|
||||||
|
ret = venc_set_properties(inst);
|
||||||
|
if (ret)
|
||||||
|
goto deinit;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
deinit:
|
deinit:
|
||||||
hfi_session_deinit(inst);
|
hfi_session_deinit(inst);
|
||||||
|
|
|
@ -30,10 +30,57 @@
|
||||||
#define AT_SLICE_BOUNDARY \
|
#define AT_SLICE_BOUNDARY \
|
||||||
V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
|
V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
|
||||||
|
|
||||||
|
static int venc_calc_bpframes(u32 gop_size, u32 conseq_b, u32 *bf, u32 *pf)
|
||||||
|
{
|
||||||
|
u32 half = (gop_size - 1) >> 1;
|
||||||
|
u32 b, p, ratio;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if (!gop_size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*bf = *pf = 0;
|
||||||
|
|
||||||
|
if (!conseq_b) {
|
||||||
|
*pf = gop_size - 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
b = p = half;
|
||||||
|
|
||||||
|
for (; b <= gop_size - 1; b++, p--) {
|
||||||
|
if (b % p)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ratio = b / p;
|
||||||
|
|
||||||
|
if (ratio == conseq_b) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ratio > conseq_b)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (b + p + 1 != gop_size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*bf = b;
|
||||||
|
*pf = p;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||||
{
|
{
|
||||||
struct venus_inst *inst = ctrl_to_inst(ctrl);
|
struct venus_inst *inst = ctrl_to_inst(ctrl);
|
||||||
struct venc_controls *ctr = &inst->controls.enc;
|
struct venc_controls *ctr = &inst->controls.enc;
|
||||||
|
u32 bframes;
|
||||||
|
int ret;
|
||||||
|
|
||||||
switch (ctrl->id) {
|
switch (ctrl->id) {
|
||||||
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
|
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
|
||||||
|
@ -102,6 +149,11 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||||
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
|
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
|
||||||
break;
|
break;
|
||||||
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
|
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
|
||||||
|
ret = venc_calc_bpframes(ctrl->val, ctr->num_b_frames, &bframes,
|
||||||
|
&ctr->num_p_frames);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
ctr->gop_size = ctrl->val;
|
ctr->gop_size = ctrl->val;
|
||||||
break;
|
break;
|
||||||
case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
|
case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
|
||||||
|
@ -114,7 +166,12 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||||
ctr->vp8_max_qp = ctrl->val;
|
ctr->vp8_max_qp = ctrl->val;
|
||||||
break;
|
break;
|
||||||
case V4L2_CID_MPEG_VIDEO_B_FRAMES:
|
case V4L2_CID_MPEG_VIDEO_B_FRAMES:
|
||||||
ctr->num_b_frames = ctrl->val;
|
ret = venc_calc_bpframes(ctr->gop_size, ctrl->val, &bframes,
|
||||||
|
&ctr->num_p_frames);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ctr->num_b_frames = bframes;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
Loading…
Reference in New Issue