aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/platform/amphion/vpu_color.c
blob: 4ae435cbc5cda215a375dfa394066eb1ba7ce1dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2020-2021 NXP
 */

#include <linux/init.h>
#include <linux/device.h>
#include <linux/ioctl.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/types.h>
#include <media/v4l2-device.h>
#include "vpu.h"
#include "vpu_helpers.h"

static const u8 colorprimaries[] = {
	V4L2_COLORSPACE_LAST,
	V4L2_COLORSPACE_REC709,         /*Rec. ITU-R BT.709-6*/
	0,
	0,
	V4L2_COLORSPACE_470_SYSTEM_M,   /*Rec. ITU-R BT.470-6 System M*/
	V4L2_COLORSPACE_470_SYSTEM_BG,  /*Rec. ITU-R BT.470-6 System B, G*/
	V4L2_COLORSPACE_SMPTE170M,      /*SMPTE170M*/
	V4L2_COLORSPACE_SMPTE240M,      /*SMPTE240M*/
	0,                              /*Generic film*/
	V4L2_COLORSPACE_BT2020,         /*Rec. ITU-R BT.2020-2*/
	0,                              /*SMPTE ST 428-1*/
};

static const u8 colortransfers[] = {
	V4L2_XFER_FUNC_LAST,
	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.709-6*/
	0,
	0,
	0,                              /*Rec. ITU-R BT.470-6 System M*/
	0,                              /*Rec. ITU-R BT.470-6 System B, G*/
	V4L2_XFER_FUNC_709,             /*SMPTE170M*/
	V4L2_XFER_FUNC_SMPTE240M,       /*SMPTE240M*/
	V4L2_XFER_FUNC_NONE,            /*Linear transfer characteristics*/
	0,
	0,
	0,                              /*IEC 61966-2-4*/
	0,                              /*Rec. ITU-R BT.1361-0 extended colour gamut*/
	V4L2_XFER_FUNC_SRGB,            /*IEC 61966-2-1 sRGB or sYCC*/
	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.2020-2 (10 bit system)*/
	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.2020-2 (12 bit system)*/
	V4L2_XFER_FUNC_SMPTE2084,       /*SMPTE ST 2084*/
	0,                              /*SMPTE ST 428-1*/
	0                               /*Rec. ITU-R BT.2100-0 hybrid log-gamma (HLG)*/
};

static const u8 colormatrixcoefs[] = {
	V4L2_YCBCR_ENC_LAST,
	V4L2_YCBCR_ENC_709,              /*Rec. ITU-R BT.709-6*/
	0,
	0,
	0,                               /*Title 47 Code of Federal Regulations*/
	V4L2_YCBCR_ENC_601,              /*Rec. ITU-R BT.601-7 625*/
	V4L2_YCBCR_ENC_601,              /*Rec. ITU-R BT.601-7 525*/
	V4L2_YCBCR_ENC_SMPTE240M,        /*SMPTE240M*/
	0,
	V4L2_YCBCR_ENC_BT2020,           /*Rec. ITU-R BT.2020-2*/
	V4L2_YCBCR_ENC_BT2020_CONST_LUM  /*Rec. ITU-R BT.2020-2 constant*/
};

u32 vpu_color_cvrt_primaries_v2i(u32 primaries)
{
	return vpu_helper_find_in_array_u8(colorprimaries, ARRAY_SIZE(colorprimaries), primaries);
}

u32 vpu_color_cvrt_primaries_i2v(u32 primaries)
{
	return primaries < ARRAY_SIZE(colorprimaries) ? colorprimaries[primaries] : 0;
}

u32 vpu_color_cvrt_transfers_v2i(u32 transfers)
{
	return vpu_helper_find_in_array_u8(colortransfers, ARRAY_SIZE(colortransfers), transfers);
}

u32 vpu_color_cvrt_transfers_i2v(u32 transfers)
{
	return transfers < ARRAY_SIZE(colortransfers) ? colortransfers[transfers] : 0;
}

u32 vpu_color_cvrt_matrix_v2i(u32 matrix)
{
	return vpu_helper_find_in_array_u8(colormatrixcoefs, ARRAY_SIZE(colormatrixcoefs), matrix);
}

u32 vpu_color_cvrt_matrix_i2v(u32 matrix)
{
	return matrix < ARRAY_SIZE(colormatrixcoefs) ? colormatrixcoefs[matrix] : 0;
}

u32 vpu_color_cvrt_full_range_v2i(u32 full_range)
{
	return (full_range == V4L2_QUANTIZATION_FULL_RANGE);
}

u32 vpu_color_cvrt_full_range_i2v(u32 full_range)
{
	if (full_range)
		return V4L2_QUANTIZATION_FULL_RANGE;

	return V4L2_QUANTIZATION_LIM_RANGE;
}

int vpu_color_check_primaries(u32 primaries)
{
	return vpu_color_cvrt_primaries_v2i(primaries) ? 0 : -EINVAL;
}

int vpu_color_check_transfers(u32 transfers)
{
	return vpu_color_cvrt_transfers_v2i(transfers) ? 0 : -EINVAL;
}

int vpu_color_check_matrix(u32 matrix)
{
	return vpu_color_cvrt_matrix_v2i(matrix) ? 0 : -EINVAL;
}

int vpu_color_check_full_range(u32 full_range)
{
	int ret = -EINVAL;

	switch (full_range) {
	case V4L2_QUANTIZATION_FULL_RANGE:
	case V4L2_QUANTIZATION_LIM_RANGE:
		ret = 0;
		break;
	default:
		break;
	}

	return ret;
}

int vpu_color_get_default(u32 primaries, u32 *ptransfers, u32 *pmatrix, u32 *pfull_range)
{
	u32 transfers;
	u32 matrix;
	u32 full_range;

	switch (primaries) {
	case V4L2_COLORSPACE_REC709:
		transfers = V4L2_XFER_FUNC_709;
		matrix = V4L2_YCBCR_ENC_709;
		break;
	case V4L2_COLORSPACE_470_SYSTEM_M:
	case V4L2_COLORSPACE_470_SYSTEM_BG:
	case V4L2_COLORSPACE_SMPTE170M:
		transfers = V4L2_XFER_FUNC_709;
		matrix = V4L2_YCBCR_ENC_601;
		break;
	case V4L2_COLORSPACE_SMPTE240M:
		transfers = V4L2_XFER_FUNC_SMPTE240M;
		matrix = V4L2_YCBCR_ENC_SMPTE240M;
		break;
	case V4L2_COLORSPACE_BT2020:
		transfers = V4L2_XFER_FUNC_709;
		matrix = V4L2_YCBCR_ENC_BT2020;
		break;
	default:
		transfers = V4L2_XFER_FUNC_DEFAULT;
		matrix = V4L2_YCBCR_ENC_DEFAULT;
		break;
	}
	full_range = V4L2_QUANTIZATION_LIM_RANGE;

	if (ptransfers)
		*ptransfers = transfers;
	if (pmatrix)
		*pmatrix = matrix;
	if (pfull_range)
		*pfull_range = full_range;

	return 0;
}