OLD | NEW |
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <assert.h> | 5 #include <assert.h> |
6 #include <getopt.h> | 6 #include <getopt.h> |
7 #include <signal.h> | 7 #include <signal.h> |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 | 9 |
10 #include <iostream> | 10 #include <iostream> |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 XFreeGC(xdisplay_, gc); | 115 XFreeGC(xdisplay_, gc); |
116 } | 116 } |
117 | 117 |
118 inline int32_t clip(int32_t value, int32_t min, int32_t max) { | 118 inline int32_t clip(int32_t value, int32_t min, int32_t max) { |
119 return (value > max ? max : value < min ? min : value); | 119 return (value > max ? max : value < min ? min : value); |
120 } | 120 } |
121 | 121 |
122 void ConvertYUVToRGB32(uint8_t* in, uint8_t* out, int32_t ifmt, | 122 void ConvertYUVToRGB32(uint8_t* in, uint8_t* out, int32_t ifmt, |
123 int32_t width, int32_t height, | 123 int32_t width, int32_t height, |
124 int32_t istride, int32_t ostride) { | 124 int32_t istride, int32_t ostride) { |
125 if (ifmt == v4l2_fourcc('Y', 'U', 'Y', 'V')) { | 125 if ((ifmt == v4l2_fourcc('Y', 'U', 'Y', 'V')) || |
| 126 (ifmt == v4l2_fourcc('Y', 'V', 'Y', 'U')) || |
| 127 (ifmt == v4l2_fourcc('U', 'Y', 'V', 'Y')) || |
| 128 (ifmt == v4l2_fourcc('V', 'Y', 'U', 'Y'))) { |
| 129 |
| 130 int y0_offset; |
| 131 int y1_offset; |
| 132 int u_offset; |
| 133 int v_offset; |
| 134 |
| 135 if (ifmt == v4l2_fourcc('Y', 'U', 'Y', 'V')) { |
| 136 y0_offset = 0; |
| 137 y1_offset = 2; |
| 138 u_offset = 1; |
| 139 v_offset = 3; |
| 140 } else if (ifmt == v4l2_fourcc('Y', 'V', 'Y', 'U')) { |
| 141 y0_offset = 0; |
| 142 y1_offset = 2; |
| 143 u_offset = 3; |
| 144 v_offset = 1; |
| 145 } else if (ifmt == v4l2_fourcc('U', 'Y', 'V', 'Y')) { |
| 146 y0_offset = 1; |
| 147 y1_offset = 3; |
| 148 u_offset = 0; |
| 149 v_offset = 2; |
| 150 } else if (ifmt == v4l2_fourcc('V', 'Y', 'U', 'Y')) { |
| 151 y0_offset = 1; |
| 152 y1_offset = 3; |
| 153 u_offset = 2; |
| 154 v_offset = 0; |
| 155 } else { |
| 156 CHECK(0); |
| 157 } |
| 158 |
126 for (int32_t i = 0; i < height; ++i) { | 159 for (int32_t i = 0; i < height; ++i) { |
127 for (int32_t j = 0; j < width * 2; j += 4) { | 160 for (int32_t j = 0; j < width * 2; j += 4) { |
128 int32_t y0 = in[j]; | 161 int32_t y0 = in[j + y0_offset]; |
129 int32_t y1 = in[j + 2]; | 162 int32_t y1 = in[j + y1_offset]; |
130 int32_t u = in[j + 1] - 128; | 163 int32_t u = in[j + u_offset] - 128; |
131 int32_t v = in[j + 3] - 128; | 164 int32_t v = in[j + v_offset] - 128; |
132 | 165 |
133 int32_t r = (298 * y0 + 409 * v + 128) >> 8; | 166 int32_t r = (298 * y0 + 409 * v + 128) >> 8; |
134 int32_t g = (298 * y0 - 100 * u - 208 * v + 128) >> 8; | 167 int32_t g = (298 * y0 - 100 * u - 208 * v + 128) >> 8; |
135 int32_t b = (298 * y0 + 516 * u + 128) >> 8; | 168 int32_t b = (298 * y0 + 516 * u + 128) >> 8; |
136 out[j * 2 + 0] = clip(b, 0, 255); | 169 |
137 out[j * 2 + 1] = clip(g, 0, 255); | 170 out[j * 2 + 0] = clip(b, 0, 255); |
138 out[j * 2 + 2] = clip(r, 0, 255); | 171 out[j * 2 + 1] = clip(g, 0, 255); |
139 out[j * 2 + 3] = 255; | 172 out[j * 2 + 2] = clip(r, 0, 255); |
140 r = (298 * y1 + 409 * v + 128) >> 8; | 173 out[j * 2 + 3] = 255; |
141 g = (298 * y1 - 100 * u - 208 * v + 128) >> 8; | 174 |
142 b = (298 * y1 + 516 * u + 128) >> 8; | 175 r = (298 * y1 + 409 * v + 128) >> 8; |
143 out[j * 2 + 4] = clip(b, 0, 255); | 176 g = (298 * y1 - 100 * u - 208 * v + 128) >> 8; |
144 out[j * 2 + 5] = clip(g, 0, 255); | 177 b = (298 * y1 + 516 * u + 128) >> 8; |
145 out[j * 2 + 6] = clip(r, 0, 255); | 178 |
146 out[j * 2 + 7] = 255; | 179 out[j * 2 + 4] = clip(b, 0, 255); |
| 180 out[j * 2 + 5] = clip(g, 0, 255); |
| 181 out[j * 2 + 6] = clip(r, 0, 255); |
| 182 out[j * 2 + 7] = 255; |
147 } | 183 } |
148 in += istride; | 184 in += istride; |
149 out += ostride; | 185 out += ostride; |
150 } | 186 } |
| 187 } else if ((ifmt == v4l2_fourcc('Y', 'U', '1', '2')) || |
| 188 (ifmt == v4l2_fourcc('Y', 'V', '1', '2'))) { |
| 189 // Can't use bytes_per_line for this. While bytes_per_line is width*1.5, |
| 190 // the rest of this part of code is using line stride as the |
| 191 // y-plane's line stride, which should just be the width of the image. |
| 192 istride = width; |
| 193 |
| 194 uint8_t* y_plane = in; |
| 195 uint8_t* u_plane = in + height * istride; |
| 196 // assumption. stride for uv is half of the y stride. |
| 197 uint8_t* v_plane = u_plane + height * istride / 4; |
| 198 |
| 199 // YU12 is identical to YV12 except that the U and V planes are swapped. |
| 200 if (ifmt == v4l2_fourcc('Y', 'V', '1', '2')) { |
| 201 uint8_t* temp = u_plane; |
| 202 u_plane = v_plane; |
| 203 v_plane = temp; |
| 204 } |
| 205 |
| 206 for (int32_t i = 0; i < height; ++i) { |
| 207 for (int32_t j = 0; j < width; ++j) { |
| 208 int32_t y = y_plane[j]; |
| 209 int32_t u = u_plane[j >> 1] - 128; |
| 210 int32_t v = v_plane[j >> 1] - 128; |
| 211 |
| 212 int32_t r = (298 * y + 409 * v + 128) >> 8; |
| 213 int32_t g = (298 * y - 100 * u - 208 * v + 128) >> 8; |
| 214 int32_t b = (298 * y + 516 * u + 128) >> 8; |
| 215 |
| 216 out[j * 4 + 0] = clip(b, 0, 255); |
| 217 out[j * 4 + 1] = clip(g, 0, 255); |
| 218 out[j * 4 + 2] = clip(r, 0, 255); |
| 219 out[j * 4 + 3] = 255; |
| 220 } |
| 221 y_plane += istride; |
| 222 if (i & 1) { |
| 223 u_plane += istride >> 1; |
| 224 v_plane += istride >> 1; |
| 225 } |
| 226 out += ostride; |
| 227 } |
151 } else { | 228 } else { |
152 CHECK(0); | 229 CHECK(0); |
153 } | 230 } |
154 } | 231 } |
155 | 232 |
156 private: | 233 private: |
157 Display* xdisplay_; | 234 Display* xdisplay_; |
158 Window xwindow_; | 235 Window xwindow_; |
159 XImage* ximage_; | 236 XImage* ximage_; |
160 bool xrunning_; | 237 bool xrunning_; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 retcode = 6; | 385 retcode = 6; |
309 | 386 |
310 device->CloseDevice(); | 387 device->CloseDevice(); |
311 | 388 |
312 if (device) | 389 if (device) |
313 delete device; | 390 delete device; |
314 | 391 |
315 return retcode; | 392 return retcode; |
316 } | 393 } |
317 | 394 |
OLD | NEW |