glupload: make _dma_buf_transform_* functions public API

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6792>
This commit is contained in:
Jakub Adam 2024-08-29 17:22:53 +02:00 committed by Nicolas Dufresne
parent 57f36ed9d9
commit d80477d769
4 changed files with 347 additions and 198 deletions

View file

@ -3500,6 +3500,14 @@ extension.</doc>
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstgldisplay.h">any display type</doc> <doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstgldisplay.h">any display type</doc>
</member> </member>
</bitfield> </bitfield>
<bitfield name="GLDrmFormatFlags" version="1.26" glib:type-name="GstGLDrmFormatFlags" glib:get-type="gst_gl_drm_format_flags_get_type" c:type="GstGLDrmFormatFlags">
<member name="include_external" value="1" c:identifier="GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL" version="1.26" glib:nick="include-external" glib:name="GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.h">include external-only formats</doc>
</member>
<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>
</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"> <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 <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
single input and producing a single output with a #GstGLFramebuffer</doc> single input and producing a single output with a #GstGLFramebuffer</doc>
@ -10910,6 +10918,62 @@ multiple times. This must be called before any other #GstGLBuffer operation.</d
</parameter> </parameter>
</parameters> </parameters>
</function-macro> </function-macro>
<function name="gl_dma_buf_transform_drm_formats_to_gst_formats" c:identifier="gst_gl_dma_buf_transform_drm_formats_to_gst_formats" version="1.26">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c">Given the DRM formats in @src #GValue, collect corresponding GST formats to
@dst #GValue. This function returns %FALSE if the context is not an EGL
context.</doc>
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.h"/>
<return-value transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c">whether any valid GST video formats were found and stored in @dst</doc>
<type name="gboolean" c:type="gboolean"/>
</return-value>
<parameters>
<parameter name="context" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c">a #GstContext</doc>
<type name="GLContext" c:type="GstGLContext*"/>
</parameter>
<parameter name="src" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c">value of "drm-format" field in #GstCaps as #GValue</doc>
<type name="GObject.Value" c:type="const GValue*"/>
</parameter>
<parameter name="flags" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c">transformation flags</doc>
<type name="GLDrmFormatFlags" c:type="GstGLDrmFormatFlags"/>
</parameter>
<parameter name="dst" direction="inout" caller-allocates="0" transfer-ownership="full">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c">empty destination #GValue</doc>
<type name="GObject.Value" c:type="GValue*"/>
</parameter>
</parameters>
</function>
<function name="gl_dma_buf_transform_gst_formats_to_drm_formats" c:identifier="gst_gl_dma_buf_transform_gst_formats_to_drm_formats" version="1.26">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c">Given the video formats in @src #GValue, collect corresponding drm formats
supported by @context into @dst #GValue. This function returns %FALSE if
the context is not an EGL context.</doc>
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.h"/>
<return-value transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c">whether any valid drm formats were found and stored in @dst</doc>
<type name="gboolean" c:type="gboolean"/>
</return-value>
<parameters>
<parameter name="context" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c">a #GstContext</doc>
<type name="GLContext" c:type="GstGLContext*"/>
</parameter>
<parameter name="src" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c">value of "format" field in #GstCaps as #GValue</doc>
<type name="GObject.Value" c:type="const GValue*"/>
</parameter>
<parameter name="flags" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c">transformation flags</doc>
<type name="GLDrmFormatFlags" c:type="GstGLDrmFormatFlags"/>
</parameter>
<parameter name="dst" direction="inout" caller-allocates="0" transfer-ownership="full">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c">empty destination #GValue</doc>
<type name="GObject.Value" c:type="GValue*"/>
</parameter>
</parameters>
</function>
<function name="gl_element_propagate_display_context" c:identifier="gst_gl_element_propagate_display_context"> <function name="gl_element_propagate_display_context" c:identifier="gst_gl_element_propagate_display_context">
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.h"/> <source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.h"/>
<return-value transfer-ownership="none"> <return-value transfer-ownership="none">

View file

@ -717,12 +717,6 @@ static const UploadMethod _gl_memory_upload = {
#if GST_GL_HAVE_DMABUF #if GST_GL_HAVE_DMABUF
typedef enum
{
GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL = 1 << 1,
GST_GL_DRM_FORMAT_LINEAR_ONLY = 2 << 1,
} GstGLDrmFormatFlags;
typedef struct _GstEGLImageCacheEntry typedef struct _GstEGLImageCacheEntry
{ {
GstEGLImage *eglimage[GST_VIDEO_MAX_PLANES]; GstEGLImage *eglimage[GST_VIDEO_MAX_PLANES];
@ -873,107 +867,6 @@ _dma_buf_upload_new (GstGLUpload * upload)
return dmabuf; return dmabuf;
} }
/* Append all drm format strings to drm_formats array. */
static void
_append_drm_formats_from_video_format (GstGLContext * context,
GstVideoFormat format, GstGLDrmFormatFlags flags,
GPtrArray * drm_formats)
{
gint32 i, fourcc;
const GArray *dma_modifiers = NULL;
char *drm_format;
fourcc = gst_video_dma_drm_fourcc_from_format (format);
if (fourcc == DRM_FORMAT_INVALID)
return;
if (!gst_gl_context_egl_get_format_modifiers (context, fourcc,
&dma_modifiers))
return;
/* No modifier info, lets warn and move on */
if (!dma_modifiers) {
GST_WARNING_OBJECT (context, "Undefined modifiers list for %"
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));
return;
}
for (i = 0; i < dma_modifiers->len; i++) {
GstGLDmaModifier *mod = &g_array_index (dma_modifiers, GstGLDmaModifier, i);
if (!(flags & GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL) && mod->external_only)
continue;
if (flags & GST_GL_DRM_FORMAT_LINEAR_ONLY && mod->modifier != DRM_FORMAT_MOD_LINEAR)
continue;
drm_format = gst_video_dma_drm_fourcc_to_string (fourcc, mod->modifier);
g_ptr_array_add (drm_formats, drm_format);
}
}
/* Given the video formats in src GValue, collecting all the according
drm formats to dst GValue. Return FALSE if no valid drm formats found. */
static gboolean
_dma_buf_transform_gst_formats_to_drm_formats (GstGLContext * context,
const GValue * video_value, GstGLDrmFormatFlags flags,
GValue * drm_value)
{
GstVideoFormat gst_format;
GPtrArray *all_drm_formats = NULL;
guint i;
all_drm_formats = g_ptr_array_new ();
if (G_VALUE_HOLDS_STRING (video_value)) {
gst_format =
gst_video_format_from_string (g_value_get_string (video_value));
if (gst_format != GST_VIDEO_FORMAT_UNKNOWN) {
_append_drm_formats_from_video_format (context, gst_format,
flags, all_drm_formats);
}
} else if (GST_VALUE_HOLDS_LIST (video_value)) {
guint num_values = gst_value_list_get_size (video_value);
for (i = 0; i < num_values; i++) {
const GValue *val = gst_value_list_get_value (video_value, i);
gst_format = gst_video_format_from_string (g_value_get_string (val));
if (gst_format == GST_VIDEO_FORMAT_UNKNOWN)
continue;
_append_drm_formats_from_video_format (context, gst_format,
flags, all_drm_formats);
}
}
if (all_drm_formats->len == 0) {
g_ptr_array_unref (all_drm_formats);
return FALSE;
}
if (all_drm_formats->len == 1) {
g_value_init (drm_value, G_TYPE_STRING);
g_value_take_string (drm_value, g_ptr_array_index (all_drm_formats, 0));
} else {
GValue item = G_VALUE_INIT;
gst_value_list_init (drm_value, all_drm_formats->len);
for (i = 0; i < all_drm_formats->len; i++) {
g_value_init (&item, G_TYPE_STRING);
g_value_take_string (&item, g_ptr_array_index (all_drm_formats, i));
gst_value_list_append_value (drm_value, &item);
g_value_unset (&item);
}
}
/* The strings are already token by the GValue, no need to free. */
g_ptr_array_unref (all_drm_formats);
return TRUE;
}
static gboolean static gboolean
_check_modifier (GstGLContext * context, guint32 fourcc, _check_modifier (GstGLContext * context, guint32 fourcc,
guint64 modifier, gboolean include_external) guint64 modifier, gboolean include_external)
@ -1019,93 +912,6 @@ _set_default_formats_list (GstStructure * structure)
gst_structure_take_value (structure, "format", &formats); gst_structure_take_value (structure, "format", &formats);
} }
static GstVideoFormat
_get_video_format_from_drm_format (GstGLContext * context,
const gchar * drm_format, GstGLDrmFormatFlags flags)
{
GstVideoFormat gst_format;
guint32 fourcc;
guint64 modifier;
fourcc = gst_video_dma_drm_fourcc_from_string (drm_format, &modifier);
if (fourcc == DRM_FORMAT_INVALID)
return GST_VIDEO_FORMAT_UNKNOWN;
if (flags & GST_GL_DRM_FORMAT_LINEAR_ONLY && modifier != DRM_FORMAT_MOD_LINEAR)
return GST_VIDEO_FORMAT_UNKNOWN;
gst_format = gst_video_dma_drm_fourcc_to_format (fourcc);
if (gst_format == GST_VIDEO_FORMAT_UNKNOWN)
return GST_VIDEO_FORMAT_UNKNOWN;
if (!_check_modifier (context, fourcc, modifier, flags & GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL))
return GST_VIDEO_FORMAT_UNKNOWN;
return gst_format;
}
/* Given the drm formats in src GValue, collecting all the according
gst formats to dst GValue. Return FALSE if no valid drm formats found. */
static gboolean
_dma_buf_transform_drm_formats_to_gst_formats (GstGLContext * context,
const GValue * drm_value, GstGLDrmFormatFlags flags,
GValue * video_value)
{
GstVideoFormat gst_format;
GArray *all_formats = NULL;
guint i;
all_formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat));
if (G_VALUE_HOLDS_STRING (drm_value)) {
gst_format = _get_video_format_from_drm_format (context,
g_value_get_string (drm_value), flags);
if (gst_format != GST_VIDEO_FORMAT_UNKNOWN)
g_array_append_val (all_formats, gst_format);
} else if (GST_VALUE_HOLDS_LIST (drm_value)) {
guint num_values = gst_value_list_get_size (drm_value);
for (i = 0; i < num_values; i++) {
const GValue *val = gst_value_list_get_value (drm_value, i);
gst_format = _get_video_format_from_drm_format (context,
g_value_get_string (val), flags);
if (gst_format == GST_VIDEO_FORMAT_UNKNOWN)
continue;
g_array_append_val (all_formats, gst_format);
}
}
if (all_formats->len == 0) {
g_array_unref (all_formats);
return FALSE;
}
if (all_formats->len == 1) {
g_value_init (video_value, G_TYPE_STRING);
gst_format = g_array_index (all_formats, GstVideoFormat, 0);
g_value_set_string (video_value, gst_video_format_to_string (gst_format));
} else {
GValue item = G_VALUE_INIT;
gst_value_list_init (video_value, all_formats->len);
for (i = 0; i < all_formats->len; i++) {
g_value_init (&item, G_TYPE_STRING);
gst_format = g_array_index (all_formats, GstVideoFormat, i);
g_value_set_string (&item, gst_video_format_to_string (gst_format));
gst_value_list_append_value (video_value, &item);
g_value_unset (&item);
}
}
g_array_unref (all_formats);
return TRUE;
}
static gboolean static gboolean
_dma_buf_convert_format_field_in_structure (GstGLContext * context, _dma_buf_convert_format_field_in_structure (GstGLContext * context,
GstStructure * structure, GstPadDirection direction, GstStructure * structure, GstPadDirection direction,
@ -1132,7 +938,7 @@ _dma_buf_convert_format_field_in_structure (GstGLContext * context,
val = gst_structure_get_value (structure, "format"); val = gst_structure_get_value (structure, "format");
} }
if (_dma_buf_transform_gst_formats_to_drm_formats (context, if (gst_gl_dma_buf_transform_gst_formats_to_drm_formats (context,
val, flags, &drm_formats)) { val, flags, &drm_formats)) {
gst_structure_take_value (structure, "drm-format", &drm_formats); gst_structure_take_value (structure, "drm-format", &drm_formats);
} else { } else {
@ -1157,7 +963,7 @@ _dma_buf_convert_format_field_in_structure (GstGLContext * context,
return TRUE; return TRUE;
} }
if (_dma_buf_transform_drm_formats_to_gst_formats (context, if (gst_gl_dma_buf_transform_drm_formats_to_gst_formats (context,
val, flags, &gst_formats)) { val, flags, &gst_formats)) {
gst_structure_take_value (structure, "format", &gst_formats); gst_structure_take_value (structure, "format", &gst_formats);
} else { } else {
@ -1192,7 +998,8 @@ _dma_buf_check_formats_in_structure (GstGLContext * context,
if (fourcc == DRM_FORMAT_INVALID) if (fourcc == DRM_FORMAT_INVALID)
return FALSE; return FALSE;
if (!_check_modifier (context, fourcc, if (context &&
!gst_gl_context_egl_format_supports_modifier (context, fourcc,
DRM_FORMAT_MOD_LINEAR, include_external)) DRM_FORMAT_MOD_LINEAR, include_external))
return FALSE; return FALSE;
@ -1214,7 +1021,8 @@ _dma_buf_check_formats_in_structure (GstGLContext * context,
if (fourcc == DRM_FORMAT_INVALID) if (fourcc == DRM_FORMAT_INVALID)
continue; continue;
if (!_check_modifier (context, fourcc, if (context &&
!gst_gl_context_egl_format_supports_modifier (context, fourcc,
DRM_FORMAT_MOD_LINEAR, include_external)) DRM_FORMAT_MOD_LINEAR, include_external))
continue; continue;

View file

@ -45,6 +45,16 @@
#include <gst/gl/wayland/gstgldisplay_wayland.h> #include <gst/gl/wayland/gstgldisplay_wayland.h>
#endif #endif
#if GST_GL_HAVE_PLATFORM_EGL
#include "egl/gstglcontext_egl.h"
#endif
#if GST_GL_HAVE_DMABUF
#ifdef HAVE_LIBDRM
#include <drm_fourcc.h>
#endif
#endif
#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0)) #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)) #define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0)) #define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
@ -916,3 +926,236 @@ void gst_gl_set_affine_transformation_meta_from_ndc
gst_gl_multiply_matrix4 (to_ndc_matrix, matrix, tmp); gst_gl_multiply_matrix4 (to_ndc_matrix, matrix, tmp);
gst_gl_multiply_matrix4 (tmp, from_ndc_matrix, meta->matrix); gst_gl_multiply_matrix4 (tmp, from_ndc_matrix, meta->matrix);
} }
#ifdef HAVE_LIBDRM
/* Append all drm format strings to drm_formats array. */
static void
_append_drm_formats_from_video_format (GstGLContext * context,
GstVideoFormat format, GstGLDrmFormatFlags flags, GPtrArray * drm_formats)
{
gint32 i, fourcc;
const GArray *dma_modifiers = NULL;
char *drm_format;
fourcc = gst_video_dma_drm_fourcc_from_format (format);
if (fourcc == DRM_FORMAT_INVALID)
return;
if (!gst_gl_context_egl_get_format_modifiers (context, fourcc,
&dma_modifiers))
return;
/* No modifier info, lets warn and move on */
if (!dma_modifiers) {
GST_WARNING_OBJECT (context, "Undefined modifiers list for %"
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));
return;
}
for (i = 0; i < dma_modifiers->len; i++) {
GstGLDmaModifier *mod = &g_array_index (dma_modifiers, GstGLDmaModifier, i);
if (!(flags & GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL) && mod->external_only)
continue;
if (flags & GST_GL_DRM_FORMAT_LINEAR_ONLY &&
mod->modifier != DRM_FORMAT_MOD_LINEAR)
continue;
drm_format = gst_video_dma_drm_fourcc_to_string (fourcc, mod->modifier);
g_ptr_array_add (drm_formats, drm_format);
}
}
#endif
/**
* gst_gl_dma_buf_transform_gst_formats_to_drm_formats:
* @context: (transfer none): a #GstContext
* @src: value of "format" field in #GstCaps as #GValue
* @flags: transformation flags
* @dst: (inout): empty destination #GValue
*
* Given the video formats in @src #GValue, collect corresponding drm formats
* supported by @context into @dst #GValue. This function returns %FALSE if
* the context is not an EGL context.
*
* Returns: whether any valid drm formats were found and stored in @dst
*
* Since: 1.26
*/
gboolean
gst_gl_dma_buf_transform_gst_formats_to_drm_formats (GstGLContext * context,
const GValue * src, GstGLDrmFormatFlags flags, GValue * dst)
{
#ifdef HAVE_LIBDRM
GstVideoFormat gst_format;
GPtrArray *all_drm_formats = NULL;
guint i;
/* This is only supported with EGL */
if (!GST_IS_GL_CONTEXT_EGL (context))
return FALSE;
all_drm_formats = g_ptr_array_new ();
if (G_VALUE_HOLDS_STRING (src)) {
gst_format = gst_video_format_from_string (g_value_get_string (src));
if (gst_format != GST_VIDEO_FORMAT_UNKNOWN) {
_append_drm_formats_from_video_format (context, gst_format,
flags, all_drm_formats);
}
} else if (GST_VALUE_HOLDS_LIST (src)) {
guint num_values = gst_value_list_get_size (src);
for (i = 0; i < num_values; i++) {
const GValue *val = gst_value_list_get_value (src, i);
gst_format = gst_video_format_from_string (g_value_get_string (val));
if (gst_format == GST_VIDEO_FORMAT_UNKNOWN)
continue;
_append_drm_formats_from_video_format (context, gst_format,
flags, all_drm_formats);
}
}
if (all_drm_formats->len == 0) {
g_ptr_array_unref (all_drm_formats);
return FALSE;
}
if (all_drm_formats->len == 1) {
g_value_init (dst, G_TYPE_STRING);
g_value_take_string (dst, g_ptr_array_index (all_drm_formats, 0));
} else {
GValue item = G_VALUE_INIT;
gst_value_list_init (dst, all_drm_formats->len);
for (i = 0; i < all_drm_formats->len; i++) {
g_value_init (&item, G_TYPE_STRING);
g_value_take_string (&item, g_ptr_array_index (all_drm_formats, i));
gst_value_list_append_value (dst, &item);
g_value_unset (&item);
}
}
/* The strings are already taken by the GValue, no need to free. */
g_ptr_array_unref (all_drm_formats);
return TRUE;
#else
return FALSE;
#endif
}
#ifdef HAVE_LIBDRM
static GstVideoFormat
_get_video_format_from_drm_format (GstGLContext * context,
const gchar * drm_format, GstGLDrmFormatFlags flags)
{
GstVideoFormat gst_format;
guint32 fourcc;
guint64 modifier;
fourcc = gst_video_dma_drm_fourcc_from_string (drm_format, &modifier);
if (fourcc == DRM_FORMAT_INVALID)
return GST_VIDEO_FORMAT_UNKNOWN;
if (flags & GST_GL_DRM_FORMAT_LINEAR_ONLY &&
modifier != DRM_FORMAT_MOD_LINEAR)
return GST_VIDEO_FORMAT_UNKNOWN;
gst_format = gst_video_dma_drm_fourcc_to_format (fourcc);
if (gst_format == GST_VIDEO_FORMAT_UNKNOWN)
return GST_VIDEO_FORMAT_UNKNOWN;
if (!gst_gl_context_egl_format_supports_modifier (context, fourcc, modifier,
flags & GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL))
return GST_VIDEO_FORMAT_UNKNOWN;
return gst_format;
}
#endif
/**
* gst_gl_dma_buf_transform_drm_formats_to_gst_formats:
* @context: (transfer none): a #GstContext
* @src: value of "drm-format" field in #GstCaps as #GValue
* @flags: transformation flags
* @dst: (inout): empty destination #GValue
*
* Given the DRM formats in @src #GValue, collect corresponding GST formats to
* @dst #GValue. This function returns %FALSE if the context is not an EGL
* context.
*
* Returns: whether any valid GST video formats were found and stored in @dst
*
* Since: 1.26
*/
gboolean
gst_gl_dma_buf_transform_drm_formats_to_gst_formats (GstGLContext * context,
const GValue * src, GstGLDrmFormatFlags flags, GValue * dst)
{
#ifdef HAVE_LIBDRM
GstVideoFormat gst_format;
GArray *all_formats = NULL;
guint i;
/* This is only supported with EGL */
if (!GST_IS_GL_CONTEXT_EGL (context))
return FALSE;
all_formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat));
if (G_VALUE_HOLDS_STRING (src)) {
gst_format = _get_video_format_from_drm_format (context,
g_value_get_string (src), flags);
if (gst_format != GST_VIDEO_FORMAT_UNKNOWN)
g_array_append_val (all_formats, gst_format);
} else if (GST_VALUE_HOLDS_LIST (src)) {
guint num_values = gst_value_list_get_size (src);
for (i = 0; i < num_values; i++) {
const GValue *val = gst_value_list_get_value (src, i);
gst_format = _get_video_format_from_drm_format (context,
g_value_get_string (val), flags);
if (gst_format == GST_VIDEO_FORMAT_UNKNOWN)
continue;
g_array_append_val (all_formats, gst_format);
}
}
if (all_formats->len == 0) {
g_array_unref (all_formats);
return FALSE;
}
if (all_formats->len == 1) {
g_value_init (dst, G_TYPE_STRING);
gst_format = g_array_index (all_formats, GstVideoFormat, 0);
g_value_set_string (dst, gst_video_format_to_string (gst_format));
} else {
GValue item = G_VALUE_INIT;
gst_value_list_init (dst, all_formats->len);
for (i = 0; i < all_formats->len; i++) {
g_value_init (&item, G_TYPE_STRING);
gst_format = g_array_index (all_formats, GstVideoFormat, i);
g_value_set_string (&item, gst_video_format_to_string (gst_format));
gst_value_list_append_value (dst, &item);
g_value_unset (&item);
}
}
g_array_unref (all_formats);
return TRUE;
#else
return FALSE;
#endif
}

View file

@ -67,6 +67,40 @@ void gst_gl_set_affine_transformation_meta_from_ndc (GstVideoAffineTransformatio
GST_GL_API GST_GL_API
void gst_gl_multiply_matrix4 (const gfloat * a, const gfloat * b, gfloat * result); void gst_gl_multiply_matrix4 (const gfloat * a, const gfloat * b, gfloat * result);
/**
* 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)
*
* Since: 1.26
*/
typedef enum
{
/**
* GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL:
*
* include external-only formats
*
* Since: 1.26
*/
GST_GL_DRM_FORMAT_INCLUDE_EXTERNAL = 1 << 0,
/**
* GST_GL_DRM_FORMAT_LINEAR_ONLY:
*
* only include formats with linear modifier
*
* Since: 1.26
*/
GST_GL_DRM_FORMAT_LINEAR_ONLY = 1 << 1,
} GstGLDrmFormatFlags;
GST_GL_API
gboolean gst_gl_dma_buf_transform_gst_formats_to_drm_formats (GstGLContext * context,
const GValue * src, GstGLDrmFormatFlags flags, GValue * dst);
GST_GL_API
gboolean gst_gl_dma_buf_transform_drm_formats_to_gst_formats (GstGLContext * context,
const GValue * src, GstGLDrmFormatFlags flags, GValue * dst);
G_END_DECLS G_END_DECLS