2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2003> David Schleef <ds@schleef.org>
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., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * This file was (probably) generated from
23 * gstvideotemplate.c,v 1.18 2005/11/14 02:13:34 thomasvs Exp
25 * $Id: make_filter,v 1.8 2004/04/19 22:51:57 ds Exp $
33 #include <gst/base/gstbasetransform.h>
34 #include <gst/video/video.h>
38 #include <cog/cogvirtframe.h>
39 #include "gstcogutils.h"
40 #include "gstcogorc.h"
42 #define GST_TYPE_COGCOLORSPACE \
43 (gst_cogcolorspace_get_type())
44 #define GST_COGCOLORSPACE(obj) \
45 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_COGCOLORSPACE,GstCogcolorspace))
46 #define GST_COGCOLORSPACE_CLASS(klass) \
47 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_COGCOLORSPACE,GstCogcolorspaceClass))
48 #define GST_IS_COGCOLORSPACE(obj) \
49 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_COGCOLORSPACE))
50 #define GST_IS_COGCOLORSPACE_CLASS(obj) \
51 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_COGCOLORSPACE))
53 typedef struct _GstCogcolorspace GstCogcolorspace;
54 typedef struct _GstCogcolorspaceClass GstCogcolorspaceClass;
56 struct _GstCogcolorspace
58 GstBaseTransform base_transform;
63 struct _GstCogcolorspaceClass
65 GstBaseTransformClass parent_class;
69 GType gst_cogcolorspace_get_type (void);
71 /* GstCogcolorspace signals and args */
78 #define DEFAULT_QUALITY 5
86 static void gst_cogcolorspace_set_property (GObject * object, guint prop_id,
87 const GValue * value, GParamSpec * pspec);
88 static void gst_cogcolorspace_get_property (GObject * object, guint prop_id,
89 GValue * value, GParamSpec * pspec);
91 static GstCaps *gst_cogcolorspace_transform_caps (GstBaseTransform *
92 base_transform, GstPadDirection direction, GstCaps * caps);
93 static GstFlowReturn gst_cogcolorspace_transform (GstBaseTransform *
94 base_transform, GstBuffer * inbuf, GstBuffer * outbuf);
95 static gboolean gst_cogcolorspace_get_unit_size (GstBaseTransform *
96 base_transform, GstCaps * caps, guint * size);
98 static GstStaticPadTemplate gst_cogcolorspace_sink_template =
99 GST_STATIC_PAD_TEMPLATE ("sink",
102 GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV
103 ("{ I420, YV12, YUY2, UYVY, AYUV, Y42B, Y444, v216, v210 }")
104 ";" GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_xRGB
105 ";" GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_BGRA
106 ";" GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_ABGR)
109 static GstStaticPadTemplate gst_cogcolorspace_src_template =
110 GST_STATIC_PAD_TEMPLATE ("src",
113 GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV
114 ("{ I420, YV12, YUY2, UYVY, AYUV, Y42B, Y444, v216, v210 }")
115 ";" GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_xRGB
116 ";" GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_BGRA
117 ";" GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_ABGR)
120 GST_BOILERPLATE (GstCogcolorspace, gst_cogcolorspace, GstBaseTransform,
121 GST_TYPE_BASE_TRANSFORM);
124 gst_cogcolorspace_base_init (gpointer g_class)
127 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
129 gst_element_class_add_static_pad_template (element_class,
130 &gst_cogcolorspace_src_template);
131 gst_element_class_add_static_pad_template (element_class,
132 &gst_cogcolorspace_sink_template);
134 gst_element_class_set_details_simple (element_class,
135 "YCbCr/RGB format conversion", "Filter/Converter/Video",
136 "YCbCr/RGB format conversion", "David Schleef <ds@schleef.org>");
140 gst_cogcolorspace_class_init (GstCogcolorspaceClass * colorspace_class)
142 GObjectClass *gobject_class;
143 GstBaseTransformClass *base_transform_class;
145 gobject_class = G_OBJECT_CLASS (colorspace_class);
146 base_transform_class = GST_BASE_TRANSFORM_CLASS (colorspace_class);
148 gobject_class->set_property = gst_cogcolorspace_set_property;
149 gobject_class->get_property = gst_cogcolorspace_get_property;
151 g_object_class_install_property (gobject_class, PROP_QUALITY,
152 g_param_spec_int ("quality", "Quality", "Quality",
153 0, 10, DEFAULT_QUALITY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
155 base_transform_class->transform = gst_cogcolorspace_transform;
156 base_transform_class->transform_caps = gst_cogcolorspace_transform_caps;
157 base_transform_class->get_unit_size = gst_cogcolorspace_get_unit_size;
159 base_transform_class->passthrough_on_same_caps = TRUE;
163 gst_cogcolorspace_init (GstCogcolorspace * colorspace,
164 GstCogcolorspaceClass * klass)
166 GST_DEBUG ("gst_cogcolorspace_init");
168 colorspace->quality = DEFAULT_QUALITY;
172 gst_cogcolorspace_set_property (GObject * object, guint prop_id,
173 const GValue * value, GParamSpec * pspec)
175 GstCogcolorspace *colorspace;
177 g_return_if_fail (GST_IS_COGCOLORSPACE (object));
178 colorspace = GST_COGCOLORSPACE (object);
180 GST_DEBUG ("gst_cogcolorspace_set_property");
183 GST_OBJECT_LOCK (colorspace);
184 colorspace->quality = g_value_get_int (value);
185 GST_OBJECT_UNLOCK (colorspace);
193 gst_cogcolorspace_get_property (GObject * object, guint prop_id, GValue * value,
196 GstCogcolorspace *colorspace;
198 g_return_if_fail (GST_IS_COGCOLORSPACE (object));
199 colorspace = GST_COGCOLORSPACE (object);
203 GST_OBJECT_LOCK (colorspace);
204 g_value_set_int (value, colorspace->quality);
205 GST_OBJECT_UNLOCK (colorspace);
208 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
215 transform_value (GValue * dest)
217 GValue fourcc = { 0 };
219 g_value_init (dest, GST_TYPE_LIST);
220 g_value_init (&fourcc, GST_TYPE_FOURCC);
222 gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('I', '4', '2', '0'));
223 gst_value_list_append_value (dest, &fourcc);
225 gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('Y', 'V', '1', '2'));
226 gst_value_list_append_value (dest, &fourcc);
228 gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'));
229 gst_value_list_append_value (dest, &fourcc);
231 gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'));
232 gst_value_list_append_value (dest, &fourcc);
234 gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'));
235 gst_value_list_append_value (dest, &fourcc);
237 gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('Y', '4', '2', 'B'));
238 gst_value_list_append_value (dest, &fourcc);
240 gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('Y', '4', '4', '4'));
241 gst_value_list_append_value (dest, &fourcc);
243 gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('v', '2', '1', '0'));
244 gst_value_list_append_value (dest, &fourcc);
246 gst_value_set_fourcc (&fourcc, GST_MAKE_FOURCC ('v', '2', '1', '6'));
247 gst_value_list_append_value (dest, &fourcc);
249 g_value_unset (&fourcc);
254 gst_cogcolorspace_caps_remove_format_info (GstCaps * caps)
257 GstStructure *structure;
260 caps = gst_caps_copy (caps);
262 for (i = 0; i < gst_caps_get_size (caps); i++) {
263 structure = gst_caps_get_structure (caps, i);
265 gst_structure_set_name (structure, "video/x-raw-yuv");
266 gst_structure_remove_field (structure, "format");
267 gst_structure_remove_field (structure, "endianness");
268 gst_structure_remove_field (structure, "depth");
269 gst_structure_remove_field (structure, "bpp");
270 gst_structure_remove_field (structure, "red_mask");
271 gst_structure_remove_field (structure, "green_mask");
272 gst_structure_remove_field (structure, "blue_mask");
273 gst_structure_remove_field (structure, "alpha_mask");
274 gst_structure_remove_field (structure, "palette_data");
275 gst_structure_remove_field (structure, "color-matrix");
276 gst_structure_remove_field (structure, "chroma-site");
279 gst_caps_do_simplify (caps);
280 rgbcaps = gst_caps_copy (caps);
282 for (i = 0; i < gst_caps_get_size (rgbcaps); i++) {
283 structure = gst_caps_get_structure (rgbcaps, i);
285 gst_structure_set_name (structure, "video/x-raw-rgb");
288 gst_caps_append (caps, rgbcaps);
294 gst_cogcolorspace_transform_caps (GstBaseTransform * base_transform,
295 GstPadDirection direction, GstCaps * caps)
299 GstStructure *structure;
300 GValue new_value = { 0 };
303 caps = gst_caps_copy (caps);
305 for (i = 0; i < gst_caps_get_size (caps); i++) {
306 structure = gst_caps_get_structure (caps, i);
308 value = gst_structure_get_value (structure, "format");
309 transform_value (&new_value);
310 gst_structure_set_value (structure, "format", &new_value);
311 g_value_unset (&new_value);
320 template = gst_ffmpegcsp_codectype_to_caps (CODEC_TYPE_VIDEO, NULL);
321 result = gst_caps_intersect (caps, template);
322 gst_caps_unref (template);
324 gst_caps_append (result, gst_ffmpegcsp_caps_remove_format_info (caps));
328 return gst_cogcolorspace_caps_remove_format_info (caps);
332 gst_cogcolorspace_get_unit_size (GstBaseTransform * base_transform,
333 GstCaps * caps, guint * size)
336 GstVideoFormat format;
339 ret = gst_video_format_parse_caps (caps, &format, &width, &height);
343 *size = gst_video_format_get_size (format, width, height);
348 static CogColorMatrix
349 gst_cogcolorspace_caps_get_color_matrix (GstCaps * caps)
353 s = gst_video_parse_caps_color_matrix (caps);
356 return COG_COLOR_MATRIX_SDTV;
358 if (strcmp (s, "sdtv") == 0) {
359 return COG_COLOR_MATRIX_SDTV;
360 } else if (strcmp (s, "hdtv") == 0) {
361 return COG_COLOR_MATRIX_HDTV;
364 return COG_COLOR_MATRIX_SDTV;
368 gst_cogcolorspace_caps_get_chroma_site (GstCaps * caps)
372 s = gst_video_parse_caps_chroma_site (caps);
375 return COG_COLOR_MATRIX_SDTV;
377 if (strcmp (s, "jpeg") == 0) {
378 return COG_CHROMA_SITE_JPEG;
379 } else if (strcmp (s, "mpeg2") == 0) {
380 return COG_CHROMA_SITE_MPEG2;
383 return COG_CHROMA_SITE_MPEG2;
387 convert_I420_YUY2 (CogFrame * dest, CogFrame * src)
391 for (i = 0; i < dest->height; i += 2) {
392 cogorc_convert_I420_YUY2 (COG_FRAME_DATA_GET_LINE (dest->components + 0, i),
393 COG_FRAME_DATA_GET_LINE (dest->components + 0, i + 1),
394 COG_FRAME_DATA_GET_LINE (src->components + 0, i),
395 COG_FRAME_DATA_GET_LINE (src->components + 0, i + 1),
396 COG_FRAME_DATA_GET_LINE (src->components + 1, i >> 1),
397 COG_FRAME_DATA_GET_LINE (src->components + 2, i >> 1),
398 (dest->width + 1) / 2);
403 convert_I420_UYVY (CogFrame * dest, CogFrame * src)
407 for (i = 0; i < dest->height; i += 2) {
408 cogorc_convert_I420_UYVY (COG_FRAME_DATA_GET_LINE (dest->components + 0, i),
409 COG_FRAME_DATA_GET_LINE (dest->components + 0, i + 1),
410 COG_FRAME_DATA_GET_LINE (src->components + 0, i),
411 COG_FRAME_DATA_GET_LINE (src->components + 0, i + 1),
412 COG_FRAME_DATA_GET_LINE (src->components + 1, i >> 1),
413 COG_FRAME_DATA_GET_LINE (src->components + 2, i >> 1),
414 (dest->width + 1) / 2);
419 convert_I420_AYUV (CogFrame * dest, CogFrame * src)
423 for (i = 0; i < dest->height; i += 2) {
424 cogorc_convert_I420_AYUV (COG_FRAME_DATA_GET_LINE (dest->components + 0, i),
425 COG_FRAME_DATA_GET_LINE (dest->components + 0, i + 1),
426 COG_FRAME_DATA_GET_LINE (src->components + 0, i),
427 COG_FRAME_DATA_GET_LINE (src->components + 0, i + 1),
428 COG_FRAME_DATA_GET_LINE (src->components + 1, i >> 1),
429 COG_FRAME_DATA_GET_LINE (src->components + 2, i >> 1), dest->width);
434 convert_I420_Y42B (CogFrame * dest, CogFrame * src)
436 cogorc_memcpy_2d (dest->components[0].data, dest->components[0].stride,
437 src->components[0].data, src->components[0].stride,
438 dest->width, dest->height);
440 cogorc_planar_chroma_420_422 (dest->components[1].data,
441 2 * dest->components[1].stride,
442 COG_FRAME_DATA_GET_LINE (dest->components + 2, 1),
443 2 * dest->components[1].stride, src->components[1].data,
444 src->components[1].stride, (dest->width + 1) / 2, dest->height / 2);
446 cogorc_planar_chroma_420_422 (dest->components[2].data,
447 2 * dest->components[2].stride,
448 COG_FRAME_DATA_GET_LINE (dest->components + 2, 1),
449 2 * dest->components[2].stride, src->components[2].data,
450 src->components[2].stride, (dest->width + 1) / 2, dest->height / 2);
454 convert_I420_Y444 (CogFrame * dest, CogFrame * src)
456 cogorc_memcpy_2d (dest->components[0].data, dest->components[0].stride,
457 src->components[0].data, src->components[0].stride,
458 dest->width, dest->height);
460 cogorc_planar_chroma_420_444 (dest->components[1].data,
461 2 * dest->components[1].stride,
462 COG_FRAME_DATA_GET_LINE (dest->components + 1, 1),
463 2 * dest->components[1].stride, src->components[1].data,
464 src->components[1].stride, (dest->width + 1) / 2, (dest->height + 1) / 2);
466 cogorc_planar_chroma_420_444 (dest->components[2].data,
467 2 * dest->components[2].stride,
468 COG_FRAME_DATA_GET_LINE (dest->components + 2, 1),
469 2 * dest->components[2].stride, src->components[2].data,
470 src->components[2].stride, (dest->width + 1) / 2, (dest->height + 1) / 2);
474 convert_YUY2_I420 (CogFrame * dest, CogFrame * src)
478 for (i = 0; i < dest->height; i += 2) {
479 cogorc_convert_YUY2_I420 (COG_FRAME_DATA_GET_LINE (dest->components + 0, i),
480 COG_FRAME_DATA_GET_LINE (dest->components + 0, i + 1),
481 COG_FRAME_DATA_GET_LINE (dest->components + 1, i >> 1),
482 COG_FRAME_DATA_GET_LINE (dest->components + 2, i >> 1),
483 COG_FRAME_DATA_GET_LINE (src->components + 0, i),
484 COG_FRAME_DATA_GET_LINE (src->components + 0, i + 1),
485 (dest->width + 1) / 2);
490 convert_YUY2_AYUV (CogFrame * dest, CogFrame * src)
492 cogorc_convert_YUY2_AYUV (dest->components[0].data,
493 dest->components[0].stride, src->components[0].data,
494 src->components[0].stride, (dest->width + 1) / 2, dest->height);
498 convert_YUY2_Y42B (CogFrame * dest, CogFrame * src)
500 cogorc_convert_YUY2_Y42B (dest->components[0].data,
501 dest->components[0].stride, dest->components[1].data,
502 dest->components[1].stride, dest->components[2].data,
503 dest->components[2].stride, src->components[0].data,
504 src->components[0].stride, (dest->width + 1) / 2, dest->height);
508 convert_YUY2_Y444 (CogFrame * dest, CogFrame * src)
510 cogorc_convert_YUY2_Y444 (dest->components[0].data,
511 dest->components[0].stride, dest->components[1].data,
512 dest->components[1].stride, dest->components[2].data,
513 dest->components[2].stride, src->components[0].data,
514 src->components[0].stride, (dest->width + 1) / 2, dest->height);
519 convert_UYVY_I420 (CogFrame * dest, CogFrame * src)
523 for (i = 0; i < dest->height; i += 2) {
524 cogorc_convert_UYVY_I420 (COG_FRAME_DATA_GET_LINE (dest->components + 0, i),
525 COG_FRAME_DATA_GET_LINE (dest->components + 0, i + 1),
526 COG_FRAME_DATA_GET_LINE (dest->components + 1, i >> 1),
527 COG_FRAME_DATA_GET_LINE (dest->components + 2, i >> 1),
528 COG_FRAME_DATA_GET_LINE (src->components + 0, i),
529 COG_FRAME_DATA_GET_LINE (src->components + 0, i + 1),
530 (dest->width + 1) / 2);
535 convert_UYVY_AYUV (CogFrame * dest, CogFrame * src)
537 cogorc_convert_UYVY_AYUV (dest->components[0].data,
538 dest->components[0].stride, src->components[0].data,
539 src->components[0].stride, (dest->width + 1) / 2, dest->height);
543 convert_UYVY_YUY2 (CogFrame * dest, CogFrame * src)
545 cogorc_convert_UYVY_YUY2 (dest->components[0].data,
546 dest->components[0].stride, src->components[0].data,
547 src->components[0].stride, (dest->width + 1) / 2, dest->height);
551 convert_UYVY_Y42B (CogFrame * dest, CogFrame * src)
553 cogorc_convert_UYVY_Y42B (dest->components[0].data,
554 dest->components[0].stride, dest->components[1].data,
555 dest->components[1].stride, dest->components[2].data,
556 dest->components[2].stride, src->components[0].data,
557 src->components[0].stride, (dest->width + 1) / 2, dest->height);
561 convert_UYVY_Y444 (CogFrame * dest, CogFrame * src)
563 cogorc_convert_UYVY_Y444 (dest->components[0].data,
564 dest->components[0].stride, dest->components[1].data,
565 dest->components[1].stride, dest->components[2].data,
566 dest->components[2].stride, src->components[0].data,
567 src->components[0].stride, (dest->width + 1) / 2, dest->height);
571 convert_AYUV_I420 (CogFrame * dest, CogFrame * src)
573 cogorc_convert_AYUV_I420 (COG_FRAME_DATA_GET_LINE (dest->components + 0, 0),
574 2 * dest->components[0].stride,
575 COG_FRAME_DATA_GET_LINE (dest->components + 0, 1),
576 2 * dest->components[0].stride,
577 dest->components[1].data, dest->components[1].stride,
578 dest->components[2].data, dest->components[2].stride,
579 COG_FRAME_DATA_GET_LINE (src->components + 0, 0),
580 /* FIXME why not 2* ? */
581 src->components[0].stride,
582 COG_FRAME_DATA_GET_LINE (src->components + 0, 1),
583 src->components[0].stride, dest->width / 2, dest->height / 2);
587 convert_AYUV_YUY2 (CogFrame * dest, CogFrame * src)
589 cogorc_convert_AYUV_YUY2 (dest->components[0].data,
590 dest->components[0].stride, src->components[0].data,
591 src->components[0].stride, dest->width / 2, dest->height);
595 convert_AYUV_UYVY (CogFrame * dest, CogFrame * src)
597 cogorc_convert_AYUV_UYVY (dest->components[0].data,
598 dest->components[0].stride, src->components[0].data,
599 src->components[0].stride, dest->width / 2, dest->height);
603 convert_AYUV_Y42B (CogFrame * dest, CogFrame * src)
605 cogorc_convert_AYUV_Y42B (dest->components[0].data,
606 dest->components[0].stride, dest->components[1].data,
607 dest->components[1].stride, dest->components[2].data,
608 dest->components[2].stride, src->components[0].data,
609 src->components[0].stride, (dest->width + 1) / 2, dest->height);
613 convert_AYUV_Y444 (CogFrame * dest, CogFrame * src)
615 cogorc_convert_AYUV_Y444 (dest->components[0].data,
616 dest->components[0].stride, dest->components[1].data,
617 dest->components[1].stride, dest->components[2].data,
618 dest->components[2].stride, src->components[0].data,
619 src->components[0].stride, dest->width, dest->height);
623 convert_Y42B_I420 (CogFrame * dest, CogFrame * src)
625 cogorc_memcpy_2d (dest->components[0].data, dest->components[0].stride,
626 src->components[0].data, src->components[0].stride,
627 dest->width, dest->height);
629 cogorc_planar_chroma_422_420 (dest->components[1].data,
630 dest->components[1].stride, src->components[1].data,
631 2 * src->components[1].stride,
632 COG_FRAME_DATA_GET_LINE (src->components + 1, 1),
633 2 * src->components[1].stride, (dest->width + 1) / 2,
634 (dest->height + 1) / 2);
636 cogorc_planar_chroma_422_420 (dest->components[2].data,
637 dest->components[2].stride, src->components[2].data,
638 2 * src->components[2].stride,
639 COG_FRAME_DATA_GET_LINE (src->components + 2, 1),
640 2 * src->components[2].stride, (dest->width + 1) / 2,
641 (dest->height + 1) / 2);
645 convert_Y42B_Y444 (CogFrame * dest, CogFrame * src)
647 cogorc_memcpy_2d (dest->components[0].data, dest->components[0].stride,
648 src->components[0].data, src->components[0].stride,
649 dest->width, dest->height);
651 cogorc_planar_chroma_422_444 (dest->components[1].data,
652 dest->components[1].stride, src->components[1].data,
653 src->components[1].stride, (dest->width + 1) / 2, dest->height);
655 cogorc_planar_chroma_422_444 (dest->components[2].data,
656 dest->components[2].stride, src->components[2].data,
657 src->components[2].stride, (dest->width + 1) / 2, dest->height);
661 convert_Y42B_YUY2 (CogFrame * dest, CogFrame * src)
663 cogorc_convert_Y42B_YUY2 (dest->components[0].data,
664 dest->components[0].stride, src->components[0].data,
665 src->components[0].stride, src->components[1].data,
666 src->components[1].stride, src->components[2].data,
667 src->components[2].stride, (dest->width + 1) / 2, dest->height);
671 convert_Y42B_UYVY (CogFrame * dest, CogFrame * src)
673 cogorc_convert_Y42B_UYVY (dest->components[0].data,
674 dest->components[0].stride, src->components[0].data,
675 src->components[0].stride, src->components[1].data,
676 src->components[1].stride, src->components[2].data,
677 src->components[2].stride, (dest->width + 1) / 2, dest->height);
681 convert_Y42B_AYUV (CogFrame * dest, CogFrame * src)
683 cogorc_convert_Y42B_AYUV (dest->components[0].data,
684 dest->components[0].stride, src->components[0].data,
685 src->components[0].stride, src->components[1].data,
686 src->components[1].stride, src->components[2].data,
687 src->components[2].stride, (dest->width) / 2, dest->height);
691 convert_Y444_I420 (CogFrame * dest, CogFrame * src)
693 cogorc_memcpy_2d (dest->components[0].data, dest->components[0].stride,
694 src->components[0].data, src->components[0].stride,
695 dest->width, dest->height);
697 cogorc_planar_chroma_444_420 (dest->components[1].data,
698 dest->components[1].stride, src->components[1].data,
699 2 * src->components[1].stride,
700 COG_FRAME_DATA_GET_LINE (src->components + 1, 1),
701 2 * src->components[1].stride, (dest->width + 1) / 2,
702 (dest->height + 1) / 2);
704 cogorc_planar_chroma_444_420 (dest->components[2].data,
705 dest->components[2].stride, src->components[2].data,
706 2 * src->components[2].stride,
707 COG_FRAME_DATA_GET_LINE (src->components + 2, 1),
708 2 * src->components[2].stride, (dest->width + 1) / 2,
709 (dest->height + 1) / 2);
713 convert_Y444_Y42B (CogFrame * dest, CogFrame * src)
715 cogorc_memcpy_2d (dest->components[0].data, dest->components[0].stride,
716 src->components[0].data, src->components[0].stride,
717 dest->width, dest->height);
719 cogorc_planar_chroma_444_422 (dest->components[1].data,
720 dest->components[1].stride, src->components[1].data,
721 src->components[1].stride, (dest->width + 1) / 2, dest->height);
723 cogorc_planar_chroma_444_422 (dest->components[2].data,
724 dest->components[2].stride, src->components[2].data,
725 src->components[2].stride, (dest->width + 1) / 2, dest->height);
729 convert_Y444_YUY2 (CogFrame * dest, CogFrame * src)
731 cogorc_convert_Y444_YUY2 (dest->components[0].data,
732 dest->components[0].stride, src->components[0].data,
733 src->components[0].stride, src->components[1].data,
734 src->components[1].stride, src->components[2].data,
735 src->components[2].stride, (dest->width + 1) / 2, dest->height);
739 convert_Y444_UYVY (CogFrame * dest, CogFrame * src)
741 cogorc_convert_Y444_UYVY (dest->components[0].data,
742 dest->components[0].stride, src->components[0].data,
743 src->components[0].stride, src->components[1].data,
744 src->components[1].stride, src->components[2].data,
745 src->components[2].stride, (dest->width + 1) / 2, dest->height);
749 convert_Y444_AYUV (CogFrame * dest, CogFrame * src)
751 cogorc_convert_Y444_AYUV (dest->components[0].data,
752 dest->components[0].stride, src->components[0].data,
753 src->components[0].stride, src->components[1].data,
754 src->components[1].stride, src->components[2].data,
755 src->components[2].stride, dest->width, dest->height);
759 convert_AYUV_ARGB (CogFrame * dest, CogFrame * src)
761 cogorc_convert_AYUV_ARGB (dest->components[0].data,
762 dest->components[0].stride, src->components[0].data,
763 src->components[0].stride, dest->width, dest->height);
767 convert_AYUV_BGRA (CogFrame * dest, CogFrame * src)
769 cogorc_convert_AYUV_BGRA (dest->components[0].data,
770 dest->components[0].stride, src->components[0].data,
771 src->components[0].stride, dest->width, dest->height);
775 convert_AYUV_ABGR (CogFrame * dest, CogFrame * src)
777 cogorc_convert_AYUV_ABGR (dest->components[0].data,
778 dest->components[0].stride, src->components[0].data,
779 src->components[0].stride, dest->width, dest->height);
783 convert_AYUV_RGBA (CogFrame * dest, CogFrame * src)
785 cogorc_convert_AYUV_RGBA (dest->components[0].data,
786 dest->components[0].stride, src->components[0].data,
787 src->components[0].stride, dest->width, dest->height);
791 convert_I420_BGRA (CogFrame * dest, CogFrame * src)
797 for (i = 0; i < dest->height; i++) {
799 cogorc_convert_I420_BGRA_avg (COG_FRAME_DATA_GET_LINE (dest->components
800 + 0, i), COG_FRAME_DATA_GET_LINE (src->components + 0, i),
801 COG_FRAME_DATA_GET_LINE (src->components + 1, i >> 1),
802 COG_FRAME_DATA_GET_LINE (src->components + 1, (i >> 1) + 1),
803 COG_FRAME_DATA_GET_LINE (src->components + 2, i >> 1),
804 COG_FRAME_DATA_GET_LINE (src->components + 2, (i >> 1) + 1),
807 cogorc_convert_I420_BGRA (COG_FRAME_DATA_GET_LINE (dest->components + 0,
808 i), COG_FRAME_DATA_GET_LINE (src->components + 0, i),
809 COG_FRAME_DATA_GET_LINE (src->components + 1, i >> 1),
810 COG_FRAME_DATA_GET_LINE (src->components + 2, i >> 1), dest->width);
814 for (i = 0; i < dest->height; i++) {
815 cogorc_convert_I420_BGRA (COG_FRAME_DATA_GET_LINE (dest->components + 0,
816 i), COG_FRAME_DATA_GET_LINE (src->components + 0, i),
817 COG_FRAME_DATA_GET_LINE (src->components + 1, i >> 1),
818 COG_FRAME_DATA_GET_LINE (src->components + 2, i >> 1), dest->width);
831 void (*convert) (CogFrame * dest, CogFrame * src);
832 } CogColorspaceTransform;
833 static CogColorspaceTransform transforms[] = {
834 {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_YUY2, convert_I420_YUY2},
835 {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_UYVY, convert_I420_UYVY},
836 {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_AYUV, convert_I420_AYUV},
837 {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_Y42B, convert_I420_Y42B},
838 {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_Y444, convert_I420_Y444},
840 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_I420, convert_YUY2_I420},
841 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_UYVY, convert_UYVY_YUY2}, /* alias */
842 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_AYUV, convert_YUY2_AYUV},
843 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_Y42B, convert_YUY2_Y42B},
844 {GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_Y444, convert_YUY2_Y444},
846 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_I420, convert_UYVY_I420},
847 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_YUY2, convert_UYVY_YUY2},
848 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_AYUV, convert_UYVY_AYUV},
849 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_Y42B, convert_UYVY_Y42B},
850 {GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_Y444, convert_UYVY_Y444},
852 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_I420, convert_AYUV_I420},
853 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_YUY2, convert_AYUV_YUY2},
854 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_UYVY, convert_AYUV_UYVY},
855 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_Y42B, convert_AYUV_Y42B},
856 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_Y444, convert_AYUV_Y444},
858 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_I420, convert_Y42B_I420},
859 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_YUY2, convert_Y42B_YUY2},
860 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_UYVY, convert_Y42B_UYVY},
861 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_AYUV, convert_Y42B_AYUV},
862 {GST_VIDEO_FORMAT_Y42B, GST_VIDEO_FORMAT_Y444, convert_Y42B_Y444},
864 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_I420, convert_Y444_I420},
865 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_YUY2, convert_Y444_YUY2},
866 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_UYVY, convert_Y444_UYVY},
867 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_AYUV, convert_Y444_AYUV},
868 {GST_VIDEO_FORMAT_Y444, GST_VIDEO_FORMAT_Y42B, convert_Y444_Y42B},
870 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_ARGB, convert_AYUV_ARGB},
871 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_BGRA, convert_AYUV_BGRA},
872 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_xRGB, convert_AYUV_ARGB}, /* alias */
873 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_BGRx, convert_AYUV_BGRA}, /* alias */
874 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_ABGR, convert_AYUV_ABGR},
875 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_RGBA, convert_AYUV_RGBA},
876 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_xBGR, convert_AYUV_ABGR}, /* alias */
877 {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_RGBx, convert_AYUV_RGBA}, /* alias */
879 {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_BGRA, convert_I420_BGRA},
883 gst_cogcolorspace_transform (GstBaseTransform * base_transform,
884 GstBuffer * inbuf, GstBuffer * outbuf)
886 GstCogcolorspace *compress;
892 CogFrameFormat new_subsample;
894 CogColorMatrix in_color_matrix;
895 CogColorMatrix out_color_matrix;
896 CogChromaSite in_chroma_site;
897 CogChromaSite out_chroma_site;
899 g_return_val_if_fail (GST_IS_COGCOLORSPACE (base_transform), GST_FLOW_ERROR);
900 compress = GST_COGCOLORSPACE (base_transform);
902 ret = gst_video_format_parse_caps (inbuf->caps, &in_format, &width, &height);
904 gst_video_format_parse_caps (outbuf->caps, &out_format, &width, &height);
906 return GST_FLOW_ERROR;
909 in_color_matrix = gst_cogcolorspace_caps_get_color_matrix (inbuf->caps);
910 out_color_matrix = gst_cogcolorspace_caps_get_color_matrix (outbuf->caps);
912 in_chroma_site = gst_cogcolorspace_caps_get_chroma_site (inbuf->caps);
913 out_chroma_site = gst_cogcolorspace_caps_get_chroma_site (outbuf->caps);
915 frame = gst_cog_buffer_wrap (gst_buffer_ref (inbuf),
916 in_format, width, height);
917 out_frame = gst_cog_buffer_wrap (gst_buffer_ref (outbuf),
918 out_format, width, height);
920 if (in_format == out_format) {
921 memcpy (GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf),
922 GST_BUFFER_SIZE (outbuf));
928 for (i = 0; i < sizeof (transforms) / sizeof (transforms[0]); i++) {
929 if (transforms[i].in_format == in_format &&
930 transforms[i].out_format == out_format) {
931 transforms[i].convert (out_frame, frame);
932 cog_frame_unref (frame);
933 cog_frame_unref (out_frame);
939 GST_DEBUG ("no fastpath match %d %d", in_format, out_format);
942 switch (out_format) {
943 case GST_VIDEO_FORMAT_YUY2:
944 case GST_VIDEO_FORMAT_UYVY:
945 case GST_VIDEO_FORMAT_YVYU:
946 case GST_VIDEO_FORMAT_Y42B:
947 case GST_VIDEO_FORMAT_v210:
948 case GST_VIDEO_FORMAT_v216:
949 new_subsample = COG_FRAME_FORMAT_U8_422;
951 case GST_VIDEO_FORMAT_I420:
952 case GST_VIDEO_FORMAT_YV12:
953 new_subsample = COG_FRAME_FORMAT_U8_420;
955 case GST_VIDEO_FORMAT_Y444:
956 case GST_VIDEO_FORMAT_RGBx:
957 case GST_VIDEO_FORMAT_xRGB:
958 case GST_VIDEO_FORMAT_BGRx:
959 case GST_VIDEO_FORMAT_xBGR:
960 case GST_VIDEO_FORMAT_RGBA:
961 case GST_VIDEO_FORMAT_ARGB:
962 case GST_VIDEO_FORMAT_BGRA:
963 case GST_VIDEO_FORMAT_ABGR:
965 new_subsample = COG_FRAME_FORMAT_U8_444;
969 frame = cog_virt_frame_new_unpack (frame);
971 if (gst_video_format_is_yuv (out_format) &&
972 gst_video_format_is_rgb (in_format)) {
973 frame = cog_virt_frame_new_color_matrix_RGB_to_YCbCr (frame,
974 out_color_matrix, 8);
975 frame = cog_virt_frame_new_subsample (frame, new_subsample,
976 out_chroma_site, (compress->quality >= 3) ? 2 : 1);
979 if (gst_video_format_is_yuv (out_format) &&
980 gst_video_format_is_yuv (in_format)) {
981 if ((in_color_matrix != out_color_matrix ||
982 in_chroma_site != out_chroma_site)) {
983 frame = cog_virt_frame_new_subsample (frame, COG_FRAME_FORMAT_U8_444,
984 in_chroma_site, (compress->quality >= 5) ? 8 : 6);
985 frame = cog_virt_frame_new_color_matrix_YCbCr_to_YCbCr (frame,
986 in_color_matrix, out_color_matrix, 8);
988 frame = cog_virt_frame_new_subsample (frame, new_subsample,
989 in_chroma_site, (compress->quality >= 5) ? 8 : 6);
992 if (gst_video_format_is_rgb (out_format) &&
993 gst_video_format_is_yuv (in_format)) {
994 frame = cog_virt_frame_new_subsample (frame, new_subsample,
995 in_chroma_site, (compress->quality >= 3) ? 2 : 1);
996 frame = cog_virt_frame_new_color_matrix_YCbCr_to_RGB (frame,
997 in_color_matrix, (compress->quality >= 5) ? 8 : 6);
1000 switch (out_format) {
1001 case GST_VIDEO_FORMAT_YUY2:
1002 frame = cog_virt_frame_new_pack_YUY2 (frame);
1004 case GST_VIDEO_FORMAT_UYVY:
1005 frame = cog_virt_frame_new_pack_UYVY (frame);
1007 case GST_VIDEO_FORMAT_AYUV:
1008 frame = cog_virt_frame_new_pack_AYUV (frame);
1010 case GST_VIDEO_FORMAT_v216:
1011 frame = cog_virt_frame_new_pack_v216 (frame);
1013 case GST_VIDEO_FORMAT_v210:
1014 frame = cog_virt_frame_new_pack_v210 (frame);
1016 case GST_VIDEO_FORMAT_RGBx:
1017 frame = cog_virt_frame_new_pack_RGBx (frame);
1019 case GST_VIDEO_FORMAT_xRGB:
1020 frame = cog_virt_frame_new_pack_xRGB (frame);
1022 case GST_VIDEO_FORMAT_BGRx:
1023 frame = cog_virt_frame_new_pack_BGRx (frame);
1025 case GST_VIDEO_FORMAT_xBGR:
1026 frame = cog_virt_frame_new_pack_xBGR (frame);
1028 case GST_VIDEO_FORMAT_RGBA:
1029 frame = cog_virt_frame_new_pack_RGBA (frame);
1031 case GST_VIDEO_FORMAT_ARGB:
1032 frame = cog_virt_frame_new_pack_ARGB (frame);
1034 case GST_VIDEO_FORMAT_BGRA:
1035 frame = cog_virt_frame_new_pack_BGRA (frame);
1037 case GST_VIDEO_FORMAT_ABGR:
1038 frame = cog_virt_frame_new_pack_ABGR (frame);
1044 cog_virt_frame_render (frame, out_frame);
1045 cog_frame_unref (frame);
1046 cog_frame_unref (out_frame);