1 /*
2 * Copyright Samsung Electronics Co.,LTD.
3 * Copyright (C) 2016 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include <linux/videodev2.h>
19 #include <log/log.h>
20 #include <mali_gralloc_formats.h>
21 #include <system/graphics.h>
22 #include <exynos_format.h> // hardware/smasung_slsi/exynos/include
23 #include "acrylic_internal.h"
24
25 #define V4L2_PIX_FMT_NV12N v4l2_fourcc('N', 'N', '1', '2')
26 #define V4L2_PIX_FMT_NV12N_10B v4l2_fourcc('B', 'N', '1', '2')
27 #define V4L2_PIX_FMT_YUV420N v4l2_fourcc('Y', 'N', '1', '2')
28 #define V4L2_PIX_FMT_NV12M_S10B v4l2_fourcc('B', 'M', '1', '2')
29 #define V4L2_PIX_FMT_NV21M_S10B v4l2_fourcc('B', 'M', '2', '1')
30 #define V4L2_PIX_FMT_NV16M_S10B v4l2_fourcc('B', 'M', '1', '6')
31 #define V4L2_PIX_FMT_NV61M_S10B v4l2_fourcc('B', 'M', '6', '1')
32 #define V4L2_PIX_FMT_NV12M_P010 v4l2_fourcc('P', 'M', '1', '2')
33 #define V4L2_PIX_FMT_NV21M_P010 v4l2_fourcc('P', 'M', '2', '1')
34 #define V4L2_PIX_FMT_NV16M_P210 v4l2_fourcc('P', 'M', '1', '6')
35 #define V4L2_PIX_FMT_NV61M_P210 v4l2_fourcc('P', 'M', '6', '1')
36 #define V4L2_PIX_FMT_NV12_P010 v4l2_fourcc('P', 'N', '1', '2')
37 #define V4L2_PIX_FMT_ARGB2101010 v4l2_fourcc('A', 'R', '3', '0')
38 #define V4L2_PIX_FMT_ABGR2101010 v4l2_fourcc('A', 'R', '1', '0')
39 #define V4L2_PIX_FMT_RGBA1010102 v4l2_fourcc('R', 'A', '3', '0')
40 #define V4L2_PIX_FMT_BGRA1010102 v4l2_fourcc('B', 'A', '1', '0')
41
42 /* 12 Y/CbCr 4:2:0 SBWC */
43 #define V4L2_PIX_FMT_NV12M_SBWC_8B v4l2_fourcc('M', '1', 'S', '8')
44 #define V4L2_PIX_FMT_NV12M_SBWC_10B v4l2_fourcc('M', '1', 'S', '1')
45 /* 21 Y/CrCb 4:2:0 SBWC */
46 #define V4L2_PIX_FMT_NV21M_SBWC_8B v4l2_fourcc('M', '2', 'S', '8')
47 #define V4L2_PIX_FMT_NV21M_SBWC_10B v4l2_fourcc('M', '2', 'S', '1')
48 /* 12 Y/CbCr 4:2:0 SBWC single */
49 #define V4L2_PIX_FMT_NV12N_SBWC_8B v4l2_fourcc('N', '1', 'S', '8')
50 #define V4L2_PIX_FMT_NV12N_SBWC_10B v4l2_fourcc('N', '1', 'S', '1')
51 /* 12 Y/CbCr 4:2:0 SBWC Lossy */
52 #define V4L2_PIX_FMT_NV12M_SBWCL_8B v4l2_fourcc('M', '1', 'L', '8')
53 #define V4L2_PIX_FMT_NV12M_SBWCL_10B v4l2_fourcc('M', '1', 'L', '1')
54 /* 12 Y/CbCr 4:2:0 SBWC Lossy single */
55 #define V4L2_PIX_FMT_NV12N_SBWCL_8B v4l2_fourcc('N', '1', 'L', '8')
56 #define V4L2_PIX_FMT_NV12N_SBWCL_10B v4l2_fourcc('N', '1', 'L', '1')
57
58
59 static uint32_t __halfmt_to_v4l2_rgb[][2] = {
60 {HAL_PIXEL_FORMAT_RGBA_8888, V4L2_PIX_FMT_ABGR32 },
61 {HAL_PIXEL_FORMAT_BGRA_8888, V4L2_PIX_FMT_ARGB32 },
62 {HAL_PIXEL_FORMAT_RGBX_8888, V4L2_PIX_FMT_XBGR32 },
63 {HAL_PIXEL_FORMAT_RGB_888, V4L2_PIX_FMT_RGB24 },
64 {HAL_PIXEL_FORMAT_RGB_565, V4L2_PIX_FMT_RGB565 },
65 };
66
67 // The V4L2_PIX_FMT_RGB32, V4L2_PIX_FMT_BGR32 are deprecated in V4L2.
68 // But the legacy mscl driver and libhwcutils requires them.
69 static uint32_t __halfmt_to_v4l2_rgb_deprecated[][2] = {
70 {HAL_PIXEL_FORMAT_RGBA_8888, V4L2_PIX_FMT_RGB32 },
71 {HAL_PIXEL_FORMAT_BGRA_8888, V4L2_PIX_FMT_BGR32 },
72 {HAL_PIXEL_FORMAT_RGBX_8888, V4L2_PIX_FMT_RGB32 },
73 {HAL_PIXEL_FORMAT_RGB_888, V4L2_PIX_FMT_RGB24 },
74 {HAL_PIXEL_FORMAT_RGB_565, V4L2_PIX_FMT_RGB565 },
75 {HAL_PIXEL_FORMAT_RGBA_1010102, V4L2_PIX_FMT_ABGR2101010 },
76 };
77
78 static uint32_t __halfmt_to_v4l2_ycbcr[][2] = {
79 {HAL_PIXEL_FORMAT_YV12, V4L2_PIX_FMT_YVU420 },
80 {HAL_PIXEL_FORMAT_EXYNOS_YV12_M, V4L2_PIX_FMT_YVU420M },
81 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P, V4L2_PIX_FMT_YUV420 },
82 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN, V4L2_PIX_FMT_YUV420N },
83 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M, V4L2_PIX_FMT_YUV420M },
84 {HAL_PIXEL_FORMAT_YCrCb_420_SP, V4L2_PIX_FMT_NV21 },
85 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, V4L2_PIX_FMT_NV21M },
86 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, V4L2_PIX_FMT_NV21M },
87 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, V4L2_PIX_FMT_NV12 },
88 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, V4L2_PIX_FMT_NV12N },
89 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, V4L2_PIX_FMT_NV12M },
90 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV, V4L2_PIX_FMT_NV12M },
91 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B, V4L2_PIX_FMT_NV12N_10B },
92 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B, V4L2_PIX_FMT_NV12M_S10B },
93 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, V4L2_PIX_FMT_NV12M_P010 },
94 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_SPN, V4L2_PIX_FMT_NV12_P010 },
95 {HAL_PIXEL_FORMAT_YCBCR_P010, V4L2_PIX_FMT_NV12_P010 },
96 {HAL_PIXEL_FORMAT_YCbCr_422_I, V4L2_PIX_FMT_YUYV },
97 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_422_I, V4L2_PIX_FMT_YVYU },
98 {HAL_PIXEL_FORMAT_YCbCr_422_SP, V4L2_PIX_FMT_NV16 },
99 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC, V4L2_PIX_FMT_NV12M_SBWC_8B },
100 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC, V4L2_PIX_FMT_NV12M_SBWC_10B },
101 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC, V4L2_PIX_FMT_NV21M_SBWC_8B },
102 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC, V4L2_PIX_FMT_NV21M_SBWC_10B },
103 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC, V4L2_PIX_FMT_NV12N_SBWC_8B },
104 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC, V4L2_PIX_FMT_NV12N_SBWC_10B },
105 };
106
halfmt_to_v4l2_ycbcr(uint32_t halfmt)107 static uint32_t halfmt_to_v4l2_ycbcr(uint32_t halfmt)
108 {
109 for (size_t i = 0 ; i < ARRSIZE(__halfmt_to_v4l2_ycbcr); i++) {
110 if (__halfmt_to_v4l2_ycbcr[i][0] == halfmt)
111 return __halfmt_to_v4l2_ycbcr[i][1];
112 }
113
114 ALOGE("Unable to find the proper v4l2 format for HAL format %#x", halfmt);
115
116 return 0; // it is alright to return 0 for an error because a fmt identifier is 4cc value
117 }
118
halfmt_to_v4l2(uint32_t halfmt)119 uint32_t halfmt_to_v4l2(uint32_t halfmt)
120 {
121 for (size_t i = 0 ; i < ARRSIZE(__halfmt_to_v4l2_rgb); i++) {
122 if (__halfmt_to_v4l2_rgb[i][0] == halfmt)
123 return __halfmt_to_v4l2_rgb[i][1];
124 }
125
126 return halfmt_to_v4l2_ycbcr(halfmt);
127 }
128
halfmt_to_v4l2_deprecated(uint32_t halfmt)129 uint32_t halfmt_to_v4l2_deprecated(uint32_t halfmt)
130 {
131 for (size_t i = 0 ; i < ARRSIZE(__halfmt_to_v4l2_rgb_deprecated); i++) {
132 if (__halfmt_to_v4l2_rgb_deprecated[i][0] == halfmt)
133 return __halfmt_to_v4l2_rgb_deprecated[i][1];
134 }
135
136 return halfmt_to_v4l2_ycbcr(halfmt);
137 }
138
139
140 static struct {
141 uint32_t fmt; // HAL_PIXEL_FORMAT that describe how pixels are stored in memory
142 uint8_t bufcnt; // the number of buffer to describe @fmt
143 uint8_t subfactor; // Horizontal (upper 4 bits)and vertical (lower 4 bits) chroma subsampling factor
144 uint8_t bpp[MAX_HW2D_PLANES]; // bits in a buffer per pixel
145 uint32_t equivalent; // The equivalent format on a single buffer without H/W constraints
146 uint8_t planecnt; // the number of planes to describe @fmt
147 } __halfmt_plane_bpp[] = {
148 {HAL_PIXEL_FORMAT_RGBA_8888, 1, 0x11, {32, 0, 0, 0}, HAL_PIXEL_FORMAT_RGBA_8888, 1},
149 {HAL_PIXEL_FORMAT_BGRA_8888, 1, 0x11, {32, 0, 0, 0}, HAL_PIXEL_FORMAT_BGRA_8888, 1},
150 {HAL_PIXEL_FORMAT_RGBA_1010102, 1, 0x11, {32, 0, 0, 0}, HAL_PIXEL_FORMAT_RGBA_1010102, 1},
151 {HAL_PIXEL_FORMAT_RGBX_8888, 1, 0x11, {32, 0, 0, 0}, HAL_PIXEL_FORMAT_RGBX_8888, 1},
152 {HAL_PIXEL_FORMAT_RGB_888, 1, 0x11, {24, 0, 0, 0}, HAL_PIXEL_FORMAT_RGB_888, 1},
153 {HAL_PIXEL_FORMAT_RGB_565, 1, 0x11, {16, 0, 0, 0}, HAL_PIXEL_FORMAT_RGB_565, 1},
154 {HAL_PIXEL_FORMAT_YCbCr_422_I, 1, 0x21, {16, 0, 0, 0}, HAL_PIXEL_FORMAT_YCbCr_422_I, 1},
155 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_422_I, 1, 0x21, {16, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCrCb_422_I, 1},
156 {HAL_PIXEL_FORMAT_YCbCr_422_SP, 1, 0x21, {16, 0, 0, 0}, HAL_PIXEL_FORMAT_YCbCr_422_SP, 2},
157 {HAL_PIXEL_FORMAT_YV12, 1, 0x22, {12, 0, 0, 0}, HAL_PIXEL_FORMAT_YV12, 2},
158 {HAL_PIXEL_FORMAT_EXYNOS_YV12_M, 3, 0x22, { 8, 2, 2, 0}, HAL_PIXEL_FORMAT_YV12, 2},
159 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P, 1, 0x22, {12, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P, 2},
160 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_PN, 1, 0x22, {12, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P, 2},
161 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M, 3, 0x22, { 8, 2, 2, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P, 2},
162 {HAL_PIXEL_FORMAT_YCrCb_420_SP, 1, 0x22, {12, 0, 0, 0}, HAL_PIXEL_FORMAT_YCrCb_420_SP, 2},
163 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M, 2, 0x22, { 8, 4, 0, 0}, HAL_PIXEL_FORMAT_YCrCb_420_SP, 2},
164 {HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL, 2, 0x22, { 8, 4, 0, 0}, HAL_PIXEL_FORMAT_YCrCb_420_SP, 2},
165 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, 1, 0x22, {12, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, 2},
166 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN, 1, 0x22, {12, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, 2},
167 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_TILED, 1, 0x22, {12, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, 2},
168 {HAL_PIXEL_FORMAT_GOOGLE_NV12_SP, 1, 0x22, {12, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, 2},
169 {MALI_GRALLOC_FORMAT_INTERNAL_YUV420_8BIT_I, 1, 0x22, {12, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, 2},
170 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M, 2, 0x22, { 8, 4, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, 2},
171 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV, 2, 0x22, { 8, 4, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, 2},
172 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED, 2, 0x22, { 8, 4, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP, 2},
173 {HAL_PIXEL_FORMAT_YCBCR_P010, 1, 0x22, {24, 0, 0, 0}, HAL_PIXEL_FORMAT_YCBCR_P010, 2},
174 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M, 2, 0x22, {16, 8, 0, 0}, HAL_PIXEL_FORMAT_YCBCR_P010, 2},
175 {HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B, 1, 0x22, {24, 0, 0, 0}, HAL_PIXEL_FORMAT_YCBCR_P010, 2},
176 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_SPN, 1, 0x22, {24, 0, 0, 0}, HAL_PIXEL_FORMAT_YCBCR_P010, 2},
177 {MALI_GRALLOC_FORMAT_INTERNAL_YUV420_10BIT_I, 1, 0x22, {15, 0, 0, 0}, HAL_PIXEL_FORMAT_YCBCR_P010, 2},
178 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC, 2, 0x22, { 8, 4, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC, 2},
179 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC, 1, 0x22, {12, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC, 2},
180 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC, 2, 0x22, {16, 8, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC, 2},
181 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC, 1, 0x22, {24, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC, 2},
182 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50, 2, 0x22, {8, 4, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50, 2},
183 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50, 1, 0x22, {12, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50, 2},
184 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75, 2, 0x22, {8, 4, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75, 2},
185 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75, 1, 0x22, {12, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75, 2},
186 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40, 2, 0x22, {16, 8, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40, 2},
187 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40, 1, 0x22, {24, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40, 2},
188 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60, 2,0x22, {16, 8, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60, 2},
189 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60, 1, 0x22, {24, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60, 2},
190 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80, 2, 0x22, {16, 8, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80, 2},
191 {HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80, 1, 0x22, {24, 0, 0, 0}, HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80, 2},
192 };
193
194 #define MFC_PAD_SIZE 256
195 #define MFC_2B_PAD_SIZE (MFC_PAD_SIZE / 4)
196 #define MFC_ALIGN(v) (((v) + 15) & ~15)
197
198 #define NV12_MFC_Y_PAYLOAD(w, h) (MFC_ALIGN(w) * MFC_ALIGN(h))
199 #define NV12_MFC_C_PAYLOAD(w, h) (MFC_ALIGN(w) * MFC_ALIGN(h) / 2)
200 #define NV12_MFC_PAYLOAD(w, h) (NV12_MFC_Y_PAYLOAD(w, h) + MFC_PAD_SIZE + (MFC_ALIGN(w) * (h) / 2))
201
halfmt_plane_length(uint32_t fmt,unsigned int plane,uint32_t width,uint32_t height)202 size_t halfmt_plane_length(uint32_t fmt, unsigned int plane, uint32_t width, uint32_t height)
203 {
204 for (size_t i = 0; i < ARRSIZE(__halfmt_plane_bpp); i++) {
205 if (__halfmt_plane_bpp[i].fmt == fmt) {
206 LOGASSERT(plane < __halfmt_plane_bpp[i].bufcnt,
207 "Plane count of HAL format %#x is %u but %d plane is requested", fmt,
208 __halfmt_plane_bpp[i].bufcnt, plane);
209 if (plane < __halfmt_plane_bpp[i].bufcnt)
210 return (__halfmt_plane_bpp[i].bpp[plane] * width * height) / 8;
211 }
212 }
213
214 LOGASSERT(1, "Unable to find HAL format %#x with plane %d", fmt, plane);
215
216 return 0;
217 }
218
halfmt_bpp(uint32_t fmt)219 unsigned int halfmt_bpp(uint32_t fmt)
220 {
221 for (size_t i = 0 ; i < ARRSIZE(__halfmt_plane_bpp); i++) {
222 if (__halfmt_plane_bpp[i].fmt == fmt)
223 return __halfmt_plane_bpp[i].bpp[0] + __halfmt_plane_bpp[i].bpp[1] + __halfmt_plane_bpp[i].bpp[2];
224 }
225
226 LOGASSERT(1, "Unable to find HAL format %#x", fmt);
227
228 return 0;
229 }
230
231 #define DEFINE_HALFMT_PROPERTY_GETTER(rettype, funcname, member) \
232 rettype funcname(uint32_t fmt) \
233 { \
234 for (size_t i = 0 ; i < ARRSIZE(__halfmt_plane_bpp); i++) { \
235 if (__halfmt_plane_bpp[i].fmt == fmt) \
236 return __halfmt_plane_bpp[i].member; \
237 } \
238 LOGASSERT(1, "Unable to find HAL format %#x", fmt); \
239 return 0; \
240 }
241
242 DEFINE_HALFMT_PROPERTY_GETTER(unsigned int, halfmt_buf_count, bufcnt)
243 DEFINE_HALFMT_PROPERTY_GETTER(uint8_t, halfmt_chroma_subsampling, subfactor)
244 DEFINE_HALFMT_PROPERTY_GETTER(uint32_t, find_format_equivalent, equivalent)
245 DEFINE_HALFMT_PROPERTY_GETTER(uint8_t, halfmt_plane_count, planecnt)
246
247 static struct {
248 int32_t hal;
249 uint32_t v4l2;
250 } __haldataspace_to_v4l2[] = {
251 {HAL_DATASPACE_STANDARD_BT709 | HAL_DATASPACE_RANGE_FULL, V4L2_COLORSPACE_SRGB},
252 {HAL_DATASPACE_STANDARD_BT709 | HAL_DATASPACE_RANGE_LIMITED, V4L2_COLORSPACE_REC709},
253 {HAL_DATASPACE_STANDARD_BT601_625 | HAL_DATASPACE_RANGE_FULL, V4L2_COLORSPACE_JPEG},
254 {HAL_DATASPACE_STANDARD_BT601_525 | HAL_DATASPACE_RANGE_FULL, V4L2_COLORSPACE_JPEG},
255 {HAL_DATASPACE_STANDARD_BT601_625 | HAL_DATASPACE_RANGE_LIMITED, V4L2_COLORSPACE_SMPTE170M},
256 {HAL_DATASPACE_STANDARD_BT601_525 | HAL_DATASPACE_RANGE_LIMITED, V4L2_COLORSPACE_SMPTE170M},
257 {HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_RANGE_LIMITED, V4L2_COLORSPACE_BT2020},
258 {HAL_DATASPACE_STANDARD_FILM | HAL_DATASPACE_RANGE_FULL, V4L2_COLORSPACE_SRGB},
259 {HAL_DATASPACE_STANDARD_FILM | HAL_DATASPACE_RANGE_LIMITED, V4L2_COLORSPACE_REC709},
260 {HAL_DATASPACE_SRGB, V4L2_COLORSPACE_SRGB},
261 {HAL_DATASPACE_JFIF, V4L2_COLORSPACE_JPEG},
262 {HAL_DATASPACE_BT601_525, V4L2_COLORSPACE_SMPTE170M},
263 {HAL_DATASPACE_BT601_625, V4L2_COLORSPACE_SMPTE170M},
264 {HAL_DATASPACE_BT709, V4L2_COLORSPACE_REC709},
265 };
266
267 #define HAL_DATASPACE_LEGACY_TYPE_MASK ((1 << HAL_DATASPACE_STANDARD_SHIFT) - 1)
268
haldataspace_to_v4l2(int dataspace,uint32_t width,uint32_t height)269 uint32_t haldataspace_to_v4l2(int dataspace, uint32_t width, uint32_t height)
270 {
271 // if legacy type, discard upper bits above 15th
272 if ((dataspace & HAL_DATASPACE_LEGACY_TYPE_MASK) != 0) {
273 dataspace &= HAL_DATASPACE_LEGACY_TYPE_MASK;
274 } else {
275 dataspace &= ~HAL_DATASPACE_LEGACY_TYPE_MASK;
276 // if Y value range is not specified, force it to the limited.
277 if ((dataspace & HAL_DATASPACE_RANGE_MASK) == 0)
278 dataspace |= HAL_DATASPACE_RANGE_LIMITED;
279 // if colorspace is not specified, force it to 709 or 601 according to the resolution
280 if ((dataspace & HAL_DATASPACE_STANDARD_MASK) == 0)
281 dataspace |= ((width * height) < (1280 * 720))
282 ? HAL_DATASPACE_STANDARD_BT601_625
283 : HAL_DATASPACE_STANDARD_BT709;
284 // discard transfer function type values because it is not required during color space conviersion
285 dataspace &= ~HAL_DATASPACE_TRANSFER_MASK;
286 }
287 for (size_t i = 0 ; i < ARRSIZE(__haldataspace_to_v4l2); i++) {
288 if (__haldataspace_to_v4l2[i].hal == dataspace)
289 return __haldataspace_to_v4l2[i].v4l2;
290 }
291
292 LOGASSERT(1, "Unable to find HAL dataspace value %#x", dataspace);
293
294 return V4L2_COLORSPACE_DEFAULT;
295 }
296