diff options
author | Guillaume Desmottes <guillaume.desmottes@collabora.com> | 2019-07-09 13:07:32 +0200 |
---|---|---|
committer | Guillaume Desmottes <guillaume.desmottes@collabora.com> | 2019-11-05 17:30:21 +0530 |
commit | 800cc4bd6710b60da09982d1efdfde2613d950a9 (patch) | |
tree | 452a47c673673339c12735c522807073c1c5ba27 | |
parent | 611f37c2ae88420a751c62b1a67c15362feb94cc (diff) | |
download | gst-omx-800cc4bd6710b60da09982d1efdfde2613d950a9.tar.gz |
omxbufferpool: use gst_video_meta_set_alignment()
Tell buffer consumer about our paddings.
v4l2src can now uses these paddings information when trying to import
buffers to configure the v4l2 driver accordingly.
-rw-r--r-- | omx/gstomxbufferpool.c | 10 | ||||
-rw-r--r-- | omx/gstomxvideo.c | 93 | ||||
-rw-r--r-- | omx/gstomxvideo.h | 3 |
3 files changed, 105 insertions, 1 deletions
diff --git a/omx/gstomxbufferpool.c b/omx/gstomxbufferpool.c index 7b95d7c..b885685 100644 --- a/omx/gstomxbufferpool.c +++ b/omx/gstomxbufferpool.c @@ -26,6 +26,7 @@ #endif #include "gstomxbufferpool.h" +#include "gstomxvideo.h" #include <gst/allocators/gstdmabuf.h> @@ -410,11 +411,18 @@ gst_omx_buffer_pool_alloc_buffer (GstBufferPool * bpool, /* We always add the videometa. It's the job of the user * to copy the buffer if pool->need_copy is TRUE */ - gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE, + GstVideoMeta *meta; + GstVideoAlignment align; + + meta = gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE, GST_VIDEO_INFO_FORMAT (&pool->video_info), GST_VIDEO_INFO_WIDTH (&pool->video_info), GST_VIDEO_INFO_HEIGHT (&pool->video_info), GST_VIDEO_INFO_N_PLANES (&pool->video_info), offset, stride); + + if (gst_omx_video_get_port_padding (pool->port, &pool->video_info, + &align)) + gst_video_meta_set_alignment (meta, align); } } 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; +} diff --git a/omx/gstomxvideo.h b/omx/gstomxvideo.h index 8252df9..e124382 100644 --- a/omx/gstomxvideo.h +++ b/omx/gstomxvideo.h @@ -63,6 +63,9 @@ OMX_U32 gst_omx_video_calculate_framerate_q16 (GstVideoInfo * info); gboolean gst_omx_video_is_equal_framerate_q16 (OMX_U32 q16_a, OMX_U32 q16_b); +gboolean gst_omx_video_get_port_padding (GstOMXPort * port, GstVideoInfo * info_orig, + GstVideoAlignment * align); + G_END_DECLS #endif /* __GST_OMX_VIDEO_H__ */ |