aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2013-09-16 17:21:49 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2013-09-16 17:21:47 -0700
commiteff0a75a366a4c0bb6ded3d775194b51eea29c8f (patch)
tree1262973966569e9865151ccbbeb2842270e95acb
parent8899bb86607abb1b9ffe46ffe18954c884940ffe (diff)
parent94f4085efd7d8f73f1c5632bbb4600a50e4046b6 (diff)
Merge "msm: vidc: Add support for encoder rotation"
-rw-r--r--drivers/media/platform/msm/vidc/hfi_packetization.c43
-rw-r--r--drivers/media/platform/msm/vidc/msm_venc.c54
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_internal.h1
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.c9
-rw-r--r--drivers/media/platform/msm/vidc/vidc_hfi_api.h9
-rw-r--r--drivers/media/platform/msm/vidc/vidc_hfi_helper.h5
6 files changed, 120 insertions, 1 deletions
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 1dccf36233f..458f5390da7 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -1175,7 +1175,50 @@ int create_pkt_cmd_session_set_property(
break;
}
case HAL_CONFIG_VPE_OPERATIONS:
+ {
+ struct hfi_operations_type *hfi;
+ struct hal_operations *prop =
+ (struct hal_operations *) pdata;
+ pkt->rg_property_data[0] = HFI_PROPERTY_CONFIG_VPE_OPERATIONS;
+ hfi = (struct hfi_operations_type *) &pkt->rg_property_data[1];
+ switch (prop->rotate) {
+ case HAL_ROTATE_NONE:
+ hfi->rotation = HFI_ROTATE_NONE;
+ break;
+ case HAL_ROTATE_90:
+ hfi->rotation = HFI_ROTATE_90;
+ break;
+ case HAL_ROTATE_180:
+ hfi->rotation = HFI_ROTATE_180;
+ break;
+ case HAL_ROTATE_270:
+ hfi->rotation = HFI_ROTATE_270;
+ break;
+ default:
+ dprintk(VIDC_ERR, "Invalid rotation setting: 0x%x",
+ prop->rotate);
+ rc = -EINVAL;
+ break;
+ }
+ switch (prop->flip) {
+ case HAL_FLIP_NONE:
+ hfi->flip = HFI_FLIP_NONE;
+ break;
+ case HAL_FLIP_HORIZONTAL:
+ hfi->flip = HFI_FLIP_HORIZONTAL;
+ break;
+ case HAL_FLIP_VERTICAL:
+ hfi->flip = HFI_FLIP_VERTICAL;
+ break;
+ default:
+ dprintk(VIDC_ERR, "Invalid flip setting: 0x%x",
+ prop->flip);
+ rc = -EINVAL;
+ break;
+ }
+ pkt->size += sizeof(u32) + sizeof(struct hfi_operations_type);
break;
+ }
case HAL_PARAM_VENC_INTRA_REFRESH:
{
struct hfi_intra_refresh *hfi;
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 2d0f713fc11..d0a2964813a 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -1240,6 +1240,19 @@ static inline int venc_v4l2_to_hal(int id, int value)
default:
goto unknown_value;
}
+ case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION:
+ switch (value) {
+ case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE:
+ return HAL_ROTATE_NONE;
+ case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90:
+ return HAL_ROTATE_90;
+ case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180:
+ return HAL_ROTATE_180;
+ case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270:
+ return HAL_ROTATE_270;
+ default:
+ goto unknown_value;
+ }
}
unknown_value:
@@ -1558,9 +1571,19 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
pdata = &profile_level;
break;
case V4L2_CID_MPEG_VIDC_VIDEO_ROTATION:
+ if (!(inst->capability.pixelprocess_capabilities &
+ HAL_VIDEO_ENCODER_ROTATION_CAPABILITY)) {
+ dprintk(VIDC_ERR, "Rotation not supported: 0x%x",
+ ctrl->id);
+ rc = -ENOTSUPP;
+ break;
+ }
property_id =
HAL_CONFIG_VPE_OPERATIONS;
- operations.rotate = ctrl->val;
+ 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: {
@@ -1936,8 +1959,16 @@ static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
{
int rc = 0, c = 0;
+ struct hfi_device *hdev;
+
struct msm_vidc_inst *inst = container_of(ctrl->handler,
struct msm_vidc_inst, ctrl_handler);
+
+ if (!inst || !inst->core || !inst->core->device) {
+ dprintk(VIDC_ERR, "%s invalid parameters", __func__);
+ return -EINVAL;
+ }
+
rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
if (rc) {
@@ -1946,6 +1977,10 @@ static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
goto failed_open_done;
}
+ hdev = inst->core->device;
+ inst->capability.pixelprocess_capabilities =
+ call_hfi_op(hdev, get_core_capabilities);
+
for (c = 0; c < ctrl->ncontrols; ++c) {
if (ctrl->cluster[c]->is_new) {
struct v4l2_ctrl *temp = ctrl->cluster[c];
@@ -1993,6 +2028,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
inst->prop.height = DEFAULT_HEIGHT;
inst->prop.width = DEFAULT_WIDTH;
inst->prop.fps = 15;
+ inst->capability.pixelprocess_capabilities = 0;
return rc;
}
@@ -2188,6 +2224,8 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
rc = -EINVAL;
goto exit;
}
+ inst->prop.width = f->fmt.pix_mp.width;
+ inst->prop.height = f->fmt.pix_mp.height;
} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
struct hal_uncompressed_format_select hal_fmt = {0};
struct hal_frame_size frame_sz;
@@ -2264,11 +2302,25 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
}
inst->fmts[fmt->type] = fmt;
if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ struct hal_frame_size frame_sz;
rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
if (rc) {
dprintk(VIDC_ERR, "Failed to open instance\n");
goto exit;
}
+ inst->capability.pixelprocess_capabilities =
+ call_hfi_op(hdev, get_core_capabilities);
+ frame_sz.width = inst->prop.width;
+ frame_sz.height = inst->prop.height;
+ frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
+ rc = call_hfi_op(hdev, session_set_property,
+ (void *)inst->session, HAL_PARAM_FRAME_SIZE,
+ &frame_sz);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to set OUTPUT framesize\n");
+ goto exit;
+ }
}
} else {
dprintk(VIDC_ERR, "Buf type not recognized, type = %d\n",
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 15f4e3ffd77..16545b3080e 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -177,6 +177,7 @@ struct msm_vidc_core_capability {
struct hal_capability_supported width;
struct hal_capability_supported height;
struct hal_capability_supported frame_rate;
+ u32 pixelprocess_capabilities;
u32 capability_set;
};
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index aaf1f50754d..b3034f39603 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -3288,6 +3288,14 @@ int venus_hfi_get_stride_scanline(int color_fmt,
return 0;
}
+int venus_hfi_get_core_capabilities(void)
+{
+ return HAL_VIDEO_ENCODER_ROTATION_CAPABILITY |
+ HAL_VIDEO_ENCODER_SCALING_CAPABILITY |
+ HAL_VIDEO_ENCODER_DEINTERLACE_CAPABILITY |
+ HAL_VIDEO_DECODER_MULTI_STREAM_CAPABILITY;
+}
+
int venus_hfi_capability_check(u32 fourcc, u32 width,
u32 *max_width, u32 *max_height)
{
@@ -3460,6 +3468,7 @@ static void venus_init_hfi_callbacks(struct hfi_device *hdev)
hdev->get_fw_info = venus_hfi_get_fw_info;
hdev->get_stride_scanline = venus_hfi_get_stride_scanline;
hdev->capability_check = venus_hfi_capability_check;
+ hdev->get_core_capabilities = venus_hfi_get_core_capabilities;
}
int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id,
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 6a5f2b15e96..83dcded7a71 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -188,6 +188,14 @@ enum hal_domain {
HAL_UNUSED_DOMAIN = 0x10000000,
};
+enum hal_core_capabilities {
+ HAL_VIDEO_ENCODER_ROTATION_CAPABILITY = 0x00000001,
+ HAL_VIDEO_ENCODER_SCALING_CAPABILITY = 0x00000002,
+ HAL_VIDEO_ENCODER_DEINTERLACE_CAPABILITY = 0x00000004,
+ HAL_VIDEO_DECODER_MULTI_STREAM_CAPABILITY = 0x00000008,
+ HAL_VIDEO_UNUSED_CAPABILITY = 0x10000000,
+};
+
enum hal_video_codec {
HAL_VIDEO_CODEC_UNKNOWN = 0x00000000,
HAL_VIDEO_CODEC_MVC = 0x00000001,
@@ -1110,6 +1118,7 @@ struct hfi_device {
int (*capability_check)(u32 fourcc, u32 width,
u32 *max_width, u32 *max_height);
int (*session_clean)(void *sess);
+ int (*get_core_capabilities)(void);
};
typedef void (*hfi_cmd_response_callback) (enum command_response cmd,
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index c25c3c3e221..f5180a4970c 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -439,6 +439,11 @@ struct hfi_idr_period {
u32 idr_period;
};
+struct hfi_operations_type {
+ u32 rotation;
+ u32 flip;
+};
+
struct hfi_max_num_b_frames {
u32 max_num_b_frames;
};