opengl: upload: Fix and improve DRM modifiers direct import

When using direct DMABuf upload, supported DRM formats and modifiers
pairs should be translated to RGBA. Instead of overwriting the translation
to RGBA, which may endup having nothing to override, we introduce a new
flag for the transform helper, so it can do direct translation.

This fixes a regression introduced by !9306, and fixes more negotiations
issues.

Fixes #4525

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9339>
This commit is contained in:
Nicolas Dufresne 2025-07-07 09:17:11 -04:00 committed by Tim-Philipp Müller
parent 4ed83e5973
commit d45864d77c
6 changed files with 43 additions and 30 deletions

View File

@ -3510,6 +3510,10 @@ extension.</doc>
<member name="include_emulated" value="4" c:identifier="GST_GL_DRM_FORMAT_INCLUDE_EMULATED" version="1.26" glib:nick="include-emulated" glib:name="GST_GL_DRM_FORMAT_INCLUDE_EMULATED">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.h">include emulated formats</doc>
</member>
<member name="direct_import" value="8" c:identifier="GST_GL_DRM_FORMAT_DIRECT_IMPORT" version="1.28" glib:nick="direct-import" glib:name="GST_GL_DRM_FORMAT_DIRECT_IMPORT">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.h">EGL is responsible for the colorspace conversion. In this case, all
supported modifiers get translated to RGBA.</doc>
</member>
</bitfield>
<class name="GLFilter" c:symbol-prefix="gl_filter" c:type="GstGLFilter" parent="GLBaseFilter" glib:type-name="GstGLFilter" glib:get-type="gst_gl_filter_get_type" glib:type-struct="GLFilterClass">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglfilter.c">#GstGLFilter helps to implement simple OpenGL filter elements taking a

View File

@ -1893,25 +1893,25 @@ gst_gl_context_egl_format_supports_modifier (GstGLContext * context,
}
/**
* gst_gl_context_egl_format_list_all_drm_formats:
* gst_gl_context_egl_append_all_drm_formats:
* @context: an EGL #GstGLContext
* @drm_fmt_list: a #GValue initialized to hold %GST_TYPE_LIST
* @drm_fromats: a #GPtrArray holding strings
* @external_only: set to %TRUE to include external only formats
*
* Append all fourcc/modifier pair supported for this egl context. This is
* Append all fourcc/modifier pair supported for this EGL context. This is
* useful when implementating direct dmabuf upload as all the formats can be
* processed as RGBA in this case.
*
* Since 1.28
*/
void
gst_gl_context_egl_format_list_all_drm_formats (GstGLContext * context,
GValue * drm_fmt_list)
gst_gl_context_egl_append_all_drm_formats (GstGLContext * context,
GPtrArray * drm_formats, gboolean include_external)
{
#if GST_GL_HAVE_DMABUF
GstGLContextEGL *egl;
g_return_if_fail (GST_IS_GL_CONTEXT_EGL (context));
g_return_if_fail (GST_VALUE_HOLDS_LIST (drm_fmt_list));
if (!gst_gl_context_egl_fetch_dma_formats (context))
return;
@ -1928,14 +1928,14 @@ gst_gl_context_egl_format_list_all_drm_formats (GstGLContext * context,
for (gint j = 0; j < format->modifiers->len; j++) {
GstGLDmaModifier *modifier;
GValue value = G_VALUE_INIT;
g_value_init (&value, G_TYPE_STRING);
modifier = &g_array_index (format->modifiers, GstGLDmaModifier, j);
if (modifier->external_only && !include_external)
continue;
gchar *drm_fmt_str = gst_video_dma_drm_fourcc_to_string (format->fourcc,
modifier->modifier);
g_value_take_string (&value, drm_fmt_str);
gst_value_list_append_and_take_value (drm_fmt_list, &value);
g_ptr_array_add (drm_formats, drm_fmt_str);
}
}

View File

@ -121,8 +121,9 @@ gboolean gst_gl_context_egl_format_supports_modifier (GstGLContext *
gboolean include_external);
G_GNUC_INTERNAL
void gst_gl_context_egl_format_list_all_drm_formats (GstGLContext * context,
GValue *drm_fmt_list);
void gst_gl_context_egl_append_all_drm_formats (GstGLContext * context,
GPtrArray *drm_formats,
gboolean include_external);
G_GNUC_INTERNAL
gboolean gst_gl_context_egl_supports_modifier (GstGLContext * context);

View File

@ -1402,7 +1402,7 @@ _direct_dma_buf_upload_transform_caps (gpointer impl, GstGLContext * context,
{
struct DmabufUpload *dmabuf = impl;
GstCaps *ret, *tmp;
GstGLDrmFormatFlags flags = 0;
GstGLDrmFormatFlags flags = GST_GL_DRM_FORMAT_DIRECT_IMPORT;
if (dmabuf->target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES)
flags |= GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL;
@ -1449,13 +1449,6 @@ _direct_dma_buf_upload_transform_caps (gpointer impl, GstGLContext * context,
return NULL;
}
/* The direct mode, sampling an imported texture will return an RGBA
vector in the same colorspace as the source image. If the source
image is stored in YUV(or some other basis) then the YUV values will
be transformed to RGB values. So, any input format is transformed to:
"video/x-raw(memory:GLMemory), format=(string)RGBA" as output. */
gst_caps_set_simple (ret, "format", G_TYPE_STRING, "RGBA", NULL);
n = gst_caps_get_size (ret);
for (i = 0; i < n; i++) {
GstStructure *s = gst_caps_get_structure (ret, i);
@ -1477,14 +1470,6 @@ _direct_dma_buf_upload_transform_caps (gpointer impl, GstGLContext * context,
flags, 1 << dmabuf->target, GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
GST_CAPS_FEATURE_MEMORY_DMABUF);
if (context && ret) {
GValue direct_fmts = G_VALUE_INIT;
g_value_init (&direct_fmts, GST_TYPE_LIST);
gst_gl_context_egl_format_list_all_drm_formats (context, &direct_fmts);
gst_caps_set_value_static_str (ret, "drm-format", &direct_fmts);
g_value_unset (&direct_fmts);
}
tmp = _dma_buf_upload_transform_caps_common (caps, context, direction,
flags, 1 << dmabuf->target, GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY);

View File

@ -935,10 +935,19 @@ _append_drm_formats_from_video_format (GstGLContext * context,
{
const gboolean include_external =
!!(flags & GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL);
const gboolean direct_import = !!(flags & GST_GL_DRM_FORMAT_DIRECT_IMPORT);
guint32 fourcc;
guint64 modifier;
char *drm_format;
if (direct_import) {
if (format != GST_VIDEO_FORMAT_RGBA)
return;
gst_gl_context_egl_append_all_drm_formats (context, drm_formats,
include_external);
return;
}
fourcc = gst_video_dma_drm_format_from_gst_format (format, &modifier);
if (fourcc == DRM_FORMAT_INVALID)
return;
@ -1057,7 +1066,11 @@ _get_video_format_from_drm_format (GstGLContext * context,
modifier != DRM_FORMAT_MOD_LINEAR)
return GST_VIDEO_FORMAT_UNKNOWN;
gst_format = gst_video_dma_drm_format_to_gst_format (fourcc, modifier);
if (flags & GST_GL_DRM_FORMAT_DIRECT_IMPORT)
gst_format = GST_VIDEO_FORMAT_RGBA;
else
gst_format = gst_video_dma_drm_format_to_gst_format (fourcc, modifier);
if (gst_format == GST_VIDEO_FORMAT_UNKNOWN)
return GST_VIDEO_FORMAT_UNKNOWN;

View File

@ -72,6 +72,7 @@ void gst_gl_multiply_matrix4 (const gfloat * a, const gfloat * b, gfloat * resul
* @GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL: include external-only formats (Since: 1.26)
* @GST_GL_DRM_FORMAT_LINEAR_ONLY: only include formats with linear modifier (Since: 1.26)
* @GST_GL_DRM_FORMAT_INCLUDE_EMULATED: include emulated formats (Since: 1.26)
* @GST_GL_DRM_FORMAT_DIRECT_IMPORT: EGL is doing the color convertion (Since: 1.28)
*
* Since: 1.26
*/
@ -101,6 +102,15 @@ typedef enum
* Since: 1.26
*/
GST_GL_DRM_FORMAT_INCLUDE_EMULATED = 1 << 2,
/**
* GST_GL_DRM_FORMAT_DIRECT_IMPORT:
*
* EGL is responsible for the colorspace conversion. In this case, all
* supported modifiers get translated to RGBA.
*
* Since: 1.28
*/
GST_GL_DRM_FORMAT_DIRECT_IMPORT = 1 << 3,
} GstGLDrmFormatFlags;
GST_GL_API