camera: Add multiplanar support in postprocessing.
The current postprocessing framework uses single
planar structures. Change the data structures
to support multiplanar image formats.
Change-Id: I27dc6f4c544a4a628bbf2b073d6abd899450a396
Signed-off-by: Kiran Kumar H N <hurlisal@codeaurora.org>
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
index 4f82d32..a09514b 100644
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -57,9 +57,8 @@
/* Copy the divert frame struct into event ctrl struct. */
isp_event->isp_data.div_frame = *div;
- D("%s inst=%p, img_mode=%d, frame_id=%d,phy=0x%x,len=%d\n",
- __func__, pcam_inst, pcam_inst->image_mode, div->frame_id,
- (uint32_t)div->phy_addr, div->length);
+ D("%s inst=%p, img_mode=%d, frame_id=%d\n", __func__,
+ pcam_inst, pcam_inst->image_mode, div->frame.frame_id);
v4l2_event_queue(
pmctl->config_device->config_stat_event_queue.pvdev,
&v4l2_evt);
@@ -119,7 +118,7 @@
uint32_t frame_id, int pp_type)
{
struct msm_cam_v4l2_dev_inst *pcam_inst;
- int idx, rc = 0;
+ int idx, rc = 0, i, buf_idx;
int del_buf = 0; /* delete from free queue */
struct msm_cam_evt_divert_frame div;
struct msm_frame_buffer *vb = NULL;
@@ -132,32 +131,61 @@
del_buf, msg_type, fbuf);
if (!vb)
return -EINVAL;
+
vb->vidbuf.v4l2_buf.sequence = frame_id;
- mem = vb2_plane_cookie(&vb->vidbuf, 0);
+ buf_idx = vb->vidbuf.v4l2_buf.index;
div.image_mode = pcam_inst->image_mode;
div.op_mode = pcam_inst->pcam->op_mode;
div.inst_idx = pcam_inst->my_index;
div.node_idx = pcam_inst->pcam->vnode_id;
- div.phy_addr =
- videobuf2_to_pmem_contig(&vb->vidbuf, 0);
- div.phy_offset = mem->addr_offset;
- div.y_off = 0;
- div.cbcr_off = mem->offset.sp_off.cbcr_off;
- div.fd = (int)mem->vaddr;
- div.vb = (uint32_t)vb;
p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode]++;
if (p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode] == 0)
p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode]++;
- div.frame_id =
+ div.frame.frame_id =
p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode];
- div.path = mem->path;
- div.length = mem->size;
- msm_mctl_gettimeofday(&div.timestamp);
- vb->vidbuf.v4l2_buf.timestamp = div.timestamp;
+ div.frame.handle = (uint32_t)vb;
+ msm_mctl_gettimeofday(&div.frame.timestamp);
+ vb->vidbuf.v4l2_buf.timestamp = div.frame.timestamp;
div.do_pp = pp_type;
- if (!pp_type) {
- p_mctl->pp_info.div_frame[pcam_inst->image_mode].ch_paddr[0] =
- div.phy_addr;
+ /* Get the cookie for 1st plane and store the path.
+ * Also use this to check the number of planes in
+ * this buffer.*/
+ mem = vb2_plane_cookie(&vb->vidbuf, 0);
+ div.frame.path = mem->path;
+ if (mem->buffer_type == VIDEOBUF2_SINGLE_PLANE) {
+ /* This buffer contains only 1 plane. Use the
+ * single planar structure to store the info.*/
+ div.frame.num_planes = 1;
+ div.frame.sp.phy_addr =
+ videobuf2_to_pmem_contig(&vb->vidbuf, 0);
+ div.frame.sp.addr_offset = mem->addr_offset;
+ div.frame.sp.y_off = 0;
+ div.frame.sp.cbcr_off = mem->offset.sp_off.cbcr_off;
+ div.frame.sp.fd = (int)mem->vaddr;
+ div.frame.sp.length = mem->size;
+ if (!pp_type)
+ p_mctl->pp_info.div_frame[pcam_inst->image_mode].
+ ch_paddr[0] = div.frame.sp.phy_addr;
+ } else {
+ /* This buffer contains multiple planes. Use the mutliplanar
+ * structure to store the info. */
+ div.frame.num_planes = pcam_inst->plane_info.num_planes;
+ /* Now traverse through all the planes of the buffer to
+ * fill out the plane info. */
+ for (i = 0; i < div.frame.num_planes; i++) {
+ mem = vb2_plane_cookie(&vb->vidbuf, i);
+ div.frame.mp[i].phy_addr =
+ videobuf2_to_pmem_contig(&vb->vidbuf, i);
+ div.frame.mp[i].data_offset =
+ pcam_inst->buf_offset[buf_idx][i].data_offset;
+ div.frame.mp[i].addr_offset =
+ mem->addr_offset;
+ div.frame.mp[i].fd = (int)mem->vaddr;
+ div.frame.mp[i].length = mem->size;
+ }
+ if (!pp_type)
+ p_mctl->pp_info.div_frame[pcam_inst->image_mode].
+ ch_paddr[0] = div.frame.mp[0].phy_addr;
}
rc = msm_mctl_pp_buf_divert(p_mctl, pcam_inst, &div);
return rc;
@@ -622,7 +650,7 @@
if (copy_from_user(&frame, arg,
sizeof(struct msm_cam_evt_divert_frame)))
return -EFAULT;
- switch (frame.path) {
+ switch (frame.frame.path) {
case OUTPUT_TYPE_P:
msg_type = VFE_MSG_OUTPUT_P;
image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
@@ -642,8 +670,8 @@
}
rc = msm_mctl_reserve_free_buf(p_mctl, msg_type, &free_buf);
if (rc == 0) {
- frame.phy_addr = free_buf.ch_paddr[0];
- frame.vb = free_buf.vb;
+ frame.frame.sp.phy_addr = free_buf.ch_paddr[0];
+ frame.frame.handle = free_buf.vb;
if (copy_to_user((void *)arg,
&frame,
sizeof(frame))) {
@@ -667,7 +695,7 @@
if (copy_from_user(&frame, arg,
sizeof(struct msm_cam_evt_divert_frame)))
return -EFAULT;
- switch (frame.path) {
+ switch (frame.frame.path) {
case OUTPUT_TYPE_P:
msg_type = VFE_MSG_OUTPUT_P;
image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
@@ -685,7 +713,7 @@
rc = -EFAULT;
return rc;
}
- free_buf.ch_paddr[0] = frame.phy_addr;
+ free_buf.ch_paddr[0] = frame.frame.sp.phy_addr;
rc = msm_mctl_release_free_buf(p_mctl, msg_type, &free_buf);
D("%s: release free buf, rc = %d, phy = 0x%x",
__func__, rc, free_buf.ch_paddr[0]);
@@ -713,7 +741,7 @@
struct msm_cam_media_controller *p_mctl,
void __user *arg)
{
- struct msm_frame frame;
+ struct msm_pp_frame frame;
int msg_type, image_mode, rc = 0;
int dirty = 0;
struct msm_free_buf buf;
@@ -721,6 +749,7 @@
if (copy_from_user(&frame, arg, sizeof(frame)))
return -EFAULT;
+
spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
switch (frame.path) {
case OUTPUT_TYPE_P:
@@ -751,8 +780,12 @@
/* dirty frame. should not pass to app */
dirty = 1;
}
- } else
- buf.ch_paddr[0] = frame.buffer;
+ } else {
+ if (frame.num_planes > 1)
+ buf.ch_paddr[0] = frame.mp[0].phy_addr;
+ else
+ buf.ch_paddr[0] = frame.sp.phy_addr;
+ }
spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
/* here buf.addr is phy_addr */
rc = msm_mctl_buf_done_pp(p_mctl, msg_type, &buf, dirty);
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index befd768..1ebbf88 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -221,22 +221,52 @@
void *data;
};
+struct msm_pp_frame_sp {
+ /* phy addr of the buffer */
+ unsigned long phy_addr;
+ uint32_t y_off;
+ uint32_t cbcr_off;
+ /* buffer length */
+ uint32_t length;
+ int32_t fd;
+ uint32_t addr_offset;
+ /* mapped addr */
+ unsigned long vaddr;
+};
+
+struct msm_pp_frame_mp {
+ /* phy addr of the plane */
+ unsigned long phy_addr;
+ /* offset of plane data */
+ uint32_t data_offset;
+ /* plane length */
+ uint32_t length;
+ int32_t fd;
+ uint32_t addr_offset;
+ /* mapped addr */
+ unsigned long vaddr;
+};
+
+struct msm_pp_frame {
+ uint32_t handle; /* stores vb cookie */
+ uint32_t frame_id;
+ int path;
+ unsigned short image_type;
+ unsigned short num_planes; /* 1 for sp */
+ struct timeval timestamp;
+ union {
+ struct msm_pp_frame_sp sp;
+ struct msm_pp_frame_mp mp[MAX_PLANES];
+ };
+};
+
struct msm_cam_evt_divert_frame {
unsigned short image_mode;
unsigned short op_mode;
unsigned short inst_idx;
unsigned short node_idx;
- unsigned long phy_addr;
- uint32_t phy_offset;
- uint32_t y_off;
- uint32_t cbcr_off;
- int32_t fd;
- uint32_t frame_id;
- int path;
- uint32_t length;
- struct timeval timestamp;
+ struct msm_pp_frame frame;
int do_pp;
- uint32_t vb;
};
struct msm_mctl_pp_cmd_ack_event {
@@ -471,25 +501,6 @@
#define MSM_PLANE_Y 0
#define MSM_PLANE_UV 1
-struct msm_buffer_plane {
- int type;
- uint32_t offset;
- uint32_t length;
- uint32_t error;
- unsigned long buffer;
- unsigned long addr;
- uint32_t addr_offset;
- int fd;
-};
-struct msm_buffer {
- struct timeval timestamp;
- int memory_type;
- uint32_t frame_id;
- int path;
- int num;
- struct msm_buffer_plane planes[MSM_PLANE_MAX];
-};
-
struct msm_frame {
struct timespec ts;
int path;
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index f6668ef..b7fd30f 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -273,33 +273,5 @@
/* TBD: 3D related */
};
-struct msm_pp_frame_sp {
- unsigned long phy_addr;
- uint32_t y_off;
- uint32_t cbcr_off;
- uint32_t length;
- int32_t fd;
- uint32_t addr_offset;
-};
-
-struct msm_pp_frame_mp {
- unsigned long phy_addr;
- uint32_t data_offset;
- uint32_t length;
- int32_t fd;
- uint32_t addr_offset;
-};
-
-struct msm_pp_frame {
- uint32_t handle;
- uint32_t frame_id;
- unsigned short image_type;
- unsigned short num_planes; /* 1 for sp */
- struct timeval timestamp;
- union {
- struct msm_pp_frame_sp sp;
- };
-};
-
#endif /*__MSM_ISP_H__*/