FFmpeg
bayer_template.c
Go to the documentation of this file.
1 /*
2  * Bayer-to-RGB/YV12 template
3  * Copyright (c) 2011-2014 Peter Ross <pross@xvid.org>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #if defined(BAYER_BGGR) || defined(BAYER_GBRG)
23 #define BAYER_R 0
24 #define BAYER_G 1
25 #define BAYER_B 2
26 #endif
27 #if defined(BAYER_RGGB) || defined(BAYER_GRBG)
28 #define BAYER_R 2
29 #define BAYER_G 1
30 #define BAYER_B 0
31 #endif
32 
33 #if defined(BAYER_8)
34 #define BAYER_READ(x) (x)
35 #define BAYER_SIZEOF 1
36 #define BAYER_SHIFT 0
37 #endif
38 #if defined(BAYER_16LE)
39 #define BAYER_READ(x) AV_RL16(&(x))
40 #define BAYER_SIZEOF 2
41 #define BAYER_SHIFT 8
42 #endif
43 #if defined(BAYER_16BE)
44 #define BAYER_READ(x) AV_RB16(&(x))
45 #define BAYER_SIZEOF 2
46 #define BAYER_SHIFT 8
47 #endif
48 
49 #define S(y, x) BAYER_READ(src[(y)*src_stride + BAYER_SIZEOF*(x)])
50 #define T(y, x) (unsigned int)S(y, x)
51 #define R(y, x) dst[(y)*dst_stride + (x)*3 + BAYER_R]
52 #define G(y, x) dst[(y)*dst_stride + (x)*3 + BAYER_G]
53 #define B(y, x) dst[(y)*dst_stride + (x)*3 + BAYER_B]
54 
55 #if defined(BAYER_BGGR) || defined(BAYER_RGGB)
56 #define BAYER_TO_RGB24_COPY \
57  R(0, 0) = \
58  R(0, 1) = \
59  R(1, 1) = \
60  R(1, 0) = S(1, 1) >> BAYER_SHIFT; \
61  \
62  G(0, 1) = S(0, 1) >> BAYER_SHIFT; \
63  G(0, 0) = \
64  G(1, 1) = (T(0, 1) + T(1, 0)) >> (1 + BAYER_SHIFT); \
65  G(1, 0) = S(1, 0) >> BAYER_SHIFT; \
66  \
67  B(1, 1) = \
68  B(0, 0) = \
69  B(0, 1) = \
70  B(1, 0) = S(0, 0) >> BAYER_SHIFT;
71 #define BAYER_TO_RGB24_INTERPOLATE \
72  R(0, 0) = (T(-1, -1) + T(-1, 1) + T(1, -1) + T(1, 1)) >> (2 + BAYER_SHIFT); \
73  G(0, 0) = (T(-1, 0) + T( 0, -1) + T(0, 1) + T(1, 0)) >> (2 + BAYER_SHIFT); \
74  B(0, 0) = S(0, 0) >> BAYER_SHIFT; \
75  \
76  R(0, 1) = (T(-1, 1) + T(1, 1)) >> (1 + BAYER_SHIFT); \
77  G(0, 1) = S(0, 1) >> BAYER_SHIFT; \
78  B(0, 1) = (T(0, 0) + T(0, 2)) >> (1 + BAYER_SHIFT); \
79  \
80  R(1, 0) = (T(1, -1) + T(1, 1)) >> (1 + BAYER_SHIFT); \
81  G(1, 0) = S(1, 0) >> BAYER_SHIFT; \
82  B(1, 0) = (T(0, 0) + T(2, 0)) >> (1 + BAYER_SHIFT); \
83  \
84  R(1, 1) = S(1, 1) >> BAYER_SHIFT; \
85  G(1, 1) = (T(0, 1) + T(1, 0) + T(1, 2) + T(2, 1)) >> (2 + BAYER_SHIFT); \
86  B(1, 1) = (T(0, 0) + T(0, 2) + T(2, 0) + T(2, 2)) >> (2 + BAYER_SHIFT);
87 #else
88 #define BAYER_TO_RGB24_COPY \
89  R(0, 0) = \
90  R(0, 1) = \
91  R(1, 1) = \
92  R(1, 0) = S(1, 0) >> BAYER_SHIFT; \
93  \
94  G(0, 0) = S(0, 0) >> BAYER_SHIFT; \
95  G(1, 1) = S(1, 1) >> BAYER_SHIFT; \
96  G(0, 1) = \
97  G(1, 0) = (T(0, 0) + T(1, 1)) >> (1 + BAYER_SHIFT); \
98  \
99  B(1, 1) = \
100  B(0, 0) = \
101  B(0, 1) = \
102  B(1, 0) = S(0, 1) >> BAYER_SHIFT;
103 #define BAYER_TO_RGB24_INTERPOLATE \
104  R(0, 0) = (T(-1, 0) + T(1, 0)) >> (1 + BAYER_SHIFT); \
105  G(0, 0) = S(0, 0) >> BAYER_SHIFT; \
106  B(0, 0) = (T(0, -1) + T(0, 1)) >> (1 + BAYER_SHIFT); \
107  \
108  R(0, 1) = (T(-1, 0) + T(-1, 2) + T(1, 0) + T(1, 2)) >> (2 + BAYER_SHIFT); \
109  G(0, 1) = (T(-1, 1) + T(0, 0) + T(0, 2) + T(1, 1)) >> (2 + BAYER_SHIFT); \
110  B(0, 1) = S(0, 1) >> BAYER_SHIFT; \
111  \
112  R(1, 0) = S(1, 0) >> BAYER_SHIFT; \
113  G(1, 0) = (T(0, 0) + T(1, -1) + T(1, 1) + T(2, 0)) >> (2 + BAYER_SHIFT); \
114  B(1, 0) = (T(0, -1) + T(0, 1) + T(2, -1) + T(2, 1)) >> (2 + BAYER_SHIFT); \
115  \
116  R(1, 1) = (T(1, 0) + T(1, 2)) >> (1 + BAYER_SHIFT); \
117  G(1, 1) = S(1, 1) >> BAYER_SHIFT; \
118  B(1, 1) = (T(0, 1) + T(2, 1)) >> (1 + BAYER_SHIFT);
119 #endif
120 
121 #if defined(BAYER_BGGR) || defined(BAYER_RGGB)
122 #define BAYER_TO_RGB48_COPY \
123  R(0, 0) = \
124  R(0, 1) = \
125  R(1, 1) = \
126  R(1, 0) = S(1, 1); \
127  \
128  G(0, 1) = S(0, 1); \
129  G(0, 0) = \
130  G(1, 1) = (T(0, 1) + T(1, 0)) >> 1; \
131  G(1, 0) = S(1, 0); \
132  \
133  B(1, 1) = \
134  B(0, 0) = \
135  B(0, 1) = \
136  B(1, 0) = S(0, 0);
137 #define BAYER_TO_RGB48_INTERPOLATE \
138  R(0, 0) = (T(-1, -1) + T(-1, 1) + T(1, -1) + T(1, 1)) >> 2; \
139  G(0, 0) = (T(-1, 0) + T( 0, -1) + T(0, 1) + T(1, 0)) >> 2; \
140  B(0, 0) = S(0, 0); \
141  \
142  R(0, 1) = (T(-1, 1) + T(1, 1)) >> 1; \
143  G(0, 1) = S(0, 1); \
144  B(0, 1) = (T(0, 0) + T(0, 2)) >> 1; \
145  \
146  R(1, 0) = (T(1, -1) + T(1, 1)) >> 1; \
147  G(1, 0) = S(1, 0); \
148  B(1, 0) = (T(0, 0) + T(2, 0)) >> 1; \
149  \
150  R(1, 1) = S(1, 1); \
151  G(1, 1) = (T(0, 1) + T(1, 0) + T(1, 2) + T(2, 1)) >> 2; \
152  B(1, 1) = (T(0, 0) + T(0, 2) + T(2, 0) + T(2, 2)) >> 2;
153 #else
154 #define BAYER_TO_RGB48_COPY \
155  R(0, 0) = \
156  R(0, 1) = \
157  R(1, 1) = \
158  R(1, 0) = S(1, 0); \
159  \
160  G(0, 0) = S(0, 0); \
161  G(1, 1) = S(1, 1); \
162  G(0, 1) = \
163  G(1, 0) = (T(0, 0) + T(1, 1)) >> 1; \
164  \
165  B(1, 1) = \
166  B(0, 0) = \
167  B(0, 1) = \
168  B(1, 0) = S(0, 1);
169 #define BAYER_TO_RGB48_INTERPOLATE \
170  R(0, 0) = (T(-1, 0) + T(1, 0)) >> 1; \
171  G(0, 0) = S(0, 0); \
172  B(0, 0) = (T(0, -1) + T(0, 1)) >> 1; \
173  \
174  R(0, 1) = (T(-1, 0) + T(-1, 2) + T(1, 0) + T(1, 2)) >> 2; \
175  G(0, 1) = (T(-1, 1) + T(0, 0) + T(0, 2) + T(1, 1)) >> 2; \
176  B(0, 1) = S(0, 1); \
177  \
178  R(1, 0) = S(1, 0); \
179  G(1, 0) = (T(0, 0) + T(1, -1) + T(1, 1) + T(2, 0)) >> 2; \
180  B(1, 0) = (T(0, -1) + T(0, 1) + T(2, -1) + T(2, 1)) >> 2; \
181  \
182  R(1, 1) = (T(1, 0) + T(1, 2)) >> 1; \
183  G(1, 1) = S(1, 1); \
184  B(1, 1) = (T(0, 1) + T(2, 1)) >> 1;
185 #endif
186 
187 /**
188  * invoke ff_rgb24toyv12 for 2x2 pixels
189  */
190 #define rgb24toyv12_2x2(src, dstY, dstU, dstV, luma_stride, src_stride, rgb2yuv) \
191  ff_rgb24toyv12(src, dstY, dstV, dstU, 2, 2, luma_stride, 0, src_stride, rgb2yuv)
192 
193 static void BAYER_RENAME(rgb24_copy)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width)
194 {
195  int i;
196  for (i = 0 ; i < width; i+= 2) {
198  src += 2 * BAYER_SIZEOF;
199  dst += 6;
200  }
201 }
202 
203 static void BAYER_RENAME(rgb24_interpolate)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width)
204 {
205  int i;
206 
208  src += 2 * BAYER_SIZEOF;
209  dst += 6;
210 
211  for (i = 2 ; i < width - 2; i+= 2) {
213  src += 2 * BAYER_SIZEOF;
214  dst += 6;
215  }
216 
217  if (width > 2) {
219  }
220 }
221 
222 static void BAYER_RENAME(rgb48_copy)(const uint8_t *src, int src_stride, uint8_t *ddst, int dst_stride, int width)
223 {
224  uint16_t *dst = (uint16_t *)ddst;
225  int i;
226 
227  dst_stride /= 2;
228  for (i = 0 ; i < width; i+= 2) {
230  src += 2 * BAYER_SIZEOF;
231  dst += 6;
232  }
233 }
234 
235 static void BAYER_RENAME(rgb48_interpolate)(const uint8_t *src, int src_stride, uint8_t *ddst, int dst_stride, int width)
236 {
237  uint16_t *dst = (uint16_t *)ddst;
238  int i;
239 
240  dst_stride /= 2;
242  src += 2 * BAYER_SIZEOF;
243  dst += 6;
244 
245  for (i = 2 ; i < width - 2; i+= 2) {
247  src += 2 * BAYER_SIZEOF;
248  dst += 6;
249  }
250 
251  if (width > 2) {
253  }
254 }
255 
256 static void BAYER_RENAME(yv12_copy)(const uint8_t *src, int src_stride, uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, int luma_stride, int width, int32_t *rgb2yuv)
257 {
258  uint8_t dst[12];
259  const int dst_stride = 6;
260  int i;
261  for (i = 0 ; i < width; i+= 2) {
263  rgb24toyv12_2x2(dst, dstY, dstU, dstV, luma_stride, dst_stride, rgb2yuv);
264  src += 2 * BAYER_SIZEOF;
265  dstY += 2;
266  dstU++;
267  dstV++;
268  }
269 }
270 
271 static void BAYER_RENAME(yv12_interpolate)(const uint8_t *src, int src_stride, uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, int luma_stride, int width, int32_t *rgb2yuv)
272 {
273  uint8_t dst[12];
274  const int dst_stride = 6;
275  int i;
276 
278  rgb24toyv12_2x2(dst, dstY, dstU, dstV, luma_stride, dst_stride, rgb2yuv);
279  src += 2 * BAYER_SIZEOF;
280  dstY += 2;
281  dstU++;
282  dstV++;
283 
284  for (i = 2 ; i < width - 2; i+= 2) {
286  rgb24toyv12_2x2(dst, dstY, dstU, dstV, luma_stride, dst_stride, rgb2yuv);
287  src += 2 * BAYER_SIZEOF;
288  dstY += 2;
289  dstU++;
290  dstV++;
291  }
292 
293  if (width > 2) {
295  rgb24toyv12_2x2(dst, dstY, dstU, dstV, luma_stride, dst_stride, rgb2yuv);
296  }
297 }
298 
299 #undef S
300 #undef T
301 #undef R
302 #undef G
303 #undef B
304 #undef BAYER_TO_RGB24_COPY
305 #undef BAYER_TO_RGB24_INTERPOLATE
306 #undef BAYER_TO_RGB48_COPY
307 #undef BAYER_TO_RGB48_INTERPOLATE
308 
309 #undef BAYER_RENAME
310 
311 #undef BAYER_R
312 #undef BAYER_G
313 #undef BAYER_B
314 #undef BAYER_READ
315 #undef BAYER_SIZEOF
316 #undef BAYER_SHIFT
317 
318 #if defined(BAYER_BGGR)
319 #undef BAYER_BGGR
320 #endif
321 #if defined(BAYER_RGGB)
322 #undef BAYER_RGGB
323 #endif
324 #if defined(BAYER_GBRG)
325 #undef BAYER_GBRG
326 #endif
327 #if defined(BAYER_GRBG)
328 #undef BAYER_GRBG
329 #endif
330 #if defined(BAYER_8)
331 #undef BAYER_8
332 #endif
333 #if defined(BAYER_16LE)
334 #undef BAYER_16LE
335 #endif
336 #if defined(BAYER_16BE)
337 #undef BAYER_16BE
338 #endif
SwsContext::dstY
int dstY
Last destination vertical line output from last slice.
Definition: swscale_internal.h:431
rgb48_copy
static void BAYER_RENAME() rgb48_copy(const uint8_t *src, int src_stride, uint8_t *ddst, int dst_stride, int width)
Definition: bayer_template.c:222
BAYER_TO_RGB24_INTERPOLATE
#define BAYER_TO_RGB24_INTERPOLATE
Definition: bayer_template.c:103
BAYER_TO_RGB48_INTERPOLATE
#define BAYER_TO_RGB48_INTERPOLATE
Definition: bayer_template.c:169
rgb2yuv
static const char rgb2yuv[]
Definition: vf_scale_vulkan.c:68
BAYER_RENAME
#define BAYER_RENAME(x)
Definition: swscale_unscaled.c:1277
BAYER_TO_RGB24_COPY
#define BAYER_TO_RGB24_COPY
Definition: bayer_template.c:88
width
#define width
yv12_copy
static void BAYER_RENAME() yv12_copy(const uint8_t *src, int src_stride, uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, int luma_stride, int width, int32_t *rgb2yuv)
Definition: bayer_template.c:256
src
#define src
Definition: vp8dsp.c:255
yv12_interpolate
static void BAYER_RENAME() yv12_interpolate(const uint8_t *src, int src_stride, uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, int luma_stride, int width, int32_t *rgb2yuv)
Definition: bayer_template.c:271
BAYER_TO_RGB48_COPY
#define BAYER_TO_RGB48_COPY
Definition: bayer_template.c:154
rgb24_interpolate
static void BAYER_RENAME() rgb24_interpolate(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width)
Definition: bayer_template.c:203
rgb48_interpolate
static void BAYER_RENAME() rgb48_interpolate(const uint8_t *src, int src_stride, uint8_t *ddst, int dst_stride, int width)
Definition: bayer_template.c:235
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
rgb24toyv12_2x2
#define rgb24toyv12_2x2(src, dstY, dstU, dstV, luma_stride, src_stride, rgb2yuv)
invoke ff_rgb24toyv12 for 2x2 pixels
Definition: bayer_template.c:190
int32_t
int32_t
Definition: audioconvert.c:56
rgb24_copy
static void BAYER_RENAME() rgb24_copy(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width)
Definition: bayer_template.c:193