gldownload: enumerate emulated video formats

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6792>
This commit is contained in:
Jakub Adam 2024-09-11 18:31:10 +02:00 committed by Nicolas Dufresne
parent 1ef9f6ab26
commit b7970a4d95
6 changed files with 99 additions and 7 deletions

View file

@ -3507,6 +3507,9 @@ extension.</doc>
<member name="linear_only" value="2" c:identifier="GST_GL_DRM_FORMAT_LINEAR_ONLY" version="1.26" glib:nick="linear-only" glib:name="GST_GL_DRM_FORMAT_LINEAR_ONLY">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.h">only include formats with linear modifier</doc>
</member>
<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>
</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

@ -958,7 +958,7 @@ _convert_dma_drm (GstGLContext * context, GstStructure * s)
GValue newfmtval = G_VALUE_INIT;
if (context && gst_gl_dma_buf_transform_drm_formats_to_gst_formats (context,
drmval, 0, &newfmtval)) {
drmval, GST_GL_DRM_FORMAT_INCLUDE_EMULATED, &newfmtval)) {
gst_structure_set_value (s, "format", &newfmtval);
gst_structure_remove_field (s, "drm-format");
g_value_unset (&newfmtval);

View file

@ -489,10 +489,9 @@ gst_egl_image_from_texture (GstGLContext * context, GstGLMemory * gl_mem,
* target.
*/
static int
_drm_rgba_fourcc_from_info (const GstVideoInfo * info, int plane,
_drm_rgba_fourcc_from_format (GstVideoFormat format, int plane,
GstGLFormat * out_format)
{
GstVideoFormat format = GST_VIDEO_INFO_FORMAT (info);
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
const gint rgba_fourcc = DRM_FORMAT_ABGR8888;
const gint rgb_fourcc = DRM_FORMAT_BGR888;
@ -657,7 +656,8 @@ gst_egl_image_from_dmabuf (GstGLContext * context,
gboolean with_modifiers;
gst_video_format_info_component (in_info->finfo, plane, comp);
fourcc = _drm_rgba_fourcc_from_info (in_info, plane, &format);
fourcc = _drm_rgba_fourcc_from_format (GST_VIDEO_INFO_FORMAT (in_info), plane,
&format);
GST_DEBUG ("fourcc %.4s (%d) plane %d (%dx%d)",
(char *) &fourcc, fourcc, plane,
GST_VIDEO_INFO_COMP_WIDTH (in_info, comp[0]),
@ -1096,4 +1096,69 @@ gst_egl_image_export_dmabuf (GstEGLImage * image, int *fd, gint * stride,
return TRUE;
}
/**
* gst_egl_image_can_emulate:
* @context: a #GstGLContext (must be an EGL context)
* @format: a #GstVideoFormat
*
* Checks if the given @context can emulate @format using a limited subset of
* RGB texture formats. Such @format is then suitable for importing using
* gst_egl_image_from_dmabuf() even when GL supports the video format as
* external-only or not at all.
*
* Returns: #TRUE if @format can be emulated
*/
gboolean
gst_egl_image_can_emulate (GstGLContext * context, GstVideoFormat format)
{
const GstVideoFormatInfo *info;
guint i;
GstGLFormat out_format;
info = gst_video_format_get_info (format);
for (i = 0; i != GST_VIDEO_FORMAT_INFO_N_PLANES (info); ++i) {
int fourcc;
fourcc = _drm_rgba_fourcc_from_format (format, i, &out_format);
if (fourcc == -1) {
return FALSE;
}
if (GST_VIDEO_FORMAT_INFO_IS_YUV (info)) {
/* For YUV formats we only support linear modifier. */
if (!gst_gl_context_egl_format_supports_modifier (context, fourcc,
DRM_FORMAT_MOD_LINEAR, FALSE)) {
return FALSE;
}
} else if (GST_VIDEO_FORMAT_INFO_IS_RGB (info)) {
/* For RGB formats any DMA format that is not external-only will do. */
const GArray *dma_modifiers;
guint j;
if (!gst_gl_context_egl_get_format_modifiers (context, fourcc,
&dma_modifiers)) {
return FALSE;
}
for (j = 0; j < dma_modifiers->len; ++j) {
GstGLDmaModifier *mod =
&g_array_index (dma_modifiers, GstGLDmaModifier, j);
if (!mod->external_only) {
break;
}
}
if (j == dma_modifiers->len) {
return FALSE;
}
} else {
return FALSE;
}
}
return TRUE;
}
#endif /* GST_GL_HAVE_DMABUF */

View file

@ -111,6 +111,10 @@ GstEGLImage * gst_egl_image_from_dmabuf_direct_target_with_dma_drm
GstGLTextureTarget target);
GST_GL_API
gboolean gst_egl_image_export_dmabuf (GstEGLImage *image, int *fd, gint *stride, gsize *offset);
GST_GL_API
gboolean gst_egl_image_can_emulate (GstGLContext * context,
GstVideoFormat format);
#endif
/**

View file

@ -47,13 +47,13 @@
#if GST_GL_HAVE_PLATFORM_EGL
#include "egl/gstglcontext_egl.h"
#endif
#include "egl/gsteglimage.h"
#if GST_GL_HAVE_DMABUF
#ifdef HAVE_LIBDRM
#include <drm_fourcc.h>
#endif
#endif
#endif
#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
@ -934,6 +934,7 @@ _append_drm_formats_from_video_format (GstGLContext * context,
GstVideoFormat format, GstGLDrmFormatFlags flags, GPtrArray * drm_formats)
{
gint32 i, fourcc;
gint32 num_added = 0;
const GArray *dma_modifiers = NULL;
char *drm_format;
@ -964,6 +965,14 @@ _append_drm_formats_from_video_format (GstGLContext * context,
drm_format = gst_video_dma_drm_fourcc_to_string (fourcc, mod->modifier);
g_ptr_array_add (drm_formats, drm_format);
++num_added;
}
if (num_added == 0 && (flags & GST_GL_DRM_FORMAT_INCLUDE_EMULATED) &&
gst_egl_image_can_emulate (context, format)) {
drm_format =
gst_video_dma_drm_fourcc_to_string (fourcc, DRM_FORMAT_MOD_LINEAR);
g_ptr_array_add (drm_formats, drm_format);
}
}
#endif
@ -1071,7 +1080,9 @@ _get_video_format_from_drm_format (GstGLContext * context,
return GST_VIDEO_FORMAT_UNKNOWN;
if (!gst_gl_context_egl_format_supports_modifier (context, fourcc, modifier,
flags & GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL))
flags & GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL) &&
!(flags & GST_GL_DRM_FORMAT_INCLUDE_EMULATED &&
gst_egl_image_can_emulate (context, gst_format)))
return GST_VIDEO_FORMAT_UNKNOWN;
return gst_format;

View file

@ -71,6 +71,7 @@ void gst_gl_multiply_matrix4 (const gfloat * a, const gfloat * b, gfloat * resul
* GstGLDrmFormatFlags:
* @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)
*
* Since: 1.26
*/
@ -92,6 +93,14 @@ typedef enum
* Since: 1.26
*/
GST_GL_DRM_FORMAT_LINEAR_ONLY = 1 << 1,
/**
* GST_GL_DRM_FORMAT_INCLUDE_EMULATED:
*
* include emulated formats
*
* Since: 1.26
*/
GST_GL_DRM_FORMAT_INCLUDE_EMULATED = 1 << 2,
} GstGLDrmFormatFlags;
GST_GL_API