diff mbox series

[16/33] iris: add helpers for media format

Message ID 1690550624-14642-17-git-send-email-quic_vgarodia@quicinc.com
State New
Headers show
Series Qualcomm video decoder/encoder driver | expand

Commit Message

Vikash Garodia July 28, 2023, 1:23 p.m. UTC
From: Dikshita Agarwal <quic_dikshita@quicinc.com>

Add helpers to calculate stride, scanline, buffer size
etc. for different media formats.

Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
---
 .../platform/qcom/iris/vidc/inc/msm_media_info.h   | 599 +++++++++++++++++++++
 1 file changed, 599 insertions(+)
 create mode 100644 drivers/media/platform/qcom/iris/vidc/inc/msm_media_info.h

Comments

Dikshita Agarwal Aug. 14, 2023, 7:18 p.m. UTC | #1
On 7/28/2023 11:25 PM, Konrad Dybcio wrote:
> On 28.07.2023 15:23, Vikash Garodia wrote:
>> From: Dikshita Agarwal <quic_dikshita@quicinc.com>
>>
>> Add helpers to calculate stride, scanline, buffer size
>> etc. for different media formats.
>>
>> Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
>> Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
>> ---
> [...]
> 
> 
>> +
>> +#ifndef MSM_MEDIA_ALIGN
>> +#define MSM_MEDIA_ALIGN(__sz, __align) (((__align) & ((__align) - 1)) ?\
>> +	((((__sz) + (__align) - 1) / (__align)) * (__align)) :\
>> +	(((__sz) + (__align) - 1) & (~((__align) - 1))))
> <linux/align.h>?
> 
sure, will replace with standard ALIGN macro
>> +#endif
>> +
>> +#ifndef MSM_MEDIA_ROUNDUP
>> +#define MSM_MEDIA_ROUNDUP(__sz, __r) (((__sz) + ((__r) - 1)) / (__r))
>> +#endif
>> +
>> +/*
>> + * Function arguments:
>> + * @v4l2_fmt
>> + * @width
>> + * Progressive: width
>> + * Interlaced: width
>> + */
> Kerneldoc would be cooler
> 
Sure, will take care of this in next version.
> [...]
> 
>> +static inline unsigned int video_rgb_stride_pix(unsigned int colorformat,
>> +						unsigned int width)
>> +{
>> +	unsigned int bpp = 4;
> Always?
Will check more on this if all supported RGB formats have bpp as 4.

Thanks,
Dikshita
> 
> 
> Konrad
diff mbox series

Patch

diff --git a/drivers/media/platform/qcom/iris/vidc/inc/msm_media_info.h b/drivers/media/platform/qcom/iris/vidc/inc/msm_media_info.h
new file mode 100644
index 0000000..772b2482
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/vidc/inc/msm_media_info.h
@@ -0,0 +1,599 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __MSM_MEDIA_INFO_H__
+#define __MSM_MEDIA_INFO_H__
+
+#include "msm_vidc_internal.h"
+
+/* Width and Height should be multiple of 16 */
+#define INTERLACE_WIDTH_MAX 1920
+#define INTERLACE_HEIGHT_MAX 1920
+#define INTERLACE_MB_PER_FRAME_MAX ((1920 * 1088) / 256)
+
+#ifndef MSM_MEDIA_ALIGN
+#define MSM_MEDIA_ALIGN(__sz, __align) (((__align) & ((__align) - 1)) ?\
+	((((__sz) + (__align) - 1) / (__align)) * (__align)) :\
+	(((__sz) + (__align) - 1) & (~((__align) - 1))))
+#endif
+
+#ifndef MSM_MEDIA_ROUNDUP
+#define MSM_MEDIA_ROUNDUP(__sz, __r) (((__sz) + ((__r) - 1)) / (__r))
+#endif
+
+/*
+ * Function arguments:
+ * @v4l2_fmt
+ * @width
+ * Progressive: width
+ * Interlaced: width
+ */
+static inline unsigned int video_y_stride_bytes(unsigned int colorformat,
+						unsigned int width)
+{
+	unsigned int alignment, stride = 0;
+
+	if (!width)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_NV12:
+	case MSM_VIDC_FMT_NV21:
+	case MSM_VIDC_FMT_NV12C:
+		alignment = 128;
+		stride = MSM_MEDIA_ALIGN(width, alignment);
+		break;
+	case MSM_VIDC_FMT_TP10C:
+		alignment = 256;
+		stride = MSM_MEDIA_ALIGN(width, 192);
+		stride = MSM_MEDIA_ALIGN(stride * 4 / 3, alignment);
+		break;
+	case MSM_VIDC_FMT_P010:
+		alignment = 256;
+		stride = MSM_MEDIA_ALIGN(width * 2, alignment);
+		break;
+	default:
+		break;
+	}
+invalid_input:
+	return stride;
+}
+
+/*
+ * Function arguments:
+ * @v4l2_fmt
+ * @width
+ * Progressive: width
+ * Interlaced: width
+ */
+static inline unsigned int video_y_stride_pix(unsigned int colorformat,
+					      unsigned int width)
+{
+	unsigned int alignment, stride = 0;
+
+	if (!width)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_NV12:
+	case MSM_VIDC_FMT_NV21:
+	case MSM_VIDC_FMT_NV12C:
+	case MSM_VIDC_FMT_P010:
+		alignment = 128;
+		stride = MSM_MEDIA_ALIGN(width, alignment);
+		break;
+	case MSM_VIDC_FMT_TP10C:
+		alignment = 192;
+		stride = MSM_MEDIA_ALIGN(width, alignment);
+		break;
+	default:
+		break;
+	}
+
+invalid_input:
+	return stride;
+}
+
+/*
+ * Function arguments:
+ * @v4l2_fmt
+ * @width
+ * Progressive: width
+ * Interlaced: width
+ */
+static inline unsigned int video_uv_stride_bytes(unsigned int colorformat,
+						 unsigned int width)
+{
+	unsigned int alignment, stride = 0;
+
+	if (!width)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_NV21:
+	case MSM_VIDC_FMT_NV12:
+	case MSM_VIDC_FMT_NV12C:
+		alignment = 128;
+		stride = MSM_MEDIA_ALIGN(width, alignment);
+		break;
+	case MSM_VIDC_FMT_TP10C:
+		alignment = 256;
+		stride = MSM_MEDIA_ALIGN(width, 192);
+		stride = MSM_MEDIA_ALIGN(stride * 4 / 3, alignment);
+		break;
+	case MSM_VIDC_FMT_P010:
+		alignment = 256;
+		stride = MSM_MEDIA_ALIGN(width * 2, alignment);
+		break;
+	default:
+		break;
+	}
+invalid_input:
+	return stride;
+}
+
+/*
+ * Function arguments:
+ * @v4l2_fmt
+ * @width
+ * Progressive: width
+ * Interlaced: width
+ */
+static inline unsigned int video_uv_stride_pix(unsigned int colorformat,
+					       unsigned int width)
+{
+	unsigned int alignment, stride = 0;
+
+	if (!width)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_NV21:
+	case MSM_VIDC_FMT_NV12:
+	case MSM_VIDC_FMT_NV12C:
+	case MSM_VIDC_FMT_P010:
+		alignment = 128;
+		stride = MSM_MEDIA_ALIGN(width, alignment);
+		break;
+	case MSM_VIDC_FMT_TP10C:
+		alignment = 192;
+		stride = MSM_MEDIA_ALIGN(width, alignment);
+		break;
+	default:
+		break;
+	}
+invalid_input:
+	return stride;
+}
+
+/*
+ * Function arguments:
+ * @v4l2_fmt
+ * @height
+ * Progressive: height
+ * Interlaced: (height+1)>>1
+ */
+static inline unsigned int video_y_scanlines(unsigned int colorformat,
+					     unsigned int height)
+{
+	unsigned int alignment, sclines = 0;
+
+	if (!height)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_NV12:
+	case MSM_VIDC_FMT_NV21:
+	case MSM_VIDC_FMT_NV12C:
+	case MSM_VIDC_FMT_P010:
+		alignment = 32;
+		break;
+	case MSM_VIDC_FMT_TP10C:
+		alignment = 16;
+		break;
+	default:
+		return 0;
+	}
+	sclines = MSM_MEDIA_ALIGN(height, alignment);
+invalid_input:
+	return sclines;
+}
+
+/*
+ * Function arguments:
+ * @v4l2_fmt
+ * @height
+ * Progressive: height
+ * Interlaced: (height+1)>>1
+ */
+static inline unsigned int video_uv_scanlines(unsigned int colorformat,
+					      unsigned int height)
+{
+	unsigned int alignment, sclines = 0;
+
+	if (!height)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_NV21:
+	case MSM_VIDC_FMT_NV12:
+	case MSM_VIDC_FMT_TP10C:
+	case MSM_VIDC_FMT_P010:
+		alignment = 16;
+		break;
+	case MSM_VIDC_FMT_NV12C:
+		alignment = 32;
+		break;
+	default:
+		goto invalid_input;
+	}
+
+	sclines = MSM_MEDIA_ALIGN((height + 1) >> 1, alignment);
+
+invalid_input:
+	return sclines;
+}
+
+/*
+ * Function arguments:
+ * @v4l2_fmt
+ * @width
+ * Progressive: width
+ * Interlaced: width
+ */
+static inline unsigned int video_y_meta_stride(unsigned int colorformat,
+					       unsigned int width)
+{
+	int y_tile_width = 0, y_meta_stride = 0;
+
+	if (!width)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_NV12C:
+		y_tile_width = 32;
+		break;
+	case MSM_VIDC_FMT_TP10C:
+		y_tile_width = 48;
+		break;
+	default:
+		goto invalid_input;
+	}
+
+	y_meta_stride = MSM_MEDIA_ROUNDUP(width, y_tile_width);
+	y_meta_stride = MSM_MEDIA_ALIGN(y_meta_stride, 64);
+
+invalid_input:
+	return y_meta_stride;
+}
+
+/*
+ * Function arguments:
+ * @v4l2_fmt
+ * @height
+ * Progressive: height
+ * Interlaced: (height+1)>>1
+ */
+static inline unsigned int video_y_meta_scanlines(unsigned int colorformat,
+						  unsigned int height)
+{
+	int y_tile_height = 0, y_meta_scanlines = 0;
+
+	if (!height)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_NV12C:
+		y_tile_height = 8;
+		break;
+	case MSM_VIDC_FMT_TP10C:
+		y_tile_height = 4;
+		break;
+	default:
+		goto invalid_input;
+	}
+
+	y_meta_scanlines = MSM_MEDIA_ROUNDUP(height, y_tile_height);
+	y_meta_scanlines = MSM_MEDIA_ALIGN(y_meta_scanlines, 16);
+
+invalid_input:
+	return y_meta_scanlines;
+}
+
+/*
+ * Function arguments:
+ * @v4l2_fmt
+ * @width
+ * Progressive: width
+ * Interlaced: width
+ */
+static inline unsigned int video_uv_meta_stride(unsigned int colorformat,
+						unsigned int width)
+{
+	int uv_tile_width = 0, uv_meta_stride = 0;
+
+	if (!width)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_NV12C:
+		uv_tile_width = 16;
+		break;
+	case MSM_VIDC_FMT_TP10C:
+		uv_tile_width = 24;
+		break;
+	default:
+		goto invalid_input;
+	}
+
+	uv_meta_stride = MSM_MEDIA_ROUNDUP((width + 1) >> 1, uv_tile_width);
+	uv_meta_stride = MSM_MEDIA_ALIGN(uv_meta_stride, 64);
+
+invalid_input:
+	return uv_meta_stride;
+}
+
+/*
+ * Function arguments:
+ * @v4l2_fmt
+ * @height
+ * Progressive: height
+ * Interlaced: (height+1)>>1
+ */
+static inline unsigned int video_uv_meta_scanlines(unsigned int colorformat,
+						   unsigned int height)
+{
+	int uv_tile_height = 0, uv_meta_scanlines = 0;
+
+	if (!height)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_NV12C:
+		uv_tile_height = 8;
+		break;
+	case MSM_VIDC_FMT_TP10C:
+		uv_tile_height = 4;
+		break;
+	default:
+		goto invalid_input;
+	}
+
+	uv_meta_scanlines = MSM_MEDIA_ROUNDUP((height + 1) >> 1, uv_tile_height);
+	uv_meta_scanlines = MSM_MEDIA_ALIGN(uv_meta_scanlines, 16);
+
+invalid_input:
+	return uv_meta_scanlines;
+}
+
+static inline unsigned int video_rgb_stride_bytes(unsigned int colorformat,
+						  unsigned int width)
+{
+	unsigned int alignment = 0, stride = 0, bpp = 4;
+
+	if (!width)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_RGBA8888C:
+	case MSM_VIDC_FMT_RGBA8888:
+		alignment = 256;
+		break;
+	default:
+		goto invalid_input;
+	}
+
+	stride = MSM_MEDIA_ALIGN(width * bpp, alignment);
+
+invalid_input:
+	return stride;
+}
+
+static inline unsigned int video_rgb_stride_pix(unsigned int colorformat,
+						unsigned int width)
+{
+	unsigned int bpp = 4;
+
+	return video_rgb_stride_bytes(colorformat, width) / bpp;
+}
+
+static inline unsigned int video_rgb_scanlines(unsigned int colorformat,
+					       unsigned int height)
+{
+	unsigned int alignment = 0, scanlines = 0;
+
+	if (!height)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_RGBA8888C:
+		alignment = 16;
+		break;
+	case MSM_VIDC_FMT_RGBA8888:
+		alignment = 32;
+		break;
+	default:
+		goto invalid_input;
+	}
+
+	scanlines = MSM_MEDIA_ALIGN(height, alignment);
+
+invalid_input:
+	return scanlines;
+}
+
+static inline unsigned int video_rgb_meta_stride(unsigned int colorformat,
+						 unsigned int width)
+{
+	int rgb_tile_width = 0, rgb_meta_stride = 0;
+
+	if (!width)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_RGBA8888C:
+	case MSM_VIDC_FMT_RGBA8888:
+		rgb_tile_width = 16;
+		break;
+	default:
+		goto invalid_input;
+	}
+
+	rgb_meta_stride = MSM_MEDIA_ROUNDUP(width, rgb_tile_width);
+	rgb_meta_stride = MSM_MEDIA_ALIGN(rgb_meta_stride, 64);
+
+invalid_input:
+	return rgb_meta_stride;
+}
+
+static inline unsigned int video_rgb_meta_scanlines(unsigned int colorformat,
+						    unsigned int height)
+{
+	int rgb_tile_height = 0, rgb_meta_scanlines = 0;
+
+	if (!height)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_RGBA8888C:
+	case MSM_VIDC_FMT_RGBA8888:
+		rgb_tile_height = 4;
+		break;
+	default:
+		goto invalid_input;
+	}
+
+	rgb_meta_scanlines = MSM_MEDIA_ROUNDUP(height, rgb_tile_height);
+	rgb_meta_scanlines = MSM_MEDIA_ALIGN(rgb_meta_scanlines, 16);
+
+invalid_input:
+	return rgb_meta_scanlines;
+}
+
+static inline unsigned int video_buffer_size(unsigned int colorformat, unsigned int pix_width,
+					     unsigned int pix_height, unsigned int interlace)
+{
+	unsigned int size = 0;
+	unsigned int y_plane, uv_plane, y_stride,
+		uv_stride, y_sclines, uv_sclines;
+	unsigned int y_ubwc_plane = 0, uv_ubwc_plane = 0;
+	unsigned int y_meta_stride = 0, y_meta_scanlines = 0;
+	unsigned int uv_meta_stride = 0, uv_meta_scanlines = 0;
+	unsigned int y_meta_plane = 0, uv_meta_plane = 0;
+	unsigned int rgb_stride = 0, rgb_scanlines = 0;
+	unsigned int rgb_plane = 0, rgb_ubwc_plane = 0, rgb_meta_plane = 0;
+	unsigned int rgb_meta_stride = 0, rgb_meta_scanlines = 0;
+
+	if (!pix_width || !pix_height)
+		goto invalid_input;
+
+	y_stride = video_y_stride_bytes(colorformat, pix_width);
+	uv_stride = video_uv_stride_bytes(colorformat, pix_width);
+	y_sclines = video_y_scanlines(colorformat, pix_height);
+	uv_sclines = video_uv_scanlines(colorformat, pix_height);
+	rgb_stride = video_rgb_stride_bytes(colorformat, pix_width);
+	rgb_scanlines = video_rgb_scanlines(colorformat, pix_height);
+
+	switch (colorformat) {
+	case MSM_VIDC_FMT_NV21:
+	case MSM_VIDC_FMT_NV12:
+	case MSM_VIDC_FMT_P010:
+		y_plane = y_stride * y_sclines;
+		uv_plane = uv_stride * uv_sclines;
+		size = y_plane + uv_plane;
+		break;
+	case MSM_VIDC_FMT_NV12C:
+		y_meta_stride = video_y_meta_stride(colorformat, pix_width);
+		uv_meta_stride = video_uv_meta_stride(colorformat, pix_width);
+		if (!interlace && colorformat == MSM_VIDC_FMT_NV12C) {
+			y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
+			uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096);
+			y_meta_scanlines =
+				video_y_meta_scanlines(colorformat, pix_height);
+			y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096);
+			uv_meta_scanlines =
+				video_uv_meta_scanlines(colorformat, pix_height);
+			uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride *
+				uv_meta_scanlines, 4096);
+			size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane +
+				uv_meta_plane);
+		} else {
+			if (pix_width <= INTERLACE_WIDTH_MAX &&
+			    pix_height <= INTERLACE_HEIGHT_MAX &&
+			    (pix_height * pix_width) / 256 <= INTERLACE_MB_PER_FRAME_MAX) {
+				y_sclines =
+					video_y_scanlines(colorformat, (pix_height + 1) >> 1);
+				y_ubwc_plane =
+					MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
+				uv_sclines =
+					video_uv_scanlines(colorformat, (pix_height + 1) >> 1);
+				uv_ubwc_plane =
+					MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096);
+				y_meta_scanlines =
+				video_y_meta_scanlines(colorformat, (pix_height + 1) >> 1);
+				y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines,
+							       4096);
+				uv_meta_scanlines =
+				video_uv_meta_scanlines(colorformat, (pix_height + 1) >> 1);
+				uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride *
+								uv_meta_scanlines, 4096);
+				size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane +
+					uv_meta_plane) * 2;
+			} else {
+				y_sclines = video_y_scanlines(colorformat, pix_height);
+				y_ubwc_plane =
+					MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
+				uv_sclines = video_uv_scanlines(colorformat, pix_height);
+				uv_ubwc_plane =
+					MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096);
+				y_meta_scanlines =
+					video_y_meta_scanlines(colorformat, pix_height);
+				y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines,
+							       4096);
+				uv_meta_scanlines =
+					video_uv_meta_scanlines(colorformat, pix_height);
+				uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride *
+					uv_meta_scanlines, 4096);
+				size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane +
+					uv_meta_plane);
+			}
+		}
+		break;
+	case MSM_VIDC_FMT_TP10C:
+		y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
+		uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096);
+		y_meta_stride = video_y_meta_stride(colorformat, pix_width);
+		y_meta_scanlines = video_y_meta_scanlines(colorformat, pix_height);
+		y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096);
+		uv_meta_stride = video_uv_meta_stride(colorformat, pix_width);
+		uv_meta_scanlines = video_uv_meta_scanlines(colorformat, pix_height);
+		uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride *
+						uv_meta_scanlines, 4096);
+
+		size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane +
+			uv_meta_plane;
+		break;
+	case MSM_VIDC_FMT_RGBA8888C:
+		rgb_ubwc_plane = MSM_MEDIA_ALIGN(rgb_stride * rgb_scanlines, 4096);
+		rgb_meta_stride = video_rgb_meta_stride(colorformat, pix_width);
+		rgb_meta_scanlines = video_rgb_meta_scanlines(colorformat, pix_height);
+		rgb_meta_plane = MSM_MEDIA_ALIGN(rgb_meta_stride * rgb_meta_scanlines, 4096);
+		size = rgb_ubwc_plane + rgb_meta_plane;
+		break;
+	case MSM_VIDC_FMT_RGBA8888:
+		rgb_plane = MSM_MEDIA_ALIGN(rgb_stride * rgb_scanlines, 4096);
+		size = rgb_plane;
+		break;
+	default:
+		break;
+	}
+
+invalid_input:
+	size = MSM_MEDIA_ALIGN(size, 4096);
+	return size;
+}
+
+#endif