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_matrix8 (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 gboolean videoconvert_convert_compute_resample (VideoConvert * convert);
43 static void videoconvert_dither_verterr (VideoConvert * convert,
44 guint16 * pixels, int j);
45 static void videoconvert_dither_halftone (VideoConvert * convert,
46 guint16 * pixels, int j);
50 videoconvert_convert_new (GstVideoInfo * in_info, GstVideoInfo * out_info)
52 VideoConvert *convert;
55 convert = g_malloc0 (sizeof (VideoConvert));
57 convert->in_info = *in_info;
58 convert->out_info = *out_info;
59 convert->dither16 = NULL;
61 convert->width = GST_VIDEO_INFO_WIDTH (in_info);
62 convert->height = GST_VIDEO_INFO_HEIGHT (in_info);
64 if (!videoconvert_convert_lookup_fastpath (convert)) {
65 convert->convert = videoconvert_convert_generic;
66 if (!videoconvert_convert_compute_matrix (convert))
69 if (!videoconvert_convert_compute_resample (convert))
73 width = convert->width;
75 convert->lines = out_info->finfo->pack_lines;
76 convert->errline = g_malloc0 (sizeof (guint16) * width * 4);
83 videoconvert_convert_free (convert);
89 videoconvert_convert_free (VideoConvert * convert)
93 if (convert->upsample)
94 gst_video_chroma_resample_free (convert->upsample);
95 if (convert->downsample)
96 gst_video_chroma_resample_free (convert->downsample);
98 for (i = 0; i < convert->n_tmplines; i++)
99 g_free (convert->tmplines[i]);
100 g_free (convert->tmplines);
101 g_free (convert->errline);
107 videoconvert_convert_set_dither (VideoConvert * convert, int type)
112 convert->dither16 = NULL;
115 convert->dither16 = videoconvert_dither_verterr;
118 convert->dither16 = videoconvert_dither_halftone;
124 videoconvert_convert_convert (VideoConvert * convert,
125 GstVideoFrame * dest, const GstVideoFrame * src)
127 convert->convert (convert, dest, src);
131 #define SCALE_F ((float) (1 << SCALE))
134 videoconvert_convert_matrix8 (VideoConvert * convert, gpointer pixels)
141 for (i = 0; i < convert->width; i++) {
146 y = (convert->cmatrix[0][0] * r + convert->cmatrix[0][1] * g +
147 convert->cmatrix[0][2] * b + convert->cmatrix[0][3]) >> SCALE;
148 u = (convert->cmatrix[1][0] * r + convert->cmatrix[1][1] * g +
149 convert->cmatrix[1][2] * b + convert->cmatrix[1][3]) >> SCALE;
150 v = (convert->cmatrix[2][0] * r + convert->cmatrix[2][1] * g +
151 convert->cmatrix[2][2] * b + convert->cmatrix[2][3]) >> SCALE;
153 p[i * 4 + 1] = CLAMP (y, 0, 255);
154 p[i * 4 + 2] = CLAMP (u, 0, 255);
155 p[i * 4 + 3] = CLAMP (v, 0, 255);
160 videoconvert_convert_matrix16 (VideoConvert * convert, gpointer pixels)
167 for (i = 0; i < convert->width; i++) {
172 y = (convert->cmatrix[0][0] * r + convert->cmatrix[0][1] * g +
173 convert->cmatrix[0][2] * b + convert->cmatrix[0][3]) >> SCALE;
174 u = (convert->cmatrix[1][0] * r + convert->cmatrix[1][1] * g +
175 convert->cmatrix[1][2] * b + convert->cmatrix[1][3]) >> SCALE;
176 v = (convert->cmatrix[2][0] * r + convert->cmatrix[2][1] * g +
177 convert->cmatrix[2][2] * b + convert->cmatrix[2][3]) >> SCALE;
179 p[i * 4 + 1] = CLAMP (y, 0, 65535);
180 p[i * 4 + 2] = CLAMP (u, 0, 65535);
181 p[i * 4 + 3] = CLAMP (v, 0, 65535);
186 videoconvert_convert_compute_matrix (VideoConvert * convert)
188 GstVideoInfo *in_info, *out_info;
191 const GstVideoFormatInfo *sfinfo, *dfinfo;
192 const GstVideoFormatInfo *suinfo, *duinfo;
193 gint offset[4], scale[4];
194 gdouble Kr = 0, Kb = 0;
196 in_info = &convert->in_info;
197 out_info = &convert->out_info;
199 sfinfo = in_info->finfo;
200 dfinfo = out_info->finfo;
202 if (sfinfo->unpack_func == NULL)
205 if (dfinfo->pack_func == NULL)
208 suinfo = gst_video_format_get_info (sfinfo->unpack_format);
209 duinfo = gst_video_format_get_info (dfinfo->unpack_format);
211 convert->in_bits = GST_VIDEO_FORMAT_INFO_DEPTH (suinfo, 0);
212 convert->out_bits = GST_VIDEO_FORMAT_INFO_DEPTH (duinfo, 0);
214 GST_DEBUG ("in bits %d, out bits %d", convert->in_bits, convert->out_bits);
216 if (in_info->colorimetry.range == out_info->colorimetry.range &&
217 in_info->colorimetry.matrix == out_info->colorimetry.matrix) {
218 GST_DEBUG ("using identity color transform");
219 convert->matrix = NULL;
223 /* calculate intermediate format for the matrix. When unpacking, we expand
224 * input to 16 when one of the inputs is 16 bits */
225 if (convert->in_bits == 16 || convert->out_bits == 16) {
226 convert->matrix = videoconvert_convert_matrix16;
228 if (GST_VIDEO_FORMAT_INFO_IS_RGB (suinfo))
229 suinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_ARGB64);
231 suinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_AYUV64);
233 if (GST_VIDEO_FORMAT_INFO_IS_RGB (duinfo))
234 duinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_ARGB64);
236 duinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_AYUV64);
238 convert->matrix = videoconvert_convert_matrix8;
241 color_matrix_set_identity (&dst);
243 /* 1, bring color components to [0..1.0] range */
244 gst_video_color_range_offsets (in_info->colorimetry.range, suinfo, offset,
247 color_matrix_offset_components (&dst, -offset[0], -offset[1], -offset[2]);
249 color_matrix_scale_components (&dst, 1 / ((float) scale[0]),
250 1 / ((float) scale[1]), 1 / ((float) scale[2]));
252 /* 2. bring components to R'G'B' space */
253 if (gst_video_color_matrix_get_Kr_Kb (in_info->colorimetry.matrix, &Kr, &Kb))
254 color_matrix_YCbCr_to_RGB (&dst, Kr, Kb);
256 /* 3. inverse transfer function. R'G'B' to linear RGB */
258 /* 4. from RGB to XYZ using the primaries */
260 /* 5. from XYZ to RGB using the primaries */
262 /* 6. transfer function. linear RGB to R'G'B' */
264 /* 7. bring components to YCbCr space */
265 if (gst_video_color_matrix_get_Kr_Kb (out_info->colorimetry.matrix, &Kr, &Kb))
266 color_matrix_RGB_to_YCbCr (&dst, Kr, Kb);
268 /* 8, bring color components to nominal range */
269 gst_video_color_range_offsets (out_info->colorimetry.range, duinfo, offset,
272 color_matrix_scale_components (&dst, (float) scale[0], (float) scale[1],
275 color_matrix_offset_components (&dst, offset[0], offset[1], offset[2]);
277 /* because we're doing fixed point matrix coefficients */
278 color_matrix_scale_components (&dst, SCALE_F, SCALE_F, SCALE_F);
280 for (i = 0; i < 4; i++)
281 for (j = 0; j < 4; j++)
282 convert->cmatrix[i][j] = rint (dst.m[i][j]);
284 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[0][0],
285 convert->cmatrix[0][1], convert->cmatrix[0][2], convert->cmatrix[0][3]);
286 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[1][0],
287 convert->cmatrix[1][1], convert->cmatrix[1][2], convert->cmatrix[1][3]);
288 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[2][0],
289 convert->cmatrix[2][1], convert->cmatrix[2][2], convert->cmatrix[2][3]);
290 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[3][0],
291 convert->cmatrix[3][1], convert->cmatrix[3][2], convert->cmatrix[3][3]);
298 GST_ERROR ("no unpack_func for format %s",
299 gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (in_info)));
304 GST_ERROR ("no pack_func for format %s",
305 gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (out_info)));
311 videoconvert_dither_verterr (VideoConvert * convert, guint16 * pixels, int j)
314 guint16 *errline = convert->errline;
315 unsigned int mask = 0xff;
317 for (i = 0; i < 4 * convert->width; i++) {
318 int x = pixels[i] + errline[i];
322 errline[i] = x & mask;
327 videoconvert_dither_halftone (VideoConvert * convert, guint16 * pixels, int j)
330 static guint16 halftone[8][8] = {
331 {0, 128, 32, 160, 8, 136, 40, 168},
332 {192, 64, 224, 96, 200, 72, 232, 104},
333 {48, 176, 16, 144, 56, 184, 24, 152},
334 {240, 112, 208, 80, 248, 120, 216, 88},
335 {12, 240, 44, 172, 4, 132, 36, 164},
336 {204, 76, 236, 108, 196, 68, 228, 100},
337 {60, 188, 28, 156, 52, 180, 20, 148},
338 {252, 142, 220, 92, 244, 116, 212, 84}
341 for (i = 0; i < convert->width * 4; i++) {
343 x = pixels[i] + halftone[(i >> 2) & 7][j & 7];
351 alloc_tmplines (VideoConvert * convert, guint lines, gint width)
355 convert->n_tmplines = lines;
356 convert->tmplines = g_malloc (lines * sizeof (gpointer));
357 for (i = 0; i < lines; i++)
358 convert->tmplines[i] = g_malloc (sizeof (guint16) * (width + 8) * 4);
362 videoconvert_convert_compute_resample (VideoConvert * convert)
364 GstVideoInfo *in_info, *out_info;
365 const GstVideoFormatInfo *sfinfo, *dfinfo;
368 in_info = &convert->in_info;
369 out_info = &convert->out_info;
371 sfinfo = in_info->finfo;
372 dfinfo = out_info->finfo;
374 width = convert->width;
376 if (sfinfo->w_sub[2] != dfinfo->w_sub[2] ||
377 sfinfo->h_sub[2] != dfinfo->h_sub[2] ||
378 in_info->chroma_site != out_info->chroma_site) {
379 convert->upsample = gst_video_chroma_resample_new (0,
380 in_info->chroma_site, 0, sfinfo->unpack_format, sfinfo->w_sub[2],
384 convert->downsample = gst_video_chroma_resample_new (0,
385 out_info->chroma_site, 0, dfinfo->unpack_format, -dfinfo->w_sub[2],
389 convert->upsample = NULL;
390 convert->downsample = NULL;
393 if (convert->upsample) {
394 gst_video_chroma_resample_get_info (convert->upsample,
395 &convert->up_n_lines, &convert->up_offset);
397 convert->up_n_lines = 1;
398 convert->up_offset = 0;
400 if (convert->downsample) {
401 gst_video_chroma_resample_get_info (convert->downsample,
402 &convert->down_n_lines, &convert->down_offset);
404 convert->down_n_lines = 1;
405 convert->down_offset = 0;
407 GST_DEBUG ("upsample: %p, site: %d, offset %d, n_lines %d", convert->upsample,
408 in_info->chroma_site, convert->up_offset, convert->up_n_lines);
409 GST_DEBUG ("downsample: %p, site: %d, offset %d, n_lines %d",
410 convert->downsample, out_info->chroma_site, convert->down_offset,
411 convert->down_n_lines);
413 alloc_tmplines (convert, convert->down_n_lines + convert->up_n_lines, width);
418 #define TO_16(x) (((x)<<8) | (x))
421 convert_to16 (gpointer line, gint width)
423 guint8 *line8 = line;
424 guint16 *line16 = line;
427 for (i = (width - 1) * 4; i >= 0; i--)
428 line16[i] = TO_16 (line8[i]);
432 convert_to8 (gpointer line, gint width)
434 guint8 *line8 = line;
435 guint16 *line16 = line;
438 for (i = 0; i < width * 4; i++)
439 line8[i] = line16[i] >> 8;
442 #define UNPACK_FRAME(frame,dest,line,width) \
443 frame->info.finfo->unpack_func (frame->info.finfo, \
444 (GST_VIDEO_FRAME_IS_INTERLACED (frame) ? \
445 GST_VIDEO_PACK_FLAG_INTERLACED : \
446 GST_VIDEO_PACK_FLAG_NONE), \
447 dest, frame->data, frame->info.stride, 0, \
449 #define PACK_FRAME(frame,dest,line,width) \
450 frame->info.finfo->pack_func (frame->info.finfo, \
451 (GST_VIDEO_FRAME_IS_INTERLACED (frame) ? \
452 GST_VIDEO_PACK_FLAG_INTERLACED : \
453 GST_VIDEO_PACK_FLAG_NONE), \
454 dest, 0, frame->data, frame->info.stride, \
455 frame->info.chroma_site, line, width);
458 videoconvert_convert_generic (VideoConvert * convert, GstVideoFrame * dest,
459 const GstVideoFrame * src)
462 gint width, height, lines, max_lines;
463 guint in_bits, out_bits;
466 guint up_n_lines, down_n_lines;
467 gint up_offset, down_offset;
468 gint in_lines, out_lines;
469 gint up_line, down_line;
470 gint start_offset, stop_offset;
471 gpointer in_tmplines[8];
472 gpointer out_tmplines[8];
474 height = convert->height;
475 width = convert->width;
477 in_bits = convert->in_bits;
478 out_bits = convert->out_bits;
480 lines = convert->lines;
481 up_n_lines = convert->up_n_lines;
482 up_offset = convert->up_offset;
483 down_n_lines = convert->down_n_lines;
484 down_offset = convert->down_offset;
485 max_lines = convert->n_tmplines;
490 GST_DEBUG ("up_offset %d, up_n_lines %u", up_offset, up_n_lines);
492 start_offset = MIN (up_offset, down_offset);
493 stop_offset = height + start_offset + MAX (up_n_lines, down_n_lines);
495 for (; start_offset < stop_offset; start_offset++) {
498 idx = CLAMP (start_offset, 0, height);
499 in_tmplines[in_lines] = convert->tmplines[idx % max_lines];
500 out_tmplines[out_lines] = in_tmplines[in_lines];
501 GST_DEBUG ("start_offset %d/%d, %d, idx %u, in %d, out %d", start_offset,
502 stop_offset, up_offset, idx, in_lines, out_lines);
504 up_line = up_offset + in_lines;
506 /* extract the next line */
507 if (up_line >= 0 && up_line < height) {
508 GST_DEBUG ("unpack line %d into %d", up_line, in_lines);
509 UNPACK_FRAME (src, in_tmplines[in_lines], up_line, width);
512 if (start_offset >= up_offset)
515 if (start_offset >= down_offset)
518 if (in_lines < up_n_lines)
523 /* we have enough lines to upsample */
524 if (convert->upsample) {
525 GST_DEBUG ("doing upsample");
526 gst_video_chroma_resample (convert->upsample, in_tmplines, width);
529 /* convert upsampled lines */
530 for (k = 0; k < up_n_lines; k++) {
531 down_line = up_offset + k;
533 /* only takes lines with valid output */
534 if (down_line < 0 || down_line >= height)
537 GST_DEBUG ("handle line %d, %d/%d, down_line %d", k, out_lines,
538 down_n_lines, down_line);
540 if (out_bits == 16 || in_bits == 16) {
541 /* FIXME, we can scale in the conversion matrix */
543 convert_to16 (in_tmplines[k], width);
546 convert->matrix (convert, in_tmplines[k]);
547 if (convert->dither16)
548 convert->dither16 (convert, in_tmplines[k], down_line);
551 convert_to8 (in_tmplines[k], width);
554 convert->matrix (convert, in_tmplines[k]);
559 while (out_lines >= down_n_lines) {
560 if (convert->downsample) {
561 GST_DEBUG ("doing downsample %u", start);
562 gst_video_chroma_resample (convert->downsample,
563 &out_tmplines[start], width);
566 for (j = 0; j < down_n_lines; j += lines) {
567 idx = down_offset + j;
570 GST_DEBUG ("packing line %d %d %d", j + start, down_offset, idx);
571 /* FIXME, not correct if lines > 1 */
572 PACK_FRAME (dest, out_tmplines[j + start], idx, width);
575 down_offset += down_n_lines;
576 start += down_n_lines;
577 out_lines -= down_n_lines;
579 /* we didn't process these lines, move them up for the next round */
580 for (j = 0; j < out_lines; j++) {
581 GST_DEBUG ("move line %d->%d", j + start, j);
582 out_tmplines[j] = out_tmplines[j + start];
585 up_offset += up_n_lines;
588 gst_video_format_get_palette (GST_VIDEO_FRAME_FORMAT (dest),
590 memcpy (GST_VIDEO_FRAME_PLANE_DATA (dest, 1), pal, palsize);
594 #define FRAME_GET_PLANE_STRIDE(frame, plane) \
595 GST_VIDEO_FRAME_PLANE_STRIDE (frame, plane)
596 #define FRAME_GET_PLANE_LINE(frame, plane, line) \
597 (gpointer)(((guint8*)(GST_VIDEO_FRAME_PLANE_DATA (frame, plane))) + \
598 FRAME_GET_PLANE_STRIDE (frame, plane) * (line))
600 #define FRAME_GET_COMP_STRIDE(frame, comp) \
601 GST_VIDEO_FRAME_COMP_STRIDE (frame, comp)
602 #define FRAME_GET_COMP_LINE(frame, comp, line) \
603 (gpointer)(((guint8*)(GST_VIDEO_FRAME_COMP_DATA (frame, comp))) + \
604 FRAME_GET_COMP_STRIDE (frame, comp) * (line))
606 #define FRAME_GET_STRIDE(frame) FRAME_GET_PLANE_STRIDE (frame, 0)
607 #define FRAME_GET_LINE(frame,line) FRAME_GET_PLANE_LINE (frame, 0, line)
609 #define FRAME_GET_Y_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_Y, line)
610 #define FRAME_GET_U_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_U, line)
611 #define FRAME_GET_V_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_V, line)
612 #define FRAME_GET_A_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_A, line)
614 #define FRAME_GET_Y_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_Y)
615 #define FRAME_GET_U_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_U)
616 #define FRAME_GET_V_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_V)
617 #define FRAME_GET_A_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_A)
621 #define GET_LINE_OFFSETS(interlaced,line,l1,l2) \
623 l1 = (line & 2 ? line - 1 : line); \
632 convert_I420_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
633 const GstVideoFrame * src)
636 gint width = convert->width;
637 gint height = convert->height;
638 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
641 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
642 GET_LINE_OFFSETS (interlaced, i, l1, l2);
644 video_convert_orc_convert_I420_YUY2 (FRAME_GET_LINE (dest, l1),
645 FRAME_GET_LINE (dest, l2),
646 FRAME_GET_Y_LINE (src, l1),
647 FRAME_GET_Y_LINE (src, l2),
648 FRAME_GET_U_LINE (src, i >> 1),
649 FRAME_GET_V_LINE (src, i >> 1), (width + 1) / 2);
652 /* now handle last line */
654 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
655 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
660 convert_I420_UYVY (VideoConvert * convert, GstVideoFrame * dest,
661 const GstVideoFrame * src)
664 gint width = convert->width;
665 gint height = convert->height;
666 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
669 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
670 GET_LINE_OFFSETS (interlaced, i, l1, l2);
672 video_convert_orc_convert_I420_UYVY (FRAME_GET_LINE (dest, l1),
673 FRAME_GET_LINE (dest, l2),
674 FRAME_GET_Y_LINE (src, l1),
675 FRAME_GET_Y_LINE (src, l2),
676 FRAME_GET_U_LINE (src, i >> 1),
677 FRAME_GET_V_LINE (src, i >> 1), (width + 1) / 2);
680 /* now handle last line */
682 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
683 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
688 convert_I420_AYUV (VideoConvert * convert, GstVideoFrame * dest,
689 const GstVideoFrame * src)
692 gint width = convert->width;
693 gint height = convert->height;
694 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
697 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
698 GET_LINE_OFFSETS (interlaced, i, l1, l2);
700 video_convert_orc_convert_I420_AYUV (FRAME_GET_LINE (dest, l1),
701 FRAME_GET_LINE (dest, l2),
702 FRAME_GET_Y_LINE (src, l1),
703 FRAME_GET_Y_LINE (src, l2),
704 FRAME_GET_U_LINE (src, i >> 1), FRAME_GET_V_LINE (src, i >> 1), width);
707 /* now handle last line */
709 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
710 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
715 convert_I420_Y42B (VideoConvert * convert, GstVideoFrame * dest,
716 const GstVideoFrame * src)
718 gint width = convert->width;
719 gint height = convert->height;
721 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
722 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
723 FRAME_GET_Y_STRIDE (src), width, height);
725 video_convert_orc_planar_chroma_420_422 (FRAME_GET_U_LINE (dest, 0),
726 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (dest, 1),
727 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
728 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
730 video_convert_orc_planar_chroma_420_422 (FRAME_GET_V_LINE (dest, 0),
731 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (dest, 1),
732 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
733 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
737 convert_I420_Y444 (VideoConvert * convert, GstVideoFrame * dest,
738 const GstVideoFrame * src)
740 gint width = convert->width;
741 gint height = convert->height;
743 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
744 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
745 FRAME_GET_Y_STRIDE (src), width, height);
747 video_convert_orc_planar_chroma_420_444 (FRAME_GET_U_LINE (dest, 0),
748 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (dest, 1),
749 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
750 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
752 video_convert_orc_planar_chroma_420_444 (FRAME_GET_V_LINE (dest, 0),
753 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (dest, 1),
754 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
755 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
757 /* now handle last line */
759 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
760 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
765 convert_YUY2_I420 (VideoConvert * convert, GstVideoFrame * dest,
766 const GstVideoFrame * src)
769 gint width = convert->width;
770 gint height = convert->height;
771 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
774 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
775 GET_LINE_OFFSETS (interlaced, i, l1, l2);
777 video_convert_orc_convert_YUY2_I420 (FRAME_GET_Y_LINE (dest, l1),
778 FRAME_GET_Y_LINE (dest, l2),
779 FRAME_GET_U_LINE (dest, i >> 1),
780 FRAME_GET_V_LINE (dest, i >> 1),
781 FRAME_GET_LINE (src, l1), FRAME_GET_LINE (src, l2), (width + 1) / 2);
784 /* now handle last line */
786 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
787 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
792 convert_YUY2_AYUV (VideoConvert * convert, GstVideoFrame * dest,
793 const GstVideoFrame * src)
795 gint width = convert->width;
796 gint height = convert->height;
798 video_convert_orc_convert_YUY2_AYUV (FRAME_GET_LINE (dest, 0),
799 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
800 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
804 convert_YUY2_Y42B (VideoConvert * convert, GstVideoFrame * dest,
805 const GstVideoFrame * src)
807 gint width = convert->width;
808 gint height = convert->height;
810 video_convert_orc_convert_YUY2_Y42B (FRAME_GET_Y_LINE (dest, 0),
811 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
812 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
813 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
814 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
818 convert_YUY2_Y444 (VideoConvert * convert, GstVideoFrame * dest,
819 const GstVideoFrame * src)
821 gint width = convert->width;
822 gint height = convert->height;
824 video_convert_orc_convert_YUY2_Y444 (FRAME_GET_COMP_LINE (dest, 0, 0),
825 FRAME_GET_COMP_STRIDE (dest, 0), FRAME_GET_COMP_LINE (dest, 1, 0),
826 FRAME_GET_COMP_STRIDE (dest, 1), FRAME_GET_COMP_LINE (dest, 2, 0),
827 FRAME_GET_COMP_STRIDE (dest, 2), FRAME_GET_LINE (src, 0),
828 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
833 convert_UYVY_I420 (VideoConvert * convert, GstVideoFrame * dest,
834 const GstVideoFrame * src)
837 gint width = convert->width;
838 gint height = convert->height;
839 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
842 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
843 GET_LINE_OFFSETS (interlaced, i, l1, l2);
845 video_convert_orc_convert_UYVY_I420 (FRAME_GET_COMP_LINE (dest, 0, l1),
846 FRAME_GET_COMP_LINE (dest, 0, l2),
847 FRAME_GET_COMP_LINE (dest, 1, i >> 1),
848 FRAME_GET_COMP_LINE (dest, 2, i >> 1),
849 FRAME_GET_LINE (src, l1), FRAME_GET_LINE (src, l2), (width + 1) / 2);
852 /* now handle last line */
854 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
855 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
860 convert_UYVY_AYUV (VideoConvert * convert, GstVideoFrame * dest,
861 const GstVideoFrame * src)
863 gint width = convert->width;
864 gint height = convert->height;
866 video_convert_orc_convert_UYVY_AYUV (FRAME_GET_LINE (dest, 0),
867 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
868 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
872 convert_UYVY_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
873 const GstVideoFrame * src)
875 gint width = convert->width;
876 gint height = convert->height;
878 video_convert_orc_convert_UYVY_YUY2 (FRAME_GET_LINE (dest, 0),
879 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
880 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
884 convert_UYVY_Y42B (VideoConvert * convert, GstVideoFrame * dest,
885 const GstVideoFrame * src)
887 gint width = convert->width;
888 gint height = convert->height;
890 video_convert_orc_convert_UYVY_Y42B (FRAME_GET_Y_LINE (dest, 0),
891 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
892 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
893 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
894 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
898 convert_UYVY_Y444 (VideoConvert * convert, GstVideoFrame * dest,
899 const GstVideoFrame * src)
901 gint width = convert->width;
902 gint height = convert->height;
904 video_convert_orc_convert_UYVY_Y444 (FRAME_GET_Y_LINE (dest, 0),
905 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
906 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
907 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
908 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
912 convert_AYUV_I420 (VideoConvert * convert, GstVideoFrame * dest,
913 const GstVideoFrame * src)
915 gint width = convert->width;
916 gint height = convert->height;
918 /* only for even width/height */
919 video_convert_orc_convert_AYUV_I420 (FRAME_GET_Y_LINE (dest, 0),
920 2 * FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (dest, 1),
921 2 * FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
922 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
923 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
924 2 * FRAME_GET_STRIDE (src), FRAME_GET_LINE (src, 1),
925 2 * FRAME_GET_STRIDE (src), width / 2, height / 2);
929 convert_AYUV_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
930 const GstVideoFrame * src)
932 gint width = convert->width;
933 gint height = convert->height;
935 /* only for even width */
936 video_convert_orc_convert_AYUV_YUY2 (FRAME_GET_LINE (dest, 0),
937 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
938 FRAME_GET_STRIDE (src), width / 2, height);
942 convert_AYUV_UYVY (VideoConvert * convert, GstVideoFrame * dest,
943 const GstVideoFrame * src)
945 gint width = convert->width;
946 gint height = convert->height;
948 /* only for even width */
949 video_convert_orc_convert_AYUV_UYVY (FRAME_GET_LINE (dest, 0),
950 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
951 FRAME_GET_STRIDE (src), width / 2, height);
955 convert_AYUV_Y42B (VideoConvert * convert, GstVideoFrame * dest,
956 const GstVideoFrame * src)
958 gint width = convert->width;
959 gint height = convert->height;
961 /* only works for even width */
962 video_convert_orc_convert_AYUV_Y42B (FRAME_GET_Y_LINE (dest, 0),
963 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
964 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
965 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
966 FRAME_GET_STRIDE (src), width / 2, height);
970 convert_AYUV_Y444 (VideoConvert * convert, GstVideoFrame * dest,
971 const GstVideoFrame * src)
973 gint width = convert->width;
974 gint height = convert->height;
976 video_convert_orc_convert_AYUV_Y444 (FRAME_GET_Y_LINE (dest, 0),
977 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
978 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
979 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
980 FRAME_GET_STRIDE (src), width, height);
984 convert_Y42B_I420 (VideoConvert * convert, GstVideoFrame * dest,
985 const GstVideoFrame * src)
987 gint width = convert->width;
988 gint height = convert->height;
990 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
991 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
992 FRAME_GET_Y_STRIDE (src), width, height);
994 video_convert_orc_planar_chroma_422_420 (FRAME_GET_U_LINE (dest, 0),
995 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
996 2 * FRAME_GET_U_STRIDE (src), FRAME_GET_U_LINE (src, 1),
997 2 * FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
999 video_convert_orc_planar_chroma_422_420 (FRAME_GET_V_LINE (dest, 0),
1000 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
1001 2 * FRAME_GET_V_STRIDE (src), FRAME_GET_V_LINE (src, 1),
1002 2 * FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
1004 /* now handle last line */
1006 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
1007 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
1012 convert_Y42B_Y444 (VideoConvert * convert, GstVideoFrame * dest,
1013 const GstVideoFrame * src)
1015 gint width = convert->width;
1016 gint height = convert->height;
1018 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
1019 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1020 FRAME_GET_Y_STRIDE (src), width, height);
1022 video_convert_orc_planar_chroma_422_444 (FRAME_GET_U_LINE (dest, 0),
1023 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
1024 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height);
1026 video_convert_orc_planar_chroma_422_444 (FRAME_GET_V_LINE (dest, 0),
1027 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
1028 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
1032 convert_Y42B_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
1033 const GstVideoFrame * src)
1035 gint width = convert->width;
1036 gint height = convert->height;
1038 video_convert_orc_convert_Y42B_YUY2 (FRAME_GET_LINE (dest, 0),
1039 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1040 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1041 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1042 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
1046 convert_Y42B_UYVY (VideoConvert * convert, GstVideoFrame * dest,
1047 const GstVideoFrame * src)
1049 gint width = convert->width;
1050 gint height = convert->height;
1052 video_convert_orc_convert_Y42B_UYVY (FRAME_GET_LINE (dest, 0),
1053 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1054 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1055 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1056 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
1060 convert_Y42B_AYUV (VideoConvert * convert, GstVideoFrame * dest,
1061 const GstVideoFrame * src)
1063 gint width = convert->width;
1064 gint height = convert->height;
1066 /* only for even width */
1067 video_convert_orc_convert_Y42B_AYUV (FRAME_GET_LINE (dest, 0),
1068 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1069 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1070 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1071 FRAME_GET_V_STRIDE (src), width / 2, height);
1075 convert_Y444_I420 (VideoConvert * convert, GstVideoFrame * dest,
1076 const GstVideoFrame * src)
1078 gint width = convert->width;
1079 gint height = convert->height;
1081 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
1082 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1083 FRAME_GET_Y_STRIDE (src), width, height);
1085 video_convert_orc_planar_chroma_444_420 (FRAME_GET_U_LINE (dest, 0),
1086 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
1087 2 * FRAME_GET_U_STRIDE (src), FRAME_GET_U_LINE (src, 1),
1088 2 * FRAME_GET_U_STRIDE (src), width / 2, height / 2);
1090 video_convert_orc_planar_chroma_444_420 (FRAME_GET_V_LINE (dest, 0),
1091 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
1092 2 * FRAME_GET_V_STRIDE (src), FRAME_GET_V_LINE (src, 1),
1093 2 * FRAME_GET_V_STRIDE (src), width / 2, height / 2);
1095 /* now handle last line */
1097 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
1098 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
1103 convert_Y444_Y42B (VideoConvert * convert, GstVideoFrame * dest,
1104 const GstVideoFrame * src)
1106 gint width = convert->width;
1107 gint height = convert->height;
1109 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
1110 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1111 FRAME_GET_Y_STRIDE (src), width, height);
1113 video_convert_orc_planar_chroma_444_422 (FRAME_GET_U_LINE (dest, 0),
1114 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
1115 FRAME_GET_U_STRIDE (src), width / 2, height);
1117 video_convert_orc_planar_chroma_444_422 (FRAME_GET_V_LINE (dest, 0),
1118 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
1119 FRAME_GET_V_STRIDE (src), width / 2, height);
1123 convert_Y444_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
1124 const GstVideoFrame * src)
1126 gint width = convert->width;
1127 gint height = convert->height;
1129 video_convert_orc_convert_Y444_YUY2 (FRAME_GET_LINE (dest, 0),
1130 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1131 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1132 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1133 FRAME_GET_V_STRIDE (src), width / 2, height);
1137 convert_Y444_UYVY (VideoConvert * convert, GstVideoFrame * dest,
1138 const GstVideoFrame * src)
1140 gint width = convert->width;
1141 gint height = convert->height;
1143 video_convert_orc_convert_Y444_UYVY (FRAME_GET_LINE (dest, 0),
1144 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1145 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1146 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1147 FRAME_GET_V_STRIDE (src), width / 2, height);
1151 convert_Y444_AYUV (VideoConvert * convert, GstVideoFrame * dest,
1152 const GstVideoFrame * src)
1154 gint width = convert->width;
1155 gint height = convert->height;
1157 video_convert_orc_convert_Y444_AYUV (FRAME_GET_LINE (dest, 0),
1158 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1159 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1160 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1161 FRAME_GET_V_STRIDE (src), width, height);
1164 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1166 convert_AYUV_ARGB (VideoConvert * convert, GstVideoFrame * dest,
1167 const GstVideoFrame * src)
1169 gint width = convert->width;
1170 gint height = convert->height;
1172 video_convert_orc_convert_AYUV_ARGB (FRAME_GET_LINE (dest, 0),
1173 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1174 FRAME_GET_STRIDE (src), convert->cmatrix[0][0], convert->cmatrix[0][2],
1175 convert->cmatrix[2][1], convert->cmatrix[1][1], convert->cmatrix[1][2],
1180 convert_AYUV_BGRA (VideoConvert * convert, GstVideoFrame * dest,
1181 const GstVideoFrame * src)
1183 gint width = convert->width;
1184 gint height = convert->height;
1186 video_convert_orc_convert_AYUV_BGRA (FRAME_GET_LINE (dest, 0),
1187 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1188 FRAME_GET_STRIDE (src), convert->cmatrix[0][0], convert->cmatrix[0][2],
1189 convert->cmatrix[2][1], convert->cmatrix[1][1], convert->cmatrix[1][2],
1194 convert_AYUV_ABGR (VideoConvert * convert, GstVideoFrame * dest,
1195 const GstVideoFrame * src)
1197 gint width = convert->width;
1198 gint height = convert->height;
1200 video_convert_orc_convert_AYUV_ABGR (FRAME_GET_LINE (dest, 0),
1201 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1202 FRAME_GET_STRIDE (src), convert->cmatrix[0][0], convert->cmatrix[0][2],
1203 convert->cmatrix[2][1], convert->cmatrix[1][1], convert->cmatrix[1][2],
1208 convert_AYUV_RGBA (VideoConvert * convert, GstVideoFrame * dest,
1209 const GstVideoFrame * src)
1211 gint width = convert->width;
1212 gint height = convert->height;
1214 video_convert_orc_convert_AYUV_RGBA (FRAME_GET_LINE (dest, 0),
1215 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1216 FRAME_GET_STRIDE (src), convert->cmatrix[0][0], convert->cmatrix[0][2],
1217 convert->cmatrix[2][1], convert->cmatrix[1][1], convert->cmatrix[1][2],
1222 convert_I420_BGRA (VideoConvert * convert, GstVideoFrame * dest,
1223 const GstVideoFrame * src)
1226 gint width = convert->width;
1227 gint height = convert->height;
1229 for (i = 0; i < height; i++) {
1230 video_convert_orc_convert_I420_BGRA (FRAME_GET_LINE (dest, i),
1231 FRAME_GET_Y_LINE (src, i),
1232 FRAME_GET_U_LINE (src, i >> 1), FRAME_GET_V_LINE (src, i >> 1),
1233 convert->cmatrix[0][0], convert->cmatrix[0][2],
1234 convert->cmatrix[2][1], convert->cmatrix[1][1], convert->cmatrix[1][2],
1246 GstVideoFormat in_format;
1247 GstVideoColorMatrix in_matrix;
1248 GstVideoFormat out_format;
1249 GstVideoColorMatrix out_matrix;
1250 gboolean keeps_color_matrix;
1251 gboolean keeps_interlaced;
1252 gboolean needs_color_matrix;
1253 gint width_align, height_align;
1254 void (*convert) (VideoConvert * convert, GstVideoFrame * dest,
1255 const GstVideoFrame * src);
1258 static const VideoTransform transforms[] = {
1259 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1260 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1262 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1263 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1265 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1266 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1268 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1269 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 0, 0,
1271 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1272 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 0, 0,
1275 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1276 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1278 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1279 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1281 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1282 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1284 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1285 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 0, 0,
1287 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1288 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 0, 0,
1291 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1292 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1294 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YV12,
1295 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1297 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1298 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0, convert_UYVY_YUY2}, /* alias */
1299 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1300 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1302 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1303 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1305 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1306 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1309 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1310 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1312 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YV12,
1313 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1315 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1316 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1318 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1319 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1321 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1322 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1324 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1325 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1328 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1329 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 1, 1,
1331 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YV12,
1332 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 1, 1,
1334 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1335 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1337 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1338 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1340 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1341 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1343 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1344 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1347 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1348 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 0, 0,
1350 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YV12,
1351 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 0, 0,
1353 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1354 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1356 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1357 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1359 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1360 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1362 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1363 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1366 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1367 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 1, 0,
1369 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YV12,
1370 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 1, 0,
1372 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1373 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1375 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1376 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1378 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1379 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1381 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1382 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1385 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1386 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_ARGB,
1387 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0,
1389 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_BGRA,
1390 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0,
1392 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_xRGB,
1393 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0, convert_AYUV_ARGB}, /* alias */
1394 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_BGRx,
1395 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0, convert_AYUV_BGRA}, /* alias */
1396 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_ABGR,
1397 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0,
1399 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_RGBA,
1400 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0,
1402 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_xBGR,
1403 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0, convert_AYUV_ABGR}, /* alias */
1404 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_RGBx,
1405 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0, convert_AYUV_RGBA}, /* alias */
1407 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_BGRA,
1408 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, TRUE, 0, 0,
1410 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_BGRx,
1411 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, TRUE, 0, 0,
1413 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_BGRA,
1414 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, TRUE, 0, 0,
1416 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_BGRx,
1417 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, TRUE, 0, 0,
1423 videoconvert_convert_lookup_fastpath (VideoConvert * convert)
1426 GstVideoFormat in_format, out_format;
1427 GstVideoColorMatrix in_matrix, out_matrix;
1428 gboolean interlaced;
1431 in_format = GST_VIDEO_INFO_FORMAT (&convert->in_info);
1432 out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info);
1434 width = GST_VIDEO_INFO_WIDTH (&convert->in_info);
1435 height = GST_VIDEO_INFO_HEIGHT (&convert->in_info);
1437 in_matrix = convert->in_info.colorimetry.matrix;
1438 out_matrix = convert->out_info.colorimetry.matrix;
1440 interlaced = GST_VIDEO_INFO_IS_INTERLACED (&convert->in_info);
1441 interlaced |= GST_VIDEO_INFO_IS_INTERLACED (&convert->out_info);
1443 for (i = 0; i < sizeof (transforms) / sizeof (transforms[0]); i++) {
1444 if (transforms[i].in_format == in_format &&
1445 transforms[i].out_format == out_format &&
1446 (transforms[i].keeps_color_matrix ||
1447 (transforms[i].in_matrix == in_matrix &&
1448 transforms[i].out_matrix == out_matrix)) &&
1449 (transforms[i].keeps_interlaced || !interlaced) &&
1450 (transforms[i].width_align & width) == 0 &&
1451 (transforms[i].height_align & height) == 0) {
1452 GST_DEBUG ("using fastpath");
1453 if (transforms[i].needs_color_matrix)
1454 if (!videoconvert_convert_compute_matrix (convert))
1456 convert->convert = transforms[i].convert;
1457 alloc_tmplines (convert, 1, GST_VIDEO_INFO_WIDTH (&convert->in_info));
1461 GST_DEBUG ("no fastpath found");
1466 GST_DEBUG ("can't create matrix");