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 bffba30c6e7..5168b7aa5af 100644 --- a/drivers/media/video/msm_vidc/venus_hfi.c +++ b/drivers/media/video/msm_vidc/venus_hfi.c @@ -2996,6 +2996,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)) { @@ -3134,6 +3141,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 e12153a42d5..54282671f6c 100644 --- a/drivers/media/video/msm_vidc/vidc_hfi_api.h +++ b/drivers/media/video/msm_vidc/vidc_hfi_api.h @@ -1057,6 +1057,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;