diff mbox series

[18/30] v4l: vxd-dec: This patch implements pixel processing library

Message ID 20210818141037.19990-19-sidraya.bj@pathpartnertech.com
State New
Headers show
Series TI Video Decoder driver upstreaming to v5.14-rc6 kernel | expand

Commit Message

Sidraya Jayagond Aug. 18, 2021, 2:10 p.m. UTC
From: Sidraya <sidraya.bj@pathpartnertech.com>

This library is used to handle different pixel format layouts.

Signed-off-by: Sunita Nadampalli <sunitan@ti.com>
Signed-off-by: Sidraya <sidraya.bj@pathpartnertech.com>
---
 MAINTAINERS                                   |   2 +
 drivers/staging/media/vxd/decoder/pixel_api.c | 895 ++++++++++++++++++
 drivers/staging/media/vxd/decoder/pixel_api.h | 152 +++
 3 files changed, 1049 insertions(+)
 create mode 100644 drivers/staging/media/vxd/decoder/pixel_api.c
 create mode 100644 drivers/staging/media/vxd/decoder/pixel_api.h
diff mbox series

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index d126162984c6..bf47d48a1ec2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19600,6 +19600,8 @@  F:	drivers/staging/media/vxd/decoder/jpegfw_data.h
 F:	drivers/staging/media/vxd/decoder/jpegfw_data_shared.h
 F:	drivers/staging/media/vxd/decoder/mem_io.h
 F:	drivers/staging/media/vxd/decoder/mmu_defs.h
+F:	drivers/staging/media/vxd/decoder/pixel_api.c
+F:	drivers/staging/media/vxd/decoder/pixel_api.h
 F:	drivers/staging/media/vxd/decoder/pvdec_entropy_regs.h
 F:	drivers/staging/media/vxd/decoder/pvdec_int.h
 F:	drivers/staging/media/vxd/decoder/pvdec_vec_be_regs.h
diff --git a/drivers/staging/media/vxd/decoder/pixel_api.c b/drivers/staging/media/vxd/decoder/pixel_api.c
new file mode 100644
index 000000000000..a0620662a68e
--- /dev/null
+++ b/drivers/staging/media/vxd/decoder/pixel_api.c
@@ -0,0 +1,895 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Pixel processing function implementations
+ *
+ * Copyright (c) Imagination Technologies Ltd.
+ * Copyright (c) 2021 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Authors:
+ *	Sunita Nadampalli <sunitan@ti.com>
+ *
+ * Re-written for upstream
+ *	Sidraya Jayagond <sidraya.bj@pathpartnertech.com>
+ */
+
+#include <linux/dma-mapping.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "img_errors.h"
+#include "img_pixfmts.h"
+#include "pixel_api.h"
+#include "vdec_defs.h"
+
+#define NUM_OF_FORMATS 17
+#define PIXNAME(x) /* Pixel name support not enabled */
+#define FACT_SPEC_FORMAT_NUM_PLANES 4
+#define FACT_SPEC_FORMAT_PLANE_UNUSED 0xf
+#define FACT_SPEC_FORMAT_PLANE_CODE_BITS 4
+#define FACT_SPEC_FORMAT_PLANE_CODE_MASK 3
+#define FACT_SPEC_FORMAT_MIN_FACT_VAL 1
+
+/*
+ * @brief Pointer to the default format in the asPixelFormats array
+ * default format is an invalid format
+ * @note pointer set by initSearch()
+ * This pointer is also used to know if the arrays were sorted
+ */
+static struct pixel_pixinfo *def_fmt;
+
+/*
+ * @brief Actual array storing the pixel formats information.
+ */
+static struct pixel_pixinfo pix_fmts[NUM_OF_FORMATS] = {
+	{
+		IMG_PIXFMT_420PL12YUV8,
+		PIXEL_UV_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT8_MP,
+		PIXEL_FORMAT_420,
+		8,
+		8,
+		2
+	},
+
+	{
+		IMG_PIXFMT_420PL12YVU8,
+		PIXEL_VU_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT8_MP,
+		PIXEL_FORMAT_420,
+		8,
+		8,
+		2
+	},
+
+	{
+		IMG_PIXFMT_420PL12YUV10,
+		PIXEL_UV_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT10_MP,
+		PIXEL_FORMAT_420,
+		10,
+		10,
+		2
+	},
+
+	{
+		IMG_PIXFMT_420PL12YVU10,
+		PIXEL_VU_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT10_MP,
+		PIXEL_FORMAT_420,
+		10,
+		10,
+		2
+	},
+
+	{
+		IMG_PIXFMT_420PL12YUV10_MSB,
+		PIXEL_UV_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT10_MSB_MP,
+		PIXEL_FORMAT_420,
+		10,
+		10,
+		2
+	},
+
+	{
+		IMG_PIXFMT_420PL12YVU10_MSB,
+		PIXEL_VU_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT10_MSB_MP,
+		PIXEL_FORMAT_420,
+		10,
+		10,
+		2
+	},
+
+	{
+		IMG_PIXFMT_420PL12YUV10_LSB,
+		PIXEL_UV_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT10_LSB_MP,
+		PIXEL_FORMAT_420,
+		10,
+		10,
+		2
+	},
+
+	{
+		IMG_PIXFMT_420PL12YVU10_LSB,
+		PIXEL_VU_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT10_LSB_MP,
+		PIXEL_FORMAT_420,
+		10,
+		10,
+		2
+	},
+
+	{
+		IMG_PIXFMT_422PL12YUV8,
+		PIXEL_UV_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT8_MP,
+		PIXEL_FORMAT_422,
+		8,
+		8,
+		2
+	},
+
+	{
+		IMG_PIXFMT_422PL12YVU8,
+		PIXEL_VU_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT8_MP,
+		PIXEL_FORMAT_422,
+		8,
+		8,
+		2
+	},
+
+	{
+		IMG_PIXFMT_422PL12YUV10,
+		PIXEL_UV_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT10_MP,
+		PIXEL_FORMAT_422,
+		10,
+		10,
+		2
+	},
+
+	{
+		IMG_PIXFMT_422PL12YVU10,
+		PIXEL_VU_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT10_MP,
+		PIXEL_FORMAT_422,
+		10,
+		10,
+		2
+	},
+
+	{
+		IMG_PIXFMT_422PL12YUV10_MSB,
+		PIXEL_UV_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT10_MSB_MP,
+		PIXEL_FORMAT_422,
+		10,
+		10,
+		2
+	},
+
+	{
+		IMG_PIXFMT_422PL12YVU10_MSB,
+		PIXEL_VU_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT10_MSB_MP,
+		PIXEL_FORMAT_422,
+		10,
+		10,
+		2
+	},
+
+	{
+		IMG_PIXFMT_422PL12YUV10_LSB,
+		PIXEL_UV_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT10_LSB_MP,
+		PIXEL_FORMAT_422,
+		10,
+		10,
+		2
+	},
+
+	{
+		IMG_PIXFMT_422PL12YVU10_LSB,
+		PIXEL_VU_ORDER,
+		PIXEL_MULTICHROME,
+		PIXEL_BIT10_LSB_MP,
+		PIXEL_FORMAT_422,
+		10,
+		10,
+		2
+	},
+
+	{
+		IMG_PIXFMT_UNDEFINED,
+		PIXEL_INVALID_CI,
+		0,
+		(enum pixel_mem_packing)0,
+		PIXEL_FORMAT_INVALID,
+		0,
+		0,
+		0
+	}
+};
+
+static struct pixel_pixinfo_table pixinfo_table[] = {
+	{
+		IMG_PIXFMT_420PL12YUV8_A8,
+		{
+			PIXNAME(IMG_PIXFMT_420PL12YUV8_A8)
+			16,
+			16,
+			16,
+			0,
+			16,
+			TRUE,
+			TRUE,
+			4,
+			TRUE
+		}
+	},
+
+	{
+		IMG_PIXFMT_422PL12YUV8_A8,
+		{
+			PIXNAME(IMG_PIXFMT_422PL12YUV8_A8)
+			16,
+			16,
+			16,
+			0,
+			16,
+			TRUE,
+			FALSE,
+			4,
+			TRUE
+		}
+	},
+
+	{
+		IMG_PIXFMT_420PL12YUV8,
+		{
+			PIXNAME(IMG_PIXFMT_420PL12YUV8)
+			16,
+			16,
+			16,
+			0,
+			0,
+			TRUE,
+			TRUE,
+			4,
+			FALSE
+		}
+	},
+
+	{
+		IMG_PIXFMT_420PL12YVU8,
+		{
+			PIXNAME(IMG_PIXFMT_420PL12YVU8)
+			16,
+			16,
+			16,
+			0,
+			0,
+			TRUE,
+			TRUE,
+			4,
+			FALSE
+		}
+	},
+
+	{
+		IMG_PIXFMT_420PL12YUV10,
+		{
+			PIXNAME(IMG_PIXFMT_420PL12YUV10)
+			12,
+			16,
+			16,
+			0,
+			0,
+			TRUE,
+			TRUE,
+			4,
+			FALSE
+		}
+	},
+
+	{
+		IMG_PIXFMT_420PL12YVU10,
+		{
+			PIXNAME(IMG_PIXFMT_420PL12YVU10)
+			12,
+			16,
+			16,
+			0,
+			0,
+			TRUE,
+			TRUE,
+			4,
+			FALSE
+		}
+	},
+
+	{
+		IMG_PIXFMT_420PL12YUV10_MSB,
+		{
+			PIXNAME(IMG_PIXFMT_420PL12YUV10_MSB)
+			8,
+			16,
+			16,
+			0,
+			0,
+			TRUE,
+			TRUE,
+			4,
+			FALSE
+		}
+	},
+
+	{
+		IMG_PIXFMT_420PL12YVU10_MSB,
+		{
+			PIXNAME(IMG_PIXFMT_420PL12YVU10_MSB)
+			8,
+			16,
+			16,
+			0,
+			0,
+			TRUE,
+			TRUE,
+			4,
+			FALSE
+		}
+	},
+
+	{
+		IMG_PIXFMT_422PL12YUV8,
+		{
+			PIXNAME(IMG_PIXFMT_422PL12YUV8)
+			16,
+			16,
+			16,
+			0,
+			0,
+			TRUE,
+			FALSE,
+			4,
+			FALSE
+		}
+	},
+
+	{
+		IMG_PIXFMT_422PL12YVU8,
+		{
+			PIXNAME(IMG_PIXFMT_422PL12YVU8)
+			16,
+			16,
+			16,
+			0,
+			0,
+			TRUE,
+			FALSE,
+			4,
+			FALSE
+		}
+	},
+
+	{
+		IMG_PIXFMT_422PL12YUV10,
+		{
+			PIXNAME(IMG_PIXFMT_422PL12YUV10)
+			12,
+			16,
+			16,
+			0,
+			0,
+			TRUE,
+			FALSE,
+			4,
+			FALSE
+		}
+	},
+
+	{
+		IMG_PIXFMT_422PL12YVU10,
+		{
+			PIXNAME(IMG_PIXFMT_422PL12YVU10)
+			12,
+			16,
+			16,
+			0,
+			0,
+			TRUE,
+			FALSE,
+			4,
+			FALSE
+		}
+	},
+
+	{
+		IMG_PIXFMT_422PL12YUV10_MSB,
+		{
+			PIXNAME(IMG_PIXFMT_422PL12YUV10_MSB)
+			8,
+			16,
+			16,
+			0,
+			0,
+			TRUE,
+			FALSE,
+			4,
+			FALSE
+		}
+	},
+
+	{
+		IMG_PIXFMT_422PL12YVU10_MSB,
+		{
+			PIXNAME(IMG_PIXFMT_422PL12YVU10_MSB)
+			8,
+			16,
+			16,
+			0,
+			0,
+			TRUE,
+			FALSE,
+			4,
+			FALSE
+		}
+	},
+};
+
+static struct pixel_pixinfo_table*
+pixel_get_pixelinfo_from_pixfmt(enum img_pixfmt pix_fmt)
+{
+	unsigned int i;
+	unsigned char found = FALSE;
+	struct pixel_pixinfo_table *this_pixinfo_table_entry = NULL;
+
+	for (i = 0;
+		i < (sizeof(pixinfo_table) / sizeof(struct pixel_pixinfo_table));
+		i++) {
+		if (pix_fmt ==  pixinfo_table[i].pix_color_fmt) {
+			/*
+			 * There must only be one entry per pixel colour format
+			 * in the table
+			 */
+			VDEC_ASSERT(!found);
+			found = TRUE;
+			this_pixinfo_table_entry = &pixinfo_table[i];
+
+			/*
+			 * We deliberately do NOT break here - scan rest of
+			 * table to ensure there are not duplicate entries
+			 */
+		}
+	}
+	return this_pixinfo_table_entry;
+}
+
+/*
+ * @brief Array containing string lookup of pixel format IDC.
+ * @warning this must be kept in step with PIXEL_FormatIdc.
+ */
+unsigned char pix_fmt_idc_names[6][16] = {
+	"Monochrome",
+	"4:1:1",
+	"4:2:0",
+	"4:2:2",
+	"4:4:4",
+	"Invalid",
+};
+
+static int pixel_compare_pixfmts(const void *a, const void *b)
+{
+	return ((struct pixel_pixinfo *)a)->pixfmt -
+	       ((struct pixel_pixinfo *)b)->pixfmt;
+}
+
+static struct pixel_info*
+pixel_get_bufinfo_from_pixfmt(enum img_pixfmt pix_fmt)
+{
+	struct pixel_pixinfo_table *pixinfo_table_entry = NULL;
+	struct pixel_info *pix_info = NULL;
+
+	pixinfo_table_entry = pixel_get_pixelinfo_from_pixfmt(pix_fmt);
+	VDEC_ASSERT(pixinfo_table_entry);
+	if (pixinfo_table_entry)
+		pix_info = &pixinfo_table_entry->info;
+
+	return pix_info;
+}
+
+/*
+ * @brief Search a pixel format based on its attributes rather than its format
+ * enum.
+ * @warning use PIXEL_Comparpix_fmts to search by enum
+ */
+static int pixel_compare_pixinfo(const void *a, const void *b)
+{
+	int result = 0;
+	const struct pixel_pixinfo *fmt_a = (struct pixel_pixinfo *)a;
+	const struct pixel_pixinfo *fmt_b = (struct pixel_pixinfo *)b;
+
+	result = fmt_a->chroma_fmt_idc - fmt_b->chroma_fmt_idc;
+	if (result != 0)
+		return result;
+
+	result = fmt_a->mem_pkg - fmt_b->mem_pkg;
+	if (result != 0)
+		return result;
+
+	result = fmt_a->chroma_interleave - fmt_b->chroma_interleave;
+	if (result != 0)
+		return result;
+
+	result = fmt_a->bitdepth_y - fmt_b->bitdepth_y;
+	if (result != 0)
+		return result;
+
+	result = fmt_a->bitdepth_c - fmt_b->bitdepth_c;
+	if (result != 0)
+		return result;
+
+	result = fmt_a->num_planes - fmt_b->num_planes;
+	if (result != 0)
+		return result;
+
+	return result;
+}
+
+static void pixel_init_search(void)
+{
+	static unsigned int search_inited;
+
+	search_inited++;
+	if (search_inited == 1) {
+		if (!def_fmt) {
+			int i = 0;
+
+			i = NUM_OF_FORMATS - 1;
+			while (i >= 0) {
+				if (IMG_PIXFMT_UNDEFINED ==
+					pix_fmts[i].pixfmt) {
+					def_fmt = &pix_fmts[i];
+					break;
+				}
+			}
+			VDEC_ASSERT(def_fmt);
+		}
+	} else {
+		search_inited--;
+	}
+}
+
+static struct pixel_pixinfo *pixel_search_fmt(const struct pixel_pixinfo *key,
+					      unsigned char enum_only)
+{
+	struct pixel_pixinfo *fmt_found = NULL;
+	int (*compar)(const void *pixfmt1, const void *pixfmt2);
+
+	if (enum_only)
+		compar = &pixel_compare_pixfmts;
+	else
+		compar = &pixel_compare_pixinfo;
+
+	{
+		unsigned int i;
+
+		for (i = 0; i < NUM_OF_FORMATS; i++) {
+			if (compar(key, &pix_fmts[i]) == 0) {
+				fmt_found = &pix_fmts[i];
+				break;
+			}
+		}
+	}
+	return fmt_found;
+}
+
+/*
+ * @brief Set a pixel format info structure to the default.
+ * @warning This MODIDIFES the pointer therefore you shouldn't
+ * call it on pointer you got from the library!
+ */
+static void pixel_pixinfo_defaults(struct pixel_pixinfo *to_def)
+{
+	if (!def_fmt)
+		pixel_init_search();
+
+	memcpy(to_def, def_fmt, sizeof(struct pixel_pixinfo));
+}
+
+enum img_pixfmt pixel_get_pixfmt(enum pixel_fmt_idc chroma_fmt_idc,
+				 enum pixel_chroma_interleaved
+				 chroma_interleaved,
+				 enum pixel_mem_packing mem_pkg,
+				 unsigned int bitdepth_y, unsigned int bitdepth_c,
+				 unsigned int num_planes)
+{
+	unsigned int internal_num_planes = (num_planes == 0 || num_planes > 4) ? 2 :
+		num_planes;
+	struct pixel_pixinfo key;
+	struct pixel_pixinfo *fmt_found = NULL;
+
+	if (chroma_fmt_idc != PIXEL_FORMAT_MONO &&
+	    chroma_fmt_idc != PIXEL_FORMAT_411 &&
+	    chroma_fmt_idc != PIXEL_FORMAT_420 &&
+	    chroma_fmt_idc != PIXEL_FORMAT_422 &&
+	    chroma_fmt_idc != PIXEL_FORMAT_444)
+		return IMG_PIXFMT_UNDEFINED;
+
+	/* valid bit depth 8, 9, 10, or 16/0 for 422 */
+	if (bitdepth_y < 8 || bitdepth_y > 10)
+		return IMG_PIXFMT_UNDEFINED;
+
+	/* valid bit depth 8, 9, 10, or 16/0 for 422 */
+	if (bitdepth_c < 8 || bitdepth_c > 10)
+		return IMG_PIXFMT_UNDEFINED;
+
+	key.pixfmt = IMG_PIXFMT_UNDEFINED;
+	key.chroma_fmt_idc = chroma_fmt_idc;
+	key.chroma_interleave = chroma_interleaved;
+	key.mem_pkg = mem_pkg;
+	key.bitdepth_y = bitdepth_y;
+	key.bitdepth_c = bitdepth_c;
+	key.num_planes = internal_num_planes;
+
+	/*
+	 * 9 and 10 bits formats are handled in the same way, and there is only
+	 * one entry in the PixelFormat table
+	 */
+	if (key.bitdepth_y == 9)
+		key.bitdepth_y = 10;
+
+	/*
+	 * 9 and 10 bits formats are handled in the same way, and there is only
+	 * one entry in the PixelFormat table
+	 */
+	if (key.bitdepth_c == 9)
+		key.bitdepth_c = 10;
+
+	pixel_init_search();
+
+	/* do not search by format */
+	fmt_found = pixel_search_fmt(&key, FALSE);
+	if (!fmt_found)
+		return IMG_PIXFMT_UNDEFINED;
+
+	return fmt_found->pixfmt;
+}
+
+static void pixel_get_internal_pixelinfo(struct pixel_pixinfo *pixinfo,
+					 struct pixel_info *pix_bufinfo)
+{
+	if (pixinfo->bitdepth_y == 8 && pixinfo->bitdepth_c == 8)
+		pix_bufinfo->pixels_in_bop = 16;
+	else if (pixinfo->mem_pkg == PIXEL_BIT10_MP)
+		pix_bufinfo->pixels_in_bop = 12;
+	else
+		pix_bufinfo->pixels_in_bop = 8;
+
+	if (pixinfo->bitdepth_y == 8)
+		pix_bufinfo->ybytes_in_bop = pix_bufinfo->pixels_in_bop;
+	else
+		pix_bufinfo->ybytes_in_bop = 16;
+
+	if (pixinfo->chroma_fmt_idc == PIXEL_FORMAT_MONO) {
+		pix_bufinfo->uvbytes_in_bop = 0;
+	} else if (pixinfo->bitdepth_c == 8) {
+		pix_bufinfo->uvbytes_in_bop = pix_bufinfo->pixels_in_bop;
+		if (pixinfo->chroma_fmt_idc == PIXEL_FORMAT_422 && pixinfo->num_planes == 1) {
+			pix_bufinfo->uvbytes_in_bop = 0;
+			pix_bufinfo->pixels_in_bop = 8;
+		}
+	} else {
+		pix_bufinfo->uvbytes_in_bop = 16;
+	}
+
+	if (pixinfo->chroma_fmt_idc == PIXEL_FORMAT_444)
+		pix_bufinfo->uvbytes_in_bop *= 2;
+
+	if (pixinfo->chroma_interleave == PIXEL_INVALID_CI) {
+		pix_bufinfo->uvbytes_in_bop /= 2;
+		pix_bufinfo->vbytes_in_bop = pix_bufinfo->uvbytes_in_bop;
+	} else {
+		pix_bufinfo->vbytes_in_bop = 0;
+	}
+
+	pix_bufinfo->alphabytes_in_bop = 0;
+
+	if (pixinfo->num_planes == 1)
+		pix_bufinfo->is_planar = FALSE;
+	else
+		pix_bufinfo->is_planar = TRUE;
+
+	if (pixinfo->chroma_fmt_idc == PIXEL_FORMAT_420)
+		pix_bufinfo->uv_height_halved = TRUE;
+	else
+		pix_bufinfo->uv_height_halved = FALSE;
+
+	if (pixinfo->chroma_fmt_idc == PIXEL_FORMAT_444)
+		pix_bufinfo->uv_stride_ratio_times4 = 8;
+	else
+		pix_bufinfo->uv_stride_ratio_times4 = 4;
+
+	if (pixinfo->chroma_interleave == PIXEL_INVALID_CI)
+		pix_bufinfo->uv_stride_ratio_times4 /= 2;
+
+	pix_bufinfo->has_alpha = FALSE;
+}
+
+static void pixel_yuv_get_descriptor_int(struct pixel_info *pixinfo,
+					 struct img_pixfmt_desc  *pix_desc)
+{
+	pix_desc->bop_denom = pixinfo->pixels_in_bop;
+	pix_desc->h_denom = (pixinfo->uv_stride_ratio_times4 == 2 ||
+		!pixinfo->is_planar) ? 2 : 1;
+	pix_desc->v_denom = (pixinfo->uv_height_halved || !pixinfo->is_planar)
+		? 2 : 1;
+
+	pix_desc->planes[0] = TRUE;
+	pix_desc->bop_numer[0] = pixinfo->ybytes_in_bop;
+	pix_desc->h_numer[0] = pix_desc->h_denom;
+	pix_desc->v_numer[0] = pix_desc->v_denom;
+
+	pix_desc->planes[1] = pixinfo->is_planar;
+	pix_desc->bop_numer[1] = pixinfo->uvbytes_in_bop;
+	pix_desc->h_numer[1] = (pix_desc->h_denom * pixinfo->uv_stride_ratio_times4) / 4;
+	pix_desc->v_numer[1] = 1;
+
+	pix_desc->planes[2] = (pixinfo->vbytes_in_bop > 0) ? TRUE : FALSE;
+	pix_desc->bop_numer[2] = pixinfo->vbytes_in_bop;
+	pix_desc->h_numer[2] = (pixinfo->vbytes_in_bop > 0) ? 1 : 0;
+	pix_desc->v_numer[2] = (pixinfo->vbytes_in_bop > 0) ? 1 : 0;
+
+	pix_desc->planes[3] = pixinfo->has_alpha;
+	pix_desc->bop_numer[3] = pixinfo->alphabytes_in_bop;
+	pix_desc->h_numer[3] = pix_desc->h_denom;
+	pix_desc->v_numer[3] = pix_desc->v_denom;
+}
+
+int pixel_yuv_get_desc(struct pixel_pixinfo *pix_info, struct img_pixfmt_desc *pix_desc)
+{
+	struct pixel_info int_pix_info;
+
+	struct pixel_info *int_pix_info_old = NULL;
+	enum img_pixfmt pix_fmt = pixel_get_pixfmt(pix_info->chroma_fmt_idc,
+			pix_info->chroma_interleave,
+			pix_info->mem_pkg,
+			pix_info->bitdepth_y,
+			pix_info->bitdepth_c,
+			pix_info->num_planes);
+
+	/* Validate the output from new function. */
+	if (pix_fmt != IMG_PIXFMT_UNDEFINED)
+		int_pix_info_old = pixel_get_bufinfo_from_pixfmt(pix_fmt);
+
+	pixel_get_internal_pixelinfo(pix_info, &int_pix_info);
+
+	if (int_pix_info_old) {
+		VDEC_ASSERT(int_pix_info_old->has_alpha ==
+			int_pix_info.has_alpha);
+		VDEC_ASSERT(int_pix_info_old->is_planar ==
+			int_pix_info.is_planar);
+		VDEC_ASSERT(int_pix_info_old->uv_height_halved ==
+			int_pix_info.uv_height_halved);
+		VDEC_ASSERT(int_pix_info_old->alphabytes_in_bop ==
+			int_pix_info.alphabytes_in_bop);
+		VDEC_ASSERT(int_pix_info_old->pixels_in_bop ==
+			int_pix_info.pixels_in_bop);
+		VDEC_ASSERT(int_pix_info_old->uvbytes_in_bop ==
+			int_pix_info.uvbytes_in_bop);
+		VDEC_ASSERT(int_pix_info_old->uv_stride_ratio_times4 ==
+			int_pix_info.uv_stride_ratio_times4);
+		VDEC_ASSERT(int_pix_info_old->vbytes_in_bop ==
+			int_pix_info.vbytes_in_bop);
+		VDEC_ASSERT(int_pix_info_old->ybytes_in_bop ==
+			int_pix_info.ybytes_in_bop);
+	}
+
+	pixel_yuv_get_descriptor_int(&int_pix_info, pix_desc);
+
+	return IMG_SUCCESS;
+}
+
+struct pixel_pixinfo *pixel_get_pixinfo(const enum img_pixfmt pix_fmt)
+{
+	struct pixel_pixinfo key;
+	struct pixel_pixinfo *fmt_found = NULL;
+
+	pixel_init_search();
+	pixel_pixinfo_defaults(&key);
+	key.pixfmt = pix_fmt;
+
+	fmt_found = pixel_search_fmt(&key, TRUE);
+	if (!fmt_found)
+		return def_fmt;
+	return fmt_found;
+}
+
+int pixel_get_fmt_desc(enum img_pixfmt pix_fmt, struct img_pixfmt_desc *pix_desc)
+{
+	if (pix_fmt >= IMG_PIXFMT_ARBPLANAR8 && pix_fmt <= IMG_PIXFMT_ARBPLANAR8_LAST) {
+		unsigned int i;
+		unsigned short spec;
+
+		pix_desc->bop_denom = 1;
+		pix_desc->h_denom = 1;
+		pix_desc->v_denom = 1;
+
+		spec = (pix_fmt - IMG_PIXFMT_ARBPLANAR8) & 0xffff;
+		for (i = 0; i < FACT_SPEC_FORMAT_NUM_PLANES; i++) {
+			unsigned char code = (spec >> FACT_SPEC_FORMAT_PLANE_CODE_BITS *
+				(FACT_SPEC_FORMAT_NUM_PLANES - 1 - i)) & 0xf;
+			pix_desc->bop_numer[i] = 1;
+			pix_desc->h_numer[i] = ((code >> 2) & FACT_SPEC_FORMAT_PLANE_CODE_MASK) +
+						FACT_SPEC_FORMAT_MIN_FACT_VAL;
+			pix_desc->v_numer[i] = (code & FACT_SPEC_FORMAT_PLANE_CODE_MASK) +
+						FACT_SPEC_FORMAT_MIN_FACT_VAL;
+			if (i == 0 || code != FACT_SPEC_FORMAT_PLANE_UNUSED) {
+				pix_desc->planes[i] = TRUE;
+
+				pix_desc->h_denom =
+					pix_desc->h_denom > pix_desc->h_numer[i] ?
+					pix_desc->h_denom : pix_desc->h_numer[i];
+
+				pix_desc->v_denom =
+					pix_desc->v_denom > pix_desc->v_numer[i] ?
+					pix_desc->v_denom : pix_desc->v_numer[i];
+			} else {
+				pix_desc->planes[i] = FALSE;
+			}
+		}
+	} else {
+		struct pixel_info *info =
+			pixel_get_bufinfo_from_pixfmt(pix_fmt);
+		if (!info) {
+			VDEC_ASSERT(0);
+			return -EINVAL;
+		}
+
+		pixel_yuv_get_descriptor_int(info, pix_desc);
+	}
+
+	return IMG_SUCCESS;
+}
+
+int pixel_gen_pixfmt(enum img_pixfmt *pix_fmt, struct img_pixfmt_desc *pix_desc)
+{
+	unsigned short spec = 0, i;
+	unsigned char code;
+
+	for (i = 0; i < FACT_SPEC_FORMAT_NUM_PLANES; i++) {
+		if (pix_desc->planes[i] != 1) {
+			code = FACT_SPEC_FORMAT_PLANE_UNUSED;
+		} else {
+			code = (((pix_desc->h_numer[i] - FACT_SPEC_FORMAT_MIN_FACT_VAL) &
+				FACT_SPEC_FORMAT_PLANE_CODE_MASK) << 2) |
+				((pix_desc->v_numer[i] - FACT_SPEC_FORMAT_MIN_FACT_VAL) &
+				FACT_SPEC_FORMAT_PLANE_CODE_MASK);
+		}
+		spec |= (code << FACT_SPEC_FORMAT_PLANE_CODE_BITS *
+			(FACT_SPEC_FORMAT_NUM_PLANES - 1 - i));
+	}
+
+	*pix_fmt = (enum img_pixfmt)(IMG_PIXFMT_ARBPLANAR8 | spec);
+
+	return 0;
+}
diff --git a/drivers/staging/media/vxd/decoder/pixel_api.h b/drivers/staging/media/vxd/decoder/pixel_api.h
new file mode 100644
index 000000000000..3648c1b32ea7
--- /dev/null
+++ b/drivers/staging/media/vxd/decoder/pixel_api.h
@@ -0,0 +1,152 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Pixel processing functions header
+ *
+ * Copyright (c) Imagination Technologies Ltd.
+ * Copyright (c) 2021 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Authors:
+ *	Sunita Nadampalli <sunitan@ti.com>
+ *
+ * Re-written for upstream
+ *	Sidraya Jayagond <sidraya.bj@pathpartnertech.com>
+ */
+
+#ifndef __PIXEL_API_H__
+#define __PIXEL_API_H__
+
+#include <linux/types.h>
+
+#include "img_errors.h"
+#include "img_pixfmts.h"
+
+#define PIXEL_MULTICHROME   TRUE
+#define PIXEL_MONOCHROME    FALSE
+#define IMG_MAX_NUM_PLANES  4
+#define PIXEL_INVALID_BDC   8
+
+extern unsigned char pix_fmt_idc_names[6][16];
+
+struct img_pixfmt_desc {
+	unsigned char planes[IMG_MAX_NUM_PLANES];
+	unsigned int bop_denom;
+	unsigned int bop_numer[IMG_MAX_NUM_PLANES];
+	unsigned int h_denom;
+	unsigned int v_denom;
+	unsigned int h_numer[IMG_MAX_NUM_PLANES];
+	unsigned int v_numer[IMG_MAX_NUM_PLANES];
+};
+
+/*
+ * @brief This type defines memory chroma interleaved order
+ */
+enum pixel_chroma_interleaved {
+	PIXEL_INVALID_CI        = 0,
+	PIXEL_UV_ORDER          = 1,
+	PIXEL_VU_ORDER          = 2,
+	PIXEL_YAYB_ORDER        = 4,
+	PIXEL_AYBY_ORDER        = 8,
+	PIXEL_ORDER_FORCE32BITS = 0x7FFFFFFFU
+};
+
+/*
+ * @brief This macro translates enum pixel_chroma_interleaved values into
+ * value that can be used to write HW registers directly.
+ */
+#define PIXEL_GET_HW_CHROMA_INTERLEAVED(value) \
+	((value) & PIXEL_VU_ORDER ? TRUE : FALSE)
+
+/*
+ * @brief This type defines memory packing types
+ */
+enum pixel_mem_packing {
+	PIXEL_BIT8_MP             = 0,
+	PIXEL_BIT10_MSB_MP        = 1,
+	PIXEL_BIT10_LSB_MP        = 2,
+	PIXEL_BIT10_MP            = 3,
+	PIXEL_DEFAULT_MP          = 0xff,
+	PIXEL_DEFAULT_FORCE32BITS = 0x7FFFFFFFU
+};
+
+static inline unsigned char pixel_get_hw_memory_packing(enum pixel_mem_packing value)
+{
+	return value == PIXEL_BIT8_MP ? FALSE :
+	       value == PIXEL_BIT10_MSB_MP ? FALSE :
+	       value == PIXEL_BIT10_LSB_MP ? FALSE :
+	       value == PIXEL_BIT10_MP ? TRUE : FALSE;
+}
+
+/*
+ * @brief This type defines chroma formats
+ */
+enum pixel_fmt_idc {
+	PIXEL_FORMAT_MONO        = 0,
+	PIXEL_FORMAT_411         = 1,
+	PIXEL_FORMAT_420         = 2,
+	PIXEL_FORMAT_422         = 3,
+	PIXEL_FORMAT_444         = 4,
+	PIXEL_FORMAT_INVALID     = 0xFF,
+	PIXEL_FORMAT_FORCE32BITS = 0x7FFFFFFFU
+};
+
+static inline int pixel_get_hw_chroma_format_idc(enum pixel_fmt_idc value)
+{
+	return value == PIXEL_FORMAT_MONO ? 0 :
+	       value == PIXEL_FORMAT_420 ? 1 :
+	       value == PIXEL_FORMAT_422 ? 2 :
+	       value == PIXEL_FORMAT_444 ? 3 :
+	       PIXEL_FORMAT_INVALID;
+}
+
+/*
+ * @brief This structure contains information about the pixel formats
+ */
+struct pixel_pixinfo {
+	enum img_pixfmt pixfmt;
+	enum pixel_chroma_interleaved chroma_interleave;
+	unsigned char chroma_fmt;
+	enum pixel_mem_packing mem_pkg;
+	enum pixel_fmt_idc chroma_fmt_idc;
+	unsigned int bitdepth_y;
+	unsigned int bitdepth_c;
+	unsigned int num_planes;
+};
+
+/*
+ * @brief This type defines the image in memory
+ */
+struct pixel_info {
+	unsigned int pixels_in_bop;
+	unsigned int ybytes_in_bop;
+	unsigned int uvbytes_in_bop;
+	unsigned int vbytes_in_bop;
+	unsigned int alphabytes_in_bop;
+	unsigned char is_planar;
+	unsigned char uv_height_halved;
+	unsigned int uv_stride_ratio_times4;
+	unsigned char has_alpha;
+};
+
+struct pixel_pixinfo_table {
+	enum img_pixfmt pix_color_fmt;
+	struct pixel_info info;
+};
+
+struct pixel_pixinfo *pixel_get_pixinfo(const enum img_pixfmt pixfmt);
+
+enum img_pixfmt pixel_get_pixfmt(enum pixel_fmt_idc chroma_fmt_idc,
+				 enum pixel_chroma_interleaved
+				 chroma_interleaved,
+				 enum pixel_mem_packing mem_packing,
+				 unsigned int bitdepth_y, unsigned int bitdepth_c,
+				 unsigned int num_planes);
+
+int pixel_yuv_get_desc(struct pixel_pixinfo *pix_info,
+		       struct img_pixfmt_desc *desc);
+
+int pixel_get_fmt_desc(enum img_pixfmt pixfmt,
+		       struct img_pixfmt_desc *fmt_desc);
+
+int pixel_gen_pixfmt(enum img_pixfmt *pix_fmt, struct img_pixfmt_desc *pix_desc);
+
+#endif