mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
kmssink: Fix offsets handling
The calculation of the offset table was done base on a plane size estimation. This does not always work. Instead, use memory offset the same we as it's implement in GstVideoMeta map functions.
This commit is contained in:
parent
a3d58818e8
commit
f03fc663ef
3 changed files with 22 additions and 32 deletions
|
@ -295,13 +295,17 @@ gst_kms_allocator_new (int fd)
|
||||||
"KMSMemory::allocator", "drm-fd", fd, NULL);
|
"KMSMemory::allocator", "drm-fd", fd, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The mem_offsets are relative to the GstMemory start, unlike the vinfo->offset
|
||||||
|
* which are relative to the GstBuffer start. */
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_kms_allocator_add_fb (GstKMSAllocator * alloc, GstKMSMemory * kmsmem,
|
gst_kms_allocator_add_fb (GstKMSAllocator * alloc, GstKMSMemory * kmsmem,
|
||||||
GstVideoInfo * vinfo)
|
gsize mem_offsets[GST_VIDEO_MAX_PLANES], GstVideoInfo * vinfo)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
gint num_planes = GST_VIDEO_INFO_N_PLANES (vinfo);
|
||||||
guint32 w, h, fmt, bo_handles[4] = { 0, };
|
guint32 w, h, fmt, bo_handles[4] = { 0, };
|
||||||
guint32 offsets[4], pitches[4];
|
guint32 offsets[4] = { 0, };
|
||||||
|
guint32 pitches[4] = { 0, };
|
||||||
|
|
||||||
if (kmsmem->fb_id)
|
if (kmsmem->fb_id)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -312,19 +316,21 @@ gst_kms_allocator_add_fb (GstKMSAllocator * alloc, GstKMSMemory * kmsmem,
|
||||||
|
|
||||||
if (kmsmem->bo) {
|
if (kmsmem->bo) {
|
||||||
kms_bo_get_prop (kmsmem->bo, KMS_HANDLE, &bo_handles[0]);
|
kms_bo_get_prop (kmsmem->bo, KMS_HANDLE, &bo_handles[0]);
|
||||||
for (i = 1; i < 4; i++)
|
for (i = 1; i < num_planes; i++)
|
||||||
bo_handles[i] = bo_handles[0];
|
bo_handles[i] = bo_handles[0];
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < num_planes; i++)
|
||||||
bo_handles[i] = kmsmem->gem_handle[i];
|
bo_handles[i] = kmsmem->gem_handle[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (alloc, "bo handles: %d, %d, %d, %d", bo_handles[0],
|
GST_DEBUG_OBJECT (alloc, "bo handles: %d, %d, %d, %d", bo_handles[0],
|
||||||
bo_handles[1], bo_handles[2], bo_handles[3]);
|
bo_handles[1], bo_handles[2], bo_handles[3]);
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < num_planes; i++) {
|
||||||
offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vinfo, i);
|
offsets[i] = mem_offsets[i];
|
||||||
pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vinfo, i);
|
pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vinfo, i);
|
||||||
|
GST_DEBUG_OBJECT (alloc, "Create FB plane %i with stride %u and offset %u",
|
||||||
|
i, pitches[i], offsets[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drmModeAddFB2 (alloc->priv->fd, w, h, fmt, bo_handles, pitches,
|
ret = drmModeAddFB2 (alloc->priv->fd, w, h, fmt, bo_handles, pitches,
|
||||||
|
@ -369,7 +375,7 @@ gst_kms_allocator_bo_alloc (GstAllocator * allocator, GstVideoInfo * vinfo)
|
||||||
kmsmem = (GstKMSMemory *) mem;
|
kmsmem = (GstKMSMemory *) mem;
|
||||||
if (!gst_kms_allocator_memory_create (alloc, kmsmem, vinfo))
|
if (!gst_kms_allocator_memory_create (alloc, kmsmem, vinfo))
|
||||||
goto fail;
|
goto fail;
|
||||||
if (!gst_kms_allocator_add_fb (alloc, kmsmem, vinfo))
|
if (!gst_kms_allocator_add_fb (alloc, kmsmem, vinfo->offset, vinfo))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
return mem;
|
return mem;
|
||||||
|
@ -382,7 +388,7 @@ fail:
|
||||||
|
|
||||||
GstKMSMemory *
|
GstKMSMemory *
|
||||||
gst_kms_allocator_dmabuf_import (GstAllocator * allocator, gint * prime_fds,
|
gst_kms_allocator_dmabuf_import (GstAllocator * allocator, gint * prime_fds,
|
||||||
gint n_planes, GstVideoInfo * vinfo)
|
gint n_planes, gsize offsets[GST_VIDEO_MAX_PLANES], GstVideoInfo * vinfo)
|
||||||
{
|
{
|
||||||
GstKMSAllocator *alloc;
|
GstKMSAllocator *alloc;
|
||||||
GstMemory *mem;
|
GstMemory *mem;
|
||||||
|
@ -404,7 +410,7 @@ gst_kms_allocator_dmabuf_import (GstAllocator * allocator, gint * prime_fds,
|
||||||
goto import_fd_failed;
|
goto import_fd_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_kms_allocator_add_fb (alloc, tmp, vinfo))
|
if (!gst_kms_allocator_add_fb (alloc, tmp, offsets, vinfo))
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|
|
@ -82,6 +82,7 @@ GstMemory* gst_kms_allocator_bo_alloc (GstAllocator *allocator,
|
||||||
GstKMSMemory* gst_kms_allocator_dmabuf_import (GstAllocator *allocator,
|
GstKMSMemory* gst_kms_allocator_dmabuf_import (GstAllocator *allocator,
|
||||||
gint *prime_fds,
|
gint *prime_fds,
|
||||||
gint n_planes,
|
gint n_planes,
|
||||||
|
gsize offsets[GST_VIDEO_MAX_PLANES],
|
||||||
GstVideoInfo *vinfo);
|
GstVideoInfo *vinfo);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include <drm.h>
|
#include <drm.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include <xf86drmMode.h>
|
#include <xf86drmMode.h>
|
||||||
|
#include <drm_fourcc.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -888,21 +889,6 @@ set_cached_kmsmem (GstMemory * mem, GstMemory * kmsmem)
|
||||||
(GDestroyNotify) gst_memory_unref);
|
(GDestroyNotify) gst_memory_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gsize
|
|
||||||
get_plane_data_size (GstVideoInfo * info, guint plane)
|
|
||||||
{
|
|
||||||
gint padded_height;
|
|
||||||
gsize plane_size;
|
|
||||||
|
|
||||||
padded_height = info->height;
|
|
||||||
padded_height =
|
|
||||||
GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, plane, padded_height);
|
|
||||||
|
|
||||||
plane_size = GST_VIDEO_INFO_PLANE_STRIDE (info, plane) * padded_height;
|
|
||||||
|
|
||||||
return plane_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_kms_sink_import_dmabuf (GstKMSSink * self, GstBuffer * inbuf,
|
gst_kms_sink_import_dmabuf (GstKMSSink * self, GstBuffer * inbuf,
|
||||||
GstBuffer ** outbuf)
|
GstBuffer ** outbuf)
|
||||||
|
@ -926,6 +912,9 @@ gst_kms_sink_import_dmabuf (GstKMSSink * self, GstBuffer * inbuf,
|
||||||
n_mem = gst_buffer_n_memory (inbuf);
|
n_mem = gst_buffer_n_memory (inbuf);
|
||||||
meta = gst_buffer_get_video_meta (inbuf);
|
meta = gst_buffer_get_video_meta (inbuf);
|
||||||
|
|
||||||
|
GST_TRACE_OBJECT (self, "Found a dmabuf with %u planes and %u memories",
|
||||||
|
n_planes, n_mem);
|
||||||
|
|
||||||
/* We cannot have multiple dmabuf per plane */
|
/* We cannot have multiple dmabuf per plane */
|
||||||
if (n_mem > n_planes)
|
if (n_mem > n_planes)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -943,19 +932,13 @@ gst_kms_sink_import_dmabuf (GstKMSSink * self, GstBuffer * inbuf,
|
||||||
|
|
||||||
/* Find and validate all memories */
|
/* Find and validate all memories */
|
||||||
for (i = 0; i < n_planes; i++) {
|
for (i = 0; i < n_planes; i++) {
|
||||||
guint plane_size;
|
|
||||||
guint length;
|
guint length;
|
||||||
|
|
||||||
plane_size = get_plane_data_size (&self->vinfo, i);
|
|
||||||
if (!gst_buffer_find_memory (inbuf,
|
if (!gst_buffer_find_memory (inbuf,
|
||||||
GST_VIDEO_INFO_PLANE_OFFSET (&self->vinfo, i), plane_size,
|
GST_VIDEO_INFO_PLANE_OFFSET (&self->vinfo, i), 1,
|
||||||
&mems_idx[i], &length, &mems_skip[i]))
|
&mems_idx[i], &length, &mems_skip[i]))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* We can't have more then one dmabuf per plane */
|
|
||||||
if (length != 1)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
mems[i] = gst_buffer_peek_memory (inbuf, mems_idx[i]);
|
mems[i] = gst_buffer_peek_memory (inbuf, mems_idx[i]);
|
||||||
|
|
||||||
/* And all memory found must be dmabuf */
|
/* And all memory found must be dmabuf */
|
||||||
|
@ -977,7 +960,7 @@ gst_kms_sink_import_dmabuf (GstKMSSink * self, GstBuffer * inbuf,
|
||||||
prime_fds[1], prime_fds[2], prime_fds[3]);
|
prime_fds[1], prime_fds[2], prime_fds[3]);
|
||||||
|
|
||||||
kmsmem = gst_kms_allocator_dmabuf_import (self->allocator, prime_fds,
|
kmsmem = gst_kms_allocator_dmabuf_import (self->allocator, prime_fds,
|
||||||
n_planes, &self->vinfo);
|
n_planes, mems_skip, &self->vinfo);
|
||||||
if (!kmsmem)
|
if (!kmsmem)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue