* Boston, MA 02110-1301, USA.
*/
+/**
+ * SECTION:video-info
+ * @title: GstVideoInfo
+ * @short_description: Structures and enumerations to describe raw images
+ */
+
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
return info;
}
-static int fill_planes (GstVideoInfo * info);
+static gboolean fill_planes (GstVideoInfo * info,
+ gsize plane_size[GST_VIDEO_MAX_PLANES]);
/**
* gst_video_info_init:
- * @info: a #GstVideoInfo
+ * @info: (out caller-allocates): a #GstVideoInfo
*
* Initialize @info with default values.
*/
info->par_n = 1;
info->par_d = 1;
GST_VIDEO_INFO_MULTIVIEW_MODE (info) = GST_VIDEO_MULTIVIEW_MODE_NONE;
+ GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
+ GST_VIDEO_INFO_FIELD_ORDER (info) = GST_VIDEO_FIELD_ORDER_UNKNOWN;
}
#define MAKE_COLORIMETRY(r,m,t,p) { \
#define DEFAULT_YUV_UHD 5
static const GstVideoColorimetry default_color[] = {
- MAKE_COLORIMETRY (_16_235, BT601, BT709, SMPTE170M),
+ MAKE_COLORIMETRY (_16_235, BT601, BT601, SMPTE170M),
MAKE_COLORIMETRY (_16_235, BT709, BT709, BT709),
MAKE_COLORIMETRY (_0_255, RGB, SRGB, BT709),
MAKE_COLORIMETRY (_0_255, BT601, UNKNOWN, UNKNOWN),
const GstVideoFormatInfo *finfo = info->finfo;
if (!GST_VIDEO_FORMAT_INFO_IS_RGB (finfo) &&
- info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_RGB)
+ info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_RGB) {
+ GST_WARNING
+ ("color matrix RGB is only supported with RGB format, %s is not",
+ finfo->name);
return FALSE;
+ }
if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo) &&
- info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_UNKNOWN)
+ info->colorimetry.matrix == GST_VIDEO_COLOR_MATRIX_UNKNOWN) {
+ GST_WARNING ("Need to specify a color matrix when using YUV format (%s)",
+ finfo->name);
return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+gst_video_info_set_format_common (GstVideoInfo * info, GstVideoFormat format,
+ guint width, guint height)
+{
+ g_return_val_if_fail (info != NULL, FALSE);
+ g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, FALSE);
+
+ if (width > G_MAXINT || height > G_MAXINT)
+ return FALSE;
+
+ gst_video_info_init (info);
+
+ info->finfo = gst_video_format_get_info (format);
+ info->width = width;
+ info->height = height;
+ info->views = 1;
+
+ set_default_colorimetry (info);
return TRUE;
}
* Note: This initializes @info first, no values are preserved. This function
* does not set the offsets correctly for interlaced vertically
* subsampled formats.
+ *
+ * Returns: %FALSE if the returned video info is invalid, e.g. because the
+ * size of a frame can't be represented as a 32 bit integer (Since: 1.12)
*/
-void
+gboolean
gst_video_info_set_format (GstVideoInfo * info, GstVideoFormat format,
guint width, guint height)
{
- g_return_if_fail (info != NULL);
- g_return_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN);
-
- gst_video_info_init (info);
+ if (!gst_video_info_set_format_common (info, format, width, height))
+ return FALSE;
- info->finfo = gst_video_format_get_info (format);
- info->width = width;
- info->height = height;
- info->views = 1;
+ return fill_planes (info, NULL);
+}
- set_default_colorimetry (info);
+/**
+ * gst_video_info_set_interlaced_format:
+ * @info: a #GstVideoInfo
+ * @format: the format
+ * @mode: a #GstVideoInterlaceMode
+ * @width: a width
+ * @height: a height
+ *
+ * Same as #gst_video_info_set_format but also allowing to set the interlaced
+ * mode.
+ *
+ * Returns: %FALSE if the returned video info is invalid, e.g. because the
+ * size of a frame can't be represented as a 32 bit integer.
+ *
+ * Since: 1.16
+ */
+gboolean
+gst_video_info_set_interlaced_format (GstVideoInfo * info,
+ GstVideoFormat format, GstVideoInterlaceMode mode, guint width,
+ guint height)
+{
+ if (!gst_video_info_set_format_common (info, format, width, height))
+ return FALSE;
- fill_planes (info);
+ GST_VIDEO_INFO_INTERLACE_MODE (info) = mode;
+ return fill_planes (info, NULL);
}
static const gchar *interlace_mode[] = {
"progressive",
"interleaved",
"mixed",
- "fields"
+ "fields",
+ "alternate"
};
/**
/**
* gst_video_info_from_caps:
- * @info: a #GstVideoInfo
+ * @info: (out caller-allocates): #GstVideoInfo
* @caps: a #GstCaps
*
* Parse @caps and update @info.
gint width = 0, height = 0;
gint fps_n, fps_d;
gint par_n, par_d;
+ guint multiview_flags;
g_return_val_if_fail (info != NULL, FALSE);
g_return_val_if_fail (caps != NULL, FALSE);
else
info->interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
- if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED &&
+ /* Interlaced feature is mandatory for raw alternate streams */
+ if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE &&
+ format != GST_VIDEO_FORMAT_ENCODED) {
+ GstCapsFeatures *f;
+
+ f = gst_caps_get_features (caps, 0);
+ if (!f
+ || !gst_caps_features_contains (f, GST_CAPS_FEATURE_FORMAT_INTERLACED))
+ goto alternate_no_feature;
+ }
+
+ if (GST_VIDEO_INFO_IS_INTERLACED (info) &&
(s = gst_structure_get_string (structure, "field-order"))) {
GST_VIDEO_INFO_FIELD_ORDER (info) = gst_video_field_order_from_string (s);
} else {
else
GST_VIDEO_INFO_MULTIVIEW_MODE (info) = GST_VIDEO_MULTIVIEW_MODE_NONE;
- gst_structure_get_flagset (structure, "multiview-flags",
- &GST_VIDEO_INFO_MULTIVIEW_FLAGS (info), NULL);
+ if (gst_structure_get_flagset (structure, "multiview-flags",
+ &multiview_flags, NULL))
+ GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) = multiview_flags;
if (!gst_structure_get_int (structure, "views", &info->views))
info->views = 1;
}
if ((s = gst_structure_get_string (structure, "chroma-site")))
- info->chroma_site = gst_video_chroma_from_string (s);
+ info->chroma_site = gst_video_chroma_site_from_string (s);
else
info->chroma_site = GST_VIDEO_CHROMA_SITE_UNKNOWN;
set_default_colorimetry (info);
}
- fill_planes (info);
+ if (!fill_planes (info, NULL))
+ return FALSE;
return TRUE;
GST_ERROR ("no height property given");
return FALSE;
}
+alternate_no_feature:
+ {
+ GST_ERROR
+ ("caps has 'interlace-mode=alternate' but doesn't have the Interlaced feature");
+ return FALSE;
+ }
}
/**
* Returns: a new #GstCaps containing the info of @info.
*/
GstCaps *
-gst_video_info_to_caps (GstVideoInfo * info)
+gst_video_info_to_caps (const GstVideoInfo * info)
{
GstCaps *caps;
const gchar *format;
gst_caps_set_simple (caps, "interlace-mode", G_TYPE_STRING,
gst_video_interlace_mode_to_string (info->interlace_mode), NULL);
- if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED &&
+ if ((info->interlace_mode == GST_VIDEO_INTERLACE_MODE_INTERLEAVED ||
+ info->interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE) &&
GST_VIDEO_INFO_FIELD_ORDER (info) != GST_VIDEO_FIELD_ORDER_UNKNOWN) {
gst_caps_set_simple (caps, "field-order", G_TYPE_STRING,
gst_video_field_order_to_string (GST_VIDEO_INFO_FIELD_ORDER (info)),
NULL);
}
+ if (info->interlace_mode == GST_VIDEO_INTERLACE_MODE_ALTERNATE) {
+ /* 'alternate' mode must always be accompanied by interlaced caps feature.
+ */
+ GstCapsFeatures *features;
+
+ features = gst_caps_features_new (GST_CAPS_FEATURE_FORMAT_INTERLACED, NULL);
+ gst_caps_set_features (caps, 0, features);
+ }
+
if (GST_VIDEO_INFO_MULTIVIEW_MODE (info) != GST_VIDEO_MULTIVIEW_MODE_NONE) {
const gchar *caps_str = NULL;
+ GstVideoMultiviewFlags multiview_flags =
+ GST_VIDEO_INFO_MULTIVIEW_FLAGS (info);
/* If the half-aspect flag is set, applying it into the PAR of the
* resulting caps now seems safe, and helps with automatic behaviour
* in elements that aren't explicitly multiview aware */
- if (GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) &
- GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT) {
- GST_VIDEO_INFO_MULTIVIEW_FLAGS (info) &=
- ~GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
+ if (multiview_flags & GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT) {
+ multiview_flags &= ~GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
switch (GST_VIDEO_INFO_MULTIVIEW_MODE (info)) {
case GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE:
case GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE_QUINCUNX:
if (caps_str != NULL) {
gst_caps_set_simple (caps, "multiview-mode", G_TYPE_STRING,
caps_str, "multiview-flags", GST_TYPE_VIDEO_MULTIVIEW_FLAGSET,
- GST_VIDEO_INFO_MULTIVIEW_FLAGS (info), GST_FLAG_SET_MASK_EXACT, NULL);
+ multiview_flags, GST_FLAG_SET_MASK_EXACT, NULL);
}
}
gst_caps_set_simple (caps, "pixel-aspect-ratio",
GST_TYPE_FRACTION, par_n, par_d, NULL);
- if (info->chroma_site != GST_VIDEO_CHROMA_SITE_UNKNOWN)
- gst_caps_set_simple (caps, "chroma-site", G_TYPE_STRING,
- gst_video_chroma_to_string (info->chroma_site), NULL);
+ if (info->chroma_site != GST_VIDEO_CHROMA_SITE_UNKNOWN) {
+ gchar *chroma_site = gst_video_chroma_site_to_string (info->chroma_site);
+
+ if (!chroma_site) {
+ GST_WARNING ("Couldn't convert chroma-site 0x%x to string",
+ info->chroma_site);
+ } else {
+ gst_caps_set_simple (caps,
+ "chroma-site", G_TYPE_STRING, chroma_site, NULL);
+ g_free (chroma_site);
+ }
+ }
/* make sure we set the RGB matrix for RGB formats */
colorimetry = info->colorimetry;
return caps;
}
-static int
-fill_planes (GstVideoInfo * info)
+static gboolean
+fill_planes (GstVideoInfo * info, gsize plane_size[GST_VIDEO_MAX_PLANES])
{
gsize width, height, cr_h;
+ gint bpp = 0, i;
width = (gsize) info->width;
- height = (gsize) info->height;
+ height = (gsize) GST_VIDEO_INFO_FIELD_HEIGHT (info);
+
+ /* Sanity check the resulting frame size for overflows */
+ for (i = 0; i < GST_VIDEO_INFO_N_COMPONENTS (info); i++)
+ bpp += GST_VIDEO_INFO_COMP_DEPTH (info, i);
+ bpp = GST_ROUND_UP_8 (bpp) / 8;
+ if (bpp > 0 && GST_ROUND_UP_128 ((guint64) width) * ((guint64) height) >=
+ G_MAXUINT / bpp) {
+ GST_ERROR ("Frame size %ux%u would overflow", info->width, info->height);
+ return FALSE;
+ }
switch (info->finfo->format) {
case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_RGBA:
case GST_VIDEO_FORMAT_BGRx:
case GST_VIDEO_FORMAT_BGRA:
+ case GST_VIDEO_FORMAT_SR32:
case GST_VIDEO_FORMAT_xRGB:
case GST_VIDEO_FORMAT_ARGB:
case GST_VIDEO_FORMAT_xBGR:
case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_r210:
+ case GST_VIDEO_FORMAT_Y410:
+ case GST_VIDEO_FORMAT_VUYA:
+ case GST_VIDEO_FORMAT_BGR10A2_LE:
+ case GST_VIDEO_FORMAT_RGB10A2_LE:
info->stride[0] = width * 4;
info->offset[0] = 0;
info->size = info->stride[0] * height;
info->size = info->stride[0] * height;
break;
case GST_VIDEO_FORMAT_v216:
+ case GST_VIDEO_FORMAT_Y210:
+ case GST_VIDEO_FORMAT_Y212_BE:
+ case GST_VIDEO_FORMAT_Y212_LE:
info->stride[0] = GST_ROUND_UP_8 (width * 4);
info->offset[0] = 0;
info->size = info->stride[0] * height;
break;
case GST_VIDEO_FORMAT_GRAY16_BE:
case GST_VIDEO_FORMAT_GRAY16_LE:
+ case GST_VIDEO_FORMAT_INVZ:
info->stride[0] = GST_ROUND_UP_4 (width * 2);
info->offset[0] = 0;
info->size = info->stride[0] * height;
break;
case GST_VIDEO_FORMAT_ARGB64:
case GST_VIDEO_FORMAT_AYUV64:
+ case GST_VIDEO_FORMAT_Y412_BE:
+ case GST_VIDEO_FORMAT_Y412_LE:
info->stride[0] = width * 8;
info->offset[0] = 0;
info->size = info->stride[0] * height;
break;
case GST_VIDEO_FORMAT_I420:
+ case GST_VIDEO_FORMAT_S420:
case GST_VIDEO_FORMAT_YV12: /* same as I420, but plane 1+2 swapped */
+#ifdef TIZEN_PROFILE_TV
+ case GST_VIDEO_FORMAT_STV0:
+ case GST_VIDEO_FORMAT_STV1:
+#endif
info->stride[0] = GST_ROUND_UP_4 (width);
info->stride[1] = GST_ROUND_UP_4 (GST_ROUND_UP_2 (width) / 2);
info->stride[2] = info->stride[1];
break;
case GST_VIDEO_FORMAT_Y444:
case GST_VIDEO_FORMAT_GBR:
+ case GST_VIDEO_FORMAT_RGBP:
+ case GST_VIDEO_FORMAT_BGRP:
info->stride[0] = GST_ROUND_UP_4 (width);
info->stride[1] = info->stride[0];
info->stride[2] = info->stride[0];
info->offset[2] = info->offset[1] * 2;
info->size = info->stride[0] * height * 3;
break;
+ case GST_VIDEO_FORMAT_GBRA:
+ info->stride[0] = GST_ROUND_UP_4 (width);
+ info->stride[1] = info->stride[0];
+ info->stride[2] = info->stride[0];
+ info->stride[3] = info->stride[0];
+ info->offset[0] = 0;
+ info->offset[1] = info->stride[0] * height;
+ info->offset[2] = info->offset[1] * 2;
+ info->offset[3] = info->offset[1] * 3;
+ info->size = info->stride[0] * height * 4;
+ break;
case GST_VIDEO_FORMAT_NV12:
+#ifdef TIZEN_FEATURE_VIDEO_MODIFICATION
+ case GST_VIDEO_FORMAT_SN12:
+ case GST_VIDEO_FORMAT_ST12:
+ case GST_VIDEO_FORMAT_SN21:
+#endif
case GST_VIDEO_FORMAT_NV21:
info->stride[0] = GST_ROUND_UP_4 (width);
info->stride[1] = info->stride[0];
info->offset[0] = 0;
info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
+#ifdef TIZEN_FEATURE_VIDEO_MODIFICATION
+ info->size = info->stride[0] * GST_ROUND_UP_2 (height) * 3 / 2;
+#else
cr_h = GST_ROUND_UP_2 (height) / 2;
if (GST_VIDEO_INFO_IS_INTERLACED (info))
cr_h = GST_ROUND_UP_2 (cr_h);
info->size = info->offset[1] + info->stride[0] * cr_h;
+#endif
+ break;
+ case GST_VIDEO_FORMAT_AV12:
+ info->stride[0] = GST_ROUND_UP_4 (width);
+ info->stride[1] = info->stride[0];
+ info->stride[2] = info->stride[0];
+ info->offset[0] = 0;
+ info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
+ info->offset[2] =
+ info->offset[1] + (info->stride[1] * GST_ROUND_UP_2 (height) / 2);
+ info->size = info->offset[2] + info->stride[2] * GST_ROUND_UP_2 (height);
break;
case GST_VIDEO_FORMAT_NV16:
case GST_VIDEO_FORMAT_NV61:
break;
case GST_VIDEO_FORMAT_I420_10LE:
case GST_VIDEO_FORMAT_I420_10BE:
+ case GST_VIDEO_FORMAT_I420_12LE:
+ case GST_VIDEO_FORMAT_I420_12BE:
info->stride[0] = GST_ROUND_UP_4 (width * 2);
info->stride[1] = GST_ROUND_UP_4 (width);
info->stride[2] = info->stride[1];
break;
case GST_VIDEO_FORMAT_I422_10LE:
case GST_VIDEO_FORMAT_I422_10BE:
+ case GST_VIDEO_FORMAT_I422_12LE:
+ case GST_VIDEO_FORMAT_I422_12BE:
info->stride[0] = GST_ROUND_UP_4 (width * 2);
info->stride[1] = GST_ROUND_UP_4 (width);
info->stride[2] = info->stride[1];
break;
case GST_VIDEO_FORMAT_Y444_10LE:
case GST_VIDEO_FORMAT_Y444_10BE:
+ case GST_VIDEO_FORMAT_Y444_12LE:
+ case GST_VIDEO_FORMAT_Y444_12BE:
case GST_VIDEO_FORMAT_GBR_10LE:
case GST_VIDEO_FORMAT_GBR_10BE:
+ case GST_VIDEO_FORMAT_GBR_12LE:
+ case GST_VIDEO_FORMAT_GBR_12BE:
+ case GST_VIDEO_FORMAT_Y444_16LE:
+ case GST_VIDEO_FORMAT_Y444_16BE:
info->stride[0] = GST_ROUND_UP_4 (width * 2);
info->stride[1] = info->stride[0];
info->stride[2] = info->stride[0];
info->offset[2] = info->offset[1] * 2;
info->size = info->stride[0] * height * 3;
break;
+ case GST_VIDEO_FORMAT_GBRA_10LE:
+ case GST_VIDEO_FORMAT_GBRA_10BE:
+ case GST_VIDEO_FORMAT_GBRA_12LE:
+ case GST_VIDEO_FORMAT_GBRA_12BE:
+ info->stride[0] = GST_ROUND_UP_4 (width * 2);
+ info->stride[1] = info->stride[0];
+ info->stride[2] = info->stride[0];
+ info->stride[3] = info->stride[0];
+ info->offset[0] = 0;
+ info->offset[1] = info->stride[0] * height;
+ info->offset[2] = info->offset[1] * 2;
+ info->offset[3] = info->offset[1] * 3;
+ info->size = info->stride[0] * height * 4;
+ break;
case GST_VIDEO_FORMAT_NV12_64Z32:
info->stride[0] =
GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_128 (width) / 64,
info->offset[0] = 0;
info->offset[1] = GST_ROUND_UP_128 (width) * GST_ROUND_UP_32 (height);
info->size = info->offset[1] +
- GST_ROUND_UP_128 (width) * GST_ROUND_UP_64 (height) / 2;
+ GST_ROUND_UP_128 (width) * (GST_ROUND_UP_64 (height) / 2);
break;
+ case GST_VIDEO_FORMAT_NV12_4L4:
+ case GST_VIDEO_FORMAT_NV12_32L32:
+ {
+ gint ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info->finfo);
+ gint hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info->finfo);
+ info->stride[0] =
+ GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_N (width, 1 << ws) >> ws,
+ GST_ROUND_UP_N (height, 1 << hs) >> hs);
+ info->stride[1] =
+ GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_N (width, 1 << ws) >> ws,
+ GST_ROUND_UP_N (height, 1 << (hs + 1)) >> (hs + 1));
+ info->offset[0] = 0;
+ info->offset[1] =
+ GST_ROUND_UP_N (width, 1 << ws) * GST_ROUND_UP_N (height, 1 << hs);
+ info->size = info->offset[1] +
+ GST_ROUND_UP_N (width, 1 << ws) *
+ (GST_ROUND_UP_N (height, 1 << (hs + 1)) / 2);
+ break;
+ }
case GST_VIDEO_FORMAT_A420_10LE:
case GST_VIDEO_FORMAT_A420_10BE:
info->stride[0] = GST_ROUND_UP_4 (width * 2);
break;
case GST_VIDEO_FORMAT_P010_10LE:
case GST_VIDEO_FORMAT_P010_10BE:
+ case GST_VIDEO_FORMAT_P016_LE:
+ case GST_VIDEO_FORMAT_P016_BE:
+ case GST_VIDEO_FORMAT_P012_LE:
+ case GST_VIDEO_FORMAT_P012_BE:
info->stride[0] = GST_ROUND_UP_4 (width * 2);
info->stride[1] = info->stride[0];
info->offset[0] = 0;
cr_h = GST_ROUND_UP_2 (height) / 2;
info->size = info->offset[1] + info->stride[0] * cr_h;
break;
+ case GST_VIDEO_FORMAT_GRAY10_LE32:
+ info->stride[0] = (width + 2) / 3 * 4;
+ info->offset[0] = 0;
+ info->size = info->stride[0] * GST_ROUND_UP_2 (height);
+ break;
+ case GST_VIDEO_FORMAT_NV12_10LE32:
+ info->stride[0] = (width + 2) / 3 * 4;
+ info->stride[1] = info->stride[0];
+ info->offset[0] = 0;
+ info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
+ cr_h = GST_ROUND_UP_2 (height) / 2;
+ if (GST_VIDEO_INFO_IS_INTERLACED (info))
+ cr_h = GST_ROUND_UP_2 (cr_h);
+ info->size = info->offset[1] + info->stride[0] * cr_h;
+ break;
+ case GST_VIDEO_FORMAT_NV16_10LE32:
+ info->stride[0] = (width + 2) / 3 * 4;
+ info->stride[1] = info->stride[0];
+ info->offset[0] = 0;
+ info->offset[1] = info->stride[0] * height;
+ info->size = info->stride[0] * height * 2;
+ break;
+ case GST_VIDEO_FORMAT_NV12_10LE40:
+ info->stride[0] = ((width * 5 >> 2) + 4) / 5 * 5;
+ info->stride[1] = info->stride[0];
+ info->offset[0] = 0;
+ info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
+ cr_h = GST_ROUND_UP_2 (height) / 2;
+ if (GST_VIDEO_INFO_IS_INTERLACED (info))
+ cr_h = GST_ROUND_UP_2 (cr_h);
+ info->size = info->offset[1] + info->stride[0] * cr_h;
+ break;
case GST_VIDEO_FORMAT_ENCODED:
break;
case GST_VIDEO_FORMAT_UNKNOWN:
+#ifdef TIZEN_FEATURE_VIDEO_MODIFICATION
+ default:
+#endif
GST_ERROR ("invalid format");
g_warning ("invalid format");
+ return FALSE;
break;
}
- return 0;
+
+ if (plane_size) {
+ for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
+ if (i < GST_VIDEO_INFO_N_PLANES (info)) {
+ gint comp[GST_VIDEO_MAX_COMPONENTS];
+ guint plane_height;
+
+ /* Convert plane index to component index */
+ gst_video_format_info_component (info->finfo, i, comp);
+ plane_height =
+ GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, comp[0],
+ GST_VIDEO_INFO_FIELD_HEIGHT (info));
+ plane_size[i] = plane_height * GST_VIDEO_INFO_PLANE_STRIDE (info, i);
+ } else {
+ plane_size[i] = 0;
+ }
+ }
+ }
+
+ return TRUE;
}
/**
* @src_format: #GstFormat of the @src_value
* @src_value: value to convert
* @dest_format: #GstFormat of the @dest_value
- * @dest_value: pointer to destination value
+ * @dest_value: (out): pointer to destination value
*
* Converts among various #GstFormat types. This function handles
* GST_FORMAT_BYTES, GST_FORMAT_TIME, and GST_FORMAT_DEFAULT. For
* Returns: TRUE if the conversion was successful.
*/
gboolean
-gst_video_info_convert (GstVideoInfo * info,
+gst_video_info_convert (const GstVideoInfo * info,
GstFormat src_format, gint64 src_value,
GstFormat dest_format, gint64 * dest_value)
{
}
/**
- * gst_video_info_align:
+ * gst_video_info_align_full:
* @info: a #GstVideoInfo
* @align: alignment parameters
- *
- * Adjust the offset and stride fields in @info so that the padding and
- * stride alignment in @align is respected.
+ * @plane_size: (out) (allow-none): array used to store the plane sizes
*
* Extra padding will be added to the right side when stride alignment padding
* is required and @align will be updated with the new padding values.
+ *
+ * This variant of gst_video_info_align() provides the updated size, in bytes,
+ * of each video plane after the alignment, including all horizontal and vertical
+ * paddings.
+ *
+ * In case of GST_VIDEO_INTERLACE_MODE_ALTERNATE info, the returned sizes are the
+ * ones used to hold a single field, not the full frame.
+ *
+ * Returns: %FALSE if alignment could not be applied, e.g. because the
+ * size of a frame can't be represented as a 32 bit integer
+ *
+ * Since: 1.18
*/
-void
-gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align)
+gboolean
+gst_video_info_align_full (GstVideoInfo * info, GstVideoAlignment * align,
+ gsize plane_size[GST_VIDEO_MAX_PLANES])
{
const GstVideoFormatInfo *vinfo = info->finfo;
gint width, height;
GST_LOG ("left padding %u", align->padding_left);
aligned = TRUE;
for (i = 0; i < n_planes; i++) {
+ gint comp[GST_VIDEO_MAX_COMPONENTS];
gint hedge;
- /* this is the amout of pixels to add as left padding */
- hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, i, align->padding_left);
- hedge *= GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, i);
+ /* this is the amount of pixels to add as left padding */
+ gst_video_format_info_component (vinfo, i, comp);
+ hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, comp[0],
+ align->padding_left);
+ hedge *= GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, comp[0]);
GST_LOG ("plane %d, padding %d, alignment %u", i, hedge,
align->stride_align[i]);
info->width = padded_width;
info->height = padded_height;
- fill_planes (info);
+
+ if (!fill_planes (info, plane_size))
+ return FALSE;
/* check alignment */
aligned = TRUE;
info->height = height;
for (i = 0; i < n_planes; i++) {
- gint vedge, hedge, comp;
-
- /* Find the component for this plane, FIXME, we assume the plane number and
- * component number is the same for now, for scaling the dimensions this is
- * currently true for all formats but it might not be when adding new
- * formats. We might need to add a plane subsamling in the format info to
- * make this more generic or maybe use a plane -> component mapping. */
- comp = i;
+ gint comp[GST_VIDEO_MAX_COMPONENTS];
+ gint vedge, hedge;
+ gst_video_format_info_component (info->finfo, i, comp);
hedge =
- GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, comp, align->padding_left);
+ GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (vinfo, comp[0], align->padding_left);
vedge =
- GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (vinfo, comp, align->padding_top);
+ GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (vinfo, comp[0], align->padding_top);
GST_DEBUG ("plane %d: comp: %d, hedge %d vedge %d align %d stride %d", i,
- comp, hedge, vedge, align->stride_align[i], info->stride[i]);
+ comp[0], hedge, vedge, align->stride_align[i], info->stride[i]);
info->offset[i] += (vedge * info->stride[i]) +
- (hedge * GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, comp));
+ (hedge * GST_VIDEO_FORMAT_INFO_PSTRIDE (vinfo, comp[0]));
}
+
+ return TRUE;
+}
+
+/**
+ * gst_video_info_align:
+ * @info: a #GstVideoInfo
+ * @align: alignment parameters
+ *
+ * Adjust the offset and stride fields in @info so that the padding and
+ * stride alignment in @align is respected.
+ *
+ * Extra padding will be added to the right side when stride alignment padding
+ * is required and @align will be updated with the new padding values.
+ *
+ * Returns: %FALSE if alignment could not be applied, e.g. because the
+ * size of a frame can't be represented as a 32 bit integer (Since: 1.12)
+ */
+gboolean
+gst_video_info_align (GstVideoInfo * info, GstVideoAlignment * align)
+{
+ return gst_video_info_align_full (info, align, NULL);
}