summaryrefslogtreecommitdiff
path: root/omx/gstomxvideo.c
diff options
context:
space:
mode:
Diffstat (limited to 'omx/gstomxvideo.c')
-rw-r--r--omx/gstomxvideo.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/omx/gstomxvideo.c b/omx/gstomxvideo.c
index 627d708..8bbee9e 100644
--- a/omx/gstomxvideo.c
+++ b/omx/gstomxvideo.c
@@ -254,3 +254,96 @@ gst_omx_video_is_equal_framerate_q16 (OMX_U32 q16_a, OMX_U32 q16_b)
* an unnecessary re-negotiation. */
return fabs (((gdouble) q16_a) - ((gdouble) q16_b)) / (gdouble) q16_b < 0.01;
}
+
+gboolean
+gst_omx_video_get_port_padding (GstOMXPort * port, GstVideoInfo * info_orig,
+ GstVideoAlignment * align)
+{
+ guint nstride;
+ guint nslice_height;
+ GstVideoInfo info;
+ gsize plane_size[GST_VIDEO_MAX_PLANES];
+
+ gst_video_alignment_reset (align);
+
+ /* Create a copy of @info_orig without any offset/stride as we need a
+ * 'standard' version to compute the paddings. */
+ gst_video_info_init (&info);
+ gst_video_info_set_interlaced_format (&info,
+ GST_VIDEO_INFO_FORMAT (info_orig),
+ GST_VIDEO_INFO_INTERLACE_MODE (info_orig),
+ GST_VIDEO_INFO_WIDTH (info_orig), GST_VIDEO_INFO_HEIGHT (info_orig));
+
+ /* Retrieve the plane sizes */
+ if (!gst_video_info_align_full (&info, align, plane_size)) {
+ GST_WARNING_OBJECT (port->comp->parent, "Failed to retrieve plane sizes");
+ return FALSE;
+ }
+
+ nstride = port->port_def.format.video.nStride;
+ nslice_height = port->port_def.format.video.nSliceHeight;
+
+ if (nstride > GST_VIDEO_INFO_PLANE_STRIDE (&info, 0)) {
+ align->padding_right = nstride - GST_VIDEO_INFO_PLANE_STRIDE (&info, 0);
+
+ if (GST_VIDEO_FORMAT_INFO_IS_COMPLEX (info.finfo)) {
+ /* Stride is in bytes while padding is in pixels so we need to do manual
+ * conversions for complex formats. */
+ switch (GST_VIDEO_INFO_FORMAT (&info)) {
+ case GST_VIDEO_FORMAT_NV12_10LE32:
+ case GST_VIDEO_FORMAT_NV16_10LE32:
+ /* Need ((width + 2) / 3) 32-bits words to store one row,
+ * see unpack_NV12_10LE32 in -base.
+ *
+ * So let's say:
+ * - W = the width, in pixels
+ * - S = the stride, in bytes
+ * - P = the padding, in bytes
+ * - Δ = the padding, in pixels
+ *
+ * we then have:
+ * S = ((W+2)/3) * 4
+ * S+P = ((W+2+Δ)/3) * 4
+ *
+ * By solving this system we get:
+ * Δ = (3/4) * P
+ */
+ align->padding_right *= 0.75;
+ break;
+ default:
+ GST_FIXME_OBJECT (port->comp->parent,
+ "Stride conversion is not supported for format %s",
+ GST_VIDEO_INFO_NAME (&info));
+ return FALSE;
+ }
+ }
+
+ GST_LOG_OBJECT (port->comp->parent,
+ "OMX stride (%d) is higher than standard (%d) for port %u; right padding: %d",
+ nstride, GST_VIDEO_INFO_PLANE_STRIDE (&info, 0), port->index,
+ align->padding_right);
+ }
+
+ if (nslice_height > GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size)) {
+ align->padding_bottom =
+ nslice_height - GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size);
+
+ if (GST_VIDEO_INFO_INTERLACE_MODE (&info) ==
+ GST_VIDEO_INTERLACE_MODE_ALTERNATE) {
+ /* GstVideoAlignment defines the alignment for the full frame while
+ * OMX gives us the slice height for a single field, so we have to
+ * double the vertical padding. */
+ GST_DEBUG_OBJECT (port->comp->parent,
+ "Double bottom padding because of alternate stream");
+ align->padding_bottom *= 2;
+ }
+
+ GST_LOG_OBJECT (port->comp->parent,
+ "OMX slice height (%d) is higher than standard (%" G_GSIZE_FORMAT
+ ") for port %u; vertical padding: %d", nslice_height,
+ GST_VIDEO_INFO_PLANE_HEIGHT (&info, 0, plane_size), port->index,
+ align->padding_bottom);
+ }
+
+ return TRUE;
+}