Loading drivers/media/platform/msm/vidc/msm_venc.c +385 −5 Original line number Diff line number Diff line Loading @@ -468,7 +468,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { }, { .id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, .name = "I Frame Quantization", .name = "H264 I Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 51, Loading @@ -479,7 +479,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { }, { .id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, .name = "P Frame Quantization", .name = "H264 P Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 51, Loading @@ -490,7 +490,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { }, { .id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, .name = "B Frame Quantization", .name = "H264 B Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 51, Loading @@ -499,6 +499,61 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP, .name = "H263 I Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 31, .default_value = I_FRAME_QP, .step = 1, .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP, .name = "H263 P Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 31, .default_value = P_FRAME_QP, .step = 1, .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP, .name = "H263 B Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 31, .default_value = B_FRAME_QP, .step = 1, .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP, .name = "VPX I Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, .maximum = 127, .default_value = I_FRAME_QP, .step = 1, .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP, .name = "VPX P Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, .maximum = 127, .default_value = P_FRAME_QP, .step = 1, .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP, .name = "H264 Minimum QP", Loading @@ -521,6 +576,24 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_VPX_MIN_QP, .name = "VPX Minimum QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, .maximum = 127, .default_value = 0, .step = 1, }, { .id = V4L2_CID_MPEG_VIDEO_VPX_MAX_QP, .name = "VPX Maximum QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, .maximum = 127, .default_value = 127, .step = 1, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP, .name = "VP8 Minimum QP", Loading @@ -539,6 +612,24 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 128, .step = 1, }, { .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP, .name = "MPEG4 Minimum QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 31, .default_value = 1, .step = 1, }, { .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP, .name = "MPEG4 Maximum QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 31, .default_value = 31, .step = 1, }, { .id = V4L2_CID_MPEG_VIDEO_MIN_QP_PACKED, .name = "H264 Minimum QP PACKED", Loading Loading @@ -939,6 +1030,36 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 0, .step = 0, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP, .name = "Iframe initial QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 127, .default_value = 1, .step = 1, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP, .name = "Pframe initial QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 127, .default_value = 1, .step = 1, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP, .name = "Bframe initial QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 127, .default_value = 1, .step = 1, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP, .name = "Iframe initial QP", Loading Loading @@ -1122,7 +1243,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .name = "Set frame level QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 51, .maximum = 127, .default_value = 1, .step = 1, .qmenu = NULL, Loading Loading @@ -2230,6 +2351,9 @@ unknown_value: return -EINVAL; } static int msm_venc_validate_qp_value(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl); static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) { int rc = 0; Loading Loading @@ -2649,6 +2773,81 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) pdata = &quantization; break; } case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: { struct v4l2_ctrl *qpp, *qpb; qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP); qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP); property_id = HAL_PARAM_VENC_SESSION_QP; quantization.qpi = ctrl->val; quantization.qpp = qpp->val; quantization.qpb = qpb->val; quantization.layer_id = 0; pdata = &quantization; break; } case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: { struct v4l2_ctrl *qpi, *qpb; qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP); qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP); property_id = HAL_PARAM_VENC_SESSION_QP; quantization.qpp = ctrl->val; quantization.qpi = qpi->val; quantization.qpb = qpb->val; quantization.layer_id = 0; pdata = &quantization; break; } case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: { struct v4l2_ctrl *qpi, *qpp; qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP); qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP); property_id = HAL_PARAM_VENC_SESSION_QP; quantization.qpb = ctrl->val; quantization.qpi = qpi->val; quantization.qpp = qpp->val; quantization.layer_id = 0; pdata = &quantization; break; } case V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP: { struct v4l2_ctrl *qpp; qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP); property_id = HAL_PARAM_VENC_SESSION_QP; quantization.qpi = ctrl->val; quantization.qpp = qpp->val; /* Bframes are not supported for VPX */ quantization.qpb = 0; quantization.layer_id = 0; pdata = &quantization; break; } case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: { struct v4l2_ctrl *qpi; qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP); property_id = HAL_PARAM_VENC_SESSION_QP; quantization.qpp = ctrl->val; quantization.qpi = qpi->val; /* Bframes are not supported for VPX */ quantization.qpb = 0; quantization.layer_id = 0; pdata = &quantization; break; } case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: { struct v4l2_ctrl *qp_max; Loading Loading @@ -2689,8 +2888,85 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) pdata = &qp_range; break; } case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: { struct v4l2_ctrl *qp_max; qp_max = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP); if (ctrl->val >= qp_max->val) { dprintk(VIDC_ERR, "Bad range: Min QP (%d) > Max QP(%d)\n", ctrl->val, qp_max->val); rc = -ERANGE; break; } property_id = HAL_PARAM_VENC_SESSION_QP_RANGE; qp_range.layer_id = 0; qp_range.max_qp = qp_max->val; qp_range.min_qp = ctrl->val; pdata = &qp_range; break; } case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: { struct v4l2_ctrl *qp_min; qp_min = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP); if (ctrl->val <= qp_min->val) { dprintk(VIDC_ERR, "Bad range: Max QP (%d) < Min QP(%d)\n", ctrl->val, qp_min->val); rc = -ERANGE; break; } property_id = HAL_PARAM_VENC_SESSION_QP_RANGE; qp_range.layer_id = 0; qp_range.max_qp = ctrl->val; qp_range.min_qp = qp_min->val; pdata = &qp_range; break; } case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP: { struct v4l2_ctrl *qp_max; qp_max = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_MAX_QP); if (ctrl->val >= qp_max->val) { dprintk(VIDC_ERR, "Bad range: Min QP (%d) > Max QP(%d)\n", ctrl->val, qp_max->val); rc = -ERANGE; break; } property_id = HAL_PARAM_VENC_SESSION_QP_RANGE; qp_range.layer_id = 0; qp_range.max_qp = qp_max->val; qp_range.min_qp = ctrl->val; pdata = &qp_range; break; } case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP: { struct v4l2_ctrl *qp_min; qp_min = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_MIN_QP); if (ctrl->val <= qp_min->val) { dprintk(VIDC_ERR, "Bad range: Max QP (%d) < Min QP(%d)\n", ctrl->val, qp_min->val); rc = -ERANGE; break; } property_id = HAL_PARAM_VENC_SESSION_QP_RANGE; qp_range.layer_id = 0; qp_range.max_qp = ctrl->val; qp_range.min_qp = qp_min->val; pdata = &qp_range; break; } case V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP: { struct v4l2_ctrl *qp_max; qp_max = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP); property_id = HAL_PARAM_VENC_SESSION_QP_RANGE; qp_range.layer_id = 0; Loading @@ -2701,6 +2977,7 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } case V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP: { struct v4l2_ctrl *qp_min; qp_min = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP); property_id = HAL_PARAM_VENC_SESSION_QP_RANGE; qp_range.layer_id = 0; Loading Loading @@ -3222,6 +3499,14 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) pdata = &baselayerid; break; case V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP: /* Sanity check for the QP boundaries as we are using * same control to set dynamic QP for all the codecs */ rc = msm_venc_validate_qp_value(inst, ctrl); if (rc) { dprintk(VIDC_ERR, "Invalid QP Config QP Range\n"); break; } property_id = HAL_CONFIG_VENC_FRAME_QP; frameqp = ctrl->val; pdata = &frameqp; Loading Loading @@ -3380,7 +3665,6 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } v4l2_ctrl_lock(ctrl); #undef TRY_GET_CTRL if (!rc && property_id) { dprintk(VIDC_DBG, "Control: HAL property=%x,ctrl_value=%d\n", Loading @@ -3393,6 +3677,59 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) return rc; } static int msm_venc_validate_qp_value(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) { int rc = 0, min, max; struct v4l2_ctrl *temp_ctrl = NULL; int qp_value = ctrl->val; #define VALIDATE_BOUNDARIES(__min, __max, __val) ({\ int __rc = __val >= __min && \ __val <= __max; \ if (!__rc) \ dprintk(VIDC_ERR, "QP beyond range: min(%d) max(%d) val(%d)", \ __min, __max, __val); \ __rc; \ }) switch (inst->fmts[CAPTURE_PORT].fourcc) { case V4L2_PIX_FMT_VP8: temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_MAX_QP); max = temp_ctrl->maximum; temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_MIN_QP); min = temp_ctrl->minimum; if (!VALIDATE_BOUNDARIES(min, max, qp_value)) rc = -EINVAL; break; case V4L2_PIX_FMT_H263: case V4L2_PIX_FMT_MPEG4: temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP); max = temp_ctrl->maximum; temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP); min = temp_ctrl->minimum; if (!VALIDATE_BOUNDARIES(min, max, qp_value)) rc = -EINVAL; break; case V4L2_PIX_FMT_H264: case V4L2_PIX_FMT_HEVC: temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_MAX_QP); max = temp_ctrl->maximum; temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_MIN_QP); min = temp_ctrl->minimum; if (!VALIDATE_BOUNDARIES(min, max, qp_value)) rc = -EINVAL; break; default: dprintk(VIDC_ERR, "%s Invalid Codec\n", __func__); return -EINVAL; } return rc; #undef VALIDATE_BOUNDARIES } #undef TRY_GET_CTRL static int try_set_ext_ctrl(struct msm_vidc_inst *inst, struct v4l2_ext_controls *ctrl) { Loading @@ -3408,6 +3745,7 @@ static int try_set_ext_ctrl(struct msm_vidc_inst *inst, struct hal_aspect_ratio sar; struct hal_bitrate bitrate; struct hal_frame_size blur_res; struct v4l2_ctrl *temp_ctrl; if (!inst || !inst->core || !inst->core->device || !ctrl) { dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); Loading Loading @@ -3470,6 +3808,48 @@ static int try_set_ext_ctrl(struct msm_vidc_inst *inst, property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP; pdata = &quant; break; case V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP: /* Sanity check for the QP boundaries as we are using * same control to set Initial QP for all the codecs */ temp_ctrl->id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP; temp_ctrl->val = control[i].value; rc = msm_venc_validate_qp_value(inst, temp_ctrl); if (rc) { dprintk(VIDC_ERR, "Invalid Initial I QP\n"); break; } quant.qpi = control[i].value; property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP; pdata = &quant; break; case V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP: temp_ctrl->id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP; temp_ctrl->val = control[i].value; rc = msm_venc_validate_qp_value(inst, temp_ctrl); if (rc) { dprintk(VIDC_ERR, "Invalid Initial P QP\n"); break; } quant.qpp = control[i].value; property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP; pdata = &quant; break; case V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP: temp_ctrl->id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP; temp_ctrl->val = control[i].value; rc = msm_venc_validate_qp_value(inst, temp_ctrl); if (rc) { dprintk(VIDC_ERR, "Invalid Initial B QP\n"); break; } quant.qpb = control[i].value; property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP; pdata = &quant; break; case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE: search_range.i_frame.x_subsampled = control[i].value; property_id = HAL_PARAM_VENC_SEARCH_RANGE; Loading include/uapi/linux/v4l2-controls.h +12 −4 Original line number Diff line number Diff line Loading @@ -927,9 +927,9 @@ enum v4l2_mpeg_vidc_video_mvc_layout { V4L2_MPEG_VIDC_VIDEO_MVC_SEQUENTIAL = 0, V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM = 1 }; #define V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP (V4L2_CID_MPEG_MSM_VIDC_BASE + 44) #define V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP (V4L2_CID_MPEG_MSM_VIDC_BASE + 45) #define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 46) Loading Loading @@ -969,13 +969,13 @@ enum vl42_mpeg_vidc_video_enable_initial_qp { V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP_BFRAME = 0x4, }; #define V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP \ #define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 54) #define V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP \ #define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 55) #define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP \ #define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 56) #define V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE \ Loading Loading @@ -1211,6 +1211,14 @@ enum v4l2_mpeg_vidc_video_venc_iframesize_type { V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED, }; #define V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 99) #define V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 100) #define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 101) /* Camera class control IDs */ #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) Loading Loading
drivers/media/platform/msm/vidc/msm_venc.c +385 −5 Original line number Diff line number Diff line Loading @@ -468,7 +468,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { }, { .id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, .name = "I Frame Quantization", .name = "H264 I Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 51, Loading @@ -479,7 +479,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { }, { .id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, .name = "P Frame Quantization", .name = "H264 P Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 51, Loading @@ -490,7 +490,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { }, { .id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, .name = "B Frame Quantization", .name = "H264 B Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 51, Loading @@ -499,6 +499,61 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP, .name = "H263 I Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 31, .default_value = I_FRAME_QP, .step = 1, .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP, .name = "H263 P Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 31, .default_value = P_FRAME_QP, .step = 1, .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP, .name = "H263 B Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 31, .default_value = B_FRAME_QP, .step = 1, .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP, .name = "VPX I Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, .maximum = 127, .default_value = I_FRAME_QP, .step = 1, .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP, .name = "VPX P Frame Quantization", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, .maximum = 127, .default_value = P_FRAME_QP, .step = 1, .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP, .name = "H264 Minimum QP", Loading @@ -521,6 +576,24 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .menu_skip_mask = 0, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDEO_VPX_MIN_QP, .name = "VPX Minimum QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, .maximum = 127, .default_value = 0, .step = 1, }, { .id = V4L2_CID_MPEG_VIDEO_VPX_MAX_QP, .name = "VPX Maximum QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 0, .maximum = 127, .default_value = 127, .step = 1, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP, .name = "VP8 Minimum QP", Loading @@ -539,6 +612,24 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 128, .step = 1, }, { .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP, .name = "MPEG4 Minimum QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 31, .default_value = 1, .step = 1, }, { .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP, .name = "MPEG4 Maximum QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 31, .default_value = 31, .step = 1, }, { .id = V4L2_CID_MPEG_VIDEO_MIN_QP_PACKED, .name = "H264 Minimum QP PACKED", Loading Loading @@ -939,6 +1030,36 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 0, .step = 0, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP, .name = "Iframe initial QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 127, .default_value = 1, .step = 1, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP, .name = "Pframe initial QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 127, .default_value = 1, .step = 1, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP, .name = "Bframe initial QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 127, .default_value = 1, .step = 1, .qmenu = NULL, }, { .id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP, .name = "Iframe initial QP", Loading Loading @@ -1122,7 +1243,7 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .name = "Set frame level QP", .type = V4L2_CTRL_TYPE_INTEGER, .minimum = 1, .maximum = 51, .maximum = 127, .default_value = 1, .step = 1, .qmenu = NULL, Loading Loading @@ -2230,6 +2351,9 @@ unknown_value: return -EINVAL; } static int msm_venc_validate_qp_value(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl); static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) { int rc = 0; Loading Loading @@ -2649,6 +2773,81 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) pdata = &quantization; break; } case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: { struct v4l2_ctrl *qpp, *qpb; qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP); qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP); property_id = HAL_PARAM_VENC_SESSION_QP; quantization.qpi = ctrl->val; quantization.qpp = qpp->val; quantization.qpb = qpb->val; quantization.layer_id = 0; pdata = &quantization; break; } case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: { struct v4l2_ctrl *qpi, *qpb; qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP); qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP); property_id = HAL_PARAM_VENC_SESSION_QP; quantization.qpp = ctrl->val; quantization.qpi = qpi->val; quantization.qpb = qpb->val; quantization.layer_id = 0; pdata = &quantization; break; } case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: { struct v4l2_ctrl *qpi, *qpp; qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP); qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP); property_id = HAL_PARAM_VENC_SESSION_QP; quantization.qpb = ctrl->val; quantization.qpi = qpi->val; quantization.qpp = qpp->val; quantization.layer_id = 0; pdata = &quantization; break; } case V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP: { struct v4l2_ctrl *qpp; qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP); property_id = HAL_PARAM_VENC_SESSION_QP; quantization.qpi = ctrl->val; quantization.qpp = qpp->val; /* Bframes are not supported for VPX */ quantization.qpb = 0; quantization.layer_id = 0; pdata = &quantization; break; } case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: { struct v4l2_ctrl *qpi; qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP); property_id = HAL_PARAM_VENC_SESSION_QP; quantization.qpp = ctrl->val; quantization.qpi = qpi->val; /* Bframes are not supported for VPX */ quantization.qpb = 0; quantization.layer_id = 0; pdata = &quantization; break; } case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: { struct v4l2_ctrl *qp_max; Loading Loading @@ -2689,8 +2888,85 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) pdata = &qp_range; break; } case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: { struct v4l2_ctrl *qp_max; qp_max = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP); if (ctrl->val >= qp_max->val) { dprintk(VIDC_ERR, "Bad range: Min QP (%d) > Max QP(%d)\n", ctrl->val, qp_max->val); rc = -ERANGE; break; } property_id = HAL_PARAM_VENC_SESSION_QP_RANGE; qp_range.layer_id = 0; qp_range.max_qp = qp_max->val; qp_range.min_qp = ctrl->val; pdata = &qp_range; break; } case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: { struct v4l2_ctrl *qp_min; qp_min = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP); if (ctrl->val <= qp_min->val) { dprintk(VIDC_ERR, "Bad range: Max QP (%d) < Min QP(%d)\n", ctrl->val, qp_min->val); rc = -ERANGE; break; } property_id = HAL_PARAM_VENC_SESSION_QP_RANGE; qp_range.layer_id = 0; qp_range.max_qp = ctrl->val; qp_range.min_qp = qp_min->val; pdata = &qp_range; break; } case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP: { struct v4l2_ctrl *qp_max; qp_max = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_MAX_QP); if (ctrl->val >= qp_max->val) { dprintk(VIDC_ERR, "Bad range: Min QP (%d) > Max QP(%d)\n", ctrl->val, qp_max->val); rc = -ERANGE; break; } property_id = HAL_PARAM_VENC_SESSION_QP_RANGE; qp_range.layer_id = 0; qp_range.max_qp = qp_max->val; qp_range.min_qp = ctrl->val; pdata = &qp_range; break; } case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP: { struct v4l2_ctrl *qp_min; qp_min = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_MIN_QP); if (ctrl->val <= qp_min->val) { dprintk(VIDC_ERR, "Bad range: Max QP (%d) < Min QP(%d)\n", ctrl->val, qp_min->val); rc = -ERANGE; break; } property_id = HAL_PARAM_VENC_SESSION_QP_RANGE; qp_range.layer_id = 0; qp_range.max_qp = ctrl->val; qp_range.min_qp = qp_min->val; pdata = &qp_range; break; } case V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP: { struct v4l2_ctrl *qp_max; qp_max = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP); property_id = HAL_PARAM_VENC_SESSION_QP_RANGE; qp_range.layer_id = 0; Loading @@ -2701,6 +2977,7 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } case V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP: { struct v4l2_ctrl *qp_min; qp_min = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP); property_id = HAL_PARAM_VENC_SESSION_QP_RANGE; qp_range.layer_id = 0; Loading Loading @@ -3222,6 +3499,14 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) pdata = &baselayerid; break; case V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP: /* Sanity check for the QP boundaries as we are using * same control to set dynamic QP for all the codecs */ rc = msm_venc_validate_qp_value(inst, ctrl); if (rc) { dprintk(VIDC_ERR, "Invalid QP Config QP Range\n"); break; } property_id = HAL_CONFIG_VENC_FRAME_QP; frameqp = ctrl->val; pdata = &frameqp; Loading Loading @@ -3380,7 +3665,6 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) } v4l2_ctrl_lock(ctrl); #undef TRY_GET_CTRL if (!rc && property_id) { dprintk(VIDC_DBG, "Control: HAL property=%x,ctrl_value=%d\n", Loading @@ -3393,6 +3677,59 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) return rc; } static int msm_venc_validate_qp_value(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) { int rc = 0, min, max; struct v4l2_ctrl *temp_ctrl = NULL; int qp_value = ctrl->val; #define VALIDATE_BOUNDARIES(__min, __max, __val) ({\ int __rc = __val >= __min && \ __val <= __max; \ if (!__rc) \ dprintk(VIDC_ERR, "QP beyond range: min(%d) max(%d) val(%d)", \ __min, __max, __val); \ __rc; \ }) switch (inst->fmts[CAPTURE_PORT].fourcc) { case V4L2_PIX_FMT_VP8: temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_MAX_QP); max = temp_ctrl->maximum; temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_VPX_MIN_QP); min = temp_ctrl->minimum; if (!VALIDATE_BOUNDARIES(min, max, qp_value)) rc = -EINVAL; break; case V4L2_PIX_FMT_H263: case V4L2_PIX_FMT_MPEG4: temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP); max = temp_ctrl->maximum; temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP); min = temp_ctrl->minimum; if (!VALIDATE_BOUNDARIES(min, max, qp_value)) rc = -EINVAL; break; case V4L2_PIX_FMT_H264: case V4L2_PIX_FMT_HEVC: temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_MAX_QP); max = temp_ctrl->maximum; temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_MIN_QP); min = temp_ctrl->minimum; if (!VALIDATE_BOUNDARIES(min, max, qp_value)) rc = -EINVAL; break; default: dprintk(VIDC_ERR, "%s Invalid Codec\n", __func__); return -EINVAL; } return rc; #undef VALIDATE_BOUNDARIES } #undef TRY_GET_CTRL static int try_set_ext_ctrl(struct msm_vidc_inst *inst, struct v4l2_ext_controls *ctrl) { Loading @@ -3408,6 +3745,7 @@ static int try_set_ext_ctrl(struct msm_vidc_inst *inst, struct hal_aspect_ratio sar; struct hal_bitrate bitrate; struct hal_frame_size blur_res; struct v4l2_ctrl *temp_ctrl; if (!inst || !inst->core || !inst->core->device || !ctrl) { dprintk(VIDC_ERR, "%s invalid parameters\n", __func__); Loading Loading @@ -3470,6 +3808,48 @@ static int try_set_ext_ctrl(struct msm_vidc_inst *inst, property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP; pdata = &quant; break; case V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP: /* Sanity check for the QP boundaries as we are using * same control to set Initial QP for all the codecs */ temp_ctrl->id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP; temp_ctrl->val = control[i].value; rc = msm_venc_validate_qp_value(inst, temp_ctrl); if (rc) { dprintk(VIDC_ERR, "Invalid Initial I QP\n"); break; } quant.qpi = control[i].value; property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP; pdata = &quant; break; case V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP: temp_ctrl->id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP; temp_ctrl->val = control[i].value; rc = msm_venc_validate_qp_value(inst, temp_ctrl); if (rc) { dprintk(VIDC_ERR, "Invalid Initial P QP\n"); break; } quant.qpp = control[i].value; property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP; pdata = &quant; break; case V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP: temp_ctrl->id = V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP; temp_ctrl->val = control[i].value; rc = msm_venc_validate_qp_value(inst, temp_ctrl); if (rc) { dprintk(VIDC_ERR, "Invalid Initial B QP\n"); break; } quant.qpb = control[i].value; property_id = HAL_PARAM_VENC_ENABLE_INITIAL_QP; pdata = &quant; break; case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE: search_range.i_frame.x_subsampled = control[i].value; property_id = HAL_PARAM_VENC_SEARCH_RANGE; Loading
include/uapi/linux/v4l2-controls.h +12 −4 Original line number Diff line number Diff line Loading @@ -927,9 +927,9 @@ enum v4l2_mpeg_vidc_video_mvc_layout { V4L2_MPEG_VIDC_VIDEO_MVC_SEQUENTIAL = 0, V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM = 1 }; #define V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP (V4L2_CID_MPEG_MSM_VIDC_BASE + 44) #define V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP (V4L2_CID_MPEG_MSM_VIDC_BASE + 45) #define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 46) Loading Loading @@ -969,13 +969,13 @@ enum vl42_mpeg_vidc_video_enable_initial_qp { V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP_BFRAME = 0x4, }; #define V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP \ #define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 54) #define V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP \ #define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 55) #define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP \ #define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 56) #define V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE \ Loading Loading @@ -1211,6 +1211,14 @@ enum v4l2_mpeg_vidc_video_venc_iframesize_type { V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED, }; #define V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 99) #define V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 100) #define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 101) /* Camera class control IDs */ #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) Loading