From c546ca55edbea67327fee6a70286bd1eb2fdac37 Mon Sep 17 00:00:00 2001 From: Vinay Kalia Date: Wed, 9 Jan 2013 19:27:43 -0800 Subject: [PATCH] msm: vidc: Convey stride/scanline information Video stride and scanlines are conveyed to client in this change. This information is needed by client to render the video properly. Change-Id: I3dbbc78843ab521691e9998a872266c6dc7e4b8c Signed-off-by: Vinay Kalia --- drivers/media/video/msm_vidc/msm_vdec.c | 29 +++++++++++++++++++-- drivers/media/video/msm_vidc/venus_hfi.c | 8 ++++++ drivers/media/video/msm_vidc/vidc_hfi.h | 1 + drivers/media/video/msm_vidc/vidc_hfi_api.h | 2 ++ include/media/msm_media_info.h | 14 +++++----- 5 files changed, 45 insertions(+), 9 deletions(-) diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c index 24407dd08ea..b10787c9d49 100644 --- a/drivers/media/video/msm_vidc/msm_vdec.c +++ b/drivers/media/video/msm_vidc/msm_vdec.c @@ -578,15 +578,18 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) { const struct msm_vidc_format *fmt = NULL; struct hal_frame_size frame_sz; + struct hfi_device *hdev; + int stride, scanlines; int extra_idx = 0; int rc = 0; int ret; int i; - if (!inst || !f) { + if (!inst || !f || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, "Invalid input, inst = %p, format = %p\n", inst, f); return -EINVAL; } + hdev = inst->core->device; if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) fmt = inst->fmts[CAPTURE_PORT]; else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) @@ -601,6 +604,8 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) } f->fmt.pix_mp.height = inst->prop.height; f->fmt.pix_mp.width = inst->prop.width; + stride = inst->prop.width; + scanlines = inst->prop.height; frame_sz.buffer_type = HAL_BUFFER_OUTPUT; frame_sz.width = inst->prop.width; frame_sz.height = inst->prop.height; @@ -620,6 +625,16 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) f->fmt.pix_mp.plane_fmt[i].sizeimage; } } else { + switch (fmt->fourcc) { + case V4L2_PIX_FMT_NV12: + hdev->get_stride_scanline(COLOR_FMT_NV12, + inst->prop.width, inst->prop.height, + &stride, &scanlines); + break; + default: + dprintk(VIDC_WARN, + "Color format not recognized\n"); + } f->fmt.pix_mp.plane_fmt[0].sizeimage = inst->buff_req.buffer[HAL_BUFFER_OUTPUT].buffer_size; extra_idx = EXTRADATA_IDX(fmt->num_planes); @@ -631,7 +646,17 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) inst->bufq[CAPTURE_PORT]. vb2_bufq.plane_sizes[i] = f->fmt.pix_mp.plane_fmt[i].sizeimage; - + } + if (stride && scanlines) { + f->fmt.pix_mp.plane_fmt[0].bytesperline = + (__u16)stride; + f->fmt.pix_mp.plane_fmt[0].reserved[0] = + (__u16)scanlines; + } else { + f->fmt.pix_mp.plane_fmt[0].bytesperline = + (__u16)inst->prop.width; + f->fmt.pix_mp.plane_fmt[0].reserved[0] = + (__u16)inst->prop.height; } } else { dprintk(VIDC_ERR, diff --git a/drivers/media/video/msm_vidc/venus_hfi.c b/drivers/media/video/msm_vidc/venus_hfi.c index 015ed115e09..9e5795b44b0 100644 --- a/drivers/media/video/msm_vidc/venus_hfi.c +++ b/drivers/media/video/msm_vidc/venus_hfi.c @@ -2868,6 +2868,13 @@ static int venus_hfi_get_fw_info(void *dev, enum fw_info info) return rc; } +int venus_hfi_get_stride_scanline(int color_fmt, + int width, int height, int *stride, int *scanlines) { + *stride = VENUS_Y_STRIDE(color_fmt, width); + *scanlines = VENUS_Y_SCANLINES(color_fmt, height); + return 0; +} + static void *venus_hfi_add_device(u32 device_id, struct platform_device *pdev, void (*callback) (enum command_response cmd, void *data)) { @@ -3005,6 +3012,7 @@ static void venus_init_hfi_callbacks(struct hfi_device *hdev) hdev->load_fw = venus_hfi_load_fw; hdev->unload_fw = venus_hfi_unload_fw; hdev->get_fw_info = venus_hfi_get_fw_info; + hdev->get_stride_scanline = venus_hfi_get_stride_scanline; } int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id, diff --git a/drivers/media/video/msm_vidc/vidc_hfi.h b/drivers/media/video/msm_vidc/vidc_hfi.h index 6ff09212c92..c82f6651664 100644 --- a/drivers/media/video/msm_vidc/vidc_hfi.h +++ b/drivers/media/video/msm_vidc/vidc_hfi.h @@ -13,6 +13,7 @@ #ifndef __H_VIDC_HFI_H__ #define __H_VIDC_HFI_H__ +#include #include "vidc_hfi_helper.h" #include "vidc_hfi_api.h" diff --git a/drivers/media/video/msm_vidc/vidc_hfi_api.h b/drivers/media/video/msm_vidc/vidc_hfi_api.h index 370785cb8f0..27b145072d5 100644 --- a/drivers/media/video/msm_vidc/vidc_hfi_api.h +++ b/drivers/media/video/msm_vidc/vidc_hfi_api.h @@ -1050,6 +1050,8 @@ struct hfi_device { int (*load_fw)(void *dev); void (*unload_fw)(void *dev); int (*get_fw_info)(void *dev, enum fw_info info); + int (*get_stride_scanline)(int color_fmt, int width, + int height, int *stride, int *scanlines); }; typedef void (*hfi_cmd_response_callback) (enum command_response cmd, diff --git a/include/media/msm_media_info.h b/include/media/msm_media_info.h index ab76d7901d9..993a4ab7133 100644 --- a/include/media/msm_media_info.h +++ b/include/media/msm_media_info.h @@ -1,8 +1,8 @@ #ifndef __MEDIA_INFO_H__ #define __MEDIA_INFO_H__ -#ifndef ALIGN -#define ALIGN(__sz, __align) (((__sz) + (__align-1)) & (~(__align-1))) +#ifndef MSM_MEDIA_ALIGN +#define MSM_MEDIA_ALIGN(__sz, __align) (((__sz) + (__align-1)) & (~(__align-1))) #endif enum color_fmts { @@ -18,7 +18,7 @@ static inline unsigned int VENUS_Y_STRIDE(int color_fmt, int width) switch (color_fmt) { case COLOR_FMT_NV12: alignment = 128; - stride = ALIGN(width, alignment); + stride = MSM_MEDIA_ALIGN(width, alignment); break; default: break; @@ -36,7 +36,7 @@ static inline unsigned int VENUS_UV_STRIDE(int color_fmt, int width) switch (color_fmt) { case COLOR_FMT_NV12: alignment = 128; - stride = ALIGN(width, alignment); + stride = MSM_MEDIA_ALIGN(width, alignment); break; default: break; @@ -54,7 +54,7 @@ static inline unsigned int VENUS_Y_SCANLINES(int color_fmt, int height) switch (color_fmt) { case COLOR_FMT_NV12: alignment = 32; - sclines = ALIGN(height, alignment); + sclines = MSM_MEDIA_ALIGN(height, alignment); break; default: break; @@ -72,7 +72,7 @@ static inline unsigned int VENUS_UV_SCANLINES(int color_fmt, int height) switch (color_fmt) { case COLOR_FMT_NV12: alignment = 16; - sclines = ALIGN(((height + 1) >> 1), alignment); + sclines = MSM_MEDIA_ALIGN(((height + 1) >> 1), alignment); break; default: break; @@ -101,7 +101,7 @@ static inline unsigned int VENUS_BUFFER_SIZE( y_plane = y_stride * y_sclines; uv_plane = uv_stride * uv_sclines + uv_alignment; size = y_plane + uv_plane; - size = ALIGN(size, 4096); + size = MSM_MEDIA_ALIGN(size, 4096); break; default: break;