]>
Commit | Line | Data |
---|---|---|
2dd62390 | 1 | // SPDX-License-Identifier: LGPL-2.1 |
cd12b401 HV |
2 | /* |
3 | * A V4L2 frontend for the FWHT codec | |
4 | * | |
5 | * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | |
6 | */ | |
7 | ||
8 | #include <linux/errno.h> | |
9 | #include <linux/string.h> | |
10 | #include <linux/videodev2.h> | |
11 | #include "codec-v4l2-fwht.h" | |
12 | ||
13 | static const struct v4l2_fwht_pixfmt_info v4l2_fwht_pixfmts[] = { | |
5fbd0729 DH |
14 | { V4L2_PIX_FMT_YUV420, 1, 3, 2, 1, 1, 2, 2, 3, 3, FWHT_FL_PIXENC_YUV}, |
15 | { V4L2_PIX_FMT_YVU420, 1, 3, 2, 1, 1, 2, 2, 3, 3, FWHT_FL_PIXENC_YUV}, | |
16 | { V4L2_PIX_FMT_YUV422P, 1, 2, 1, 1, 1, 2, 1, 3, 3, FWHT_FL_PIXENC_YUV}, | |
17 | { V4L2_PIX_FMT_NV12, 1, 3, 2, 1, 2, 2, 2, 3, 2, FWHT_FL_PIXENC_YUV}, | |
18 | { V4L2_PIX_FMT_NV21, 1, 3, 2, 1, 2, 2, 2, 3, 2, FWHT_FL_PIXENC_YUV}, | |
19 | { V4L2_PIX_FMT_NV16, 1, 2, 1, 1, 2, 2, 1, 3, 2, FWHT_FL_PIXENC_YUV}, | |
20 | { V4L2_PIX_FMT_NV61, 1, 2, 1, 1, 2, 2, 1, 3, 2, FWHT_FL_PIXENC_YUV}, | |
21 | { V4L2_PIX_FMT_NV24, 1, 3, 1, 1, 2, 1, 1, 3, 2, FWHT_FL_PIXENC_YUV}, | |
22 | { V4L2_PIX_FMT_NV42, 1, 3, 1, 1, 2, 1, 1, 3, 2, FWHT_FL_PIXENC_YUV}, | |
23 | { V4L2_PIX_FMT_YUYV, 2, 2, 1, 2, 4, 2, 1, 3, 1, FWHT_FL_PIXENC_YUV}, | |
24 | { V4L2_PIX_FMT_YVYU, 2, 2, 1, 2, 4, 2, 1, 3, 1, FWHT_FL_PIXENC_YUV}, | |
25 | { V4L2_PIX_FMT_UYVY, 2, 2, 1, 2, 4, 2, 1, 3, 1, FWHT_FL_PIXENC_YUV}, | |
26 | { V4L2_PIX_FMT_VYUY, 2, 2, 1, 2, 4, 2, 1, 3, 1, FWHT_FL_PIXENC_YUV}, | |
27 | { V4L2_PIX_FMT_BGR24, 3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, | |
28 | { V4L2_PIX_FMT_RGB24, 3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, | |
29 | { V4L2_PIX_FMT_HSV24, 3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV}, | |
30 | { V4L2_PIX_FMT_BGR32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, | |
31 | { V4L2_PIX_FMT_XBGR32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, | |
32 | { V4L2_PIX_FMT_RGB32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, | |
33 | { V4L2_PIX_FMT_XRGB32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, | |
34 | { V4L2_PIX_FMT_HSV32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV}, | |
35 | { V4L2_PIX_FMT_ARGB32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, | |
36 | { V4L2_PIX_FMT_ABGR32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, | |
37 | { V4L2_PIX_FMT_GREY, 1, 1, 1, 1, 0, 1, 1, 1, 1, FWHT_FL_PIXENC_RGB}, | |
cd12b401 HV |
38 | }; |
39 | ||
5fbd0729 DH |
40 | const struct v4l2_fwht_pixfmt_info *v4l2_fwht_default_fmt(u32 width_div, |
41 | u32 height_div, | |
42 | u32 components_num, | |
43 | u32 pixenc, | |
44 | unsigned int start_idx) | |
45 | { | |
46 | unsigned int i; | |
47 | ||
48 | for (i = 0; i < ARRAY_SIZE(v4l2_fwht_pixfmts); i++) { | |
49 | if (v4l2_fwht_pixfmts[i].width_div == width_div && | |
50 | v4l2_fwht_pixfmts[i].height_div == height_div && | |
51 | (!pixenc || v4l2_fwht_pixfmts[i].pixenc == pixenc) && | |
52 | v4l2_fwht_pixfmts[i].components_num == components_num) { | |
53 | if (start_idx == 0) | |
54 | return v4l2_fwht_pixfmts + i; | |
55 | start_idx--; | |
56 | } | |
57 | } | |
58 | return NULL; | |
59 | } | |
60 | ||
cd12b401 HV |
61 | const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt(u32 pixelformat) |
62 | { | |
63 | unsigned int i; | |
64 | ||
65 | for (i = 0; i < ARRAY_SIZE(v4l2_fwht_pixfmts); i++) | |
66 | if (v4l2_fwht_pixfmts[i].id == pixelformat) | |
67 | return v4l2_fwht_pixfmts + i; | |
68 | return NULL; | |
69 | } | |
70 | ||
71 | const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt(u32 idx) | |
72 | { | |
73 | if (idx >= ARRAY_SIZE(v4l2_fwht_pixfmts)) | |
74 | return NULL; | |
75 | return v4l2_fwht_pixfmts + idx; | |
76 | } | |
77 | ||
d61b3b41 | 78 | int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) |
cd12b401 | 79 | { |
9e812549 DH |
80 | unsigned int size = state->stride * state->coded_height; |
81 | unsigned int chroma_stride = state->stride; | |
cd12b401 HV |
82 | const struct v4l2_fwht_pixfmt_info *info = state->info; |
83 | struct fwht_cframe_hdr *p_hdr; | |
84 | struct fwht_cframe cf; | |
85 | struct fwht_raw_frame rf; | |
86 | u32 encoding; | |
87 | u32 flags = 0; | |
88 | ||
d61b3b41 HV |
89 | if (!info) |
90 | return -EINVAL; | |
9e812549 | 91 | |
cd12b401 HV |
92 | rf.luma = p_in; |
93 | rf.width_div = info->width_div; | |
94 | rf.height_div = info->height_div; | |
aec89917 | 95 | rf.luma_alpha_step = info->luma_alpha_step; |
cd12b401 | 96 | rf.chroma_step = info->chroma_step; |
aec89917 DH |
97 | rf.alpha = NULL; |
98 | rf.components_num = info->components_num; | |
cd12b401 HV |
99 | |
100 | switch (info->id) { | |
19505719 DH |
101 | case V4L2_PIX_FMT_GREY: |
102 | rf.cb = NULL; | |
103 | rf.cr = NULL; | |
104 | break; | |
cd12b401 HV |
105 | case V4L2_PIX_FMT_YUV420: |
106 | rf.cb = rf.luma + size; | |
107 | rf.cr = rf.cb + size / 4; | |
9e812549 | 108 | chroma_stride /= 2; |
cd12b401 HV |
109 | break; |
110 | case V4L2_PIX_FMT_YVU420: | |
111 | rf.cr = rf.luma + size; | |
112 | rf.cb = rf.cr + size / 4; | |
9e812549 | 113 | chroma_stride /= 2; |
cd12b401 HV |
114 | break; |
115 | case V4L2_PIX_FMT_YUV422P: | |
116 | rf.cb = rf.luma + size; | |
117 | rf.cr = rf.cb + size / 2; | |
9e812549 | 118 | chroma_stride /= 2; |
cd12b401 HV |
119 | break; |
120 | case V4L2_PIX_FMT_NV12: | |
121 | case V4L2_PIX_FMT_NV16: | |
122 | case V4L2_PIX_FMT_NV24: | |
123 | rf.cb = rf.luma + size; | |
124 | rf.cr = rf.cb + 1; | |
125 | break; | |
126 | case V4L2_PIX_FMT_NV21: | |
127 | case V4L2_PIX_FMT_NV61: | |
128 | case V4L2_PIX_FMT_NV42: | |
129 | rf.cr = rf.luma + size; | |
130 | rf.cb = rf.cr + 1; | |
131 | break; | |
132 | case V4L2_PIX_FMT_YUYV: | |
133 | rf.cb = rf.luma + 1; | |
134 | rf.cr = rf.cb + 2; | |
135 | break; | |
136 | case V4L2_PIX_FMT_YVYU: | |
137 | rf.cr = rf.luma + 1; | |
138 | rf.cb = rf.cr + 2; | |
139 | break; | |
140 | case V4L2_PIX_FMT_UYVY: | |
141 | rf.cb = rf.luma; | |
142 | rf.cr = rf.cb + 2; | |
143 | rf.luma++; | |
144 | break; | |
145 | case V4L2_PIX_FMT_VYUY: | |
146 | rf.cr = rf.luma; | |
147 | rf.cb = rf.cr + 2; | |
148 | rf.luma++; | |
149 | break; | |
150 | case V4L2_PIX_FMT_RGB24: | |
151 | case V4L2_PIX_FMT_HSV24: | |
152 | rf.cr = rf.luma; | |
153 | rf.cb = rf.cr + 2; | |
154 | rf.luma++; | |
155 | break; | |
156 | case V4L2_PIX_FMT_BGR24: | |
157 | rf.cb = rf.luma; | |
158 | rf.cr = rf.cb + 2; | |
159 | rf.luma++; | |
160 | break; | |
161 | case V4L2_PIX_FMT_RGB32: | |
162 | case V4L2_PIX_FMT_XRGB32: | |
163 | case V4L2_PIX_FMT_HSV32: | |
164 | rf.cr = rf.luma + 1; | |
165 | rf.cb = rf.cr + 2; | |
166 | rf.luma += 2; | |
167 | break; | |
168 | case V4L2_PIX_FMT_BGR32: | |
169 | case V4L2_PIX_FMT_XBGR32: | |
170 | rf.cb = rf.luma; | |
171 | rf.cr = rf.cb + 2; | |
172 | rf.luma++; | |
173 | break; | |
16ecf6df DH |
174 | case V4L2_PIX_FMT_ARGB32: |
175 | rf.alpha = rf.luma; | |
176 | rf.cr = rf.luma + 1; | |
177 | rf.cb = rf.cr + 2; | |
178 | rf.luma += 2; | |
179 | break; | |
180 | case V4L2_PIX_FMT_ABGR32: | |
181 | rf.cb = rf.luma; | |
182 | rf.cr = rf.cb + 2; | |
183 | rf.luma++; | |
184 | rf.alpha = rf.cr + 1; | |
185 | break; | |
d61b3b41 HV |
186 | default: |
187 | return -EINVAL; | |
cd12b401 HV |
188 | } |
189 | ||
cd12b401 HV |
190 | cf.i_frame_qp = state->i_frame_qp; |
191 | cf.p_frame_qp = state->p_frame_qp; | |
192 | cf.rlc_data = (__be16 *)(p_out + sizeof(*p_hdr)); | |
193 | ||
194 | encoding = fwht_encode_frame(&rf, &state->ref_frame, &cf, | |
195 | !state->gop_cnt, | |
9e812549 DH |
196 | state->gop_cnt == state->gop_size - 1, |
197 | state->visible_width, | |
198 | state->visible_height, | |
199 | state->stride, chroma_stride); | |
cd12b401 HV |
200 | if (!(encoding & FWHT_FRAME_PCODED)) |
201 | state->gop_cnt = 0; | |
202 | if (++state->gop_cnt >= state->gop_size) | |
203 | state->gop_cnt = 0; | |
204 | ||
205 | p_hdr = (struct fwht_cframe_hdr *)p_out; | |
206 | p_hdr->magic1 = FWHT_MAGIC1; | |
207 | p_hdr->magic2 = FWHT_MAGIC2; | |
208 | p_hdr->version = htonl(FWHT_VERSION); | |
9e812549 DH |
209 | p_hdr->width = htonl(state->visible_width); |
210 | p_hdr->height = htonl(state->visible_height); | |
19505719 | 211 | flags |= (info->components_num - 1) << FWHT_FL_COMPONENTS_NUM_OFFSET; |
5fbd0729 | 212 | flags |= info->pixenc; |
cd12b401 HV |
213 | if (encoding & FWHT_LUMA_UNENCODED) |
214 | flags |= FWHT_FL_LUMA_IS_UNCOMPRESSED; | |
215 | if (encoding & FWHT_CB_UNENCODED) | |
216 | flags |= FWHT_FL_CB_IS_UNCOMPRESSED; | |
217 | if (encoding & FWHT_CR_UNENCODED) | |
218 | flags |= FWHT_FL_CR_IS_UNCOMPRESSED; | |
16ecf6df DH |
219 | if (encoding & FWHT_ALPHA_UNENCODED) |
220 | flags |= FWHT_FL_ALPHA_IS_UNCOMPRESSED; | |
75e3e5b8 DH |
221 | if (!(encoding & FWHT_FRAME_PCODED)) |
222 | flags |= FWHT_FL_I_FRAME; | |
cd12b401 HV |
223 | if (rf.height_div == 1) |
224 | flags |= FWHT_FL_CHROMA_FULL_HEIGHT; | |
225 | if (rf.width_div == 1) | |
226 | flags |= FWHT_FL_CHROMA_FULL_WIDTH; | |
227 | p_hdr->flags = htonl(flags); | |
228 | p_hdr->colorspace = htonl(state->colorspace); | |
229 | p_hdr->xfer_func = htonl(state->xfer_func); | |
230 | p_hdr->ycbcr_enc = htonl(state->ycbcr_enc); | |
231 | p_hdr->quantization = htonl(state->quantization); | |
232 | p_hdr->size = htonl(cf.size); | |
cd12b401 HV |
233 | return cf.size + sizeof(*p_hdr); |
234 | } | |
235 | ||
d61b3b41 | 236 | int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) |
cd12b401 | 237 | { |
9e812549 | 238 | unsigned int i, j, k; |
cd12b401 | 239 | u32 flags; |
cd12b401 | 240 | struct fwht_cframe cf; |
9e812549 | 241 | u8 *p, *ref_p; |
19505719 DH |
242 | unsigned int components_num = 3; |
243 | unsigned int version; | |
9e812549 DH |
244 | const struct v4l2_fwht_pixfmt_info *info; |
245 | unsigned int hdr_width_div, hdr_height_div; | |
cd12b401 | 246 | |
d61b3b41 HV |
247 | if (!state->info) |
248 | return -EINVAL; | |
249 | ||
9e812549 | 250 | info = state->info; |
19505719 | 251 | |
ddc1b085 | 252 | version = ntohl(state->header.version); |
19505719 DH |
253 | if (!version || version > FWHT_VERSION) { |
254 | pr_err("version %d is not supported, current version is %d\n", | |
255 | version, FWHT_VERSION); | |
256 | return -EINVAL; | |
257 | } | |
cd12b401 | 258 | |
ddc1b085 DH |
259 | if (state->header.magic1 != FWHT_MAGIC1 || |
260 | state->header.magic2 != FWHT_MAGIC2) | |
cd12b401 HV |
261 | return -EINVAL; |
262 | ||
263 | /* TODO: support resolution changes */ | |
ddc1b085 DH |
264 | if (ntohl(state->header.width) != state->visible_width || |
265 | ntohl(state->header.height) != state->visible_height) | |
cd12b401 HV |
266 | return -EINVAL; |
267 | ||
ddc1b085 | 268 | flags = ntohl(state->header.flags); |
19505719 | 269 | |
75e3e5b8 | 270 | if (version >= 2) { |
5fbd0729 DH |
271 | if ((flags & FWHT_FL_PIXENC_MSK) != info->pixenc) |
272 | return -EINVAL; | |
19505719 | 273 | components_num = 1 + ((flags & FWHT_FL_COMPONENTS_NUM_MSK) >> |
5fbd0729 | 274 | FWHT_FL_COMPONENTS_NUM_OFFSET); |
19505719 DH |
275 | } |
276 | ||
5fbd0729 DH |
277 | if (components_num != info->components_num) |
278 | return -EINVAL; | |
279 | ||
ddc1b085 DH |
280 | state->colorspace = ntohl(state->header.colorspace); |
281 | state->xfer_func = ntohl(state->header.xfer_func); | |
282 | state->ycbcr_enc = ntohl(state->header.ycbcr_enc); | |
283 | state->quantization = ntohl(state->header.quantization); | |
284 | cf.rlc_data = (__be16 *)p_in; | |
f863f222 | 285 | cf.size = ntohl(state->header.size); |
19505719 | 286 | |
9e812549 DH |
287 | hdr_width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2; |
288 | hdr_height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2; | |
289 | if (hdr_width_div != info->width_div || | |
290 | hdr_height_div != info->height_div) | |
291 | return -EINVAL; | |
cd12b401 | 292 | |
f863f222 DH |
293 | if (!fwht_decode_frame(&cf, &state->ref_frame, flags, components_num, |
294 | state->visible_width, state->visible_height, | |
295 | state->coded_width)) | |
296 | return -EINVAL; | |
cd12b401 | 297 | |
19505719 DH |
298 | /* |
299 | * TODO - handle the case where the compressed stream encodes a | |
300 | * different format than the requested decoded format. | |
301 | */ | |
cd12b401 | 302 | switch (state->info->id) { |
19505719 | 303 | case V4L2_PIX_FMT_GREY: |
9e812549 DH |
304 | ref_p = state->ref_frame.luma; |
305 | for (i = 0; i < state->coded_height; i++) { | |
306 | memcpy(p_out, ref_p, state->visible_width); | |
307 | p_out += state->stride; | |
308 | ref_p += state->coded_width; | |
309 | } | |
19505719 | 310 | break; |
cd12b401 HV |
311 | case V4L2_PIX_FMT_YUV420: |
312 | case V4L2_PIX_FMT_YUV422P: | |
9e812549 DH |
313 | ref_p = state->ref_frame.luma; |
314 | for (i = 0; i < state->coded_height; i++) { | |
315 | memcpy(p_out, ref_p, state->visible_width); | |
316 | p_out += state->stride; | |
317 | ref_p += state->coded_width; | |
318 | } | |
319 | ||
320 | ref_p = state->ref_frame.cb; | |
321 | for (i = 0; i < state->coded_height / 2; i++) { | |
322 | memcpy(p_out, ref_p, state->visible_width / 2); | |
323 | p_out += state->stride / 2; | |
324 | ref_p += state->coded_width / 2; | |
325 | } | |
326 | ref_p = state->ref_frame.cr; | |
327 | for (i = 0; i < state->coded_height / 2; i++) { | |
328 | memcpy(p_out, ref_p, state->visible_width / 2); | |
329 | p_out += state->stride / 2; | |
330 | ref_p += state->coded_width / 2; | |
331 | } | |
cd12b401 HV |
332 | break; |
333 | case V4L2_PIX_FMT_YVU420: | |
9e812549 DH |
334 | ref_p = state->ref_frame.luma; |
335 | for (i = 0; i < state->coded_height; i++) { | |
336 | memcpy(p_out, ref_p, state->visible_width); | |
337 | p_out += state->stride; | |
338 | ref_p += state->coded_width; | |
339 | } | |
340 | ||
341 | ref_p = state->ref_frame.cr; | |
342 | for (i = 0; i < state->coded_height / 2; i++) { | |
343 | memcpy(p_out, ref_p, state->visible_width / 2); | |
344 | p_out += state->stride / 2; | |
345 | ref_p += state->coded_width / 2; | |
346 | } | |
347 | ref_p = state->ref_frame.cb; | |
348 | for (i = 0; i < state->coded_height / 2; i++) { | |
349 | memcpy(p_out, ref_p, state->visible_width / 2); | |
350 | p_out += state->stride / 2; | |
351 | ref_p += state->coded_width / 2; | |
352 | } | |
cd12b401 HV |
353 | break; |
354 | case V4L2_PIX_FMT_NV12: | |
355 | case V4L2_PIX_FMT_NV16: | |
356 | case V4L2_PIX_FMT_NV24: | |
9e812549 DH |
357 | ref_p = state->ref_frame.luma; |
358 | for (i = 0; i < state->coded_height; i++) { | |
359 | memcpy(p_out, ref_p, state->visible_width); | |
360 | p_out += state->stride; | |
361 | ref_p += state->coded_width; | |
362 | } | |
363 | ||
364 | k = 0; | |
365 | for (i = 0; i < state->coded_height / 2; i++) { | |
366 | for (j = 0, p = p_out; j < state->coded_width / 2; j++) { | |
367 | *p++ = state->ref_frame.cb[k]; | |
368 | *p++ = state->ref_frame.cr[k]; | |
369 | k++; | |
370 | } | |
371 | p_out += state->stride; | |
cd12b401 HV |
372 | } |
373 | break; | |
374 | case V4L2_PIX_FMT_NV21: | |
375 | case V4L2_PIX_FMT_NV61: | |
376 | case V4L2_PIX_FMT_NV42: | |
9e812549 DH |
377 | ref_p = state->ref_frame.luma; |
378 | for (i = 0; i < state->coded_height; i++) { | |
379 | memcpy(p_out, ref_p, state->visible_width); | |
380 | p_out += state->stride; | |
381 | ref_p += state->coded_width; | |
382 | } | |
383 | ||
384 | k = 0; | |
385 | for (i = 0; i < state->coded_height / 2; i++) { | |
386 | for (j = 0, p = p_out; j < state->coded_width / 2; j++) { | |
387 | *p++ = state->ref_frame.cr[k]; | |
388 | *p++ = state->ref_frame.cb[k]; | |
389 | k++; | |
390 | } | |
391 | p_out += state->stride; | |
cd12b401 HV |
392 | } |
393 | break; | |
394 | case V4L2_PIX_FMT_YUYV: | |
9e812549 DH |
395 | k = 0; |
396 | for (i = 0; i < state->coded_height; i++) { | |
397 | for (j = 0, p = p_out; j < state->coded_width / 2; j++) { | |
398 | *p++ = state->ref_frame.luma[k]; | |
399 | *p++ = state->ref_frame.cb[k / 2]; | |
400 | *p++ = state->ref_frame.luma[k + 1]; | |
401 | *p++ = state->ref_frame.cr[k / 2]; | |
402 | k += 2; | |
403 | } | |
404 | p_out += state->stride; | |
cd12b401 HV |
405 | } |
406 | break; | |
407 | case V4L2_PIX_FMT_YVYU: | |
9e812549 DH |
408 | k = 0; |
409 | for (i = 0; i < state->coded_height; i++) { | |
410 | for (j = 0, p = p_out; j < state->coded_width / 2; j++) { | |
411 | *p++ = state->ref_frame.luma[k]; | |
412 | *p++ = state->ref_frame.cr[k / 2]; | |
413 | *p++ = state->ref_frame.luma[k + 1]; | |
414 | *p++ = state->ref_frame.cb[k / 2]; | |
415 | k += 2; | |
416 | } | |
417 | p_out += state->stride; | |
cd12b401 HV |
418 | } |
419 | break; | |
420 | case V4L2_PIX_FMT_UYVY: | |
9e812549 DH |
421 | k = 0; |
422 | for (i = 0; i < state->coded_height; i++) { | |
423 | for (j = 0, p = p_out; j < state->coded_width / 2; j++) { | |
424 | *p++ = state->ref_frame.cb[k / 2]; | |
425 | *p++ = state->ref_frame.luma[k]; | |
426 | *p++ = state->ref_frame.cr[k / 2]; | |
427 | *p++ = state->ref_frame.luma[k + 1]; | |
428 | k += 2; | |
429 | } | |
430 | p_out += state->stride; | |
cd12b401 HV |
431 | } |
432 | break; | |
433 | case V4L2_PIX_FMT_VYUY: | |
9e812549 DH |
434 | k = 0; |
435 | for (i = 0; i < state->coded_height; i++) { | |
436 | for (j = 0, p = p_out; j < state->coded_width / 2; j++) { | |
437 | *p++ = state->ref_frame.cr[k / 2]; | |
438 | *p++ = state->ref_frame.luma[k]; | |
439 | *p++ = state->ref_frame.cb[k / 2]; | |
440 | *p++ = state->ref_frame.luma[k + 1]; | |
441 | k += 2; | |
442 | } | |
443 | p_out += state->stride; | |
cd12b401 HV |
444 | } |
445 | break; | |
446 | case V4L2_PIX_FMT_RGB24: | |
447 | case V4L2_PIX_FMT_HSV24: | |
9e812549 DH |
448 | k = 0; |
449 | for (i = 0; i < state->coded_height; i++) { | |
450 | for (j = 0, p = p_out; j < state->coded_width; j++) { | |
451 | *p++ = state->ref_frame.cr[k]; | |
452 | *p++ = state->ref_frame.luma[k]; | |
453 | *p++ = state->ref_frame.cb[k]; | |
454 | k++; | |
455 | } | |
456 | p_out += state->stride; | |
cd12b401 HV |
457 | } |
458 | break; | |
459 | case V4L2_PIX_FMT_BGR24: | |
9e812549 DH |
460 | k = 0; |
461 | for (i = 0; i < state->coded_height; i++) { | |
462 | for (j = 0, p = p_out; j < state->coded_width; j++) { | |
463 | *p++ = state->ref_frame.cb[k]; | |
464 | *p++ = state->ref_frame.luma[k]; | |
465 | *p++ = state->ref_frame.cr[k]; | |
466 | k++; | |
467 | } | |
468 | p_out += state->stride; | |
cd12b401 HV |
469 | } |
470 | break; | |
471 | case V4L2_PIX_FMT_RGB32: | |
472 | case V4L2_PIX_FMT_XRGB32: | |
473 | case V4L2_PIX_FMT_HSV32: | |
9e812549 DH |
474 | k = 0; |
475 | for (i = 0; i < state->coded_height; i++) { | |
476 | for (j = 0, p = p_out; j < state->coded_width; j++) { | |
477 | *p++ = 0; | |
478 | *p++ = state->ref_frame.cr[k]; | |
479 | *p++ = state->ref_frame.luma[k]; | |
480 | *p++ = state->ref_frame.cb[k]; | |
481 | k++; | |
482 | } | |
483 | p_out += state->stride; | |
cd12b401 HV |
484 | } |
485 | break; | |
486 | case V4L2_PIX_FMT_BGR32: | |
487 | case V4L2_PIX_FMT_XBGR32: | |
9e812549 DH |
488 | k = 0; |
489 | for (i = 0; i < state->coded_height; i++) { | |
490 | for (j = 0, p = p_out; j < state->coded_width; j++) { | |
491 | *p++ = state->ref_frame.cb[k]; | |
492 | *p++ = state->ref_frame.luma[k]; | |
493 | *p++ = state->ref_frame.cr[k]; | |
494 | *p++ = 0; | |
495 | k++; | |
496 | } | |
497 | p_out += state->stride; | |
cd12b401 HV |
498 | } |
499 | break; | |
16ecf6df | 500 | case V4L2_PIX_FMT_ARGB32: |
9e812549 DH |
501 | k = 0; |
502 | for (i = 0; i < state->coded_height; i++) { | |
503 | for (j = 0, p = p_out; j < state->coded_width; j++) { | |
504 | *p++ = state->ref_frame.alpha[k]; | |
505 | *p++ = state->ref_frame.cr[k]; | |
506 | *p++ = state->ref_frame.luma[k]; | |
507 | *p++ = state->ref_frame.cb[k]; | |
508 | k++; | |
509 | } | |
510 | p_out += state->stride; | |
16ecf6df DH |
511 | } |
512 | break; | |
513 | case V4L2_PIX_FMT_ABGR32: | |
9e812549 DH |
514 | k = 0; |
515 | for (i = 0; i < state->coded_height; i++) { | |
516 | for (j = 0, p = p_out; j < state->coded_width; j++) { | |
517 | *p++ = state->ref_frame.cb[k]; | |
518 | *p++ = state->ref_frame.luma[k]; | |
519 | *p++ = state->ref_frame.cr[k]; | |
520 | *p++ = state->ref_frame.alpha[k]; | |
521 | k++; | |
522 | } | |
523 | p_out += state->stride; | |
16ecf6df DH |
524 | } |
525 | break; | |
d61b3b41 HV |
526 | default: |
527 | return -EINVAL; | |
cd12b401 HV |
528 | } |
529 | return 0; | |
530 | } |