From 16e46bf7a5f563ad144ea26747a77d7b9e1a3640 Mon Sep 17 00:00:00 2001 From: Alan Kwong Date: Thu, 10 Nov 2016 01:39:16 -0500 Subject: msm: sde: add compression ratio support to v4l2 rotator Current v4l2 rotator does not support compression ratio for user buffer. This patch add new uapi for get/set compression ratio for v4l2 buffer. CRs-Fixed: 1088736 Change-Id: I15ed94a8b505a7bae4d7ad31fd4ad1be240d75d6 Signed-off-by: Alan Kwong --- .../platform/msm/sde/rotator/sde_rotator_dev.c | 102 ++++++++++++++++++++- .../platform/msm/sde/rotator/sde_rotator_dev.h | 2 + include/uapi/media/msm_sde_rotator.h | 19 ++++ 3 files changed, 119 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c index 08075ae90507..a929e4db8f07 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c @@ -121,6 +121,25 @@ static void sde_rotator_get_config_from_ctx(struct sde_rotator_ctx *ctx, config->output.format = ctx->format_cap.fmt.pix.pixelformat; config->output.comp_ratio.numer = 1; config->output.comp_ratio.denom = 1; + + /* + * Use compression ratio of the first buffer to estimate + * performance requirement of the session. If core layer does + * not support dynamic per buffer compression ratio recalculation, + * this configuration will determine the overall static compression + * ratio of the session. + */ + if (ctx->vbinfo_out) + config->input.comp_ratio = ctx->vbinfo_out[0].comp_ratio; + if (ctx->vbinfo_cap) + config->output.comp_ratio = ctx->vbinfo_cap[0].comp_ratio; + + SDEDEV_DBG(ctx->rot_dev->dev, "config s:%d out_cr:%u/%u cap_cr:%u/%u\n", + ctx->session_id, + config->input.comp_ratio.numer, + config->input.comp_ratio.denom, + config->output.comp_ratio.numer, + config->output.comp_ratio.denom); } /* @@ -272,8 +291,11 @@ static int sde_rotator_queue_setup(struct vb2_queue *q, ctx->nbuf_out, GFP_KERNEL); if (!ctx->vbinfo_out) return -ENOMEM; - for (i = 0; i < ctx->nbuf_out; i++) + for (i = 0; i < ctx->nbuf_out; i++) { ctx->vbinfo_out[i].fd = -1; + ctx->vbinfo_out[i].comp_ratio.numer = 1; + ctx->vbinfo_out[i].comp_ratio.denom = 1; + } break; case V4L2_BUF_TYPE_VIDEO_CAPTURE: ctx->nbuf_cap = *num_buffers; @@ -282,8 +304,11 @@ static int sde_rotator_queue_setup(struct vb2_queue *q, ctx->nbuf_cap, GFP_KERNEL); if (!ctx->vbinfo_cap) return -ENOMEM; - for (i = 0; i < ctx->nbuf_cap; i++) + for (i = 0; i < ctx->nbuf_cap; i++) { ctx->vbinfo_cap[i].fd = -1; + ctx->vbinfo_cap[i].comp_ratio.numer = 1; + ctx->vbinfo_cap[i].comp_ratio.denom = 1; + } break; default: return -EINVAL; @@ -1688,6 +1713,7 @@ static long sde_rotator_private_ioctl(struct file *file, void *fh, sde_rotator_ctx_from_fh(file->private_data); struct sde_rotator_device *rot_dev = ctx->rot_dev; struct msm_sde_rotator_fence *fence = arg; + struct msm_sde_rotator_comp_ratio *comp_ratio = arg; struct sde_rotator_vbinfo *vbinfo; switch (cmd) { @@ -1766,6 +1792,52 @@ static long sde_rotator_private_ioctl(struct file *file, void *fh, ctx->session_id, fence->index, fence->fd); break; + case VIDIOC_S_SDE_ROTATOR_COMP_RATIO: + if (!comp_ratio) + return -EINVAL; + else if (!comp_ratio->numer || !comp_ratio->denom) + return -EINVAL; + else if (comp_ratio->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && + comp_ratio->index < ctx->nbuf_out) + vbinfo = &ctx->vbinfo_out[comp_ratio->index]; + else if (comp_ratio->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && + comp_ratio->index < ctx->nbuf_cap) + vbinfo = &ctx->vbinfo_cap[comp_ratio->index]; + else + return -EINVAL; + + vbinfo->comp_ratio.numer = comp_ratio->numer; + vbinfo->comp_ratio.denom = comp_ratio->denom; + + SDEDEV_DBG(rot_dev->dev, + "VIDIOC_S_SDE_ROTATOR_COMP_RATIO s:%d i:%d t:%d cr:%u/%u\n", + ctx->session_id, comp_ratio->index, + comp_ratio->type, + vbinfo->comp_ratio.numer, + vbinfo->comp_ratio.denom); + break; + case VIDIOC_G_SDE_ROTATOR_COMP_RATIO: + if (!comp_ratio) + return -EINVAL; + else if (comp_ratio->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && + comp_ratio->index < ctx->nbuf_out) + vbinfo = &ctx->vbinfo_out[comp_ratio->index]; + else if (comp_ratio->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && + comp_ratio->index < ctx->nbuf_cap) + vbinfo = &ctx->vbinfo_cap[comp_ratio->index]; + else + return -EINVAL; + + comp_ratio->numer = vbinfo->comp_ratio.numer; + comp_ratio->denom = vbinfo->comp_ratio.denom; + + SDEDEV_DBG(rot_dev->dev, + "VIDIOC_G_SDE_ROTATOR_COMP_RATIO s:%d i:%d t:%d cr:%u/%u\n", + ctx->session_id, comp_ratio->index, + comp_ratio->type, + comp_ratio->numer, + comp_ratio->denom); + break; default: SDEDEV_WARN(rot_dev->dev, "invalid ioctl type %x\n", cmd); return -ENOTTY; @@ -1805,6 +1877,24 @@ static long sde_rotator_compat_ioctl32(struct file *file, break; } + case VIDIOC_S_SDE_ROTATOR_COMP_RATIO: + case VIDIOC_G_SDE_ROTATOR_COMP_RATIO: + { + struct msm_sde_rotator_comp_ratio comp_ratio; + + if (copy_from_user(&comp_ratio, (void __user *)arg, + sizeof(struct msm_sde_rotator_comp_ratio))) + return -EFAULT; + + ret = sde_rotator_private_ioctl(file, file->private_data, + 0, cmd, (void *)&comp_ratio); + + if (copy_to_user((void __user *)arg, &comp_ratio, + sizeof(struct msm_sde_rotator_comp_ratio))) + return -EFAULT; + + break; + } default: ret = -ENOIOCTLCMD; break; @@ -1949,13 +2039,15 @@ static int sde_rotator_process_buffers(struct sde_rotator_ctx *ctx, vbinfo_cap = &ctx->vbinfo_cap[dst_buf->index]; SDEDEV_DBG(rot_dev->dev, - "process buffer s:%d.%u src:(%u,%u,%u,%u) dst:(%u,%u,%u,%u) rot:%d flip:%d/%d sec:%d\n", + "process buffer s:%d.%u src:(%u,%u,%u,%u) dst:(%u,%u,%u,%u) rot:%d flip:%d/%d sec:%d src_cr:%u/%u dst_cr:%u/%u\n", ctx->session_id, vbinfo_cap->fence_ts, ctx->crop_out.left, ctx->crop_out.top, ctx->crop_out.width, ctx->crop_out.height, ctx->crop_cap.left, ctx->crop_cap.top, ctx->crop_cap.width, ctx->crop_cap.height, - ctx->rotate, ctx->hflip, ctx->vflip, ctx->secure); + ctx->rotate, ctx->hflip, ctx->vflip, ctx->secure, + vbinfo_out->comp_ratio.numer, vbinfo_out->comp_ratio.denom, + vbinfo_cap->comp_ratio.numer, vbinfo_cap->comp_ratio.denom); /* allocate slot for timestamp */ ts = stats->ts[stats->count++ % SDE_ROTATOR_NUM_EVENTS]; @@ -2014,11 +2106,13 @@ static int sde_rotator_process_buffers(struct sde_rotator_ctx *ctx, item.input.planes[0].stride = ctx->format_out.fmt.pix.bytesperline; item.input.plane_count = 1; item.input.fence = NULL; + item.input.comp_ratio = vbinfo_out->comp_ratio; item.output.planes[0].buffer = dst_handle->buffer; item.output.planes[0].offset = dst_handle->addr; item.output.planes[0].stride = ctx->format_cap.fmt.pix.bytesperline; item.output.plane_count = 1; item.output.fence = NULL; + item.output.comp_ratio = vbinfo_cap->comp_ratio; item.sequence_id = vbinfo_cap->fence_ts; item.ts = ts; diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.h index f3c904817296..1b73be79eec3 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.h +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.h @@ -66,6 +66,7 @@ struct sde_rotator_buf_handle { * @fence_ts: completion timestamp associated with fd * @qbuf_ts: timestamp associated with buffer queue event * @dqbuf_ts: Pointer to timestamp associated with buffer dequeue event + * @comp_ratio: compression ratio of this buffer */ struct sde_rotator_vbinfo { int fd; @@ -73,6 +74,7 @@ struct sde_rotator_vbinfo { u32 fence_ts; ktime_t qbuf_ts; ktime_t *dqbuf_ts; + struct sde_mult_factor comp_ratio; }; /* diff --git a/include/uapi/media/msm_sde_rotator.h b/include/uapi/media/msm_sde_rotator.h index 12976e3f14d7..1c41418b9fcf 100644 --- a/include/uapi/media/msm_sde_rotator.h +++ b/include/uapi/media/msm_sde_rotator.h @@ -77,11 +77,30 @@ struct msm_sde_rotator_fence { __u32 reserved[5]; }; +/** +* struct msm_sde_rotator_comp_ratio - v4l2 buffer compression ratio +* @index: id number of the buffer +* @type: enum v4l2_buf_type; buffer type +* @numer: numerator of the ratio +* @denom: denominator of the ratio +**/ +struct msm_sde_rotator_comp_ratio { + __u32 index; + __u32 type; + __u32 numer; + __u32 denom; + __u32 reserved[4]; +}; + /* SDE Rotator private ioctl ID */ #define VIDIOC_G_SDE_ROTATOR_FENCE \ _IOWR('V', BASE_VIDIOC_PRIVATE + 10, struct msm_sde_rotator_fence) #define VIDIOC_S_SDE_ROTATOR_FENCE \ _IOWR('V', BASE_VIDIOC_PRIVATE + 11, struct msm_sde_rotator_fence) +#define VIDIOC_G_SDE_ROTATOR_COMP_RATIO \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 12, struct msm_sde_rotator_comp_ratio) +#define VIDIOC_S_SDE_ROTATOR_COMP_RATIO \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 13, struct msm_sde_rotator_comp_ratio) /* SDE Rotator private control ID's */ #define V4L2_CID_SDE_ROTATOR_SECURE (V4L2_CID_USER_BASE + 0x1000) -- cgit v1.2.3