mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-04 15:36:35 +00:00
glupload: make _dma_buf_transform_* functions public API
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6792>
This commit is contained in:
parent
57f36ed9d9
commit
d80477d769
4 changed files with 347 additions and 198 deletions
|
@ -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>
|
||||
</member>
|
||||
</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">
|
||||
<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>
|
||||
|
@ -10910,6 +10918,62 @@ multiple times. This must be called before any other #GstGLBuffer operation.</d
|
|||
</parameter>
|
||||
</parameters>
|
||||
</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">
|
||||
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.h"/>
|
||||
<return-value transfer-ownership="none">
|
||||
|
|
|
@ -717,12 +717,6 @@ static const UploadMethod _gl_memory_upload = {
|
|||
|
||||
#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
|
||||
{
|
||||
GstEGLImage *eglimage[GST_VIDEO_MAX_PLANES];
|
||||
|
@ -873,107 +867,6 @@ _dma_buf_upload_new (GstGLUpload * upload)
|
|||
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
|
||||
_check_modifier (GstGLContext * context, guint32 fourcc,
|
||||
guint64 modifier, gboolean include_external)
|
||||
|
@ -1019,93 +912,6 @@ _set_default_formats_list (GstStructure * structure)
|
|||
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
|
||||
_dma_buf_convert_format_field_in_structure (GstGLContext * context,
|
||||
GstStructure * structure, GstPadDirection direction,
|
||||
|
@ -1132,7 +938,7 @@ _dma_buf_convert_format_field_in_structure (GstGLContext * context,
|
|||
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)) {
|
||||
gst_structure_take_value (structure, "drm-format", &drm_formats);
|
||||
} else {
|
||||
|
@ -1157,7 +963,7 @@ _dma_buf_convert_format_field_in_structure (GstGLContext * context,
|
|||
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)) {
|
||||
gst_structure_take_value (structure, "format", &gst_formats);
|
||||
} else {
|
||||
|
@ -1192,7 +998,8 @@ _dma_buf_check_formats_in_structure (GstGLContext * context,
|
|||
if (fourcc == DRM_FORMAT_INVALID)
|
||||
return FALSE;
|
||||
|
||||
if (!_check_modifier (context, fourcc,
|
||||
if (context &&
|
||||
!gst_gl_context_egl_format_supports_modifier (context, fourcc,
|
||||
DRM_FORMAT_MOD_LINEAR, include_external))
|
||||
return FALSE;
|
||||
|
||||
|
@ -1214,7 +1021,8 @@ _dma_buf_check_formats_in_structure (GstGLContext * context,
|
|||
if (fourcc == DRM_FORMAT_INVALID)
|
||||
continue;
|
||||
|
||||
if (!_check_modifier (context, fourcc,
|
||||
if (context &&
|
||||
!gst_gl_context_egl_format_supports_modifier (context, fourcc,
|
||||
DRM_FORMAT_MOD_LINEAR, include_external))
|
||||
continue;
|
||||
|
||||
|
|
|
@ -45,6 +45,16 @@
|
|||
#include <gst/gl/wayland/gstgldisplay_wayland.h>
|
||||
#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_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))
|
||||
|
@ -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 (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
|
||||
}
|
||||
|
|
|
@ -67,6 +67,40 @@ void gst_gl_set_affine_transformation_meta_from_ndc (GstVideoAffineTransformatio
|
|||
GST_GL_API
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in a new issue