Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / gst-libs / gst / video / video.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  * Library       <2002> Ronald Bultje <rbultje@ronald.bitfreak.net>
4  * Copyright (C) 2007 David A. Schleef <ds@schleef.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include "config.h"
24 #endif
25
26 #include "video.h"
27
28 /**
29  * SECTION:gstvideo
30  * @short_description: Support library for video operations
31  *
32  * <refsect2>
33  * <para>
34  * This library contains some helper functions and includes the
35  * videosink and videofilter base classes.
36  * </para>
37  * </refsect2>
38  */
39
40 static GstVideoFormat gst_video_format_from_rgb32_masks (int red_mask,
41     int green_mask, int blue_mask);
42 static GstVideoFormat gst_video_format_from_rgba32_masks (int red_mask,
43     int green_mask, int blue_mask, int alpha_mask);
44 static GstVideoFormat gst_video_format_from_rgb24_masks (int red_mask,
45     int green_mask, int blue_mask);
46 static GstVideoFormat gst_video_format_from_rgb16_masks (int red_mask,
47     int green_mask, int blue_mask);
48
49
50 /**
51  * gst_video_frame_rate:
52  * @pad: pointer to a #GstPad
53  *
54  * A convenience function to retrieve a GValue holding the framerate
55  * from the caps on a pad.
56  *
57  * The pad needs to have negotiated caps containing a framerate property.
58  *
59  * Returns: NULL if the pad has no configured caps or the configured caps
60  * do not contain a framerate.
61  *
62  */
63 const GValue *
64 gst_video_frame_rate (GstPad * pad)
65 {
66   const GValue *fps;
67   gchar *fps_string;
68   GstCaps *caps = NULL;
69   GstStructure *structure;
70
71   /* get pad caps */
72   caps = gst_pad_get_current_caps (pad);
73   if (caps == NULL)
74     goto no_caps;
75
76   structure = gst_caps_get_structure (caps, 0);
77   if ((fps = gst_structure_get_value (structure, "framerate")) == NULL)
78     goto no_framerate;
79
80   if (!GST_VALUE_HOLDS_FRACTION (fps))
81     goto no_fraction;
82
83   fps_string = gst_value_serialize (fps);
84   GST_DEBUG ("Framerate request on pad %s:%s: %s",
85       GST_DEBUG_PAD_NAME (pad), fps_string);
86   g_free (fps_string);
87
88   gst_caps_unref (caps);
89
90   return fps;
91
92   /* ERRORS */
93 no_caps:
94   {
95     g_warning ("gstvideo: failed to get caps of pad %s:%s",
96         GST_DEBUG_PAD_NAME (pad));
97     return NULL;
98   }
99 no_framerate:
100   {
101     g_warning ("gstvideo: failed to get framerate property of pad %s:%s",
102         GST_DEBUG_PAD_NAME (pad));
103     gst_caps_unref (caps);
104     return NULL;
105   }
106 no_fraction:
107   {
108     g_warning
109         ("gstvideo: framerate property of pad %s:%s is not of type Fraction",
110         GST_DEBUG_PAD_NAME (pad));
111     gst_caps_unref (caps);
112     return NULL;
113   }
114 }
115
116 /**
117  * gst_video_get_size:
118  * @pad: pointer to a #GstPad
119  * @width: pointer to integer to hold pixel width of the video frames (output)
120  * @height: pointer to integer to hold pixel height of the video frames (output)
121  *
122  * Inspect the caps of the provided pad and retrieve the width and height of
123  * the video frames it is configured for.
124  *
125  * The pad needs to have negotiated caps containing width and height properties.
126  *
127  * Returns: TRUE if the width and height could be retrieved.
128  *
129  */
130 gboolean
131 gst_video_get_size (GstPad * pad, gint * width, gint * height)
132 {
133   GstCaps *caps = NULL;
134   GstStructure *structure;
135   gboolean ret;
136
137   g_return_val_if_fail (pad != NULL, FALSE);
138   g_return_val_if_fail (width != NULL, FALSE);
139   g_return_val_if_fail (height != NULL, FALSE);
140
141   caps = gst_pad_get_current_caps (pad);
142   if (caps == NULL)
143     goto no_caps;
144
145   structure = gst_caps_get_structure (caps, 0);
146   ret = gst_structure_get_int (structure, "width", width);
147   ret &= gst_structure_get_int (structure, "height", height);
148   gst_caps_unref (caps);
149
150   if (!ret)
151     goto no_size;
152
153   GST_DEBUG ("size request on pad %s:%s: %dx%d",
154       GST_DEBUG_PAD_NAME (pad), width ? *width : -1, height ? *height : -1);
155
156   return TRUE;
157
158   /* ERROR */
159 no_caps:
160   {
161     g_warning ("gstvideo: failed to get caps of pad %s:%s",
162         GST_DEBUG_PAD_NAME (pad));
163     return FALSE;
164   }
165 no_size:
166   {
167     g_warning ("gstvideo: failed to get size properties on pad %s:%s",
168         GST_DEBUG_PAD_NAME (pad));
169     return FALSE;
170   }
171 }
172
173 /**
174  * gst_video_calculate_display_ratio:
175  * @dar_n: Numerator of the calculated display_ratio
176  * @dar_d: Denominator of the calculated display_ratio
177  * @video_width: Width of the video frame in pixels
178  * @video_height: Height of the video frame in pixels
179  * @video_par_n: Numerator of the pixel aspect ratio of the input video.
180  * @video_par_d: Denominator of the pixel aspect ratio of the input video.
181  * @display_par_n: Numerator of the pixel aspect ratio of the display device
182  * @display_par_d: Denominator of the pixel aspect ratio of the display device
183  *
184  * Given the Pixel Aspect Ratio and size of an input video frame, and the
185  * pixel aspect ratio of the intended display device, calculates the actual
186  * display ratio the video will be rendered with.
187  *
188  * Returns: A boolean indicating success and a calculated Display Ratio in the
189  * dar_n and dar_d parameters.
190  * The return value is FALSE in the case of integer overflow or other error.
191  *
192  * Since: 0.10.7
193  */
194 gboolean
195 gst_video_calculate_display_ratio (guint * dar_n, guint * dar_d,
196     guint video_width, guint video_height,
197     guint video_par_n, guint video_par_d,
198     guint display_par_n, guint display_par_d)
199 {
200   gint num, den;
201   gint tmp_n, tmp_d;
202
203   g_return_val_if_fail (dar_n != NULL, FALSE);
204   g_return_val_if_fail (dar_d != NULL, FALSE);
205
206   /* Calculate (video_width * video_par_n * display_par_d) /
207    * (video_height * video_par_d * display_par_n) */
208   if (!gst_util_fraction_multiply (video_width, video_height, video_par_n,
209           video_par_d, &tmp_n, &tmp_d))
210     goto error_overflow;
211
212   if (!gst_util_fraction_multiply (tmp_n, tmp_d, display_par_d, display_par_n,
213           &num, &den))
214     goto error_overflow;
215
216   g_return_val_if_fail (num > 0, FALSE);
217   g_return_val_if_fail (den > 0, FALSE);
218
219   *dar_n = num;
220   *dar_d = den;
221
222   return TRUE;
223 error_overflow:
224   return FALSE;
225 }
226
227 /**
228  * gst_video_format_parse_caps_interlaced:
229  * @caps: the fixed #GstCaps to parse
230  * @interlaced: whether @caps represents interlaced video or not, may be NULL (output)
231  *
232  * Extracts whether the caps represents interlaced content or not and places it
233  * in @interlaced.
234  *
235  * Since: 0.10.23
236  *
237  * Returns: TRUE if @caps was parsed correctly.
238  */
239 gboolean
240 gst_video_format_parse_caps_interlaced (GstCaps * caps, gboolean * interlaced)
241 {
242   GstStructure *structure;
243
244   if (!gst_caps_is_fixed (caps))
245     return FALSE;
246
247   structure = gst_caps_get_structure (caps, 0);
248
249   if (interlaced) {
250     if (!gst_structure_get_boolean (structure, "interlaced", interlaced))
251       *interlaced = FALSE;
252   }
253
254   return TRUE;
255 }
256
257 /**
258  * gst_video_parse_caps_color_matrix:
259  * @caps: the fixed #GstCaps to parse
260  *
261  * Extracts the color matrix used by the caps.  Possible values are
262  * "sdtv" for the standard definition color matrix (as specified in
263  * Rec. ITU-R BT.470-6) or "hdtv" for the high definition color
264  * matrix (as specified in Rec. ITU-R BT.709)
265  *
266  * Since: 0.10.29
267  *
268  * Returns: a color matrix string, or NULL if no color matrix could be
269  *     determined.
270  */
271 const char *
272 gst_video_parse_caps_color_matrix (GstCaps * caps)
273 {
274   GstStructure *structure;
275   const char *s;
276
277   if (!gst_caps_is_fixed (caps))
278     return NULL;
279
280   structure = gst_caps_get_structure (caps, 0);
281
282   s = gst_structure_get_string (structure, "color-matrix");
283   if (s)
284     return s;
285
286   if (gst_structure_has_name (structure, "video/x-raw-yuv")) {
287     return "sdtv";
288   }
289
290   return NULL;
291 }
292
293 /**
294  * gst_video_parse_caps_chroma_site:
295  * @caps: the fixed #GstCaps to parse
296  *
297  * Extracts the chroma site used by the caps.  Possible values are
298  * "mpeg2" for MPEG-2 style chroma siting (co-sited horizontally,
299  * halfway-sited vertically), "jpeg" for JPEG and Theora style
300  * chroma siting (halfway-sited both horizontally and vertically).
301  * Other chroma site values are possible, but uncommon.
302  *
303  * When no chroma site is specified in the caps, it should be assumed
304  * to be "mpeg2".
305  *
306  * Since: 0.10.29
307  *
308  * Returns: a chroma site string, or NULL if no chroma site could be
309  *     determined.
310  */
311 const char *
312 gst_video_parse_caps_chroma_site (GstCaps * caps)
313 {
314   GstStructure *structure;
315   const char *s;
316
317   if (!gst_caps_is_fixed (caps))
318     return NULL;
319
320   structure = gst_caps_get_structure (caps, 0);
321
322   s = gst_structure_get_string (structure, "chroma-site");
323   if (s)
324     return s;
325
326   if (gst_structure_has_name (structure, "video/x-raw-yuv")) {
327     return "mpeg2";
328   }
329
330   return NULL;
331 }
332
333 /**
334  * gst_video_format_parse_caps:
335  * @caps: the #GstCaps to parse
336  * @format: the #GstVideoFormat of the video represented by @caps (output)
337  * @width: the width of the video represented by @caps, may be NULL (output)
338  * @height: the height of the video represented by @caps, may be NULL (output)
339  *
340  * Determines the #GstVideoFormat of @caps and places it in the location
341  * pointed to by @format.  Extracts the size of the video and places it
342  * in the location pointed to by @width and @height.  If @caps does not
343  * represent one of the raw video formats listed in #GstVideoFormat, the
344  * function will fail and return FALSE.
345  *
346  * Since: 0.10.16
347  *
348  * Returns: TRUE if @caps was parsed correctly.
349  */
350 gboolean
351 gst_video_format_parse_caps (const GstCaps * caps, GstVideoFormat * format,
352     int *width, int *height)
353 {
354   GstStructure *structure;
355   gboolean ok = TRUE;
356
357   if (!gst_caps_is_fixed (caps))
358     return FALSE;
359
360   structure = gst_caps_get_structure (caps, 0);
361
362   if (format) {
363     if (gst_structure_has_name (structure, "video/x-raw-yuv")) {
364       guint32 fourcc;
365
366       ok &= gst_structure_get_fourcc (structure, "format", &fourcc);
367
368       *format = gst_video_format_from_fourcc (fourcc);
369       if (*format == GST_VIDEO_FORMAT_UNKNOWN) {
370         ok = FALSE;
371       }
372     } else if (gst_structure_has_name (structure, "video/x-raw-rgb")) {
373       int depth;
374       int bpp;
375       int endianness = 0;
376       int red_mask = 0;
377       int green_mask = 0;
378       int blue_mask = 0;
379       int alpha_mask = 0;
380       gboolean have_alpha;
381
382       ok &= gst_structure_get_int (structure, "depth", &depth);
383       ok &= gst_structure_get_int (structure, "bpp", &bpp);
384
385       if (bpp != 8) {
386         ok &= gst_structure_get_int (structure, "endianness", &endianness);
387         ok &= gst_structure_get_int (structure, "red_mask", &red_mask);
388         ok &= gst_structure_get_int (structure, "green_mask", &green_mask);
389         ok &= gst_structure_get_int (structure, "blue_mask", &blue_mask);
390       }
391       have_alpha = gst_structure_get_int (structure, "alpha_mask", &alpha_mask);
392
393       if (depth == 30 && bpp == 32 && endianness == G_BIG_ENDIAN) {
394         *format = GST_VIDEO_FORMAT_r210;
395       } else if (depth == 24 && bpp == 32 && endianness == G_BIG_ENDIAN) {
396         *format = gst_video_format_from_rgb32_masks (red_mask, green_mask,
397             blue_mask);
398         if (*format == GST_VIDEO_FORMAT_UNKNOWN) {
399           ok = FALSE;
400         }
401       } else if (depth == 32 && bpp == 32 && endianness == G_BIG_ENDIAN &&
402           have_alpha) {
403         *format = gst_video_format_from_rgba32_masks (red_mask, green_mask,
404             blue_mask, alpha_mask);
405         if (*format == GST_VIDEO_FORMAT_UNKNOWN) {
406           ok = FALSE;
407         }
408       } else if (depth == 24 && bpp == 24 && endianness == G_BIG_ENDIAN) {
409         *format = gst_video_format_from_rgb24_masks (red_mask, green_mask,
410             blue_mask);
411         if (*format == GST_VIDEO_FORMAT_UNKNOWN) {
412           ok = FALSE;
413         }
414       } else if ((depth == 15 || depth == 16) && bpp == 16 &&
415           endianness == G_BYTE_ORDER) {
416         *format = gst_video_format_from_rgb16_masks (red_mask, green_mask,
417             blue_mask);
418         if (*format == GST_VIDEO_FORMAT_UNKNOWN) {
419           ok = FALSE;
420         }
421       } else if (depth == 8 && bpp == 8) {
422         *format = GST_VIDEO_FORMAT_RGB8_PALETTED;
423       } else if (depth == 64 && bpp == 64) {
424         *format = gst_video_format_from_rgba32_masks (red_mask, green_mask,
425             blue_mask, alpha_mask);
426         if (*format == GST_VIDEO_FORMAT_ARGB) {
427           *format = GST_VIDEO_FORMAT_ARGB64;
428         } else {
429           *format = GST_VIDEO_FORMAT_UNKNOWN;
430           ok = FALSE;
431         }
432       } else {
433         ok = FALSE;
434       }
435     } else if (gst_structure_has_name (structure, "video/x-raw-gray")) {
436       int depth;
437       int bpp;
438       int endianness;
439
440       ok &= gst_structure_get_int (structure, "depth", &depth);
441       ok &= gst_structure_get_int (structure, "bpp", &bpp);
442
443       if (bpp > 8)
444         ok &= gst_structure_get_int (structure, "endianness", &endianness);
445
446       if (depth == 8 && bpp == 8) {
447         *format = GST_VIDEO_FORMAT_GRAY8;
448       } else if (depth == 16 && bpp == 16 && endianness == G_BIG_ENDIAN) {
449         *format = GST_VIDEO_FORMAT_GRAY16_BE;
450       } else if (depth == 16 && bpp == 16 && endianness == G_LITTLE_ENDIAN) {
451         *format = GST_VIDEO_FORMAT_GRAY16_LE;
452       } else {
453         ok = FALSE;
454       }
455     } else {
456       ok = FALSE;
457     }
458   }
459
460   if (width) {
461     ok &= gst_structure_get_int (structure, "width", width);
462   }
463
464   if (height) {
465     ok &= gst_structure_get_int (structure, "height", height);
466   }
467
468   return ok;
469 }
470
471
472 /**
473  * gst_video_parse_caps_framerate:
474  * @caps: pointer to a #GstCaps instance
475  * @fps_n: pointer to integer to hold numerator of frame rate (output)
476  * @fps_d: pointer to integer to hold denominator of frame rate (output)
477  *
478  * Extracts the frame rate from @caps and places the values in the locations
479  * pointed to by @fps_n and @fps_d.  Returns TRUE if the values could be
480  * parsed correctly, FALSE if not.
481  *
482  * This function can be used with #GstCaps that have any media type; it
483  * is not limited to formats handled by #GstVideoFormat.
484  *
485  * Since: 0.10.16
486  *
487  * Returns: TRUE if @caps was parsed correctly.
488  */
489 gboolean
490 gst_video_parse_caps_framerate (GstCaps * caps, int *fps_n, int *fps_d)
491 {
492   GstStructure *structure;
493
494   if (!gst_caps_is_fixed (caps))
495     return FALSE;
496
497   structure = gst_caps_get_structure (caps, 0);
498
499   return gst_structure_get_fraction (structure, "framerate", fps_n, fps_d);
500 }
501
502 /**
503  * gst_video_parse_caps_pixel_aspect_ratio:
504  * @caps: pointer to a #GstCaps instance
505  * @par_n: pointer to numerator of pixel aspect ratio (output)
506  * @par_d: pointer to denominator of pixel aspect ratio (output)
507  *
508  * Extracts the pixel aspect ratio from @caps and places the values in
509  * the locations pointed to by @par_n and @par_d.  Returns TRUE if the
510  * values could be parsed correctly, FALSE if not.
511  *
512  * This function can be used with #GstCaps that have any media type; it
513  * is not limited to formats handled by #GstVideoFormat.
514  *
515  * Since: 0.10.16
516  *
517  * Returns: TRUE if @caps was parsed correctly.
518  */
519 gboolean
520 gst_video_parse_caps_pixel_aspect_ratio (GstCaps * caps, int *par_n, int *par_d)
521 {
522   GstStructure *structure;
523
524   if (!gst_caps_is_fixed (caps))
525     return FALSE;
526
527   structure = gst_caps_get_structure (caps, 0);
528
529   if (!gst_structure_get_fraction (structure, "pixel-aspect-ratio",
530           par_n, par_d)) {
531     *par_n = 1;
532     *par_d = 1;
533   }
534   return TRUE;
535 }
536
537 /**
538  * gst_video_format_new_caps_interlaced:
539  * @format: the #GstVideoFormat describing the raw video format
540  * @width: width of video
541  * @height: height of video
542  * @framerate_n: numerator of frame rate
543  * @framerate_d: denominator of frame rate
544  * @par_n: numerator of pixel aspect ratio
545  * @par_d: denominator of pixel aspect ratio
546  * @interlaced: #TRUE if the format is interlaced
547  *
548  * Creates a new #GstCaps object based on the parameters provided.
549  *
550  * Since: 0.10.23
551  *
552  * Returns: a new #GstCaps object, or NULL if there was an error
553  */
554 GstCaps *
555 gst_video_format_new_caps_interlaced (GstVideoFormat format,
556     int width, int height, int framerate_n, int framerate_d, int par_n,
557     int par_d, gboolean interlaced)
558 {
559   GstCaps *res;
560
561   res =
562       gst_video_format_new_caps (format, width, height, framerate_n,
563       framerate_d, par_n, par_d);
564   if (interlaced && (res != NULL))
565     gst_caps_set_simple (res, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
566
567   return res;
568 }
569
570 static GstCaps *
571 gst_video_format_new_caps_raw (GstVideoFormat format)
572 {
573   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
574
575   if (gst_video_format_is_yuv (format)) {
576     return gst_caps_new_simple ("video/x-raw-yuv",
577         "format", GST_TYPE_FOURCC, gst_video_format_to_fourcc (format), NULL);
578   }
579   if (gst_video_format_is_rgb (format)) {
580     GstCaps *caps;
581     int red_mask = 0;
582     int blue_mask = 0;
583     int green_mask = 0;
584     int alpha_mask;
585     int depth;
586     int bpp;
587     gboolean have_alpha;
588     unsigned int mask = 0;
589
590     switch (format) {
591       case GST_VIDEO_FORMAT_RGBx:
592       case GST_VIDEO_FORMAT_BGRx:
593       case GST_VIDEO_FORMAT_xRGB:
594       case GST_VIDEO_FORMAT_xBGR:
595         bpp = 32;
596         depth = 24;
597         have_alpha = FALSE;
598         break;
599       case GST_VIDEO_FORMAT_RGBA:
600       case GST_VIDEO_FORMAT_BGRA:
601       case GST_VIDEO_FORMAT_ARGB:
602       case GST_VIDEO_FORMAT_ABGR:
603         bpp = 32;
604         depth = 32;
605         have_alpha = TRUE;
606         break;
607       case GST_VIDEO_FORMAT_RGB:
608       case GST_VIDEO_FORMAT_BGR:
609         bpp = 24;
610         depth = 24;
611         have_alpha = FALSE;
612         break;
613       case GST_VIDEO_FORMAT_RGB16:
614       case GST_VIDEO_FORMAT_BGR16:
615         bpp = 16;
616         depth = 16;
617         have_alpha = FALSE;
618         break;
619       case GST_VIDEO_FORMAT_RGB15:
620       case GST_VIDEO_FORMAT_BGR15:
621         bpp = 16;
622         depth = 15;
623         have_alpha = FALSE;
624         break;
625       case GST_VIDEO_FORMAT_RGB8_PALETTED:
626         bpp = 8;
627         depth = 8;
628         have_alpha = FALSE;
629         break;
630       case GST_VIDEO_FORMAT_ARGB64:
631         bpp = 64;
632         depth = 64;
633         have_alpha = TRUE;
634         break;
635       case GST_VIDEO_FORMAT_r210:
636         bpp = 32;
637         depth = 30;
638         have_alpha = FALSE;
639         break;
640       default:
641         return NULL;
642     }
643     if (bpp == 32 && depth == 30) {
644       red_mask = 0x3ff00000;
645       green_mask = 0x000ffc00;
646       blue_mask = 0x000003ff;
647       have_alpha = FALSE;
648     } else if (bpp == 32 || bpp == 24 || bpp == 64) {
649       if (bpp == 32) {
650         mask = 0xff000000;
651       } else {
652         mask = 0xff0000;
653       }
654       red_mask =
655           mask >> (8 * gst_video_format_get_component_offset (format, 0, 0, 0));
656       green_mask =
657           mask >> (8 * gst_video_format_get_component_offset (format, 1, 0, 0));
658       blue_mask =
659           mask >> (8 * gst_video_format_get_component_offset (format, 2, 0, 0));
660     } else if (bpp == 16) {
661       switch (format) {
662         case GST_VIDEO_FORMAT_RGB16:
663           red_mask = GST_VIDEO_COMP1_MASK_16_INT;
664           green_mask = GST_VIDEO_COMP2_MASK_16_INT;
665           blue_mask = GST_VIDEO_COMP3_MASK_16_INT;
666           break;
667         case GST_VIDEO_FORMAT_BGR16:
668           red_mask = GST_VIDEO_COMP3_MASK_16_INT;
669           green_mask = GST_VIDEO_COMP2_MASK_16_INT;
670           blue_mask = GST_VIDEO_COMP1_MASK_16_INT;
671           break;
672           break;
673         case GST_VIDEO_FORMAT_RGB15:
674           red_mask = GST_VIDEO_COMP1_MASK_15_INT;
675           green_mask = GST_VIDEO_COMP2_MASK_15_INT;
676           blue_mask = GST_VIDEO_COMP3_MASK_15_INT;
677           break;
678         case GST_VIDEO_FORMAT_BGR15:
679           red_mask = GST_VIDEO_COMP3_MASK_15_INT;
680           green_mask = GST_VIDEO_COMP2_MASK_15_INT;
681           blue_mask = GST_VIDEO_COMP1_MASK_15_INT;
682           break;
683         default:
684           g_assert_not_reached ();
685       }
686     } else if (bpp != 8) {
687       g_assert_not_reached ();
688     }
689
690     caps = gst_caps_new_simple ("video/x-raw-rgb",
691         "bpp", G_TYPE_INT, bpp, "depth", G_TYPE_INT, depth, NULL);
692
693     if (bpp != 8) {
694       gst_caps_set_simple (caps,
695           "endianness", G_TYPE_INT, G_BIG_ENDIAN,
696           "red_mask", G_TYPE_INT, red_mask,
697           "green_mask", G_TYPE_INT, green_mask,
698           "blue_mask", G_TYPE_INT, blue_mask, NULL);
699     }
700
701     if (have_alpha) {
702       alpha_mask =
703           mask >> (8 * gst_video_format_get_component_offset (format, 3, 0, 0));
704       gst_caps_set_simple (caps, "alpha_mask", G_TYPE_INT, alpha_mask, NULL);
705     }
706     return caps;
707   }
708
709   if (gst_video_format_is_gray (format)) {
710     GstCaps *caps;
711     int bpp;
712     int depth;
713     int endianness;
714
715     switch (format) {
716       case GST_VIDEO_FORMAT_GRAY8:
717         bpp = depth = 8;
718         endianness = G_BIG_ENDIAN;
719         break;
720       case GST_VIDEO_FORMAT_GRAY16_BE:
721         bpp = depth = 16;
722         endianness = G_BIG_ENDIAN;
723         break;
724       case GST_VIDEO_FORMAT_GRAY16_LE:
725         bpp = depth = 16;
726         endianness = G_LITTLE_ENDIAN;
727         break;
728       default:
729         return NULL;
730         break;
731     }
732
733     if (bpp <= 8) {
734       caps = gst_caps_new_simple ("video/x-raw-gray",
735           "bpp", G_TYPE_INT, bpp, "depth", G_TYPE_INT, depth, NULL);
736     } else {
737       caps = gst_caps_new_simple ("video/x-raw-gray",
738           "bpp", G_TYPE_INT, bpp,
739           "depth", G_TYPE_INT, depth,
740           "endianness", G_TYPE_INT, endianness, NULL);
741     }
742
743     return caps;
744   }
745
746   return NULL;
747 }
748
749 /**
750  * gst_video_format_new_template_caps:
751  * @format: the #GstVideoFormat describing the raw video format
752  *
753  * Creates a new #GstCaps object based on the parameters provided.
754  * Size, frame rate, and pixel aspect ratio are set to the full
755  * range.
756  *
757  * Since: 0.10.33
758  *
759  * Returns: a new #GstCaps object, or NULL if there was an error
760  */
761 GstCaps *
762 gst_video_format_new_template_caps (GstVideoFormat format)
763 {
764   GstCaps *caps;
765   GstStructure *structure;
766
767   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
768
769   caps = gst_video_format_new_caps_raw (format);
770   if (caps) {
771     GValue value = { 0 };
772     GValue v = { 0 };
773
774     structure = gst_caps_get_structure (caps, 0);
775
776     gst_structure_set (structure,
777         "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
778         "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
779         "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
780         "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
781
782     g_value_init (&value, GST_TYPE_LIST);
783     g_value_init (&v, G_TYPE_BOOLEAN);
784     g_value_set_boolean (&v, TRUE);
785     gst_value_list_append_value (&value, &v);
786     g_value_set_boolean (&v, FALSE);
787     gst_value_list_append_value (&value, &v);
788
789     gst_structure_set_value (structure, "interlaced", &value);
790
791     g_value_reset (&value);
792     g_value_reset (&v);
793   }
794
795   return caps;
796 }
797
798 /**
799  * gst_video_format_new_caps:
800  * @format: the #GstVideoFormat describing the raw video format
801  * @width: width of video
802  * @height: height of video
803  * @framerate_n: numerator of frame rate
804  * @framerate_d: denominator of frame rate
805  * @par_n: numerator of pixel aspect ratio
806  * @par_d: denominator of pixel aspect ratio
807  *
808  * Creates a new #GstCaps object based on the parameters provided.
809  *
810  * Since: 0.10.16
811  *
812  * Returns: a new #GstCaps object, or NULL if there was an error
813  */
814 GstCaps *
815 gst_video_format_new_caps (GstVideoFormat format, int width,
816     int height, int framerate_n, int framerate_d, int par_n, int par_d)
817 {
818   GstCaps *caps;
819   GstStructure *structure;
820
821   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
822   g_return_val_if_fail (width > 0 && height > 0, NULL);
823
824   caps = gst_video_format_new_caps_raw (format);
825   if (caps) {
826     structure = gst_caps_get_structure (caps, 0);
827
828     gst_structure_set (structure,
829         "width", G_TYPE_INT, width,
830         "height", G_TYPE_INT, height,
831         "framerate", GST_TYPE_FRACTION, framerate_n, framerate_d,
832         "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
833   }
834
835   return caps;
836 }
837
838
839 /**
840  * gst_video_format_from_fourcc:
841  * @fourcc: a FOURCC value representing raw YUV video
842  *
843  * Converts a FOURCC value into the corresponding #GstVideoFormat.
844  * If the FOURCC cannot be represented by #GstVideoFormat,
845  * #GST_VIDEO_FORMAT_UNKNOWN is returned.
846  *
847  * Since: 0.10.16
848  *
849  * Returns: the #GstVideoFormat describing the FOURCC value
850  */
851 GstVideoFormat
852 gst_video_format_from_fourcc (guint32 fourcc)
853 {
854   switch (fourcc) {
855     case GST_MAKE_FOURCC ('I', '4', '2', '0'):
856       return GST_VIDEO_FORMAT_I420;
857     case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
858       return GST_VIDEO_FORMAT_YV12;
859     case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
860       return GST_VIDEO_FORMAT_YUY2;
861     case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'):
862       return GST_VIDEO_FORMAT_YVYU;
863     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
864       return GST_VIDEO_FORMAT_UYVY;
865     case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
866       return GST_VIDEO_FORMAT_AYUV;
867     case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
868       return GST_VIDEO_FORMAT_Y41B;
869     case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
870       return GST_VIDEO_FORMAT_Y42B;
871     case GST_MAKE_FOURCC ('Y', '4', '4', '4'):
872       return GST_VIDEO_FORMAT_Y444;
873     case GST_MAKE_FOURCC ('v', '2', '1', '0'):
874       return GST_VIDEO_FORMAT_v210;
875     case GST_MAKE_FOURCC ('v', '2', '1', '6'):
876       return GST_VIDEO_FORMAT_v216;
877     case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
878       return GST_VIDEO_FORMAT_NV12;
879     case GST_MAKE_FOURCC ('N', 'V', '2', '1'):
880       return GST_VIDEO_FORMAT_NV21;
881     case GST_MAKE_FOURCC ('v', '3', '0', '8'):
882       return GST_VIDEO_FORMAT_v308;
883     case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
884     case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
885     case GST_MAKE_FOURCC ('G', 'R', 'E', 'Y'):
886       return GST_VIDEO_FORMAT_Y800;
887     case GST_MAKE_FOURCC ('Y', '1', '6', ' '):
888       return GST_VIDEO_FORMAT_Y16;
889     case GST_MAKE_FOURCC ('U', 'Y', 'V', 'P'):
890       return GST_VIDEO_FORMAT_UYVP;
891     case GST_MAKE_FOURCC ('A', '4', '2', '0'):
892       return GST_VIDEO_FORMAT_A420;
893     case GST_MAKE_FOURCC ('Y', 'U', 'V', '9'):
894       return GST_VIDEO_FORMAT_YUV9;
895     case GST_MAKE_FOURCC ('Y', 'V', 'U', '9'):
896       return GST_VIDEO_FORMAT_YVU9;
897     case GST_MAKE_FOURCC ('I', 'Y', 'U', '1'):
898       return GST_VIDEO_FORMAT_IYU1;
899     case GST_MAKE_FOURCC ('A', 'Y', '6', '4'):
900       return GST_VIDEO_FORMAT_AYUV64;
901     default:
902       return GST_VIDEO_FORMAT_UNKNOWN;
903   }
904 }
905
906 /**
907  * gst_video_format_to_fourcc:
908  * @format: a #GstVideoFormat video format
909  *
910  * Converts a #GstVideoFormat value into the corresponding FOURCC.  Only
911  * a few YUV formats have corresponding FOURCC values.  If @format has
912  * no corresponding FOURCC value, 0 is returned.
913  *
914  * Since: 0.10.16
915  *
916  * Returns: the FOURCC corresponding to @format
917  */
918 guint32
919 gst_video_format_to_fourcc (GstVideoFormat format)
920 {
921   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
922
923   switch (format) {
924     case GST_VIDEO_FORMAT_I420:
925       return GST_MAKE_FOURCC ('I', '4', '2', '0');
926     case GST_VIDEO_FORMAT_YV12:
927       return GST_MAKE_FOURCC ('Y', 'V', '1', '2');
928     case GST_VIDEO_FORMAT_YUY2:
929       return GST_MAKE_FOURCC ('Y', 'U', 'Y', '2');
930     case GST_VIDEO_FORMAT_YVYU:
931       return GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U');
932     case GST_VIDEO_FORMAT_UYVY:
933       return GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
934     case GST_VIDEO_FORMAT_AYUV:
935       return GST_MAKE_FOURCC ('A', 'Y', 'U', 'V');
936     case GST_VIDEO_FORMAT_Y41B:
937       return GST_MAKE_FOURCC ('Y', '4', '1', 'B');
938     case GST_VIDEO_FORMAT_Y42B:
939       return GST_MAKE_FOURCC ('Y', '4', '2', 'B');
940     case GST_VIDEO_FORMAT_Y444:
941       return GST_MAKE_FOURCC ('Y', '4', '4', '4');
942     case GST_VIDEO_FORMAT_v210:
943       return GST_MAKE_FOURCC ('v', '2', '1', '0');
944     case GST_VIDEO_FORMAT_v216:
945       return GST_MAKE_FOURCC ('v', '2', '1', '6');
946     case GST_VIDEO_FORMAT_NV12:
947       return GST_MAKE_FOURCC ('N', 'V', '1', '2');
948     case GST_VIDEO_FORMAT_NV21:
949       return GST_MAKE_FOURCC ('N', 'V', '2', '1');
950     case GST_VIDEO_FORMAT_v308:
951       return GST_MAKE_FOURCC ('v', '3', '0', '8');
952     case GST_VIDEO_FORMAT_Y800:
953       return GST_MAKE_FOURCC ('Y', '8', '0', '0');
954     case GST_VIDEO_FORMAT_Y16:
955       return GST_MAKE_FOURCC ('Y', '1', '6', ' ');
956     case GST_VIDEO_FORMAT_UYVP:
957       return GST_MAKE_FOURCC ('U', 'Y', 'V', 'P');
958     case GST_VIDEO_FORMAT_A420:
959       return GST_MAKE_FOURCC ('A', '4', '2', '0');
960     case GST_VIDEO_FORMAT_YUV9:
961       return GST_MAKE_FOURCC ('Y', 'U', 'V', '9');
962     case GST_VIDEO_FORMAT_YVU9:
963       return GST_MAKE_FOURCC ('Y', 'V', 'U', '9');
964     case GST_VIDEO_FORMAT_IYU1:
965       return GST_MAKE_FOURCC ('I', 'Y', 'U', '1');
966     case GST_VIDEO_FORMAT_AYUV64:
967       return GST_MAKE_FOURCC ('A', 'Y', '6', '4');
968     default:
969       return 0;
970   }
971 }
972
973 /*
974  * gst_video_format_from_rgb32_masks:
975  * @red_mask: red bit mask
976  * @green_mask: green bit mask
977  * @blue_mask: blue bit mask
978  *
979  * Converts red, green, blue bit masks into the corresponding
980  * #GstVideoFormat.
981  *
982  * Since: 0.10.16
983  *
984  * Returns: the #GstVideoFormat corresponding to the bit masks
985  */
986 static GstVideoFormat
987 gst_video_format_from_rgb32_masks (int red_mask, int green_mask, int blue_mask)
988 {
989   if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
990       blue_mask == 0x0000ff00) {
991     return GST_VIDEO_FORMAT_RGBx;
992   }
993   if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
994       blue_mask == 0xff000000) {
995     return GST_VIDEO_FORMAT_BGRx;
996   }
997   if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
998       blue_mask == 0x000000ff) {
999     return GST_VIDEO_FORMAT_xRGB;
1000   }
1001   if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
1002       blue_mask == 0x00ff0000) {
1003     return GST_VIDEO_FORMAT_xBGR;
1004   }
1005
1006   return GST_VIDEO_FORMAT_UNKNOWN;
1007 }
1008
1009 static GstVideoFormat
1010 gst_video_format_from_rgba32_masks (int red_mask, int green_mask,
1011     int blue_mask, int alpha_mask)
1012 {
1013   if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
1014       blue_mask == 0x0000ff00 && alpha_mask == 0x000000ff) {
1015     return GST_VIDEO_FORMAT_RGBA;
1016   }
1017   if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
1018       blue_mask == 0xff000000 && alpha_mask == 0x000000ff) {
1019     return GST_VIDEO_FORMAT_BGRA;
1020   }
1021   if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
1022       blue_mask == 0x000000ff && alpha_mask == 0xff000000) {
1023     return GST_VIDEO_FORMAT_ARGB;
1024   }
1025   if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
1026       blue_mask == 0x00ff0000 && alpha_mask == 0xff000000) {
1027     return GST_VIDEO_FORMAT_ABGR;
1028   }
1029
1030   return GST_VIDEO_FORMAT_UNKNOWN;
1031 }
1032
1033 static GstVideoFormat
1034 gst_video_format_from_rgb24_masks (int red_mask, int green_mask, int blue_mask)
1035 {
1036   if (red_mask == 0xff0000 && green_mask == 0x00ff00 && blue_mask == 0x0000ff) {
1037     return GST_VIDEO_FORMAT_RGB;
1038   }
1039   if (red_mask == 0x0000ff && green_mask == 0x00ff00 && blue_mask == 0xff0000) {
1040     return GST_VIDEO_FORMAT_BGR;
1041   }
1042
1043   return GST_VIDEO_FORMAT_UNKNOWN;
1044 }
1045
1046 static GstVideoFormat
1047 gst_video_format_from_rgb16_masks (int red_mask, int green_mask, int blue_mask)
1048 {
1049   if (red_mask == GST_VIDEO_COMP1_MASK_16_INT
1050       && green_mask == GST_VIDEO_COMP2_MASK_16_INT
1051       && blue_mask == GST_VIDEO_COMP3_MASK_16_INT) {
1052     return GST_VIDEO_FORMAT_RGB16;
1053   }
1054   if (red_mask == GST_VIDEO_COMP3_MASK_16_INT
1055       && green_mask == GST_VIDEO_COMP2_MASK_16_INT
1056       && blue_mask == GST_VIDEO_COMP1_MASK_16_INT) {
1057     return GST_VIDEO_FORMAT_BGR16;
1058   }
1059   if (red_mask == GST_VIDEO_COMP1_MASK_15_INT
1060       && green_mask == GST_VIDEO_COMP2_MASK_15_INT
1061       && blue_mask == GST_VIDEO_COMP3_MASK_15_INT) {
1062     return GST_VIDEO_FORMAT_RGB15;
1063   }
1064   if (red_mask == GST_VIDEO_COMP3_MASK_15_INT
1065       && green_mask == GST_VIDEO_COMP2_MASK_15_INT
1066       && blue_mask == GST_VIDEO_COMP1_MASK_15_INT) {
1067     return GST_VIDEO_FORMAT_BGR15;
1068   }
1069
1070   return GST_VIDEO_FORMAT_UNKNOWN;
1071 }
1072
1073 /**
1074  * gst_video_format_is_rgb:
1075  * @format: a #GstVideoFormat
1076  *
1077  * Determine whether the video format is an RGB format.
1078  *
1079  * Since: 0.10.16
1080  *
1081  * Returns: TRUE if @format represents RGB video
1082  */
1083 gboolean
1084 gst_video_format_is_rgb (GstVideoFormat format)
1085 {
1086   switch (format) {
1087     case GST_VIDEO_FORMAT_I420:
1088     case GST_VIDEO_FORMAT_YV12:
1089     case GST_VIDEO_FORMAT_YUY2:
1090     case GST_VIDEO_FORMAT_YVYU:
1091     case GST_VIDEO_FORMAT_UYVY:
1092     case GST_VIDEO_FORMAT_AYUV:
1093     case GST_VIDEO_FORMAT_Y41B:
1094     case GST_VIDEO_FORMAT_Y42B:
1095     case GST_VIDEO_FORMAT_Y444:
1096     case GST_VIDEO_FORMAT_v210:
1097     case GST_VIDEO_FORMAT_v216:
1098     case GST_VIDEO_FORMAT_NV12:
1099     case GST_VIDEO_FORMAT_NV21:
1100     case GST_VIDEO_FORMAT_v308:
1101     case GST_VIDEO_FORMAT_UYVP:
1102     case GST_VIDEO_FORMAT_A420:
1103     case GST_VIDEO_FORMAT_YUV9:
1104     case GST_VIDEO_FORMAT_YVU9:
1105     case GST_VIDEO_FORMAT_IYU1:
1106     case GST_VIDEO_FORMAT_AYUV64:
1107       return FALSE;
1108     case GST_VIDEO_FORMAT_RGBx:
1109     case GST_VIDEO_FORMAT_BGRx:
1110     case GST_VIDEO_FORMAT_xRGB:
1111     case GST_VIDEO_FORMAT_xBGR:
1112     case GST_VIDEO_FORMAT_RGBA:
1113     case GST_VIDEO_FORMAT_BGRA:
1114     case GST_VIDEO_FORMAT_ARGB:
1115     case GST_VIDEO_FORMAT_ABGR:
1116     case GST_VIDEO_FORMAT_RGB:
1117     case GST_VIDEO_FORMAT_BGR:
1118     case GST_VIDEO_FORMAT_RGB16:
1119     case GST_VIDEO_FORMAT_BGR16:
1120     case GST_VIDEO_FORMAT_RGB15:
1121     case GST_VIDEO_FORMAT_BGR15:
1122     case GST_VIDEO_FORMAT_RGB8_PALETTED:
1123     case GST_VIDEO_FORMAT_ARGB64:
1124     case GST_VIDEO_FORMAT_r210:
1125       return TRUE;
1126     default:
1127       return FALSE;
1128   }
1129 }
1130
1131 /**
1132  * gst_video_format_is_yuv:
1133  * @format: a #GstVideoFormat
1134  *
1135  * Determine whether the video format is a YUV format.
1136  *
1137  * Since: 0.10.16
1138  *
1139  * Returns: TRUE if @format represents YUV video
1140  */
1141 gboolean
1142 gst_video_format_is_yuv (GstVideoFormat format)
1143 {
1144   switch (format) {
1145     case GST_VIDEO_FORMAT_I420:
1146     case GST_VIDEO_FORMAT_YV12:
1147     case GST_VIDEO_FORMAT_YUY2:
1148     case GST_VIDEO_FORMAT_YVYU:
1149     case GST_VIDEO_FORMAT_UYVY:
1150     case GST_VIDEO_FORMAT_AYUV:
1151     case GST_VIDEO_FORMAT_Y41B:
1152     case GST_VIDEO_FORMAT_Y42B:
1153     case GST_VIDEO_FORMAT_Y444:
1154     case GST_VIDEO_FORMAT_v210:
1155     case GST_VIDEO_FORMAT_v216:
1156     case GST_VIDEO_FORMAT_NV12:
1157     case GST_VIDEO_FORMAT_NV21:
1158     case GST_VIDEO_FORMAT_v308:
1159     case GST_VIDEO_FORMAT_Y800:
1160     case GST_VIDEO_FORMAT_Y16:
1161     case GST_VIDEO_FORMAT_UYVP:
1162     case GST_VIDEO_FORMAT_A420:
1163     case GST_VIDEO_FORMAT_YUV9:
1164     case GST_VIDEO_FORMAT_YVU9:
1165     case GST_VIDEO_FORMAT_IYU1:
1166     case GST_VIDEO_FORMAT_AYUV64:
1167       return TRUE;
1168     case GST_VIDEO_FORMAT_RGBx:
1169     case GST_VIDEO_FORMAT_BGRx:
1170     case GST_VIDEO_FORMAT_xRGB:
1171     case GST_VIDEO_FORMAT_xBGR:
1172     case GST_VIDEO_FORMAT_RGBA:
1173     case GST_VIDEO_FORMAT_BGRA:
1174     case GST_VIDEO_FORMAT_ARGB:
1175     case GST_VIDEO_FORMAT_ABGR:
1176     case GST_VIDEO_FORMAT_RGB:
1177     case GST_VIDEO_FORMAT_BGR:
1178     case GST_VIDEO_FORMAT_RGB16:
1179     case GST_VIDEO_FORMAT_BGR16:
1180     case GST_VIDEO_FORMAT_RGB15:
1181     case GST_VIDEO_FORMAT_BGR15:
1182     case GST_VIDEO_FORMAT_RGB8_PALETTED:
1183     case GST_VIDEO_FORMAT_ARGB64:
1184     case GST_VIDEO_FORMAT_r210:
1185       return FALSE;
1186     default:
1187       return FALSE;
1188   }
1189 }
1190
1191 /**
1192  * gst_video_format_is_gray:
1193  * @format: a #GstVideoFormat
1194  *
1195  * Determine whether the video format is a grayscale format.
1196  *
1197  * Since: 0.10.29
1198  *
1199  * Returns: TRUE if @format represents grayscale video
1200  */
1201 gboolean
1202 gst_video_format_is_gray (GstVideoFormat format)
1203 {
1204   switch (format) {
1205     case GST_VIDEO_FORMAT_GRAY8:
1206     case GST_VIDEO_FORMAT_GRAY16_BE:
1207     case GST_VIDEO_FORMAT_GRAY16_LE:
1208     case GST_VIDEO_FORMAT_Y800:
1209     case GST_VIDEO_FORMAT_Y16:
1210       return TRUE;
1211     default:
1212       return FALSE;
1213   }
1214 }
1215
1216 /**
1217  * gst_video_format_has_alpha:
1218  * @format: a #GstVideoFormat
1219  *
1220  * Returns TRUE or FALSE depending on if the video format provides an
1221  * alpha channel.
1222  *
1223  * Since: 0.10.16
1224  *
1225  * Returns: TRUE if @format has an alpha channel
1226  */
1227 gboolean
1228 gst_video_format_has_alpha (GstVideoFormat format)
1229 {
1230   switch (format) {
1231     case GST_VIDEO_FORMAT_I420:
1232     case GST_VIDEO_FORMAT_YV12:
1233     case GST_VIDEO_FORMAT_YUY2:
1234     case GST_VIDEO_FORMAT_YVYU:
1235     case GST_VIDEO_FORMAT_UYVY:
1236     case GST_VIDEO_FORMAT_Y41B:
1237     case GST_VIDEO_FORMAT_Y42B:
1238     case GST_VIDEO_FORMAT_Y444:
1239     case GST_VIDEO_FORMAT_v210:
1240     case GST_VIDEO_FORMAT_v216:
1241     case GST_VIDEO_FORMAT_NV12:
1242     case GST_VIDEO_FORMAT_NV21:
1243     case GST_VIDEO_FORMAT_v308:
1244     case GST_VIDEO_FORMAT_Y800:
1245     case GST_VIDEO_FORMAT_Y16:
1246     case GST_VIDEO_FORMAT_UYVP:
1247     case GST_VIDEO_FORMAT_YUV9:
1248     case GST_VIDEO_FORMAT_YVU9:
1249     case GST_VIDEO_FORMAT_IYU1:
1250       return FALSE;
1251     case GST_VIDEO_FORMAT_AYUV:
1252     case GST_VIDEO_FORMAT_RGBA:
1253     case GST_VIDEO_FORMAT_BGRA:
1254     case GST_VIDEO_FORMAT_ARGB:
1255     case GST_VIDEO_FORMAT_ABGR:
1256     case GST_VIDEO_FORMAT_A420:
1257     case GST_VIDEO_FORMAT_RGB8_PALETTED:
1258     case GST_VIDEO_FORMAT_ARGB64:
1259     case GST_VIDEO_FORMAT_AYUV64:
1260       return TRUE;
1261     case GST_VIDEO_FORMAT_RGBx:
1262     case GST_VIDEO_FORMAT_BGRx:
1263     case GST_VIDEO_FORMAT_xRGB:
1264     case GST_VIDEO_FORMAT_xBGR:
1265     case GST_VIDEO_FORMAT_RGB:
1266     case GST_VIDEO_FORMAT_BGR:
1267     case GST_VIDEO_FORMAT_RGB16:
1268     case GST_VIDEO_FORMAT_BGR16:
1269     case GST_VIDEO_FORMAT_RGB15:
1270     case GST_VIDEO_FORMAT_BGR15:
1271     case GST_VIDEO_FORMAT_r210:
1272       return FALSE;
1273     default:
1274       return FALSE;
1275   }
1276 }
1277
1278 /**
1279  * gst_video_format_get_component_depth:
1280  * @format: a #GstVideoFormat
1281  * @component: the video component (e.g. 0 for 'R' in RGB)
1282  *
1283  * Returns the number of bits used to encode an individual pixel of
1284  * a given @component.  Typically this is 8, although higher and lower
1285  * values are possible for some formats.
1286  *
1287  * Since: 0.10.33
1288  *
1289  * Returns: depth of component
1290  */
1291 int
1292 gst_video_format_get_component_depth (GstVideoFormat format, int component)
1293 {
1294   if (component == 3 && !gst_video_format_has_alpha (format))
1295     return 0;
1296
1297   switch (format) {
1298     case GST_VIDEO_FORMAT_RGB16:
1299     case GST_VIDEO_FORMAT_BGR16:
1300       if (component == 1)
1301         return 6;
1302       return 5;
1303     case GST_VIDEO_FORMAT_RGB15:
1304     case GST_VIDEO_FORMAT_BGR15:
1305       return 5;
1306     case GST_VIDEO_FORMAT_I420:
1307     case GST_VIDEO_FORMAT_YV12:
1308     case GST_VIDEO_FORMAT_YUY2:
1309     case GST_VIDEO_FORMAT_YVYU:
1310     case GST_VIDEO_FORMAT_UYVY:
1311     case GST_VIDEO_FORMAT_Y41B:
1312     case GST_VIDEO_FORMAT_Y42B:
1313     case GST_VIDEO_FORMAT_Y444:
1314     case GST_VIDEO_FORMAT_NV12:
1315     case GST_VIDEO_FORMAT_NV21:
1316     case GST_VIDEO_FORMAT_v308:
1317     case GST_VIDEO_FORMAT_Y800:
1318     case GST_VIDEO_FORMAT_YUV9:
1319     case GST_VIDEO_FORMAT_YVU9:
1320     case GST_VIDEO_FORMAT_IYU1:
1321     case GST_VIDEO_FORMAT_AYUV:
1322     case GST_VIDEO_FORMAT_RGBA:
1323     case GST_VIDEO_FORMAT_BGRA:
1324     case GST_VIDEO_FORMAT_ARGB:
1325     case GST_VIDEO_FORMAT_ABGR:
1326     case GST_VIDEO_FORMAT_A420:
1327     case GST_VIDEO_FORMAT_RGB8_PALETTED:
1328     case GST_VIDEO_FORMAT_RGBx:
1329     case GST_VIDEO_FORMAT_BGRx:
1330     case GST_VIDEO_FORMAT_xRGB:
1331     case GST_VIDEO_FORMAT_xBGR:
1332     case GST_VIDEO_FORMAT_RGB:
1333     case GST_VIDEO_FORMAT_BGR:
1334     default:
1335       return 8;
1336     case GST_VIDEO_FORMAT_v210:
1337     case GST_VIDEO_FORMAT_UYVP:
1338     case GST_VIDEO_FORMAT_r210:
1339       return 10;
1340     case GST_VIDEO_FORMAT_Y16:
1341     case GST_VIDEO_FORMAT_v216:
1342     case GST_VIDEO_FORMAT_ARGB64:
1343     case GST_VIDEO_FORMAT_AYUV64:
1344       return 16;
1345   }
1346
1347 }
1348
1349 /**
1350  * gst_video_format_get_row_stride:
1351  * @format: a #GstVideoFormat
1352  * @component: the component index
1353  * @width: the width of video
1354  *
1355  * Calculates the row stride (number of bytes from one row of pixels to
1356  * the next) for the video component with an index of @component.  For
1357  * YUV video, Y, U, and V have component indices of 0, 1, and 2,
1358  * respectively.  For RGB video, R, G, and B have component indicies of
1359  * 0, 1, and 2, respectively.  Alpha channels, if present, have a component
1360  * index of 3.  The @width parameter always represents the width of the
1361  * video, not the component.
1362  *
1363  * Since: 0.10.16
1364  *
1365  * Returns: row stride of component @component
1366  */
1367 int
1368 gst_video_format_get_row_stride (GstVideoFormat format, int component,
1369     int width)
1370 {
1371   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
1372   g_return_val_if_fail (component >= 0 && component <= 3, 0);
1373   g_return_val_if_fail (width > 0, 0);
1374
1375   switch (format) {
1376     case GST_VIDEO_FORMAT_I420:
1377     case GST_VIDEO_FORMAT_YV12:
1378       if (component == 0) {
1379         return GST_ROUND_UP_4 (width);
1380       } else {
1381         return GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2);
1382       }
1383     case GST_VIDEO_FORMAT_YUY2:
1384     case GST_VIDEO_FORMAT_YVYU:
1385     case GST_VIDEO_FORMAT_UYVY:
1386       return GST_ROUND_UP_4 (width * 2);
1387     case GST_VIDEO_FORMAT_AYUV:
1388     case GST_VIDEO_FORMAT_RGBx:
1389     case GST_VIDEO_FORMAT_BGRx:
1390     case GST_VIDEO_FORMAT_xRGB:
1391     case GST_VIDEO_FORMAT_xBGR:
1392     case GST_VIDEO_FORMAT_RGBA:
1393     case GST_VIDEO_FORMAT_BGRA:
1394     case GST_VIDEO_FORMAT_ARGB:
1395     case GST_VIDEO_FORMAT_ABGR:
1396     case GST_VIDEO_FORMAT_r210:
1397       return width * 4;
1398     case GST_VIDEO_FORMAT_RGB16:
1399     case GST_VIDEO_FORMAT_BGR16:
1400     case GST_VIDEO_FORMAT_RGB15:
1401     case GST_VIDEO_FORMAT_BGR15:
1402       return GST_ROUND_UP_4 (width * 2);
1403     case GST_VIDEO_FORMAT_RGB:
1404     case GST_VIDEO_FORMAT_BGR:
1405     case GST_VIDEO_FORMAT_v308:
1406       return GST_ROUND_UP_4 (width * 3);
1407     case GST_VIDEO_FORMAT_Y41B:
1408       if (component == 0) {
1409         return GST_ROUND_UP_4 (width);
1410       } else {
1411         return GST_ROUND_UP_16 (width) / 4;
1412       }
1413     case GST_VIDEO_FORMAT_Y42B:
1414       if (component == 0) {
1415         return GST_ROUND_UP_4 (width);
1416       } else {
1417         return GST_ROUND_UP_8 (width) / 2;
1418       }
1419     case GST_VIDEO_FORMAT_Y444:
1420       return GST_ROUND_UP_4 (width);
1421     case GST_VIDEO_FORMAT_v210:
1422       return ((width + 47) / 48) * 128;
1423     case GST_VIDEO_FORMAT_v216:
1424       return GST_ROUND_UP_8 (width * 4);
1425     case GST_VIDEO_FORMAT_NV12:
1426     case GST_VIDEO_FORMAT_NV21:
1427       return GST_ROUND_UP_4 (width);
1428     case GST_VIDEO_FORMAT_GRAY8:
1429     case GST_VIDEO_FORMAT_Y800:
1430       return GST_ROUND_UP_4 (width);
1431     case GST_VIDEO_FORMAT_GRAY16_BE:
1432     case GST_VIDEO_FORMAT_GRAY16_LE:
1433     case GST_VIDEO_FORMAT_Y16:
1434       return GST_ROUND_UP_4 (width * 2);
1435     case GST_VIDEO_FORMAT_UYVP:
1436       return GST_ROUND_UP_4 ((width * 2 * 5 + 3) / 4);
1437     case GST_VIDEO_FORMAT_A420:
1438       if (component == 0 || component == 3) {
1439         return GST_ROUND_UP_4 (width);
1440       } else {
1441         return GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2);
1442       }
1443     case GST_VIDEO_FORMAT_RGB8_PALETTED:
1444       return GST_ROUND_UP_4 (width);
1445     case GST_VIDEO_FORMAT_YUV9:
1446     case GST_VIDEO_FORMAT_YVU9:
1447       if (component == 0) {
1448         return GST_ROUND_UP_4 (width);
1449       } else {
1450         return GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4);
1451       }
1452     case GST_VIDEO_FORMAT_IYU1:
1453       return GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) +
1454           GST_ROUND_UP_4 (width) / 2);
1455     case GST_VIDEO_FORMAT_ARGB64:
1456     case GST_VIDEO_FORMAT_AYUV64:
1457       return width * 8;
1458     default:
1459       return 0;
1460   }
1461 }
1462
1463 /**
1464  * gst_video_format_get_pixel_stride:
1465  * @format: a #GstVideoFormat
1466  * @component: the component index
1467  *
1468  * Calculates the pixel stride (number of bytes from one pixel to the
1469  * pixel to its immediate left) for the video component with an index
1470  * of @component.  See @gst_video_format_get_row_stride for a description
1471  * of the component index.
1472  *
1473  * Since: 0.10.16
1474  *
1475  * Returns: pixel stride of component @component
1476  */
1477 int
1478 gst_video_format_get_pixel_stride (GstVideoFormat format, int component)
1479 {
1480   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
1481   g_return_val_if_fail (component >= 0 && component <= 3, 0);
1482
1483   switch (format) {
1484     case GST_VIDEO_FORMAT_I420:
1485     case GST_VIDEO_FORMAT_YV12:
1486     case GST_VIDEO_FORMAT_Y41B:
1487     case GST_VIDEO_FORMAT_Y42B:
1488     case GST_VIDEO_FORMAT_Y444:
1489     case GST_VIDEO_FORMAT_A420:
1490     case GST_VIDEO_FORMAT_YUV9:
1491     case GST_VIDEO_FORMAT_YVU9:
1492       return 1;
1493     case GST_VIDEO_FORMAT_YUY2:
1494     case GST_VIDEO_FORMAT_YVYU:
1495     case GST_VIDEO_FORMAT_UYVY:
1496       if (component == 0) {
1497         return 2;
1498       } else {
1499         return 4;
1500       }
1501     case GST_VIDEO_FORMAT_IYU1:
1502       /* doesn't make much sense for IYU1 because it's 1 or 3
1503        * for luma depending on position */
1504       return 0;
1505     case GST_VIDEO_FORMAT_AYUV:
1506     case GST_VIDEO_FORMAT_RGBx:
1507     case GST_VIDEO_FORMAT_BGRx:
1508     case GST_VIDEO_FORMAT_xRGB:
1509     case GST_VIDEO_FORMAT_xBGR:
1510     case GST_VIDEO_FORMAT_RGBA:
1511     case GST_VIDEO_FORMAT_BGRA:
1512     case GST_VIDEO_FORMAT_ARGB:
1513     case GST_VIDEO_FORMAT_ABGR:
1514     case GST_VIDEO_FORMAT_r210:
1515       return 4;
1516     case GST_VIDEO_FORMAT_RGB16:
1517     case GST_VIDEO_FORMAT_BGR16:
1518     case GST_VIDEO_FORMAT_RGB15:
1519     case GST_VIDEO_FORMAT_BGR15:
1520       return 2;
1521     case GST_VIDEO_FORMAT_RGB:
1522     case GST_VIDEO_FORMAT_BGR:
1523     case GST_VIDEO_FORMAT_v308:
1524       return 3;
1525     case GST_VIDEO_FORMAT_v210:
1526       /* v210 is packed at the bit level, so pixel stride doesn't make sense */
1527       return 0;
1528     case GST_VIDEO_FORMAT_v216:
1529       if (component == 0) {
1530         return 4;
1531       } else {
1532         return 8;
1533       }
1534     case GST_VIDEO_FORMAT_NV12:
1535     case GST_VIDEO_FORMAT_NV21:
1536       if (component == 0) {
1537         return 1;
1538       } else {
1539         return 2;
1540       }
1541     case GST_VIDEO_FORMAT_GRAY8:
1542     case GST_VIDEO_FORMAT_Y800:
1543       return 1;
1544     case GST_VIDEO_FORMAT_GRAY16_BE:
1545     case GST_VIDEO_FORMAT_GRAY16_LE:
1546     case GST_VIDEO_FORMAT_Y16:
1547       return 2;
1548     case GST_VIDEO_FORMAT_UYVP:
1549       /* UYVP is packed at the bit level, so pixel stride doesn't make sense */
1550       return 0;
1551     case GST_VIDEO_FORMAT_RGB8_PALETTED:
1552       return 1;
1553     case GST_VIDEO_FORMAT_ARGB64:
1554     case GST_VIDEO_FORMAT_AYUV64:
1555       return 8;
1556     default:
1557       return 0;
1558   }
1559 }
1560
1561 /**
1562  * gst_video_format_get_component_width:
1563  * @format: a #GstVideoFormat
1564  * @component: the component index
1565  * @width: the width of video
1566  *
1567  * Calculates the width of the component.  See
1568  * @gst_video_format_get_row_stride for a description
1569  * of the component index.
1570  *
1571  * Since: 0.10.16
1572  *
1573  * Returns: width of component @component
1574  */
1575 int
1576 gst_video_format_get_component_width (GstVideoFormat format,
1577     int component, int width)
1578 {
1579   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
1580   g_return_val_if_fail (component >= 0 && component <= 3, 0);
1581   g_return_val_if_fail (width > 0, 0);
1582
1583   switch (format) {
1584     case GST_VIDEO_FORMAT_I420:
1585     case GST_VIDEO_FORMAT_YV12:
1586     case GST_VIDEO_FORMAT_YUY2:
1587     case GST_VIDEO_FORMAT_YVYU:
1588     case GST_VIDEO_FORMAT_UYVY:
1589     case GST_VIDEO_FORMAT_Y42B:
1590     case GST_VIDEO_FORMAT_v210:
1591     case GST_VIDEO_FORMAT_v216:
1592     case GST_VIDEO_FORMAT_NV12:
1593     case GST_VIDEO_FORMAT_NV21:
1594     case GST_VIDEO_FORMAT_UYVP:
1595       if (component == 0) {
1596         return width;
1597       } else {
1598         return GST_ROUND_UP_2 (width) / 2;
1599       }
1600     case GST_VIDEO_FORMAT_Y41B:
1601     case GST_VIDEO_FORMAT_YUV9:
1602     case GST_VIDEO_FORMAT_YVU9:
1603     case GST_VIDEO_FORMAT_IYU1:
1604       if (component == 0) {
1605         return width;
1606       } else {
1607         return GST_ROUND_UP_4 (width) / 4;
1608       }
1609     case GST_VIDEO_FORMAT_AYUV:
1610     case GST_VIDEO_FORMAT_RGBx:
1611     case GST_VIDEO_FORMAT_BGRx:
1612     case GST_VIDEO_FORMAT_xRGB:
1613     case GST_VIDEO_FORMAT_xBGR:
1614     case GST_VIDEO_FORMAT_RGBA:
1615     case GST_VIDEO_FORMAT_BGRA:
1616     case GST_VIDEO_FORMAT_ARGB:
1617     case GST_VIDEO_FORMAT_ABGR:
1618     case GST_VIDEO_FORMAT_RGB:
1619     case GST_VIDEO_FORMAT_BGR:
1620     case GST_VIDEO_FORMAT_RGB16:
1621     case GST_VIDEO_FORMAT_BGR16:
1622     case GST_VIDEO_FORMAT_RGB15:
1623     case GST_VIDEO_FORMAT_BGR15:
1624     case GST_VIDEO_FORMAT_Y444:
1625     case GST_VIDEO_FORMAT_v308:
1626     case GST_VIDEO_FORMAT_GRAY8:
1627     case GST_VIDEO_FORMAT_GRAY16_BE:
1628     case GST_VIDEO_FORMAT_GRAY16_LE:
1629     case GST_VIDEO_FORMAT_Y800:
1630     case GST_VIDEO_FORMAT_Y16:
1631     case GST_VIDEO_FORMAT_RGB8_PALETTED:
1632     case GST_VIDEO_FORMAT_ARGB64:
1633     case GST_VIDEO_FORMAT_AYUV64:
1634     case GST_VIDEO_FORMAT_r210:
1635       return width;
1636     case GST_VIDEO_FORMAT_A420:
1637       if (component == 0 || component == 3) {
1638         return width;
1639       } else {
1640         return GST_ROUND_UP_2 (width) / 2;
1641       }
1642     default:
1643       return 0;
1644   }
1645 }
1646
1647 /**
1648  * gst_video_format_get_component_height:
1649  * @format: a #GstVideoFormat
1650  * @component: the component index
1651  * @height: the height of video
1652  *
1653  * Calculates the height of the component.  See
1654  * @gst_video_format_get_row_stride for a description
1655  * of the component index.
1656  *
1657  * Since: 0.10.16
1658  *
1659  * Returns: height of component @component
1660  */
1661 int
1662 gst_video_format_get_component_height (GstVideoFormat format,
1663     int component, int height)
1664 {
1665   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
1666   g_return_val_if_fail (component >= 0 && component <= 3, 0);
1667   g_return_val_if_fail (height > 0, 0);
1668
1669   switch (format) {
1670     case GST_VIDEO_FORMAT_I420:
1671     case GST_VIDEO_FORMAT_YV12:
1672     case GST_VIDEO_FORMAT_NV12:
1673     case GST_VIDEO_FORMAT_NV21:
1674       if (component == 0) {
1675         return height;
1676       } else {
1677         return GST_ROUND_UP_2 (height) / 2;
1678       }
1679     case GST_VIDEO_FORMAT_Y41B:
1680     case GST_VIDEO_FORMAT_Y42B:
1681     case GST_VIDEO_FORMAT_YUY2:
1682     case GST_VIDEO_FORMAT_YVYU:
1683     case GST_VIDEO_FORMAT_UYVY:
1684     case GST_VIDEO_FORMAT_AYUV:
1685     case GST_VIDEO_FORMAT_RGBx:
1686     case GST_VIDEO_FORMAT_BGRx:
1687     case GST_VIDEO_FORMAT_xRGB:
1688     case GST_VIDEO_FORMAT_xBGR:
1689     case GST_VIDEO_FORMAT_RGBA:
1690     case GST_VIDEO_FORMAT_BGRA:
1691     case GST_VIDEO_FORMAT_ARGB:
1692     case GST_VIDEO_FORMAT_ABGR:
1693     case GST_VIDEO_FORMAT_RGB:
1694     case GST_VIDEO_FORMAT_BGR:
1695     case GST_VIDEO_FORMAT_RGB16:
1696     case GST_VIDEO_FORMAT_BGR16:
1697     case GST_VIDEO_FORMAT_RGB15:
1698     case GST_VIDEO_FORMAT_BGR15:
1699     case GST_VIDEO_FORMAT_Y444:
1700     case GST_VIDEO_FORMAT_v210:
1701     case GST_VIDEO_FORMAT_v216:
1702     case GST_VIDEO_FORMAT_v308:
1703     case GST_VIDEO_FORMAT_GRAY8:
1704     case GST_VIDEO_FORMAT_GRAY16_BE:
1705     case GST_VIDEO_FORMAT_GRAY16_LE:
1706     case GST_VIDEO_FORMAT_Y800:
1707     case GST_VIDEO_FORMAT_Y16:
1708     case GST_VIDEO_FORMAT_UYVP:
1709     case GST_VIDEO_FORMAT_RGB8_PALETTED:
1710     case GST_VIDEO_FORMAT_IYU1:
1711     case GST_VIDEO_FORMAT_ARGB64:
1712     case GST_VIDEO_FORMAT_AYUV64:
1713     case GST_VIDEO_FORMAT_r210:
1714       return height;
1715     case GST_VIDEO_FORMAT_A420:
1716       if (component == 0 || component == 3) {
1717         return height;
1718       } else {
1719         return GST_ROUND_UP_2 (height) / 2;
1720       }
1721     case GST_VIDEO_FORMAT_YUV9:
1722     case GST_VIDEO_FORMAT_YVU9:
1723       if (component == 0) {
1724         return height;
1725       } else {
1726         return GST_ROUND_UP_4 (height) / 4;
1727       }
1728     default:
1729       return 0;
1730   }
1731 }
1732
1733 /**
1734  * gst_video_format_get_component_offset:
1735  * @format: a #GstVideoFormat
1736  * @component: the component index
1737  * @width: the width of video
1738  * @height: the height of video
1739  *
1740  * Calculates the offset (in bytes) of the first pixel of the component
1741  * with index @component.  For packed formats, this will typically be a
1742  * small integer (0, 1, 2, 3).  For planar formats, this will be a
1743  * (relatively) large offset to the beginning of the second or third
1744  * component planes.  See @gst_video_format_get_row_stride for a description
1745  * of the component index.
1746  *
1747  * Since: 0.10.16
1748  *
1749  * Returns: offset of component @component
1750  */
1751 int
1752 gst_video_format_get_component_offset (GstVideoFormat format,
1753     int component, int width, int height)
1754 {
1755   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
1756   g_return_val_if_fail (component >= 0 && component <= 3, 0);
1757   g_return_val_if_fail ((!gst_video_format_is_yuv (format)) || (width > 0
1758           && height > 0), 0);
1759
1760   switch (format) {
1761     case GST_VIDEO_FORMAT_I420:
1762       if (component == 0)
1763         return 0;
1764       if (component == 1)
1765         return GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height);
1766       if (component == 2) {
1767         return GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height) +
1768             GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2) *
1769             (GST_ROUND_UP_2 (height) / 2);
1770       }
1771       break;
1772     case GST_VIDEO_FORMAT_YV12:        /* same as I420, but components 1+2 swapped */
1773       if (component == 0)
1774         return 0;
1775       if (component == 2)
1776         return GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height);
1777       if (component == 1) {
1778         return GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height) +
1779             GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2) *
1780             (GST_ROUND_UP_2 (height) / 2);
1781       }
1782       break;
1783     case GST_VIDEO_FORMAT_YUY2:
1784       if (component == 0)
1785         return 0;
1786       if (component == 1)
1787         return 1;
1788       if (component == 2)
1789         return 3;
1790       break;
1791     case GST_VIDEO_FORMAT_YVYU:
1792       if (component == 0)
1793         return 0;
1794       if (component == 1)
1795         return 3;
1796       if (component == 2)
1797         return 1;
1798       break;
1799     case GST_VIDEO_FORMAT_UYVY:
1800       if (component == 0)
1801         return 1;
1802       if (component == 1)
1803         return 0;
1804       if (component == 2)
1805         return 2;
1806       break;
1807     case GST_VIDEO_FORMAT_AYUV:
1808       if (component == 0)
1809         return 1;
1810       if (component == 1)
1811         return 2;
1812       if (component == 2)
1813         return 3;
1814       if (component == 3)
1815         return 0;
1816       break;
1817     case GST_VIDEO_FORMAT_RGBx:
1818     case GST_VIDEO_FORMAT_RGBA:
1819       if (component == 0)
1820         return 0;
1821       if (component == 1)
1822         return 1;
1823       if (component == 2)
1824         return 2;
1825       if (component == 3)
1826         return 3;
1827       break;
1828     case GST_VIDEO_FORMAT_BGRx:
1829     case GST_VIDEO_FORMAT_BGRA:
1830       if (component == 0)
1831         return 2;
1832       if (component == 1)
1833         return 1;
1834       if (component == 2)
1835         return 0;
1836       if (component == 3)
1837         return 3;
1838       break;
1839     case GST_VIDEO_FORMAT_xRGB:
1840     case GST_VIDEO_FORMAT_ARGB:
1841       if (component == 0)
1842         return 1;
1843       if (component == 1)
1844         return 2;
1845       if (component == 2)
1846         return 3;
1847       if (component == 3)
1848         return 0;
1849       break;
1850     case GST_VIDEO_FORMAT_xBGR:
1851     case GST_VIDEO_FORMAT_ABGR:
1852       if (component == 0)
1853         return 3;
1854       if (component == 1)
1855         return 2;
1856       if (component == 2)
1857         return 1;
1858       if (component == 3)
1859         return 0;
1860       break;
1861     case GST_VIDEO_FORMAT_RGB:
1862     case GST_VIDEO_FORMAT_v308:
1863       if (component == 0)
1864         return 0;
1865       if (component == 1)
1866         return 1;
1867       if (component == 2)
1868         return 2;
1869       break;
1870     case GST_VIDEO_FORMAT_BGR:
1871       if (component == 0)
1872         return 2;
1873       if (component == 1)
1874         return 1;
1875       if (component == 2)
1876         return 0;
1877       break;
1878     case GST_VIDEO_FORMAT_Y41B:
1879       if (component == 0)
1880         return 0;
1881       if (component == 1)
1882         return GST_ROUND_UP_4 (width) * height;
1883       if (component == 2)
1884         return (GST_ROUND_UP_4 (width) +
1885             (GST_ROUND_UP_16 (width) / 4)) * height;
1886       break;
1887     case GST_VIDEO_FORMAT_Y42B:
1888       if (component == 0)
1889         return 0;
1890       if (component == 1)
1891         return GST_ROUND_UP_4 (width) * height;
1892       if (component == 2)
1893         return (GST_ROUND_UP_4 (width) + (GST_ROUND_UP_8 (width) / 2)) * height;
1894       break;
1895     case GST_VIDEO_FORMAT_Y444:
1896       return GST_ROUND_UP_4 (width) * height * component;
1897     case GST_VIDEO_FORMAT_v210:
1898     case GST_VIDEO_FORMAT_r210:
1899       /* v210 is bit-packed, so this doesn't make sense */
1900       return 0;
1901     case GST_VIDEO_FORMAT_v216:
1902       if (component == 0)
1903         return 0;
1904       if (component == 1)
1905         return 2;
1906       if (component == 2)
1907         return 6;
1908       break;
1909     case GST_VIDEO_FORMAT_NV12:
1910       if (component == 0)
1911         return 0;
1912       if (component == 1)
1913         return GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height);
1914       if (component == 2)
1915         return GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height) + 1;
1916       break;
1917     case GST_VIDEO_FORMAT_NV21:
1918       if (component == 0)
1919         return 0;
1920       if (component == 1)
1921         return GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height) + 1;
1922       if (component == 2)
1923         return GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height);
1924       break;
1925     case GST_VIDEO_FORMAT_GRAY8:
1926     case GST_VIDEO_FORMAT_GRAY16_BE:
1927     case GST_VIDEO_FORMAT_GRAY16_LE:
1928     case GST_VIDEO_FORMAT_Y800:
1929     case GST_VIDEO_FORMAT_Y16:
1930       return 0;
1931     case GST_VIDEO_FORMAT_UYVP:
1932       /* UYVP is bit-packed, so this doesn't make sense */
1933       return 0;
1934     case GST_VIDEO_FORMAT_A420:
1935       if (component == 0)
1936         return 0;
1937       if (component == 1)
1938         return GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height);
1939       if (component == 2) {
1940         return GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height) +
1941             GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2) *
1942             (GST_ROUND_UP_2 (height) / 2);
1943       }
1944       if (component == 3) {
1945         return GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height) +
1946             2 * GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2) *
1947             (GST_ROUND_UP_2 (height) / 2);
1948       }
1949       break;
1950     case GST_VIDEO_FORMAT_RGB8_PALETTED:
1951       return 0;
1952     case GST_VIDEO_FORMAT_YUV9:
1953       if (component == 0)
1954         return 0;
1955       if (component == 1)
1956         return GST_ROUND_UP_4 (width) * height;
1957       if (component == 2) {
1958         return GST_ROUND_UP_4 (width) * height +
1959             GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4) *
1960             (GST_ROUND_UP_4 (height) / 4);
1961       }
1962       break;
1963     case GST_VIDEO_FORMAT_YVU9:
1964       if (component == 0)
1965         return 0;
1966       if (component == 1) {
1967         return GST_ROUND_UP_4 (width) * height +
1968             GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4) *
1969             (GST_ROUND_UP_4 (height) / 4);
1970       }
1971       if (component == 2)
1972         return GST_ROUND_UP_4 (width) * height;
1973       break;
1974     case GST_VIDEO_FORMAT_IYU1:
1975       if (component == 0)
1976         return 1;
1977       if (component == 1)
1978         return 0;
1979       if (component == 2)
1980         return 4;
1981       break;
1982     case GST_VIDEO_FORMAT_ARGB64:
1983     case GST_VIDEO_FORMAT_AYUV64:
1984       if (component == 0)
1985         return 2;
1986       if (component == 1)
1987         return 4;
1988       if (component == 2)
1989         return 6;
1990       if (component == 3)
1991         return 0;
1992       break;
1993     default:
1994       break;
1995   }
1996   GST_WARNING ("unhandled format %d or component %d", format, component);
1997   return 0;
1998 }
1999
2000 /**
2001  * gst_video_format_get_size:
2002  * @format: a #GstVideoFormat
2003  * @width: the width of video
2004  * @height: the height of video
2005  *
2006  * Calculates the total number of bytes in the raw video format.  This
2007  * number should be used when allocating a buffer for raw video.
2008  *
2009  * Since: 0.10.16
2010  *
2011  * Returns: size (in bytes) of raw video format
2012  */
2013 int
2014 gst_video_format_get_size (GstVideoFormat format, int width, int height)
2015 {
2016   int size;
2017
2018   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
2019   g_return_val_if_fail (width > 0 && height > 0, 0);
2020
2021   switch (format) {
2022     case GST_VIDEO_FORMAT_I420:
2023     case GST_VIDEO_FORMAT_YV12:
2024       size = GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height);
2025       size += GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2) *
2026           (GST_ROUND_UP_2 (height) / 2) * 2;
2027       return size;
2028     case GST_VIDEO_FORMAT_IYU1:
2029       return GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) +
2030           GST_ROUND_UP_4 (width) / 2) * height;
2031     case GST_VIDEO_FORMAT_YUY2:
2032     case GST_VIDEO_FORMAT_YVYU:
2033     case GST_VIDEO_FORMAT_UYVY:
2034       return GST_ROUND_UP_4 (width * 2) * height;
2035     case GST_VIDEO_FORMAT_AYUV:
2036     case GST_VIDEO_FORMAT_RGBx:
2037     case GST_VIDEO_FORMAT_BGRx:
2038     case GST_VIDEO_FORMAT_xRGB:
2039     case GST_VIDEO_FORMAT_xBGR:
2040     case GST_VIDEO_FORMAT_RGBA:
2041     case GST_VIDEO_FORMAT_BGRA:
2042     case GST_VIDEO_FORMAT_ARGB:
2043     case GST_VIDEO_FORMAT_ABGR:
2044     case GST_VIDEO_FORMAT_r210:
2045       return width * 4 * height;
2046     case GST_VIDEO_FORMAT_RGB16:
2047     case GST_VIDEO_FORMAT_BGR16:
2048     case GST_VIDEO_FORMAT_RGB15:
2049     case GST_VIDEO_FORMAT_BGR15:
2050       return GST_ROUND_UP_4 (width * 2) * height;
2051     case GST_VIDEO_FORMAT_RGB:
2052     case GST_VIDEO_FORMAT_BGR:
2053     case GST_VIDEO_FORMAT_v308:
2054       return GST_ROUND_UP_4 (width * 3) * height;
2055     case GST_VIDEO_FORMAT_Y41B:
2056       /* simplification of ROUNDUP4(w)*h + 2*((ROUNDUP16(w)/4)*h */
2057       return (GST_ROUND_UP_4 (width) + (GST_ROUND_UP_16 (width) / 2)) * height;
2058     case GST_VIDEO_FORMAT_Y42B:
2059       /* simplification of ROUNDUP4(w)*h + 2*(ROUNDUP8(w)/2)*h */
2060       return (GST_ROUND_UP_4 (width) + GST_ROUND_UP_8 (width)) * height;
2061     case GST_VIDEO_FORMAT_Y444:
2062       return GST_ROUND_UP_4 (width) * height * 3;
2063     case GST_VIDEO_FORMAT_v210:
2064       return ((width + 47) / 48) * 128 * height;
2065     case GST_VIDEO_FORMAT_v216:
2066       return GST_ROUND_UP_8 (width * 4) * height;
2067     case GST_VIDEO_FORMAT_NV12:
2068     case GST_VIDEO_FORMAT_NV21:
2069       return GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height) * 3 / 2;
2070     case GST_VIDEO_FORMAT_GRAY8:
2071     case GST_VIDEO_FORMAT_Y800:
2072     case GST_VIDEO_FORMAT_RGB8_PALETTED:
2073       return GST_ROUND_UP_4 (width) * height;
2074     case GST_VIDEO_FORMAT_GRAY16_BE:
2075     case GST_VIDEO_FORMAT_GRAY16_LE:
2076     case GST_VIDEO_FORMAT_Y16:
2077       return GST_ROUND_UP_4 (width * 2) * height;
2078     case GST_VIDEO_FORMAT_UYVP:
2079       return GST_ROUND_UP_4 ((width * 2 * 5 + 3) / 4) * height;
2080     case GST_VIDEO_FORMAT_A420:
2081       size = 2 * GST_ROUND_UP_4 (width) * GST_ROUND_UP_2 (height);
2082       size += GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2) *
2083           (GST_ROUND_UP_2 (height) / 2) * 2;
2084       return size;
2085     case GST_VIDEO_FORMAT_YUV9:
2086     case GST_VIDEO_FORMAT_YVU9:
2087       size = GST_ROUND_UP_4 (width) * height;
2088       size += GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4) *
2089           (GST_ROUND_UP_4 (height) / 4) * 2;
2090       return size;
2091     case GST_VIDEO_FORMAT_ARGB64:
2092     case GST_VIDEO_FORMAT_AYUV64:
2093       return width * 8 * height;
2094     default:
2095       return 0;
2096   }
2097 }
2098
2099 /**
2100  * gst_video_get_size_from_caps:
2101  * @caps: a pointer to #GstCaps
2102  * @size: a pointer to a gint that will be assigned the size (in bytes) of a video frame with the given caps
2103  *
2104  * Calculates the total number of bytes in the raw video format for the given
2105  * caps.  This number should be used when allocating a buffer for raw video.
2106  *
2107  * Since: 0.10.34
2108  *
2109  * Returns: %TRUE if the size could be calculated from the caps
2110  */
2111 gboolean
2112 gst_video_get_size_from_caps (const GstCaps * caps, gint * size)
2113 {
2114   GstVideoFormat format = 0;
2115   gint width = 0, height = 0;
2116
2117   g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
2118   g_return_val_if_fail (size != NULL, FALSE);
2119
2120   if (gst_video_format_parse_caps (caps, &format, &width, &height) == FALSE) {
2121     GST_WARNING ("Could not parse caps: %" GST_PTR_FORMAT, caps);
2122     return FALSE;
2123   }
2124
2125   *size = gst_video_format_get_size (format, width, height);
2126   return TRUE;
2127 }
2128
2129 /**
2130  * gst_video_format_convert:
2131  * @format: a #GstVideoFormat
2132  * @width: the width of video
2133  * @height: the height of video
2134  * @fps_n: frame rate numerator
2135  * @fps_d: frame rate denominator
2136  * @src_format: #GstFormat of the @src_value
2137  * @src_value: value to convert
2138  * @dest_format: #GstFormat of the @dest_value
2139  * @dest_value: pointer to destination value
2140  *
2141  * Converts among various #GstFormat types.  This function handles
2142  * GST_FORMAT_BYTES, GST_FORMAT_TIME, and GST_FORMAT_DEFAULT.  For
2143  * raw video, GST_FORMAT_DEFAULT corresponds to video frames.  This
2144  * function can be to handle pad queries of the type GST_QUERY_CONVERT.
2145  *
2146  * Since: 0.10.16
2147  *
2148  * Returns: TRUE if the conversion was successful.
2149  */
2150 gboolean
2151 gst_video_format_convert (GstVideoFormat format, int width, int height,
2152     int fps_n, int fps_d,
2153     GstFormat src_format, gint64 src_value,
2154     GstFormat dest_format, gint64 * dest_value)
2155 {
2156   gboolean ret = FALSE;
2157   int size;
2158
2159   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
2160   g_return_val_if_fail (width > 0 && height > 0, 0);
2161
2162   size = gst_video_format_get_size (format, width, height);
2163
2164   GST_DEBUG ("converting value %" G_GINT64_FORMAT " from %s to %s",
2165       src_value, gst_format_get_name (src_format),
2166       gst_format_get_name (dest_format));
2167
2168   if (src_format == dest_format) {
2169     *dest_value = src_value;
2170     ret = TRUE;
2171     goto done;
2172   }
2173
2174   if (src_value == -1) {
2175     *dest_value = -1;
2176     ret = TRUE;
2177     goto done;
2178   }
2179
2180   /* bytes to frames */
2181   if (src_format == GST_FORMAT_BYTES && dest_format == GST_FORMAT_DEFAULT) {
2182     if (size != 0) {
2183       *dest_value = gst_util_uint64_scale_int (src_value, 1, size);
2184     } else {
2185       GST_ERROR ("blocksize is 0");
2186       *dest_value = 0;
2187     }
2188     ret = TRUE;
2189     goto done;
2190   }
2191
2192   /* frames to bytes */
2193   if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_BYTES) {
2194     *dest_value = gst_util_uint64_scale_int (src_value, size, 1);
2195     ret = TRUE;
2196     goto done;
2197   }
2198
2199   /* time to frames */
2200   if (src_format == GST_FORMAT_TIME && dest_format == GST_FORMAT_DEFAULT) {
2201     if (fps_d != 0) {
2202       *dest_value = gst_util_uint64_scale (src_value,
2203           fps_n, GST_SECOND * fps_d);
2204     } else {
2205       GST_ERROR ("framerate denominator is 0");
2206       *dest_value = 0;
2207     }
2208     ret = TRUE;
2209     goto done;
2210   }
2211
2212   /* frames to time */
2213   if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_TIME) {
2214     if (fps_n != 0) {
2215       *dest_value = gst_util_uint64_scale (src_value,
2216           GST_SECOND * fps_d, fps_n);
2217     } else {
2218       GST_ERROR ("framerate numerator is 0");
2219       *dest_value = 0;
2220     }
2221     ret = TRUE;
2222     goto done;
2223   }
2224
2225   /* time to bytes */
2226   if (src_format == GST_FORMAT_TIME && dest_format == GST_FORMAT_BYTES) {
2227     if (fps_d != 0) {
2228       *dest_value = gst_util_uint64_scale (src_value,
2229           fps_n * size, GST_SECOND * fps_d);
2230     } else {
2231       GST_ERROR ("framerate denominator is 0");
2232       *dest_value = 0;
2233     }
2234     ret = TRUE;
2235     goto done;
2236   }
2237
2238   /* bytes to time */
2239   if (src_format == GST_FORMAT_BYTES && dest_format == GST_FORMAT_TIME) {
2240     if (fps_n != 0 && size != 0) {
2241       *dest_value = gst_util_uint64_scale (src_value,
2242           GST_SECOND * fps_d, fps_n * size);
2243     } else {
2244       GST_ERROR ("framerate denominator and/or blocksize is 0");
2245       *dest_value = 0;
2246     }
2247     ret = TRUE;
2248   }
2249
2250 done:
2251
2252   GST_DEBUG ("ret=%d result %" G_GINT64_FORMAT, ret, *dest_value);
2253
2254   return ret;
2255 }
2256
2257 #define GST_VIDEO_EVENT_STILL_STATE_NAME "GstEventStillFrame"
2258
2259 /**
2260  * gst_video_event_new_still_frame:
2261  * @in_still: boolean value for the still-frame state of the event.
2262  *
2263  * Creates a new Still Frame event. If @in_still is %TRUE, then the event
2264  * represents the start of a still frame sequence. If it is %FALSE, then
2265  * the event ends a still frame sequence.
2266  *
2267  * To parse an event created by gst_video_event_new_still_frame() use
2268  * gst_video_event_parse_still_frame().
2269  *
2270  * Returns: The new GstEvent
2271  * Since: 0.10.26
2272  */
2273 GstEvent *
2274 gst_video_event_new_still_frame (gboolean in_still)
2275 {
2276   GstEvent *still_event;
2277   GstStructure *s;
2278
2279   s = gst_structure_new (GST_VIDEO_EVENT_STILL_STATE_NAME,
2280       "still-state", G_TYPE_BOOLEAN, in_still, NULL);
2281   still_event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
2282
2283   return still_event;
2284 }
2285
2286 /**
2287  * gst_video_event_parse_still_frame:
2288  * @event: A #GstEvent to parse
2289  * @in_still: A boolean to receive the still-frame status from the event, or NULL
2290  *
2291  * Parse a #GstEvent, identify if it is a Still Frame event, and
2292  * return the still-frame state from the event if it is.
2293  * If the event represents the start of a still frame, the in_still
2294  * variable will be set to TRUE, otherwise FALSE. It is OK to pass NULL for the
2295  * in_still variable order to just check whether the event is a valid still-frame
2296  * event.
2297  *
2298  * Create a still frame event using gst_video_event_new_still_frame()
2299  *
2300  * Returns: %TRUE if the event is a valid still-frame event. %FALSE if not
2301  * Since: 0.10.26
2302  */
2303 gboolean
2304 gst_video_event_parse_still_frame (GstEvent * event, gboolean * in_still)
2305 {
2306   const GstStructure *s;
2307   gboolean ev_still_state;
2308
2309   g_return_val_if_fail (event != NULL, FALSE);
2310
2311   if (GST_EVENT_TYPE (event) != GST_EVENT_CUSTOM_DOWNSTREAM)
2312     return FALSE;               /* Not a still frame event */
2313
2314   s = gst_event_get_structure (event);
2315   if (s == NULL
2316       || !gst_structure_has_name (s, GST_VIDEO_EVENT_STILL_STATE_NAME))
2317     return FALSE;               /* Not a still frame event */
2318   if (!gst_structure_get_boolean (s, "still-state", &ev_still_state))
2319     return FALSE;               /* Not a still frame event */
2320   if (in_still)
2321     *in_still = ev_still_state;
2322   return TRUE;
2323 }
2324
2325 /**
2326  * gst_video_parse_caps_palette:
2327  * @caps: #GstCaps to parse
2328  *
2329  * Returns the palette data from the caps as a #GstBuffer. For
2330  * #GST_VIDEO_FORMAT_RGB8_PALETTED this is containing 256 #guint32
2331  * values, each containing ARGB colors in native endianness.
2332  *
2333  * Returns: a #GstBuffer containing the palette data. Unref after usage.
2334  * Since: 0.10.32
2335  */
2336 GstBuffer *
2337 gst_video_parse_caps_palette (GstCaps * caps)
2338 {
2339   GstStructure *s;
2340   const GValue *p_v;
2341   GstBuffer *p;
2342
2343   if (!gst_caps_is_fixed (caps))
2344     return NULL;
2345
2346   s = gst_caps_get_structure (caps, 0);
2347
2348   p_v = gst_structure_get_value (s, "palette_data");
2349   if (!p_v || !GST_VALUE_HOLDS_BUFFER (p_v))
2350     return NULL;
2351
2352   p = gst_buffer_ref (gst_value_get_buffer (p_v));
2353
2354   return p;
2355 }