/src/gstreamer/subprojects/gst-plugins-base/gst-libs/gst/video/video-info.c
Line | Count | Source |
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., 51 Franklin St, Fifth Floor, |
19 | | * Boston, MA 02110-1301, USA. |
20 | | */ |
21 | | |
22 | | /** |
23 | | * SECTION:video-info |
24 | | * @title: GstVideoInfo |
25 | | * @short_description: Structures and enumerations to describe raw images |
26 | | */ |
27 | | |
28 | | #ifdef HAVE_CONFIG_H |
29 | | # include "config.h" |
30 | | #endif |
31 | | |
32 | | #include <string.h> |
33 | | #include <stdio.h> |
34 | | |
35 | | #include "video-info.h" |
36 | | #include "video-tile.h" |
37 | | |
38 | | #ifndef GST_DISABLE_GST_DEBUG |
39 | | #define GST_CAT_DEFAULT ensure_debug_category() |
40 | | static GstDebugCategory * |
41 | | ensure_debug_category (void) |
42 | 0 | { |
43 | 0 | static gsize cat_gonce = 0; |
44 | |
|
45 | 0 | if (g_once_init_enter (&cat_gonce)) { |
46 | 0 | gsize cat_done; |
47 | |
|
48 | 0 | cat_done = (gsize) _gst_debug_category_new ("video-info", 0, |
49 | 0 | "video-info structure"); |
50 | |
|
51 | 0 | g_once_init_leave (&cat_gonce, cat_done); |
52 | 0 | } |
53 | |
|
54 | 0 | return (GstDebugCategory *) cat_gonce; |
55 | 0 | } |
56 | | #else |
57 | | #define ensure_debug_category() /* NOOP */ |
58 | | #endif /* GST_DISABLE_GST_DEBUG */ |
59 | | |
60 | | /** |
61 | | * gst_video_info_copy: |
62 | | * @info: a #GstVideoInfo |
63 | | * |
64 | | * Copy a GstVideoInfo structure. |
65 | | * |
66 | | * Returns: (transfer full): a new #GstVideoInfo. free with gst_video_info_free. |
67 | | * |
68 | | * Since: 1.6 |
69 | | */ |
70 | | GstVideoInfo * |
71 | | gst_video_info_copy (const GstVideoInfo * info) |
72 | 0 | { |
73 | 0 | return g_memdup2 (info, sizeof (GstVideoInfo)); |
74 | 0 | } |
75 | | |
76 | | /** |
77 | | * gst_video_info_free: |
78 | | * @info: a #GstVideoInfo |
79 | | * |
80 | | * Free a GstVideoInfo structure previously allocated with gst_video_info_new() |
81 | | * or gst_video_info_copy(). |
82 | | * |
83 | | * Since: 1.6 |
84 | | */ |
85 | | void |
86 | | gst_video_info_free (GstVideoInfo * info) |
87 | 0 | { |
88 | 0 | g_free (info); |
89 | 0 | } |
90 | | |
91 | 0 | G_DEFINE_BOXED_TYPE (GstVideoInfo, gst_video_info, |
92 | 0 | (GBoxedCopyFunc) gst_video_info_copy, (GBoxedFreeFunc) gst_video_info_free); |
93 | 0 |
|
94 | 0 | /** |
95 | 0 | * gst_video_info_new: |
96 | 0 | * |
97 | 0 | * Allocate a new #GstVideoInfo that is also initialized with |
98 | 0 | * gst_video_info_init(). |
99 | 0 | * |
100 | 0 | * Returns: (transfer full): a new #GstVideoInfo. free with gst_video_info_free(). |
101 | 0 | * |
102 | 0 | * Since: 1.6 |
103 | 0 | */ |
104 | 0 | GstVideoInfo * |
105 | 0 | gst_video_info_new (void) |
106 | 0 | { |
107 | 0 | GstVideoInfo *info; |
108 | |
|
109 | 0 | info = g_new (GstVideoInfo, 1); |
110 | 0 | gst_video_info_init (info); |
111 | |
|
112 | 0 | return info; |
113 | 0 | } |
114 | | |
115 | | static gboolean fill_planes (GstVideoInfo * info, |
116 | | gsize plane_size[GST_VIDEO_MAX_PLANES]); |
117 | | |
118 | | /** |
119 | | * gst_video_info_init: |
120 | | * @info: (out caller-allocates): a #GstVideoInfo |
121 | | * |
122 | | * Initialize @info with default values. |
123 | | */ |
124 | | void |
125 | | gst_video_info_init (GstVideoInfo * info) |
126 | 6 | { |
127 | 6 | g_return_if_fail (info != NULL); |
128 | | |
129 | 6 | memset (info, 0, sizeof (GstVideoInfo)); |
130 | | |
131 | 6 | info->finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_UNKNOWN); |
132 | | |
133 | 6 | info->views = 1; |
134 | | /* arrange for sensible defaults, e.g. if turned into caps */ |
135 | 6 | info->fps_n = 0; |
136 | 6 | info->fps_d = 1; |
137 | 6 | info->par_n = 1; |
138 | 6 | info->par_d = 1; |
139 | 6 | GST_VIDEO_INFO_MULTIVIEW_MODE (info) = GST_VIDEO_MULTIVIEW_MODE_NONE; |
140 | 6 | GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) = GST_VIDEO_MULTIVIEW_FLAGS_NONE; |
141 | 6 | GST_VIDEO_INFO_FIELD_ORDER (info) = GST_VIDEO_FIELD_ORDER_UNKNOWN; |
142 | 6 | } |
143 | | |
144 | | #define MAKE_COLORIMETRY(r,m,t,p) { \ |
145 | | GST_VIDEO_COLOR_RANGE ##r, GST_VIDEO_COLOR_MATRIX_ ##m, \ |
146 | | GST_VIDEO_TRANSFER_ ##t, GST_VIDEO_COLOR_PRIMARIES_ ##p } |
147 | | |
148 | 0 | #define DEFAULT_YUV_SD 0 |
149 | 0 | #define DEFAULT_YUV_HD 1 |
150 | 0 | #define DEFAULT_RGB 2 |
151 | 0 | #define DEFAULT_GRAY 3 |
152 | 3 | #define DEFAULT_UNKNOWN 4 |
153 | | |
154 | | static const GstVideoColorimetry default_color[] = { |
155 | | MAKE_COLORIMETRY (_16_235, BT601, BT601, 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 | | }; |
161 | | |
162 | | static void |
163 | | set_default_colorimetry (GstVideoInfo * info) |
164 | 3 | { |
165 | 3 | const GstVideoFormatInfo *finfo = info->finfo; |
166 | | |
167 | 3 | if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo)) { |
168 | 0 | if (info->height > 576) { |
169 | 0 | info->colorimetry = default_color[DEFAULT_YUV_HD]; |
170 | 0 | } else { |
171 | 0 | info->colorimetry = default_color[DEFAULT_YUV_SD]; |
172 | 0 | } |
173 | 3 | } else if (GST_VIDEO_FORMAT_INFO_IS_GRAY (finfo)) { |
174 | 0 | info->colorimetry = default_color[DEFAULT_GRAY]; |
175 | 3 | } else if (GST_VIDEO_FORMAT_INFO_IS_RGB (finfo)) { |
176 | 0 | info->colorimetry = default_color[DEFAULT_RGB]; |
177 | 3 | } else { |
178 | 3 | info->colorimetry = default_color[DEFAULT_UNKNOWN]; |
179 | 3 | } |
180 | 3 | } |
181 | | |
182 | | static gboolean |
183 | | validate_colorimetry (const GstVideoInfo * info) |
184 | 0 | { |
185 | 0 | const GstVideoFormatInfo *finfo = info->finfo; |
186 | |
|
187 | 0 | if ((GST_VIDEO_FORMAT_INFO_IS_YUV (finfo) |
188 | 0 | || GST_VIDEO_FORMAT_INFO_IS_GRAY (finfo)) |
189 | 0 | && info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_RGB) { |
190 | 0 | GST_WARNING |
191 | 0 | ("color matrix RGB is only supported with RGB format, %s is not", |
192 | 0 | finfo->name); |
193 | 0 | return FALSE; |
194 | 0 | } |
195 | | |
196 | 0 | if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo) && |
197 | 0 | info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_UNKNOWN) { |
198 | 0 | GST_WARNING ("Need to specify a color matrix when using YUV format (%s)", |
199 | 0 | finfo->name); |
200 | 0 | return FALSE; |
201 | 0 | } |
202 | | |
203 | 0 | return TRUE; |
204 | 0 | } |
205 | | |
206 | | static void |
207 | | set_default_chroma_site (GstVideoInfo * info) |
208 | 3 | { |
209 | 3 | const GstVideoFormatInfo *finfo = info->finfo; |
210 | | |
211 | 3 | if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo)) { |
212 | 0 | if (info->height > 576) { |
213 | 0 | info->chroma_site = GST_VIDEO_CHROMA_SITE_H_COSITED; |
214 | 0 | } else { |
215 | 0 | info->chroma_site = GST_VIDEO_CHROMA_SITE_NONE; |
216 | 0 | } |
217 | 3 | } else { |
218 | 3 | info->chroma_site = GST_VIDEO_CHROMA_SITE_UNKNOWN; |
219 | 3 | } |
220 | 3 | } |
221 | | |
222 | | static gboolean |
223 | | validate_chroma_site (const GstVideoInfo * info) |
224 | 0 | { |
225 | 0 | const GstVideoFormatInfo *finfo = info->finfo; |
226 | |
|
227 | 0 | if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo)) { |
228 | | // FIXME: Might also want to check here for subsampling? |
229 | | // - chroma-site only makes sense with subsampled formats? |
230 | | // - ALT_LINE only makes sense for formats with vertical subsampling, and if |
231 | | // also V_COSITED? |
232 | 0 | if ((info->chroma_site & GST_VIDEO_CHROMA_SITE_NONE) && |
233 | 0 | (info->chroma_site & (GST_VIDEO_CHROMA_SITE_H_COSITED | |
234 | 0 | GST_VIDEO_CHROMA_SITE_V_COSITED))) { |
235 | 0 | GST_WARNING |
236 | 0 | ("No chroma siting together with horizontal or vertical cositing is invalid"); |
237 | 0 | return FALSE; |
238 | 0 | } |
239 | 0 | } else if (info->chroma_site != GST_VIDEO_CHROMA_SITE_UNKNOWN) { |
240 | 0 | GST_WARNING ("chroma-site only makes sense for YUV formats, %s is none", |
241 | 0 | finfo->name); |
242 | 0 | return FALSE; |
243 | 0 | } |
244 | | |
245 | 0 | return TRUE; |
246 | 0 | } |
247 | | |
248 | | static gboolean |
249 | | gst_video_info_set_format_common (GstVideoInfo * info, GstVideoFormat format, |
250 | | guint width, guint height) |
251 | 0 | { |
252 | 0 | g_return_val_if_fail (info != NULL, FALSE); |
253 | 0 | g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, FALSE); |
254 | | |
255 | 0 | if (width > G_MAXINT || height > G_MAXINT) |
256 | 0 | return FALSE; |
257 | | |
258 | 0 | gst_video_info_init (info); |
259 | |
|
260 | 0 | info->finfo = gst_video_format_get_info (format); |
261 | 0 | info->width = width; |
262 | 0 | info->height = height; |
263 | 0 | info->views = 1; |
264 | |
|
265 | 0 | set_default_colorimetry (info); |
266 | |
|
267 | 0 | return TRUE; |
268 | 0 | } |
269 | | |
270 | | /** |
271 | | * gst_video_info_set_format: |
272 | | * @info: a #GstVideoInfo |
273 | | * @format: the format |
274 | | * @width: a width |
275 | | * @height: a height |
276 | | * |
277 | | * Set the default info for a video frame of @format and @width and @height. |
278 | | * |
279 | | * Note: This initializes @info first, no values are preserved. This function |
280 | | * does not set the offsets correctly for interlaced vertically |
281 | | * subsampled formats. |
282 | | * |
283 | | * Returns: %FALSE if the returned video info is invalid, e.g. because the |
284 | | * size of a frame can't be represented as a 32 bit integer (Since: 1.12) |
285 | | */ |
286 | | gboolean |
287 | | gst_video_info_set_format (GstVideoInfo * info, GstVideoFormat format, |
288 | | guint width, guint height) |
289 | 0 | { |
290 | 0 | if (!gst_video_info_set_format_common (info, format, width, height)) |
291 | 0 | return FALSE; |
292 | | |
293 | 0 | return fill_planes (info, NULL); |
294 | 0 | } |
295 | | |
296 | | /** |
297 | | * gst_video_info_set_interlaced_format: |
298 | | * @info: a #GstVideoInfo |
299 | | * @format: the format |
300 | | * @mode: a #GstVideoInterlaceMode |
301 | | * @width: a width |
302 | | * @height: a height |
303 | | * |
304 | | * Same as #gst_video_info_set_format but also allowing to set the interlaced |
305 | | * mode. |
306 | | * |
307 | | * Returns: %FALSE if the returned video info is invalid, e.g. because the |
308 | | * size of a frame can't be represented as a 32 bit integer. |
309 | | * |
310 | | * Since: 1.16 |
311 | | */ |
312 | | gboolean |
313 | | gst_video_info_set_interlaced_format (GstVideoInfo * info, |
314 | | GstVideoFormat format, GstVideoInterlaceMode mode, guint width, |
315 | | guint height) |
316 | 0 | { |
317 | 0 | if (!gst_video_info_set_format_common (info, format, width, height)) |
318 | 0 | return FALSE; |
319 | | |
320 | 0 | GST_VIDEO_INFO_INTERLACE_MODE (info) = mode; |
321 | 0 | return fill_planes (info, NULL); |
322 | 0 | } |
323 | | |
324 | | static const gchar *interlace_mode[] = { |
325 | | "progressive", |
326 | | "interleaved", |
327 | | "mixed", |
328 | | "fields", |
329 | | "alternate" |
330 | | }; |
331 | | |
332 | | /** |
333 | | * gst_video_interlace_mode_to_string: |
334 | | * @mode: a #GstVideoInterlaceMode |
335 | | * |
336 | | * Convert @mode to its string representation. |
337 | | * |
338 | | * Returns: @mode as a string. |
339 | | * |
340 | | * Since: 1.6 |
341 | | */ |
342 | | const gchar * |
343 | | gst_video_interlace_mode_to_string (GstVideoInterlaceMode mode) |
344 | 0 | { |
345 | 0 | if (((guint) mode) >= G_N_ELEMENTS (interlace_mode)) |
346 | 0 | return NULL; |
347 | | |
348 | 0 | return interlace_mode[mode]; |
349 | 0 | } |
350 | | |
351 | | /** |
352 | | * gst_video_interlace_mode_from_string: |
353 | | * @mode: a mode |
354 | | * |
355 | | * Convert @mode to a #GstVideoInterlaceMode |
356 | | * |
357 | | * Returns: the #GstVideoInterlaceMode of @mode or |
358 | | * #GST_VIDEO_INTERLACE_MODE_PROGRESSIVE when @mode is not a valid |
359 | | * string representation for a #GstVideoInterlaceMode. |
360 | | * |
361 | | * Since: 1.6 |
362 | | */ |
363 | | GstVideoInterlaceMode |
364 | | gst_video_interlace_mode_from_string (const gchar * mode) |
365 | 0 | { |
366 | 0 | gint i; |
367 | 0 | for (i = 0; i < G_N_ELEMENTS (interlace_mode); i++) { |
368 | 0 | if (g_str_equal (interlace_mode[i], mode)) |
369 | 0 | return i; |
370 | 0 | } |
371 | 0 | return GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; |
372 | 0 | } |
373 | | |
374 | | static const gchar *field_order[] = { |
375 | | "unknown", |
376 | | "top-field-first", |
377 | | "bottom-field-first" |
378 | | }; |
379 | | |
380 | | /** |
381 | | * gst_video_field_order_to_string: |
382 | | * @order: a #GstVideoFieldOrder |
383 | | * |
384 | | * Convert @order to its string representation. |
385 | | * |
386 | | * Returns: @order as a string. |
387 | | * |
388 | | * Since: 1.12 |
389 | | */ |
390 | | const gchar * |
391 | | gst_video_field_order_to_string (GstVideoFieldOrder order) |
392 | 0 | { |
393 | 0 | if (((guint) order) >= G_N_ELEMENTS (field_order)) |
394 | 0 | return NULL; |
395 | | |
396 | 0 | return field_order[order]; |
397 | 0 | } |
398 | | |
399 | | /** |
400 | | * gst_video_field_order_from_string: |
401 | | * @order: a field order |
402 | | * |
403 | | * Convert @order to a #GstVideoFieldOrder |
404 | | * |
405 | | * Returns: the #GstVideoFieldOrder of @order or |
406 | | * #GST_VIDEO_FIELD_ORDER_UNKNOWN when @order is not a valid |
407 | | * string representation for a #GstVideoFieldOrder. |
408 | | * |
409 | | * Since: 1.12 |
410 | | */ |
411 | | GstVideoFieldOrder |
412 | | gst_video_field_order_from_string (const gchar * order) |
413 | 0 | { |
414 | 0 | gint i; |
415 | 0 | for (i = 0; i < G_N_ELEMENTS (field_order); i++) { |
416 | 0 | if (g_str_equal (field_order[i], order)) |
417 | 0 | return i; |
418 | 0 | } |
419 | 0 | return GST_VIDEO_FIELD_ORDER_UNKNOWN; |
420 | 0 | } |
421 | | |
422 | | /** |
423 | | * gst_video_info_from_caps: |
424 | | * @info: (out caller-allocates): #GstVideoInfo |
425 | | * @caps: a #GstCaps |
426 | | * |
427 | | * Parse @caps and update @info. |
428 | | * |
429 | | * Returns: TRUE if @caps could be parsed |
430 | | */ |
431 | | gboolean |
432 | | gst_video_info_from_caps (GstVideoInfo * info, const GstCaps * caps) |
433 | 3 | { |
434 | 3 | GstStructure *structure; |
435 | 3 | const gchar *s; |
436 | 3 | GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN; |
437 | 3 | gint width = 0, height = 0; |
438 | 3 | gint fps_n, fps_d; |
439 | 3 | gint par_n, par_d; |
440 | 3 | guint multiview_flags; |
441 | | |
442 | 3 | g_return_val_if_fail (info != NULL, FALSE); |
443 | 3 | g_return_val_if_fail (caps != NULL, FALSE); |
444 | 3 | g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE); |
445 | | |
446 | 3 | GST_DEBUG ("parsing caps %" GST_PTR_FORMAT, caps); |
447 | | |
448 | 3 | structure = gst_caps_get_structure (caps, 0); |
449 | | |
450 | 3 | if (gst_structure_has_name (structure, "video/x-raw")) { |
451 | 0 | if (!(s = gst_structure_get_string (structure, "format"))) |
452 | 0 | goto no_format; |
453 | | |
454 | 0 | format = gst_video_format_from_string (s); |
455 | 0 | if (format == GST_VIDEO_FORMAT_UNKNOWN) |
456 | 0 | goto unknown_format; |
457 | |
|
458 | 3 | } else if (g_str_has_prefix (gst_structure_get_name (structure), "video/") || |
459 | 3 | g_str_has_prefix (gst_structure_get_name (structure), "image/")) { |
460 | 3 | format = GST_VIDEO_FORMAT_ENCODED; |
461 | 3 | } else { |
462 | 0 | goto wrong_name; |
463 | 0 | } |
464 | | |
465 | | /* width and height are mandatory, except for non-raw-formats */ |
466 | 3 | if (!gst_structure_get_int (structure, "width", &width) && |
467 | 0 | format != GST_VIDEO_FORMAT_ENCODED) |
468 | 0 | goto no_width; |
469 | 3 | if (!gst_structure_get_int (structure, "height", &height) && |
470 | 0 | format != GST_VIDEO_FORMAT_ENCODED) |
471 | 0 | goto no_height; |
472 | | |
473 | 3 | gst_video_info_init (info); |
474 | | |
475 | 3 | info->finfo = gst_video_format_get_info (format); |
476 | 3 | info->width = width; |
477 | 3 | info->height = height; |
478 | | |
479 | 3 | if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)) { |
480 | 3 | if (fps_n == 0) { |
481 | | /* variable framerate */ |
482 | 0 | info->flags |= GST_VIDEO_FLAG_VARIABLE_FPS; |
483 | | /* see if we have a max-framerate */ |
484 | 0 | gst_structure_get_fraction (structure, "max-framerate", &fps_n, &fps_d); |
485 | 0 | } |
486 | 3 | info->fps_n = fps_n; |
487 | 3 | info->fps_d = fps_d; |
488 | 3 | } else { |
489 | | /* unspecified is variable framerate */ |
490 | 0 | info->fps_n = 0; |
491 | 0 | info->fps_d = 1; |
492 | 0 | } |
493 | | |
494 | 3 | if (gst_structure_get_fraction (structure, "pixel-aspect-ratio", |
495 | 3 | &par_n, &par_d)) { |
496 | 3 | info->par_n = par_n; |
497 | 3 | info->par_d = par_d; |
498 | 3 | } else { |
499 | 0 | info->par_n = 1; |
500 | 0 | info->par_d = 1; |
501 | 0 | } |
502 | | |
503 | 3 | if ((s = gst_structure_get_string (structure, "interlace-mode"))) |
504 | 0 | info->interlace_mode = gst_video_interlace_mode_from_string (s); |
505 | 3 | else |
506 | 3 | info->interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; |
507 | | |
508 | | /* Interlaced feature is mandatory for raw alternate streams */ |
509 | 3 | if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE && |
510 | 0 | format != GST_VIDEO_FORMAT_ENCODED) { |
511 | 0 | GstCapsFeatures *f; |
512 | |
|
513 | 0 | f = gst_caps_get_features (caps, 0); |
514 | 0 | if (!f |
515 | 0 | || !gst_caps_features_contains (f, GST_CAPS_FEATURE_FORMAT_INTERLACED)) |
516 | 0 | goto alternate_no_feature; |
517 | 0 | } |
518 | | |
519 | 3 | if (GST_VIDEO_INFO_IS_INTERLACED (info) && |
520 | 0 | (s = gst_structure_get_string (structure, "field-order"))) { |
521 | 0 | GST_VIDEO_INFO_FIELD_ORDER (info) = gst_video_field_order_from_string (s); |
522 | 3 | } else { |
523 | 3 | GST_VIDEO_INFO_FIELD_ORDER (info) = GST_VIDEO_FIELD_ORDER_UNKNOWN; |
524 | 3 | } |
525 | | |
526 | 3 | { |
527 | 3 | if ((s = gst_structure_get_string (structure, "multiview-mode"))) |
528 | 0 | GST_VIDEO_INFO_MULTIVIEW_MODE (info) = |
529 | 0 | gst_video_multiview_mode_from_caps_string (s); |
530 | 3 | else |
531 | 3 | GST_VIDEO_INFO_MULTIVIEW_MODE (info) = GST_VIDEO_MULTIVIEW_MODE_NONE; |
532 | | |
533 | 3 | if (gst_structure_get_flagset (structure, "multiview-flags", |
534 | 3 | &multiview_flags, NULL)) |
535 | 0 | GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) = multiview_flags; |
536 | | |
537 | 3 | if (!gst_structure_get_int (structure, "views", &info->views)) |
538 | 3 | info->views = 1; |
539 | | |
540 | | /* At one point, I tried normalising the half-aspect flag here, |
541 | | * but it behaves weird for GstVideoInfo operations other than |
542 | | * directly converting to/from caps - sometimes causing the |
543 | | * PAR to be doubled/halved too many times */ |
544 | 3 | } |
545 | | |
546 | 3 | if ((s = gst_structure_get_string (structure, "chroma-site"))) { |
547 | 0 | info->chroma_site = gst_video_chroma_site_from_string (s); |
548 | 0 | if (!validate_chroma_site (info)) { |
549 | 0 | GST_WARNING ("invalid chroma-site, using default"); |
550 | 0 | set_default_chroma_site (info); |
551 | 0 | } else if (GST_VIDEO_FORMAT_INFO_IS_YUV (info->finfo) |
552 | 0 | && info->chroma_site == GST_VIDEO_CHROMA_SITE_UNKNOWN) { |
553 | | /* force a default chroma-site for YUV formats */ |
554 | 0 | set_default_chroma_site (info); |
555 | 0 | } |
556 | 3 | } else { |
557 | 3 | set_default_chroma_site (info); |
558 | 3 | } |
559 | | |
560 | 3 | if ((s = gst_structure_get_string (structure, "colorimetry"))) { |
561 | 0 | if (!gst_video_colorimetry_from_string (&info->colorimetry, s)) { |
562 | 0 | GST_WARNING ("unparsable colorimetry, using default"); |
563 | 0 | set_default_colorimetry (info); |
564 | 0 | } else if (!validate_colorimetry (info)) { |
565 | 0 | GST_WARNING ("invalid colorimetry, using default"); |
566 | 0 | set_default_colorimetry (info); |
567 | 0 | } else { |
568 | | /* force RGB matrix for RGB formats */ |
569 | 0 | if (GST_VIDEO_FORMAT_INFO_IS_RGB (info->finfo) && |
570 | 0 | info->colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_RGB) { |
571 | 0 | GST_WARNING ("invalid matrix %d for RGB format, using RGB", |
572 | 0 | info->colorimetry.matrix); |
573 | 0 | info->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB; |
574 | 0 | } |
575 | 0 | } |
576 | 3 | } else { |
577 | 3 | GST_DEBUG ("no colorimetry, using default"); |
578 | 3 | set_default_colorimetry (info); |
579 | 3 | } |
580 | | |
581 | 3 | if (!fill_planes (info, NULL)) |
582 | 0 | return FALSE; |
583 | | |
584 | 3 | return TRUE; |
585 | | |
586 | | /* ERROR */ |
587 | 0 | wrong_name: |
588 | 0 | { |
589 | 0 | GST_ERROR ("wrong name '%s', expected video/ or image/", |
590 | 0 | gst_structure_get_name (structure)); |
591 | 0 | return FALSE; |
592 | 3 | } |
593 | 0 | no_format: |
594 | 0 | { |
595 | 0 | GST_ERROR ("no format given"); |
596 | 0 | return FALSE; |
597 | 3 | } |
598 | 0 | unknown_format: |
599 | 0 | { |
600 | 0 | GST_ERROR ("unknown format '%s' given", s); |
601 | 0 | return FALSE; |
602 | 3 | } |
603 | 0 | no_width: |
604 | 0 | { |
605 | 0 | GST_ERROR ("no width property given"); |
606 | 0 | return FALSE; |
607 | 3 | } |
608 | 0 | no_height: |
609 | 0 | { |
610 | 0 | GST_ERROR ("no height property given"); |
611 | 0 | return FALSE; |
612 | 3 | } |
613 | 0 | alternate_no_feature: |
614 | 0 | { |
615 | 0 | GST_ERROR |
616 | 0 | ("caps has 'interlace-mode=alternate' but doesn't have the Interlaced feature"); |
617 | 0 | return FALSE; |
618 | 3 | } |
619 | 3 | } |
620 | | |
621 | | /** |
622 | | * gst_video_info_new_from_caps: |
623 | | * @caps: a #GstCaps |
624 | | * |
625 | | * Parse @caps to generate a #GstVideoInfo. |
626 | | * |
627 | | * Returns: (transfer full) (nullable): A #GstVideoInfo, or %NULL if @caps couldn't be parsed |
628 | | * Since: 1.20 |
629 | | */ |
630 | | GstVideoInfo * |
631 | | gst_video_info_new_from_caps (const GstCaps * caps) |
632 | 0 | { |
633 | 0 | GstVideoInfo *ret = gst_video_info_new (); |
634 | |
|
635 | 0 | if (gst_video_info_from_caps (ret, caps)) { |
636 | 0 | return ret; |
637 | 0 | } else { |
638 | 0 | gst_video_info_free (ret); |
639 | 0 | return NULL; |
640 | 0 | } |
641 | 0 | } |
642 | | |
643 | | /** |
644 | | * gst_video_info_is_equal: |
645 | | * @info: a #GstVideoInfo |
646 | | * @other: a #GstVideoInfo |
647 | | * |
648 | | * Compares two #GstVideoInfo and returns whether they are equal or not |
649 | | * |
650 | | * Returns: %TRUE if @info and @other are equal, else %FALSE. |
651 | | */ |
652 | | gboolean |
653 | | gst_video_info_is_equal (const GstVideoInfo * info, const GstVideoInfo * other) |
654 | 0 | { |
655 | 0 | gint i; |
656 | |
|
657 | 0 | if (info == other) |
658 | 0 | return TRUE; |
659 | 0 | if (info->finfo == NULL || other->finfo == NULL) |
660 | 0 | return FALSE; |
661 | 0 | if (GST_VIDEO_INFO_FORMAT (info) != GST_VIDEO_INFO_FORMAT (other)) |
662 | 0 | return FALSE; |
663 | 0 | if (GST_VIDEO_INFO_INTERLACE_MODE (info) != |
664 | 0 | GST_VIDEO_INFO_INTERLACE_MODE (other)) |
665 | 0 | return FALSE; |
666 | 0 | if (GST_VIDEO_INFO_FLAGS (info) != GST_VIDEO_INFO_FLAGS (other)) |
667 | 0 | return FALSE; |
668 | 0 | if (GST_VIDEO_INFO_WIDTH (info) != GST_VIDEO_INFO_WIDTH (other)) |
669 | 0 | return FALSE; |
670 | 0 | if (GST_VIDEO_INFO_HEIGHT (info) != GST_VIDEO_INFO_HEIGHT (other)) |
671 | 0 | return FALSE; |
672 | 0 | if (GST_VIDEO_INFO_SIZE (info) != GST_VIDEO_INFO_SIZE (other)) |
673 | 0 | return FALSE; |
674 | 0 | if (GST_VIDEO_INFO_PAR_N (info) != GST_VIDEO_INFO_PAR_N (other)) |
675 | 0 | return FALSE; |
676 | 0 | if (GST_VIDEO_INFO_PAR_D (info) != GST_VIDEO_INFO_PAR_D (other)) |
677 | 0 | return FALSE; |
678 | 0 | if (GST_VIDEO_INFO_FPS_N (info) != GST_VIDEO_INFO_FPS_N (other)) |
679 | 0 | return FALSE; |
680 | 0 | if (GST_VIDEO_INFO_FPS_D (info) != GST_VIDEO_INFO_FPS_D (other)) |
681 | 0 | return FALSE; |
682 | 0 | if (!gst_video_colorimetry_is_equal (&GST_VIDEO_INFO_COLORIMETRY (info), |
683 | 0 | &GST_VIDEO_INFO_COLORIMETRY (other))) |
684 | 0 | return FALSE; |
685 | 0 | if (GST_VIDEO_INFO_CHROMA_SITE (info) != GST_VIDEO_INFO_CHROMA_SITE (other)) |
686 | 0 | return FALSE; |
687 | 0 | if (GST_VIDEO_INFO_MULTIVIEW_MODE (info) != |
688 | 0 | GST_VIDEO_INFO_MULTIVIEW_MODE (other)) |
689 | 0 | return FALSE; |
690 | 0 | if (GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) != |
691 | 0 | GST_VIDEO_INFO_MULTIVIEW_FLAGS (other)) |
692 | 0 | return FALSE; |
693 | 0 | if (GST_VIDEO_INFO_VIEWS (info) != GST_VIDEO_INFO_VIEWS (other)) |
694 | 0 | return FALSE; |
695 | | |
696 | 0 | for (i = 0; i < info->finfo->n_planes; i++) { |
697 | 0 | if (info->stride[i] != other->stride[i]) |
698 | 0 | return FALSE; |
699 | 0 | if (info->offset[i] != other->offset[i]) |
700 | 0 | return FALSE; |
701 | 0 | } |
702 | | |
703 | 0 | return TRUE; |
704 | 0 | } |
705 | | |
706 | | /** |
707 | | * gst_video_info_to_caps: |
708 | | * @info: a #GstVideoInfo |
709 | | * |
710 | | * Convert the values of @info into a #GstCaps. |
711 | | * |
712 | | * Returns: (transfer full): a new #GstCaps containing the info of @info. |
713 | | */ |
714 | | GstCaps * |
715 | | gst_video_info_to_caps (const GstVideoInfo * info) |
716 | 0 | { |
717 | 0 | GstCaps *caps; |
718 | 0 | const gchar *format; |
719 | 0 | gchar *color; |
720 | 0 | gint par_n, par_d; |
721 | 0 | GstVideoColorimetry colorimetry; |
722 | |
|
723 | 0 | g_return_val_if_fail (info != NULL, NULL); |
724 | 0 | g_return_val_if_fail (info->finfo != NULL, NULL); |
725 | 0 | g_return_val_if_fail (info->finfo->format != GST_VIDEO_FORMAT_UNKNOWN, NULL); |
726 | | |
727 | 0 | format = gst_video_format_to_string (info->finfo->format); |
728 | 0 | g_return_val_if_fail (format != NULL, NULL); |
729 | | |
730 | 0 | caps = gst_caps_new_static_str_simple ("video/x-raw", |
731 | 0 | "format", G_TYPE_STRING, format, |
732 | 0 | "width", G_TYPE_INT, info->width, |
733 | 0 | "height", G_TYPE_INT, info->height, NULL); |
734 | |
|
735 | 0 | par_n = info->par_n; |
736 | 0 | par_d = info->par_d; |
737 | |
|
738 | 0 | gst_caps_set_simple_static_str (caps, "interlace-mode", G_TYPE_STRING, |
739 | 0 | gst_video_interlace_mode_to_string (info->interlace_mode), NULL); |
740 | |
|
741 | 0 | if ((info->interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED || |
742 | 0 | info->interlace_mode == GST_VIDEO_INTERLACE_MODE_FIELDS || |
743 | 0 | info->interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE) && |
744 | 0 | GST_VIDEO_INFO_FIELD_ORDER (info) != GST_VIDEO_FIELD_ORDER_UNKNOWN) { |
745 | 0 | gst_caps_set_simple_static_str (caps, "field-order", G_TYPE_STRING, |
746 | 0 | gst_video_field_order_to_string (GST_VIDEO_INFO_FIELD_ORDER (info)), |
747 | 0 | NULL); |
748 | 0 | } |
749 | |
|
750 | 0 | if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE) { |
751 | | /* 'alternate' mode must always be accompanied by interlaced caps feature. |
752 | | */ |
753 | 0 | GstCapsFeatures *features; |
754 | |
|
755 | 0 | features = |
756 | 0 | gst_caps_features_new_static_str (GST_CAPS_FEATURE_FORMAT_INTERLACED, |
757 | 0 | NULL); |
758 | 0 | gst_caps_set_features (caps, 0, features); |
759 | 0 | } |
760 | |
|
761 | 0 | if (GST_VIDEO_INFO_MULTIVIEW_MODE (info) != GST_VIDEO_MULTIVIEW_MODE_NONE) { |
762 | 0 | const gchar *caps_str = NULL; |
763 | 0 | GstVideoMultiviewFlags multiview_flags = |
764 | 0 | GST_VIDEO_INFO_MULTIVIEW_FLAGS (info); |
765 | | |
766 | | /* If the half-aspect flag is set, applying it into the PAR of the |
767 | | * resulting caps now seems safe, and helps with automatic behaviour |
768 | | * in elements that aren't explicitly multiview aware */ |
769 | 0 | if (multiview_flags & GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT) { |
770 | 0 | multiview_flags &= ~GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT; |
771 | 0 | switch (GST_VIDEO_INFO_MULTIVIEW_MODE (info)) { |
772 | 0 | case GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE: |
773 | 0 | case GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE_QUINCUNX: |
774 | 0 | case GST_VIDEO_MULTIVIEW_MODE_COLUMN_INTERLEAVED: |
775 | 0 | case GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD: |
776 | 0 | par_n *= 2; /* double the width / half the height */ |
777 | 0 | break; |
778 | 0 | case GST_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED: |
779 | 0 | case GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM: |
780 | 0 | par_d *= 2; /* half the width / double the height */ |
781 | 0 | break; |
782 | 0 | default: |
783 | 0 | break; |
784 | 0 | } |
785 | 0 | } |
786 | | |
787 | 0 | caps_str = |
788 | 0 | gst_video_multiview_mode_to_caps_string (GST_VIDEO_INFO_MULTIVIEW_MODE |
789 | 0 | (info)); |
790 | 0 | if (caps_str != NULL) { |
791 | 0 | gst_caps_set_simple_static_str (caps, "multiview-mode", G_TYPE_STRING, |
792 | 0 | caps_str, "multiview-flags", GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, |
793 | 0 | multiview_flags, GST_FLAG_SET_MASK_EXACT, NULL); |
794 | 0 | } |
795 | 0 | } |
796 | | |
797 | 0 | gst_caps_set_simple_static_str (caps, "pixel-aspect-ratio", |
798 | 0 | GST_TYPE_FRACTION, par_n, par_d, NULL); |
799 | |
|
800 | 0 | if (info->chroma_site != GST_VIDEO_CHROMA_SITE_UNKNOWN) { |
801 | 0 | gchar *chroma_site = gst_video_chroma_site_to_string (info->chroma_site); |
802 | |
|
803 | 0 | if (!chroma_site) { |
804 | 0 | GST_WARNING ("Couldn't convert chroma-site 0x%x to string", |
805 | 0 | info->chroma_site); |
806 | 0 | } else { |
807 | 0 | gst_caps_set_simple_static_str (caps, |
808 | 0 | "chroma-site", G_TYPE_STRING, chroma_site, NULL); |
809 | 0 | g_free (chroma_site); |
810 | 0 | } |
811 | 0 | } |
812 | | |
813 | | /* make sure we set the RGB matrix for RGB formats */ |
814 | 0 | colorimetry = info->colorimetry; |
815 | 0 | if (GST_VIDEO_FORMAT_INFO_IS_RGB (info->finfo) && |
816 | 0 | colorimetry.matrix != GST_VIDEO_COLOR_MATRIX_RGB) { |
817 | 0 | GST_WARNING ("invalid matrix %d for RGB format, using RGB", |
818 | 0 | colorimetry.matrix); |
819 | 0 | colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_RGB; |
820 | 0 | } |
821 | 0 | if ((color = gst_video_colorimetry_to_string (&colorimetry))) { |
822 | 0 | gst_caps_set_simple_static_str (caps, "colorimetry", G_TYPE_STRING, color, |
823 | 0 | NULL); |
824 | 0 | g_free (color); |
825 | 0 | } |
826 | |
|
827 | 0 | if (info->views > 1) |
828 | 0 | gst_caps_set_simple_static_str (caps, "views", G_TYPE_INT, info->views, |
829 | 0 | NULL); |
830 | |
|
831 | 0 | if (info->flags & GST_VIDEO_FLAG_VARIABLE_FPS && info->fps_n != 0) { |
832 | | /* variable fps with a max-framerate */ |
833 | 0 | gst_caps_set_simple_static_str (caps, "framerate", GST_TYPE_FRACTION, 0, 1, |
834 | 0 | "max-framerate", GST_TYPE_FRACTION, info->fps_n, info->fps_d, NULL); |
835 | 0 | } else { |
836 | | /* no variable fps or no max-framerate */ |
837 | 0 | gst_caps_set_simple_static_str (caps, "framerate", GST_TYPE_FRACTION, |
838 | 0 | info->fps_n, info->fps_d, NULL); |
839 | 0 | } |
840 | |
|
841 | 0 | return caps; |
842 | 0 | } |
843 | | |
844 | | static gboolean |
845 | | fill_planes (GstVideoInfo * info, gsize plane_size[GST_VIDEO_MAX_PLANES]) |
846 | 3 | { |
847 | 3 | gsize width, height, cr_h; |
848 | 3 | gint bpp = 0, i; |
849 | | |
850 | 3 | width = (gsize) info->width; |
851 | 3 | height = (gsize) GST_VIDEO_INFO_FIELD_HEIGHT (info); |
852 | | |
853 | | /* Sanity check the resulting frame size for overflows */ |
854 | 3 | for (i = 0; i < GST_VIDEO_INFO_N_COMPONENTS (info); i++) |
855 | 3 | bpp += GST_VIDEO_INFO_COMP_DEPTH (info, i); |
856 | 3 | bpp = GST_ROUND_UP_8 (bpp) / 8; |
857 | 3 | if (bpp > 0 && GST_ROUND_UP_128 ((guint64) width) * ((guint64) height) >= |
858 | 0 | G_MAXUINT / bpp) { |
859 | 0 | GST_ERROR ("Frame size %ux%u would overflow", info->width, info->height); |
860 | 0 | return FALSE; |
861 | 0 | } |
862 | | |
863 | 3 | switch (info->finfo->format) { |
864 | 0 | case GST_VIDEO_FORMAT_YUY2: |
865 | 0 | case GST_VIDEO_FORMAT_YVYU: |
866 | 0 | case GST_VIDEO_FORMAT_UYVY: |
867 | 0 | case GST_VIDEO_FORMAT_VYUY: |
868 | 0 | info->stride[0] = GST_ROUND_UP_4 (width * 2); |
869 | 0 | info->offset[0] = 0; |
870 | 0 | info->size = info->stride[0] * height; |
871 | 0 | break; |
872 | 0 | case GST_VIDEO_FORMAT_AYUV: |
873 | 0 | case GST_VIDEO_FORMAT_RGBx: |
874 | 0 | case GST_VIDEO_FORMAT_RGBA: |
875 | 0 | case GST_VIDEO_FORMAT_BGRx: |
876 | 0 | case GST_VIDEO_FORMAT_BGRA: |
877 | 0 | case GST_VIDEO_FORMAT_xRGB: |
878 | 0 | case GST_VIDEO_FORMAT_ARGB: |
879 | 0 | case GST_VIDEO_FORMAT_xBGR: |
880 | 0 | case GST_VIDEO_FORMAT_ABGR: |
881 | 0 | case GST_VIDEO_FORMAT_r210: |
882 | 0 | case GST_VIDEO_FORMAT_Y410: |
883 | 0 | case GST_VIDEO_FORMAT_VUYA: |
884 | 0 | case GST_VIDEO_FORMAT_BGR10A2_LE: |
885 | 0 | case GST_VIDEO_FORMAT_RGB10A2_LE: |
886 | 0 | case GST_VIDEO_FORMAT_BGR10x2_LE: |
887 | 0 | case GST_VIDEO_FORMAT_RGB10x2_LE: |
888 | 0 | case GST_VIDEO_FORMAT_RBGA: |
889 | 0 | info->stride[0] = width * 4; |
890 | 0 | info->offset[0] = 0; |
891 | 0 | info->size = info->stride[0] * height; |
892 | 0 | break; |
893 | 0 | case GST_VIDEO_FORMAT_RGB16: |
894 | 0 | case GST_VIDEO_FORMAT_BGR16: |
895 | 0 | case GST_VIDEO_FORMAT_RGB15: |
896 | 0 | case GST_VIDEO_FORMAT_BGR15: |
897 | 0 | info->stride[0] = GST_ROUND_UP_4 (width * 2); |
898 | 0 | info->offset[0] = 0; |
899 | 0 | info->size = info->stride[0] * height; |
900 | 0 | break; |
901 | 0 | case GST_VIDEO_FORMAT_RGB: |
902 | 0 | case GST_VIDEO_FORMAT_BGR: |
903 | 0 | case GST_VIDEO_FORMAT_v308: |
904 | 0 | case GST_VIDEO_FORMAT_IYU2: |
905 | 0 | info->stride[0] = GST_ROUND_UP_4 (width * 3); |
906 | 0 | info->offset[0] = 0; |
907 | 0 | info->size = info->stride[0] * height; |
908 | 0 | break; |
909 | 0 | case GST_VIDEO_FORMAT_v210: |
910 | 0 | info->stride[0] = ((width + 47) / 48) * 128; |
911 | 0 | info->offset[0] = 0; |
912 | 0 | info->size = info->stride[0] * height; |
913 | 0 | break; |
914 | 0 | case GST_VIDEO_FORMAT_v216: |
915 | 0 | case GST_VIDEO_FORMAT_Y210: |
916 | 0 | case GST_VIDEO_FORMAT_Y212_BE: |
917 | 0 | case GST_VIDEO_FORMAT_Y212_LE: |
918 | 0 | case GST_VIDEO_FORMAT_Y216_BE: |
919 | 0 | case GST_VIDEO_FORMAT_Y216_LE: |
920 | 0 | info->stride[0] = GST_ROUND_UP_8 (width * 4); |
921 | 0 | info->offset[0] = 0; |
922 | 0 | info->size = info->stride[0] * height; |
923 | 0 | break; |
924 | 0 | case GST_VIDEO_FORMAT_GRAY8: |
925 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
926 | 0 | info->offset[0] = 0; |
927 | 0 | info->size = info->stride[0] * height; |
928 | 0 | break; |
929 | 0 | case GST_VIDEO_FORMAT_GRAY16_BE: |
930 | 0 | case GST_VIDEO_FORMAT_GRAY16_LE: |
931 | 0 | info->stride[0] = GST_ROUND_UP_4 (width * 2); |
932 | 0 | info->offset[0] = 0; |
933 | 0 | info->size = info->stride[0] * height; |
934 | 0 | break; |
935 | 0 | case GST_VIDEO_FORMAT_UYVP: |
936 | 0 | info->stride[0] = GST_ROUND_UP_4 ((GST_ROUND_UP_2 (width) * 5) / 2); |
937 | 0 | info->offset[0] = 0; |
938 | 0 | info->size = info->stride[0] * height; |
939 | 0 | break; |
940 | 0 | case GST_VIDEO_FORMAT_RGB8P: |
941 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
942 | 0 | info->stride[1] = 4; |
943 | 0 | info->offset[0] = 0; |
944 | 0 | info->offset[1] = info->stride[0] * height; |
945 | 0 | info->size = info->offset[1] + (4 * 256); |
946 | 0 | break; |
947 | 0 | case GST_VIDEO_FORMAT_IYU1: |
948 | 0 | info->stride[0] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) + |
949 | 0 | GST_ROUND_UP_4 (width) / 2); |
950 | 0 | info->offset[0] = 0; |
951 | 0 | info->size = info->stride[0] * height; |
952 | 0 | break; |
953 | 0 | case GST_VIDEO_FORMAT_ARGB64: |
954 | 0 | case GST_VIDEO_FORMAT_ARGB64_BE: |
955 | 0 | case GST_VIDEO_FORMAT_ARGB64_LE: |
956 | 0 | case GST_VIDEO_FORMAT_RGBA64_BE: |
957 | 0 | case GST_VIDEO_FORMAT_RGBA64_LE: |
958 | 0 | case GST_VIDEO_FORMAT_BGRA64_BE: |
959 | 0 | case GST_VIDEO_FORMAT_BGRA64_LE: |
960 | 0 | case GST_VIDEO_FORMAT_ABGR64_BE: |
961 | 0 | case GST_VIDEO_FORMAT_ABGR64_LE: |
962 | 0 | case GST_VIDEO_FORMAT_AYUV64: |
963 | 0 | case GST_VIDEO_FORMAT_Y412_BE: |
964 | 0 | case GST_VIDEO_FORMAT_Y412_LE: |
965 | 0 | case GST_VIDEO_FORMAT_Y416_BE: |
966 | 0 | case GST_VIDEO_FORMAT_Y416_LE: |
967 | 0 | info->stride[0] = width * 8; |
968 | 0 | info->offset[0] = 0; |
969 | 0 | info->size = info->stride[0] * height; |
970 | 0 | break; |
971 | 0 | case GST_VIDEO_FORMAT_I420: |
972 | 0 | case GST_VIDEO_FORMAT_YV12: /* same as I420, but plane 1+2 swapped */ |
973 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
974 | 0 | info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2); |
975 | 0 | info->stride[2] = info->stride[1]; |
976 | 0 | info->offset[0] = 0; |
977 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
978 | 0 | cr_h = GST_ROUND_UP_2 (height) / 2; |
979 | 0 | if (GST_VIDEO_INFO_IS_INTERLACED (info)) |
980 | 0 | cr_h = GST_ROUND_UP_2 (cr_h); |
981 | 0 | info->offset[2] = info->offset[1] + info->stride[1] * cr_h; |
982 | 0 | info->size = info->offset[2] + info->stride[2] * cr_h; |
983 | 0 | break; |
984 | 0 | case GST_VIDEO_FORMAT_Y41B: |
985 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
986 | 0 | info->stride[1] = GST_ROUND_UP_16 (width) / 4; |
987 | 0 | info->stride[2] = info->stride[1]; |
988 | 0 | info->offset[0] = 0; |
989 | 0 | info->offset[1] = info->stride[0] * height; |
990 | 0 | info->offset[2] = info->offset[1] + info->stride[1] * height; |
991 | | /* simplification of ROUNDUP4(w)*h + 2*((ROUNDUP16(w)/4)*h */ |
992 | 0 | info->size = (info->stride[0] + (GST_ROUND_UP_16 (width) / 2)) * height; |
993 | 0 | break; |
994 | 0 | case GST_VIDEO_FORMAT_Y42B: |
995 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
996 | 0 | info->stride[1] = GST_ROUND_UP_8 (width) / 2; |
997 | 0 | info->stride[2] = info->stride[1]; |
998 | 0 | info->offset[0] = 0; |
999 | 0 | info->offset[1] = info->stride[0] * height; |
1000 | 0 | info->offset[2] = info->offset[1] + info->stride[1] * height; |
1001 | | /* simplification of ROUNDUP4(w)*h + 2*(ROUNDUP8(w)/2)*h */ |
1002 | 0 | info->size = (info->stride[0] + GST_ROUND_UP_8 (width)) * height; |
1003 | 0 | break; |
1004 | 0 | case GST_VIDEO_FORMAT_Y444: |
1005 | 0 | case GST_VIDEO_FORMAT_GBR: |
1006 | 0 | case GST_VIDEO_FORMAT_RGBP: |
1007 | 0 | case GST_VIDEO_FORMAT_BGRP: |
1008 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
1009 | 0 | info->stride[1] = info->stride[0]; |
1010 | 0 | info->stride[2] = info->stride[0]; |
1011 | 0 | info->offset[0] = 0; |
1012 | 0 | info->offset[1] = info->stride[0] * height; |
1013 | 0 | info->offset[2] = info->offset[1] * 2; |
1014 | 0 | info->size = info->stride[0] * height * 3; |
1015 | 0 | break; |
1016 | 0 | case GST_VIDEO_FORMAT_GBRA: |
1017 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
1018 | 0 | info->stride[1] = info->stride[0]; |
1019 | 0 | info->stride[2] = info->stride[0]; |
1020 | 0 | info->stride[3] = info->stride[0]; |
1021 | 0 | info->offset[0] = 0; |
1022 | 0 | info->offset[1] = info->stride[0] * height; |
1023 | 0 | info->offset[2] = info->offset[1] * 2; |
1024 | 0 | info->offset[3] = info->offset[1] * 3; |
1025 | 0 | info->size = info->stride[0] * height * 4; |
1026 | 0 | break; |
1027 | 0 | case GST_VIDEO_FORMAT_NV12: |
1028 | 0 | case GST_VIDEO_FORMAT_NV21: |
1029 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
1030 | 0 | info->stride[1] = info->stride[0]; |
1031 | 0 | info->offset[0] = 0; |
1032 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
1033 | 0 | cr_h = GST_ROUND_UP_2 (height) / 2; |
1034 | 0 | if (GST_VIDEO_INFO_IS_INTERLACED (info)) |
1035 | 0 | cr_h = GST_ROUND_UP_2 (cr_h); |
1036 | 0 | info->size = info->offset[1] + info->stride[0] * cr_h; |
1037 | 0 | break; |
1038 | 0 | case GST_VIDEO_FORMAT_AV12: |
1039 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
1040 | 0 | info->stride[1] = info->stride[0]; |
1041 | 0 | info->stride[2] = info->stride[0]; |
1042 | 0 | info->offset[0] = 0; |
1043 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
1044 | 0 | info->offset[2] = |
1045 | 0 | info->offset[1] + (info->stride[1] * GST_ROUND_UP_2 (height) / 2); |
1046 | 0 | info->size = info->offset[2] + info->stride[2] * GST_ROUND_UP_2 (height); |
1047 | 0 | break; |
1048 | 0 | case GST_VIDEO_FORMAT_NV16: |
1049 | 0 | case GST_VIDEO_FORMAT_NV61: |
1050 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
1051 | 0 | info->stride[1] = info->stride[0]; |
1052 | 0 | info->offset[0] = 0; |
1053 | 0 | info->offset[1] = info->stride[0] * height; |
1054 | 0 | info->size = info->stride[0] * height * 2; |
1055 | 0 | break; |
1056 | 0 | case GST_VIDEO_FORMAT_NV24: |
1057 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
1058 | 0 | info->stride[1] = GST_ROUND_UP_4 (width * 2); |
1059 | 0 | info->offset[0] = 0; |
1060 | 0 | info->offset[1] = info->stride[0] * height; |
1061 | 0 | info->size = info->stride[0] * height + info->stride[1] * height; |
1062 | 0 | break; |
1063 | 0 | case GST_VIDEO_FORMAT_A420: |
1064 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
1065 | 0 | info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2); |
1066 | 0 | info->stride[2] = info->stride[1]; |
1067 | 0 | info->stride[3] = info->stride[0]; |
1068 | 0 | info->offset[0] = 0; |
1069 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
1070 | 0 | cr_h = GST_ROUND_UP_2 (height) / 2; |
1071 | 0 | if (GST_VIDEO_INFO_IS_INTERLACED (info)) |
1072 | 0 | cr_h = GST_ROUND_UP_2 (cr_h); |
1073 | 0 | info->offset[2] = info->offset[1] + info->stride[1] * cr_h; |
1074 | 0 | info->offset[3] = info->offset[2] + info->stride[2] * cr_h; |
1075 | 0 | info->size = info->offset[3] + info->stride[0] * GST_ROUND_UP_2 (height); |
1076 | 0 | break; |
1077 | 0 | case GST_VIDEO_FORMAT_A422: |
1078 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
1079 | 0 | info->stride[1] = GST_ROUND_UP_8 (width) / 2; |
1080 | 0 | info->stride[2] = info->stride[1]; |
1081 | 0 | info->stride[3] = info->stride[0]; |
1082 | 0 | info->offset[0] = 0; |
1083 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
1084 | 0 | info->offset[2] = info->offset[1] + |
1085 | 0 | info->stride[1] * GST_ROUND_UP_2 (height); |
1086 | 0 | info->offset[3] = |
1087 | 0 | info->offset[2] + info->stride[2] * GST_ROUND_UP_2 (height); |
1088 | 0 | info->size = info->offset[3] + info->stride[0] * GST_ROUND_UP_2 (height); |
1089 | 0 | break; |
1090 | 0 | case GST_VIDEO_FORMAT_A444: |
1091 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
1092 | 0 | info->stride[1] = info->stride[0]; |
1093 | 0 | info->stride[2] = info->stride[0]; |
1094 | 0 | info->stride[3] = info->stride[0]; |
1095 | 0 | info->offset[0] = 0; |
1096 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
1097 | 0 | info->offset[2] = info->offset[1] + |
1098 | 0 | info->stride[1] * GST_ROUND_UP_2 (height); |
1099 | 0 | info->offset[3] = |
1100 | 0 | info->offset[2] + info->stride[2] * GST_ROUND_UP_2 (height); |
1101 | 0 | info->size = info->offset[3] + info->stride[0] * GST_ROUND_UP_2 (height); |
1102 | 0 | break; |
1103 | 0 | case GST_VIDEO_FORMAT_YUV9: |
1104 | 0 | case GST_VIDEO_FORMAT_YVU9: |
1105 | 0 | info->stride[0] = GST_ROUND_UP_4 (width); |
1106 | 0 | info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) / 4); |
1107 | 0 | info->stride[2] = info->stride[1]; |
1108 | 0 | info->offset[0] = 0; |
1109 | 0 | info->offset[1] = info->stride[0] * height; |
1110 | 0 | cr_h = GST_ROUND_UP_4 (height) / 4; |
1111 | 0 | if (GST_VIDEO_INFO_IS_INTERLACED (info)) |
1112 | 0 | cr_h = GST_ROUND_UP_2 (cr_h); |
1113 | 0 | info->offset[2] = info->offset[1] + info->stride[1] * cr_h; |
1114 | 0 | info->size = info->offset[2] + info->stride[2] * cr_h; |
1115 | 0 | break; |
1116 | 0 | case GST_VIDEO_FORMAT_I420_10LE: |
1117 | 0 | case GST_VIDEO_FORMAT_I420_10BE: |
1118 | 0 | case GST_VIDEO_FORMAT_I420_12LE: |
1119 | 0 | case GST_VIDEO_FORMAT_I420_12BE: |
1120 | 0 | info->stride[0] = GST_ROUND_UP_4 (width * 2); |
1121 | 0 | info->stride[1] = GST_ROUND_UP_4 (width); |
1122 | 0 | info->stride[2] = info->stride[1]; |
1123 | 0 | info->offset[0] = 0; |
1124 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
1125 | 0 | cr_h = GST_ROUND_UP_2 (height) / 2; |
1126 | 0 | if (GST_VIDEO_INFO_IS_INTERLACED (info)) |
1127 | 0 | cr_h = GST_ROUND_UP_2 (cr_h); |
1128 | 0 | info->offset[2] = info->offset[1] + info->stride[1] * cr_h; |
1129 | 0 | info->size = info->offset[2] + info->stride[2] * cr_h; |
1130 | 0 | break; |
1131 | 0 | case GST_VIDEO_FORMAT_I422_10LE: |
1132 | 0 | case GST_VIDEO_FORMAT_I422_10BE: |
1133 | 0 | case GST_VIDEO_FORMAT_I422_12LE: |
1134 | 0 | case GST_VIDEO_FORMAT_I422_12BE: |
1135 | 0 | info->stride[0] = GST_ROUND_UP_4 (width * 2); |
1136 | 0 | info->stride[1] = GST_ROUND_UP_4 (width); |
1137 | 0 | info->stride[2] = info->stride[1]; |
1138 | 0 | info->offset[0] = 0; |
1139 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
1140 | 0 | info->offset[2] = info->offset[1] + |
1141 | 0 | info->stride[1] * GST_ROUND_UP_2 (height); |
1142 | 0 | info->size = info->offset[2] + info->stride[2] * GST_ROUND_UP_2 (height); |
1143 | 0 | break; |
1144 | 0 | case GST_VIDEO_FORMAT_Y444_10LE: |
1145 | 0 | case GST_VIDEO_FORMAT_Y444_10BE: |
1146 | 0 | case GST_VIDEO_FORMAT_Y444_12LE: |
1147 | 0 | case GST_VIDEO_FORMAT_Y444_12BE: |
1148 | 0 | case GST_VIDEO_FORMAT_GBR_10LE: |
1149 | 0 | case GST_VIDEO_FORMAT_GBR_10BE: |
1150 | 0 | case GST_VIDEO_FORMAT_GBR_12LE: |
1151 | 0 | case GST_VIDEO_FORMAT_GBR_12BE: |
1152 | 0 | case GST_VIDEO_FORMAT_GBR_16LE: |
1153 | 0 | case GST_VIDEO_FORMAT_GBR_16BE: |
1154 | 0 | case GST_VIDEO_FORMAT_Y444_16LE: |
1155 | 0 | case GST_VIDEO_FORMAT_Y444_16BE: |
1156 | 0 | info->stride[0] = GST_ROUND_UP_4 (width * 2); |
1157 | 0 | info->stride[1] = info->stride[0]; |
1158 | 0 | info->stride[2] = info->stride[0]; |
1159 | 0 | info->offset[0] = 0; |
1160 | 0 | info->offset[1] = info->stride[0] * height; |
1161 | 0 | info->offset[2] = info->offset[1] * 2; |
1162 | 0 | info->size = info->stride[0] * height * 3; |
1163 | 0 | break; |
1164 | 0 | case GST_VIDEO_FORMAT_GBRA_10LE: |
1165 | 0 | case GST_VIDEO_FORMAT_GBRA_10BE: |
1166 | 0 | case GST_VIDEO_FORMAT_GBRA_12LE: |
1167 | 0 | case GST_VIDEO_FORMAT_GBRA_12BE: |
1168 | 0 | info->stride[0] = GST_ROUND_UP_4 (width * 2); |
1169 | 0 | info->stride[1] = info->stride[0]; |
1170 | 0 | info->stride[2] = info->stride[0]; |
1171 | 0 | info->stride[3] = info->stride[0]; |
1172 | 0 | info->offset[0] = 0; |
1173 | 0 | info->offset[1] = info->stride[0] * height; |
1174 | 0 | info->offset[2] = info->offset[1] * 2; |
1175 | 0 | info->offset[3] = info->offset[1] * 3; |
1176 | 0 | info->size = info->stride[0] * height * 4; |
1177 | 0 | break; |
1178 | 0 | case GST_VIDEO_FORMAT_NV12_64Z32: |
1179 | 0 | info->stride[0] = |
1180 | 0 | GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_128 (width) / 64, |
1181 | 0 | GST_ROUND_UP_32 (height) / 32); |
1182 | 0 | info->stride[1] = |
1183 | 0 | GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_128 (width) / 64, |
1184 | 0 | GST_ROUND_UP_64 (height) / 64); |
1185 | 0 | info->offset[0] = 0; |
1186 | 0 | info->offset[1] = GST_ROUND_UP_128 (width) * GST_ROUND_UP_32 (height); |
1187 | 0 | info->size = info->offset[1] + |
1188 | 0 | GST_ROUND_UP_128 (width) * (GST_ROUND_UP_64 (height) / 2); |
1189 | 0 | break; |
1190 | 0 | case GST_VIDEO_FORMAT_NV12_4L4: |
1191 | 0 | case GST_VIDEO_FORMAT_NV12_32L32: |
1192 | 0 | case GST_VIDEO_FORMAT_NV12_10LE40_4L4: |
1193 | 0 | { |
1194 | 0 | const gsize tile_size = GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, 0); |
1195 | 0 | gint tile_width = GST_VIDEO_FORMAT_INFO_TILE_WIDTH (info->finfo, 0); |
1196 | 0 | gint tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (info->finfo, 0); |
1197 | 0 | gint n_tile_x = GST_ROUND_UP_N (info->width, tile_width) / tile_width; |
1198 | 0 | gint n_tile_y = GST_ROUND_UP_N (info->height, tile_height) / tile_height; |
1199 | |
|
1200 | 0 | info->stride[0] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, n_tile_y); |
1201 | 0 | info->stride[1] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, |
1202 | 0 | GST_ROUND_UP_2 (n_tile_y) / 2); |
1203 | 0 | info->offset[1] = n_tile_x * n_tile_y * tile_size; |
1204 | 0 | info->size = info->offset[1] + |
1205 | 0 | n_tile_x * GST_ROUND_UP_2 (n_tile_y) / 2 * tile_size; |
1206 | 0 | break; |
1207 | 0 | } |
1208 | 0 | case GST_VIDEO_FORMAT_NV12_16L32S: |
1209 | 0 | { |
1210 | 0 | const gsize y_tile_size = |
1211 | 0 | GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, 0); |
1212 | 0 | const gsize uv_tile_size = |
1213 | 0 | GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, 1); |
1214 | 0 | gint tile_width = GST_VIDEO_FORMAT_INFO_TILE_WIDTH (info->finfo, 0); |
1215 | 0 | gint tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (info->finfo, 0); |
1216 | 0 | gint n_tile_x = GST_ROUND_UP_N (info->width, tile_width) / tile_width; |
1217 | 0 | gint n_tile_y = GST_ROUND_UP_N (info->height, tile_height) / tile_height; |
1218 | |
|
1219 | 0 | info->stride[0] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, n_tile_y); |
1220 | | /* |
1221 | | * size of UV plane tiles is subsample, hence have the same number of |
1222 | | * tiles in both directions. |
1223 | | */ |
1224 | 0 | info->stride[1] = info->stride[0]; |
1225 | 0 | info->offset[0] = 0; |
1226 | 0 | info->offset[1] = n_tile_x * n_tile_y * y_tile_size; |
1227 | 0 | info->size = info->offset[1] + n_tile_x * n_tile_y * uv_tile_size; |
1228 | 0 | break; |
1229 | 0 | } |
1230 | 0 | case GST_VIDEO_FORMAT_A420_10LE: |
1231 | 0 | case GST_VIDEO_FORMAT_A420_10BE: |
1232 | 0 | case GST_VIDEO_FORMAT_A420_12LE: |
1233 | 0 | case GST_VIDEO_FORMAT_A420_12BE: |
1234 | 0 | case GST_VIDEO_FORMAT_A420_16LE: |
1235 | 0 | case GST_VIDEO_FORMAT_A420_16BE: |
1236 | 0 | info->stride[0] = GST_ROUND_UP_4 (width * 2); |
1237 | 0 | info->stride[1] = GST_ROUND_UP_4 (width); |
1238 | 0 | info->stride[2] = info->stride[1]; |
1239 | 0 | info->stride[3] = info->stride[0]; |
1240 | 0 | info->offset[0] = 0; |
1241 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
1242 | 0 | cr_h = GST_ROUND_UP_2 (height) / 2; |
1243 | 0 | if (GST_VIDEO_INFO_IS_INTERLACED (info)) |
1244 | 0 | cr_h = GST_ROUND_UP_2 (cr_h); |
1245 | 0 | info->offset[2] = info->offset[1] + info->stride[1] * cr_h; |
1246 | 0 | info->offset[3] = info->offset[2] + info->stride[2] * cr_h; |
1247 | 0 | info->size = info->offset[3] + info->stride[0] * GST_ROUND_UP_2 (height); |
1248 | 0 | break; |
1249 | 0 | case GST_VIDEO_FORMAT_A422_10LE: |
1250 | 0 | case GST_VIDEO_FORMAT_A422_10BE: |
1251 | 0 | case GST_VIDEO_FORMAT_A422_12LE: |
1252 | 0 | case GST_VIDEO_FORMAT_A422_12BE: |
1253 | 0 | case GST_VIDEO_FORMAT_A422_16LE: |
1254 | 0 | case GST_VIDEO_FORMAT_A422_16BE: |
1255 | 0 | info->stride[0] = GST_ROUND_UP_4 (width * 2); |
1256 | 0 | info->stride[1] = GST_ROUND_UP_4 (width); |
1257 | 0 | info->stride[2] = info->stride[1]; |
1258 | 0 | info->stride[3] = info->stride[0]; |
1259 | 0 | info->offset[0] = 0; |
1260 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
1261 | 0 | info->offset[2] = info->offset[1] + |
1262 | 0 | info->stride[1] * GST_ROUND_UP_2 (height); |
1263 | 0 | info->offset[3] = |
1264 | 0 | info->offset[2] + info->stride[2] * GST_ROUND_UP_2 (height); |
1265 | 0 | info->size = info->offset[3] + info->stride[0] * GST_ROUND_UP_2 (height); |
1266 | 0 | break; |
1267 | 0 | case GST_VIDEO_FORMAT_A444_10LE: |
1268 | 0 | case GST_VIDEO_FORMAT_A444_10BE: |
1269 | 0 | case GST_VIDEO_FORMAT_A444_12LE: |
1270 | 0 | case GST_VIDEO_FORMAT_A444_12BE: |
1271 | 0 | case GST_VIDEO_FORMAT_A444_16LE: |
1272 | 0 | case GST_VIDEO_FORMAT_A444_16BE: |
1273 | 0 | info->stride[0] = GST_ROUND_UP_4 (width * 2); |
1274 | 0 | info->stride[1] = info->stride[0]; |
1275 | 0 | info->stride[2] = info->stride[0]; |
1276 | 0 | info->stride[3] = info->stride[0]; |
1277 | 0 | info->offset[0] = 0; |
1278 | 0 | info->offset[1] = info->stride[0] * height; |
1279 | 0 | info->offset[2] = info->offset[1] * 2; |
1280 | 0 | info->offset[3] = info->offset[1] * 3; |
1281 | 0 | info->size = info->stride[0] * height * 4; |
1282 | 0 | break; |
1283 | 0 | case GST_VIDEO_FORMAT_P010_10LE: |
1284 | 0 | case GST_VIDEO_FORMAT_P010_10BE: |
1285 | 0 | case GST_VIDEO_FORMAT_P016_LE: |
1286 | 0 | case GST_VIDEO_FORMAT_P016_BE: |
1287 | 0 | case GST_VIDEO_FORMAT_P012_LE: |
1288 | 0 | case GST_VIDEO_FORMAT_P012_BE: |
1289 | 0 | info->stride[0] = GST_ROUND_UP_4 (width * 2); |
1290 | 0 | info->stride[1] = info->stride[0]; |
1291 | 0 | info->offset[0] = 0; |
1292 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
1293 | 0 | cr_h = GST_ROUND_UP_2 (height) / 2; |
1294 | 0 | info->size = info->offset[1] + info->stride[0] * cr_h; |
1295 | 0 | break; |
1296 | 0 | case GST_VIDEO_FORMAT_GRAY10_LE16: |
1297 | 0 | info->stride[0] = GST_ROUND_UP_4 (width * 2); |
1298 | 0 | info->offset[0] = 0; |
1299 | 0 | info->size = info->stride[0] * height; |
1300 | 0 | break; |
1301 | 0 | case GST_VIDEO_FORMAT_GRAY10_LE32: |
1302 | 0 | info->stride[0] = (width + 2) / 3 * 4; |
1303 | 0 | info->offset[0] = 0; |
1304 | 0 | info->size = info->stride[0] * GST_ROUND_UP_2 (height); |
1305 | 0 | break; |
1306 | 0 | case GST_VIDEO_FORMAT_NV12_10LE32: |
1307 | 0 | info->stride[0] = (width + 2) / 3 * 4; |
1308 | 0 | info->stride[1] = info->stride[0]; |
1309 | 0 | info->offset[0] = 0; |
1310 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
1311 | 0 | cr_h = GST_ROUND_UP_2 (height) / 2; |
1312 | 0 | if (GST_VIDEO_INFO_IS_INTERLACED (info)) |
1313 | 0 | cr_h = GST_ROUND_UP_2 (cr_h); |
1314 | 0 | info->size = info->offset[1] + info->stride[0] * cr_h; |
1315 | 0 | break; |
1316 | 0 | case GST_VIDEO_FORMAT_NV16_10LE32: |
1317 | 0 | info->stride[0] = (width + 2) / 3 * 4; |
1318 | 0 | info->stride[1] = info->stride[0]; |
1319 | 0 | info->offset[0] = 0; |
1320 | 0 | info->offset[1] = info->stride[0] * height; |
1321 | 0 | info->size = info->stride[0] * height * 2; |
1322 | 0 | break; |
1323 | 0 | case GST_VIDEO_FORMAT_NV16_10LE40: |
1324 | 0 | info->stride[0] = ((width * 5 >> 2) + 4) / 5 * 5; |
1325 | 0 | info->stride[1] = info->stride[0]; |
1326 | 0 | info->offset[0] = 0; |
1327 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
1328 | 0 | info->size = info->offset[1] * 2; |
1329 | 0 | break; |
1330 | 0 | case GST_VIDEO_FORMAT_NV12_10LE40: |
1331 | 0 | info->stride[0] = ((width * 5 >> 2) + 4) / 5 * 5; |
1332 | 0 | info->stride[1] = info->stride[0]; |
1333 | 0 | info->offset[0] = 0; |
1334 | 0 | info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height); |
1335 | 0 | cr_h = GST_ROUND_UP_2 (height) / 2; |
1336 | 0 | if (GST_VIDEO_INFO_IS_INTERLACED (info)) |
1337 | 0 | cr_h = GST_ROUND_UP_2 (cr_h); |
1338 | 0 | info->size = info->offset[1] + info->stride[0] * cr_h; |
1339 | 0 | break; |
1340 | 0 | case GST_VIDEO_FORMAT_NV12_8L128: |
1341 | 0 | { |
1342 | 0 | gint tile_size = GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, 0); |
1343 | 0 | gint tile_width = GST_VIDEO_FORMAT_INFO_TILE_WIDTH (info->finfo, 0); |
1344 | 0 | gint tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (info->finfo, 0); |
1345 | 0 | gint ALIGN_W = tile_width; |
1346 | 0 | gint ALIGN_H = tile_height; |
1347 | 0 | guint n_tile_x, y_n_tile_y, uv_n_tile_y; |
1348 | |
|
1349 | 0 | if (GST_VIDEO_INFO_IS_INTERLACED (info)) |
1350 | 0 | ALIGN_H *= 2; |
1351 | |
|
1352 | 0 | n_tile_x = GST_ROUND_UP_N (width, ALIGN_W) / tile_width; |
1353 | 0 | y_n_tile_y = GST_ROUND_UP_N (height, ALIGN_H) / tile_height; |
1354 | 0 | uv_n_tile_y = GST_ROUND_UP_2 (y_n_tile_y) / 2; |
1355 | |
|
1356 | 0 | info->stride[0] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, y_n_tile_y); |
1357 | 0 | info->stride[1] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, uv_n_tile_y); |
1358 | 0 | info->offset[0] = 0; |
1359 | 0 | info->offset[1] = n_tile_x * y_n_tile_y * tile_size; |
1360 | 0 | info->size = info->offset[1] + n_tile_x * uv_n_tile_y * tile_size; |
1361 | 0 | break; |
1362 | 0 | } |
1363 | 0 | case GST_VIDEO_FORMAT_NV12_10BE_8L128: |
1364 | 0 | { |
1365 | 0 | gint tile_size = GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, 0); |
1366 | 0 | gint tile_stride = GST_VIDEO_FORMAT_INFO_TILE_STRIDE (info->finfo, 0); |
1367 | 0 | gint tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (info->finfo, 0); |
1368 | 0 | gint stride = GST_ROUND_UP_8 (width * 10) >> 3; |
1369 | 0 | gint ALIGN_W = tile_stride; |
1370 | 0 | gint ALIGN_H = tile_height; |
1371 | 0 | guint n_tile_x, y_n_tile_y, uv_n_tile_y; |
1372 | |
|
1373 | 0 | if (GST_VIDEO_INFO_IS_INTERLACED (info)) |
1374 | 0 | ALIGN_H *= 2; |
1375 | |
|
1376 | 0 | n_tile_x = GST_ROUND_UP_N (stride, ALIGN_W) / tile_stride; |
1377 | 0 | y_n_tile_y = GST_ROUND_UP_N (height, ALIGN_H) / tile_height; |
1378 | 0 | uv_n_tile_y = GST_ROUND_UP_2 (y_n_tile_y) / 2; |
1379 | |
|
1380 | 0 | info->stride[0] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, y_n_tile_y); |
1381 | 0 | info->stride[1] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, uv_n_tile_y); |
1382 | 0 | info->offset[0] = 0; |
1383 | 0 | info->offset[1] = n_tile_x * y_n_tile_y * tile_size; |
1384 | 0 | info->size = info->offset[1] + n_tile_x * uv_n_tile_y * tile_size; |
1385 | 0 | break; |
1386 | 0 | } |
1387 | 0 | case GST_VIDEO_FORMAT_MT2110T: |
1388 | 0 | case GST_VIDEO_FORMAT_MT2110R: |
1389 | 0 | { |
1390 | 0 | const gsize tile_size = GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, 0); |
1391 | 0 | gint n_tile_x = GST_ROUND_UP_16 (info->width) / 16; |
1392 | 0 | gint n_tile_y = GST_ROUND_UP_32 (info->height) / 32; |
1393 | |
|
1394 | 0 | info->stride[0] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, n_tile_y); |
1395 | 0 | info->stride[1] = info->stride[0]; |
1396 | 0 | info->offset[0] = 0; |
1397 | 0 | info->offset[1] = tile_size * n_tile_x * n_tile_y; |
1398 | 0 | info->size = info->offset[1] + info->offset[1] / 2; |
1399 | 0 | break; |
1400 | 0 | } |
1401 | 3 | case GST_VIDEO_FORMAT_ENCODED: |
1402 | 3 | case GST_VIDEO_FORMAT_DMA_DRM: |
1403 | 3 | break; |
1404 | 0 | case GST_VIDEO_FORMAT_UNKNOWN: |
1405 | 0 | GST_ERROR ("invalid format"); |
1406 | 0 | g_warning ("invalid format"); |
1407 | 0 | return FALSE; |
1408 | 0 | break; |
1409 | 3 | } |
1410 | | |
1411 | 3 | if (plane_size) { |
1412 | 0 | for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) { |
1413 | 0 | if (i < GST_VIDEO_INFO_N_PLANES (info)) { |
1414 | 0 | if (GST_VIDEO_FORMAT_INFO_IS_TILED (info->finfo)) { |
1415 | 0 | guint x_tiles = GST_VIDEO_TILE_X_TILES (info->stride[i]); |
1416 | 0 | guint y_tiles = GST_VIDEO_TILE_Y_TILES (info->stride[i]); |
1417 | 0 | plane_size[i] = x_tiles * y_tiles * |
1418 | 0 | GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, i); |
1419 | 0 | } else { |
1420 | 0 | gint comp[GST_VIDEO_MAX_COMPONENTS]; |
1421 | 0 | guint plane_height; |
1422 | | |
1423 | | /* Convert plane index to component index */ |
1424 | 0 | gst_video_format_info_component (info->finfo, i, comp); |
1425 | 0 | plane_height = |
1426 | 0 | GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, comp[0], |
1427 | 0 | GST_VIDEO_INFO_FIELD_HEIGHT (info)); |
1428 | 0 | plane_size[i] = plane_height * GST_VIDEO_INFO_PLANE_STRIDE (info, i); |
1429 | 0 | } |
1430 | 0 | } else { |
1431 | 0 | plane_size[i] = 0; |
1432 | 0 | } |
1433 | 0 | } |
1434 | 0 | } |
1435 | | |
1436 | 3 | return TRUE; |
1437 | 3 | } |
1438 | | |
1439 | | /** |
1440 | | * gst_video_info_convert: |
1441 | | * @info: a #GstVideoInfo |
1442 | | * @src_format: #GstFormat of the @src_value |
1443 | | * @src_value: value to convert |
1444 | | * @dest_format: #GstFormat of the @dest_value |
1445 | | * @dest_value: (out): pointer to destination value |
1446 | | * |
1447 | | * Converts among various #GstFormat types. This function handles |
1448 | | * GST_FORMAT_BYTES, GST_FORMAT_TIME, and GST_FORMAT_DEFAULT. For |
1449 | | * raw video, GST_FORMAT_DEFAULT corresponds to video frames. This |
1450 | | * function can be used to handle pad queries of the type GST_QUERY_CONVERT. |
1451 | | * |
1452 | | * Returns: TRUE if the conversion was successful. |
1453 | | */ |
1454 | | gboolean |
1455 | | gst_video_info_convert (const GstVideoInfo * info, |
1456 | | GstFormat src_format, gint64 src_value, |
1457 | | GstFormat dest_format, gint64 * dest_value) |
1458 | 0 | { |
1459 | 0 | gboolean ret = FALSE; |
1460 | 0 | int fps_n, fps_d; |
1461 | 0 | gsize size; |
1462 | |
|
1463 | 0 | g_return_val_if_fail (info != NULL, 0); |
1464 | 0 | g_return_val_if_fail (info->finfo != NULL, 0); |
1465 | 0 | g_return_val_if_fail (info->finfo->format != GST_VIDEO_FORMAT_UNKNOWN, 0); |
1466 | 0 | g_return_val_if_fail (info->size > 0, 0); |
1467 | | |
1468 | 0 | size = info->size; |
1469 | 0 | fps_n = info->fps_n; |
1470 | 0 | fps_d = info->fps_d; |
1471 | |
|
1472 | 0 | GST_DEBUG ("converting value %" G_GINT64_FORMAT " from %s to %s", |
1473 | 0 | src_value, gst_format_get_name (src_format), |
1474 | 0 | gst_format_get_name (dest_format)); |
1475 | |
|
1476 | 0 | if (src_format == dest_format) { |
1477 | 0 | *dest_value = src_value; |
1478 | 0 | ret = TRUE; |
1479 | 0 | goto done; |
1480 | 0 | } |
1481 | | |
1482 | 0 | if (src_value == -1) { |
1483 | 0 | *dest_value = -1; |
1484 | 0 | ret = TRUE; |
1485 | 0 | goto done; |
1486 | 0 | } |
1487 | | |
1488 | | /* bytes to frames */ |
1489 | 0 | if (src_format == GST_FORMAT_BYTES && dest_format == GST_FORMAT_DEFAULT) { |
1490 | 0 | if (size != 0) { |
1491 | 0 | *dest_value = gst_util_uint64_scale (src_value, 1, size); |
1492 | 0 | } else { |
1493 | 0 | GST_ERROR ("blocksize is 0"); |
1494 | 0 | *dest_value = 0; |
1495 | 0 | } |
1496 | 0 | ret = TRUE; |
1497 | 0 | goto done; |
1498 | 0 | } |
1499 | | |
1500 | | /* frames to bytes */ |
1501 | 0 | if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_BYTES) { |
1502 | 0 | *dest_value = gst_util_uint64_scale (src_value, size, 1); |
1503 | 0 | ret = TRUE; |
1504 | 0 | goto done; |
1505 | 0 | } |
1506 | | |
1507 | | /* time to frames */ |
1508 | 0 | if (src_format == GST_FORMAT_TIME && dest_format == GST_FORMAT_DEFAULT) { |
1509 | 0 | if (fps_d != 0) { |
1510 | 0 | *dest_value = gst_util_uint64_scale (src_value, |
1511 | 0 | fps_n, GST_SECOND * fps_d); |
1512 | 0 | } else { |
1513 | 0 | GST_ERROR ("framerate denominator is 0"); |
1514 | 0 | *dest_value = 0; |
1515 | 0 | } |
1516 | 0 | ret = TRUE; |
1517 | 0 | goto done; |
1518 | 0 | } |
1519 | | |
1520 | | /* frames to time */ |
1521 | 0 | if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_TIME) { |
1522 | 0 | if (fps_n != 0) { |
1523 | 0 | *dest_value = gst_util_uint64_scale (src_value, |
1524 | 0 | GST_SECOND * fps_d, fps_n); |
1525 | 0 | } else { |
1526 | 0 | GST_ERROR ("framerate numerator is 0"); |
1527 | 0 | *dest_value = 0; |
1528 | 0 | } |
1529 | 0 | ret = TRUE; |
1530 | 0 | goto done; |
1531 | 0 | } |
1532 | | |
1533 | | /* time to bytes */ |
1534 | 0 | if (src_format == GST_FORMAT_TIME && dest_format == GST_FORMAT_BYTES) { |
1535 | 0 | if (fps_d != 0) { |
1536 | 0 | *dest_value = gst_util_uint64_scale (src_value, |
1537 | 0 | fps_n * size, GST_SECOND * fps_d); |
1538 | 0 | } else { |
1539 | 0 | GST_ERROR ("framerate denominator is 0"); |
1540 | 0 | *dest_value = 0; |
1541 | 0 | } |
1542 | 0 | ret = TRUE; |
1543 | 0 | goto done; |
1544 | 0 | } |
1545 | | |
1546 | | /* bytes to time */ |
1547 | 0 | if (src_format == GST_FORMAT_BYTES && dest_format == GST_FORMAT_TIME) { |
1548 | 0 | if (fps_n != 0 && size != 0) { |
1549 | 0 | *dest_value = gst_util_uint64_scale (src_value, |
1550 | 0 | GST_SECOND * fps_d, fps_n * size); |
1551 | 0 | } else { |
1552 | 0 | GST_ERROR ("framerate denominator and/or blocksize is 0"); |
1553 | 0 | *dest_value = 0; |
1554 | 0 | } |
1555 | 0 | ret = TRUE; |
1556 | 0 | } |
1557 | |
|
1558 | 0 | done: |
1559 | |
|
1560 | 0 | GST_DEBUG ("ret=%d result %" G_GINT64_FORMAT, ret, *dest_value); |
1561 | |
|
1562 | 0 | return ret; |
1563 | 0 | } |
1564 | | |
1565 | | /** |
1566 | | * gst_video_info_align_full: |
1567 | | * @info: a #GstVideoInfo |
1568 | | * @align: alignment parameters |
1569 | | * @plane_size: (out) (optional): array used to store the plane sizes |
1570 | | * |
1571 | | * Extra padding will be added to the right side when stride alignment padding |
1572 | | * is required and @align will be updated with the new padding values. |
1573 | | * |
1574 | | * This variant of gst_video_info_align() provides the updated size, in bytes, |
1575 | | * of each video plane after the alignment, including all horizontal and vertical |
1576 | | * paddings. |
1577 | | * |
1578 | | * In case of GST_VIDEO_INTERLACE_MODE_ALTERNATE info, the returned sizes are the |
1579 | | * ones used to hold a single field, not the full frame. |
1580 | | * |
1581 | | * Returns: %FALSE if alignment could not be applied, e.g. because the |
1582 | | * size of a frame can't be represented as a 32 bit integer |
1583 | | * |
1584 | | * Since: 1.18 |
1585 | | */ |
1586 | | gboolean |
1587 | | gst_video_info_align_full (GstVideoInfo * info, GstVideoAlignment * align, |
1588 | | gsize plane_size[GST_VIDEO_MAX_PLANES]) |
1589 | 0 | { |
1590 | 0 | const GstVideoFormatInfo *vinfo = info->finfo; |
1591 | 0 | gint width, height; |
1592 | 0 | gint padded_width, padded_height; |
1593 | 0 | gint i, n_planes; |
1594 | 0 | gboolean aligned; |
1595 | |
|
1596 | 0 | width = GST_VIDEO_INFO_WIDTH (info); |
1597 | 0 | height = GST_VIDEO_INFO_HEIGHT (info); |
1598 | |
|
1599 | 0 | GST_LOG ("padding %u-%ux%u-%u", align->padding_top, |
1600 | 0 | align->padding_left, align->padding_right, align->padding_bottom); |
1601 | |
|
1602 | 0 | n_planes = GST_VIDEO_INFO_N_PLANES (info); |
1603 | |
|
1604 | 0 | if (GST_VIDEO_FORMAT_INFO_HAS_PALETTE (vinfo)) |
1605 | 0 | n_planes--; |
1606 | | |
1607 | | /* first make sure the left padding does not cause alignment problems later */ |
1608 | 0 | do { |
1609 | 0 | GST_LOG ("left padding %u", align->padding_left); |
1610 | 0 | aligned = TRUE; |
1611 | 0 | for (i = 0; i < n_planes; i++) { |
1612 | 0 | gint comp[GST_VIDEO_MAX_COMPONENTS]; |
1613 | 0 | gint hedge; |
1614 | | |
1615 | | /* this is the amount of pixels to add as left padding */ |
1616 | 0 | gst_video_format_info_component (vinfo, i, comp); |
1617 | 0 | hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, comp[0], |
1618 | 0 | align->padding_left); |
1619 | 0 | hedge *= GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, comp[0]); |
1620 | |
|
1621 | 0 | GST_LOG ("plane %d, padding %d, alignment %u", i, hedge, |
1622 | 0 | align->stride_align[i]); |
1623 | 0 | aligned &= (hedge & align->stride_align[i]) == 0; |
1624 | 0 | } |
1625 | 0 | if (aligned) |
1626 | 0 | break; |
1627 | | |
1628 | 0 | GST_LOG ("unaligned padding, increasing padding"); |
1629 | | /* increase padded_width */ |
1630 | 0 | align->padding_left += align->padding_left & ~(align->padding_left - 1); |
1631 | 0 | } while (!aligned); |
1632 | | |
1633 | | /* add the padding */ |
1634 | 0 | padded_width = width + align->padding_left + align->padding_right; |
1635 | 0 | padded_height = height + align->padding_top + align->padding_bottom; |
1636 | |
|
1637 | 0 | do { |
1638 | 0 | GST_LOG ("padded dimension %u-%u", padded_width, padded_height); |
1639 | |
|
1640 | 0 | info->width = padded_width; |
1641 | 0 | info->height = padded_height; |
1642 | |
|
1643 | 0 | if (!fill_planes (info, plane_size)) |
1644 | 0 | return FALSE; |
1645 | | |
1646 | | /* check alignment */ |
1647 | 0 | aligned = TRUE; |
1648 | 0 | for (i = 0; i < n_planes; i++) { |
1649 | 0 | GST_LOG ("plane %d, stride %d, alignment %u", i, info->stride[i], |
1650 | 0 | align->stride_align[i]); |
1651 | 0 | aligned &= (info->stride[i] & align->stride_align[i]) == 0; |
1652 | 0 | } |
1653 | 0 | if (aligned) |
1654 | 0 | break; |
1655 | | |
1656 | 0 | GST_LOG ("unaligned strides, increasing dimension"); |
1657 | | /* increase padded_width */ |
1658 | 0 | padded_width += padded_width & ~(padded_width - 1); |
1659 | 0 | } while (!aligned); |
1660 | | |
1661 | 0 | align->padding_right = padded_width - width - align->padding_left; |
1662 | |
|
1663 | 0 | info->width = width; |
1664 | 0 | info->height = height; |
1665 | |
|
1666 | 0 | for (i = 0; i < n_planes; i++) { |
1667 | 0 | gint comp[GST_VIDEO_MAX_COMPONENTS]; |
1668 | 0 | gint vedge, hedge; |
1669 | |
|
1670 | 0 | gst_video_format_info_component (info->finfo, i, comp); |
1671 | 0 | hedge = |
1672 | 0 | GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, comp[0], align->padding_left); |
1673 | 0 | vedge = |
1674 | 0 | GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (vinfo, comp[0], align->padding_top); |
1675 | |
|
1676 | 0 | GST_DEBUG ("plane %d: comp: %d, hedge %d vedge %d align %d stride %d", i, |
1677 | 0 | comp[0], hedge, vedge, align->stride_align[i], info->stride[i]); |
1678 | |
|
1679 | 0 | info->offset[i] += (vedge * info->stride[i]) + |
1680 | 0 | (hedge * GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, comp[0])); |
1681 | 0 | } |
1682 | |
|
1683 | 0 | return TRUE; |
1684 | 0 | } |
1685 | | |
1686 | | /** |
1687 | | * gst_video_info_align: |
1688 | | * @info: a #GstVideoInfo |
1689 | | * @align: alignment parameters |
1690 | | * |
1691 | | * Adjust the offset and stride fields in @info so that the padding and |
1692 | | * stride alignment in @align is respected. |
1693 | | * |
1694 | | * Extra padding will be added to the right side when stride alignment padding |
1695 | | * is required and @align will be updated with the new padding values. |
1696 | | * |
1697 | | * Returns: %FALSE if alignment could not be applied, e.g. because the |
1698 | | * size of a frame can't be represented as a 32 bit integer (Since: 1.12) |
1699 | | */ |
1700 | | gboolean |
1701 | | gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align) |
1702 | 0 | { |
1703 | | return gst_video_info_align_full (info, align, NULL); |
1704 | 0 | } |