diff --git a/girs/GstGL-1.0.gir b/girs/GstGL-1.0.gir index 8282637e5d..e9fd842c10 100644 --- a/girs/GstGL-1.0.gir +++ b/girs/GstGL-1.0.gir @@ -3507,6 +3507,9 @@ extension. only include formats with linear modifier + + include emulated formats + #GstGLFilter helps to implement simple OpenGL filter elements taking a diff --git a/subprojects/gst-plugins-base/ext/gl/gstgldownloadelement.c b/subprojects/gst-plugins-base/ext/gl/gstgldownloadelement.c index 6c0e91c63c..00e63c9a1a 100644 --- a/subprojects/gst-plugins-base/ext/gl/gstgldownloadelement.c +++ b/subprojects/gst-plugins-base/ext/gl/gstgldownloadelement.c @@ -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); diff --git a/subprojects/gst-plugins-base/gst-libs/gst/gl/egl/gsteglimage.c b/subprojects/gst-plugins-base/gst-libs/gst/gl/egl/gsteglimage.c index c3ee82afdb..1dc4e9064c 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/gl/egl/gsteglimage.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/gl/egl/gsteglimage.c @@ -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 */ diff --git a/subprojects/gst-plugins-base/gst-libs/gst/gl/egl/gsteglimage.h b/subprojects/gst-plugins-base/gst-libs/gst/gl/egl/gsteglimage.h index b34607d40c..c69d65a768 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/gl/egl/gsteglimage.h +++ b/subprojects/gst-plugins-base/gst-libs/gst/gl/egl/gsteglimage.h @@ -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 /** diff --git a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c index cae5942e1e..71a3c93081 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c @@ -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 #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; diff --git a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.h b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.h index 9258cdc64f..78d4091c1e 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.h +++ b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.h @@ -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