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>
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.
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.
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., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
24 * @title: GstVideoInfo
25 * @short_description: Structures and enumerations to describe raw images
35 #include "video-info.h"
36 #include "video-tile.h"
38 #ifndef GST_DISABLE_GST_DEBUG
39 #define GST_CAT_DEFAULT ensure_debug_category()
40 static GstDebugCategory *
41 ensure_debug_category (void)
43 static gsize cat_gonce = 0;
45 if (g_once_init_enter (&cat_gonce)) {
48 cat_done = (gsize) _gst_debug_category_new ("video-info", 0,
49 "video-info structure");
51 g_once_init_leave (&cat_gonce, cat_done);
54 return (GstDebugCategory *) cat_gonce;
57 #define ensure_debug_category() /* NOOP */
58 #endif /* GST_DISABLE_GST_DEBUG */
61 * gst_video_info_copy:
62 * @info: a #GstVideoInfo
64 * Copy a GstVideoInfo structure.
66 * Returns: a new #GstVideoInfo. free with gst_video_info_free.
71 gst_video_info_copy (const GstVideoInfo * info)
73 return g_slice_dup (GstVideoInfo, info);
77 * gst_video_info_free:
78 * @info: a #GstVideoInfo
80 * Free a GstVideoInfo structure previously allocated with gst_video_info_new()
81 * or gst_video_info_copy().
86 gst_video_info_free (GstVideoInfo * info)
88 g_slice_free (GstVideoInfo, info);
91 G_DEFINE_BOXED_TYPE (GstVideoInfo, gst_video_info,
92 (GBoxedCopyFunc) gst_video_info_copy, (GBoxedFreeFunc) gst_video_info_free);
97 * Allocate a new #GstVideoInfo that is also initialized with
98 * gst_video_info_init().
100 * Returns: a new #GstVideoInfo. free with gst_video_info_free().
105 gst_video_info_new (void)
109 info = g_slice_new (GstVideoInfo);
110 gst_video_info_init (info);
115 static gboolean fill_planes (GstVideoInfo * info);
118 * gst_video_info_init:
119 * @info: a #GstVideoInfo
121 * Initialize @info with default values.
124 gst_video_info_init (GstVideoInfo * info)
126 g_return_if_fail (info != NULL);
128 memset (info, 0, sizeof (GstVideoInfo));
130 info->finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_UNKNOWN);
133 /* arrange for sensible defaults, e.g. if turned into caps */
138 GST_VIDEO_INFO_MULTIVIEW_MODE (info) = GST_VIDEO_MULTIVIEW_MODE_NONE;
139 GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
140 GST_VIDEO_INFO_FIELD_ORDER (info) = GST_VIDEO_FIELD_ORDER_UNKNOWN;
143 #define MAKE_COLORIMETRY(r,m,t,p) { \
144 GST_VIDEO_COLOR_RANGE ##r, GST_VIDEO_COLOR_MATRIX_ ##m, \
145 GST_VIDEO_TRANSFER_ ##t, GST_VIDEO_COLOR_PRIMARIES_ ##p }
147 #define DEFAULT_YUV_SD 0
148 #define DEFAULT_YUV_HD 1
149 #define DEFAULT_RGB 2
150 #define DEFAULT_GRAY 3
151 #define DEFAULT_UNKNOWN 4
152 #define DEFAULT_YUV_UHD 5
154 static const GstVideoColorimetry default_color[] = {
155 MAKE_COLORIMETRY (_16_235, BT601, BT709, SMPTE170M),
156 MAKE_COLORIMETRY (_16_235, BT709, BT709, BT709),
157 MAKE_COLORIMETRY (_0_255, RGB, SRGB, BT709),
158 MAKE_COLORIMETRY (_0_255, BT601, UNKNOWN, UNKNOWN),
159 MAKE_COLORIMETRY (_UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN),
160 MAKE_COLORIMETRY (_16_235, BT2020, BT2020_12, BT2020),
164 set_default_colorimetry (GstVideoInfo * info)
166 const GstVideoFormatInfo *finfo = info->finfo;
168 if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo)) {
169 if (info->height >= 2160) {
170 info->chroma_site = GST_VIDEO_CHROMA_SITE_H_COSITED;
171 info->colorimetry = default_color[DEFAULT_YUV_UHD];
172 } else if (info->height > 576) {
173 info->chroma_site = GST_VIDEO_CHROMA_SITE_H_COSITED;
174 info->colorimetry = default_color[DEFAULT_YUV_HD];
176 info->chroma_site = GST_VIDEO_CHROMA_SITE_NONE;
177 info->colorimetry = default_color[DEFAULT_YUV_SD];
179 } else if (GST_VIDEO_FORMAT_INFO_IS_GRAY (finfo)) {
180 info->colorimetry = default_color[DEFAULT_GRAY];
181 } else if (GST_VIDEO_FORMAT_INFO_IS_RGB (finfo)) {
182 info->colorimetry = default_color[DEFAULT_RGB];
184 info->colorimetry = default_color[DEFAULT_UNKNOWN];
189 validate_colorimetry (GstVideoInfo * info)
191 const GstVideoFormatInfo *finfo = info->finfo;
193 if (!GST_VIDEO_FORMAT_INFO_IS_RGB (finfo) &&
194 info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_RGB) {
196 ("color matrix RGB is only supported with RGB format, %s is not",
201 if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo) &&
202 info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_UNKNOWN) {
203 GST_WARNING ("Need to specify a color matrix when using YUV format (%s)",
212 gst_video_info_set_format_common (GstVideoInfo * info, GstVideoFormat format,
213 guint width, guint height)
215 g_return_val_if_fail (info != NULL, FALSE);
216 g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, FALSE);
218 if (width > G_MAXINT || height > G_MAXINT)
221 gst_video_info_init (info);
223 info->finfo = gst_video_format_get_info (format);
225 info->height = height;
228 set_default_colorimetry (info);
234 * gst_video_info_set_format:
235 * @info: a #GstVideoInfo
236 * @format: the format
240 * Set the default info for a video frame of @format and @width and @height.
242 * Note: This initializes @info first, no values are preserved. This function
243 * does not set the offsets correctly for interlaced vertically
244 * subsampled formats.
246 * Returns: %FALSE if the returned video info is invalid, e.g. because the
247 * size of a frame can't be represented as a 32 bit integer (Since: 1.12)
250 gst_video_info_set_format (GstVideoInfo * info, GstVideoFormat format,
251 guint width, guint height)
253 if (!gst_video_info_set_format_common (info, format, width, height))
256 return fill_planes (info);
260 * gst_video_info_set_interlaced_format:
261 * @info: a #GstVideoInfo
262 * @format: the format
263 * @mode: a #GstVideoInterlaceMode
267 * Same as #gst_video_info_set_format but also allowing to set the interlaced
270 * Returns: %FALSE if the returned video info is invalid, e.g. because the
271 * size of a frame can't be represented as a 32 bit integer.
276 gst_video_info_set_interlaced_format (GstVideoInfo * info,
277 GstVideoFormat format, GstVideoInterlaceMode mode, guint width,
280 if (!gst_video_info_set_format_common (info, format, width, height))
283 GST_VIDEO_INFO_INTERLACE_MODE (info) = mode;
284 return fill_planes (info);
287 static const gchar *interlace_mode[] = {
296 * gst_video_interlace_mode_to_string:
297 * @mode: a #GstVideoInterlaceMode
299 * Convert @mode to its string representation.
301 * Returns: @mode as a string or NULL if @mode in invalid.
306 gst_video_interlace_mode_to_string (GstVideoInterlaceMode mode)
308 if (((guint) mode) >= G_N_ELEMENTS (interlace_mode))
311 return interlace_mode[mode];
315 * gst_video_interlace_mode_from_string:
318 * Convert @mode to a #GstVideoInterlaceMode
320 * Returns: the #GstVideoInterlaceMode of @mode or
321 * #GST_VIDEO_INTERLACE_MODE_PROGRESSIVE when @mode is not a valid
322 * string representation for a #GstVideoInterlaceMode.
326 GstVideoInterlaceMode
327 gst_video_interlace_mode_from_string (const gchar * mode)
330 for (i = 0; i < G_N_ELEMENTS (interlace_mode); i++) {
331 if (g_str_equal (interlace_mode[i], mode))
334 return GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
337 static const gchar *field_order[] = {
344 * gst_video_field_order_to_string:
345 * @order: a #GstVideoFieldOrder
347 * Convert @order to its string representation.
349 * Returns: @order as a string or NULL if @order in invalid.
354 gst_video_field_order_to_string (GstVideoFieldOrder order)
356 if (((guint) order) >= G_N_ELEMENTS (field_order))
359 return field_order[order];
363 * gst_video_field_order_from_string:
364 * @order: a field order
366 * Convert @order to a #GstVideoFieldOrder
368 * Returns: the #GstVideoFieldOrder of @order or
369 * #GST_VIDEO_FIELD_ORDER_UNKNOWN when @order is not a valid
370 * string representation for a #GstVideoFieldOrder.
375 gst_video_field_order_from_string (const gchar * order)
378 for (i = 0; i < G_N_ELEMENTS (field_order); i++) {
379 if (g_str_equal (field_order[i], order))
382 return GST_VIDEO_FIELD_ORDER_UNKNOWN;
386 * gst_video_info_from_caps:
387 * @info: a #GstVideoInfo
390 * Parse @caps and update @info.
392 * Returns: TRUE if @caps could be parsed
395 gst_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps)
397 GstStructure *structure;
399 GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
400 gint width = 0, height = 0;
403 guint multiview_flags;
405 g_return_val_if_fail (info != NULL, FALSE);
406 g_return_val_if_fail (caps != NULL, FALSE);
407 g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
409 GST_DEBUG ("parsing caps %" GST_PTR_FORMAT, caps);
411 structure = gst_caps_get_structure (caps, 0);
413 if (gst_structure_has_name (structure, "video/x-raw")) {
414 if (!(s = gst_structure_get_string (structure, "format")))
417 format = gst_video_format_from_string (s);
418 if (format == GST_VIDEO_FORMAT_UNKNOWN)
421 } else if (g_str_has_prefix (gst_structure_get_name (structure), "video/") ||
422 g_str_has_prefix (gst_structure_get_name (structure), "image/")) {
423 format = GST_VIDEO_FORMAT_ENCODED;
428 /* width and height are mandatory, except for non-raw-formats */
429 if (!gst_structure_get_int (structure, "width", &width) &&
430 format != GST_VIDEO_FORMAT_ENCODED)
432 if (!gst_structure_get_int (structure, "height", &height) &&
433 format != GST_VIDEO_FORMAT_ENCODED)
436 gst_video_info_init (info);
438 info->finfo = gst_video_format_get_info (format);
440 info->height = height;
442 if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)) {
444 /* variable framerate */
445 info->flags |= GST_VIDEO_FLAG_VARIABLE_FPS;
446 /* see if we have a max-framerate */
447 gst_structure_get_fraction (structure, "max-framerate", &fps_n, &fps_d);
452 /* unspecified is variable framerate */
457 if (gst_structure_get_fraction (structure, "pixel-aspect-ratio",
466 if ((s = gst_structure_get_string (structure, "interlace-mode")))
467 info->interlace_mode = gst_video_interlace_mode_from_string (s);
469 info->interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
471 /* Interlaced feature is mandatory for raw alternate streams */
472 if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE &&
473 format != GST_VIDEO_FORMAT_ENCODED) {
476 f = gst_caps_get_features (caps, 0);
478 || !gst_caps_features_contains (f, GST_CAPS_FEATURE_FORMAT_INTERLACED))
479 goto alternate_no_feature;
482 if (GST_VIDEO_INFO_IS_INTERLACED (info) &&
483 (s = gst_structure_get_string (structure, "field-order"))) {
484 GST_VIDEO_INFO_FIELD_ORDER (info) = gst_video_field_order_from_string (s);
486 GST_VIDEO_INFO_FIELD_ORDER (info) = GST_VIDEO_FIELD_ORDER_UNKNOWN;
490 if ((s = gst_structure_get_string (structure, "multiview-mode")))
491 GST_VIDEO_INFO_MULTIVIEW_MODE (info) =
492 gst_video_multiview_mode_from_caps_string (s);
494 GST_VIDEO_INFO_MULTIVIEW_MODE (info) = GST_VIDEO_MULTIVIEW_MODE_NONE;
496 if (gst_structure_get_flagset (structure, "multiview-flags",
497 &multiview_flags, NULL))
498 GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) = multiview_flags;
500 if (!gst_structure_get_int (structure, "views", &info->views))
503 /* At one point, I tried normalising the half-aspect flag here,
504 * but it behaves weird for GstVideoInfo operations other than
505 * directly converting to/from caps - sometimes causing the
506 * PAR to be doubled/halved too many times */
509 if ((s = gst_structure_get_string (structure, "chroma-site")))
510 info->chroma_site = gst_video_chroma_from_string (s);
512 info->chroma_site = GST_VIDEO_CHROMA_SITE_UNKNOWN;
514 if ((s = gst_structure_get_string (structure, "colorimetry"))) {
515 if (!gst_video_colorimetry_from_string (&info->colorimetry, s)) {
516 GST_WARNING ("unparsable colorimetry, using default");
517 set_default_colorimetry (info);
518 } else if (!validate_colorimetry (info)) {
519 GST_WARNING ("invalid colorimetry, using default");
520 set_default_colorimetry (info);
522 /* force RGB matrix for RGB formats */
523 if (GST_VIDEO_FORMAT_INFO_IS_RGB (info->finfo) &&
524 info->colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_RGB) {
525 GST_WARNING ("invalid matrix %d for RGB format, using RGB",
526 info->colorimetry.matrix);
527 info->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
531 GST_DEBUG ("no colorimetry, using default");
532 set_default_colorimetry (info);
535 if (!fill_planes (info))
543 GST_ERROR ("wrong name '%s', expected video/ or image/",
544 gst_structure_get_name (structure));
549 GST_ERROR ("no format given");
554 GST_ERROR ("unknown format '%s' given", s);
559 GST_ERROR ("no width property given");
564 GST_ERROR ("no height property given");
567 alternate_no_feature:
570 ("caps has 'interlace-mode=alternate' but doesn't have the Interlaced feature");
576 * gst_video_info_is_equal:
577 * @info: a #GstVideoInfo
578 * @other: a #GstVideoInfo
580 * Compares two #GstVideoInfo and returns whether they are equal or not
582 * Returns: %TRUE if @info and @other are equal, else %FALSE.
585 gst_video_info_is_equal (const GstVideoInfo * info, const GstVideoInfo * other)
589 if (GST_VIDEO_INFO_FORMAT (info) != GST_VIDEO_INFO_FORMAT (other))
591 if (GST_VIDEO_INFO_INTERLACE_MODE (info) !=
592 GST_VIDEO_INFO_INTERLACE_MODE (other))
594 if (GST_VIDEO_INFO_FLAGS (info) != GST_VIDEO_INFO_FLAGS (other))
596 if (GST_VIDEO_INFO_WIDTH (info) != GST_VIDEO_INFO_WIDTH (other))
598 if (GST_VIDEO_INFO_HEIGHT (info) != GST_VIDEO_INFO_HEIGHT (other))
600 if (GST_VIDEO_INFO_SIZE (info) != GST_VIDEO_INFO_SIZE (other))
602 if (GST_VIDEO_INFO_PAR_N (info) != GST_VIDEO_INFO_PAR_N (other))
604 if (GST_VIDEO_INFO_PAR_D (info) != GST_VIDEO_INFO_PAR_D (other))
606 if (GST_VIDEO_INFO_FPS_N (info) != GST_VIDEO_INFO_FPS_N (other))
608 if (GST_VIDEO_INFO_FPS_D (info) != GST_VIDEO_INFO_FPS_D (other))
610 if (!gst_video_colorimetry_is_equal (&GST_VIDEO_INFO_COLORIMETRY (info),
611 &GST_VIDEO_INFO_COLORIMETRY (other)))
613 if (GST_VIDEO_INFO_CHROMA_SITE (info) != GST_VIDEO_INFO_CHROMA_SITE (other))
615 if (GST_VIDEO_INFO_MULTIVIEW_MODE (info) !=
616 GST_VIDEO_INFO_MULTIVIEW_MODE (other))
618 if (GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) !=
619 GST_VIDEO_INFO_MULTIVIEW_FLAGS (other))
621 if (GST_VIDEO_INFO_VIEWS (info) != GST_VIDEO_INFO_VIEWS (other))
624 for (i = 0; i < info->finfo->n_planes; i++) {
625 if (info->stride[i] != other->stride[i])
627 if (info->offset[i] != other->offset[i])
635 * gst_video_info_to_caps:
636 * @info: a #GstVideoInfo
638 * Convert the values of @info into a #GstCaps.
640 * Returns: a new #GstCaps containing the info of @info.
643 gst_video_info_to_caps (GstVideoInfo * info)
649 GstVideoColorimetry colorimetry;
651 g_return_val_if_fail (info != NULL, NULL);
652 g_return_val_if_fail (info->finfo != NULL, NULL);
653 g_return_val_if_fail (info->finfo->format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
655 format = gst_video_format_to_string (info->finfo->format);
656 g_return_val_if_fail (format != NULL, NULL);
658 caps = gst_caps_new_simple ("video/x-raw",
659 "format", G_TYPE_STRING, format,
660 "width", G_TYPE_INT, info->width,
661 "height", G_TYPE_INT, info->height, NULL);
666 gst_caps_set_simple (caps, "interlace-mode", G_TYPE_STRING,
667 gst_video_interlace_mode_to_string (info->interlace_mode), NULL);
669 if ((info->interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED ||
670 info->interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE) &&
671 GST_VIDEO_INFO_FIELD_ORDER (info) != GST_VIDEO_FIELD_ORDER_UNKNOWN) {
672 gst_caps_set_simple (caps, "field-order", G_TYPE_STRING,
673 gst_video_field_order_to_string (GST_VIDEO_INFO_FIELD_ORDER (info)),
677 if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE) {
678 /* 'alternate' mode must always be accompanied by interlaced caps feature.
680 GstCapsFeatures *features;
682 features = gst_caps_features_new (GST_CAPS_FEATURE_FORMAT_INTERLACED, NULL);
683 gst_caps_set_features (caps, 0, features);
686 if (GST_VIDEO_INFO_MULTIVIEW_MODE (info) != GST_VIDEO_MULTIVIEW_MODE_NONE) {
687 const gchar *caps_str = NULL;
689 /* If the half-aspect flag is set, applying it into the PAR of the
690 * resulting caps now seems safe, and helps with automatic behaviour
691 * in elements that aren't explicitly multiview aware */
692 if (GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) &
693 GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT) {
694 GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) &=
695 ~GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
696 switch (GST_VIDEO_INFO_MULTIVIEW_MODE (info)) {
697 case GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE:
698 case GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE_QUINCUNX:
699 case GST_VIDEO_MULTIVIEW_MODE_COLUMN_INTERLEAVED:
700 case GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD:
701 par_n *= 2; /* double the width / half the height */
703 case GST_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED:
704 case GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM:
705 par_d *= 2; /* half the width / double the height */
713 gst_video_multiview_mode_to_caps_string (GST_VIDEO_INFO_MULTIVIEW_MODE
715 if (caps_str != NULL) {
716 gst_caps_set_simple (caps, "multiview-mode", G_TYPE_STRING,
717 caps_str, "multiview-flags", GST_TYPE_VIDEO_MULTIVIEW_FLAGSET,
718 GST_VIDEO_INFO_MULTIVIEW_FLAGS (info), GST_FLAG_SET_MASK_EXACT, NULL);
722 gst_caps_set_simple (caps, "pixel-aspect-ratio",
723 GST_TYPE_FRACTION, par_n, par_d, NULL);
725 if (info->chroma_site != GST_VIDEO_CHROMA_SITE_UNKNOWN)
726 gst_caps_set_simple (caps, "chroma-site", G_TYPE_STRING,
727 gst_video_chroma_to_string (info->chroma_site), NULL);
729 /* make sure we set the RGB matrix for RGB formats */
730 colorimetry = info->colorimetry;
731 if (GST_VIDEO_FORMAT_INFO_IS_RGB (info->finfo) &&
732 colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_RGB) {
733 GST_WARNING ("invalid matrix %d for RGB format, using RGB",
735 colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
737 if ((color = gst_video_colorimetry_to_string (&colorimetry))) {
738 gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, color, NULL);
743 gst_caps_set_simple (caps, "views", G_TYPE_INT, info->views, NULL);
745 if (info->flags & GST_VIDEO_FLAG_VARIABLE_FPS && info->fps_n != 0) {
746 /* variable fps with a max-framerate */
747 gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, 0, 1,
748 "max-framerate", GST_TYPE_FRACTION, info->fps_n, info->fps_d, NULL);
750 /* no variable fps or no max-framerate */
751 gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION,
752 info->fps_n, info->fps_d, NULL);
759 fill_planes (GstVideoInfo * info)
761 gsize width, height, cr_h;
764 width = (gsize) info->width;
765 height = (gsize) GST_VIDEO_INFO_FIELD_HEIGHT (info);
767 /* Sanity check the resulting frame size for overflows */
768 for (i = 0; i < GST_VIDEO_INFO_N_COMPONENTS (info); i++)
769 bpp += GST_VIDEO_INFO_COMP_DEPTH (info, i);
770 bpp = GST_ROUND_UP_8 (bpp) / 8;
771 if (bpp > 0 && GST_ROUND_UP_128 ((guint64) width) * ((guint64) height) >=
773 GST_ERROR ("Frame size %ux%u would overflow", info->width, info->height);
777 switch (info->finfo->format) {
778 case GST_VIDEO_FORMAT_YUY2:
779 case GST_VIDEO_FORMAT_YVYU:
780 case GST_VIDEO_FORMAT_UYVY:
781 case GST_VIDEO_FORMAT_VYUY:
782 info->stride[0] = GST_ROUND_UP_4 (width * 2);
784 info->size = info->stride[0] * height;
786 case GST_VIDEO_FORMAT_AYUV:
787 case GST_VIDEO_FORMAT_RGBx:
788 case GST_VIDEO_FORMAT_RGBA:
789 case GST_VIDEO_FORMAT_BGRx:
790 case GST_VIDEO_FORMAT_BGRA:
791 case GST_VIDEO_FORMAT_xRGB:
792 case GST_VIDEO_FORMAT_ARGB:
793 case GST_VIDEO_FORMAT_xBGR:
794 case GST_VIDEO_FORMAT_ABGR:
795 case GST_VIDEO_FORMAT_r210:
796 case GST_VIDEO_FORMAT_Y410:
797 case GST_VIDEO_FORMAT_VUYA:
798 case GST_VIDEO_FORMAT_BGR10A2_LE:
799 case GST_VIDEO_FORMAT_RGB10A2_LE:
800 info->stride[0] = width * 4;
802 info->size = info->stride[0] * height;
804 case GST_VIDEO_FORMAT_RGB16:
805 case GST_VIDEO_FORMAT_BGR16:
806 case GST_VIDEO_FORMAT_RGB15:
807 case GST_VIDEO_FORMAT_BGR15:
808 info->stride[0] = GST_ROUND_UP_4 (width * 2);
810 info->size = info->stride[0] * height;
812 case GST_VIDEO_FORMAT_RGB:
813 case GST_VIDEO_FORMAT_BGR:
814 case GST_VIDEO_FORMAT_v308:
815 case GST_VIDEO_FORMAT_IYU2:
816 info->stride[0] = GST_ROUND_UP_4 (width * 3);
818 info->size = info->stride[0] * height;
820 case GST_VIDEO_FORMAT_v210:
821 info->stride[0] = ((width + 47) / 48) * 128;
823 info->size = info->stride[0] * height;
825 case GST_VIDEO_FORMAT_v216:
826 case GST_VIDEO_FORMAT_Y210:
827 info->stride[0] = GST_ROUND_UP_8 (width * 4);
829 info->size = info->stride[0] * height;
831 case GST_VIDEO_FORMAT_GRAY8:
832 info->stride[0] = GST_ROUND_UP_4 (width);
834 info->size = info->stride[0] * height;
836 case GST_VIDEO_FORMAT_GRAY16_BE:
837 case GST_VIDEO_FORMAT_GRAY16_LE:
838 info->stride[0] = GST_ROUND_UP_4 (width * 2);
840 info->size = info->stride[0] * height;
842 case GST_VIDEO_FORMAT_UYVP:
843 info->stride[0] = GST_ROUND_UP_4 ((width * 2 * 5 + 3) / 4);
845 info->size = info->stride[0] * height;
847 case GST_VIDEO_FORMAT_RGB8P:
848 info->stride[0] = GST_ROUND_UP_4 (width);
851 info->offset[1] = info->stride[0] * height;
852 info->size = info->offset[1] + (4 * 256);
854 case GST_VIDEO_FORMAT_IYU1:
855 info->stride[0] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) +
856 GST_ROUND_UP_4 (width) / 2);
858 info->size = info->stride[0] * height;
860 case GST_VIDEO_FORMAT_ARGB64:
861 case GST_VIDEO_FORMAT_AYUV64:
862 info->stride[0] = width * 8;
864 info->size = info->stride[0] * height;
866 case GST_VIDEO_FORMAT_I420:
867 case GST_VIDEO_FORMAT_YV12: /* same as I420, but plane 1+2 swapped */
868 info->stride[0] = GST_ROUND_UP_4 (width);
869 info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2);
870 info->stride[2] = info->stride[1];
872 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
873 cr_h = GST_ROUND_UP_2 (height) / 2;
874 if (GST_VIDEO_INFO_IS_INTERLACED (info))
875 cr_h = GST_ROUND_UP_2 (cr_h);
876 info->offset[2] = info->offset[1] + info->stride[1] * cr_h;
877 info->size = info->offset[2] + info->stride[2] * cr_h;
879 case GST_VIDEO_FORMAT_Y41B:
880 info->stride[0] = GST_ROUND_UP_4 (width);
881 info->stride[1] = GST_ROUND_UP_16 (width) / 4;
882 info->stride[2] = info->stride[1];
884 info->offset[1] = info->stride[0] * height;
885 info->offset[2] = info->offset[1] + info->stride[1] * height;
886 /* simplification of ROUNDUP4(w)*h + 2*((ROUNDUP16(w)/4)*h */
887 info->size = (info->stride[0] + (GST_ROUND_UP_16 (width) / 2)) * height;
889 case GST_VIDEO_FORMAT_Y42B:
890 info->stride[0] = GST_ROUND_UP_4 (width);
891 info->stride[1] = GST_ROUND_UP_8 (width) / 2;
892 info->stride[2] = info->stride[1];
894 info->offset[1] = info->stride[0] * height;
895 info->offset[2] = info->offset[1] + info->stride[1] * height;
896 /* simplification of ROUNDUP4(w)*h + 2*(ROUNDUP8(w)/2)*h */
897 info->size = (info->stride[0] + GST_ROUND_UP_8 (width)) * height;
899 case GST_VIDEO_FORMAT_Y444:
900 case GST_VIDEO_FORMAT_GBR:
901 info->stride[0] = GST_ROUND_UP_4 (width);
902 info->stride[1] = info->stride[0];
903 info->stride[2] = info->stride[0];
905 info->offset[1] = info->stride[0] * height;
906 info->offset[2] = info->offset[1] * 2;
907 info->size = info->stride[0] * height * 3;
909 case GST_VIDEO_FORMAT_GBRA:
910 info->stride[0] = GST_ROUND_UP_4 (width);
911 info->stride[1] = info->stride[0];
912 info->stride[2] = info->stride[0];
913 info->stride[3] = info->stride[0];
915 info->offset[1] = info->stride[0] * height;
916 info->offset[2] = info->offset[1] * 2;
917 info->offset[3] = info->offset[1] * 3;
918 info->size = info->stride[0] * height * 4;
920 case GST_VIDEO_FORMAT_NV12:
921 case GST_VIDEO_FORMAT_NV21:
922 info->stride[0] = GST_ROUND_UP_4 (width);
923 info->stride[1] = info->stride[0];
925 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
926 cr_h = GST_ROUND_UP_2 (height) / 2;
927 if (GST_VIDEO_INFO_IS_INTERLACED (info))
928 cr_h = GST_ROUND_UP_2 (cr_h);
929 info->size = info->offset[1] + info->stride[0] * cr_h;
931 case GST_VIDEO_FORMAT_NV16:
932 case GST_VIDEO_FORMAT_NV61:
933 info->stride[0] = GST_ROUND_UP_4 (width);
934 info->stride[1] = info->stride[0];
936 info->offset[1] = info->stride[0] * height;
937 info->size = info->stride[0] * height * 2;
939 case GST_VIDEO_FORMAT_NV24:
940 info->stride[0] = GST_ROUND_UP_4 (width);
941 info->stride[1] = GST_ROUND_UP_4 (width * 2);
943 info->offset[1] = info->stride[0] * height;
944 info->size = info->stride[0] * height + info->stride[1] * height;
946 case GST_VIDEO_FORMAT_A420:
947 info->stride[0] = GST_ROUND_UP_4 (width);
948 info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2);
949 info->stride[2] = info->stride[1];
950 info->stride[3] = info->stride[0];
952 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
953 cr_h = GST_ROUND_UP_2 (height) / 2;
954 if (GST_VIDEO_INFO_IS_INTERLACED (info))
955 cr_h = GST_ROUND_UP_2 (cr_h);
956 info->offset[2] = info->offset[1] + info->stride[1] * cr_h;
957 info->offset[3] = info->offset[2] + info->stride[2] * cr_h;
958 info->size = info->offset[3] + info->stride[0] * GST_ROUND_UP_2 (height);
960 case GST_VIDEO_FORMAT_YUV9:
961 case GST_VIDEO_FORMAT_YVU9:
962 info->stride[0] = GST_ROUND_UP_4 (width);
963 info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4);
964 info->stride[2] = info->stride[1];
966 info->offset[1] = info->stride[0] * height;
967 cr_h = GST_ROUND_UP_4 (height) / 4;
968 if (GST_VIDEO_INFO_IS_INTERLACED (info))
969 cr_h = GST_ROUND_UP_2 (cr_h);
970 info->offset[2] = info->offset[1] + info->stride[1] * cr_h;
971 info->size = info->offset[2] + info->stride[2] * cr_h;
973 case GST_VIDEO_FORMAT_I420_10LE:
974 case GST_VIDEO_FORMAT_I420_10BE:
975 case GST_VIDEO_FORMAT_I420_12LE:
976 case GST_VIDEO_FORMAT_I420_12BE:
977 info->stride[0] = GST_ROUND_UP_4 (width * 2);
978 info->stride[1] = GST_ROUND_UP_4 (width);
979 info->stride[2] = info->stride[1];
981 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
982 cr_h = GST_ROUND_UP_2 (height) / 2;
983 if (GST_VIDEO_INFO_IS_INTERLACED (info))
984 cr_h = GST_ROUND_UP_2 (cr_h);
985 info->offset[2] = info->offset[1] + info->stride[1] * cr_h;
986 info->size = info->offset[2] + info->stride[2] * cr_h;
988 case GST_VIDEO_FORMAT_I422_10LE:
989 case GST_VIDEO_FORMAT_I422_10BE:
990 case GST_VIDEO_FORMAT_I422_12LE:
991 case GST_VIDEO_FORMAT_I422_12BE:
992 info->stride[0] = GST_ROUND_UP_4 (width * 2);
993 info->stride[1] = GST_ROUND_UP_4 (width);
994 info->stride[2] = info->stride[1];
996 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
997 info->offset[2] = info->offset[1] +
998 info->stride[1] * GST_ROUND_UP_2 (height);
999 info->size = info->offset[2] + info->stride[2] * GST_ROUND_UP_2 (height);
1001 case GST_VIDEO_FORMAT_Y444_10LE:
1002 case GST_VIDEO_FORMAT_Y444_10BE:
1003 case GST_VIDEO_FORMAT_Y444_12LE:
1004 case GST_VIDEO_FORMAT_Y444_12BE:
1005 case GST_VIDEO_FORMAT_GBR_10LE:
1006 case GST_VIDEO_FORMAT_GBR_10BE:
1007 case GST_VIDEO_FORMAT_GBR_12LE:
1008 case GST_VIDEO_FORMAT_GBR_12BE:
1009 case GST_VIDEO_FORMAT_Y444_16LE:
1010 case GST_VIDEO_FORMAT_Y444_16BE:
1011 info->stride[0] = GST_ROUND_UP_4 (width * 2);
1012 info->stride[1] = info->stride[0];
1013 info->stride[2] = info->stride[0];
1014 info->offset[0] = 0;
1015 info->offset[1] = info->stride[0] * height;
1016 info->offset[2] = info->offset[1] * 2;
1017 info->size = info->stride[0] * height * 3;
1019 case GST_VIDEO_FORMAT_GBRA_10LE:
1020 case GST_VIDEO_FORMAT_GBRA_10BE:
1021 case GST_VIDEO_FORMAT_GBRA_12LE:
1022 case GST_VIDEO_FORMAT_GBRA_12BE:
1023 info->stride[0] = GST_ROUND_UP_4 (width * 2);
1024 info->stride[1] = info->stride[0];
1025 info->stride[2] = info->stride[0];
1026 info->stride[3] = info->stride[0];
1027 info->offset[0] = 0;
1028 info->offset[1] = info->stride[0] * height;
1029 info->offset[2] = info->offset[1] * 2;
1030 info->offset[3] = info->offset[1] * 3;
1031 info->size = info->stride[0] * height * 4;
1033 case GST_VIDEO_FORMAT_NV12_64Z32:
1035 GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_128 (width) / 64,
1036 GST_ROUND_UP_32 (height) / 32);
1038 GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_128 (width) / 64,
1039 GST_ROUND_UP_64 (height) / 64);
1040 info->offset[0] = 0;
1041 info->offset[1] = GST_ROUND_UP_128 (width) * GST_ROUND_UP_32 (height);
1042 info->size = info->offset[1] +
1043 GST_ROUND_UP_128 (width) * GST_ROUND_UP_64 (height) / 2;
1045 case GST_VIDEO_FORMAT_A420_10LE:
1046 case GST_VIDEO_FORMAT_A420_10BE:
1047 info->stride[0] = GST_ROUND_UP_4 (width * 2);
1048 info->stride[1] = GST_ROUND_UP_4 (width);
1049 info->stride[2] = info->stride[1];
1050 info->stride[3] = info->stride[0];
1051 info->offset[0] = 0;
1052 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
1053 cr_h = GST_ROUND_UP_2 (height) / 2;
1054 if (GST_VIDEO_INFO_IS_INTERLACED (info))
1055 cr_h = GST_ROUND_UP_2 (cr_h);
1056 info->offset[2] = info->offset[1] + info->stride[1] * cr_h;
1057 info->offset[3] = info->offset[2] + info->stride[2] * cr_h;
1058 info->size = info->offset[3] + info->stride[0] * GST_ROUND_UP_2 (height);
1060 case GST_VIDEO_FORMAT_A422_10LE:
1061 case GST_VIDEO_FORMAT_A422_10BE:
1062 info->stride[0] = GST_ROUND_UP_4 (width * 2);
1063 info->stride[1] = GST_ROUND_UP_4 (width);
1064 info->stride[2] = info->stride[1];
1065 info->stride[3] = info->stride[0];
1066 info->offset[0] = 0;
1067 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
1068 info->offset[2] = info->offset[1] +
1069 info->stride[1] * GST_ROUND_UP_2 (height);
1071 info->offset[2] + info->stride[2] * GST_ROUND_UP_2 (height);
1072 info->size = info->offset[3] + info->stride[0] * GST_ROUND_UP_2 (height);
1074 case GST_VIDEO_FORMAT_A444_10LE:
1075 case GST_VIDEO_FORMAT_A444_10BE:
1076 info->stride[0] = GST_ROUND_UP_4 (width * 2);
1077 info->stride[1] = info->stride[0];
1078 info->stride[2] = info->stride[0];
1079 info->stride[3] = info->stride[0];
1080 info->offset[0] = 0;
1081 info->offset[1] = info->stride[0] * height;
1082 info->offset[2] = info->offset[1] * 2;
1083 info->offset[3] = info->offset[1] * 3;
1084 info->size = info->stride[0] * height * 4;
1086 case GST_VIDEO_FORMAT_P010_10LE:
1087 case GST_VIDEO_FORMAT_P010_10BE:
1088 info->stride[0] = GST_ROUND_UP_4 (width * 2);
1089 info->stride[1] = info->stride[0];
1090 info->offset[0] = 0;
1091 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
1092 cr_h = GST_ROUND_UP_2 (height) / 2;
1093 info->size = info->offset[1] + info->stride[0] * cr_h;
1095 case GST_VIDEO_FORMAT_GRAY10_LE32:
1096 info->stride[0] = (width + 2) / 3 * 4;
1097 info->offset[0] = 0;
1098 info->size = info->stride[0] * GST_ROUND_UP_2 (height);
1100 case GST_VIDEO_FORMAT_NV12_10LE32:
1101 info->stride[0] = (width + 2) / 3 * 4;
1102 info->stride[1] = info->stride[0];
1103 info->offset[0] = 0;
1104 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
1105 cr_h = GST_ROUND_UP_2 (height) / 2;
1106 if (GST_VIDEO_INFO_IS_INTERLACED (info))
1107 cr_h = GST_ROUND_UP_2 (cr_h);
1108 info->size = info->offset[1] + info->stride[0] * cr_h;
1110 case GST_VIDEO_FORMAT_NV16_10LE32:
1111 info->stride[0] = (width + 2) / 3 * 4;
1112 info->stride[1] = info->stride[0];
1113 info->offset[0] = 0;
1114 info->offset[1] = info->stride[0] * height;
1115 info->size = info->stride[0] * height * 2;
1117 case GST_VIDEO_FORMAT_NV12_10LE40:
1118 info->stride[0] = ((width * 5 >> 2) + 4) / 5 * 5;
1119 info->stride[1] = info->stride[0];
1120 info->offset[0] = 0;
1121 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
1122 cr_h = GST_ROUND_UP_2 (height) / 2;
1123 if (GST_VIDEO_INFO_IS_INTERLACED (info))
1124 cr_h = GST_ROUND_UP_2 (cr_h);
1125 info->size = info->offset[1] + info->stride[0] * cr_h;
1128 case GST_VIDEO_FORMAT_ENCODED:
1130 case GST_VIDEO_FORMAT_UNKNOWN:
1131 GST_ERROR ("invalid format");
1132 g_warning ("invalid format");
1140 * gst_video_info_convert:
1141 * @info: a #GstVideoInfo
1142 * @src_format: #GstFormat of the @src_value
1143 * @src_value: value to convert
1144 * @dest_format: #GstFormat of the @dest_value
1145 * @dest_value: (out): pointer to destination value
1147 * Converts among various #GstFormat types. This function handles
1148 * GST_FORMAT_BYTES, GST_FORMAT_TIME, and GST_FORMAT_DEFAULT. For
1149 * raw video, GST_FORMAT_DEFAULT corresponds to video frames. This
1150 * function can be used to handle pad queries of the type GST_QUERY_CONVERT.
1152 * Returns: TRUE if the conversion was successful.
1155 gst_video_info_convert (GstVideoInfo * info,
1156 GstFormat src_format, gint64 src_value,
1157 GstFormat dest_format, gint64 * dest_value)
1159 gboolean ret = FALSE;
1163 g_return_val_if_fail (info != NULL, 0);
1164 g_return_val_if_fail (info->finfo != NULL, 0);
1165 g_return_val_if_fail (info->finfo->format != GST_VIDEO_FORMAT_UNKNOWN, 0);
1166 g_return_val_if_fail (info->size > 0, 0);
1169 fps_n = info->fps_n;
1170 fps_d = info->fps_d;
1172 GST_DEBUG ("converting value %" G_GINT64_FORMAT " from %s to %s",
1173 src_value, gst_format_get_name (src_format),
1174 gst_format_get_name (dest_format));
1176 if (src_format == dest_format) {
1177 *dest_value = src_value;
1182 if (src_value == -1) {
1188 /* bytes to frames */
1189 if (src_format == GST_FORMAT_BYTES && dest_format == GST_FORMAT_DEFAULT) {
1191 *dest_value = gst_util_uint64_scale (src_value, 1, size);
1193 GST_ERROR ("blocksize is 0");
1200 /* frames to bytes */
1201 if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_BYTES) {
1202 *dest_value = gst_util_uint64_scale (src_value, size, 1);
1207 /* time to frames */
1208 if (src_format == GST_FORMAT_TIME && dest_format == GST_FORMAT_DEFAULT) {
1210 *dest_value = gst_util_uint64_scale (src_value,
1211 fps_n, GST_SECOND * fps_d);
1213 GST_ERROR ("framerate denominator is 0");
1220 /* frames to time */
1221 if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_TIME) {
1223 *dest_value = gst_util_uint64_scale (src_value,
1224 GST_SECOND * fps_d, fps_n);
1226 GST_ERROR ("framerate numerator is 0");
1234 if (src_format == GST_FORMAT_TIME && dest_format == GST_FORMAT_BYTES) {
1236 *dest_value = gst_util_uint64_scale (src_value,
1237 fps_n * size, GST_SECOND * fps_d);
1239 GST_ERROR ("framerate denominator is 0");
1247 if (src_format == GST_FORMAT_BYTES && dest_format == GST_FORMAT_TIME) {
1248 if (fps_n != 0 && size != 0) {
1249 *dest_value = gst_util_uint64_scale (src_value,
1250 GST_SECOND * fps_d, fps_n * size);
1252 GST_ERROR ("framerate denominator and/or blocksize is 0");
1260 GST_DEBUG ("ret=%d result %" G_GINT64_FORMAT, ret, *dest_value);
1266 * gst_video_info_align:
1267 * @info: a #GstVideoInfo
1268 * @align: alignment parameters
1270 * Adjust the offset and stride fields in @info so that the padding and
1271 * stride alignment in @align is respected.
1273 * Extra padding will be added to the right side when stride alignment padding
1274 * is required and @align will be updated with the new padding values.
1276 * Returns: %FALSE if alignment could not be applied, e.g. because the
1277 * size of a frame can't be represented as a 32 bit integer (Since: 1.12)
1280 gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align)
1282 const GstVideoFormatInfo *vinfo = info->finfo;
1284 gint padded_width, padded_height;
1288 width = GST_VIDEO_INFO_WIDTH (info);
1289 height = GST_VIDEO_INFO_HEIGHT (info);
1291 GST_LOG ("padding %u-%ux%u-%u", align->padding_top,
1292 align->padding_left, align->padding_right, align->padding_bottom);
1294 n_planes = GST_VIDEO_INFO_N_PLANES (info);
1296 if (GST_VIDEO_FORMAT_INFO_HAS_PALETTE (vinfo))
1299 /* first make sure the left padding does not cause alignment problems later */
1301 GST_LOG ("left padding %u", align->padding_left);
1303 for (i = 0; i < n_planes; i++) {
1306 /* this is the amout of pixels to add as left padding */
1307 hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, i, align->padding_left);
1308 hedge *= GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, i);
1310 GST_LOG ("plane %d, padding %d, alignment %u", i, hedge,
1311 align->stride_align[i]);
1312 aligned &= (hedge & align->stride_align[i]) == 0;
1317 GST_LOG ("unaligned padding, increasing padding");
1318 /* increase padded_width */
1319 align->padding_left += align->padding_left & ~(align->padding_left - 1);
1322 /* add the padding */
1323 padded_width = width + align->padding_left + align->padding_right;
1324 padded_height = height + align->padding_top + align->padding_bottom;
1327 GST_LOG ("padded dimension %u-%u", padded_width, padded_height);
1329 info->width = padded_width;
1330 info->height = padded_height;
1332 if (!fill_planes (info))
1335 /* check alignment */
1337 for (i = 0; i < n_planes; i++) {
1338 GST_LOG ("plane %d, stride %d, alignment %u", i, info->stride[i],
1339 align->stride_align[i]);
1340 aligned &= (info->stride[i] & align->stride_align[i]) == 0;
1345 GST_LOG ("unaligned strides, increasing dimension");
1346 /* increase padded_width */
1347 padded_width += padded_width & ~(padded_width - 1);
1350 align->padding_right = padded_width - width - align->padding_left;
1352 info->width = width;
1353 info->height = height;
1355 for (i = 0; i < n_planes; i++) {
1356 gint vedge, hedge, comp;
1358 /* Find the component for this plane, FIXME, we assume the plane number and
1359 * component number is the same for now, for scaling the dimensions this is
1360 * currently true for all formats but it might not be when adding new
1361 * formats. We might need to add a plane subsamling in the format info to
1362 * make this more generic or maybe use a plane -> component mapping. */
1366 GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, comp, align->padding_left);
1368 GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (vinfo, comp, align->padding_top);
1370 GST_DEBUG ("plane %d: comp: %d, hedge %d vedge %d align %d stride %d", i,
1371 comp, hedge, vedge, align->stride_align[i], info->stride[i]);
1373 info->offset[i] += (vedge * info->stride[i]) +
1374 (hedge * GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, comp));