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;
70 lines = out_info->finfo->pack_lines;
72 convert->lines = lines;
74 convert->tmpline8 = g_malloc (lines * sizeof (guint8) * (width + 8) * 4);
75 convert->tmpline16 = g_malloc (lines * sizeof (guint16) * (width + 8) * 4);
76 convert->errline = g_malloc0 (sizeof (guint16) * width * 4);
83 videoconvert_convert_free (convert);
89 videoconvert_convert_free (VideoConvert * convert)
91 g_free (convert->tmpline8);
92 g_free (convert->tmpline16);
93 g_free (convert->errline);
99 videoconvert_convert_set_dither (VideoConvert * convert, int type)
104 convert->dither16 = NULL;
107 convert->dither16 = videoconvert_dither_verterr;
110 convert->dither16 = videoconvert_dither_halftone;
116 videoconvert_convert_convert (VideoConvert * convert,
117 GstVideoFrame * dest, const GstVideoFrame * src)
119 convert->convert (convert, dest, src);
123 #define SCALE_F ((float) (1 << SCALE))
126 videoconvert_convert_matrix (VideoConvert * convert, guint8 * pixels)
132 for (i = 0; i < convert->width; i++) {
133 r = pixels[i * 4 + 1];
134 g = pixels[i * 4 + 2];
135 b = pixels[i * 4 + 3];
137 y = (convert->cmatrix[0][0] * r + convert->cmatrix[0][1] * g +
138 convert->cmatrix[0][2] * b + convert->cmatrix[0][3]) >> SCALE;
139 u = (convert->cmatrix[1][0] * r + convert->cmatrix[1][1] * g +
140 convert->cmatrix[1][2] * b + convert->cmatrix[1][3]) >> SCALE;
141 v = (convert->cmatrix[2][0] * r + convert->cmatrix[2][1] * g +
142 convert->cmatrix[2][2] * b + convert->cmatrix[2][3]) >> SCALE;
144 pixels[i * 4 + 1] = CLAMP (y, 0, 255);
145 pixels[i * 4 + 2] = CLAMP (u, 0, 255);
146 pixels[i * 4 + 3] = CLAMP (v, 0, 255);
151 videoconvert_convert_matrix16 (VideoConvert * convert, guint16 * pixels)
157 for (i = 0; i < convert->width; i++) {
158 r = pixels[i * 4 + 1];
159 g = pixels[i * 4 + 2];
160 b = pixels[i * 4 + 3];
162 y = (convert->cmatrix[0][0] * r + convert->cmatrix[0][1] * g +
163 convert->cmatrix[0][2] * b + convert->cmatrix[0][3]) >> SCALE;
164 u = (convert->cmatrix[1][0] * r + convert->cmatrix[1][1] * g +
165 convert->cmatrix[1][2] * b + convert->cmatrix[1][3]) >> SCALE;
166 v = (convert->cmatrix[2][0] * r + convert->cmatrix[2][1] * g +
167 convert->cmatrix[2][2] * b + convert->cmatrix[2][3]) >> SCALE;
169 pixels[i * 4 + 1] = CLAMP (y, 0, 65535);
170 pixels[i * 4 + 2] = CLAMP (u, 0, 65535);
171 pixels[i * 4 + 3] = CLAMP (v, 0, 65535);
176 get_Kr_Kb (GstVideoColorMatrix matrix, gdouble * Kr, gdouble * Kb)
183 case GST_VIDEO_COLOR_MATRIX_RGB:
187 case GST_VIDEO_COLOR_MATRIX_FCC:
191 case GST_VIDEO_COLOR_MATRIX_BT709:
195 case GST_VIDEO_COLOR_MATRIX_BT601:
199 case GST_VIDEO_COLOR_MATRIX_SMPTE240M:
204 GST_DEBUG ("matrix: %d, Kr %f, Kb %f", matrix, *Kr, *Kb);
209 videoconvert_convert_compute_matrix (VideoConvert * convert)
211 GstVideoInfo *in_info, *out_info;
214 const GstVideoFormatInfo *sfinfo, *dfinfo;
215 const GstVideoFormatInfo *suinfo, *duinfo;
216 gint offset[4], scale[4];
217 gdouble Kr = 0, Kb = 0;
219 in_info = &convert->in_info;
220 out_info = &convert->out_info;
222 sfinfo = in_info->finfo;
223 dfinfo = out_info->finfo;
225 if (sfinfo->unpack_func == NULL)
228 if (dfinfo->pack_func == NULL)
231 suinfo = gst_video_format_get_info (sfinfo->unpack_format);
232 duinfo = gst_video_format_get_info (dfinfo->unpack_format);
234 convert->in_bits = GST_VIDEO_FORMAT_INFO_DEPTH (suinfo, 0);
235 convert->out_bits = GST_VIDEO_FORMAT_INFO_DEPTH (duinfo, 0);
237 GST_DEBUG ("in bits %d, out bits %d", convert->in_bits, convert->out_bits);
239 if (in_info->colorimetry.range == out_info->colorimetry.range &&
240 in_info->colorimetry.matrix == out_info->colorimetry.matrix) {
241 GST_DEBUG ("using identity color transform");
242 convert->matrix = NULL;
243 convert->matrix16 = NULL;
247 /* calculate intermediate format for the matrix. When unpacking, we expand
248 * input to 16 when one of the inputs is 16 bits */
249 if (convert->in_bits == 16 || convert->out_bits == 16) {
250 if (GST_VIDEO_FORMAT_INFO_IS_RGB (suinfo))
251 suinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_ARGB64);
253 suinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_AYUV64);
255 if (GST_VIDEO_FORMAT_INFO_IS_RGB (duinfo))
256 duinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_ARGB64);
258 duinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_AYUV64);
261 color_matrix_set_identity (&dst);
263 /* 1, bring color components to [0..1.0] range */
264 gst_video_color_range_offsets (in_info->colorimetry.range, suinfo, offset,
266 color_matrix_offset_components (&dst, -offset[0], -offset[1], -offset[2]);
268 color_matrix_scale_components (&dst, 1 / ((float) scale[0]),
269 1 / ((float) scale[1]), 1 / ((float) scale[2]));
271 /* 2. bring components to R'G'B' space */
272 if (get_Kr_Kb (in_info->colorimetry.matrix, &Kr, &Kb))
273 color_matrix_YCbCr_to_RGB (&dst, Kr, Kb);
275 /* 3. inverse transfer function. R'G'B' to linear RGB */
277 /* 4. from RGB to XYZ using the primaries */
279 /* 5. from XYZ to RGB using the primaries */
281 /* 6. transfer function. linear RGB to R'G'B' */
283 /* 7. bring components to YCbCr space */
284 if (get_Kr_Kb (out_info->colorimetry.matrix, &Kr, &Kb))
285 color_matrix_RGB_to_YCbCr (&dst, Kr, Kb);
287 /* 8, bring color components to nominal range */
288 gst_video_color_range_offsets (out_info->colorimetry.range, duinfo, offset,
290 color_matrix_scale_components (&dst, (float) scale[0], (float) scale[1],
293 color_matrix_offset_components (&dst, offset[0], offset[1], offset[2]);
295 /* because we're doing fixed point matrix coefficients */
296 color_matrix_scale_components (&dst, SCALE_F, SCALE_F, SCALE_F);
298 for (i = 0; i < 4; i++)
299 for (j = 0; j < 4; j++)
300 convert->cmatrix[i][j] = rint (dst.m[i][j]);
302 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[0][0],
303 convert->cmatrix[0][1], convert->cmatrix[0][2], convert->cmatrix[0][3]);
304 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[1][0],
305 convert->cmatrix[1][1], convert->cmatrix[1][2], convert->cmatrix[1][3]);
306 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[2][0],
307 convert->cmatrix[2][1], convert->cmatrix[2][2], convert->cmatrix[2][3]);
308 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[3][0],
309 convert->cmatrix[3][1], convert->cmatrix[3][2], convert->cmatrix[3][3]);
311 convert->matrix = videoconvert_convert_matrix;
312 convert->matrix16 = videoconvert_convert_matrix16;
319 GST_ERROR ("no unpack_func for format %s",
320 gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (in_info)));
325 GST_ERROR ("no pack_func for format %s",
326 gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (out_info)));
332 videoconvert_dither_verterr (VideoConvert * convert, guint16 * pixels, int j)
335 guint16 *tmpline = convert->tmpline16;
336 guint16 *errline = convert->errline;
337 unsigned int mask = 0xff;
339 for (i = 0; i < 4 * convert->width; i++) {
340 int x = tmpline[i] + errline[i];
344 errline[i] = x & mask;
349 videoconvert_dither_halftone (VideoConvert * convert, guint16 * pixels, int j)
352 guint16 *tmpline = convert->tmpline16;
353 static guint16 halftone[8][8] = {
354 {0, 128, 32, 160, 8, 136, 40, 168},
355 {192, 64, 224, 96, 200, 72, 232, 104},
356 {48, 176, 16, 144, 56, 184, 24, 152},
357 {240, 112, 208, 80, 248, 120, 216, 88},
358 {12, 240, 44, 172, 4, 132, 36, 164},
359 {204, 76, 236, 108, 196, 68, 228, 100},
360 {60, 188, 28, 156, 52, 180, 20, 148},
361 {252, 142, 220, 92, 244, 116, 212, 84}
364 for (i = 0; i < convert->width * 4; i++) {
366 x = tmpline[i] + halftone[(i >> 2) & 7][j & 7];
373 #define TO_16(x) (((x)<<8) | (x))
375 #define UNPACK_FRAME(frame,dest,line,width) \
376 frame->info.finfo->unpack_func (frame->info.finfo, \
377 (GST_VIDEO_FRAME_IS_INTERLACED (frame) ? \
378 GST_VIDEO_PACK_FLAG_INTERLACED : \
379 GST_VIDEO_PACK_FLAG_NONE), \
380 dest, frame->data, frame->info.stride, 0, \
382 #define PACK_FRAME(frame,dest,line,width) \
383 frame->info.finfo->pack_func (frame->info.finfo, \
384 (GST_VIDEO_FRAME_IS_INTERLACED (frame) ? \
385 GST_VIDEO_PACK_FLAG_INTERLACED : \
386 GST_VIDEO_PACK_FLAG_NONE), \
387 dest, 0, frame->data, frame->info.stride, \
388 frame->info.chroma_site, line, width);
391 videoconvert_convert_generic (VideoConvert * convert, GstVideoFrame * dest,
392 const GstVideoFrame * src)
395 gint width, height, lines;
396 guint in_bits, out_bits;
402 height = convert->height;
403 width = convert->width;
405 in_bits = convert->in_bits;
406 out_bits = convert->out_bits;
408 lines = convert->lines;
410 for (j = 0; j < height; j += lines) {
411 tmpline8 = convert->tmpline8;
412 tmpline16 = convert->tmpline16;
414 for (k = 0; k < lines; k++) {
416 UNPACK_FRAME (src, tmpline16, j + k, width);
418 UNPACK_FRAME (src, tmpline8, j + k, width);
421 for (i = 0; i < width * 4; i++)
422 tmpline16[i] = TO_16 (tmpline8[i]);
425 if (out_bits == 16 || in_bits == 16) {
426 if (convert->matrix16)
427 convert->matrix16 (convert, tmpline16);
428 if (convert->dither16)
429 convert->dither16 (convert, tmpline16, j);
432 convert->matrix (convert, tmpline8);
434 tmpline8 += width * 4;
435 tmpline16 += width * 8;
437 tmpline8 = convert->tmpline8;
438 tmpline16 = convert->tmpline16;
440 if (out_bits == 16) {
441 PACK_FRAME (dest, tmpline16, j, width);
444 for (i = 0; i < width * 4 * lines; i++)
445 tmpline8[i] = tmpline16[i] >> 8;
447 PACK_FRAME (dest, tmpline8, j, width);
451 gst_video_format_get_palette (GST_VIDEO_FRAME_FORMAT (dest),
453 memcpy (GST_VIDEO_FRAME_PLANE_DATA (dest, 1), pal, palsize);
457 #define FRAME_GET_PLANE_STRIDE(frame, plane) \
458 GST_VIDEO_FRAME_PLANE_STRIDE (frame, plane)
459 #define FRAME_GET_PLANE_LINE(frame, plane, line) \
460 (gpointer)(((guint8*)(GST_VIDEO_FRAME_PLANE_DATA (frame, plane))) + \
461 FRAME_GET_PLANE_STRIDE (frame, plane) * (line))
463 #define FRAME_GET_COMP_STRIDE(frame, comp) \
464 GST_VIDEO_FRAME_COMP_STRIDE (frame, comp)
465 #define FRAME_GET_COMP_LINE(frame, comp, line) \
466 (gpointer)(((guint8*)(GST_VIDEO_FRAME_COMP_DATA (frame, comp))) + \
467 FRAME_GET_COMP_STRIDE (frame, comp) * (line))
469 #define FRAME_GET_STRIDE(frame) FRAME_GET_PLANE_STRIDE (frame, 0)
470 #define FRAME_GET_LINE(frame,line) FRAME_GET_PLANE_LINE (frame, 0, line)
472 #define FRAME_GET_Y_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_Y, line)
473 #define FRAME_GET_U_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_U, line)
474 #define FRAME_GET_V_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_V, line)
475 #define FRAME_GET_A_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_A, line)
477 #define FRAME_GET_Y_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_Y)
478 #define FRAME_GET_U_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_U)
479 #define FRAME_GET_V_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_V)
480 #define FRAME_GET_A_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_A)
484 #define GET_LINE_OFFSETS(interlaced,line,l1,l2) \
486 l1 = (line & 2 ? line - 1 : line); \
495 convert_I420_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
496 const GstVideoFrame * src)
499 gint width = convert->width;
500 gint height = convert->height;
501 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
504 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
505 GET_LINE_OFFSETS (interlaced, i, l1, l2);
507 video_convert_orc_convert_I420_YUY2 (FRAME_GET_LINE (dest, l1),
508 FRAME_GET_LINE (dest, l2),
509 FRAME_GET_Y_LINE (src, l1),
510 FRAME_GET_Y_LINE (src, l2),
511 FRAME_GET_U_LINE (src, i >> 1),
512 FRAME_GET_V_LINE (src, i >> 1), (width + 1) / 2);
515 /* now handle last line */
517 UNPACK_FRAME (src, convert->tmpline8, height - 1, width);
518 PACK_FRAME (dest, convert->tmpline8, height - 1, width);
523 convert_I420_UYVY (VideoConvert * convert, GstVideoFrame * dest,
524 const GstVideoFrame * src)
527 gint width = convert->width;
528 gint height = convert->height;
529 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
532 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
533 GET_LINE_OFFSETS (interlaced, i, l1, l2);
535 video_convert_orc_convert_I420_UYVY (FRAME_GET_LINE (dest, l1),
536 FRAME_GET_LINE (dest, l2),
537 FRAME_GET_Y_LINE (src, l1),
538 FRAME_GET_Y_LINE (src, l2),
539 FRAME_GET_U_LINE (src, i >> 1),
540 FRAME_GET_V_LINE (src, i >> 1), (width + 1) / 2);
543 /* now handle last line */
545 UNPACK_FRAME (src, convert->tmpline8, height - 1, width);
546 PACK_FRAME (dest, convert->tmpline8, height - 1, width);
551 convert_I420_AYUV (VideoConvert * convert, GstVideoFrame * dest,
552 const GstVideoFrame * src)
555 gint width = convert->width;
556 gint height = convert->height;
557 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
560 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
561 GET_LINE_OFFSETS (interlaced, i, l1, l2);
563 video_convert_orc_convert_I420_AYUV (FRAME_GET_LINE (dest, l1),
564 FRAME_GET_LINE (dest, l2),
565 FRAME_GET_Y_LINE (src, l1),
566 FRAME_GET_Y_LINE (src, l2),
567 FRAME_GET_U_LINE (src, i >> 1), FRAME_GET_V_LINE (src, i >> 1), width);
570 /* now handle last line */
572 UNPACK_FRAME (src, convert->tmpline8, height - 1, width);
573 PACK_FRAME (dest, convert->tmpline8, height - 1, width);
578 convert_I420_Y42B (VideoConvert * convert, GstVideoFrame * dest,
579 const GstVideoFrame * src)
581 gint width = convert->width;
582 gint height = convert->height;
584 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
585 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
586 FRAME_GET_Y_STRIDE (src), width, height);
588 video_convert_orc_planar_chroma_420_422 (FRAME_GET_U_LINE (dest, 0),
589 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (dest, 1),
590 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
591 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
593 video_convert_orc_planar_chroma_420_422 (FRAME_GET_V_LINE (dest, 0),
594 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (dest, 1),
595 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
596 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
600 convert_I420_Y444 (VideoConvert * convert, GstVideoFrame * dest,
601 const GstVideoFrame * src)
603 gint width = convert->width;
604 gint height = convert->height;
606 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
607 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
608 FRAME_GET_Y_STRIDE (src), width, height);
610 video_convert_orc_planar_chroma_420_444 (FRAME_GET_U_LINE (dest, 0),
611 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (dest, 1),
612 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
613 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
615 video_convert_orc_planar_chroma_420_444 (FRAME_GET_V_LINE (dest, 0),
616 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (dest, 1),
617 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
618 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
620 /* now handle last line */
622 UNPACK_FRAME (src, convert->tmpline8, height - 1, width);
623 PACK_FRAME (dest, convert->tmpline8, height - 1, width);
628 convert_YUY2_I420 (VideoConvert * convert, GstVideoFrame * dest,
629 const GstVideoFrame * src)
632 gint width = convert->width;
633 gint height = convert->height;
634 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
641 for (i = 0; i < h; i += 2) {
642 GET_LINE_OFFSETS (interlaced, i, l1, l2);
644 video_convert_orc_convert_YUY2_I420 (FRAME_GET_Y_LINE (dest, l1),
645 FRAME_GET_Y_LINE (dest, l2),
646 FRAME_GET_U_LINE (dest, i >> 1),
647 FRAME_GET_V_LINE (dest, i >> 1),
648 FRAME_GET_LINE (src, l1), FRAME_GET_LINE (src, l2), (width + 1) / 2);
651 /* now handle last line */
653 UNPACK_FRAME (src, convert->tmpline8, height - 1, width);
654 PACK_FRAME (dest, convert->tmpline8, height - 1, width);
659 convert_YUY2_AYUV (VideoConvert * convert, GstVideoFrame * dest,
660 const GstVideoFrame * src)
662 gint width = convert->width;
663 gint height = convert->height;
665 video_convert_orc_convert_YUY2_AYUV (FRAME_GET_LINE (dest, 0),
666 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
667 FRAME_GET_STRIDE (src), (width + 1) / 2,
668 height & 1 ? height - 1 : height);
670 /* now handle last line */
672 UNPACK_FRAME (src, convert->tmpline8, height - 1, width);
673 PACK_FRAME (dest, convert->tmpline8, height - 1, width);
678 convert_YUY2_Y42B (VideoConvert * convert, GstVideoFrame * dest,
679 const GstVideoFrame * src)
681 gint width = convert->width;
682 gint height = convert->height;
684 video_convert_orc_convert_YUY2_Y42B (FRAME_GET_Y_LINE (dest, 0),
685 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
686 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
687 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
688 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
692 convert_YUY2_Y444 (VideoConvert * convert, GstVideoFrame * dest,
693 const GstVideoFrame * src)
695 gint width = convert->width;
696 gint height = convert->height;
698 video_convert_orc_convert_YUY2_Y444 (FRAME_GET_COMP_LINE (dest, 0, 0),
699 FRAME_GET_COMP_STRIDE (dest, 0), FRAME_GET_COMP_LINE (dest, 1, 0),
700 FRAME_GET_COMP_STRIDE (dest, 1), FRAME_GET_COMP_LINE (dest, 2, 0),
701 FRAME_GET_COMP_STRIDE (dest, 2), FRAME_GET_LINE (src, 0),
702 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
707 convert_UYVY_I420 (VideoConvert * convert, GstVideoFrame * dest,
708 const GstVideoFrame * src)
711 gint width = convert->width;
712 gint height = convert->height;
713 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
716 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
717 GET_LINE_OFFSETS (interlaced, i, l1, l2);
719 video_convert_orc_convert_UYVY_I420 (FRAME_GET_COMP_LINE (dest, 0, l1),
720 FRAME_GET_COMP_LINE (dest, 0, l2),
721 FRAME_GET_COMP_LINE (dest, 1, i >> 1),
722 FRAME_GET_COMP_LINE (dest, 2, i >> 1),
723 FRAME_GET_LINE (src, l1), FRAME_GET_LINE (src, l2), (width + 1) / 2);
726 /* now handle last line */
728 UNPACK_FRAME (src, convert->tmpline8, height - 1, width);
729 PACK_FRAME (dest, convert->tmpline8, height - 1, width);
734 convert_UYVY_AYUV (VideoConvert * convert, GstVideoFrame * dest,
735 const GstVideoFrame * src)
737 gint width = convert->width;
738 gint height = convert->height;
740 video_convert_orc_convert_UYVY_AYUV (FRAME_GET_LINE (dest, 0),
741 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
742 FRAME_GET_STRIDE (src), (width + 1) / 2,
743 height & 1 ? height - 1 : height);
745 /* now handle last line */
747 UNPACK_FRAME (src, convert->tmpline8, height - 1, width);
748 PACK_FRAME (dest, convert->tmpline8, height - 1, width);
753 convert_UYVY_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
754 const GstVideoFrame * src)
756 gint width = convert->width;
757 gint height = convert->height;
759 video_convert_orc_convert_UYVY_YUY2 (FRAME_GET_LINE (dest, 0),
760 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
761 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
765 convert_UYVY_Y42B (VideoConvert * convert, GstVideoFrame * dest,
766 const GstVideoFrame * src)
768 gint width = convert->width;
769 gint height = convert->height;
771 video_convert_orc_convert_UYVY_Y42B (FRAME_GET_Y_LINE (dest, 0),
772 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
773 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
774 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
775 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
779 convert_UYVY_Y444 (VideoConvert * convert, GstVideoFrame * dest,
780 const GstVideoFrame * src)
782 gint width = convert->width;
783 gint height = convert->height;
785 video_convert_orc_convert_UYVY_Y444 (FRAME_GET_Y_LINE (dest, 0),
786 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
787 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
788 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
789 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
793 convert_AYUV_I420 (VideoConvert * convert, GstVideoFrame * dest,
794 const GstVideoFrame * src)
796 gint width = convert->width;
797 gint height = convert->height;
799 video_convert_orc_convert_AYUV_I420 (FRAME_GET_Y_LINE (dest, 0),
800 2 * FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (dest, 1),
801 2 * FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
802 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
803 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
804 2 * FRAME_GET_STRIDE (src), FRAME_GET_LINE (src, 1),
805 2 * FRAME_GET_STRIDE (src), width / 2, height / 2);
809 convert_AYUV_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
810 const GstVideoFrame * src)
812 gint width = convert->width;
813 gint height = convert->height;
815 video_convert_orc_convert_AYUV_YUY2 (FRAME_GET_LINE (dest, 0),
816 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
817 FRAME_GET_STRIDE (src), width / 2, height);
821 convert_AYUV_UYVY (VideoConvert * convert, GstVideoFrame * dest,
822 const GstVideoFrame * src)
824 gint width = convert->width;
825 gint height = convert->height;
827 video_convert_orc_convert_AYUV_UYVY (FRAME_GET_LINE (dest, 0),
828 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
829 FRAME_GET_STRIDE (src), width / 2, height);
833 convert_AYUV_Y42B (VideoConvert * convert, GstVideoFrame * dest,
834 const GstVideoFrame * src)
836 gint width = convert->width;
837 gint height = convert->height;
839 video_convert_orc_convert_AYUV_Y42B (FRAME_GET_Y_LINE (dest, 0),
840 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
841 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
842 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
843 FRAME_GET_STRIDE (src), (width + 1) / 2,
844 height & 1 ? height - 1 : height);
846 /* now handle last line */
848 UNPACK_FRAME (src, convert->tmpline8, height - 1, width);
849 PACK_FRAME (dest, convert->tmpline8, height - 1, width);
854 convert_AYUV_Y444 (VideoConvert * convert, GstVideoFrame * dest,
855 const GstVideoFrame * src)
857 gint width = convert->width;
858 gint height = convert->height;
860 video_convert_orc_convert_AYUV_Y444 (FRAME_GET_Y_LINE (dest, 0),
861 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
862 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
863 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
864 FRAME_GET_STRIDE (src), width, height);
868 convert_Y42B_I420 (VideoConvert * convert, GstVideoFrame * dest,
869 const GstVideoFrame * src)
871 gint width = convert->width;
872 gint height = convert->height;
874 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
875 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
876 FRAME_GET_Y_STRIDE (src), width, height);
878 video_convert_orc_planar_chroma_422_420 (FRAME_GET_U_LINE (dest, 0),
879 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
880 2 * FRAME_GET_U_STRIDE (src), FRAME_GET_U_LINE (src, 1),
881 2 * FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
883 video_convert_orc_planar_chroma_422_420 (FRAME_GET_V_LINE (dest, 0),
884 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
885 2 * FRAME_GET_V_STRIDE (src), FRAME_GET_V_LINE (src, 1),
886 2 * FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
888 /* now handle last line */
890 UNPACK_FRAME (src, convert->tmpline8, height - 1, width);
891 PACK_FRAME (dest, convert->tmpline8, height - 1, width);
896 convert_Y42B_Y444 (VideoConvert * convert, GstVideoFrame * dest,
897 const GstVideoFrame * src)
899 gint width = convert->width;
900 gint height = convert->height;
902 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
903 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
904 FRAME_GET_Y_STRIDE (src), width, height);
906 video_convert_orc_planar_chroma_422_444 (FRAME_GET_U_LINE (dest, 0),
907 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
908 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height);
910 video_convert_orc_planar_chroma_422_444 (FRAME_GET_V_LINE (dest, 0),
911 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
912 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
916 convert_Y42B_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
917 const GstVideoFrame * src)
919 gint width = convert->width;
920 gint height = convert->height;
922 video_convert_orc_convert_Y42B_YUY2 (FRAME_GET_LINE (dest, 0),
923 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
924 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
925 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
926 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
930 convert_Y42B_UYVY (VideoConvert * convert, GstVideoFrame * dest,
931 const GstVideoFrame * src)
933 gint width = convert->width;
934 gint height = convert->height;
936 video_convert_orc_convert_Y42B_UYVY (FRAME_GET_LINE (dest, 0),
937 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
938 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
939 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
940 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
944 convert_Y42B_AYUV (VideoConvert * convert, GstVideoFrame * dest,
945 const GstVideoFrame * src)
947 gint width = convert->width;
948 gint height = convert->height;
950 video_convert_orc_convert_Y42B_AYUV (FRAME_GET_LINE (dest, 0),
951 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
952 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
953 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
954 FRAME_GET_V_STRIDE (src), (width) / 2, height);
958 convert_Y444_I420 (VideoConvert * convert, GstVideoFrame * dest,
959 const GstVideoFrame * src)
961 gint width = convert->width;
962 gint height = convert->height;
964 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
965 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
966 FRAME_GET_Y_STRIDE (src), width, height);
968 video_convert_orc_planar_chroma_444_420 (FRAME_GET_U_LINE (dest, 0),
969 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
970 2 * FRAME_GET_U_STRIDE (src), FRAME_GET_U_LINE (src, 1),
971 2 * FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
973 video_convert_orc_planar_chroma_444_420 (FRAME_GET_V_LINE (dest, 0),
974 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
975 2 * FRAME_GET_V_STRIDE (src), FRAME_GET_V_LINE (src, 1),
976 2 * FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
978 /* now handle last line */
980 UNPACK_FRAME (src, convert->tmpline8, height - 1, width);
981 PACK_FRAME (dest, convert->tmpline8, height - 1, width);
986 convert_Y444_Y42B (VideoConvert * convert, GstVideoFrame * dest,
987 const GstVideoFrame * src)
989 gint width = convert->width;
990 gint height = convert->height;
992 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
993 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
994 FRAME_GET_Y_STRIDE (src), width, height);
996 video_convert_orc_planar_chroma_444_422 (FRAME_GET_U_LINE (dest, 0),
997 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
998 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height);
1000 video_convert_orc_planar_chroma_444_422 (FRAME_GET_V_LINE (dest, 0),
1001 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
1002 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
1006 convert_Y444_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
1007 const GstVideoFrame * src)
1009 gint width = convert->width;
1010 gint height = convert->height;
1012 video_convert_orc_convert_Y444_YUY2 (FRAME_GET_LINE (dest, 0),
1013 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1014 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1015 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1016 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
1020 convert_Y444_UYVY (VideoConvert * convert, GstVideoFrame * dest,
1021 const GstVideoFrame * src)
1023 gint width = convert->width;
1024 gint height = convert->height;
1026 video_convert_orc_convert_Y444_UYVY (FRAME_GET_LINE (dest, 0),
1027 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1028 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1029 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1030 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
1034 convert_Y444_AYUV (VideoConvert * convert, GstVideoFrame * dest,
1035 const GstVideoFrame * src)
1037 gint width = convert->width;
1038 gint height = convert->height;
1040 video_convert_orc_convert_Y444_AYUV (FRAME_GET_LINE (dest, 0),
1041 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1042 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1043 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1044 FRAME_GET_V_STRIDE (src), width, height);
1047 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1049 convert_AYUV_ARGB (VideoConvert * convert, GstVideoFrame * dest,
1050 const GstVideoFrame * src)
1052 gint width = convert->width;
1053 gint height = convert->height;
1055 video_convert_orc_convert_AYUV_ARGB (FRAME_GET_LINE (dest, 0),
1056 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1057 FRAME_GET_STRIDE (src), width, height);
1061 convert_AYUV_BGRA (VideoConvert * convert, GstVideoFrame * dest,
1062 const GstVideoFrame * src)
1064 gint width = convert->width;
1065 gint height = convert->height;
1067 video_convert_orc_convert_AYUV_BGRA (FRAME_GET_LINE (dest, 0),
1068 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1069 FRAME_GET_STRIDE (src), width, height);
1073 convert_AYUV_ABGR (VideoConvert * convert, GstVideoFrame * dest,
1074 const GstVideoFrame * src)
1076 gint width = convert->width;
1077 gint height = convert->height;
1079 video_convert_orc_convert_AYUV_ABGR (FRAME_GET_LINE (dest, 0),
1080 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1081 FRAME_GET_STRIDE (src), width, height);
1085 convert_AYUV_RGBA (VideoConvert * convert, GstVideoFrame * dest,
1086 const GstVideoFrame * src)
1088 gint width = convert->width;
1089 gint height = convert->height;
1091 video_convert_orc_convert_AYUV_RGBA (FRAME_GET_LINE (dest, 0),
1092 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1093 FRAME_GET_STRIDE (src), width, height);
1097 convert_I420_BGRA (VideoConvert * convert, GstVideoFrame * dest,
1098 const GstVideoFrame * src)
1102 gint width = convert->width;
1103 gint height = convert->height;
1106 for (i = 0; i < height; i++) {
1108 video_convert_orc_convert_I420_BGRA_avg (FRAME_GET_LINE (dest, i),
1109 FRAME_GET_Y_LINE (src, i),
1110 FRAME_GET_U_LINE (src, i >> 1),
1111 FRAME_GET_U_LINE (src, (i >> 1) + 1),
1112 FRAME_GET_V_LINE (src, i >> 1),
1113 FRAME_GET_V_LINE (src, (i >> 1) + 1), width);
1115 video_convert_orc_convert_I420_BGRA (FRAME_GET_LINE (dest, i),
1116 FRAME_GET_Y_LINE (src, i),
1117 FRAME_GET_U_LINE (src, i >> 1),
1118 FRAME_GET_V_LINE (src, i >> 1), width);
1122 for (i = 0; i < height; i++) {
1123 video_convert_orc_convert_I420_BGRA (FRAME_GET_LINE (dest, i),
1124 FRAME_GET_Y_LINE (src, i),
1125 FRAME_GET_U_LINE (src, i >> 1),
1126 FRAME_GET_V_LINE (src, i >> 1), width);
1138 GstVideoFormat in_format;
1139 GstVideoColorMatrix in_matrix;
1140 GstVideoFormat out_format;
1141 GstVideoColorMatrix out_matrix;
1142 gboolean keeps_color_matrix;
1143 gboolean keeps_interlaced;
1144 void (*convert) (VideoConvert * convert, GstVideoFrame * dest,
1145 const GstVideoFrame * src);
1147 static const VideoTransform transforms[] = {
1148 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1149 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_I420_YUY2},
1150 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1151 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_I420_UYVY},
1152 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1153 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_I420_AYUV},
1154 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1155 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, convert_I420_Y42B},
1156 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1157 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, convert_I420_Y444},
1159 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1160 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_YUY2_I420},
1161 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1162 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_UYVY_YUY2}, /* alias */
1163 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1164 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_YUY2_AYUV},
1165 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1166 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_YUY2_Y42B},
1167 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1168 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_YUY2_Y444},
1170 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1171 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_UYVY_I420},
1172 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1173 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_UYVY_YUY2},
1174 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1175 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_UYVY_AYUV},
1176 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1177 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_UYVY_Y42B},
1178 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1179 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_UYVY_Y444},
1181 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1182 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, convert_AYUV_I420},
1183 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1184 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_AYUV_YUY2},
1185 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1186 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_AYUV_UYVY},
1187 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1188 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_AYUV_Y42B},
1189 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1190 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_AYUV_Y444},
1192 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1193 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, convert_Y42B_I420},
1194 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1195 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y42B_YUY2},
1196 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1197 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y42B_UYVY},
1198 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1199 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y42B_AYUV},
1200 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1201 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y42B_Y444},
1203 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1204 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, convert_Y444_I420},
1205 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1206 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y444_YUY2},
1207 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1208 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y444_UYVY},
1209 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1210 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y444_AYUV},
1211 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1212 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, convert_Y444_Y42B},
1214 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1215 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_ARGB,
1216 GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_ARGB},
1217 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_BGRA,
1218 GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_BGRA},
1219 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_xRGB, GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_ARGB}, /* alias */
1220 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_BGRx, GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_BGRA}, /* alias */
1221 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_ABGR,
1222 GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_ABGR},
1223 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_RGBA,
1224 GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_RGBA},
1225 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_xBGR, GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_ABGR}, /* alias */
1226 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_RGBx, GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, convert_AYUV_RGBA}, /* alias */
1228 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_BGRA,
1229 GST_VIDEO_COLOR_MATRIX_RGB, FALSE, FALSE, convert_I420_BGRA},
1234 videoconvert_convert_lookup_fastpath (VideoConvert * convert)
1237 GstVideoFormat in_format, out_format;
1238 GstVideoColorMatrix in_matrix, out_matrix;
1239 gboolean interlaced;
1241 in_format = GST_VIDEO_INFO_FORMAT (&convert->in_info);
1242 out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info);
1244 in_matrix = convert->in_info.colorimetry.matrix;
1245 out_matrix = convert->out_info.colorimetry.matrix;
1247 interlaced = GST_VIDEO_INFO_IS_INTERLACED (&convert->in_info);
1248 interlaced |= GST_VIDEO_INFO_IS_INTERLACED (&convert->out_info);
1250 for (i = 0; i < sizeof (transforms) / sizeof (transforms[0]); i++) {
1251 if (transforms[i].in_format == in_format &&
1252 transforms[i].out_format == out_format &&
1253 (transforms[i].keeps_color_matrix ||
1254 (transforms[i].in_matrix == in_matrix &&
1255 transforms[i].out_matrix == out_matrix)) &&
1256 (transforms[i].keeps_interlaced || !interlaced)) {
1257 GST_DEBUG ("using fastpath");
1258 convert->convert = transforms[i].convert;