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 "bad-video-orc.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 get_Kr_Kb (GstVideoColorMatrix matrix, gdouble * Kr, gdouble * Kb)
193 case GST_VIDEO_COLOR_MATRIX_RGB:
197 case GST_VIDEO_COLOR_MATRIX_FCC:
201 case GST_VIDEO_COLOR_MATRIX_BT709:
205 case GST_VIDEO_COLOR_MATRIX_BT601:
209 case GST_VIDEO_COLOR_MATRIX_SMPTE240M:
214 GST_DEBUG ("matrix: %d, Kr %f, Kb %f", matrix, *Kr, *Kb);
219 videoconvert_convert_compute_matrix (VideoConvert * convert)
221 GstVideoInfo *in_info, *out_info;
224 const GstVideoFormatInfo *sfinfo, *dfinfo;
225 const GstVideoFormatInfo *suinfo, *duinfo;
226 gint offset[4], scale[4];
227 gdouble Kr = 0, Kb = 0;
229 in_info = &convert->in_info;
230 out_info = &convert->out_info;
232 sfinfo = in_info->finfo;
233 dfinfo = out_info->finfo;
235 if (sfinfo->unpack_func == NULL)
238 if (dfinfo->pack_func == NULL)
241 suinfo = gst_video_format_get_info (sfinfo->unpack_format);
242 duinfo = gst_video_format_get_info (dfinfo->unpack_format);
244 convert->in_bits = GST_VIDEO_FORMAT_INFO_DEPTH (suinfo, 0);
245 convert->out_bits = GST_VIDEO_FORMAT_INFO_DEPTH (duinfo, 0);
247 GST_DEBUG ("in bits %d, out bits %d", convert->in_bits, convert->out_bits);
249 if (in_info->colorimetry.range == out_info->colorimetry.range &&
250 in_info->colorimetry.matrix == out_info->colorimetry.matrix) {
251 GST_DEBUG ("using identity color transform");
252 convert->matrix = NULL;
256 /* calculate intermediate format for the matrix. When unpacking, we expand
257 * input to 16 when one of the inputs is 16 bits */
258 if (convert->in_bits == 16 || convert->out_bits == 16) {
259 convert->matrix = videoconvert_convert_matrix16;
261 if (GST_VIDEO_FORMAT_INFO_IS_RGB (suinfo))
262 suinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_ARGB64);
264 suinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_AYUV64);
266 if (GST_VIDEO_FORMAT_INFO_IS_RGB (duinfo))
267 duinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_ARGB64);
269 duinfo = gst_video_format_get_info (GST_VIDEO_FORMAT_AYUV64);
271 convert->matrix = videoconvert_convert_matrix8;
274 color_matrix_set_identity (&dst);
276 /* 1, bring color components to [0..1.0] range */
277 gst_video_color_range_offsets (in_info->colorimetry.range, suinfo, offset,
280 color_matrix_offset_components (&dst, -offset[0], -offset[1], -offset[2]);
282 color_matrix_scale_components (&dst, 1 / ((float) scale[0]),
283 1 / ((float) scale[1]), 1 / ((float) scale[2]));
285 /* 2. bring components to R'G'B' space */
286 if (get_Kr_Kb (in_info->colorimetry.matrix, &Kr, &Kb))
287 color_matrix_YCbCr_to_RGB (&dst, Kr, Kb);
289 /* 3. inverse transfer function. R'G'B' to linear RGB */
291 /* 4. from RGB to XYZ using the primaries */
293 /* 5. from XYZ to RGB using the primaries */
295 /* 6. transfer function. linear RGB to R'G'B' */
297 /* 7. bring components to YCbCr space */
298 if (get_Kr_Kb (out_info->colorimetry.matrix, &Kr, &Kb))
299 color_matrix_RGB_to_YCbCr (&dst, Kr, Kb);
301 /* 8, bring color components to nominal range */
302 gst_video_color_range_offsets (out_info->colorimetry.range, duinfo, offset,
305 color_matrix_scale_components (&dst, (float) scale[0], (float) scale[1],
308 color_matrix_offset_components (&dst, offset[0], offset[1], offset[2]);
310 /* because we're doing fixed point matrix coefficients */
311 color_matrix_scale_components (&dst, SCALE_F, SCALE_F, SCALE_F);
313 for (i = 0; i < 4; i++)
314 for (j = 0; j < 4; j++)
315 convert->cmatrix[i][j] = rint (dst.m[i][j]);
317 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[0][0],
318 convert->cmatrix[0][1], convert->cmatrix[0][2], convert->cmatrix[0][3]);
319 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[1][0],
320 convert->cmatrix[1][1], convert->cmatrix[1][2], convert->cmatrix[1][3]);
321 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[2][0],
322 convert->cmatrix[2][1], convert->cmatrix[2][2], convert->cmatrix[2][3]);
323 GST_DEBUG ("[%6d %6d %6d %6d]", convert->cmatrix[3][0],
324 convert->cmatrix[3][1], convert->cmatrix[3][2], convert->cmatrix[3][3]);
331 GST_ERROR ("no unpack_func for format %s",
332 gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (in_info)));
337 GST_ERROR ("no pack_func for format %s",
338 gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (out_info)));
344 videoconvert_dither_verterr (VideoConvert * convert, guint16 * pixels, int j)
347 guint16 *errline = convert->errline;
348 unsigned int mask = 0xff;
350 for (i = 0; i < 4 * convert->width; i++) {
351 int x = pixels[i] + errline[i];
355 errline[i] = x & mask;
360 videoconvert_dither_halftone (VideoConvert * convert, guint16 * pixels, int j)
363 static guint16 halftone[8][8] = {
364 {0, 128, 32, 160, 8, 136, 40, 168},
365 {192, 64, 224, 96, 200, 72, 232, 104},
366 {48, 176, 16, 144, 56, 184, 24, 152},
367 {240, 112, 208, 80, 248, 120, 216, 88},
368 {12, 240, 44, 172, 4, 132, 36, 164},
369 {204, 76, 236, 108, 196, 68, 228, 100},
370 {60, 188, 28, 156, 52, 180, 20, 148},
371 {252, 142, 220, 92, 244, 116, 212, 84}
374 for (i = 0; i < convert->width * 4; i++) {
376 x = pixels[i] + halftone[(i >> 2) & 7][j & 7];
384 alloc_tmplines (VideoConvert * convert, guint lines, gint width)
388 convert->n_tmplines = lines;
389 convert->tmplines = g_malloc (lines * sizeof (gpointer));
390 for (i = 0; i < lines; i++)
391 convert->tmplines[i] = g_malloc (sizeof (guint16) * (width + 8) * 4);
395 videoconvert_convert_compute_resample (VideoConvert * convert)
397 GstVideoInfo *in_info, *out_info;
398 const GstVideoFormatInfo *sfinfo, *dfinfo;
401 in_info = &convert->in_info;
402 out_info = &convert->out_info;
404 sfinfo = in_info->finfo;
405 dfinfo = out_info->finfo;
407 width = convert->width;
409 if (sfinfo->w_sub[2] != dfinfo->w_sub[2] ||
410 sfinfo->h_sub[2] != dfinfo->h_sub[2] ||
411 in_info->chroma_site != out_info->chroma_site) {
412 convert->upsample = gst_video_chroma_resample_new (0,
413 in_info->chroma_site, 0, sfinfo->unpack_format, sfinfo->w_sub[2],
417 convert->downsample = gst_video_chroma_resample_new (0,
418 out_info->chroma_site, 0, dfinfo->unpack_format, -dfinfo->w_sub[2],
422 convert->upsample = NULL;
423 convert->downsample = NULL;
426 if (convert->upsample) {
427 gst_video_chroma_resample_get_info (convert->upsample,
428 &convert->up_n_lines, &convert->up_offset);
430 convert->up_n_lines = 1;
431 convert->up_offset = 0;
433 if (convert->downsample) {
434 gst_video_chroma_resample_get_info (convert->downsample,
435 &convert->down_n_lines, &convert->down_offset);
437 convert->down_n_lines = 1;
438 convert->down_offset = 0;
440 GST_DEBUG ("upsample: %p, site: %d, offset %d, n_lines %d", convert->upsample,
441 in_info->chroma_site, convert->up_offset, convert->up_n_lines);
442 GST_DEBUG ("downsample: %p, site: %d, offset %d, n_lines %d",
443 convert->downsample, out_info->chroma_site, convert->down_offset,
444 convert->down_n_lines);
446 alloc_tmplines (convert, convert->down_n_lines + convert->up_n_lines, width);
451 #define TO_16(x) (((x)<<8) | (x))
454 convert_to16 (gpointer line, gint width)
456 guint8 *line8 = line;
457 guint16 *line16 = line;
460 for (i = (width - 1) * 4; i >= 0; i--)
461 line16[i] = TO_16 (line8[i]);
465 convert_to8 (gpointer line, gint width)
467 guint8 *line8 = line;
468 guint16 *line16 = line;
471 for (i = 0; i < width * 4; i++)
472 line8[i] = line16[i] >> 8;
475 #define UNPACK_FRAME(frame,dest,line,width) \
476 frame->info.finfo->unpack_func (frame->info.finfo, \
477 (GST_VIDEO_FRAME_IS_INTERLACED (frame) ? \
478 GST_VIDEO_PACK_FLAG_INTERLACED : \
479 GST_VIDEO_PACK_FLAG_NONE), \
480 dest, frame->data, frame->info.stride, 0, \
482 #define PACK_FRAME(frame,dest,line,width) \
483 frame->info.finfo->pack_func (frame->info.finfo, \
484 (GST_VIDEO_FRAME_IS_INTERLACED (frame) ? \
485 GST_VIDEO_PACK_FLAG_INTERLACED : \
486 GST_VIDEO_PACK_FLAG_NONE), \
487 dest, 0, frame->data, frame->info.stride, \
488 frame->info.chroma_site, line, width);
491 videoconvert_convert_generic (VideoConvert * convert, GstVideoFrame * dest,
492 const GstVideoFrame * src)
495 gint width, height, lines, max_lines;
496 guint in_bits, out_bits;
499 guint up_n_lines, down_n_lines;
500 gint up_offset, down_offset;
501 gint in_lines, out_lines;
502 gint up_line, down_line;
503 gint start_offset, stop_offset;
504 gpointer in_tmplines[8];
505 gpointer out_tmplines[8];
507 height = convert->height;
508 width = convert->width;
510 in_bits = convert->in_bits;
511 out_bits = convert->out_bits;
513 lines = convert->lines;
514 up_n_lines = convert->up_n_lines;
515 up_offset = convert->up_offset;
516 down_n_lines = convert->down_n_lines;
517 down_offset = convert->down_offset;
518 max_lines = convert->n_tmplines;
523 GST_DEBUG ("up_offset %d, up_n_lines %u", up_offset, up_n_lines);
525 start_offset = MIN (up_offset, down_offset);
526 stop_offset = height + start_offset + MAX (up_n_lines, down_n_lines);
528 for (; start_offset < stop_offset; start_offset++) {
531 idx = CLAMP (start_offset, 0, height);
532 in_tmplines[in_lines] = convert->tmplines[idx % max_lines];
533 out_tmplines[out_lines] = in_tmplines[in_lines];
534 GST_DEBUG ("start_offset %d/%d, %d, idx %u, in %d, out %d", start_offset,
535 stop_offset, up_offset, idx, in_lines, out_lines);
537 up_line = up_offset + in_lines;
539 /* extract the next line */
540 if (up_line >= 0 && up_line < height) {
541 GST_DEBUG ("unpack line %d into %d", up_line, in_lines);
542 UNPACK_FRAME (src, in_tmplines[in_lines], up_line, width);
545 if (start_offset >= up_offset)
548 if (start_offset >= down_offset)
551 if (in_lines < up_n_lines)
556 /* we have enough lines to upsample */
557 if (convert->upsample) {
558 GST_DEBUG ("doing upsample");
559 gst_video_chroma_resample (convert->upsample, in_tmplines, width);
562 /* convert upsampled lines */
563 for (k = 0; k < up_n_lines; k++) {
564 down_line = up_offset + k;
566 /* only takes lines with valid output */
567 if (down_line < 0 || down_line >= height)
570 GST_DEBUG ("handle line %d, %d/%d, down_line %d", k, out_lines,
571 down_n_lines, down_line);
573 if (out_bits == 16 || in_bits == 16) {
574 /* FIXME, we can scale in the conversion matrix */
576 convert_to16 (in_tmplines[k], width);
579 convert->matrix (convert, in_tmplines[k]);
580 if (convert->dither16)
581 convert->dither16 (convert, in_tmplines[k], down_line);
584 convert_to8 (in_tmplines[k], width);
587 convert->matrix (convert, in_tmplines[k]);
592 while (out_lines >= down_n_lines) {
593 if (convert->downsample) {
594 GST_DEBUG ("doing downsample %u", start);
595 gst_video_chroma_resample (convert->downsample,
596 &out_tmplines[start], width);
599 for (j = 0; j < down_n_lines; j += lines) {
600 idx = down_offset + j;
603 GST_DEBUG ("packing line %d %d %d", j + start, down_offset, idx);
604 /* FIXME, not correct if lines > 1 */
605 PACK_FRAME (dest, out_tmplines[j + start], idx, width);
608 down_offset += down_n_lines;
609 start += down_n_lines;
610 out_lines -= down_n_lines;
612 /* we didn't process these lines, move them up for the next round */
613 for (j = 0; j < out_lines; j++) {
614 GST_DEBUG ("move line %d->%d", j + start, j);
615 out_tmplines[j] = out_tmplines[j + start];
618 up_offset += up_n_lines;
621 gst_video_format_get_palette (GST_VIDEO_FRAME_FORMAT (dest),
623 memcpy (GST_VIDEO_FRAME_PLANE_DATA (dest, 1), pal, palsize);
627 #define FRAME_GET_PLANE_STRIDE(frame, plane) \
628 GST_VIDEO_FRAME_PLANE_STRIDE (frame, plane)
629 #define FRAME_GET_PLANE_LINE(frame, plane, line) \
630 (gpointer)(((guint8*)(GST_VIDEO_FRAME_PLANE_DATA (frame, plane))) + \
631 FRAME_GET_PLANE_STRIDE (frame, plane) * (line))
633 #define FRAME_GET_COMP_STRIDE(frame, comp) \
634 GST_VIDEO_FRAME_COMP_STRIDE (frame, comp)
635 #define FRAME_GET_COMP_LINE(frame, comp, line) \
636 (gpointer)(((guint8*)(GST_VIDEO_FRAME_COMP_DATA (frame, comp))) + \
637 FRAME_GET_COMP_STRIDE (frame, comp) * (line))
639 #define FRAME_GET_STRIDE(frame) FRAME_GET_PLANE_STRIDE (frame, 0)
640 #define FRAME_GET_LINE(frame,line) FRAME_GET_PLANE_LINE (frame, 0, line)
642 #define FRAME_GET_Y_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_Y, line)
643 #define FRAME_GET_U_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_U, line)
644 #define FRAME_GET_V_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_V, line)
645 #define FRAME_GET_A_LINE(frame,line) FRAME_GET_COMP_LINE(frame, GST_VIDEO_COMP_A, line)
647 #define FRAME_GET_Y_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_Y)
648 #define FRAME_GET_U_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_U)
649 #define FRAME_GET_V_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_V)
650 #define FRAME_GET_A_STRIDE(frame) FRAME_GET_COMP_STRIDE(frame, GST_VIDEO_COMP_A)
654 #define GET_LINE_OFFSETS(interlaced,line,l1,l2) \
656 l1 = (line & 2 ? line - 1 : line); \
665 convert_I420_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
666 const GstVideoFrame * src)
669 gint width = convert->width;
670 gint height = convert->height;
671 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
674 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
675 GET_LINE_OFFSETS (interlaced, i, l1, l2);
677 video_convert_orc_convert_I420_YUY2 (FRAME_GET_LINE (dest, l1),
678 FRAME_GET_LINE (dest, l2),
679 FRAME_GET_Y_LINE (src, l1),
680 FRAME_GET_Y_LINE (src, l2),
681 FRAME_GET_U_LINE (src, i >> 1),
682 FRAME_GET_V_LINE (src, i >> 1), (width + 1) / 2);
685 /* now handle last line */
687 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
688 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
693 convert_I420_UYVY (VideoConvert * convert, GstVideoFrame * dest,
694 const GstVideoFrame * src)
697 gint width = convert->width;
698 gint height = convert->height;
699 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
702 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
703 GET_LINE_OFFSETS (interlaced, i, l1, l2);
705 video_convert_orc_convert_I420_UYVY (FRAME_GET_LINE (dest, l1),
706 FRAME_GET_LINE (dest, l2),
707 FRAME_GET_Y_LINE (src, l1),
708 FRAME_GET_Y_LINE (src, l2),
709 FRAME_GET_U_LINE (src, i >> 1),
710 FRAME_GET_V_LINE (src, i >> 1), (width + 1) / 2);
713 /* now handle last line */
715 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
716 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
721 convert_I420_AYUV (VideoConvert * convert, GstVideoFrame * dest,
722 const GstVideoFrame * src)
725 gint width = convert->width;
726 gint height = convert->height;
727 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
730 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
731 GET_LINE_OFFSETS (interlaced, i, l1, l2);
733 video_convert_orc_convert_I420_AYUV (FRAME_GET_LINE (dest, l1),
734 FRAME_GET_LINE (dest, l2),
735 FRAME_GET_Y_LINE (src, l1),
736 FRAME_GET_Y_LINE (src, l2),
737 FRAME_GET_U_LINE (src, i >> 1), FRAME_GET_V_LINE (src, i >> 1), width);
740 /* now handle last line */
742 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
743 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
748 convert_I420_Y42B (VideoConvert * convert, GstVideoFrame * dest,
749 const GstVideoFrame * src)
751 gint width = convert->width;
752 gint height = convert->height;
754 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
755 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
756 FRAME_GET_Y_STRIDE (src), width, height);
758 video_convert_orc_planar_chroma_420_422 (FRAME_GET_U_LINE (dest, 0),
759 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (dest, 1),
760 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
761 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
763 video_convert_orc_planar_chroma_420_422 (FRAME_GET_V_LINE (dest, 0),
764 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (dest, 1),
765 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
766 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
770 convert_I420_Y444 (VideoConvert * convert, GstVideoFrame * dest,
771 const GstVideoFrame * src)
773 gint width = convert->width;
774 gint height = convert->height;
776 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
777 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
778 FRAME_GET_Y_STRIDE (src), width, height);
780 video_convert_orc_planar_chroma_420_444 (FRAME_GET_U_LINE (dest, 0),
781 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (dest, 1),
782 2 * FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
783 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
785 video_convert_orc_planar_chroma_420_444 (FRAME_GET_V_LINE (dest, 0),
786 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (dest, 1),
787 2 * FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
788 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
790 /* now handle last line */
792 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
793 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
798 convert_YUY2_I420 (VideoConvert * convert, GstVideoFrame * dest,
799 const GstVideoFrame * src)
802 gint width = convert->width;
803 gint height = convert->height;
804 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
807 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
808 GET_LINE_OFFSETS (interlaced, i, l1, l2);
810 video_convert_orc_convert_YUY2_I420 (FRAME_GET_Y_LINE (dest, l1),
811 FRAME_GET_Y_LINE (dest, l2),
812 FRAME_GET_U_LINE (dest, i >> 1),
813 FRAME_GET_V_LINE (dest, i >> 1),
814 FRAME_GET_LINE (src, l1), FRAME_GET_LINE (src, l2), (width + 1) / 2);
817 /* now handle last line */
819 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
820 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
825 convert_YUY2_AYUV (VideoConvert * convert, GstVideoFrame * dest,
826 const GstVideoFrame * src)
828 gint width = convert->width;
829 gint height = convert->height;
831 video_convert_orc_convert_YUY2_AYUV (FRAME_GET_LINE (dest, 0),
832 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
833 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
837 convert_YUY2_Y42B (VideoConvert * convert, GstVideoFrame * dest,
838 const GstVideoFrame * src)
840 gint width = convert->width;
841 gint height = convert->height;
843 video_convert_orc_convert_YUY2_Y42B (FRAME_GET_Y_LINE (dest, 0),
844 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
845 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
846 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
847 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
851 convert_YUY2_Y444 (VideoConvert * convert, GstVideoFrame * dest,
852 const GstVideoFrame * src)
854 gint width = convert->width;
855 gint height = convert->height;
857 video_convert_orc_convert_YUY2_Y444 (FRAME_GET_COMP_LINE (dest, 0, 0),
858 FRAME_GET_COMP_STRIDE (dest, 0), FRAME_GET_COMP_LINE (dest, 1, 0),
859 FRAME_GET_COMP_STRIDE (dest, 1), FRAME_GET_COMP_LINE (dest, 2, 0),
860 FRAME_GET_COMP_STRIDE (dest, 2), FRAME_GET_LINE (src, 0),
861 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
866 convert_UYVY_I420 (VideoConvert * convert, GstVideoFrame * dest,
867 const GstVideoFrame * src)
870 gint width = convert->width;
871 gint height = convert->height;
872 gboolean interlaced = GST_VIDEO_FRAME_IS_INTERLACED (src);
875 for (i = 0; i < GST_ROUND_DOWN_2 (height); i += 2) {
876 GET_LINE_OFFSETS (interlaced, i, l1, l2);
878 video_convert_orc_convert_UYVY_I420 (FRAME_GET_COMP_LINE (dest, 0, l1),
879 FRAME_GET_COMP_LINE (dest, 0, l2),
880 FRAME_GET_COMP_LINE (dest, 1, i >> 1),
881 FRAME_GET_COMP_LINE (dest, 2, i >> 1),
882 FRAME_GET_LINE (src, l1), FRAME_GET_LINE (src, l2), (width + 1) / 2);
885 /* now handle last line */
887 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
888 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
893 convert_UYVY_AYUV (VideoConvert * convert, GstVideoFrame * dest,
894 const GstVideoFrame * src)
896 gint width = convert->width;
897 gint height = convert->height;
899 video_convert_orc_convert_UYVY_AYUV (FRAME_GET_LINE (dest, 0),
900 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
901 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
905 convert_UYVY_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
906 const GstVideoFrame * src)
908 gint width = convert->width;
909 gint height = convert->height;
911 video_convert_orc_convert_UYVY_YUY2 (FRAME_GET_LINE (dest, 0),
912 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
913 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
917 convert_UYVY_Y42B (VideoConvert * convert, GstVideoFrame * dest,
918 const GstVideoFrame * src)
920 gint width = convert->width;
921 gint height = convert->height;
923 video_convert_orc_convert_UYVY_Y42B (FRAME_GET_Y_LINE (dest, 0),
924 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
925 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
926 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
927 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
931 convert_UYVY_Y444 (VideoConvert * convert, GstVideoFrame * dest,
932 const GstVideoFrame * src)
934 gint width = convert->width;
935 gint height = convert->height;
937 video_convert_orc_convert_UYVY_Y444 (FRAME_GET_Y_LINE (dest, 0),
938 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
939 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
940 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
941 FRAME_GET_STRIDE (src), (width + 1) / 2, height);
945 convert_AYUV_I420 (VideoConvert * convert, GstVideoFrame * dest,
946 const GstVideoFrame * src)
948 gint width = convert->width;
949 gint height = convert->height;
951 /* only for even width/height */
952 video_convert_orc_convert_AYUV_I420 (FRAME_GET_Y_LINE (dest, 0),
953 2 * FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (dest, 1),
954 2 * FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
955 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
956 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
957 2 * FRAME_GET_STRIDE (src), FRAME_GET_LINE (src, 1),
958 2 * FRAME_GET_STRIDE (src), width / 2, height / 2);
962 convert_AYUV_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
963 const GstVideoFrame * src)
965 gint width = convert->width;
966 gint height = convert->height;
968 /* only for even width */
969 video_convert_orc_convert_AYUV_YUY2 (FRAME_GET_LINE (dest, 0),
970 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
971 FRAME_GET_STRIDE (src), width / 2, height);
975 convert_AYUV_UYVY (VideoConvert * convert, GstVideoFrame * dest,
976 const GstVideoFrame * src)
978 gint width = convert->width;
979 gint height = convert->height;
981 /* only for even width */
982 video_convert_orc_convert_AYUV_UYVY (FRAME_GET_LINE (dest, 0),
983 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
984 FRAME_GET_STRIDE (src), width / 2, height);
988 convert_AYUV_Y42B (VideoConvert * convert, GstVideoFrame * dest,
989 const GstVideoFrame * src)
991 gint width = convert->width;
992 gint height = convert->height;
994 /* only works for even width */
995 video_convert_orc_convert_AYUV_Y42B (FRAME_GET_Y_LINE (dest, 0),
996 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
997 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
998 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
999 FRAME_GET_STRIDE (src), width / 2, height);
1003 convert_AYUV_Y444 (VideoConvert * convert, GstVideoFrame * dest,
1004 const GstVideoFrame * src)
1006 gint width = convert->width;
1007 gint height = convert->height;
1009 video_convert_orc_convert_AYUV_Y444 (FRAME_GET_Y_LINE (dest, 0),
1010 FRAME_GET_Y_STRIDE (dest), FRAME_GET_U_LINE (dest, 0),
1011 FRAME_GET_U_STRIDE (dest), FRAME_GET_V_LINE (dest, 0),
1012 FRAME_GET_V_STRIDE (dest), FRAME_GET_LINE (src, 0),
1013 FRAME_GET_STRIDE (src), width, height);
1017 convert_Y42B_I420 (VideoConvert * convert, GstVideoFrame * dest,
1018 const GstVideoFrame * src)
1020 gint width = convert->width;
1021 gint height = convert->height;
1023 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
1024 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1025 FRAME_GET_Y_STRIDE (src), width, height);
1027 video_convert_orc_planar_chroma_422_420 (FRAME_GET_U_LINE (dest, 0),
1028 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
1029 2 * FRAME_GET_U_STRIDE (src), FRAME_GET_U_LINE (src, 1),
1030 2 * FRAME_GET_U_STRIDE (src), (width + 1) / 2, height / 2);
1032 video_convert_orc_planar_chroma_422_420 (FRAME_GET_V_LINE (dest, 0),
1033 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
1034 2 * FRAME_GET_V_STRIDE (src), FRAME_GET_V_LINE (src, 1),
1035 2 * FRAME_GET_V_STRIDE (src), (width + 1) / 2, height / 2);
1037 /* now handle last line */
1039 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
1040 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
1045 convert_Y42B_Y444 (VideoConvert * convert, GstVideoFrame * dest,
1046 const GstVideoFrame * src)
1048 gint width = convert->width;
1049 gint height = convert->height;
1051 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
1052 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1053 FRAME_GET_Y_STRIDE (src), width, height);
1055 video_convert_orc_planar_chroma_422_444 (FRAME_GET_U_LINE (dest, 0),
1056 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
1057 FRAME_GET_U_STRIDE (src), (width + 1) / 2, height);
1059 video_convert_orc_planar_chroma_422_444 (FRAME_GET_V_LINE (dest, 0),
1060 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
1061 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
1065 convert_Y42B_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
1066 const GstVideoFrame * src)
1068 gint width = convert->width;
1069 gint height = convert->height;
1071 video_convert_orc_convert_Y42B_YUY2 (FRAME_GET_LINE (dest, 0),
1072 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1073 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1074 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1075 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
1079 convert_Y42B_UYVY (VideoConvert * convert, GstVideoFrame * dest,
1080 const GstVideoFrame * src)
1082 gint width = convert->width;
1083 gint height = convert->height;
1085 video_convert_orc_convert_Y42B_UYVY (FRAME_GET_LINE (dest, 0),
1086 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1087 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1088 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1089 FRAME_GET_V_STRIDE (src), (width + 1) / 2, height);
1093 convert_Y42B_AYUV (VideoConvert * convert, GstVideoFrame * dest,
1094 const GstVideoFrame * src)
1096 gint width = convert->width;
1097 gint height = convert->height;
1099 /* only for even width */
1100 video_convert_orc_convert_Y42B_AYUV (FRAME_GET_LINE (dest, 0),
1101 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1102 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1103 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1104 FRAME_GET_V_STRIDE (src), width / 2, height);
1108 convert_Y444_I420 (VideoConvert * convert, GstVideoFrame * dest,
1109 const GstVideoFrame * src)
1111 gint width = convert->width;
1112 gint height = convert->height;
1114 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
1115 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1116 FRAME_GET_Y_STRIDE (src), width, height);
1118 video_convert_orc_planar_chroma_444_420 (FRAME_GET_U_LINE (dest, 0),
1119 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
1120 2 * FRAME_GET_U_STRIDE (src), FRAME_GET_U_LINE (src, 1),
1121 2 * FRAME_GET_U_STRIDE (src), width / 2, height / 2);
1123 video_convert_orc_planar_chroma_444_420 (FRAME_GET_V_LINE (dest, 0),
1124 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
1125 2 * FRAME_GET_V_STRIDE (src), FRAME_GET_V_LINE (src, 1),
1126 2 * FRAME_GET_V_STRIDE (src), width / 2, height / 2);
1128 /* now handle last line */
1130 UNPACK_FRAME (src, convert->tmplines[0], height - 1, width);
1131 PACK_FRAME (dest, convert->tmplines[0], height - 1, width);
1136 convert_Y444_Y42B (VideoConvert * convert, GstVideoFrame * dest,
1137 const GstVideoFrame * src)
1139 gint width = convert->width;
1140 gint height = convert->height;
1142 video_convert_orc_memcpy_2d (FRAME_GET_Y_LINE (dest, 0),
1143 FRAME_GET_Y_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1144 FRAME_GET_Y_STRIDE (src), width, height);
1146 video_convert_orc_planar_chroma_444_422 (FRAME_GET_U_LINE (dest, 0),
1147 FRAME_GET_U_STRIDE (dest), FRAME_GET_U_LINE (src, 0),
1148 FRAME_GET_U_STRIDE (src), width / 2, height);
1150 video_convert_orc_planar_chroma_444_422 (FRAME_GET_V_LINE (dest, 0),
1151 FRAME_GET_V_STRIDE (dest), FRAME_GET_V_LINE (src, 0),
1152 FRAME_GET_V_STRIDE (src), width / 2, height);
1156 convert_Y444_YUY2 (VideoConvert * convert, GstVideoFrame * dest,
1157 const GstVideoFrame * src)
1159 gint width = convert->width;
1160 gint height = convert->height;
1162 video_convert_orc_convert_Y444_YUY2 (FRAME_GET_LINE (dest, 0),
1163 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1164 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1165 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1166 FRAME_GET_V_STRIDE (src), width / 2, height);
1170 convert_Y444_UYVY (VideoConvert * convert, GstVideoFrame * dest,
1171 const GstVideoFrame * src)
1173 gint width = convert->width;
1174 gint height = convert->height;
1176 video_convert_orc_convert_Y444_UYVY (FRAME_GET_LINE (dest, 0),
1177 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1178 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1179 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1180 FRAME_GET_V_STRIDE (src), width / 2, height);
1184 convert_Y444_AYUV (VideoConvert * convert, GstVideoFrame * dest,
1185 const GstVideoFrame * src)
1187 gint width = convert->width;
1188 gint height = convert->height;
1190 video_convert_orc_convert_Y444_AYUV (FRAME_GET_LINE (dest, 0),
1191 FRAME_GET_STRIDE (dest), FRAME_GET_Y_LINE (src, 0),
1192 FRAME_GET_Y_STRIDE (src), FRAME_GET_U_LINE (src, 0),
1193 FRAME_GET_U_STRIDE (src), FRAME_GET_V_LINE (src, 0),
1194 FRAME_GET_V_STRIDE (src), width, height);
1197 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1199 convert_AYUV_ARGB (VideoConvert * convert, GstVideoFrame * dest,
1200 const GstVideoFrame * src)
1202 gint width = convert->width;
1203 gint height = convert->height;
1205 video_convert_orc_convert_AYUV_ARGB (FRAME_GET_LINE (dest, 0),
1206 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1207 FRAME_GET_STRIDE (src), convert->cmatrix[0][0], convert->cmatrix[0][2],
1208 convert->cmatrix[2][1], convert->cmatrix[1][1], convert->cmatrix[1][2],
1213 convert_AYUV_BGRA (VideoConvert * convert, GstVideoFrame * dest,
1214 const GstVideoFrame * src)
1216 gint width = convert->width;
1217 gint height = convert->height;
1219 video_convert_orc_convert_AYUV_BGRA (FRAME_GET_LINE (dest, 0),
1220 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1221 FRAME_GET_STRIDE (src), convert->cmatrix[0][0], convert->cmatrix[0][2],
1222 convert->cmatrix[2][1], convert->cmatrix[1][1], convert->cmatrix[1][2],
1227 convert_AYUV_ABGR (VideoConvert * convert, GstVideoFrame * dest,
1228 const GstVideoFrame * src)
1230 gint width = convert->width;
1231 gint height = convert->height;
1233 video_convert_orc_convert_AYUV_ABGR (FRAME_GET_LINE (dest, 0),
1234 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1235 FRAME_GET_STRIDE (src), convert->cmatrix[0][0], convert->cmatrix[0][2],
1236 convert->cmatrix[2][1], convert->cmatrix[1][1], convert->cmatrix[1][2],
1241 convert_AYUV_RGBA (VideoConvert * convert, GstVideoFrame * dest,
1242 const GstVideoFrame * src)
1244 gint width = convert->width;
1245 gint height = convert->height;
1247 video_convert_orc_convert_AYUV_RGBA (FRAME_GET_LINE (dest, 0),
1248 FRAME_GET_STRIDE (dest), FRAME_GET_LINE (src, 0),
1249 FRAME_GET_STRIDE (src), convert->cmatrix[0][0], convert->cmatrix[0][2],
1250 convert->cmatrix[2][1], convert->cmatrix[1][1], convert->cmatrix[1][2],
1255 convert_I420_BGRA (VideoConvert * convert, GstVideoFrame * dest,
1256 const GstVideoFrame * src)
1259 gint width = convert->width;
1260 gint height = convert->height;
1262 for (i = 0; i < height; i++) {
1263 video_convert_orc_convert_I420_BGRA (FRAME_GET_LINE (dest, i),
1264 FRAME_GET_Y_LINE (src, i),
1265 FRAME_GET_U_LINE (src, i >> 1), FRAME_GET_V_LINE (src, i >> 1),
1266 convert->cmatrix[0][0], convert->cmatrix[0][2],
1267 convert->cmatrix[2][1], convert->cmatrix[1][1], convert->cmatrix[1][2],
1279 GstVideoFormat in_format;
1280 GstVideoColorMatrix in_matrix;
1281 GstVideoFormat out_format;
1282 GstVideoColorMatrix out_matrix;
1283 gboolean keeps_color_matrix;
1284 gboolean keeps_interlaced;
1285 gboolean needs_color_matrix;
1286 gint width_align, height_align;
1287 void (*convert) (VideoConvert * convert, GstVideoFrame * dest,
1288 const GstVideoFrame * src);
1291 static const VideoTransform transforms[] = {
1292 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1293 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1295 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1296 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1298 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1299 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1301 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1302 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 0, 0,
1304 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1305 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 0, 0,
1308 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1309 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1311 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1312 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1314 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1315 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1317 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1318 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 0, 0,
1320 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1321 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 0, 0,
1324 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1325 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1327 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YV12,
1328 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1330 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1331 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0, convert_UYVY_YUY2}, /* alias */
1332 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1333 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1335 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1336 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1338 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1339 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1342 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1343 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1345 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YV12,
1346 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1348 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1349 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1351 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1352 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1354 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1355 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1357 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1358 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1361 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1362 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 1, 1,
1364 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YV12,
1365 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 1, 1,
1367 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1368 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1370 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1371 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1373 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1374 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1376 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1377 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1380 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1381 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 0, 0,
1383 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YV12,
1384 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 0, 0,
1386 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1387 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1389 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1390 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1392 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1393 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1395 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y444,
1396 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1399 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_I420,
1400 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 1, 0,
1402 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YV12,
1403 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, FALSE, 1, 0,
1405 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_YUY2,
1406 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1408 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_UYVY,
1409 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1411 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_AYUV,
1412 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 0, 0,
1414 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_Y42B,
1415 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, FALSE, 1, 0,
1418 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1419 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_ARGB,
1420 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0,
1422 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_BGRA,
1423 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0,
1425 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_xRGB,
1426 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0, convert_AYUV_ARGB}, /* alias */
1427 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_BGRx,
1428 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0, convert_AYUV_BGRA}, /* alias */
1429 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_ABGR,
1430 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0,
1432 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_RGBA,
1433 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0,
1435 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_xBGR,
1436 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0, convert_AYUV_ABGR}, /* alias */
1437 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_RGBx,
1438 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, TRUE, TRUE, 0, 0, convert_AYUV_RGBA}, /* alias */
1440 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_BGRA,
1441 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, TRUE, 0, 0,
1443 {GST_VIDEO_FORMAT_I420, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_BGRx,
1444 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, TRUE, 0, 0,
1446 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_BGRA,
1447 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, TRUE, 0, 0,
1449 {GST_VIDEO_FORMAT_YV12, GST_VIDEO_COLOR_MATRIX_UNKNOWN, GST_VIDEO_FORMAT_BGRx,
1450 GST_VIDEO_COLOR_MATRIX_UNKNOWN, TRUE, FALSE, TRUE, 0, 0,
1456 videoconvert_convert_lookup_fastpath (VideoConvert * convert)
1459 GstVideoFormat in_format, out_format;
1460 GstVideoColorMatrix in_matrix, out_matrix;
1461 gboolean interlaced;
1464 in_format = GST_VIDEO_INFO_FORMAT (&convert->in_info);
1465 out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info);
1467 width = GST_VIDEO_INFO_WIDTH (&convert->in_info);
1468 height = GST_VIDEO_INFO_HEIGHT (&convert->in_info);
1470 in_matrix = convert->in_info.colorimetry.matrix;
1471 out_matrix = convert->out_info.colorimetry.matrix;
1473 interlaced = GST_VIDEO_INFO_IS_INTERLACED (&convert->in_info);
1474 interlaced |= GST_VIDEO_INFO_IS_INTERLACED (&convert->out_info);
1476 for (i = 0; i < sizeof (transforms) / sizeof (transforms[0]); i++) {
1477 if (transforms[i].in_format == in_format &&
1478 transforms[i].out_format == out_format &&
1479 (transforms[i].keeps_color_matrix ||
1480 (transforms[i].in_matrix == in_matrix &&
1481 transforms[i].out_matrix == out_matrix)) &&
1482 (transforms[i].keeps_interlaced || !interlaced) &&
1483 (transforms[i].width_align & width) == 0 &&
1484 (transforms[i].height_align & height) == 0) {
1485 GST_DEBUG ("using fastpath");
1486 if (transforms[i].needs_color_matrix)
1487 if (!videoconvert_convert_compute_matrix (convert))
1489 convert->convert = transforms[i].convert;
1490 alloc_tmplines (convert, 1, GST_VIDEO_INFO_WIDTH (&convert->in_info));
1494 GST_DEBUG ("no fastpath found");
1499 GST_DEBUG ("can't create matrix");