| Line | Branch | Exec | Source |
|---|---|---|---|
| 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) { | |
| 197 | ✗ | BAYER_TO_RGB24_COPY | |
| 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 | |||
| 207 | ✗ | BAYER_TO_RGB24_COPY | |
| 208 | ✗ | src += 2 * BAYER_SIZEOF; | |
| 209 | ✗ | dst += 6; | |
| 210 | |||
| 211 | ✗ | for (i = 2 ; i < width - 2; i+= 2) { | |
| 212 | ✗ | BAYER_TO_RGB24_INTERPOLATE | |
| 213 | ✗ | src += 2 * BAYER_SIZEOF; | |
| 214 | ✗ | dst += 6; | |
| 215 | } | ||
| 216 | |||
| 217 | ✗ | if (width > 2) { | |
| 218 | ✗ | BAYER_TO_RGB24_COPY | |
| 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) { | |
| 229 | ✗ | BAYER_TO_RGB48_COPY | |
| 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; | |
| 241 | ✗ | BAYER_TO_RGB48_COPY | |
| 242 | ✗ | src += 2 * BAYER_SIZEOF; | |
| 243 | ✗ | dst += 6; | |
| 244 | |||
| 245 | ✗ | for (i = 2 ; i < width - 2; i+= 2) { | |
| 246 | ✗ | BAYER_TO_RGB48_INTERPOLATE | |
| 247 | ✗ | src += 2 * BAYER_SIZEOF; | |
| 248 | ✗ | dst += 6; | |
| 249 | } | ||
| 250 | |||
| 251 | ✗ | if (width > 2) { | |
| 252 | ✗ | BAYER_TO_RGB48_COPY | |
| 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, const 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) { | |
| 262 | ✗ | BAYER_TO_RGB24_COPY | |
| 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, const int32_t *rgb2yuv) | |
| 272 | { | ||
| 273 | uint8_t dst[12]; | ||
| 274 | ✗ | const int dst_stride = 6; | |
| 275 | int i; | ||
| 276 | |||
| 277 | ✗ | BAYER_TO_RGB24_COPY | |
| 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) { | |
| 285 | ✗ | BAYER_TO_RGB24_INTERPOLATE | |
| 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) { | |
| 294 | ✗ | BAYER_TO_RGB24_COPY | |
| 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 | ||
| 339 |