gldownload: Implement importing RGBA with modifiers

For single plane RGBA based formats, implement support for modifiers.
This fixes issues where linear is actually configured in GL causing
visual artifacts.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6792>
This commit is contained in:
Nicolas Dufresne 2024-11-07 15:37:44 -05:00
parent b7970a4d95
commit a18f1af1a4
4 changed files with 42 additions and 9 deletions

View File

@ -36,8 +36,10 @@
typedef struct _GstGLDMABufBufferPoolPrivate typedef struct _GstGLDMABufBufferPoolPrivate
{ {
GstBufferPool *dmabuf_pool; GstBufferPool *dmabuf_pool;
GstCaps *dmabuf_caps;
GstGLMemoryAllocator *allocator; GstGLMemoryAllocator *allocator;
GstGLVideoAllocationParams *glparams; GstGLVideoAllocationParams *glparams;
GstVideoInfoDmaDrm drm_info;
gboolean add_glsyncmeta; gboolean add_glsyncmeta;
} GstGLDMABufBufferPoolPrivate; } GstGLDMABufBufferPoolPrivate;
@ -126,7 +128,11 @@ gst_gl_dmabuf_buffer_pool_set_config (GstBufferPool * pool,
/* Now configure the dma-buf pool, and sync the config */ /* Now configure the dma-buf pool, and sync the config */
dma_config = gst_buffer_pool_get_config (self->priv->dmabuf_pool); dma_config = gst_buffer_pool_get_config (self->priv->dmabuf_pool);
gst_buffer_pool_config_set_params (dma_config, caps, size, min, max); gst_buffer_pool_config_set_params (dma_config, self->priv->dmabuf_caps,
size, min, max);
/* VideoMeta should be implicit, but it costs nothing to request it */
gst_buffer_pool_config_add_option (dma_config,
GST_BUFFER_POOL_OPTION_VIDEO_META);
gst_buffer_pool_config_add_option (dma_config, gst_buffer_pool_config_add_option (dma_config,
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
gst_buffer_pool_config_set_video_alignment (dma_config, &video_align); gst_buffer_pool_config_set_video_alignment (dma_config, &video_align);
@ -134,13 +140,13 @@ gst_gl_dmabuf_buffer_pool_set_config (GstBufferPool * pool,
if (!gst_buffer_pool_set_config (self->priv->dmabuf_pool, dma_config)) { if (!gst_buffer_pool_set_config (self->priv->dmabuf_pool, dma_config)) {
dma_config = gst_buffer_pool_get_config (self->priv->dmabuf_pool); dma_config = gst_buffer_pool_get_config (self->priv->dmabuf_pool);
if (!gst_buffer_pool_config_validate_params (dma_config, caps, size, min, if (!gst_buffer_pool_config_validate_params (dma_config,
max)) { self->priv->dmabuf_caps, size, min, max)) {
gst_structure_free (config); gst_structure_free (config);
return FALSE; return FALSE;
} }
if (!gst_buffer_pool_config_get_params (dma_config, &caps, &size, &min, if (!gst_buffer_pool_config_get_params (dma_config, NULL, &size, &min,
&max)) { &max)) {
gst_structure_free (dma_config); gst_structure_free (dma_config);
goto wrong_config; goto wrong_config;
@ -265,6 +271,7 @@ gst_gl_dmabuf_buffer_pool_acquire_buffer (GstBufferPool * pool,
GstGLBufferPool *glpool = GST_GL_BUFFER_POOL (pool); GstGLBufferPool *glpool = GST_GL_BUFFER_POOL (pool);
GstVideoInfo *v_info = self->priv->glparams->v_info; GstVideoInfo *v_info = self->priv->glparams->v_info;
GstVideoMeta *vmeta;
GstFlowReturn ret; GstFlowReturn ret;
GstBuffer *dmabuf; GstBuffer *dmabuf;
GstBuffer *buf; GstBuffer *buf;
@ -276,6 +283,9 @@ gst_gl_dmabuf_buffer_pool_acquire_buffer (GstBufferPool * pool,
goto no_buffer; goto no_buffer;
} }
vmeta = gst_buffer_get_video_meta (dmabuf);
g_return_val_if_fail (vmeta, GST_FLOW_ERROR);
data.n_planes = GST_VIDEO_INFO_N_PLANES (v_info); data.n_planes = GST_VIDEO_INFO_N_PLANES (v_info);
for (i = 0; i < data.n_planes; ++i) { for (i = 0; i < data.n_planes; ++i) {
@ -283,6 +293,9 @@ gst_gl_dmabuf_buffer_pool_acquire_buffer (GstBufferPool * pool,
gsize skip; gsize skip;
GstMemory *dmabufmem; GstMemory *dmabufmem;
self->priv->drm_info.vinfo.stride[i] = v_info->stride[i] = vmeta->stride[i];
self->priv->drm_info.vinfo.offset[i] = v_info->offset[i] = vmeta->offset[i];
if (!gst_buffer_find_memory (dmabuf, GST_VIDEO_INFO_PLANE_OFFSET (v_info, if (!gst_buffer_find_memory (dmabuf, GST_VIDEO_INFO_PLANE_OFFSET (v_info,
i), 1, &mem_idx, &length, &skip)) { i), 1, &mem_idx, &length, &skip)) {
GST_WARNING_OBJECT (self, "Could not find memory for plane %d", i); GST_WARNING_OBJECT (self, "Could not find memory for plane %d", i);
@ -293,8 +306,17 @@ gst_gl_dmabuf_buffer_pool_acquire_buffer (GstBufferPool * pool,
g_assert (gst_is_dmabuf_memory (dmabufmem)); g_assert (gst_is_dmabuf_memory (dmabufmem));
data.eglimage[i] = gst_egl_image_from_dmabuf (glpool->context, /* Anything that is not using GLMemory format RGBA is using indirect
gst_dmabuf_memory_get_fd (dmabufmem), v_info, i, skip); * dmabuf importation with linear modifiers */
if (GST_VIDEO_INFO_FORMAT (v_info) != GST_VIDEO_FORMAT_RGBA) {
data.eglimage[i] = gst_egl_image_from_dmabuf (glpool->context,
gst_dmabuf_memory_get_fd (dmabufmem), v_info, i, skip);
} else {
int fd = gst_dmabuf_memory_get_fd (dmabufmem);
data.eglimage[i] =
gst_egl_image_from_dmabuf_direct_target_with_dma_drm (glpool->context,
1, &fd, &skip, &self->priv->drm_info, GL_TEXTURE_2D);
}
} }
gst_gl_context_thread_add (glpool->context, _wrap_dmabuf_eglimage, &data); gst_gl_context_thread_add (glpool->context, _wrap_dmabuf_eglimage, &data);
@ -388,7 +410,7 @@ gst_gl_dmabuf_buffer_unwrap (GstBuffer * buffer)
GstBufferPool * GstBufferPool *
gst_gl_dmabuf_buffer_pool_new (GstGLContext * context, gst_gl_dmabuf_buffer_pool_new (GstGLContext * context,
GstBufferPool * dmabuf_pool) GstBufferPool * dmabuf_pool, GstCaps * dmabuf_caps)
{ {
GstGLDMABufBufferPool *pool; GstGLDMABufBufferPool *pool;
@ -398,6 +420,9 @@ gst_gl_dmabuf_buffer_pool_new (GstGLContext * context,
GST_GL_BUFFER_POOL (pool)->context = gst_object_ref (context); GST_GL_BUFFER_POOL (pool)->context = gst_object_ref (context);
pool->priv->dmabuf_pool = gst_object_ref (dmabuf_pool); pool->priv->dmabuf_pool = gst_object_ref (dmabuf_pool);
pool->priv->dmabuf_caps = gst_caps_ref (dmabuf_caps);
gst_video_info_dma_drm_from_caps (&pool->priv->drm_info, dmabuf_caps);
GST_LOG_OBJECT (pool, "new GL-DMABuf buffer pool for pool %" GST_PTR_FORMAT GST_LOG_OBJECT (pool, "new GL-DMABuf buffer pool for pool %" GST_PTR_FORMAT
" and context %" GST_PTR_FORMAT, dmabuf_pool, context); " and context %" GST_PTR_FORMAT, dmabuf_pool, context);

View File

@ -50,7 +50,8 @@ struct _GstGLDMABufBufferPool
GstGLDMABufBufferPoolPrivate *priv; GstGLDMABufBufferPoolPrivate *priv;
}; };
GstBufferPool *gst_gl_dmabuf_buffer_pool_new (GstGLContext * context, GstBufferPool * dmabuf_pool); GstBufferPool *gst_gl_dmabuf_buffer_pool_new (GstGLContext * context, GstBufferPool * dmabuf_pool,
GstCaps * dmabuf_caps);
gboolean gst_is_gl_dmabuf_buffer (GstBuffer * buffer); gboolean gst_is_gl_dmabuf_buffer (GstBuffer * buffer);

View File

@ -901,6 +901,7 @@ gst_gl_download_element_stop (GstBaseTransform * bt)
} }
gst_clear_object (&dl->foreign_dmabuf_pool); gst_clear_object (&dl->foreign_dmabuf_pool);
gst_clear_caps (&dl->foreign_dmabuf_caps);
return TRUE; return TRUE;
} }
@ -952,6 +953,7 @@ _convert_dma_drm (GstGLContext * context, GstStructure * s)
return FALSE; return FALSE;
} }
/* Convert from DMA_DRM to GstVideo formats */
if (G_VALUE_HOLDS_STRING (fmtval) && if (G_VALUE_HOLDS_STRING (fmtval) &&
g_str_equal (g_value_get_string (fmtval), "DMA_DRM")) { g_str_equal (g_value_get_string (fmtval), "DMA_DRM")) {
const GValue *drmval = gst_structure_get_value (s, "drm-format"); const GValue *drmval = gst_structure_get_value (s, "drm-format");
@ -965,6 +967,7 @@ _convert_dma_drm (GstGLContext * context, GstStructure * s)
} else { } else {
return FALSE; return FALSE;
} }
/* Otherwise convert from GstVideo to DMA_DRM */
} else { } else {
GValue drmfmtval = G_VALUE_INIT; GValue drmfmtval = G_VALUE_INIT;
@ -1474,6 +1477,7 @@ gst_gl_download_element_decide_allocation (GstBaseTransform * trans,
const GstCapsFeatures *features; const GstCapsFeatures *features;
gst_clear_object (&download->foreign_dmabuf_pool); gst_clear_object (&download->foreign_dmabuf_pool);
gst_clear_caps (&download->foreign_dmabuf_caps);
gst_query_parse_allocation (query, &caps, NULL); gst_query_parse_allocation (query, &caps, NULL);
features = gst_caps_get_features (caps, 0); features = gst_caps_get_features (caps, 0);
@ -1483,6 +1487,7 @@ gst_gl_download_element_decide_allocation (GstBaseTransform * trans,
gst_query_parse_nth_allocation_pool (query, 0, gst_query_parse_nth_allocation_pool (query, 0,
&download->foreign_dmabuf_pool, NULL, NULL, NULL); &download->foreign_dmabuf_pool, NULL, NULL, NULL);
download->foreign_dmabuf_caps = gst_caps_ref (caps);
gst_query_remove_nth_allocation_pool (query, 0); gst_query_remove_nth_allocation_pool (query, 0);
} }
@ -1565,7 +1570,8 @@ gst_gl_download_element_propose_allocation (GstBaseTransform * bt,
#if GST_GL_HAVE_PLATFORM_EGL && GST_GL_HAVE_DMABUF #if GST_GL_HAVE_PLATFORM_EGL && GST_GL_HAVE_DMABUF
if (!pool && GST_GL_DOWNLOAD_ELEMENT (bt)->foreign_dmabuf_pool) { if (!pool && GST_GL_DOWNLOAD_ELEMENT (bt)->foreign_dmabuf_pool) {
pool = gst_gl_dmabuf_buffer_pool_new (context, pool = gst_gl_dmabuf_buffer_pool_new (context,
GST_GL_DOWNLOAD_ELEMENT (bt)->foreign_dmabuf_pool); GST_GL_DOWNLOAD_ELEMENT (bt)->foreign_dmabuf_pool,
GST_GL_DOWNLOAD_ELEMENT (bt)->foreign_dmabuf_caps);
GST_LOG_OBJECT (bt, "offering dma-buf-backed GL buffer pool"); GST_LOG_OBJECT (bt, "offering dma-buf-backed GL buffer pool");
} }

View File

@ -55,6 +55,7 @@ struct _GstGLDownloadElement
gboolean try_dmabuf_exports; gboolean try_dmabuf_exports;
GstAllocator * dmabuf_allocator; GstAllocator * dmabuf_allocator;
GstBufferPool * foreign_dmabuf_pool; GstBufferPool * foreign_dmabuf_pool;
GstCaps * foreign_dmabuf_caps;
gboolean add_videometa; gboolean add_videometa;
}; };