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.
29 #include "video-info.h"
30 #include "video-tile.h"
32 static int fill_planes (GstVideoInfo * info);
35 * gst_video_info_init:
36 * @info: a #GstVideoInfo
38 * Initialize @info with default values.
41 gst_video_info_init (GstVideoInfo * info)
43 g_return_if_fail (info != NULL);
45 memset (info, 0, sizeof (GstVideoInfo));
47 info->finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_UNKNOWN);
50 /* arrange for sensible defaults, e.g. if turned into caps */
57 #define MAKE_COLORIMETRY(r,m,t,p) { \
58 GST_VIDEO_COLOR_RANGE ##r, GST_VIDEO_COLOR_MATRIX_ ##m, \
59 GST_VIDEO_TRANSFER_ ##t, GST_VIDEO_COLOR_PRIMARIES_ ##p }
61 #define DEFAULT_YUV_SD 0
62 #define DEFAULT_YUV_HD 1
64 #define DEFAULT_GRAY 3
65 #define DEFAULT_UNKNOWN 4
66 #define DEFAULT_YUV_UHD 5
68 static const GstVideoColorimetry default_color[] = {
69 MAKE_COLORIMETRY (_16_235, BT601, BT709, SMPTE170M),
70 MAKE_COLORIMETRY (_16_235, BT709, BT709, BT709),
71 MAKE_COLORIMETRY (_0_255, RGB, SRGB, BT709),
72 MAKE_COLORIMETRY (_0_255, BT601, UNKNOWN, UNKNOWN),
73 MAKE_COLORIMETRY (_UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN),
74 MAKE_COLORIMETRY (_16_235, BT2020, BT2020_12, BT2020),
78 set_default_colorimetry (GstVideoInfo * info)
80 const GstVideoFormatInfo *finfo = info->finfo;
82 if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo)) {
83 if (info->height >= 2160) {
84 info->chroma_site = GST_VIDEO_CHROMA_SITE_H_COSITED;
85 info->colorimetry = default_color[DEFAULT_YUV_UHD];
86 } else if (info->height > 576) {
87 info->chroma_site = GST_VIDEO_CHROMA_SITE_H_COSITED;
88 info->colorimetry = default_color[DEFAULT_YUV_HD];
90 info->chroma_site = GST_VIDEO_CHROMA_SITE_NONE;
91 info->colorimetry = default_color[DEFAULT_YUV_SD];
93 } else if (GST_VIDEO_FORMAT_INFO_IS_GRAY (finfo)) {
94 info->colorimetry = default_color[DEFAULT_GRAY];
95 } else if (GST_VIDEO_FORMAT_INFO_IS_RGB (finfo)) {
96 info->colorimetry = default_color[DEFAULT_RGB];
98 info->colorimetry = default_color[DEFAULT_UNKNOWN];
103 * gst_video_info_set_format:
104 * @info: a #GstVideoInfo
105 * @format: the format
109 * Set the default info for a video frame of @format and @width and @height.
111 * Note: This initializes @info first, no values are preserved. This function
112 * does not set the offsets correctly for interlaced vertically
113 * subsampled formats.
116 gst_video_info_set_format (GstVideoInfo * info, GstVideoFormat format,
117 guint width, guint height)
119 g_return_if_fail (info != NULL);
120 g_return_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN);
122 gst_video_info_init (info);
124 info->finfo = gst_video_format_get_info (format);
126 info->height = height;
128 set_default_colorimetry (info);
133 static const gchar *interlace_mode[] = {
141 gst_interlace_mode_to_string (GstVideoInterlaceMode mode)
143 if (((guint) mode) >= G_N_ELEMENTS (interlace_mode))
146 return interlace_mode[mode];
149 static GstVideoInterlaceMode
150 gst_interlace_mode_from_string (const gchar * mode)
153 for (i = 0; i < G_N_ELEMENTS (interlace_mode); i++) {
154 if (g_str_equal (interlace_mode[i], mode))
157 return GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
161 * gst_video_info_from_caps:
162 * @info: a #GstVideoInfo
165 * Parse @caps and update @info.
167 * Returns: TRUE if @caps could be parsed
170 gst_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps)
172 GstStructure *structure;
174 GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
175 gint width = 0, height = 0, views;
179 g_return_val_if_fail (info != NULL, FALSE);
180 g_return_val_if_fail (caps != NULL, FALSE);
181 g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
183 GST_DEBUG ("parsing caps %" GST_PTR_FORMAT, caps);
185 structure = gst_caps_get_structure (caps, 0);
187 if (gst_structure_has_name (structure, "video/x-raw")) {
188 if (!(s = gst_structure_get_string (structure, "format")))
191 format = gst_video_format_from_string (s);
192 if (format == GST_VIDEO_FORMAT_UNKNOWN)
195 } else if (g_str_has_prefix (gst_structure_get_name (structure), "video/") ||
196 g_str_has_prefix (gst_structure_get_name (structure), "image/")) {
197 format = GST_VIDEO_FORMAT_ENCODED;
202 /* width and height are mandatory, except for non-raw-formats */
203 if (!gst_structure_get_int (structure, "width", &width) &&
204 format != GST_VIDEO_FORMAT_ENCODED)
206 if (!gst_structure_get_int (structure, "height", &height) &&
207 format != GST_VIDEO_FORMAT_ENCODED)
210 gst_video_info_init (info);
212 info->finfo = gst_video_format_get_info (format);
214 info->height = height;
216 if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)) {
218 /* variable framerate */
219 info->flags |= GST_VIDEO_FLAG_VARIABLE_FPS;
220 /* see if we have a max-framerate */
221 gst_structure_get_fraction (structure, "max-framerate", &fps_n, &fps_d);
226 /* unspecified is variable framerate */
231 if ((s = gst_structure_get_string (structure, "interlace-mode")))
232 info->interlace_mode = gst_interlace_mode_from_string (s);
234 info->interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
236 if (gst_structure_get_int (structure, "views", &views))
241 if ((s = gst_structure_get_string (structure, "chroma-site")))
242 info->chroma_site = gst_video_chroma_from_string (s);
244 info->chroma_site = GST_VIDEO_CHROMA_SITE_UNKNOWN;
246 if ((s = gst_structure_get_string (structure, "colorimetry")))
247 gst_video_colorimetry_from_string (&info->colorimetry, s);
249 set_default_colorimetry (info);
251 if (gst_structure_get_fraction (structure, "pixel-aspect-ratio",
266 GST_ERROR ("wrong name '%s', expected video/ or image/",
267 gst_structure_get_name (structure));
272 GST_ERROR ("no format given");
277 GST_ERROR ("unknown format '%s' given", s);
282 GST_ERROR ("no width property given");
287 GST_ERROR ("no height property given");
293 * gst_video_info_is_equal:
294 * @info: a #GstVideoInfo
295 * @other: a #GstVideoInfo
297 * Compares two #GstVideoInfo and returns whether they are equal or not
299 * Returns: %TRUE if @info and @other are equal, else %FALSE.
302 gst_video_info_is_equal (const GstVideoInfo * info, const GstVideoInfo * other)
306 if (GST_VIDEO_INFO_FORMAT (info) != GST_VIDEO_INFO_FORMAT (other))
308 if (GST_VIDEO_INFO_INTERLACE_MODE (info) !=
309 GST_VIDEO_INFO_INTERLACE_MODE (other))
311 if (GST_VIDEO_INFO_FLAGS (info) != GST_VIDEO_INFO_FLAGS (other))
313 if (GST_VIDEO_INFO_WIDTH (info) != GST_VIDEO_INFO_WIDTH (other))
315 if (GST_VIDEO_INFO_HEIGHT (info) != GST_VIDEO_INFO_HEIGHT (other))
317 if (GST_VIDEO_INFO_SIZE (info) != GST_VIDEO_INFO_SIZE (other))
319 if (GST_VIDEO_INFO_PAR_N (info) != GST_VIDEO_INFO_PAR_N (other))
321 if (GST_VIDEO_INFO_PAR_D (info) != GST_VIDEO_INFO_PAR_D (other))
323 if (GST_VIDEO_INFO_FPS_N (info) != GST_VIDEO_INFO_FPS_N (other))
325 if (GST_VIDEO_INFO_FPS_D (info) != GST_VIDEO_INFO_FPS_D (other))
328 for (i = 0; i < info->finfo->n_planes; i++) {
329 if (info->stride[i] != other->stride[i])
331 if (info->offset[i] != other->offset[i])
339 * gst_video_info_to_caps:
340 * @info: a #GstVideoInfo
342 * Convert the values of @info into a #GstCaps.
344 * Returns: a new #GstCaps containing the info of @info.
347 gst_video_info_to_caps (GstVideoInfo * info)
353 g_return_val_if_fail (info != NULL, NULL);
354 g_return_val_if_fail (info->finfo != NULL, NULL);
355 g_return_val_if_fail (info->finfo->format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
357 format = gst_video_format_to_string (info->finfo->format);
358 g_return_val_if_fail (format != NULL, NULL);
360 caps = gst_caps_new_simple ("video/x-raw",
361 "format", G_TYPE_STRING, format,
362 "width", G_TYPE_INT, info->width,
363 "height", G_TYPE_INT, info->height,
364 "pixel-aspect-ratio", GST_TYPE_FRACTION, info->par_n, info->par_d, NULL);
366 gst_caps_set_simple (caps, "interlace-mode", G_TYPE_STRING,
367 gst_interlace_mode_to_string (info->interlace_mode), NULL);
369 if (info->chroma_site != GST_VIDEO_CHROMA_SITE_UNKNOWN)
370 gst_caps_set_simple (caps, "chroma-site", G_TYPE_STRING,
371 gst_video_chroma_to_string (info->chroma_site), NULL);
373 if ((color = gst_video_colorimetry_to_string (&info->colorimetry))) {
374 gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, color, NULL);
379 gst_caps_set_simple (caps, "views", G_TYPE_INT, info->views, NULL);
381 if (info->flags & GST_VIDEO_FLAG_VARIABLE_FPS && info->fps_n != 0) {
382 /* variable fps with a max-framerate */
383 gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, 0, 1,
384 "max-framerate", GST_TYPE_FRACTION, info->fps_n, info->fps_d, NULL);
386 /* no variable fps or no max-framerate */
387 gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION,
388 info->fps_n, info->fps_d, NULL);
395 fill_planes (GstVideoInfo * info)
397 gsize width, height, cr_h;
399 width = (gsize) info->width;
400 height = (gsize) info->height;
402 switch (info->finfo->format) {
403 case GST_VIDEO_FORMAT_YUY2:
404 case GST_VIDEO_FORMAT_YVYU:
405 case GST_VIDEO_FORMAT_UYVY:
406 info->stride[0] = GST_ROUND_UP_4 (width * 2);
408 info->size = info->stride[0] * height;
410 case GST_VIDEO_FORMAT_AYUV:
411 case GST_VIDEO_FORMAT_RGBx:
412 case GST_VIDEO_FORMAT_RGBA:
413 case GST_VIDEO_FORMAT_BGRx:
414 case GST_VIDEO_FORMAT_BGRA:
415 case GST_VIDEO_FORMAT_xRGB:
416 case GST_VIDEO_FORMAT_ARGB:
417 case GST_VIDEO_FORMAT_xBGR:
418 case GST_VIDEO_FORMAT_ABGR:
419 case GST_VIDEO_FORMAT_r210:
420 info->stride[0] = width * 4;
422 info->size = info->stride[0] * height;
424 case GST_VIDEO_FORMAT_RGB16:
425 case GST_VIDEO_FORMAT_BGR16:
426 case GST_VIDEO_FORMAT_RGB15:
427 case GST_VIDEO_FORMAT_BGR15:
428 info->stride[0] = GST_ROUND_UP_4 (width * 2);
430 info->size = info->stride[0] * height;
432 case GST_VIDEO_FORMAT_RGB:
433 case GST_VIDEO_FORMAT_BGR:
434 case GST_VIDEO_FORMAT_v308:
435 info->stride[0] = GST_ROUND_UP_4 (width * 3);
437 info->size = info->stride[0] * height;
439 case GST_VIDEO_FORMAT_v210:
440 info->stride[0] = ((width + 47) / 48) * 128;
442 info->size = info->stride[0] * height;
444 case GST_VIDEO_FORMAT_v216:
445 info->stride[0] = GST_ROUND_UP_8 (width * 4);
447 info->size = info->stride[0] * height;
449 case GST_VIDEO_FORMAT_GRAY8:
450 info->stride[0] = GST_ROUND_UP_4 (width);
452 info->size = info->stride[0] * height;
454 case GST_VIDEO_FORMAT_GRAY16_BE:
455 case GST_VIDEO_FORMAT_GRAY16_LE:
456 info->stride[0] = GST_ROUND_UP_4 (width * 2);
458 info->size = info->stride[0] * height;
460 case GST_VIDEO_FORMAT_UYVP:
461 info->stride[0] = GST_ROUND_UP_4 ((width * 2 * 5 + 3) / 4);
463 info->size = info->stride[0] * height;
465 case GST_VIDEO_FORMAT_RGB8P:
466 info->stride[0] = GST_ROUND_UP_4 (width);
469 info->offset[1] = info->stride[0] * height;
470 info->size = info->offset[1] + (4 * 256);
472 case GST_VIDEO_FORMAT_IYU1:
473 info->stride[0] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) +
474 GST_ROUND_UP_4 (width) / 2);
476 info->size = info->stride[0] * height;
478 case GST_VIDEO_FORMAT_ARGB64:
479 case GST_VIDEO_FORMAT_AYUV64:
480 info->stride[0] = width * 8;
482 info->size = info->stride[0] * height;
484 case GST_VIDEO_FORMAT_I420:
485 case GST_VIDEO_FORMAT_YV12: /* same as I420, but plane 1+2 swapped */
486 info->stride[0] = GST_ROUND_UP_4 (width);
487 info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2);
488 info->stride[2] = info->stride[1];
490 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
491 cr_h = GST_ROUND_UP_2 (height) / 2;
492 if (GST_VIDEO_INFO_IS_INTERLACED (info))
493 cr_h = GST_ROUND_UP_2 (cr_h);
494 info->offset[2] = info->offset[1] + info->stride[1] * cr_h;
495 info->size = info->offset[2] + info->stride[2] * cr_h;
496 GST_DEBUG ("%d %d %d", GST_VIDEO_INFO_IS_INTERLACED (info),
497 (int) info->offset[2], (int) info->size);
499 case GST_VIDEO_FORMAT_Y41B:
500 info->stride[0] = GST_ROUND_UP_4 (width);
501 info->stride[1] = GST_ROUND_UP_16 (width) / 4;
502 info->stride[2] = info->stride[1];
504 info->offset[1] = info->stride[0] * height;
505 info->offset[2] = info->offset[1] + info->stride[1] * height;
506 /* simplification of ROUNDUP4(w)*h + 2*((ROUNDUP16(w)/4)*h */
507 info->size = (info->stride[0] + (GST_ROUND_UP_16 (width) / 2)) * height;
509 case GST_VIDEO_FORMAT_Y42B:
510 info->stride[0] = GST_ROUND_UP_4 (width);
511 info->stride[1] = GST_ROUND_UP_8 (width) / 2;
512 info->stride[2] = info->stride[1];
514 info->offset[1] = info->stride[0] * height;
515 info->offset[2] = info->offset[1] + info->stride[1] * height;
516 /* simplification of ROUNDUP4(w)*h + 2*(ROUNDUP8(w)/2)*h */
517 info->size = (info->stride[0] + GST_ROUND_UP_8 (width)) * height;
519 case GST_VIDEO_FORMAT_Y444:
520 case GST_VIDEO_FORMAT_GBR:
521 info->stride[0] = GST_ROUND_UP_4 (width);
522 info->stride[1] = info->stride[0];
523 info->stride[2] = info->stride[0];
525 info->offset[1] = info->stride[0] * height;
526 info->offset[2] = info->offset[1] * 2;
527 info->size = info->stride[0] * height * 3;
529 case GST_VIDEO_FORMAT_NV12:
530 case GST_VIDEO_FORMAT_NV21:
531 info->stride[0] = GST_ROUND_UP_4 (width);
532 info->stride[1] = info->stride[0];
534 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
535 cr_h = GST_ROUND_UP_2 (height) / 2;
536 if (GST_VIDEO_INFO_IS_INTERLACED (info))
537 cr_h = GST_ROUND_UP_2 (cr_h);
538 info->size = info->offset[1] + info->stride[0] * cr_h;
540 case GST_VIDEO_FORMAT_NV16:
541 info->stride[0] = GST_ROUND_UP_4 (width);
542 info->stride[1] = info->stride[0];
544 info->offset[1] = info->stride[0] * height;
545 info->size = info->stride[0] * height * 2;
547 case GST_VIDEO_FORMAT_NV24:
548 info->stride[0] = GST_ROUND_UP_4 (width);
549 info->stride[1] = GST_ROUND_UP_4 (width * 2);
551 info->offset[1] = info->stride[0] * height;
552 info->size = info->stride[0] * height + info->stride[1] * height;
554 case GST_VIDEO_FORMAT_A420:
555 info->stride[0] = GST_ROUND_UP_4 (width);
556 info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2);
557 info->stride[2] = info->stride[1];
558 info->stride[3] = info->stride[0];
560 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
561 cr_h = GST_ROUND_UP_2 (height) / 2;
562 if (GST_VIDEO_INFO_IS_INTERLACED (info))
563 cr_h = GST_ROUND_UP_2 (cr_h);
564 info->offset[2] = info->offset[1] + info->stride[1] * cr_h;
565 info->offset[3] = info->offset[2] + info->stride[2] * cr_h;
566 info->size = info->offset[3] + info->stride[0] * GST_ROUND_UP_2 (height);
568 case GST_VIDEO_FORMAT_YUV9:
569 case GST_VIDEO_FORMAT_YVU9:
570 info->stride[0] = GST_ROUND_UP_4 (width);
571 info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4);
572 info->stride[2] = info->stride[1];
574 info->offset[1] = info->stride[0] * height;
575 cr_h = GST_ROUND_UP_4 (height) / 4;
576 if (GST_VIDEO_INFO_IS_INTERLACED (info))
577 cr_h = GST_ROUND_UP_2 (cr_h);
578 info->offset[2] = info->offset[1] + info->stride[1] * cr_h;
579 info->size = info->offset[2] + info->stride[2] * cr_h;
581 case GST_VIDEO_FORMAT_I420_10LE:
582 case GST_VIDEO_FORMAT_I420_10BE:
583 info->stride[0] = GST_ROUND_UP_4 (width * 2);
584 info->stride[1] = GST_ROUND_UP_4 (width);
585 info->stride[2] = info->stride[1];
587 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
588 cr_h = GST_ROUND_UP_2 (height) / 2;
589 if (GST_VIDEO_INFO_IS_INTERLACED (info))
590 cr_h = GST_ROUND_UP_2 (cr_h);
591 info->offset[2] = info->offset[1] + info->stride[1] * cr_h;
592 info->size = info->offset[2] + info->stride[2] * cr_h;
594 case GST_VIDEO_FORMAT_I422_10LE:
595 case GST_VIDEO_FORMAT_I422_10BE:
596 info->stride[0] = GST_ROUND_UP_4 (width * 2);
597 info->stride[1] = GST_ROUND_UP_4 (width);
598 info->stride[2] = info->stride[1];
600 info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
601 info->offset[2] = info->offset[1] +
602 info->stride[1] * GST_ROUND_UP_2 (height);
603 info->size = info->offset[2] + info->stride[2] * GST_ROUND_UP_2 (height);
605 case GST_VIDEO_FORMAT_Y444_10LE:
606 case GST_VIDEO_FORMAT_Y444_10BE:
607 case GST_VIDEO_FORMAT_GBR_10LE:
608 case GST_VIDEO_FORMAT_GBR_10BE:
609 info->stride[0] = GST_ROUND_UP_4 (width * 2);
610 info->stride[1] = info->stride[0];
611 info->stride[2] = info->stride[0];
613 info->offset[1] = info->stride[0] * height;
614 info->offset[2] = info->offset[1] * 2;
615 info->size = info->stride[0] * height * 3;
617 case GST_VIDEO_FORMAT_NV12_64Z32:
619 GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_128 (width) / 64,
620 GST_ROUND_UP_32 (height) / 32);
622 GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_128 (width) / 64,
623 GST_ROUND_UP_64 (height) / 64);
625 info->offset[1] = GST_ROUND_UP_128 (width) * GST_ROUND_UP_32 (height);
626 info->size = info->offset[1] +
627 GST_ROUND_UP_128 (width) * GST_ROUND_UP_64 (height) / 2;
629 case GST_VIDEO_FORMAT_ENCODED:
631 case GST_VIDEO_FORMAT_UNKNOWN:
632 GST_ERROR ("invalid format");
633 g_warning ("invalid format");
640 * gst_video_info_convert:
641 * @info: a #GstVideoInfo
642 * @src_format: #GstFormat of the @src_value
643 * @src_value: value to convert
644 * @dest_format: #GstFormat of the @dest_value
645 * @dest_value: pointer to destination value
647 * Converts among various #GstFormat types. This function handles
648 * GST_FORMAT_BYTES, GST_FORMAT_TIME, and GST_FORMAT_DEFAULT. For
649 * raw video, GST_FORMAT_DEFAULT corresponds to video frames. This
650 * function can be used to handle pad queries of the type GST_QUERY_CONVERT.
652 * Returns: TRUE if the conversion was successful.
655 gst_video_info_convert (GstVideoInfo * info,
656 GstFormat src_format, gint64 src_value,
657 GstFormat dest_format, gint64 * dest_value)
659 gboolean ret = FALSE;
663 g_return_val_if_fail (info != NULL, 0);
664 g_return_val_if_fail (info->finfo != NULL, 0);
665 g_return_val_if_fail (info->finfo->format != GST_VIDEO_FORMAT_UNKNOWN, 0);
666 g_return_val_if_fail (info->size > 0, 0);
672 GST_DEBUG ("converting value %" G_GINT64_FORMAT " from %s to %s",
673 src_value, gst_format_get_name (src_format),
674 gst_format_get_name (dest_format));
676 if (src_format == dest_format) {
677 *dest_value = src_value;
682 if (src_value == -1) {
688 /* bytes to frames */
689 if (src_format == GST_FORMAT_BYTES && dest_format == GST_FORMAT_DEFAULT) {
691 *dest_value = gst_util_uint64_scale (src_value, 1, size);
693 GST_ERROR ("blocksize is 0");
700 /* frames to bytes */
701 if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_BYTES) {
702 *dest_value = gst_util_uint64_scale (src_value, size, 1);
708 if (src_format == GST_FORMAT_TIME && dest_format == GST_FORMAT_DEFAULT) {
710 *dest_value = gst_util_uint64_scale (src_value,
711 fps_n, GST_SECOND * fps_d);
713 GST_ERROR ("framerate denominator is 0");
721 if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_TIME) {
723 *dest_value = gst_util_uint64_scale (src_value,
724 GST_SECOND * fps_d, fps_n);
726 GST_ERROR ("framerate numerator is 0");
734 if (src_format == GST_FORMAT_TIME && dest_format == GST_FORMAT_BYTES) {
736 *dest_value = gst_util_uint64_scale (src_value,
737 fps_n * size, GST_SECOND * fps_d);
739 GST_ERROR ("framerate denominator is 0");
747 if (src_format == GST_FORMAT_BYTES && dest_format == GST_FORMAT_TIME) {
748 if (fps_n != 0 && size != 0) {
749 *dest_value = gst_util_uint64_scale (src_value,
750 GST_SECOND * fps_d, fps_n * size);
752 GST_ERROR ("framerate denominator and/or blocksize is 0");
760 GST_DEBUG ("ret=%d result %" G_GINT64_FORMAT, ret, *dest_value);
766 * gst_video_info_align:
767 * @info: a #GstVideoInfo
768 * @align: alignment parameters
770 * Adjust the offset and stride fields in @info so that the padding and
771 * stride alignment in @align is respected.
773 * Extra padding will be added to the right side when stride alignment padding
774 * is required and @align will be updated with the new padding values.
777 gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align)
779 const GstVideoFormatInfo *vinfo = info->finfo;
781 gint padded_width, padded_height;
785 width = GST_VIDEO_INFO_WIDTH (info);
786 height = GST_VIDEO_INFO_HEIGHT (info);
788 GST_LOG ("padding %u-%ux%u-%u", align->padding_top,
789 align->padding_left, align->padding_right, align->padding_bottom);
791 n_planes = GST_VIDEO_INFO_N_PLANES (info);
793 if (GST_VIDEO_FORMAT_INFO_HAS_PALETTE (vinfo))
796 /* first make sure the left padding does not cause alignment problems later */
798 GST_LOG ("left padding %u", align->padding_left);
800 for (i = 0; i < n_planes; i++) {
803 /* this is the amout of pixels to add as left padding */
804 hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, i, align->padding_left);
805 hedge *= GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, i);
807 GST_LOG ("plane %d, padding %d, alignment %u", i, hedge,
808 align->stride_align[i]);
809 aligned &= (hedge & align->stride_align[i]) == 0;
814 GST_LOG ("unaligned padding, increasing padding");
815 /* increase padded_width */
816 align->padding_left += align->padding_left & ~(align->padding_left - 1);
819 /* add the padding */
820 padded_width = width + align->padding_left + align->padding_right;
821 padded_height = height + align->padding_top + align->padding_bottom;
824 GST_LOG ("padded dimension %u-%u", padded_width, padded_height);
826 info->width = padded_width;
827 info->height = padded_height;
830 /* check alignment */
832 for (i = 0; i < n_planes; i++) {
833 GST_LOG ("plane %d, stride %d, alignment %u", i, info->stride[i],
834 align->stride_align[i]);
835 aligned &= (info->stride[i] & align->stride_align[i]) == 0;
840 GST_LOG ("unaligned strides, increasing dimension");
841 /* increase padded_width */
842 padded_width += padded_width & ~(padded_width - 1);
845 align->padding_right = padded_width - width - align->padding_left;
848 info->height = height;
850 for (i = 0; i < n_planes; i++) {
851 gint vedge, hedge, comp;
853 /* Find the component for this plane, FIXME, we assume the plane number and
854 * component number is the same for now, for scaling the dimensions this is
855 * currently true for all formats but it might not be when adding new
856 * formats. We might need to add a plane subsamling in the format info to
857 * make this more generic or maybe use a plane -> component mapping. */
861 GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, comp, align->padding_left);
863 GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (vinfo, comp, align->padding_top);
865 GST_DEBUG ("plane %d: comp: %d, hedge %d vedge %d align %d stride %d", i,
866 comp, hedge, vedge, align->stride_align[i], info->stride[i]);
868 info->offset[i] += (vedge * info->stride[i]) +
869 (hedge * GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, comp));