2 * Copyright (C) 2010 David Schleef <ds@schleef.org>
3 * Copyright (C) 2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
25 #include "videoconvert.h"
31 #include "gstvideoconvertorc.h"
34 static void videoconvert_convert_generic (VideoConvert * convert,
35 GstVideoFrame * dest, const GstVideoFrame * src);
36 static void videoconvert_convert_matrix (VideoConvert * convert,
38 static void videoconvert_convert_matrix16 (VideoConvert * convert,
40 static gboolean videoconvert_convert_lookup_fastpath (VideoConvert * convert);
41 static gboolean videoconvert_convert_compute_matrix (VideoConvert * convert);
42 static void videoconvert_dither_verterr (VideoConvert * convert,
43 guint16 * pixels, int j);
44 static void videoconvert_dither_halftone (VideoConvert * convert,
45 guint16 * pixels, int j);
49 videoconvert_convert_new (GstVideoInfo * in_info, GstVideoInfo * out_info)
51 VideoConvert *convert;
54 convert = g_malloc0 (sizeof (VideoConvert));
56 convert->in_info = *in_info;
57 convert->out_info = *out_info;
58 convert->dither16 = NULL;
60 if (!videoconvert_convert_lookup_fastpath (convert)) {
61 convert->convert = videoconvert_convert_generic;
62 if (!videoconvert_convert_compute_matrix (convert))
66 convert->width = GST_VIDEO_INFO_WIDTH (in_info);
67 convert->height = GST_VIDEO_INFO_HEIGHT (in_info);
69 width = convert->width;
71 convert->tmpline = g_malloc (sizeof (guint8) * (width + 8) * 4);
72 convert->tmpline16 = g_malloc (sizeof (guint16) * (width + 8) * 4);
73 convert->errline = g_malloc0 (sizeof (guint16) * width * 4);
80 videoconvert_convert_free (convert);
86 videoconvert_convert_free (VideoConvert * convert)
88 g_free (convert->tmpline);
89 g_free (convert->tmpline16);
90 g_free (convert->errline);
96 videoconvert_convert_set_dither (VideoConvert * convert, int type)
101 convert->dither16 = NULL;
104 convert->dither16 = videoconvert_dither_verterr;
107 convert->dither16 = videoconvert_dither_halftone;
113 videoconvert_convert_convert (VideoConvert * convert,
114 GstVideoFrame * dest, const GstVideoFrame * src)
116 convert->convert (convert, dest, src);
120 #define SCALE_F ((float) (1 << SCALE))
123 videoconvert_convert_matrix (VideoConvert * convert, guint8 * pixels)
129 for (i = 0; i < convert->width; i++) {
130 r = pixels[i * 4 + 1];
131 g = pixels[i * 4 + 2];
132 b = pixels[i * 4 + 3];
134 y = (convert->cmatrix[0][0] * r + convert->cmatrix[0][1] * g +
135 convert->cmatrix[0][2] * b + convert->cmatrix[0][3]) >> SCALE;
136 u = (convert->cmatrix[1][0] * r + convert->cmatrix[1][1] * g +
137 convert->cmatrix[1][2] * b + convert->cmatrix[1][3]) >> SCALE;
138 v = (convert->cmatrix[2][0] * r + convert->cmatrix[2][1] * g +
139 convert->cmatrix[2][2] * b + convert->cmatrix[2][3]) >> SCALE;
141 pixels[i * 4 + 1] = CLAMP (y, 0, 255);
142 pixels[i * 4 + 2] = CLAMP (u, 0, 255);
143 pixels[i * 4 + 3] = CLAMP (v, 0, 255);
148 videoconvert_convert_matrix16 (VideoConvert * convert, guint16 * pixels)
154 for (i = 0; i < convert->width; i++) {
155 r = pixels[i * 4 + 1];
156 g = pixels[i * 4 + 2];
157 b = pixels[i * 4 + 3];
159 y = (convert->cmatrix[0][0] * r + convert->cmatrix[0][1] * g +
160 convert->cmatrix[0][2] * b + convert->cmatrix[0][3]) >> SCALE;
161 u = (convert->cmatrix[1][0] * r + convert->cmatrix[1][1] * g +
162 convert->cmatrix[1][2] * b + convert->cmatrix[1][3]) >> SCALE;
163 v = (convert->cmatrix[2][0] * r + convert->cmatrix[2][1] * g +
164 convert->cmatrix[2][2] * b + convert->cmatrix[2][3]) >> SCALE;
166 pixels[i * 4 + 1] = CLAMP (y, 0, 65535);
167 pixels[i * 4 + 2] = CLAMP (u, 0, 65535);
168 pixels[i * 4 + 3] = CLAMP (v, 0, 65535);
173 get_Kr_Kb (GstVideoColorMatrix matrix, gdouble * Kr, gdouble * Kb)
180 case GST_VIDEO_COLOR_MATRIX_RGB:
184 case GST_VIDEO_COLOR_MATRIX_FCC:
188 case GST_VIDEO_COLOR_MATRIX_BT709:
192 case GST_VIDEO_COLOR_MATRIX_BT601:
196 case GST_VIDEO_COLOR_MATRIX_SMPTE240M:
201 GST_DEBUG ("matrix: %d, Kr %f, Kb %f", matrix, *Kr, *Kb);
206 videoconvert_convert_compute_matrix (VideoConvert * convert)
208 GstVideoInfo *in_info, *out_info;
211 const GstVideoFormatInfo *sfinfo, *dfinfo;
212 const GstVideoFormatInfo *suinfo, *duinfo;
213 gint offset[4], scale[4];
214 gdouble Kr = 0, Kb = 0;
216 in_info = &convert->in_info;
217 out_info = &convert->out_info;
219 sfinfo = in_info->finfo;
220 dfinfo = out_info->finfo;
222 if (sfinfo->unpack_func == NULL)
225 if (dfinfo->pack_func == NULL)
228 suinfo = gst_video_format_get_info (sfinfo->unpack_format);
229 duinfo = gst_video_format_get_info (dfinfo->unpack_format);
231 convert->in_bits = GST_VIDEO_FORMAT_INFO_DEPTH (suinfo, 0);
232 convert->out_bits = GST_VIDEO_FORMAT_INFO_DEPTH (duinfo, 0);
234 GST_DEBUG ("in bits %d, out bits %d", convert->in_bits, convert->out_bits);
236 if (in_info->colorimetry.range == out_info->colorimetry.range &&
237 in_info->colorimetry.matrix == out_info->colorimetry.matrix) {
238 GST_DEBUG ("using identity color transform");
239 convert->matrix = NULL;
240 convert->matrix16 = NULL;
244 /* calculate intermediate format for the matrix. When unpacking, we expand
245 * input to 16 when one of the inputs is 16 bits */
246 if (convert->in_bits == 16 || convert->out_bits == 16) {
247 if (GST_VIDEO_FORMAT_INFO_IS_RGB (suinfo))
248 suinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_ARGB64);
250 suinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_AYUV64);
252 if (GST_VIDEO_FORMAT_INFO_IS_RGB (duinfo))
253 duinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_ARGB64);
255 duinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_AYUV64);
258 color_matrix_set_identity (&dst);
260 /* 1, bring color components to [0..1.0] range */
261 gst_video_color_range_offsets (in_info->colorimetry.range, suinfo, offset,
263 color_matrix_offset_components (&dst, -offset[0], -offset[1], -offset[2]);
265 color_matrix_scale_components (&dst, 1 / ((float) scale[0]),
266 1 / ((float) scale[1]), 1 / ((float) scale[2]));
268 /* 2. bring components to R'G'B' space */
269 if (get_Kr_Kb (in_info->colorimetry.matrix, &Kr, &Kb))
270 color_matrix_YCbCr_to_RGB (&dst, Kr, Kb);
272 /* 3. inverse transfer function. R'G'B' to linear RGB */
274 /* 4. from RGB to XYZ using the primaries */
276 /* 5. from XYZ to RGB using the primaries */
278 /* 6. transfer function. linear RGB to R'G'B' */
280 /* 7. bring components to YCbCr space */
281 if (get_Kr_Kb (out_info->colorimetry.matrix, &Kr, &Kb))
282 color_matrix_RGB_to_YCbCr (&dst, Kr, Kb);
284 /* 8, bring color components to nominal range */
285 gst_video_color_range_offsets (out_info->colorimetry.range, duinfo, offset,
287 color_matrix_scale_components (&dst, (float) scale[0], (float) scale[1],
290 color_matrix_offset_components (&dst, offset[0], offset[1], offset[2]);
292 /* because we're doing fixed point matrix coefficients */
293 color_matrix_scale_components (&dst, SCALE_F, SCALE_F, SCALE_F);
295 for (i = 0; i < 4; i++)
296 for (j = 0; j < 4; j++)
297 convert->cmatrix[i][j] = rint (dst.m[i][j]);
299 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[0][0],
300 convert->cmatrix[0][1], convert->cmatrix[0][2], convert->cmatrix[0][3]);
301 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[1][0],
302 convert->cmatrix[1][1], convert->cmatrix[1][2], convert->cmatrix[1][3]);
303 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[2][0],
304 convert->cmatrix[2][1], convert->cmatrix[2][2], convert->cmatrix[2][3]);
305 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[3][0],
306 convert->cmatrix[3][1], convert->cmatrix[3][2], convert->cmatrix[3][3]);
308 convert->matrix = videoconvert_convert_matrix;
309 convert->matrix16 = videoconvert_convert_matrix16;
316 GST_ERROR ("no unpack_func for format %s",
317 gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (in_info)));
322 GST_ERROR ("no pack_func for format %s",
323 gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (out_info)));
329 videoconvert_dither_verterr (VideoConvert * convert, guint16 * pixels, int j)
332 guint16 *tmpline = convert->tmpline16;
333 guint16 *errline = convert->errline;
334 unsigned int mask = 0xff;
336 for (i = 0; i < 4 * convert->width; i++) {
337 int x = tmpline[i] + errline[i];
341 errline[i] = x & mask;
346 videoconvert_dither_halftone (VideoConvert * convert, guint16 * pixels, int j)
349 guint16 *tmpline = convert->tmpline16;
350 static guint16 halftone[8][8] = {
351 {0, 128, 32, 160, 8, 136, 40, 168},
352 {192, 64, 224, 96, 200, 72, 232, 104},
353 {48, 176, 16, 144, 56, 184, 24, 152},
354 {240, 112, 208, 80, 248, 120, 216, 88},
355 {12, 240, 44, 172, 4, 132, 36, 164},
356 {204, 76, 236, 108, 196, 68, 228, 100},
357 {60, 188, 28, 156, 52, 180, 20, 148},
358 {252, 142, 220, 92, 244, 116, 212, 84}
361 for (i = 0; i < convert->width * 4; i++) {
363 x = tmpline[i] + halftone[(i >> 2) & 7][j & 7];
370 #define TO_16(x) (((x)<<8) | (x))
372 #define UNPACK_FRAME(frame,dest,line,width) \
373 frame->info.finfo->unpack_func (frame->info.finfo, \
374 (GST_VIDEO_FRAME_IS_INTERLACED (frame) ? \
375 GST_VIDEO_PACK_FLAG_INTERLACED : \
376 GST_VIDEO_PACK_FLAG_NONE), \
377 dest, frame->data, frame->info.stride, 0, \
379 #define PACK_FRAME(frame,dest,line,width) \
380 frame->info.finfo->pack_func (frame->info.finfo, \
381 (GST_VIDEO_FRAME_IS_INTERLACED (frame) ? \
382 GST_VIDEO_PACK_FLAG_INTERLACED : \
383 GST_VIDEO_PACK_FLAG_NONE), \
384 dest, 0, frame->data, frame->info.stride, \
385 frame->info.chroma_site, line, width);
388 videoconvert_convert_generic (VideoConvert * convert, GstVideoFrame * dest,
389 const GstVideoFrame * src)
393 guint in_bits, out_bits;
397 height = convert->height;
398 width = convert->width;
400 in_bits = convert->in_bits;
401 out_bits = convert->out_bits;
403 for (j = 0; j < height; j++) {
405 UNPACK_FRAME (src, convert->tmpline16, j, width);
407 UNPACK_FRAME (src, convert->tmpline, j, width);
410 for (i = 0; i < width * 4; i++)
411 convert->tmpline16[i] = TO_16 (convert->tmpline[i]);
414 if (out_bits == 16 || in_bits == 16) {
415 if (convert->matrix16)
416 convert->matrix16 (convert, convert->tmpline16);
417 if (convert->dither16)
418 convert->dither16 (convert, convert->tmpline16, j);
421 convert->matrix (convert, convert->tmpline);
424 if (out_bits == 16) {
425 PACK_FRAME (dest, convert->tmpline16, j, width);
428 for (i = 0; i < width * 4; i++)
429 convert->tmpline[i] = convert->tmpline16[i] >> 8;
431 PACK_FRAME (dest, convert->tmpline, j, width);
435 gst_video_format_get_palette (GST_VIDEO_FRAME_FORMAT (dest),
437 memcpy (GST_VIDEO_FRAME_PLANE_DATA (dest, 1), pal, palsize);
441 #define FRAME_GET_PLANE_STRIDE(frame, plane) \
442 GST_VIDEO_FRAME_PLANE_STRIDE (frame, plane)
443 #define FRAME_GET_PLANE_LINE(frame, plane, line) \
444 (gpointer)(((guint8*)(GST_VIDEO_FRAME_PLANE_DATA (frame, plane))) + \
445 FRAME_GET_PLANE_STRIDE (frame, plane) * (line))
447 #define FRAME_GET_COMP_STRIDE(frame, comp) \
448 GST_VIDEO_FRAME_COMP_STRIDE (frame, comp)
449 #define FRAME_GET_COMP_LINE(frame, comp, line) \
450 (gpointer)(((guint8*)(GST_VIDEO_FRAME_COMP_DATA (frame, comp))) + \
451 FRAME_GET_COMP_STRIDE (frame, comp) * (line))
453 #define FRAME_GET_STRIDE(frame) FRAME_GET_PLANE_STRIDE (frame, 0)
454 #define FRAME_GET_LINE(frame,line) FRAME_GET_PLANE_LINE (frame, 0, line)
456 #define FRAME_GET_Y_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_Y, line)
457 #define FRAME_GET_U_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_U, line)
458 #define FRAME_GET_V_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_V, line)
459 #define FRAME_GET_A_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_A, line)
461 #define FRAME_GET_Y_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_Y)
462 #define FRAME_GET_U_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_U)
463 #define FRAME_GET_V_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_V)
464 #define FRAME_GET_A_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_A)
468 #define GET_LINE_OFFSETS(interlaced,line,l1,l2) \
470 l1 = (line & 2 ? line - 1 : line); \
479 convert_I420_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
480 const GstVideoFrame * src)
483 gint width = convert->width;
484 gint height = convert->height;
485 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
488 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
489 GET_LINE_OFFSETS (interlaced, i, l1, l2);
491 video_convert_orc_convert_I420_YUY2 (FRAME_GET_LINE (dest, l1),
492 FRAME_GET_LINE (dest, l2),
493 FRAME_GET_Y_LINE (src, l1),
494 FRAME_GET_Y_LINE (src, l2),
495 FRAME_GET_U_LINE (src, i >> 1),
496 FRAME_GET_V_LINE (src, i >> 1), (width + 1) / 2);
499 /* now handle last line */
501 UNPACK_FRAME (src, convert->tmpline, height - 1, width);
502 PACK_FRAME (dest, convert->tmpline, height - 1, width);
507 convert_I420_UYVY (VideoConvert * convert, GstVideoFrame * dest,
508 const GstVideoFrame * src)
511 gint width = convert->width;
512 gint height = convert->height;
513 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
516 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
517 GET_LINE_OFFSETS (interlaced, i, l1, l2);
519 video_convert_orc_convert_I420_UYVY (FRAME_GET_LINE (dest, l1),
520 FRAME_GET_LINE (dest, l2),
521 FRAME_GET_Y_LINE (src, l1),
522 FRAME_GET_Y_LINE (src, l2),
523 FRAME_GET_U_LINE (src, i >> 1),
524 FRAME_GET_V_LINE (src, i >> 1), (width + 1) / 2);
527 /* now handle last line */
529 UNPACK_FRAME (src, convert->tmpline, height - 1, width);
530 PACK_FRAME (dest, convert->tmpline, height - 1, width);
535 convert_I420_AYUV (VideoConvert * convert, GstVideoFrame * dest,
536 const GstVideoFrame * src)
539 gint width = convert->width;
540 gint height = convert->height;
541 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
544 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
545 GET_LINE_OFFSETS (interlaced, i, l1, l2);
547 video_convert_orc_convert_I420_AYUV (FRAME_GET_LINE (dest, l1),
548 FRAME_GET_LINE (dest, l2),
549 FRAME_GET_Y_LINE (src, l1),
550 FRAME_GET_Y_LINE (src, l2),
551 FRAME_GET_U_LINE (src, i >> 1), FRAME_GET_V_LINE (src, i >> 1), width);
554 /* now handle last line */
556 UNPACK_FRAME (src, convert->tmpline, height - 1, width);
557 PACK_FRAME (dest, convert->tmpline, height - 1, width);
562 convert_I420_Y42B (VideoConvert * convert, GstVideoFrame * dest,
563 const GstVideoFrame * src)
565 gint width = convert->width;
566 gint height = convert->height;
568 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
569 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
570 FRAME_GET_Y_STRIDE (src), width, height);
572 video_convert_orc_planar_chroma_420_422 (FRAME_GET_U_LINE (dest, 0),
573 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (dest, 1),
574 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
575 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
577 video_convert_orc_planar_chroma_420_422 (FRAME_GET_V_LINE (dest, 0),
578 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (dest, 1),
579 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
580 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
584 convert_I420_Y444 (VideoConvert * convert, GstVideoFrame * dest,
585 const GstVideoFrame * src)
587 gint width = convert->width;
588 gint height = convert->height;
590 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
591 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
592 FRAME_GET_Y_STRIDE (src), width, height);
594 video_convert_orc_planar_chroma_420_444 (FRAME_GET_U_LINE (dest, 0),
595 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (dest, 1),
596 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
597 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
599 video_convert_orc_planar_chroma_420_444 (FRAME_GET_V_LINE (dest, 0),
600 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (dest, 1),
601 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
602 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
604 /* now handle last line */
606 UNPACK_FRAME (src, convert->tmpline, height - 1, width);
607 PACK_FRAME (dest, convert->tmpline, height - 1, width);
612 convert_YUY2_I420 (VideoConvert * convert, GstVideoFrame * dest,
613 const GstVideoFrame * src)
616 gint width = convert->width;
617 gint height = convert->height;
618 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
625 for (i = 0; i < h; i += 2) {
626 GET_LINE_OFFSETS (interlaced, i, l1, l2);
628 video_convert_orc_convert_YUY2_I420 (FRAME_GET_Y_LINE (dest, l1),
629 FRAME_GET_Y_LINE (dest, l2),
630 FRAME_GET_U_LINE (dest, i >> 1),
631 FRAME_GET_V_LINE (dest, i >> 1),
632 FRAME_GET_LINE (src, l1), FRAME_GET_LINE (src, l2), (width + 1) / 2);
635 /* now handle last line */
637 UNPACK_FRAME (src, convert->tmpline, height - 1, width);
638 PACK_FRAME (dest, convert->tmpline, height - 1, width);
643 convert_YUY2_AYUV (VideoConvert * convert, GstVideoFrame * dest,
644 const GstVideoFrame * src)
646 gint width = convert->width;
647 gint height = convert->height;
649 video_convert_orc_convert_YUY2_AYUV (FRAME_GET_LINE (dest, 0),
650 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
651 FRAME_GET_STRIDE (src), (width + 1) / 2,
652 height & 1 ? height - 1 : height);
654 /* now handle last line */
656 UNPACK_FRAME (src, convert->tmpline, height - 1, width);
657 PACK_FRAME (dest, convert->tmpline, height - 1, width);
662 convert_YUY2_Y42B (VideoConvert * convert, GstVideoFrame * dest,
663 const GstVideoFrame * src)
665 gint width = convert->width;
666 gint height = convert->height;
668 video_convert_orc_convert_YUY2_Y42B (FRAME_GET_Y_LINE (dest, 0),
669 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
670 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
671 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
672 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
676 convert_YUY2_Y444 (VideoConvert * convert, GstVideoFrame * dest,
677 const GstVideoFrame * src)
679 gint width = convert->width;
680 gint height = convert->height;
682 video_convert_orc_convert_YUY2_Y444 (FRAME_GET_COMP_LINE (dest, 0, 0),
683 FRAME_GET_COMP_STRIDE (dest, 0), FRAME_GET_COMP_LINE (dest, 1, 0),
684 FRAME_GET_COMP_STRIDE (dest, 1), FRAME_GET_COMP_LINE (dest, 2, 0),
685 FRAME_GET_COMP_STRIDE (dest, 2), FRAME_GET_LINE (src, 0),
686 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
691 convert_UYVY_I420 (VideoConvert * convert, GstVideoFrame * dest,
692 const GstVideoFrame * src)
695 gint width = convert->width;
696 gint height = convert->height;
697 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
700 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
701 GET_LINE_OFFSETS (interlaced, i, l1, l2);
703 video_convert_orc_convert_UYVY_I420 (FRAME_GET_COMP_LINE (dest, 0, l1),
704 FRAME_GET_COMP_LINE (dest, 0, l2),
705 FRAME_GET_COMP_LINE (dest, 1, i >> 1),
706 FRAME_GET_COMP_LINE (dest, 2, i >> 1),
707 FRAME_GET_LINE (src, l1), FRAME_GET_LINE (src, l2), (width + 1) / 2);
710 /* now handle last line */
712 UNPACK_FRAME (src, convert->tmpline, height - 1, width);
713 PACK_FRAME (dest, convert->tmpline, height - 1, width);
718 convert_UYVY_AYUV (VideoConvert * convert, GstVideoFrame * dest,
719 const GstVideoFrame * src)
721 gint width = convert->width;
722 gint height = convert->height;
724 video_convert_orc_convert_UYVY_AYUV (FRAME_GET_LINE (dest, 0),
725 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
726 FRAME_GET_STRIDE (src), (width + 1) / 2,
727 height & 1 ? height - 1 : height);
729 /* now handle last line */
731 UNPACK_FRAME (src, convert->tmpline, height - 1, width);
732 PACK_FRAME (dest, convert->tmpline, height - 1, width);
737 convert_UYVY_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
738 const GstVideoFrame * src)
740 gint width = convert->width;
741 gint height = convert->height;
743 video_convert_orc_convert_UYVY_YUY2 (FRAME_GET_LINE (dest, 0),
744 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
745 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
749 convert_UYVY_Y42B (VideoConvert * convert, GstVideoFrame * dest,
750 const GstVideoFrame * src)
752 gint width = convert->width;
753 gint height = convert->height;
755 video_convert_orc_convert_UYVY_Y42B (FRAME_GET_Y_LINE (dest, 0),
756 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
757 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
758 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
759 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
763 convert_UYVY_Y444 (VideoConvert * convert, GstVideoFrame * dest,
764 const GstVideoFrame * src)
766 gint width = convert->width;
767 gint height = convert->height;
769 video_convert_orc_convert_UYVY_Y444 (FRAME_GET_Y_LINE (dest, 0),
770 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
771 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
772 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
773 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
777 convert_AYUV_I420 (VideoConvert * convert, GstVideoFrame * dest,
778 const GstVideoFrame * src)
780 gint width = convert->width;
781 gint height = convert->height;
783 video_convert_orc_convert_AYUV_I420 (FRAME_GET_Y_LINE (dest, 0),
784 2 * FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (dest, 1),
785 2 * FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
786 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
787 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
788 2 * FRAME_GET_STRIDE (src), FRAME_GET_LINE (src, 1),
789 2 * FRAME_GET_STRIDE (src), width / 2, height / 2);
793 convert_AYUV_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
794 const GstVideoFrame * src)
796 gint width = convert->width;
797 gint height = convert->height;
799 video_convert_orc_convert_AYUV_YUY2 (FRAME_GET_LINE (dest, 0),
800 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
801 FRAME_GET_STRIDE (src), width / 2, height);
805 convert_AYUV_UYVY (VideoConvert * convert, GstVideoFrame * dest,
806 const GstVideoFrame * src)
808 gint width = convert->width;
809 gint height = convert->height;
811 video_convert_orc_convert_AYUV_UYVY (FRAME_GET_LINE (dest, 0),
812 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
813 FRAME_GET_STRIDE (src), width / 2, height);
817 convert_AYUV_Y42B (VideoConvert * convert, GstVideoFrame * dest,
818 const GstVideoFrame * src)
820 gint width = convert->width;
821 gint height = convert->height;
823 video_convert_orc_convert_AYUV_Y42B (FRAME_GET_Y_LINE (dest, 0),
824 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
825 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
826 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
827 FRAME_GET_STRIDE (src), (width + 1) / 2,
828 height & 1 ? height - 1 : height);
830 /* now handle last line */
832 UNPACK_FRAME (src, convert->tmpline, height - 1, width);
833 PACK_FRAME (dest, convert->tmpline, height - 1, width);
838 convert_AYUV_Y444 (VideoConvert * convert, GstVideoFrame * dest,
839 const GstVideoFrame * src)
841 gint width = convert->width;
842 gint height = convert->height;
844 video_convert_orc_convert_AYUV_Y444 (FRAME_GET_Y_LINE (dest, 0),
845 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
846 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
847 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
848 FRAME_GET_STRIDE (src), width, height);
852 convert_Y42B_I420 (VideoConvert * convert, GstVideoFrame * dest,
853 const GstVideoFrame * src)
855 gint width = convert->width;
856 gint height = convert->height;
858 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
859 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
860 FRAME_GET_Y_STRIDE (src), width, height);
862 video_convert_orc_planar_chroma_422_420 (FRAME_GET_U_LINE (dest, 0),
863 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
864 2 * FRAME_GET_U_STRIDE (src), FRAME_GET_U_LINE (src, 1),
865 2 * FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
867 video_convert_orc_planar_chroma_422_420 (FRAME_GET_V_LINE (dest, 0),
868 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
869 2 * FRAME_GET_V_STRIDE (src), FRAME_GET_V_LINE (src, 1),
870 2 * FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
872 /* now handle last line */
874 UNPACK_FRAME (src, convert->tmpline, height - 1, width);
875 PACK_FRAME (dest, convert->tmpline, height - 1, width);
880 convert_Y42B_Y444 (VideoConvert * convert, GstVideoFrame * dest,
881 const GstVideoFrame * src)
883 gint width = convert->width;
884 gint height = convert->height;
886 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
887 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
888 FRAME_GET_Y_STRIDE (src), width, height);
890 video_convert_orc_planar_chroma_422_444 (FRAME_GET_U_LINE (dest, 0),
891 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
892 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height);
894 video_convert_orc_planar_chroma_422_444 (FRAME_GET_V_LINE (dest, 0),
895 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
896 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
900 convert_Y42B_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
901 const GstVideoFrame * src)
903 gint width = convert->width;
904 gint height = convert->height;
906 video_convert_orc_convert_Y42B_YUY2 (FRAME_GET_LINE (dest, 0),
907 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
908 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
909 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
910 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
914 convert_Y42B_UYVY (VideoConvert * convert, GstVideoFrame * dest,
915 const GstVideoFrame * src)
917 gint width = convert->width;
918 gint height = convert->height;
920 video_convert_orc_convert_Y42B_UYVY (FRAME_GET_LINE (dest, 0),
921 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
922 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
923 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
924 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
928 convert_Y42B_AYUV (VideoConvert * convert, GstVideoFrame * dest,
929 const GstVideoFrame * src)
931 gint width = convert->width;
932 gint height = convert->height;
934 video_convert_orc_convert_Y42B_AYUV (FRAME_GET_LINE (dest, 0),
935 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
936 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
937 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
938 FRAME_GET_V_STRIDE (src), (width) / 2, height);
942 convert_Y444_I420 (VideoConvert * convert, GstVideoFrame * dest,
943 const GstVideoFrame * src)
945 gint width = convert->width;
946 gint height = convert->height;
948 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
949 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
950 FRAME_GET_Y_STRIDE (src), width, height);
952 video_convert_orc_planar_chroma_444_420 (FRAME_GET_U_LINE (dest, 0),
953 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
954 2 * FRAME_GET_U_STRIDE (src), FRAME_GET_U_LINE (src, 1),
955 2 * FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
957 video_convert_orc_planar_chroma_444_420 (FRAME_GET_V_LINE (dest, 0),
958 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
959 2 * FRAME_GET_V_STRIDE (src), FRAME_GET_V_LINE (src, 1),
960 2 * FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
962 /* now handle last line */
964 UNPACK_FRAME (src, convert->tmpline, height - 1, width);
965 PACK_FRAME (dest, convert->tmpline, height - 1, width);
970 convert_Y444_Y42B (VideoConvert * convert, GstVideoFrame * dest,
971 const GstVideoFrame * src)
973 gint width = convert->width;
974 gint height = convert->height;
976 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
977 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
978 FRAME_GET_Y_STRIDE (src), width, height);
980 video_convert_orc_planar_chroma_444_422 (FRAME_GET_U_LINE (dest, 0),
981 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
982 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height);
984 video_convert_orc_planar_chroma_444_422 (FRAME_GET_V_LINE (dest, 0),
985 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
986 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
990 convert_Y444_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
991 const GstVideoFrame * src)
993 gint width = convert->width;
994 gint height = convert->height;
996 video_convert_orc_convert_Y444_YUY2 (FRAME_GET_LINE (dest, 0),
997 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
998 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
999 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1000 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
1004 convert_Y444_UYVY (VideoConvert * convert, GstVideoFrame * dest,
1005 const GstVideoFrame * src)
1007 gint width = convert->width;
1008 gint height = convert->height;
1010 video_convert_orc_convert_Y444_UYVY (FRAME_GET_LINE (dest, 0),
1011 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1012 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1013 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1014 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
1018 convert_Y444_AYUV (VideoConvert * convert, GstVideoFrame * dest,
1019 const GstVideoFrame * src)
1021 gint width = convert->width;
1022 gint height = convert->height;
1024 video_convert_orc_convert_Y444_AYUV (FRAME_GET_LINE (dest, 0),
1025 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1026 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1027 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1028 FRAME_GET_V_STRIDE (src), width, height);
1031 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1033 convert_AYUV_ARGB (VideoConvert * convert, GstVideoFrame * dest,
1034 const GstVideoFrame * src)
1036 gint width = convert->width;
1037 gint height = convert->height;
1039 video_convert_orc_convert_AYUV_ARGB (FRAME_GET_LINE (dest, 0),
1040 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1041 FRAME_GET_STRIDE (src), width, height);
1045 convert_AYUV_BGRA (VideoConvert * convert, GstVideoFrame * dest,
1046 const GstVideoFrame * src)
1048 gint width = convert->width;
1049 gint height = convert->height;
1051 video_convert_orc_convert_AYUV_BGRA (FRAME_GET_LINE (dest, 0),
1052 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1053 FRAME_GET_STRIDE (src), width, height);
1057 convert_AYUV_ABGR (VideoConvert * convert, GstVideoFrame * dest,
1058 const GstVideoFrame * src)
1060 gint width = convert->width;
1061 gint height = convert->height;
1063 video_convert_orc_convert_AYUV_ABGR (FRAME_GET_LINE (dest, 0),
1064 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1065 FRAME_GET_STRIDE (src), width, height);
1069 convert_AYUV_RGBA (VideoConvert * convert, GstVideoFrame * dest,
1070 const GstVideoFrame * src)
1072 gint width = convert->width;
1073 gint height = convert->height;
1075 video_convert_orc_convert_AYUV_RGBA (FRAME_GET_LINE (dest, 0),
1076 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1077 FRAME_GET_STRIDE (src), width, height);
1081 convert_I420_BGRA (VideoConvert * convert, GstVideoFrame * dest,
1082 const GstVideoFrame * src)
1086 gint width = convert->width;
1087 gint height = convert->height;
1090 for (i = 0; i < height; i++) {
1092 video_convert_orc_convert_I420_BGRA_avg (FRAME_GET_LINE (dest, i),
1093 FRAME_GET_Y_LINE (src, i),
1094 FRAME_GET_U_LINE (src, i >> 1),
1095 FRAME_GET_U_LINE (src, (i >> 1) + 1),
1096 FRAME_GET_V_LINE (src, i >> 1),
1097 FRAME_GET_V_LINE (src, (i >> 1) + 1), width);
1099 video_convert_orc_convert_I420_BGRA (FRAME_GET_LINE (dest, i),
1100 FRAME_GET_Y_LINE (src, i),
1101 FRAME_GET_U_LINE (src, i >> 1),
1102 FRAME_GET_V_LINE (src, i >> 1), width);
1106 for (i = 0; i < height; i++) {
1107 video_convert_orc_convert_I420_BGRA (FRAME_GET_LINE (dest, i),
1108 FRAME_GET_Y_LINE (src, i),
1109 FRAME_GET_U_LINE (src, i >> 1),
1110 FRAME_GET_V_LINE (src, i >> 1), width);
1122 GstVideoFormat in_format;
1123 GstVideoColorMatrix in_matrix;
1124 GstVideoFormat out_format;
1125 GstVideoColorMatrix out_matrix;
1126 gboolean keeps_color_matrix;
1127 gboolean keeps_interlaced;
1128 void (*convert) (VideoConvert * convert, GstVideoFrame * dest,
1129 const GstVideoFrame * src);
1131 static const VideoTransform transforms[] = {
1132 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1133 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_I420_YUY2},
1134 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1135 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_I420_UYVY},
1136 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1137 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_I420_AYUV},
1138 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1139 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, convert_I420_Y42B},
1140 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1141 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, convert_I420_Y444},
1143 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1144 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_YUY2_I420},
1145 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1146 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_UYVY_YUY2}, /* alias */
1147 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1148 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_YUY2_AYUV},
1149 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1150 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_YUY2_Y42B},
1151 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1152 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_YUY2_Y444},
1154 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1155 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_UYVY_I420},
1156 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1157 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_UYVY_YUY2},
1158 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1159 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_UYVY_AYUV},
1160 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1161 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_UYVY_Y42B},
1162 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1163 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_UYVY_Y444},
1165 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1166 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, convert_AYUV_I420},
1167 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1168 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_AYUV_YUY2},
1169 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1170 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_AYUV_UYVY},
1171 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1172 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_AYUV_Y42B},
1173 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1174 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_AYUV_Y444},
1176 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1177 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, convert_Y42B_I420},
1178 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1179 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y42B_YUY2},
1180 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1181 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y42B_UYVY},
1182 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1183 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y42B_AYUV},
1184 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1185 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y42B_Y444},
1187 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1188 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, convert_Y444_I420},
1189 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1190 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y444_YUY2},
1191 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1192 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y444_UYVY},
1193 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1194 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y444_AYUV},
1195 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1196 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y444_Y42B},
1198 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1199 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_ARGB,
1200 GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_ARGB},
1201 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_BGRA,
1202 GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_BGRA},
1203 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_xRGB, GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_ARGB}, /* alias */
1204 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_BGRx, GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_BGRA}, /* alias */
1205 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_ABGR,
1206 GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_ABGR},
1207 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_RGBA,
1208 GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_RGBA},
1209 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_xBGR, GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_ABGR}, /* alias */
1210 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_RGBx, GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_RGBA}, /* alias */
1212 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_BGRA,
1213 GST_VIDEO_COLOR_MATRIX_RGB, FALSE, FALSE, convert_I420_BGRA},
1218 videoconvert_convert_lookup_fastpath (VideoConvert * convert)
1221 GstVideoFormat in_format, out_format;
1222 GstVideoColorMatrix in_matrix, out_matrix;
1223 gboolean interlaced;
1225 in_format = GST_VIDEO_INFO_FORMAT (&convert->in_info);
1226 out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info);
1228 in_matrix = convert->in_info.colorimetry.matrix;
1229 out_matrix = convert->out_info.colorimetry.matrix;
1231 interlaced = GST_VIDEO_INFO_IS_INTERLACED (&convert->in_info);
1232 interlaced |= GST_VIDEO_INFO_IS_INTERLACED (&convert->out_info);
1234 for (i = 0; i < sizeof (transforms) / sizeof (transforms[0]); i++) {
1235 if (transforms[i].in_format == in_format &&
1236 transforms[i].out_format == out_format &&
1237 (transforms[i].keeps_color_matrix ||
1238 (transforms[i].in_matrix == in_matrix &&
1239 transforms[i].out_matrix == out_matrix)) &&
1240 (transforms[i].keeps_interlaced || !interlaced)) {
1241 GST_DEBUG ("using fastpath");
1242 convert->convert = transforms[i].convert;