Merge "msm: vidc: Check image encode capabilities"

This commit is contained in:
qctecmdr 2019-07-25 17:21:42 -07:00 • committed by Gerrit - the friendly Code Review server
commit 048032c021
8 changed files with 149 additions and 128 deletions

View file

@ -1506,12 +1506,6 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
"%s: set bitrate mode failed\n", __func__);
break;
}
case V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY:
inst->frame_quality = ctrl->val;
break;
case V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE:
inst->grid_enable = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_BITRATE:
inst->clk_data.bitrate = ctrl->val;
if (inst->state == MSM_VIDC_START_DONE) {
@ -1774,6 +1768,8 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
__func__);
}
break;
case V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY:
case V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE:
case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER:
case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE:
case V4L2_CID_ROTATE:
@ -2800,12 +2796,74 @@ int msm_venc_set_qp_range(struct msm_vidc_inst *inst)
return rc;
}
int msm_venc_set_frame_quality(struct msm_vidc_inst *inst)
static void set_all_intra_preconditions(struct msm_vidc_inst *inst)
{
struct v4l2_ctrl *ctrl = NULL, *ctrl_t = NULL;
/* 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;
}
static void set_heif_preconditions(struct msm_vidc_inst *inst)
{
struct v4l2_ctrl *ctrl = NULL;
/* Reset PFrames */
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_GOP_SIZE);
if (ctrl->val) {
dprintk(VIDC_HIGH, "Reset P-frame count for HEIF\n");
ctrl->val = 0;
}
/* Reset BFrames */
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_B_FRAMES);
if (ctrl->val) {
dprintk(VIDC_HIGH, "Reset B-frame count for HEIF\n");
ctrl->val = 0;
}
return;
}
int msm_venc_set_image_properties(struct msm_vidc_inst *inst)
{
int rc = 0;
struct hfi_device *hdev;
struct v4l2_ctrl *ctrl;
struct hfi_heic_frame_quality frame_quality;
struct hfi_heic_grid_enable grid_enable;
if (!inst || !inst->core) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
@ -2819,31 +2877,13 @@ int msm_venc_set_frame_quality(struct msm_vidc_inst *inst)
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY);
frame_quality.frame_quality = ctrl->val;
dprintk(VIDC_HIGH, "%s: %d\n", __func__, frame_quality.frame_quality);
dprintk(VIDC_HIGH, "%s: frame quality: %d\n", __func__,
frame_quality.frame_quality);
rc = call_hfi_op(hdev, session_set_property, inst->session,
HFI_PROPERTY_CONFIG_HEIC_FRAME_QUALITY, &frame_quality,
sizeof(frame_quality));
if (rc)
dprintk(VIDC_ERR, "%s: set property failed\n", __func__);
return rc;
}
int msm_venc_set_grid(struct msm_vidc_inst *inst)
{
int rc = 0;
struct hfi_device *hdev;
struct v4l2_ctrl *ctrl;
struct hfi_heic_grid_enable grid_enable;
if (!inst || !inst->core) {
dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
return -EINVAL;
}
hdev = inst->core->device;
if (inst->rc_type != V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)
return 0;
dprintk(VIDC_ERR, "%s: set frame quality failed\n", __func__);
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE);
@ -2853,12 +2893,16 @@ int msm_venc_set_grid(struct msm_vidc_inst *inst)
else
grid_enable.grid_enable = true;
dprintk(VIDC_HIGH, "%s: %d\n", __func__, grid_enable.grid_enable);
dprintk(VIDC_HIGH, "%s: grid enable: %d\n", __func__,
grid_enable.grid_enable);
rc = call_hfi_op(hdev, session_set_property, inst->session,
HFI_PROPERTY_CONFIG_HEIC_GRID_ENABLE, &grid_enable,
sizeof(grid_enable));
if (rc)
dprintk(VIDC_ERR, "%s: set property failed\n", __func__);
dprintk(VIDC_ERR, "%s: set grid enable failed\n", __func__);
set_all_intra_preconditions(inst);
set_heif_preconditions(inst);
return rc;
}
@ -4027,7 +4071,7 @@ int msm_venc_set_lossless(struct msm_vidc_inst *inst)
int handle_all_intra_restrictions(struct msm_vidc_inst *inst)
{
struct v4l2_ctrl *ctrl, *ctrl_t;
struct v4l2_ctrl *ctrl = NULL;
u32 n_fps, fps_max;
struct msm_vidc_capability *capability;
struct v4l2_format *f;
@ -4078,38 +4122,7 @@ int handle_all_intra_restrictions(struct msm_vidc_inst *inst)
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;
}
set_all_intra_preconditions(inst);
return 0;
}
@ -4210,10 +4223,7 @@ int msm_venc_set_properties(struct msm_vidc_inst *inst)
rc = msm_venc_set_qp_range(inst);
if (rc)
goto exit;
rc = msm_venc_set_frame_quality(inst);
if (rc)
goto exit;
rc = msm_venc_set_grid(inst);
rc = msm_venc_set_image_properties(inst);
if (rc)
goto exit;
rc = msm_venc_set_au_delimiter_mode(inst);

View file

@ -826,15 +826,6 @@ static inline int start_streaming(struct msm_vidc_inst *inst)
is_secondary_output_mode(inst))
b.buffer_type = HFI_BUFFER_OUTPUT2;
/* HEIC HW/FWK tiling encode is supported only for CQ RC mode */
if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) {
if (!heic_encode_session_supported(inst)) {
dprintk(VIDC_ERR,
"HEIC Encode session not supported\n");
return -ENOTSUPP;
}
}
/* Check if current session is under HW capability */
rc = msm_vidc_check_session_supported(inst);
if (rc) {
@ -1440,9 +1431,6 @@ static int try_get_ctrl_for_instance(struct msm_vidc_inst *inst,
V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
inst->profile);
break;
case V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE:
ctrl->val = inst->grid_enable;
break;
case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
ctrl->val = msm_comm_hfi_to_v4l2(
V4L2_CID_MPEG_VIDEO_H264_LEVEL,

View file

@ -1069,8 +1069,7 @@ int msm_dcvs_try_enable(struct msm_vidc_inst *inst)
inst->flags & VIDC_THUMBNAIL ||
inst->clk_data.low_latency_mode ||
inst->batch.enable ||
inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ ||
inst->grid_enable) {
inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) {
dprintk(VIDC_HIGH, "DCVS disabled: %pK\n", inst);
inst->clk_data.dcvs_mode = false;
return false;

View file

@ -2387,48 +2387,6 @@ int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst,
return 0;
}
bool heic_encode_session_supported(struct msm_vidc_inst *inst)
{
u32 slice_mode;
u32 idr_period = IDR_PERIOD;
u32 n_bframes;
u32 n_pframes;
struct v4l2_format *f;
slice_mode = msm_comm_g_ctrl_for_id(inst,
V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE);
n_bframes = msm_comm_g_ctrl_for_id(inst,
V4L2_CID_MPEG_VIDEO_B_FRAMES);
n_pframes = msm_comm_g_ctrl_for_id(inst,
V4L2_CID_MPEG_VIDEO_GOP_SIZE);
/*
* HEIC Encode is supported for Constant Quality RC mode only.
* All configurations below except grid_enable are required for any
* HEIC session including FWK tiled HEIC encode.
* grid_enable flag along with dimension check enables HW tiling.
*/
f = &inst->fmts[OUTPUT_PORT].v4l2_fmt;
if (inst->session_type == MSM_VIDC_ENCODER &&
get_hal_codec(f->fmt.pix_mp.pixelformat) ==
HAL_VIDEO_CODEC_HEVC &&
inst->frame_quality >= MIN_FRAME_QUALITY &&
inst->frame_quality <= MAX_FRAME_QUALITY &&
slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE &&
idr_period == 1 &&
n_bframes == 0 &&
n_pframes == 0) {
if (inst->grid_enable > 0) {
if (f->fmt.pix_mp.width < HEIC_GRID_DIMENSION ||
f->fmt.pix_mp.height < HEIC_GRID_DIMENSION)
return false;
}
return true;
} else {
return false;
}
}
static bool is_eos_buffer(struct msm_vidc_inst *inst, u32 device_addr)
{
struct eos_buf *temp, *next;
@ -5585,6 +5543,9 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst)
/* ignore thumbnail session */
if (is_thumbnail_session(temp))
continue;
/* ignore HEIF sessions */
if (is_image_session(temp))
continue;
mbpf += NUM_MBS_PER_FRAME(
temp->fmts[INPUT_PORT].v4l2_fmt.fmt.pix_mp.height,
temp->fmts[INPUT_PORT].v4l2_fmt.fmt.pix_mp.width);
@ -5629,10 +5590,15 @@ int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst)
u32 x_min, x_max, y_min, y_max;
u32 input_height, input_width, output_height, output_width;
struct v4l2_format *f;
struct v4l2_ctrl *ctrl = NULL;
if (inst->grid_enable > 0) {
dprintk(VIDC_HIGH, "Skip scaling check for HEIC\n");
return 0;
/* Grid get_ctrl allowed for encode session only */
if (is_image_session(inst)) {
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE);
if (ctrl->val > 0) {
dprintk(VIDC_HIGH, "Skip scaling check for HEIC\n");
return 0;
}
}
f = &inst->fmts[INPUT_PORT].v4l2_fmt;
@ -5719,6 +5685,7 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
u32 width_min, width_max, height_min, height_max;
u32 mbpf_max;
struct v4l2_format *f;
struct v4l2_ctrl *ctrl = NULL;
if (!inst || !inst->core || !inst->core->device) {
dprintk(VIDC_ERR, "%s: Invalid parameter\n", __func__);
@ -5774,6 +5741,48 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
input_height = f->fmt.pix_mp.height;
input_width = f->fmt.pix_mp.width;
if (is_image_session(inst)) {
if (is_secure_session(inst)) {
dprintk(VIDC_ERR,
"Secure image encode isn't supported!\n");
return -ENOTSUPP;
}
ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE);
if (ctrl->val > 0) {
if (inst->fmts[INPUT_PORT].v4l2_fmt.fmt.pix_mp.pixelformat !=
V4L2_PIX_FMT_NV12 &&
inst->fmts[INPUT_PORT].v4l2_fmt.fmt.pix_mp.pixelformat !=
V4L2_PIX_FMT_NV12_512)
return -ENOTSUPP;
width_min =
capability->cap[CAP_HEIC_IMAGE_FRAME_WIDTH].min;
width_max =
capability->cap[CAP_HEIC_IMAGE_FRAME_WIDTH].max;
height_min =
capability->cap[CAP_HEIC_IMAGE_FRAME_HEIGHT].min;
height_max =
capability->cap[CAP_HEIC_IMAGE_FRAME_HEIGHT].max;
mbpf_max = capability->cap[CAP_MBS_PER_FRAME].max;
input_height = ALIGN(input_height, 512);
input_width = ALIGN(input_width, 512);
output_height = input_height;
output_width = input_width;
} else {
width_min =
capability->cap[CAP_HEVC_IMAGE_FRAME_WIDTH].min;
width_max =
capability->cap[CAP_HEVC_IMAGE_FRAME_WIDTH].max;
height_min =
capability->cap[CAP_HEVC_IMAGE_FRAME_HEIGHT].min;
height_max =
capability->cap[CAP_HEVC_IMAGE_FRAME_HEIGHT].max;
mbpf_max = capability->cap[CAP_MBS_PER_FRAME].max;
}
}
if (inst->session_type == MSM_VIDC_ENCODER && (input_width % 2 != 0 ||
input_height % 2 != 0 || output_width % 2 != 0 ||
output_height % 2 != 0)) {

View file

@ -84,6 +84,14 @@ static inline u32 get_v4l2_codec(struct msm_vidc_inst *inst)
return f->fmt.pix_mp.pixelformat;
}
static inline bool is_image_session(struct msm_vidc_inst *inst)
{
/* Grid may or may not be enabled for an image encode session */
return inst->session_type == MSM_VIDC_ENCODER &&
get_v4l2_codec(inst) == V4L2_PIX_FMT_HEVC &&
inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ;
}
static inline bool is_realtime_session(struct msm_vidc_inst *inst)
{
return !!(inst->flags & VIDC_REALTIME);

View file

@ -520,8 +520,6 @@ struct msm_vidc_inst {
u32 colour_space;
u32 profile;
u32 level;
u32 grid_enable;
u32 frame_quality;
u32 rc_type;
u32 hybrid_hp;
u32 layer_bitrate;
@ -560,7 +558,6 @@ void handle_cmd_response(enum hal_command_response cmd, void *data);
int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
enum hal_ssr_trigger_type type);
int msm_vidc_noc_error_info(struct msm_vidc_core *core);
bool heic_encode_session_supported(struct msm_vidc_inst *inst);
int msm_vidc_check_session_supported(struct msm_vidc_inst *inst);
int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst);
void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type);

View file

@ -359,6 +359,12 @@ static struct msm_vidc_codec_capability kona_capabilities[] = {
/* All intra encoding usecase specific */
{CAP_ALLINTRA_MAX_FPS, ENC, H264|HEVC, 1, 240, 1, 30},
/* Image specific */
{CAP_HEVC_IMAGE_FRAME_WIDTH, ENC, HEVC, 128, 512, 1, 512},
{CAP_HEVC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 128, 512, 1, 512},
{CAP_HEIC_IMAGE_FRAME_WIDTH, ENC, HEVC, 512, 8192, 1, 8192},
{CAP_HEIC_IMAGE_FRAME_HEIGHT, ENC, HEVC, 512, 8192, 1, 8192},
};
/*

View file

@ -284,6 +284,10 @@ enum hal_capability {
CAP_LOSSLESS_FRAME_HEIGHT,
CAP_LOSSLESS_MBS_PER_FRAME,
CAP_ALLINTRA_MAX_FPS,
CAP_HEVC_IMAGE_FRAME_WIDTH,
CAP_HEVC_IMAGE_FRAME_HEIGHT,
CAP_HEIC_IMAGE_FRAME_WIDTH,
CAP_HEIC_IMAGE_FRAME_HEIGHT,
CAP_MAX,
};