msm: venc: add all intra encoding supports

1. Add all intra encoding capability;
2. Disable LTR, HP, Slice mode and IR settings;
3. Use WorkMode2, HQ and Pipeline 4 by force;
4. Ignore dynamic switch between IPPP and all intra;
5. Reject sessions if static/dynamic frame rate
   larger than 240;
6. Reject any non HEVC or AVC sessions;
7. Reject any HEVC Main10 profile sessions;
8. Reset all intra flag to false when stream off;

Change-Id: I9f405a7712c84bc6f8319025a7fb2a0a7f9064df
Signed-off-by: Shi Zhongbo <zhongbos@codeaurora.org>
This commit is contained in:
Shi Zhongbo 2019-07-19 10:03:29 +08:00
commit c074c474fb
8 changed files with 134 additions and 1 deletions

View file

@ -1477,6 +1477,12 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
switch (ctrl->id) {
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
if (inst->state == MSM_VIDC_START_DONE) {
if (inst->all_intra) {
dprintk(VIDC_HIGH,
"%s: ignore dynamic gop size for all intra\n",
__func__);
break;
}
rc = msm_venc_set_intra_period(inst);
if (rc)
dprintk(VIDC_ERR,
@ -1869,12 +1875,27 @@ int msm_venc_set_frame_rate(struct msm_vidc_inst *inst)
int rc = 0;
struct hfi_device *hdev;
struct hfi_frame_rate frame_rate;
struct msm_vidc_capability *capability;
u32 fps_max;
if (!inst || !inst->core) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
return -EINVAL;
}
hdev = inst->core->device;
capability = &inst->capability;
/* Check frame rate */
if (inst->all_intra)
fps_max = capability->cap[CAP_ALLINTRA_MAX_FPS].max;
else
fps_max = capability->cap[CAP_FRAMERATE].max;
if (inst->clk_data.frame_rate >> 16 > fps_max) {
dprintk(VIDC_ERR, "%s: Unsupported frame rate\n",
__func__);
return -ENOTSUPP;
}
frame_rate.buffer_type = HFI_BUFFER_OUTPUT;
frame_rate.frame_rate = inst->clk_data.frame_rate;
@ -2289,6 +2310,14 @@ int msm_venc_set_intra_period(struct msm_vidc_inst *inst)
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES);
intra_period.bframes = ctrl->val;
if (inst->state == MSM_VIDC_START_DONE &&
!intra_period.pframes && !intra_period.bframes) {
dprintk(VIDC_HIGH,
"%s: Switch from IPPP to All Intra is not allowed\n",
__func__);
return rc;
}
dprintk(VIDC_HIGH, "%s: %d %d\n", __func__, intra_period.pframes,
intra_period.bframes);
rc = call_hfi_op(hdev, session_set_property, inst->session,
@ -3989,10 +4018,102 @@ int msm_venc_set_lossless(struct msm_vidc_inst *inst)
return rc;
}
int handle_all_intra_restrictions(struct msm_vidc_inst *inst)
{
struct v4l2_ctrl *ctrl, *ctrl_t;
u32 n_fps, fps_max;
struct msm_vidc_capability *capability;
struct v4l2_format *f;
enum hal_video_codec codec;
struct hfi_intra_period intra_period;
if (!inst || !inst->core) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
return -EINVAL;
}
if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)
return 0;
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_GOP_SIZE);
intra_period.pframes = ctrl->val;
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES);
intra_period.bframes = ctrl->val;
if (!intra_period.pframes && !intra_period.bframes)
inst->all_intra = true;
else
return 0;
dprintk(VIDC_HIGH, "All Intra(IDRs) Encoding\n");
/* check codec and profile */
f = &inst->fmts[OUTPUT_PORT].v4l2_fmt;
codec = get_hal_codec(f->fmt.pix_mp.pixelformat);
if (codec != HAL_VIDEO_CODEC_HEVC && codec != HAL_VIDEO_CODEC_H264) {
dprintk(VIDC_ERR, "Unsupported codec for all intra\n");
return -ENOTSUPP;
}
if (codec == HAL_VIDEO_CODEC_HEVC &&
inst->profile == HFI_HEVC_PROFILE_MAIN10) {
dprintk(VIDC_ERR, "Unsupported HEVC profile for all intra\n");
return -ENOTSUPP;
}
/* check supported bit rate mode and frame rate */
capability = &inst->capability;
n_fps = inst->clk_data.frame_rate >> 16;
fps_max = capability->cap[CAP_ALLINTRA_MAX_FPS].max;
if ((inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
inst->rc_type != RATE_CONTROL_OFF &&
inst->rc_type != RATE_CONTROL_LOSSLESS) ||
n_fps > fps_max) {
dprintk(VIDC_ERR, "Unsupported bitrate mode or frame rate\n");
return -ENOTSUPP;
}
/* Disable multi slice */
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE);
if (ctrl->val) {
dprintk(VIDC_HIGH, "Disable multi slice for all intra\n");
ctrl->val = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
}
/* Disable LTR */
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT);
if (ctrl->val) {
dprintk(VIDC_HIGH, "Disable LTR for all intra\n");
ctrl->val = 0;
}
/* Disable Layer encoding */
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER);
ctrl_t = get_ctrl(inst,
V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER);
if (ctrl->val || ctrl_t->val) {
dprintk(VIDC_HIGH, "Disable layer encoding for all intra\n");
ctrl->val = 0;
ctrl_t->val = 0;
}
/* Disable IR */
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM);
ctrl_t = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB);
if (ctrl->val || ctrl_t->val) {
dprintk(VIDC_HIGH, "Disable IR for all intra\n");
ctrl->val = 0;
ctrl_t->val = 0;
}
return 0;
}
int msm_venc_set_properties(struct msm_vidc_inst *inst)
{
int rc = 0;
rc = handle_all_intra_restrictions(inst);
if (rc)
goto exit;
rc = msm_venc_set_frame_size(inst);
if (rc)
goto exit;

View file

@ -39,4 +39,5 @@ int msm_venc_set_hp_layer(struct msm_vidc_inst *inst);
int msm_venc_set_base_layer_priority_id(struct msm_vidc_inst *inst);
int msm_venc_set_lossless(struct msm_vidc_inst *inst);
int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst);
int handle_all_intra_restrictions(struct msm_vidc_inst *inst);
#endif

View file

@ -1105,6 +1105,7 @@ static inline int stop_streaming(struct msm_vidc_inst *inst)
dprintk(VIDC_ERR,
"%s: failed to unprepare preprocess\n",
__func__);
inst->all_intra = false;
}
msm_clock_data_reset(inst);
@ -1551,6 +1552,7 @@ void *msm_vidc_open(int core_id, int session_type)
inst->smem_ops = &msm_vidc_smem_ops;
inst->rc_type = RATE_CONTROL_OFF;
inst->dpb_extra_binfo = NULL;
inst->all_intra = false;
for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) {

View file

@ -1518,7 +1518,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst)
pdata.video_work_mode = HFI_WORKMODE_1;
latency.enable = true;
}
if (inst->rc_type == RATE_CONTROL_LOSSLESS) {
if (inst->rc_type == RATE_CONTROL_LOSSLESS || inst->all_intra) {
pdata.video_work_mode = HFI_WORKMODE_2;
latency.enable = false;
}
@ -1738,6 +1738,7 @@ int msm_vidc_decide_core_and_power_mode_iris2(struct msm_vidc_inst *inst)
if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ ||
inst->rc_type == RATE_CONTROL_LOSSLESS ||
inst->all_intra ||
(mbpf <= max_hq_mbpf && mbps <= max_hq_mbps))
enable = false;

View file

@ -1571,6 +1571,9 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data)
&inst->capability.cap[CAP_LOSSLESS_FRAME_HEIGHT]);
print_cap("lossless_mbs_per_frame",
&inst->capability.cap[CAP_LOSSLESS_MBS_PER_FRAME]);
/* All intra encoding usecase specific */
print_cap("all_intra_frame_rate",
&inst->capability.cap[CAP_ALLINTRA_MAX_FPS]);
msm_vidc_comm_update_ctrl_limits(inst);

View file

@ -533,6 +533,7 @@ struct msm_vidc_inst {
struct delayed_work batch_work;
struct msm_vidc_inst_smem_ops *smem_ops;
int (*buffer_size_calculators)(struct msm_vidc_inst *inst);
bool all_intra;
};
extern struct msm_vidc_drv *vidc_driver;

View file

@ -356,6 +356,9 @@ static struct msm_vidc_codec_capability kona_capabilities[] = {
{CAP_LOSSLESS_FRAME_HEIGHT, ENC, H264|HEVC, 128, 4096, 1, 1080},
/* (4096 * 2304) / 256 */
{CAP_LOSSLESS_MBS_PER_FRAME, ENC, H264|HEVC, 64, 36864, 1, 36864},
/* All intra encoding usecase specific */
{CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 240, 1, 30},
};
/*

View file

@ -283,6 +283,7 @@ enum hal_capability {
CAP_LOSSLESS_FRAME_WIDTH,
CAP_LOSSLESS_FRAME_HEIGHT,
CAP_LOSSLESS_MBS_PER_FRAME,
CAP_ALLINTRA_MAX_FPS,
CAP_MAX,
};