SDL  2.0
SDL_yuv.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../SDL_internal.h"
22 
23 #include "SDL_endian.h"
24 #include "SDL_video.h"
25 #include "SDL_pixels_c.h"
26 #include "SDL_yuv_c.h"
27 
28 #include "yuv2rgb/yuv_rgb.h"
29 
30 #define SDL_YUV_SD_THRESHOLD 576
31 
32 
34 
35 
37 {
39 }
40 
42 {
44 }
45 
47 {
49  if (mode == SDL_YUV_CONVERSION_AUTOMATIC) {
50  if (height <= SDL_YUV_SD_THRESHOLD) {
52  } else {
54  }
55  }
56  return mode;
57 }
58 
59 static int GetYUVConversionType(int width, int height, YCbCrType *yuv_type)
60 {
61  switch (SDL_GetYUVConversionModeForResolution(width, height)) {
63  *yuv_type = YCBCR_JPEG;
64  break;
66  *yuv_type = YCBCR_601;
67  break;
69  *yuv_type = YCBCR_709;
70  break;
71  default:
72  return SDL_SetError("Unexpected YUV conversion mode");
73  }
74  return 0;
75 }
76 
78 {
79  return (format == SDL_PIXELFORMAT_YV12 ||
80  format == SDL_PIXELFORMAT_IYUV ||
81  format == SDL_PIXELFORMAT_NV12 ||
82  format == SDL_PIXELFORMAT_NV21);
83 }
84 
86 {
87  return (format == SDL_PIXELFORMAT_YUY2 ||
88  format == SDL_PIXELFORMAT_UYVY ||
89  format == SDL_PIXELFORMAT_YVYU);
90 }
91 
92 static int GetYUVPlanes(int width, int height, Uint32 format, const void *yuv, int yuv_pitch,
93  const Uint8 **y, const Uint8 **u, const Uint8 **v, Uint32 *y_stride, Uint32 *uv_stride)
94 {
95  const Uint8 *planes[3] = { NULL, NULL, NULL };
96  int pitches[3] = { 0, 0, 0 };
97 
98  switch (format) {
101  pitches[0] = yuv_pitch;
102  pitches[1] = (pitches[0] + 1) / 2;
103  pitches[2] = (pitches[0] + 1) / 2;
104  planes[0] = (const Uint8 *)yuv;
105  planes[1] = planes[0] + pitches[0] * height;
106  planes[2] = planes[1] + pitches[1] * ((height + 1) / 2);
107  break;
111  pitches[0] = yuv_pitch;
112  planes[0] = (const Uint8 *)yuv;
113  break;
116  pitches[0] = yuv_pitch;
117  pitches[1] = 2 * ((pitches[0] + 1) / 2);
118  planes[0] = (const Uint8 *)yuv;
119  planes[1] = planes[0] + pitches[0] * height;
120  break;
121  default:
122  return SDL_SetError("GetYUVPlanes(): Unsupported YUV format: %s", SDL_GetPixelFormatName(format));
123  }
124 
125  switch (format) {
127  *y = planes[0];
128  *y_stride = pitches[0];
129  *v = planes[1];
130  *u = planes[2];
131  *uv_stride = pitches[1];
132  break;
134  *y = planes[0];
135  *y_stride = pitches[0];
136  *v = planes[2];
137  *u = planes[1];
138  *uv_stride = pitches[1];
139  break;
141  *y = planes[0];
142  *y_stride = pitches[0];
143  *v = *y + 3;
144  *u = *y + 1;
145  *uv_stride = pitches[0];
146  break;
148  *y = planes[0] + 1;
149  *y_stride = pitches[0];
150  *v = *y + 1;
151  *u = *y - 1;
152  *uv_stride = pitches[0];
153  break;
155  *y = planes[0];
156  *y_stride = pitches[0];
157  *v = *y + 1;
158  *u = *y + 3;
159  *uv_stride = pitches[0];
160  break;
162  *y = planes[0];
163  *y_stride = pitches[0];
164  *u = planes[1];
165  *v = *u + 1;
166  *uv_stride = pitches[1];
167  break;
169  *y = planes[0];
170  *y_stride = pitches[0];
171  *v = planes[1];
172  *u = *v + 1;
173  *uv_stride = pitches[1];
174  break;
175  default:
176  /* Should have caught this above */
177  return SDL_SetError("GetYUVPlanes[2]: Unsupported YUV format: %s", SDL_GetPixelFormatName(format));
178  }
179  return 0;
180 }
181 
183  Uint32 src_format, Uint32 dst_format,
185  const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride,
186  Uint8 *rgb, Uint32 rgb_stride,
187  YCbCrType yuv_type)
188 {
189 #ifdef __SSE2__
190  if (!SDL_HasSSE2()) {
191  return SDL_FALSE;
192  }
193 
194  if (src_format == SDL_PIXELFORMAT_YV12 ||
195  src_format == SDL_PIXELFORMAT_IYUV) {
196 
197  switch (dst_format) {
199  yuv420_rgb565_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
200  return SDL_TRUE;
202  yuv420_rgb24_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
203  return SDL_TRUE;
206  yuv420_rgba_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
207  return SDL_TRUE;
210  yuv420_bgra_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
211  return SDL_TRUE;
214  yuv420_argb_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
215  return SDL_TRUE;
218  yuv420_abgr_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
219  return SDL_TRUE;
220  default:
221  break;
222  }
223  }
224 
225  if (src_format == SDL_PIXELFORMAT_YUY2 ||
226  src_format == SDL_PIXELFORMAT_UYVY ||
227  src_format == SDL_PIXELFORMAT_YVYU) {
228 
229  switch (dst_format) {
231  yuv422_rgb565_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
232  return SDL_TRUE;
234  yuv422_rgb24_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
235  return SDL_TRUE;
238  yuv422_rgba_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
239  return SDL_TRUE;
242  yuv422_bgra_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
243  return SDL_TRUE;
246  yuv422_argb_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
247  return SDL_TRUE;
250  yuv422_abgr_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
251  return SDL_TRUE;
252  default:
253  break;
254  }
255  }
256 
257  if (src_format == SDL_PIXELFORMAT_NV12 ||
258  src_format == SDL_PIXELFORMAT_NV21) {
259 
260  switch (dst_format) {
262  yuvnv12_rgb565_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
263  return SDL_TRUE;
265  yuvnv12_rgb24_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
266  return SDL_TRUE;
269  yuvnv12_rgba_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
270  return SDL_TRUE;
273  yuvnv12_bgra_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
274  return SDL_TRUE;
277  yuvnv12_argb_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
278  return SDL_TRUE;
281  yuvnv12_abgr_sseu(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
282  return SDL_TRUE;
283  default:
284  break;
285  }
286  }
287 #endif
288  return SDL_FALSE;
289 }
290 
292  Uint32 src_format, Uint32 dst_format,
294  const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride,
295  Uint8 *rgb, Uint32 rgb_stride,
296  YCbCrType yuv_type)
297 {
298 #ifdef __MSA__
299  if (!SDL_HasMSA()) {
300  return SDL_FALSE;
301  }
302  if (src_format == SDL_PIXELFORMAT_YV12 ||
303  src_format == SDL_PIXELFORMAT_IYUV) {
304 
305  switch (dst_format) {
307  yuv420_rgb24_msa(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
308  return SDL_TRUE;
311  yuv420_rgba_msa(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
312  return SDL_TRUE;
315  yuv420_bgra_msa(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
316  return SDL_TRUE;
319  yuv420_argb_msa(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
320  return SDL_TRUE;
323  yuv420_abgr_msa(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
324  return SDL_TRUE;
325  default:
326  break;
327  }
328  }
329 #endif
330  return SDL_FALSE;
331 }
332 
334  Uint32 src_format, Uint32 dst_format,
336  const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride,
337  Uint8 *rgb, Uint32 rgb_stride,
338  YCbCrType yuv_type)
339 {
340 #ifdef __loongarch_sx
341  if (!SDL_HasLSX()) {
342  return SDL_FALSE;
343  }
344  if (src_format == SDL_PIXELFORMAT_YV12 ||
345  src_format == SDL_PIXELFORMAT_IYUV) {
346 
347  switch (dst_format) {
349  yuv420_rgb24_lsx(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
350  return SDL_TRUE;
353  yuv420_rgba_lsx(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
354  return SDL_TRUE;
357  yuv420_bgra_lsx(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
358  return SDL_TRUE;
361  yuv420_argb_lsx(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
362  return SDL_TRUE;
365  yuv420_abgr_lsx(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
366  return SDL_TRUE;
367  default:
368  break;
369  }
370  }
371 #endif
372  return SDL_FALSE;
373 }
374 
376  Uint32 src_format, Uint32 dst_format,
378  const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride,
379  Uint8 *rgb, Uint32 rgb_stride,
380  YCbCrType yuv_type)
381 {
382  if (src_format == SDL_PIXELFORMAT_YV12 ||
383  src_format == SDL_PIXELFORMAT_IYUV) {
384 
385  switch (dst_format) {
387  yuv420_rgb565_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
388  return SDL_TRUE;
390  yuv420_rgb24_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
391  return SDL_TRUE;
394  yuv420_rgba_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
395  return SDL_TRUE;
398  yuv420_bgra_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
399  return SDL_TRUE;
402  yuv420_argb_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
403  return SDL_TRUE;
406  yuv420_abgr_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
407  return SDL_TRUE;
408  default:
409  break;
410  }
411  }
412 
413  if (src_format == SDL_PIXELFORMAT_YUY2 ||
414  src_format == SDL_PIXELFORMAT_UYVY ||
415  src_format == SDL_PIXELFORMAT_YVYU) {
416 
417  switch (dst_format) {
419  yuv422_rgb565_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
420  return SDL_TRUE;
422  yuv422_rgb24_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
423  return SDL_TRUE;
426  yuv422_rgba_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
427  return SDL_TRUE;
430  yuv422_bgra_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
431  return SDL_TRUE;
434  yuv422_argb_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
435  return SDL_TRUE;
438  yuv422_abgr_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
439  return SDL_TRUE;
440  default:
441  break;
442  }
443  }
444 
445  if (src_format == SDL_PIXELFORMAT_NV12 ||
446  src_format == SDL_PIXELFORMAT_NV21) {
447 
448  switch (dst_format) {
450  yuvnv12_rgb565_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
451  return SDL_TRUE;
453  yuvnv12_rgb24_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
454  return SDL_TRUE;
457  yuvnv12_rgba_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
458  return SDL_TRUE;
461  yuvnv12_bgra_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
462  return SDL_TRUE;
465  yuvnv12_argb_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
466  return SDL_TRUE;
469  yuvnv12_abgr_std(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
470  return SDL_TRUE;
471  default:
472  break;
473  }
474  }
475  return SDL_FALSE;
476 }
477 
478 int
480  Uint32 src_format, const void *src, int src_pitch,
481  Uint32 dst_format, void *dst, int dst_pitch)
482 {
483  const Uint8 *y = NULL;
484  const Uint8 *u = NULL;
485  const Uint8 *v = NULL;
486  Uint32 y_stride = 0;
487  Uint32 uv_stride = 0;
488  YCbCrType yuv_type = YCBCR_601;
489 
490  if (GetYUVPlanes(width, height, src_format, src, src_pitch, &y, &u, &v, &y_stride, &uv_stride) < 0) {
491  return -1;
492  }
493 
494  if (GetYUVConversionType(width, height, &yuv_type) < 0) {
495  return -1;
496  }
497 
498  if (yuv_rgb_sse(src_format, dst_format, width, height, y, u, v, y_stride, uv_stride, (Uint8*)dst, dst_pitch, yuv_type)) {
499  return 0;
500  }
501 
502  if (yuv_rgb_msa(src_format, dst_format, width, height, y, u, v, y_stride, uv_stride, (Uint8*)dst, dst_pitch, yuv_type)) {
503  return 0;
504  }
505 
506  if (yuv_rgb_lsx(src_format, dst_format, width, height, y, u, v, y_stride, uv_stride, (Uint8*)dst, dst_pitch, yuv_type)) {
507  return 0;
508  }
509 
510  if (yuv_rgb_std(src_format, dst_format, width, height, y, u, v, y_stride, uv_stride, (Uint8*)dst, dst_pitch, yuv_type)) {
511  return 0;
512  }
513 
514  /* No fast path for the RGB format, instead convert using an intermediate buffer */
515  if (dst_format != SDL_PIXELFORMAT_ARGB8888) {
516  int ret;
517  void *tmp;
518  int tmp_pitch = (width * sizeof(Uint32));
519 
520  tmp = SDL_malloc(tmp_pitch * height);
521  if (tmp == NULL) {
522  return SDL_OutOfMemory();
523  }
524 
525  /* convert src/src_format to tmp/ARGB8888 */
526  ret = SDL_ConvertPixels_YUV_to_RGB(width, height, src_format, src, src_pitch, SDL_PIXELFORMAT_ARGB8888, tmp, tmp_pitch);
527  if (ret < 0) {
528  SDL_free(tmp);
529  return ret;
530  }
531 
532  /* convert tmp/ARGB8888 to dst/RGB */
533  ret = SDL_ConvertPixels(width, height, SDL_PIXELFORMAT_ARGB8888, tmp, tmp_pitch, dst_format, dst, dst_pitch);
534  SDL_free(tmp);
535  return ret;
536  }
537 
538  return SDL_SetError("Unsupported YUV conversion");
539 }
540 
542 {
543  int y_offset;
544  float y[3]; /* Rfactor, Gfactor, Bfactor */
545  float u[3]; /* Rfactor, Gfactor, Bfactor */
546  float v[3]; /* Rfactor, Gfactor, Bfactor */
547 };
548 
549 static int
550 SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
551 {
552  const int src_pitch_x_2 = src_pitch * 2;
553  const int height_half = height / 2;
554  const int height_remainder = (height & 0x1);
555  const int width_half = width / 2;
556  const int width_remainder = (width & 0x1);
557  int i, j;
558 
559  static struct RGB2YUVFactors RGB2YUVFactorTables[SDL_YUV_CONVERSION_BT709 + 1] =
560  {
561  /* ITU-T T.871 (JPEG) */
562  {
563  0,
564  { 0.2990f, 0.5870f, 0.1140f },
565  { -0.1687f, -0.3313f, 0.5000f },
566  { 0.5000f, -0.4187f, -0.0813f },
567  },
568  /* ITU-R BT.601-7 */
569  {
570  16,
571  { 0.2568f, 0.5041f, 0.0979f },
572  { -0.1482f, -0.2910f, 0.4392f },
573  { 0.4392f, -0.3678f, -0.0714f },
574  },
575  /* ITU-R BT.709-6 */
576  {
577  16,
578  { 0.1826f, 0.6142f, 0.0620f },
579  {-0.1006f, -0.3386f, 0.4392f },
580  { 0.4392f, -0.3989f, -0.0403f },
581  },
582  };
583  const struct RGB2YUVFactors *cvt = &RGB2YUVFactorTables[SDL_GetYUVConversionModeForResolution(width, height)];
584 
585 #define MAKE_Y(r, g, b) (Uint8)((int)(cvt->y[0] * (r) + cvt->y[1] * (g) + cvt->y[2] * (b) + 0.5f) + cvt->y_offset)
586 #define MAKE_U(r, g, b) (Uint8)((int)(cvt->u[0] * (r) + cvt->u[1] * (g) + cvt->u[2] * (b) + 0.5f) + 128)
587 #define MAKE_V(r, g, b) (Uint8)((int)(cvt->v[0] * (r) + cvt->v[1] * (g) + cvt->v[2] * (b) + 0.5f) + 128)
588 
589 #define READ_2x2_PIXELS \
590  const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \
591  const Uint32 p2 = ((const Uint32 *)curr_row)[2 * i + 1]; \
592  const Uint32 p3 = ((const Uint32 *)next_row)[2 * i]; \
593  const Uint32 p4 = ((const Uint32 *)next_row)[2 * i + 1]; \
594  const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000) + (p3 & 0x00ff0000) + (p4 & 0x00ff0000)) >> 18; \
595  const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00) + (p3 & 0x0000ff00) + (p4 & 0x0000ff00)) >> 10; \
596  const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff) + (p3 & 0x000000ff) + (p4 & 0x000000ff)) >> 2; \
597 
598 #define READ_2x1_PIXELS \
599  const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \
600  const Uint32 p2 = ((const Uint32 *)next_row)[2 * i]; \
601  const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000)) >> 17; \
602  const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00)) >> 9; \
603  const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff)) >> 1; \
604 
605 #define READ_1x2_PIXELS \
606  const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \
607  const Uint32 p2 = ((const Uint32 *)curr_row)[2 * i + 1]; \
608  const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000)) >> 17; \
609  const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00)) >> 9; \
610  const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff)) >> 1; \
611 
612 #define READ_1x1_PIXEL \
613  const Uint32 p = ((const Uint32 *)curr_row)[2 * i]; \
614  const Uint32 r = (p & 0x00ff0000) >> 16; \
615  const Uint32 g = (p & 0x0000ff00) >> 8; \
616  const Uint32 b = (p & 0x000000ff); \
617 
618 #define READ_TWO_RGB_PIXELS \
619  const Uint32 p = ((const Uint32 *)curr_row)[2 * i]; \
620  const Uint32 r = (p & 0x00ff0000) >> 16; \
621  const Uint32 g = (p & 0x0000ff00) >> 8; \
622  const Uint32 b = (p & 0x000000ff); \
623  const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i + 1]; \
624  const Uint32 r1 = (p1 & 0x00ff0000) >> 16; \
625  const Uint32 g1 = (p1 & 0x0000ff00) >> 8; \
626  const Uint32 b1 = (p1 & 0x000000ff); \
627  const Uint32 R = (r + r1)/2; \
628  const Uint32 G = (g + g1)/2; \
629  const Uint32 B = (b + b1)/2; \
630 
631 #define READ_ONE_RGB_PIXEL READ_1x1_PIXEL
632 
633  switch (dst_format)
634  {
639  {
640  const Uint8 *curr_row, *next_row;
641 
642  Uint8 *plane_y;
643  Uint8 *plane_u;
644  Uint8 *plane_v;
645  Uint8 *plane_interleaved_uv;
646  Uint32 y_stride, uv_stride, y_skip, uv_skip;
647 
648  GetYUVPlanes(width, height, dst_format, dst, dst_pitch,
649  (const Uint8 **)&plane_y, (const Uint8 **)&plane_u, (const Uint8 **)&plane_v,
650  &y_stride, &uv_stride);
651  plane_interleaved_uv = (plane_y + height * y_stride);
652  y_skip = (y_stride - width);
653 
654  curr_row = (const Uint8*)src;
655 
656  /* Write Y plane */
657  for (j = 0; j < height; j++) {
658  for (i = 0; i < width; i++) {
659  const Uint32 p1 = ((const Uint32 *)curr_row)[i];
660  const Uint32 r = (p1 & 0x00ff0000) >> 16;
661  const Uint32 g = (p1 & 0x0000ff00) >> 8;
662  const Uint32 b = (p1 & 0x000000ff);
663  *plane_y++ = MAKE_Y(r, g, b);
664  }
665  plane_y += y_skip;
666  curr_row += src_pitch;
667  }
668 
669  curr_row = (const Uint8*)src;
670  next_row = (const Uint8*)src;
671  next_row += src_pitch;
672 
673  if (dst_format == SDL_PIXELFORMAT_YV12 || dst_format == SDL_PIXELFORMAT_IYUV)
674  {
675  /* Write UV planes, not interleaved */
676  uv_skip = (uv_stride - (width + 1)/2);
677  for (j = 0; j < height_half; j++) {
678  for (i = 0; i < width_half; i++) {
680  *plane_u++ = MAKE_U(r, g, b);
681  *plane_v++ = MAKE_V(r, g, b);
682  }
683  if (width_remainder) {
685  *plane_u++ = MAKE_U(r, g, b);
686  *plane_v++ = MAKE_V(r, g, b);
687  }
688  plane_u += uv_skip;
689  plane_v += uv_skip;
690  curr_row += src_pitch_x_2;
691  next_row += src_pitch_x_2;
692  }
693  if (height_remainder) {
694  for (i = 0; i < width_half; i++) {
696  *plane_u++ = MAKE_U(r, g, b);
697  *plane_v++ = MAKE_V(r, g, b);
698  }
699  if (width_remainder) {
701  *plane_u++ = MAKE_U(r, g, b);
702  *plane_v++ = MAKE_V(r, g, b);
703  }
704  plane_u += uv_skip;
705  plane_v += uv_skip;
706  }
707  }
708  else if (dst_format == SDL_PIXELFORMAT_NV12)
709  {
710  uv_skip = (uv_stride - ((width + 1)/2)*2);
711  for (j = 0; j < height_half; j++) {
712  for (i = 0; i < width_half; i++) {
714  *plane_interleaved_uv++ = MAKE_U(r, g, b);
715  *plane_interleaved_uv++ = MAKE_V(r, g, b);
716  }
717  if (width_remainder) {
719  *plane_interleaved_uv++ = MAKE_U(r, g, b);
720  *plane_interleaved_uv++ = MAKE_V(r, g, b);
721  }
722  plane_interleaved_uv += uv_skip;
723  curr_row += src_pitch_x_2;
724  next_row += src_pitch_x_2;
725  }
726  if (height_remainder) {
727  for (i = 0; i < width_half; i++) {
729  *plane_interleaved_uv++ = MAKE_U(r, g, b);
730  *plane_interleaved_uv++ = MAKE_V(r, g, b);
731  }
732  if (width_remainder) {
734  *plane_interleaved_uv++ = MAKE_U(r, g, b);
735  *plane_interleaved_uv++ = MAKE_V(r, g, b);
736  }
737  }
738  }
739  else /* dst_format == SDL_PIXELFORMAT_NV21 */
740  {
741  uv_skip = (uv_stride - ((width + 1)/2)*2);
742  for (j = 0; j < height_half; j++) {
743  for (i = 0; i < width_half; i++) {
745  *plane_interleaved_uv++ = MAKE_V(r, g, b);
746  *plane_interleaved_uv++ = MAKE_U(r, g, b);
747  }
748  if (width_remainder) {
750  *plane_interleaved_uv++ = MAKE_V(r, g, b);
751  *plane_interleaved_uv++ = MAKE_U(r, g, b);
752  }
753  plane_interleaved_uv += uv_skip;
754  curr_row += src_pitch_x_2;
755  next_row += src_pitch_x_2;
756  }
757  if (height_remainder) {
758  for (i = 0; i < width_half; i++) {
760  *plane_interleaved_uv++ = MAKE_V(r, g, b);
761  *plane_interleaved_uv++ = MAKE_U(r, g, b);
762  }
763  if (width_remainder) {
765  *plane_interleaved_uv++ = MAKE_V(r, g, b);
766  *plane_interleaved_uv++ = MAKE_U(r, g, b);
767  }
768  }
769  }
770  }
771  break;
772 
776  {
777  const Uint8 *curr_row = (const Uint8*) src;
778  Uint8 *plane = (Uint8*) dst;
779  const int row_size = (4 * ((width + 1) / 2));
780  int plane_skip;
781 
782  if (dst_pitch < row_size) {
783  return SDL_SetError("Destination pitch is too small, expected at least %d\n", row_size);
784  }
785  plane_skip = (dst_pitch - row_size);
786 
787  /* Write YUV plane, packed */
788  if (dst_format == SDL_PIXELFORMAT_YUY2)
789  {
790  for (j = 0; j < height; j++) {
791  for (i = 0; i < width_half; i++) {
793  /* Y U Y1 V */
794  *plane++ = MAKE_Y(r, g, b);
795  *plane++ = MAKE_U(R, G, B);
796  *plane++ = MAKE_Y(r1, g1, b1);
797  *plane++ = MAKE_V(R, G, B);
798  }
799  if (width_remainder) {
801  /* Y U Y V */
802  *plane++ = MAKE_Y(r, g, b);
803  *plane++ = MAKE_U(r, g, b);
804  *plane++ = MAKE_Y(r, g, b);
805  *plane++ = MAKE_V(r, g, b);
806  }
807  plane += plane_skip;
808  curr_row += src_pitch;
809  }
810  }
811  else if (dst_format == SDL_PIXELFORMAT_UYVY)
812  {
813  for (j = 0; j < height; j++) {
814  for (i = 0; i < width_half; i++) {
816  /* U Y V Y1 */
817  *plane++ = MAKE_U(R, G, B);
818  *plane++ = MAKE_Y(r, g, b);
819  *plane++ = MAKE_V(R, G, B);
820  *plane++ = MAKE_Y(r1, g1, b1);
821  }
822  if (width_remainder) {
824  /* U Y V Y */
825  *plane++ = MAKE_U(r, g, b);
826  *plane++ = MAKE_Y(r, g, b);
827  *plane++ = MAKE_V(r, g, b);
828  *plane++ = MAKE_Y(r, g, b);
829  }
830  plane += plane_skip;
831  curr_row += src_pitch;
832  }
833  }
834  else if (dst_format == SDL_PIXELFORMAT_YVYU)
835  {
836  for (j = 0; j < height; j++) {
837  for (i = 0; i < width_half; i++) {
839  /* Y V Y1 U */
840  *plane++ = MAKE_Y(r, g, b);
841  *plane++ = MAKE_V(R, G, B);
842  *plane++ = MAKE_Y(r1, g1, b1);
843  *plane++ = MAKE_U(R, G, B);
844  }
845  if (width_remainder) {
847  /* Y V Y U */
848  *plane++ = MAKE_Y(r, g, b);
849  *plane++ = MAKE_V(r, g, b);
850  *plane++ = MAKE_Y(r, g, b);
851  *plane++ = MAKE_U(r, g, b);
852  }
853  plane += plane_skip;
854  curr_row += src_pitch;
855  }
856  }
857  }
858  break;
859 
860  default:
861  return SDL_SetError("Unsupported YUV destination format: %s", SDL_GetPixelFormatName(dst_format));
862  }
863 #undef MAKE_Y
864 #undef MAKE_U
865 #undef MAKE_V
866 #undef READ_2x2_PIXELS
867 #undef READ_2x1_PIXELS
868 #undef READ_1x2_PIXELS
869 #undef READ_1x1_PIXEL
870 #undef READ_TWO_RGB_PIXELS
871 #undef READ_ONE_RGB_PIXEL
872  return 0;
873 }
874 
875 int
877  Uint32 src_format, const void *src, int src_pitch,
878  Uint32 dst_format, void *dst, int dst_pitch)
879 {
880 #if 0 /* Doesn't handle odd widths */
881  /* RGB24 to FOURCC */
882  if (src_format == SDL_PIXELFORMAT_RGB24) {
883  Uint8 *y;
884  Uint8 *u;
885  Uint8 *v;
886  Uint32 y_stride;
887  Uint32 uv_stride;
888  YCbCrType yuv_type;
889 
890  if (GetYUVPlanes(width, height, dst_format, dst, dst_pitch, (const Uint8 **)&y, (const Uint8 **)&u, (const Uint8 **)&v, &y_stride, &uv_stride) < 0) {
891  return -1;
892  }
893 
894  if (GetYUVConversionType(width, height, &yuv_type) < 0) {
895  return -1;
896  }
897 
898  rgb24_yuv420_std(width, height, src, src_pitch, y, u, v, y_stride, uv_stride, yuv_type);
899  return 0;
900  }
901 #endif
902 
903  /* ARGB8888 to FOURCC */
904  if (src_format == SDL_PIXELFORMAT_ARGB8888) {
905  return SDL_ConvertPixels_ARGB8888_to_YUV(width, height, src, src_pitch, dst_format, dst, dst_pitch);
906  }
907 
908  /* not ARGB8888 to FOURCC : need an intermediate conversion */
909  {
910  int ret;
911  void *tmp;
912  int tmp_pitch = (width * sizeof(Uint32));
913 
914  tmp = SDL_malloc(tmp_pitch * height);
915  if (tmp == NULL) {
916  return SDL_OutOfMemory();
917  }
918 
919  /* convert src/src_format to tmp/ARGB8888 */
920  ret = SDL_ConvertPixels(width, height, src_format, src, src_pitch, SDL_PIXELFORMAT_ARGB8888, tmp, tmp_pitch);
921  if (ret == -1) {
922  SDL_free(tmp);
923  return ret;
924  }
925 
926  /* convert tmp/ARGB8888 to dst/FOURCC */
927  ret = SDL_ConvertPixels_ARGB8888_to_YUV(width, height, tmp, tmp_pitch, dst_format, dst, dst_pitch);
928  SDL_free(tmp);
929  return ret;
930  }
931 }
932 
933 static int
935  const void *src, int src_pitch, void *dst, int dst_pitch)
936 {
937  int i;
938 
939  if (IsPlanar2x2Format(format)) {
940  /* Y plane */
941  for (i = height; i--;) {
942  SDL_memcpy(dst, src, width);
943  src = (const Uint8*)src + src_pitch;
944  dst = (Uint8*)dst + dst_pitch;
945  }
946 
947  if (format == SDL_PIXELFORMAT_YV12 || format == SDL_PIXELFORMAT_IYUV) {
948  /* U and V planes are a quarter the size of the Y plane, rounded up */
949  width = (width + 1) / 2;
950  height = (height + 1) / 2;
951  src_pitch = (src_pitch + 1) / 2;
952  dst_pitch = (dst_pitch + 1) / 2;
953  for (i = height * 2; i--;) {
954  SDL_memcpy(dst, src, width);
955  src = (const Uint8*)src + src_pitch;
956  dst = (Uint8*)dst + dst_pitch;
957  }
958  } else if (format == SDL_PIXELFORMAT_NV12 || format == SDL_PIXELFORMAT_NV21) {
959  /* U/V plane is half the height of the Y plane, rounded up */
960  height = (height + 1) / 2;
961  width = ((width + 1) / 2)*2;
962  src_pitch = ((src_pitch + 1) / 2)*2;
963  dst_pitch = ((dst_pitch + 1) / 2)*2;
964  for (i = height; i--;) {
965  SDL_memcpy(dst, src, width);
966  src = (const Uint8*)src + src_pitch;
967  dst = (Uint8*)dst + dst_pitch;
968  }
969  }
970  return 0;
971  }
972 
973  if (IsPacked4Format(format)) {
974  /* Packed planes */
975  width = 4 * ((width + 1) / 2);
976  for (i = height; i--;) {
977  SDL_memcpy(dst, src, width);
978  src = (const Uint8*)src + src_pitch;
979  dst = (Uint8*)dst + dst_pitch;
980  }
981  return 0;
982  }
983 
984  return SDL_SetError("SDL_ConvertPixels_YUV_to_YUV_Copy: Unsupported YUV format: %s", SDL_GetPixelFormatName(format));
985 }
986 
987 static int
988 SDL_ConvertPixels_SwapUVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
989 {
990  int y;
991  const int UVwidth = (width + 1)/2;
992  const int UVheight = (height + 1)/2;
993 
994  /* Skip the Y plane */
995  src = (const Uint8 *)src + height * src_pitch;
996  dst = (Uint8 *)dst + height * dst_pitch;
997 
998  if (src == dst) {
999  int UVpitch = (dst_pitch + 1)/2;
1000  Uint8 *tmp;
1001  Uint8 *row1 = dst;
1002  Uint8 *row2 = (Uint8 *)dst + UVheight * UVpitch;
1003 
1004  /* Allocate a temporary row for the swap */
1005  tmp = (Uint8 *)SDL_malloc(UVwidth);
1006  if (!tmp) {
1007  return SDL_OutOfMemory();
1008  }
1009  for (y = 0; y < UVheight; ++y) {
1010  SDL_memcpy(tmp, row1, UVwidth);
1011  SDL_memcpy(row1, row2, UVwidth);
1012  SDL_memcpy(row2, tmp, UVwidth);
1013  row1 += UVpitch;
1014  row2 += UVpitch;
1015  }
1016  SDL_free(tmp);
1017  } else {
1018  const Uint8 *srcUV;
1019  Uint8 *dstUV;
1020  int srcUVPitch = ((src_pitch + 1)/2);
1021  int dstUVPitch = ((dst_pitch + 1)/2);
1022 
1023  /* Copy the first plane */
1024  srcUV = (const Uint8 *)src;
1025  dstUV = (Uint8 *)dst + UVheight * dstUVPitch;
1026  for (y = 0; y < UVheight; ++y) {
1027  SDL_memcpy(dstUV, srcUV, UVwidth);
1028  srcUV += srcUVPitch;
1029  dstUV += dstUVPitch;
1030  }
1031 
1032  /* Copy the second plane */
1033  dstUV = (Uint8 *)dst;
1034  for (y = 0; y < UVheight; ++y) {
1035  SDL_memcpy(dstUV, srcUV, UVwidth);
1036  srcUV += srcUVPitch;
1037  dstUV += dstUVPitch;
1038  }
1039  }
1040  return 0;
1041 }
1042 
1043 static int
1044 SDL_ConvertPixels_PackUVPlanes_to_NV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV)
1045 {
1046  int x, y;
1047  const int UVwidth = (width + 1)/2;
1048  const int UVheight = (height + 1)/2;
1049  const int srcUVPitch = ((src_pitch + 1)/2);
1050  const int srcUVPitchLeft = srcUVPitch - UVwidth;
1051  const int dstUVPitch = ((dst_pitch + 1)/2)*2;
1052  const int dstUVPitchLeft = dstUVPitch - UVwidth*2;
1053  const Uint8 *src1, *src2;
1054  Uint8 *dstUV;
1055  Uint8 *tmp = NULL;
1056 #ifdef __SSE2__
1057  const SDL_bool use_SSE2 = SDL_HasSSE2();
1058 #endif
1059 
1060  /* Skip the Y plane */
1061  src = (const Uint8 *)src + height * src_pitch;
1062  dst = (Uint8 *)dst + height * dst_pitch;
1063 
1064  if (src == dst) {
1065  /* Need to make a copy of the buffer so we don't clobber it while converting */
1066  tmp = (Uint8 *)SDL_malloc(2*UVheight*srcUVPitch);
1067  if (!tmp) {
1068  return SDL_OutOfMemory();
1069  }
1070  SDL_memcpy(tmp, src, 2*UVheight*srcUVPitch);
1071  src = tmp;
1072  }
1073 
1074  if (reverseUV) {
1075  src2 = (const Uint8 *)src;
1076  src1 = src2 + UVheight * srcUVPitch;
1077  } else {
1078  src1 = (const Uint8 *)src;
1079  src2 = src1 + UVheight * srcUVPitch;
1080  }
1081  dstUV = (Uint8 *)dst;
1082 
1083  y = UVheight;
1084  while (y--) {
1085  x = UVwidth;
1086 #ifdef __SSE2__
1087  if (use_SSE2) {
1088  while (x >= 16) {
1089  __m128i u = _mm_loadu_si128((__m128i *)src1);
1090  __m128i v = _mm_loadu_si128((__m128i *)src2);
1091  __m128i uv1 = _mm_unpacklo_epi8(u, v);
1092  __m128i uv2 = _mm_unpackhi_epi8(u, v);
1093  _mm_storeu_si128((__m128i*)dstUV, uv1);
1094  _mm_storeu_si128((__m128i*)(dstUV + 16), uv2);
1095  src1 += 16;
1096  src2 += 16;
1097  dstUV += 32;
1098  x -= 16;
1099  }
1100  }
1101 #endif
1102  while (x--) {
1103  *dstUV++ = *src1++;
1104  *dstUV++ = *src2++;
1105  }
1106  src1 += srcUVPitchLeft;
1107  src2 += srcUVPitchLeft;
1108  dstUV += dstUVPitchLeft;
1109  }
1110 
1111  if (tmp) {
1112  SDL_free(tmp);
1113  }
1114  return 0;
1115 }
1116 
1117 static int
1118 SDL_ConvertPixels_SplitNV_to_UVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV)
1119 {
1120  int x, y;
1121  const int UVwidth = (width + 1)/2;
1122  const int UVheight = (height + 1)/2;
1123  const int srcUVPitch = ((src_pitch + 1)/2)*2;
1124  const int srcUVPitchLeft = srcUVPitch - UVwidth*2;
1125  const int dstUVPitch = ((dst_pitch + 1)/2);
1126  const int dstUVPitchLeft = dstUVPitch - UVwidth;
1127  const Uint8 *srcUV;
1128  Uint8 *dst1, *dst2;
1129  Uint8 *tmp = NULL;
1130 #ifdef __SSE2__
1131  const SDL_bool use_SSE2 = SDL_HasSSE2();
1132 #endif
1133 
1134  /* Skip the Y plane */
1135  src = (const Uint8 *)src + height * src_pitch;
1136  dst = (Uint8 *)dst + height * dst_pitch;
1137 
1138  if (src == dst) {
1139  /* Need to make a copy of the buffer so we don't clobber it while converting */
1140  tmp = (Uint8 *)SDL_malloc(UVheight*srcUVPitch);
1141  if (!tmp) {
1142  return SDL_OutOfMemory();
1143  }
1144  SDL_memcpy(tmp, src, UVheight*srcUVPitch);
1145  src = tmp;
1146  }
1147 
1148  if (reverseUV) {
1149  dst2 = (Uint8 *)dst;
1150  dst1 = dst2 + UVheight * dstUVPitch;
1151  } else {
1152  dst1 = (Uint8 *)dst;
1153  dst2 = dst1 + UVheight * dstUVPitch;
1154  }
1155  srcUV = (const Uint8 *)src;
1156 
1157  y = UVheight;
1158  while (y--) {
1159  x = UVwidth;
1160 #ifdef __SSE2__
1161  if (use_SSE2) {
1162  __m128i mask = _mm_set1_epi16(0x00FF);
1163  while (x >= 16) {
1164  __m128i uv1 = _mm_loadu_si128((__m128i*)srcUV);
1165  __m128i uv2 = _mm_loadu_si128((__m128i*)(srcUV+16));
1166  __m128i u1 = _mm_and_si128(uv1, mask);
1167  __m128i u2 = _mm_and_si128(uv2, mask);
1168  __m128i u = _mm_packus_epi16(u1, u2);
1169  __m128i v1 = _mm_srli_epi16(uv1, 8);
1170  __m128i v2 = _mm_srli_epi16(uv2, 8);
1171  __m128i v = _mm_packus_epi16(v1, v2);
1172  _mm_storeu_si128((__m128i*)dst1, u);
1173  _mm_storeu_si128((__m128i*)dst2, v);
1174  srcUV += 32;
1175  dst1 += 16;
1176  dst2 += 16;
1177  x -= 16;
1178  }
1179  }
1180 #endif
1181  while (x--) {
1182  *dst1++ = *srcUV++;
1183  *dst2++ = *srcUV++;
1184  }
1185  srcUV += srcUVPitchLeft;
1186  dst1 += dstUVPitchLeft;
1187  dst2 += dstUVPitchLeft;
1188  }
1189 
1190  if (tmp) {
1191  SDL_free(tmp);
1192  }
1193  return 0;
1194 }
1195 
1196 static int
1197 SDL_ConvertPixels_SwapNV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1198 {
1199  int x, y;
1200  const int UVwidth = (width + 1)/2;
1201  const int UVheight = (height + 1)/2;
1202  const int srcUVPitch = ((src_pitch + 1)/2)*2;
1203  const int srcUVPitchLeft = (srcUVPitch - UVwidth*2)/sizeof(Uint16);
1204  const int dstUVPitch = ((dst_pitch + 1)/2)*2;
1205  const int dstUVPitchLeft = (dstUVPitch - UVwidth*2)/sizeof(Uint16);
1206  const Uint16 *srcUV;
1207  Uint16 *dstUV;
1208 #ifdef __SSE2__
1209  const SDL_bool use_SSE2 = SDL_HasSSE2();
1210 #endif
1211 
1212  /* Skip the Y plane */
1213  src = (const Uint8 *)src + height * src_pitch;
1214  dst = (Uint8 *)dst + height * dst_pitch;
1215 
1216  srcUV = (const Uint16 *)src;
1217  dstUV = (Uint16 *)dst;
1218  y = UVheight;
1219  while (y--) {
1220  x = UVwidth;
1221 #ifdef __SSE2__
1222  if (use_SSE2) {
1223  while (x >= 8) {
1224  __m128i uv = _mm_loadu_si128((__m128i*)srcUV);
1225  __m128i v = _mm_slli_epi16(uv, 8);
1226  __m128i u = _mm_srli_epi16(uv, 8);
1227  __m128i vu = _mm_or_si128(v, u);
1228  _mm_storeu_si128((__m128i*)dstUV, vu);
1229  srcUV += 8;
1230  dstUV += 8;
1231  x -= 8;
1232  }
1233  }
1234 #endif
1235  while (x--) {
1236  *dstUV++ = SDL_Swap16(*srcUV++);
1237  }
1238  srcUV += srcUVPitchLeft;
1239  dstUV += dstUVPitchLeft;
1240  }
1241  return 0;
1242 }
1243 
1244 static int
1246  Uint32 src_format, const void *src, int src_pitch,
1247  Uint32 dst_format, void *dst, int dst_pitch)
1248 {
1249  if (src != dst) {
1250  /* Copy Y plane */
1251  int i;
1252  const Uint8 *srcY = (const Uint8 *)src;
1253  Uint8 *dstY = (Uint8 *)dst;
1254  for (i = height; i--; ) {
1255  SDL_memcpy(dstY, srcY, width);
1256  srcY += src_pitch;
1257  dstY += dst_pitch;
1258  }
1259  }
1260 
1261  switch (src_format) {
1262  case SDL_PIXELFORMAT_YV12:
1263  switch (dst_format) {
1264  case SDL_PIXELFORMAT_IYUV:
1265  return SDL_ConvertPixels_SwapUVPlanes(width, height, src, src_pitch, dst, dst_pitch);
1266  case SDL_PIXELFORMAT_NV12:
1267  return SDL_ConvertPixels_PackUVPlanes_to_NV(width, height, src, src_pitch, dst, dst_pitch, SDL_TRUE);
1268  case SDL_PIXELFORMAT_NV21:
1269  return SDL_ConvertPixels_PackUVPlanes_to_NV(width, height, src, src_pitch, dst, dst_pitch, SDL_FALSE);
1270  default:
1271  break;
1272  }
1273  break;
1274  case SDL_PIXELFORMAT_IYUV:
1275  switch (dst_format) {
1276  case SDL_PIXELFORMAT_YV12:
1277  return SDL_ConvertPixels_SwapUVPlanes(width, height, src, src_pitch, dst, dst_pitch);
1278  case SDL_PIXELFORMAT_NV12:
1279  return SDL_ConvertPixels_PackUVPlanes_to_NV(width, height, src, src_pitch, dst, dst_pitch, SDL_FALSE);
1280  case SDL_PIXELFORMAT_NV21:
1281  return SDL_ConvertPixels_PackUVPlanes_to_NV(width, height, src, src_pitch, dst, dst_pitch, SDL_TRUE);
1282  default:
1283  break;
1284  }
1285  break;
1286  case SDL_PIXELFORMAT_NV12:
1287  switch (dst_format) {
1288  case SDL_PIXELFORMAT_YV12:
1289  return SDL_ConvertPixels_SplitNV_to_UVPlanes(width, height, src, src_pitch, dst, dst_pitch, SDL_TRUE);
1290  case SDL_PIXELFORMAT_IYUV:
1291  return SDL_ConvertPixels_SplitNV_to_UVPlanes(width, height, src, src_pitch, dst, dst_pitch, SDL_FALSE);
1292  case SDL_PIXELFORMAT_NV21:
1293  return SDL_ConvertPixels_SwapNV(width, height, src, src_pitch, dst, dst_pitch);
1294  default:
1295  break;
1296  }
1297  break;
1298  case SDL_PIXELFORMAT_NV21:
1299  switch (dst_format) {
1300  case SDL_PIXELFORMAT_YV12:
1301  return SDL_ConvertPixels_SplitNV_to_UVPlanes(width, height, src, src_pitch, dst, dst_pitch, SDL_FALSE);
1302  case SDL_PIXELFORMAT_IYUV:
1303  return SDL_ConvertPixels_SplitNV_to_UVPlanes(width, height, src, src_pitch, dst, dst_pitch, SDL_TRUE);
1304  case SDL_PIXELFORMAT_NV12:
1305  return SDL_ConvertPixels_SwapNV(width, height, src, src_pitch, dst, dst_pitch);
1306  default:
1307  break;
1308  }
1309  break;
1310  default:
1311  break;
1312  }
1313  return SDL_SetError("SDL_ConvertPixels_Planar2x2_to_Planar2x2: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format));
1314 }
1315 
1316 #define PACKED4_TO_PACKED4_ROW_SSE2(shuffle) \
1317  while (x >= 4) { \
1318  __m128i yuv = _mm_loadu_si128((__m128i*)srcYUV); \
1319  __m128i lo = _mm_unpacklo_epi8(yuv, _mm_setzero_si128()); \
1320  __m128i hi = _mm_unpackhi_epi8(yuv, _mm_setzero_si128()); \
1321  lo = _mm_shufflelo_epi16(lo, shuffle); \
1322  lo = _mm_shufflehi_epi16(lo, shuffle); \
1323  hi = _mm_shufflelo_epi16(hi, shuffle); \
1324  hi = _mm_shufflehi_epi16(hi, shuffle); \
1325  yuv = _mm_packus_epi16(lo, hi); \
1326  _mm_storeu_si128((__m128i*)dstYUV, yuv); \
1327  srcYUV += 16; \
1328  dstYUV += 16; \
1329  x -= 4; \
1330  } \
1331 
1332 static int
1333 SDL_ConvertPixels_YUY2_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1334 {
1335  int x, y;
1336  const int YUVwidth = (width + 1)/2;
1337  const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
1338  const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
1339  const Uint8 *srcYUV = (const Uint8 *)src;
1340  Uint8 *dstYUV = (Uint8 *)dst;
1341 #ifdef __SSE2__
1342  const SDL_bool use_SSE2 = SDL_HasSSE2();
1343 #endif
1344 
1345  y = height;
1346  while (y--) {
1347  x = YUVwidth;
1348 #ifdef __SSE2__
1349  if (use_SSE2) {
1350  PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(2, 3, 0, 1));
1351  }
1352 #endif
1353  while (x--) {
1354  Uint8 Y1, U, Y2, V;
1355 
1356  Y1 = srcYUV[0];
1357  U = srcYUV[1];
1358  Y2 = srcYUV[2];
1359  V = srcYUV[3];
1360  srcYUV += 4;
1361 
1362  dstYUV[0] = U;
1363  dstYUV[1] = Y1;
1364  dstYUV[2] = V;
1365  dstYUV[3] = Y2;
1366  dstYUV += 4;
1367  }
1368  srcYUV += srcYUVPitchLeft;
1369  dstYUV += dstYUVPitchLeft;
1370  }
1371  return 0;
1372 }
1373 
1374 static int
1375 SDL_ConvertPixels_YUY2_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1376 {
1377  int x, y;
1378  const int YUVwidth = (width + 1)/2;
1379  const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
1380  const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
1381  const Uint8 *srcYUV = (const Uint8 *)src;
1382  Uint8 *dstYUV = (Uint8 *)dst;
1383 #ifdef __SSE2__
1384  const SDL_bool use_SSE2 = SDL_HasSSE2();
1385 #endif
1386 
1387  y = height;
1388  while (y--) {
1389  x = YUVwidth;
1390 #ifdef __SSE2__
1391  if (use_SSE2) {
1392  PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(1, 2, 3, 0));
1393  }
1394 #endif
1395  while (x--) {
1396  Uint8 Y1, U, Y2, V;
1397 
1398  Y1 = srcYUV[0];
1399  U = srcYUV[1];
1400  Y2 = srcYUV[2];
1401  V = srcYUV[3];
1402  srcYUV += 4;
1403 
1404  dstYUV[0] = Y1;
1405  dstYUV[1] = V;
1406  dstYUV[2] = Y2;
1407  dstYUV[3] = U;
1408  dstYUV += 4;
1409  }
1410  srcYUV += srcYUVPitchLeft;
1411  dstYUV += dstYUVPitchLeft;
1412  }
1413  return 0;
1414 }
1415 
1416 static int
1417 SDL_ConvertPixels_UYVY_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1418 {
1419  int x, y;
1420  const int YUVwidth = (width + 1)/2;
1421  const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
1422  const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
1423  const Uint8 *srcYUV = (const Uint8 *)src;
1424  Uint8 *dstYUV = (Uint8 *)dst;
1425 #ifdef __SSE2__
1426  const SDL_bool use_SSE2 = SDL_HasSSE2();
1427 #endif
1428 
1429  y = height;
1430  while (y--) {
1431  x = YUVwidth;
1432 #ifdef __SSE2__
1433  if (use_SSE2) {
1434  PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(2, 3, 0, 1));
1435  }
1436 #endif
1437  while (x--) {
1438  Uint8 Y1, U, Y2, V;
1439 
1440  U = srcYUV[0];
1441  Y1 = srcYUV[1];
1442  V = srcYUV[2];
1443  Y2 = srcYUV[3];
1444  srcYUV += 4;
1445 
1446  dstYUV[0] = Y1;
1447  dstYUV[1] = U;
1448  dstYUV[2] = Y2;
1449  dstYUV[3] = V;
1450  dstYUV += 4;
1451  }
1452  srcYUV += srcYUVPitchLeft;
1453  dstYUV += dstYUVPitchLeft;
1454  }
1455  return 0;
1456 }
1457 
1458 static int
1459 SDL_ConvertPixels_UYVY_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1460 {
1461  int x, y;
1462  const int YUVwidth = (width + 1)/2;
1463  const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
1464  const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
1465  const Uint8 *srcYUV = (const Uint8 *)src;
1466  Uint8 *dstYUV = (Uint8 *)dst;
1467 #ifdef __SSE2__
1468  const SDL_bool use_SSE2 = SDL_HasSSE2();
1469 #endif
1470 
1471  y = height;
1472  while (y--) {
1473  x = YUVwidth;
1474 #ifdef __SSE2__
1475  if (use_SSE2) {
1476  PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(0, 3, 2, 1));
1477  }
1478 #endif
1479  while (x--) {
1480  Uint8 Y1, U, Y2, V;
1481 
1482  U = srcYUV[0];
1483  Y1 = srcYUV[1];
1484  V = srcYUV[2];
1485  Y2 = srcYUV[3];
1486  srcYUV += 4;
1487 
1488  dstYUV[0] = Y1;
1489  dstYUV[1] = V;
1490  dstYUV[2] = Y2;
1491  dstYUV[3] = U;
1492  dstYUV += 4;
1493  }
1494  srcYUV += srcYUVPitchLeft;
1495  dstYUV += dstYUVPitchLeft;
1496  }
1497  return 0;
1498 }
1499 
1500 static int
1501 SDL_ConvertPixels_YVYU_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1502 {
1503  int x, y;
1504  const int YUVwidth = (width + 1)/2;
1505  const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
1506  const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
1507  const Uint8 *srcYUV = (const Uint8 *)src;
1508  Uint8 *dstYUV = (Uint8 *)dst;
1509 #ifdef __SSE2__
1510  const SDL_bool use_SSE2 = SDL_HasSSE2();
1511 #endif
1512 
1513  y = height;
1514  while (y--) {
1515  x = YUVwidth;
1516 #ifdef __SSE2__
1517  if (use_SSE2) {
1518  PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(1, 2, 3, 0));
1519  }
1520 #endif
1521  while (x--) {
1522  Uint8 Y1, U, Y2, V;
1523 
1524  Y1 = srcYUV[0];
1525  V = srcYUV[1];
1526  Y2 = srcYUV[2];
1527  U = srcYUV[3];
1528  srcYUV += 4;
1529 
1530  dstYUV[0] = Y1;
1531  dstYUV[1] = U;
1532  dstYUV[2] = Y2;
1533  dstYUV[3] = V;
1534  dstYUV += 4;
1535  }
1536  srcYUV += srcYUVPitchLeft;
1537  dstYUV += dstYUVPitchLeft;
1538  }
1539  return 0;
1540 }
1541 
1542 static int
1543 SDL_ConvertPixels_YVYU_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
1544 {
1545  int x, y;
1546  const int YUVwidth = (width + 1)/2;
1547  const int srcYUVPitchLeft = (src_pitch - YUVwidth*4);
1548  const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4);
1549  const Uint8 *srcYUV = (const Uint8 *)src;
1550  Uint8 *dstYUV = (Uint8 *)dst;
1551 #ifdef __SSE2__
1552  const SDL_bool use_SSE2 = SDL_HasSSE2();
1553 #endif
1554 
1555  y = height;
1556  while (y--) {
1557  x = YUVwidth;
1558 #ifdef __SSE2__
1559  if (use_SSE2) {
1560  PACKED4_TO_PACKED4_ROW_SSE2(_MM_SHUFFLE(2, 1, 0, 3));
1561  }
1562 #endif
1563  while (x--) {
1564  Uint8 Y1, U, Y2, V;
1565 
1566  Y1 = srcYUV[0];
1567  V = srcYUV[1];
1568  Y2 = srcYUV[2];
1569  U = srcYUV[3];
1570  srcYUV += 4;
1571 
1572  dstYUV[0] = U;
1573  dstYUV[1] = Y1;
1574  dstYUV[2] = V;
1575  dstYUV[3] = Y2;
1576  dstYUV += 4;
1577  }
1578  srcYUV += srcYUVPitchLeft;
1579  dstYUV += dstYUVPitchLeft;
1580  }
1581  return 0;
1582 }
1583 
1584 static int
1586  Uint32 src_format, const void *src, int src_pitch,
1587  Uint32 dst_format, void *dst, int dst_pitch)
1588 {
1589  switch (src_format) {
1590  case SDL_PIXELFORMAT_YUY2:
1591  switch (dst_format) {
1592  case SDL_PIXELFORMAT_UYVY:
1593  return SDL_ConvertPixels_YUY2_to_UYVY(width, height, src, src_pitch, dst, dst_pitch);
1594  case SDL_PIXELFORMAT_YVYU:
1595  return SDL_ConvertPixels_YUY2_to_YVYU(width, height, src, src_pitch, dst, dst_pitch);
1596  default:
1597  break;
1598  }
1599  break;
1600  case SDL_PIXELFORMAT_UYVY:
1601  switch (dst_format) {
1602  case SDL_PIXELFORMAT_YUY2:
1603  return SDL_ConvertPixels_UYVY_to_YUY2(width, height, src, src_pitch, dst, dst_pitch);
1604  case SDL_PIXELFORMAT_YVYU:
1605  return SDL_ConvertPixels_UYVY_to_YVYU(width, height, src, src_pitch, dst, dst_pitch);
1606  default:
1607  break;
1608  }
1609  break;
1610  case SDL_PIXELFORMAT_YVYU:
1611  switch (dst_format) {
1612  case SDL_PIXELFORMAT_YUY2:
1613  return SDL_ConvertPixels_YVYU_to_YUY2(width, height, src, src_pitch, dst, dst_pitch);
1614  case SDL_PIXELFORMAT_UYVY:
1615  return SDL_ConvertPixels_YVYU_to_UYVY(width, height, src, src_pitch, dst, dst_pitch);
1616  default:
1617  break;
1618  }
1619  break;
1620  default:
1621  break;
1622  }
1623  return SDL_SetError("SDL_ConvertPixels_Packed4_to_Packed4: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format));
1624 }
1625 
1626 static int
1628  Uint32 src_format, const void *src, int src_pitch,
1629  Uint32 dst_format, void *dst, int dst_pitch)
1630 {
1631  int x, y;
1632  const Uint8 *srcY1, *srcY2, *srcU, *srcV;
1633  Uint32 srcY_pitch, srcUV_pitch;
1634  Uint32 srcY_pitch_left, srcUV_pitch_left, srcUV_pixel_stride;
1635  Uint8 *dstY1, *dstY2, *dstU1, *dstU2, *dstV1, *dstV2;
1636  Uint32 dstY_pitch, dstUV_pitch;
1637  Uint32 dst_pitch_left;
1638 
1639  if (src == dst) {
1640  return SDL_SetError("Can't change YUV plane types in-place");
1641  }
1642 
1643  if (GetYUVPlanes(width, height, src_format, src, src_pitch,
1644  &srcY1, &srcU, &srcV, &srcY_pitch, &srcUV_pitch) < 0) {
1645  return -1;
1646  }
1647  srcY2 = srcY1 + srcY_pitch;
1648  srcY_pitch_left = (srcY_pitch - width);
1649 
1650  if (src_format == SDL_PIXELFORMAT_NV12 || src_format == SDL_PIXELFORMAT_NV21) {
1651  srcUV_pixel_stride = 2;
1652  srcUV_pitch_left = (srcUV_pitch - 2*((width + 1)/2));
1653  } else {
1654  srcUV_pixel_stride = 1;
1655  srcUV_pitch_left = (srcUV_pitch - ((width + 1)/2));
1656  }
1657 
1658  if (GetYUVPlanes(width, height, dst_format, dst, dst_pitch,
1659  (const Uint8 **)&dstY1, (const Uint8 **)&dstU1, (const Uint8 **)&dstV1,
1660  &dstY_pitch, &dstUV_pitch) < 0) {
1661  return -1;
1662  }
1663  dstY2 = dstY1 + dstY_pitch;
1664  dstU2 = dstU1 + dstUV_pitch;
1665  dstV2 = dstV1 + dstUV_pitch;
1666  dst_pitch_left = (dstY_pitch - 4*((width + 1)/2));
1667 
1668  /* Copy 2x2 blocks of pixels at a time */
1669  for (y = 0; y < (height - 1); y += 2) {
1670  for (x = 0; x < (width - 1); x += 2) {
1671  /* Row 1 */
1672  *dstY1 = *srcY1++;
1673  dstY1 += 2;
1674  *dstY1 = *srcY1++;
1675  dstY1 += 2;
1676  *dstU1 = *srcU;
1677  *dstV1 = *srcV;
1678 
1679  /* Row 2 */
1680  *dstY2 = *srcY2++;
1681  dstY2 += 2;
1682  *dstY2 = *srcY2++;
1683  dstY2 += 2;
1684  *dstU2 = *srcU;
1685  *dstV2 = *srcV;
1686 
1687  srcU += srcUV_pixel_stride;
1688  srcV += srcUV_pixel_stride;
1689  dstU1 += 4;
1690  dstU2 += 4;
1691  dstV1 += 4;
1692  dstV2 += 4;
1693  }
1694 
1695  /* Last column */
1696  if (x == (width - 1)) {
1697  /* Row 1 */
1698  *dstY1 = *srcY1;
1699  dstY1 += 2;
1700  *dstY1 = *srcY1++;
1701  dstY1 += 2;
1702  *dstU1 = *srcU;
1703  *dstV1 = *srcV;
1704 
1705  /* Row 2 */
1706  *dstY2 = *srcY2;
1707  dstY2 += 2;
1708  *dstY2 = *srcY2++;
1709  dstY2 += 2;
1710  *dstU2 = *srcU;
1711  *dstV2 = *srcV;
1712 
1713  srcU += srcUV_pixel_stride;
1714  srcV += srcUV_pixel_stride;
1715  dstU1 += 4;
1716  dstU2 += 4;
1717  dstV1 += 4;
1718  dstV2 += 4;
1719  }
1720 
1721  srcY1 += srcY_pitch_left + srcY_pitch;
1722  srcY2 += srcY_pitch_left + srcY_pitch;
1723  srcU += srcUV_pitch_left;
1724  srcV += srcUV_pitch_left;
1725  dstY1 += dst_pitch_left + dstY_pitch;
1726  dstY2 += dst_pitch_left + dstY_pitch;
1727  dstU1 += dst_pitch_left + dstUV_pitch;
1728  dstU2 += dst_pitch_left + dstUV_pitch;
1729  dstV1 += dst_pitch_left + dstUV_pitch;
1730  dstV2 += dst_pitch_left + dstUV_pitch;
1731  }
1732 
1733  /* Last row */
1734  if (y == (height - 1)) {
1735  for (x = 0; x < (width - 1); x += 2) {
1736  /* Row 1 */
1737  *dstY1 = *srcY1++;
1738  dstY1 += 2;
1739  *dstY1 = *srcY1++;
1740  dstY1 += 2;
1741  *dstU1 = *srcU;
1742  *dstV1 = *srcV;
1743 
1744  srcU += srcUV_pixel_stride;
1745  srcV += srcUV_pixel_stride;
1746  dstU1 += 4;
1747  dstV1 += 4;
1748  }
1749 
1750  /* Last column */
1751  if (x == (width - 1)) {
1752  /* Row 1 */
1753  *dstY1 = *srcY1;
1754  dstY1 += 2;
1755  *dstY1 = *srcY1++;
1756  dstY1 += 2;
1757  *dstU1 = *srcU;
1758  *dstV1 = *srcV;
1759 
1760  srcU += srcUV_pixel_stride;
1761  srcV += srcUV_pixel_stride;
1762  dstU1 += 4;
1763  dstV1 += 4;
1764  }
1765  }
1766  return 0;
1767 }
1768 
1769 static int
1771  Uint32 src_format, const void *src, int src_pitch,
1772  Uint32 dst_format, void *dst, int dst_pitch)
1773 {
1774  int x, y;
1775  const Uint8 *srcY1, *srcY2, *srcU1, *srcU2, *srcV1, *srcV2;
1776  Uint32 srcY_pitch, srcUV_pitch;
1777  Uint32 src_pitch_left;
1778  Uint8 *dstY1, *dstY2, *dstU, *dstV;
1779  Uint32 dstY_pitch, dstUV_pitch;
1780  Uint32 dstY_pitch_left, dstUV_pitch_left, dstUV_pixel_stride;
1781 
1782  if (src == dst) {
1783  return SDL_SetError("Can't change YUV plane types in-place");
1784  }
1785 
1786  if (GetYUVPlanes(width, height, src_format, src, src_pitch,
1787  &srcY1, &srcU1, &srcV1, &srcY_pitch, &srcUV_pitch) < 0) {
1788  return -1;
1789  }
1790  srcY2 = srcY1 + srcY_pitch;
1791  srcU2 = srcU1 + srcUV_pitch;
1792  srcV2 = srcV1 + srcUV_pitch;
1793  src_pitch_left = (srcY_pitch - 4*((width + 1)/2));
1794 
1795  if (GetYUVPlanes(width, height, dst_format, dst, dst_pitch,
1796  (const Uint8 **)&dstY1, (const Uint8 **)&dstU, (const Uint8 **)&dstV,
1797  &dstY_pitch, &dstUV_pitch) < 0) {
1798  return -1;
1799  }
1800  dstY2 = dstY1 + dstY_pitch;
1801  dstY_pitch_left = (dstY_pitch - width);
1802 
1803  if (dst_format == SDL_PIXELFORMAT_NV12 || dst_format == SDL_PIXELFORMAT_NV21) {
1804  dstUV_pixel_stride = 2;
1805  dstUV_pitch_left = (dstUV_pitch - 2*((width + 1)/2));
1806  } else {
1807  dstUV_pixel_stride = 1;
1808  dstUV_pitch_left = (dstUV_pitch - ((width + 1)/2));
1809  }
1810 
1811  /* Copy 2x2 blocks of pixels at a time */
1812  for (y = 0; y < (height - 1); y += 2) {
1813  for (x = 0; x < (width - 1); x += 2) {
1814  /* Row 1 */
1815  *dstY1++ = *srcY1;
1816  srcY1 += 2;
1817  *dstY1++ = *srcY1;
1818  srcY1 += 2;
1819 
1820  /* Row 2 */
1821  *dstY2++ = *srcY2;
1822  srcY2 += 2;
1823  *dstY2++ = *srcY2;
1824  srcY2 += 2;
1825 
1826  *dstU = (Uint8)(((Uint32)*srcU1 + *srcU2)/2);
1827  *dstV = (Uint8)(((Uint32)*srcV1 + *srcV2)/2);
1828 
1829  srcU1 += 4;
1830  srcU2 += 4;
1831  srcV1 += 4;
1832  srcV2 += 4;
1833  dstU += dstUV_pixel_stride;
1834  dstV += dstUV_pixel_stride;
1835  }
1836 
1837  /* Last column */
1838  if (x == (width - 1)) {
1839  /* Row 1 */
1840  *dstY1 = *srcY1;
1841  srcY1 += 2;
1842  *dstY1++ = *srcY1;
1843  srcY1 += 2;
1844 
1845  /* Row 2 */
1846  *dstY2 = *srcY2;
1847  srcY2 += 2;
1848  *dstY2++ = *srcY2;
1849  srcY2 += 2;
1850 
1851  *dstU = (Uint8)(((Uint32)*srcU1 + *srcU2)/2);
1852  *dstV = (Uint8)(((Uint32)*srcV1 + *srcV2)/2);
1853 
1854  srcU1 += 4;
1855  srcU2 += 4;
1856  srcV1 += 4;
1857  srcV2 += 4;
1858  dstU += dstUV_pixel_stride;
1859  dstV += dstUV_pixel_stride;
1860  }
1861 
1862  srcY1 += src_pitch_left + srcY_pitch;
1863  srcY2 += src_pitch_left + srcY_pitch;
1864  srcU1 += src_pitch_left + srcUV_pitch;
1865  srcU2 += src_pitch_left + srcUV_pitch;
1866  srcV1 += src_pitch_left + srcUV_pitch;
1867  srcV2 += src_pitch_left + srcUV_pitch;
1868  dstY1 += dstY_pitch_left + dstY_pitch;
1869  dstY2 += dstY_pitch_left + dstY_pitch;
1870  dstU += dstUV_pitch_left;
1871  dstV += dstUV_pitch_left;
1872  }
1873 
1874  /* Last row */
1875  if (y == (height - 1)) {
1876  for (x = 0; x < (width - 1); x += 2) {
1877  *dstY1++ = *srcY1;
1878  srcY1 += 2;
1879  *dstY1++ = *srcY1;
1880  srcY1 += 2;
1881 
1882  *dstU = *srcU1;
1883  *dstV = *srcV1;
1884 
1885  srcU1 += 4;
1886  srcV1 += 4;
1887  dstU += dstUV_pixel_stride;
1888  dstV += dstUV_pixel_stride;
1889  }
1890 
1891  /* Last column */
1892  if (x == (width - 1)) {
1893  *dstY1 = *srcY1;
1894  *dstU = *srcU1;
1895  *dstV = *srcV1;
1896  }
1897  }
1898  return 0;
1899 }
1900 
1901 int
1903  Uint32 src_format, const void *src, int src_pitch,
1904  Uint32 dst_format, void *dst, int dst_pitch)
1905 {
1906  if (src_format == dst_format) {
1907  if (src == dst) {
1908  /* Nothing to do */
1909  return 0;
1910  }
1911  return SDL_ConvertPixels_YUV_to_YUV_Copy(width, height, src_format, src, src_pitch, dst, dst_pitch);
1912  }
1913 
1914  if (IsPlanar2x2Format(src_format) && IsPlanar2x2Format(dst_format)) {
1915  return SDL_ConvertPixels_Planar2x2_to_Planar2x2(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1916  } else if (IsPacked4Format(src_format) && IsPacked4Format(dst_format)) {
1917  return SDL_ConvertPixels_Packed4_to_Packed4(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1918  } else if (IsPlanar2x2Format(src_format) && IsPacked4Format(dst_format)) {
1919  return SDL_ConvertPixels_Planar2x2_to_Packed4(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1920  } else if (IsPacked4Format(src_format) && IsPlanar2x2Format(dst_format)) {
1921  return SDL_ConvertPixels_Packed4_to_Planar2x2(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1922  } else {
1923  return SDL_SetError("SDL_ConvertPixels_YUV_to_YUV: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format));
1924  }
1925 }
1926 
1927 /* vi: set ts=4 sw=4 expandtab: */
void SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode)
Set the YUV conversion mode.
Definition: SDL_yuv.c:36
void yuv420_rgb565_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
int SDL_ConvertPixels_YUV_to_YUV(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1902
void yuvnv12_rgb565_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_rgb565_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
void yuv420_bgra_lsx(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *v, const uint8_t *u, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_rgb24_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
SDL_YUV_CONVERSION_MODE SDL_GetYUVConversionModeForResolution(int width, int height)
Get the YUV conversion mode, returning the correct mode for the resolution when the current conversio...
Definition: SDL_yuv.c:46
static int SDL_ConvertPixels_YUY2_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1375
static int SDL_ConvertPixels_Planar2x2_to_Packed4(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1627
static int SDL_ConvertPixels_SwapNV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1197
static SDL_bool IsPacked4Format(Uint32 format)
Definition: SDL_yuv.c:85
const GLdouble * v
Definition: SDL_opengl.h:2064
GLenum GLenum dst
static int SDL_ConvertPixels_Packed4_to_Planar2x2(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1770
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLenum GLint GLint GLint GLint GLuint GLenum GLint GLint GLint dstY
#define READ_1x2_PIXELS
GLfloat GLfloat v1
static int SDL_ConvertPixels_YUY2_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1333
#define MAKE_Y(r, g, b)
void yuv420_abgr_lsx(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *v, const uint8_t *u, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
GLint GLint GLint srcY1
void yuv420_rgb24_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
static int SDL_ConvertPixels_SplitNV_to_UVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV)
Definition: SDL_yuv.c:1118
uint8_t Uint8
Definition: SDL_stdinc.h:179
void yuvnv12_bgra_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
#define MAKE_U(r, g, b)
GLfixed u1
static SDL_bool yuv_rgb_std(Uint32 src_format, Uint32 dst_format, Uint32 width, Uint32 height, const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride, Uint8 *rgb, Uint32 rgb_stride, YCbCrType yuv_type)
Definition: SDL_yuv.c:375
void yuv420_argb_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_abgr_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
GLenum src
void rgb24_yuv420_std(uint32_t width, uint32_t height, const uint8_t *RGB, uint32_t RGB_stride, uint8_t *Y, uint8_t *U, uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, YCbCrType yuv_type)
Definition: yuv_rgb.c:186
void yuv420_rgba_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
uint32_t Uint32
Definition: SDL_stdinc.h:203
float u[3]
Definition: SDL_yuv.c:545
static int GetYUVPlanes(int width, int height, Uint32 format, const void *yuv, int yuv_pitch, const Uint8 **y, const Uint8 **u, const Uint8 **v, Uint32 *y_stride, Uint32 *uv_stride)
Definition: SDL_yuv.c:92
void yuv420_rgb24_msa(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_abgr_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
static SDL_bool yuv_rgb_msa(Uint32 src_format, Uint32 dst_format, Uint32 width, Uint32 height, const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride, Uint8 *rgb, Uint32 rgb_stride, YCbCrType yuv_type)
Definition: SDL_yuv.c:291
void yuv422_argb_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
int SDL_ConvertPixels_YUV_to_RGB(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:479
#define MAKE_V(r, g, b)
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
#define READ_2x1_PIXELS
void yuv422_rgb24_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
static int SDL_ConvertPixels_YVYU_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1501
GLenum GLint GLint GLint srcY
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
void yuvnv12_rgba_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
#define PACKED4_TO_PACKED4_ROW_SSE2(shuffle)
Definition: SDL_yuv.c:1316
GLfixed GLfixed u2
GLfloat GLfloat GLfloat v2
#define SDL_memcpy
static int SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:550
void yuv420_rgba_lsx(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *v, const uint8_t *u, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_argb_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_rgba_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_abgr_msa(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
static int SDL_ConvertPixels_SwapUVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:988
void yuv420_rgb24_lsx(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_argb_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
#define SDL_free
static SDL_bool yuv_rgb_lsx(Uint32 src_format, Uint32 dst_format, Uint32 width, Uint32 height, const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride, Uint8 *rgb, Uint32 rgb_stride, YCbCrType yuv_type)
Definition: SDL_yuv.c:333
void yuv422_rgb565_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
static int GetYUVConversionType(int width, int height, YCbCrType *yuv_type)
Definition: SDL_yuv.c:59
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
Definition: SDL_x11sym.h:50
void yuv420_abgr_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
GLenum GLint GLuint mask
SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
Definition: SDL_endian.h:107
void yuv420_bgra_msa(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
GLenum mode
SDL_bool SDL_HasLSX(void)
Definition: SDL_cpuinfo.c:813
static SDL_bool yuv_rgb_sse(Uint32 src_format, Uint32 dst_format, Uint32 width, Uint32 height, const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride, Uint8 *rgb, Uint32 rgb_stride, YCbCrType yuv_type)
Definition: SDL_yuv.c:182
void yuvnv12_rgb24_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_abgr_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
static SDL_bool IsPlanar2x2Format(Uint32 format)
Definition: SDL_yuv.c:77
void yuv420_rgb24_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
float v[3]
Definition: SDL_yuv.c:546
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
#define READ_TWO_RGB_PIXELS
void yuv420_argb_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_rgba_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuvnv12_bgra_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
YCbCrType
Definition: yuv_rgb.h:22
static SDL_YUV_CONVERSION_MODE SDL_YUV_ConversionMode
Definition: SDL_yuv.c:33
static int SDL_ConvertPixels_UYVY_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1417
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define READ_2x2_PIXELS
void yuvnv12_argb_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
Definition: SDL_stdinc.h:161
#define READ_ONE_RGB_PIXEL
void yuv420_bgra_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
#define SDL_SetError
void yuvnv12_rgb565_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_argb_msa(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_bgra_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
#define SDL_YUV_SD_THRESHOLD
Definition: SDL_yuv.c:30
static int SDL_ConvertPixels_Packed4_to_Packed4(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1585
#define SDL_HasSSE2
#define G(x, y, z)
Definition: SDL_test_md5.c:74
float y[3]
Definition: SDL_yuv.c:544
void yuvnv12_abgr_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
uint16_t Uint16
Definition: SDL_stdinc.h:191
static int SDL_ConvertPixels_UYVY_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1459
void yuv420_bgra_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv422_rgba_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
SDL_YUV_CONVERSION_MODE
The formula used for converting between YUV and RGB.
Definition: SDL_surface.h:103
static int SDL_ConvertPixels_PackUVPlanes_to_NV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV)
Definition: SDL_yuv.c:1044
#define SDL_malloc
void yuv420_rgb565_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
#define SDL_ConvertPixels
void yuv422_abgr_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
void yuv420_argb_lsx(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *v, const uint8_t *u, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
#define V(value)
Definition: yuv_rgb.c:35
void yuv420_rgba_msa(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
static int SDL_ConvertPixels_YVYU_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1543
int SDL_ConvertPixels_RGB_to_YUV(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:876
static int SDL_ConvertPixels_Planar2x2_to_Planar2x2(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1245
SDL_YUV_CONVERSION_MODE SDL_GetYUVConversionMode()
Get the YUV conversion mode.
Definition: SDL_yuv.c:41
void yuvnv12_rgba_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
GLboolean GLboolean g
GLboolean GLboolean GLboolean b
#define READ_1x1_PIXEL
void yuvnv12_rgb24_sseu(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
#define SDL_HasMSA
static int SDL_ConvertPixels_YUV_to_YUV_Copy(int width, int height, Uint32 format, const void *src, int src_pitch, void *dst, int dst_pitch)
Definition: SDL_yuv.c:934
void yuv422_bgra_std(uint32_t width, uint32_t height, const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, uint8_t *rgb, uint32_t rgb_stride, YCbCrType yuv_type)
GLint GLint GLint GLint GLint GLint GLint dstY1
#define SDL_GetPixelFormatName