in drivers/media/platform/msm/vidc/msm_venc.c [2366:3732]
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;
struct hal_request_iframe request_iframe;
struct hal_bitrate bitrate;
struct hal_profile_level profile_level;
struct hal_h264_entropy_control h264_entropy_control;
struct hal_quantization quantization;
struct hal_intra_period intra_period;
struct hal_idr_period idr_period;
struct hal_operations operations;
struct hal_intra_refresh intra_refresh;
struct hal_multi_slice_control multi_slice_control;
struct hal_h264_db_control h264_db_control;
struct hal_enable enable;
struct hal_h264_vui_timing_info vui_timing_info;
struct hal_quantization_range qp_range;
struct hal_h264_vui_bitstream_restrc vui_bitstream_restrict;
struct hal_preserve_text_quality preserve_text_quality;
u32 property_id = 0, property_val = 0;
void *pdata = NULL;
struct v4l2_ctrl *temp_ctrl = NULL;
struct hfi_device *hdev;
struct hal_extradata_enable extra;
struct hal_mpeg4_time_resolution time_res;
struct hal_ltr_use use_ltr;
struct hal_ltr_mark mark_ltr;
struct hal_hybrid_hierp hyb_hierp;
u32 hier_p_layers = 0, hier_b_layers = 0, mbi_statistics_mode = 0;
enum hal_perf_mode venc_mode;
int max_hierp_layers;
int baselayerid = 0;
int frameqp = 0;
int pic_order_cnt = 0;
struct hal_video_signal_info signal_info = {0};
enum hal_iframesize_type iframesize_type = HAL_IFRAMESIZE_TYPE_DEFAULT;
if (!inst || !inst->core || !inst->core->device) {
dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
return -EINVAL;
}
hdev = inst->core->device;
/* Small helper macro for quickly getting a control and err checking */
#define TRY_GET_CTRL(__ctrl_id) ({ \
struct v4l2_ctrl *__temp; \
__temp = get_ctrl_from_cluster( \
__ctrl_id, \
ctrl->cluster, ctrl->ncontrols); \
if (!__temp) { \
dprintk(VIDC_ERR, "Can't find %s (%x) in cluster\n", \
#__ctrl_id, __ctrl_id); \
/* Clusters are hardcoded, if we can't find */ \
/* something then things are massively screwed up */ \
BUG_ON(1); \
} \
__temp; \
})
/*
* Unlock the control prior to setting to the hardware. Otherwise
* lower level code that attempts to do a get_ctrl() will end up
* deadlocking.
*/
v4l2_ctrl_unlock(ctrl);
switch (ctrl->id) {
case V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD:
if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264 &&
inst->fmts[CAPTURE_PORT].fourcc !=
V4L2_PIX_FMT_H264_NO_SC &&
inst->fmts[CAPTURE_PORT].fourcc !=
V4L2_PIX_FMT_HEVC) {
dprintk(VIDC_ERR,
"Control %#x only valid for H264 and HEVC\n",
ctrl->id);
rc = -ENOTSUPP;
break;
}
property_id = HAL_CONFIG_VENC_IDR_PERIOD;
idr_period.idr_period = ctrl->val;
pdata = &idr_period;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES:
case V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES:
{
int num_p, num_b;
u32 max_num_b_frames;
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES);
num_b = temp_ctrl->val;
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES);
num_p = temp_ctrl->val;
if (ctrl->id == V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES)
num_p = ctrl->val;
else if (ctrl->id == V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES)
num_b = ctrl->val;
max_num_b_frames = num_b ? MAX_NUM_B_FRAMES : 0;
property_id = HAL_PARAM_VENC_MAX_NUM_B_FRAMES;
pdata = &max_num_b_frames;
rc = call_hfi_op(hdev, session_set_property,
(void *)inst->session, property_id, pdata);
if (rc) {
dprintk(VIDC_ERR,
"Failed : Setprop MAX_NUM_B_FRAMES %d\n",
rc);
break;
}
property_id = HAL_CONFIG_VENC_INTRA_PERIOD;
intra_period.pframes = num_p;
intra_period.bframes = num_b;
/*
*Incase firmware does not have B-Frame support,
*offload the b-frame count to p-frame to make up
*for the requested Intraperiod
*/
if (!inst->capability.bframe.max) {
intra_period.pframes = num_p + num_b;
intra_period.bframes = 0;
dprintk(VIDC_DBG,
"No bframe support, changing pframe from %d to %d\n",
num_p, intra_period.pframes);
}
pdata = &intra_period;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME:
property_id = HAL_CONFIG_VENC_REQUEST_IFRAME;
request_iframe.enable = true;
pdata = &request_iframe;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL:
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
{
int final_mode = 0;
struct v4l2_ctrl update_ctrl = {.id = 0};
/* V4L2_CID_MPEG_VIDEO_BITRATE_MODE and _RATE_CONTROL
* manipulate the same thing. If one control's state
* changes, try to mirror the state in the other control's
* value */
if (ctrl->id == V4L2_CID_MPEG_VIDEO_BITRATE_MODE) {
if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) {
final_mode = HAL_RATE_CONTROL_VBR_CFR;
update_ctrl.val =
V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR;
} else {/* ...if (ctrl->val == _BITRATE_MODE_CBR) */
final_mode = HAL_RATE_CONTROL_CBR_CFR;
update_ctrl.val =
V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR;
}
update_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
} else if (ctrl->id == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL) {
switch (ctrl->val) {
case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF:
case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR:
case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR:
update_ctrl.val =
V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR:
case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR:
case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_CFR:
case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR:
update_ctrl.val =
V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
break;
}
final_mode = ctrl->val;
update_ctrl.id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE;
}
if (update_ctrl.id) {
temp_ctrl = TRY_GET_CTRL(update_ctrl.id);
temp_ctrl->val = update_ctrl.val;
}
property_id = HAL_PARAM_VENC_RATE_CONTROL;
property_val = final_mode;
pdata = &property_val;
break;
}
case V4L2_CID_MPEG_VIDEO_BITRATE:
{
property_id = HAL_CONFIG_VENC_TARGET_BITRATE;
bitrate.bit_rate = ctrl->val;
bitrate.layer_id = 0;
pdata = &bitrate;
break;
}
case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
{
struct v4l2_ctrl *avg_bitrate = TRY_GET_CTRL(
V4L2_CID_MPEG_VIDEO_BITRATE);
if (ctrl->val < avg_bitrate->val) {
dprintk(VIDC_ERR,
"Peak bitrate (%d) is lower than average bitrate (%d)\n",
ctrl->val, avg_bitrate->val);
rc = -EINVAL;
break;
} else if (ctrl->val < avg_bitrate->val * 2) {
dprintk(VIDC_WARN,
"Peak bitrate (%d) ideally should be twice the average bitrate (%d)\n",
ctrl->val, avg_bitrate->val);
}
property_id = HAL_CONFIG_VENC_MAX_BITRATE;
bitrate.bit_rate = ctrl->val;
bitrate.layer_id = 0;
pdata = &bitrate;
break;
}
case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
temp_ctrl = TRY_GET_CTRL(
V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL);
property_id = HAL_PARAM_VENC_H264_ENTROPY_CONTROL;
h264_entropy_control.entropy_mode = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, ctrl->val);
h264_entropy_control.cabac_model = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL,
temp_ctrl->val);
pdata = &h264_entropy_control;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL:
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE);
property_id = HAL_PARAM_VENC_H264_ENTROPY_CONTROL;
h264_entropy_control.cabac_model = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, ctrl->val);
h264_entropy_control.entropy_mode = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL,
temp_ctrl->val);
pdata = &h264_entropy_control;
break;
case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL);
property_id = HAL_PARAM_PROFILE_LEVEL_CURRENT;
profile_level.profile = venc_v4l2_to_hal(ctrl->id,
ctrl->val);
profile_level.level = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
temp_ctrl->val);
pdata = &profile_level;
break;
case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE);
property_id = HAL_PARAM_PROFILE_LEVEL_CURRENT;
profile_level.level = venc_v4l2_to_hal(ctrl->id,
ctrl->val);
profile_level.profile = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
temp_ctrl->val);
pdata = &profile_level;
break;
case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_LEVEL);
property_id = HAL_PARAM_PROFILE_LEVEL_CURRENT;
profile_level.profile = venc_v4l2_to_hal(ctrl->id,
ctrl->val);
profile_level.level = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDEO_H264_LEVEL,
temp_ctrl->val);
pdata = &profile_level;
dprintk(VIDC_DBG, "\nprofile: %d\n",
profile_level.profile);
break;
case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_PROFILE);
property_id = HAL_PARAM_PROFILE_LEVEL_CURRENT;
profile_level.level = venc_v4l2_to_hal(ctrl->id,
ctrl->val);
profile_level.profile = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDEO_H264_PROFILE,
temp_ctrl->val);
pdata = &profile_level;
dprintk(VIDC_DBG, "\nLevel: %d\n",
profile_level.level);
break;
case V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE:
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL);
property_id = HAL_PARAM_PROFILE_LEVEL_CURRENT;
profile_level.profile = venc_v4l2_to_hal(ctrl->id,
ctrl->val);
profile_level.level = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL,
temp_ctrl->val);
pdata = &profile_level;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL:
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE);
property_id = HAL_PARAM_PROFILE_LEVEL_CURRENT;
profile_level.level = venc_v4l2_to_hal(ctrl->id,
ctrl->val);
profile_level.profile = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE,
ctrl->val);
pdata = &profile_level;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL:
property_id = HAL_PARAM_PROFILE_LEVEL_CURRENT;
profile_level.profile = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL,
ctrl->val);
profile_level.level = HAL_VPX_PROFILE_UNUSED;
pdata = &profile_level;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE:
temp_ctrl =
TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL);
property_id = HAL_PARAM_PROFILE_LEVEL_CURRENT;
profile_level.profile = venc_v4l2_to_hal(ctrl->id,
ctrl->val);
profile_level.level = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL,
temp_ctrl->val);
pdata = &profile_level;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL:
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE);
property_id = HAL_PARAM_PROFILE_LEVEL_CURRENT;
profile_level.level = venc_v4l2_to_hal(ctrl->id,
ctrl->val);
profile_level.profile = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE,
temp_ctrl->val);
pdata = &profile_level;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION:
{
struct v4l2_ctrl *deinterlace = NULL;
if (!(inst->capability.pixelprocess_capabilities &
HAL_VIDEO_ENCODER_ROTATION_CAPABILITY)) {
dprintk(VIDC_ERR, "Rotation not supported: %#x\n",
ctrl->id);
rc = -ENOTSUPP;
break;
}
deinterlace =
TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE);
if (ctrl->val && deinterlace && deinterlace->val !=
V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_DISABLED) {
dprintk(VIDC_ERR,
"Rotation not supported with deinterlacing\n");
rc = -EINVAL;
break;
}
property_id = HAL_CONFIG_VPE_OPERATIONS;
operations.rotate = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDC_VIDEO_ROTATION,
ctrl->val);
operations.flip = HAL_FLIP_NONE;
pdata = &operations;
break;
}
case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: {
struct v4l2_ctrl *qpp, *qpb;
qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP);
qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_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_H264_P_FRAME_QP: {
struct v4l2_ctrl *qpi, *qpb;
qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP);
qpb = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_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_H264_B_FRAME_QP: {
struct v4l2_ctrl *qpi, *qpp;
qpi = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP);
qpp = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_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_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;
qp_max = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_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_H264_MAX_QP: {
struct v4l2_ctrl *qp_min;
qp_min = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_H264_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_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;
qp_range.max_qp = qp_max->val;
qp_range.min_qp = ctrl->val;
pdata = &qp_range;
break;
}
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;
qp_range.max_qp = ctrl->val;
qp_range.min_qp = qp_min->val;
pdata = &qp_range;
break;
}
case V4L2_CID_MPEG_VIDEO_MIN_QP_PACKED: {
struct v4l2_ctrl *qp_max;
qp_max = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MAX_QP_PACKED);
if (ctrl->val >= qp_max->val) {
dprintk(VIDC_ERR,
"Bad range: Min QP PACKED (0x%x) > Max QP PACKED (0x%x)\n",
ctrl->val, qp_max->val);
rc = -ERANGE;
break;
}
property_id = HAL_PARAM_VENC_SESSION_QP_RANGE_PACKED;
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_MAX_QP_PACKED: {
struct v4l2_ctrl *qp_min;
qp_min = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MIN_QP_PACKED);
if (ctrl->val <= qp_min->val) {
dprintk(VIDC_ERR,
"Bad range: Max QP PACKED (%d) < Min QP PACKED (%d)\n",
ctrl->val, qp_min->val);
rc = -ERANGE;
break;
}
property_id = HAL_PARAM_VENC_SESSION_QP_RANGE_PACKED;
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_MULTI_SLICE_MODE: {
int temp = 0;
switch (ctrl->val) {
case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB:
temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
break;
case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES:
temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
break;
case V4L2_MPEG_VIDEO_MULTI_SLICE_GOB:
temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB;
break;
case V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE:
default:
temp = 0;
break;
}
if (temp)
temp_ctrl = TRY_GET_CTRL(temp);
property_id = HAL_PARAM_VENC_MULTI_SLICE_CONTROL;
multi_slice_control.multi_slice = ctrl->val;
multi_slice_control.slice_size = temp ? temp_ctrl->val : 0;
pdata = &multi_slice_control;
break;
}
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB:
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE);
property_id = HAL_PARAM_VENC_MULTI_SLICE_CONTROL;
multi_slice_control.multi_slice = temp_ctrl->val;
multi_slice_control.slice_size = ctrl->val;
pdata = &multi_slice_control;
break;
case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE: {
bool codec_avc =
inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 ||
inst->fmts[CAPTURE_PORT].fourcc ==
V4L2_PIX_FMT_H264_NO_SC;
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE);
if (codec_avc && temp_ctrl->val ==
V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
property_id = HAL_PARAM_VENC_SLICE_DELIVERY_MODE;
enable.enable = true;
} else {
dprintk(VIDC_WARN,
"Failed : slice delivery mode is valid "\
"only for H264 encoder and MB based slicing\n");
enable.enable = false;
}
pdata = &enable;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE: {
struct v4l2_ctrl *air_mbs, *air_ref, *cir_mbs;
bool is_cont_intra_supported = false;
air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
is_cont_intra_supported =
(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264) ||
(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC);
if (is_cont_intra_supported) {
if (ctrl->val != HAL_INTRA_REFRESH_NONE)
enable.enable = true;
else
enable.enable = false;
rc = call_hfi_op(hdev, session_set_property,
(void *)inst->session,
HAL_PARAM_VENC_CONSTRAINED_INTRA_PRED, &enable);
if (rc) {
dprintk(VIDC_ERR,
"Failed to set constrained intra\n");
rc = -EINVAL;
break;
}
}
property_id = HAL_PARAM_VENC_INTRA_REFRESH;
intra_refresh.mode = ctrl->val;
intra_refresh.air_mbs = air_mbs->val;
intra_refresh.air_ref = air_ref->val;
intra_refresh.cir_mbs = cir_mbs->val;
pdata = &intra_refresh;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS: {
struct v4l2_ctrl *ir_mode, *air_ref, *cir_mbs;
ir_mode = TRY_GET_CTRL(
V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE);
air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
property_id = HAL_PARAM_VENC_INTRA_REFRESH;
intra_refresh.air_mbs = ctrl->val;
intra_refresh.mode = ir_mode->val;
intra_refresh.air_ref = air_ref->val;
intra_refresh.cir_mbs = cir_mbs->val;
pdata = &intra_refresh;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF: {
struct v4l2_ctrl *ir_mode, *air_mbs, *cir_mbs;
ir_mode = TRY_GET_CTRL(
V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE);
air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
cir_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS);
property_id = HAL_PARAM_VENC_INTRA_REFRESH;
intra_refresh.air_ref = ctrl->val;
intra_refresh.air_mbs = air_mbs->val;
intra_refresh.mode = ir_mode->val;
intra_refresh.cir_mbs = cir_mbs->val;
pdata = &intra_refresh;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS: {
struct v4l2_ctrl *ir_mode, *air_mbs, *air_ref;
ir_mode = TRY_GET_CTRL(
V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE);
air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
property_id = HAL_PARAM_VENC_INTRA_REFRESH;
intra_refresh.cir_mbs = ctrl->val;
intra_refresh.air_mbs = air_mbs->val;
intra_refresh.air_ref = air_ref->val;
intra_refresh.mode = ir_mode->val;
pdata = &intra_refresh;
break;
}
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: {
struct v4l2_ctrl *air_mbs, *air_ref;
air_mbs = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS);
air_ref = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF);
property_id = HAL_PARAM_VENC_INTRA_REFRESH;
intra_refresh.cir_mbs = ctrl->val;
intra_refresh.air_mbs = air_mbs->val;
intra_refresh.air_ref = air_ref->val;
intra_refresh.mode = HAL_INTRA_REFRESH_CYCLIC;
pdata = &intra_refresh;
break;
}
case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
{
struct v4l2_ctrl *alpha, *beta;
alpha = TRY_GET_CTRL(
V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA);
beta = TRY_GET_CTRL(
V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA);
property_id = HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
h264_db_control.slice_alpha_offset = alpha->val;
h264_db_control.slice_beta_offset = beta->val;
h264_db_control.mode = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
ctrl->val);
pdata = &h264_db_control;
break;
}
case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
{
struct v4l2_ctrl *mode, *beta;
mode = TRY_GET_CTRL(
V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE);
beta = TRY_GET_CTRL(
V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA);
property_id = HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
h264_db_control.slice_alpha_offset = ctrl->val;
h264_db_control.slice_beta_offset = beta->val;
h264_db_control.mode = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
mode->val);
pdata = &h264_db_control;
break;
}
case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
{
struct v4l2_ctrl *mode, *alpha;
mode = TRY_GET_CTRL(
V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE);
alpha = TRY_GET_CTRL(
V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA);
property_id = HAL_PARAM_VENC_H264_DEBLOCK_CONTROL;
h264_db_control.slice_alpha_offset = alpha->val;
h264_db_control.slice_beta_offset = ctrl->val;
h264_db_control.mode = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
mode->val);
pdata = &h264_db_control;
break;
}
case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
property_id = HAL_PARAM_VENC_SYNC_FRAME_SEQUENCE_HEADER;
switch (ctrl->val) {
case V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE:
enable.enable = 0;
break;
case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME:
enable.enable = 1;
break;
case V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME:
default:
rc = -ENOTSUPP;
break;
}
pdata = &enable;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_SECURE:
inst->flags |= VIDC_SECURE;
dprintk(VIDC_INFO, "Setting secure mode to: %d\n",
!!(inst->flags & VIDC_SECURE));
break;
case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA:
msm_venc_register_extradata(inst, (u32)ctrl->val);
property_id = HAL_PARAM_INDEX_EXTRADATA;
extra.index = msm_comm_get_hal_extradata_index(ctrl->val);
extra.enable = 1;
pdata = &extra;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO:
{
struct v4l2_ctrl *rc_mode;
bool cfr = false;
property_id = HAL_PARAM_VENC_H264_VUI_TIMING_INFO;
rc_mode = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL);
switch (rc_mode->val) {
case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR:
case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR:
cfr = true;
break;
default:
cfr = false;
break;
}
switch (ctrl->val) {
case V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED:
vui_timing_info.enable = 0;
break;
case V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED:
vui_timing_info.enable = 1;
vui_timing_info.fixed_frame_rate = cfr;
vui_timing_info.time_scale = NSEC_PER_SEC;
}
pdata = &vui_timing_info;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_AU_DELIMITER:
property_id = HAL_PARAM_VENC_GENERATE_AUDNAL;
switch (ctrl->val) {
case V4L2_MPEG_VIDC_VIDEO_AU_DELIMITER_DISABLED:
enable.enable = 0;
break;
case V4L2_MPEG_VIDC_VIDEO_AU_DELIMITER_ENABLED:
enable.enable = 1;
break;
default:
rc = -ENOTSUPP;
break;
}
pdata = &enable;
break;
case V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL:
switch (ctrl->val) {
case V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL:
if (inst->flags & VIDC_TURBO) {
inst->flags &= ~VIDC_TURBO;
msm_dcvs_init_load(inst);
}
break;
case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO:
inst->flags |= VIDC_TURBO;
break;
default:
dprintk(VIDC_ERR, "Perf mode %x not supported\n",
ctrl->val);
rc = -ENOTSUPP;
break;
}
msm_dcvs_try_enable(inst);
msm_comm_scale_clocks_and_bus(inst);
break;
case V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_BITSTREAM_RESTRICT:
property_id = HAL_PARAM_VENC_H264_VUI_BITSTREAM_RESTRC;
vui_bitstream_restrict.enable = ctrl->val;
pdata = &vui_bitstream_restrict;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_PRESERVE_TEXT_QUALITY:
property_id = HAL_PARAM_VENC_PRESERVE_TEXT_QUALITY;
preserve_text_quality.enable = ctrl->val;
pdata = &preserve_text_quality;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_MPEG4_TIME_RESOLUTION:
property_id = HAL_PARAM_VENC_MPEG4_TIME_RESOLUTION;
time_res.time_increment_resolution = ctrl->val;
pdata = &time_res;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE:
{
struct v4l2_ctrl *rotation = NULL;
if (!(inst->capability.pixelprocess_capabilities &
HAL_VIDEO_ENCODER_DEINTERLACE_CAPABILITY)) {
dprintk(VIDC_ERR, "Deinterlace not supported: %#x\n",
ctrl->id);
rc = -ENOTSUPP;
break;
}
rotation = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_ROTATION);
if (ctrl->val && rotation && rotation->val !=
V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE) {
dprintk(VIDC_ERR,
"Deinterlacing not supported with rotation");
rc = -EINVAL;
break;
}
property_id = HAL_CONFIG_VPE_DEINTERLACE;
switch (ctrl->val) {
case V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED:
enable.enable = 1;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_DISABLED:
default:
enable.enable = 0;
break;
}
pdata = &enable;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER:
atomic_inc(&inst->seq_hdr_reqs);
break;
case V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME:
property_id = HAL_CONFIG_VENC_USELTRFRAME;
use_ltr.ref_ltr = ctrl->val;
use_ltr.use_constraint = false;
use_ltr.frames = 0;
pdata = &use_ltr;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME:
property_id = HAL_CONFIG_VENC_MARKLTRFRAME;
mark_ltr.mark_frame = ctrl->val;
pdata = &mark_ltr;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS:
property_id = HAL_CONFIG_VENC_HIER_P_NUM_FRAMES;
hier_p_layers = ctrl->val;
if (hier_p_layers > inst->capability.hier_p.max) {
dprintk(VIDC_ERR,
"Error setting hier p num layers %d max supported is %d\n",
hier_p_layers, inst->capability.hier_p.max);
rc = -ENOTSUPP;
break;
}
pdata = &hier_p_layers;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_TIMESTAMP_MODE:
property_id = HAL_PARAM_VENC_DISABLE_RC_TIMESTAMP;
enable.enable = (ctrl->val ==
V4L2_MPEG_VIDC_VIDEO_RATE_CONTROL_TIMESTAMP_MODE_IGNORE);
pdata = &enable;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE:
property_id = HAL_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE;
enable.enable = ctrl->val;
pdata = &enable;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC:
property_id = HAL_PARAM_VENC_H264_NAL_SVC_EXT;
enable.enable = ctrl->val;
pdata = &enable;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE:
property_id = HAL_CONFIG_VENC_PERF_MODE;
switch (ctrl->val) {
case V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE:
inst->flags |= VIDC_LOW_POWER;
venc_mode = HAL_PERF_MODE_POWER_SAVE;
break;
case V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY:
inst->flags &= ~VIDC_LOW_POWER;
venc_mode = HAL_PERF_MODE_POWER_MAX_QUALITY;
break;
default:
dprintk(VIDC_ERR, "Power save mode %x not supported\n",
ctrl->val);
rc = -ENOTSUPP;
property_id = 0;
break;
}
pdata = &venc_mode;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS:
if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC) {
dprintk(VIDC_ERR, "Hier B supported for HEVC only\n");
rc = -ENOTSUPP;
break;
}
property_id = HAL_PARAM_VENC_HIER_B_MAX_ENH_LAYERS;
hier_b_layers = ctrl->val;
pdata = &hier_b_layers;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE:
property_id = HAL_PARAM_VENC_HIER_P_HYBRID_MODE;
hyb_hierp.layers = ctrl->val;
pdata = &hyb_hierp;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_MBI_STATISTICS_MODE:
property_id = HAL_PARAM_VENC_MBI_STATISTICS_MODE;
mbi_statistics_mode = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDC_VIDEO_MBI_STATISTICS_MODE,
ctrl->val);
pdata = &mbi_statistics_mode;
break;
case V4L2_CID_VIDC_QBUF_MODE:
property_id = HAL_PARAM_SYNC_BASED_INTERRUPT;
enable.enable = ctrl->val == V4L2_VIDC_QBUF_BATCHED;
pdata = &enable;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS:
property_id = HAL_PARAM_VENC_HIER_P_MAX_ENH_LAYERS;
max_hierp_layers = ctrl->val;
if (max_hierp_layers > inst->capability.hier_p.max) {
dprintk(VIDC_ERR,
"Error max HP layers(%d)>max supported(%d)\n",
max_hierp_layers, inst->capability.hier_p.max);
rc = -ENOTSUPP;
break;
}
pdata = &max_hierp_layers;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID:
property_id = HAL_CONFIG_VENC_BASELAYER_PRIORITYID;
baselayerid = ctrl->val;
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;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP:
{
rc = msm_venc_validate_qp_value(inst, ctrl);
if (rc) {
dprintk(VIDC_ERR, "Invalid Initial I QP\n");
break;
}
/*
* Defer sending property from here, set_ext_ctrl
* will send it based on the rc value.
*/
property_id = 0;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP:
{
rc = msm_venc_validate_qp_value(inst, ctrl);
if (rc) {
dprintk(VIDC_ERR, "Invalid Initial B QP\n");
break;
}
/*
* Defer sending property from here, set_ext_ctrl
* will send it based on the rc value.
*/
property_id = 0;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP:
{
rc = msm_venc_validate_qp_value(inst, ctrl);
if (rc) {
dprintk(VIDC_ERR, "Invalid Initial P QP\n");
break;
}
/*
* Defer sending property from here, set_ext_ctrl
* will send it based on the rc value.
*/
property_id = 0;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI:
property_id = HAL_PARAM_VENC_VQZIP_SEI;
enable.enable = ctrl->val;
pdata = &enable;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY:
property_id = HAL_CONFIG_REALTIME;
/* firmware has inverted values for realtime and
* non-realtime priority
*/
enable.enable = !(ctrl->val);
pdata = &enable;
switch (ctrl->val) {
case V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE:
inst->flags &= ~VIDC_REALTIME;
break;
case V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE:
inst->flags |= VIDC_REALTIME;
break;
default:
dprintk(VIDC_WARN,
"inst(%pK) invalid priority ctrl value %#x\n",
inst, ctrl->val);
break;
}
break;
case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE:
dprintk(VIDC_DBG,
"inst(%pK) operating rate changed from %d to %d\n",
inst, inst->operating_rate >> 16, ctrl->val >> 16);
inst->operating_rate = ctrl->val;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE:
{
property_id = HAL_PARAM_VENC_BITRATE_TYPE;
enable.enable = ctrl->val;
pdata = &enable;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_H264_PIC_ORDER_CNT:
{
property_id = HAL_PARAM_VENC_H264_PIC_ORDER_CNT;
pic_order_cnt = ctrl->val;
pdata = &pic_order_cnt;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE:
{
signal_info.color_space = ctrl->val;
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE);
signal_info.full_range = temp_ctrl ? temp_ctrl->val : 0;
temp_ctrl =
TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS);
signal_info.transfer_chars = temp_ctrl ? temp_ctrl->val : 0;
temp_ctrl =
TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS);
signal_info.matrix_coeffs = temp_ctrl ? temp_ctrl->val : 0;
property_id = HAL_PARAM_VENC_VIDEO_SIGNAL_INFO;
pdata = &signal_info;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE:
{
signal_info.full_range = ctrl->val;
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE);
signal_info.color_space = temp_ctrl ? temp_ctrl->val : 0;
temp_ctrl =
TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS);
signal_info.transfer_chars = temp_ctrl ? temp_ctrl->val : 0;
temp_ctrl =
TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS);
signal_info.matrix_coeffs = temp_ctrl ? temp_ctrl->val : 0;
property_id = HAL_PARAM_VENC_VIDEO_SIGNAL_INFO;
pdata = &signal_info;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS:
{
signal_info.transfer_chars = ctrl->val;
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE);
signal_info.full_range = temp_ctrl ? temp_ctrl->val : 0;
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE);
signal_info.color_space = temp_ctrl ? temp_ctrl->val : 0;
temp_ctrl =
TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS);
signal_info.matrix_coeffs = temp_ctrl ? temp_ctrl->val : 0;
property_id = HAL_PARAM_VENC_VIDEO_SIGNAL_INFO;
pdata = &signal_info;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS:
{
signal_info.matrix_coeffs = ctrl->val;
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE);
signal_info.full_range = temp_ctrl ? temp_ctrl->val : 0;
temp_ctrl =
TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS);
signal_info.transfer_chars = temp_ctrl ? temp_ctrl->val : 0;
temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE);
signal_info.color_space = temp_ctrl ? temp_ctrl->val : 0;
property_id = HAL_PARAM_VENC_VIDEO_SIGNAL_INFO;
pdata = &signal_info;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC:
if (ctrl->val == V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE) {
rc = msm_venc_set_csc(inst);
if (rc)
dprintk(VIDC_ERR, "fail to set csc: %d\n", rc);
}
break;
case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE:
{
property_id = HAL_PARAM_VENC_LOW_LATENCY;
if (ctrl->val ==
V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_ENABLE)
enable.enable = 1;
else
enable.enable = 0;
pdata = &enable;
break;
}
case V4L2_CID_MPEG_VIDC_VIDEO_H264_TRANSFORM_8x8:
property_id = HAL_PARAM_VENC_H264_TRANSFORM_8x8;
switch (ctrl->val) {
case V4L2_MPEG_VIDC_VIDEO_H264_TRANSFORM_8x8_ENABLE:
enable.enable = 1;
break;
case V4L2_MPEG_VIDC_VIDEO_H264_TRANSFORM_8x8_DISABLE:
enable.enable = 0;
break;
default:
dprintk(VIDC_ERR,
"Invalid H264 8x8 transform control value %d\n",
ctrl->val);
rc = -ENOTSUPP;
break;
}
pdata = &enable;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE:
property_id = HAL_PARAM_VENC_IFRAMESIZE_TYPE;
iframesize_type = venc_v4l2_to_hal(
V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE,
ctrl->val);
pdata = &iframesize_type;
break;
default:
dprintk(VIDC_ERR, "Unsupported index: %x\n", ctrl->id);
rc = -ENOTSUPP;
break;
}
v4l2_ctrl_lock(ctrl);
if (!rc && property_id) {
dprintk(VIDC_DBG, "Control: HAL property=%x,ctrl_value=%d\n",
property_id,
ctrl->val);
rc = call_hfi_op(hdev, session_set_property,
(void *)inst->session, property_id, pdata);
}
return rc;
}