glupload: add a helper function to convert drm formats into gst formats

Co-authored-by: Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3524>
This commit is contained in:
He Junyan 2023-05-19 19:25:15 +08:00 committed by GStreamer Marge Bot
parent 6dd3d6f1c1
commit 95707bb80d

View file

@ -737,6 +737,124 @@ _dma_buf_transform_gst_formats_to_drm_formats (GstGLContext * context,
return TRUE;
}
static gboolean
_check_modifier (GstGLContext * context, guint32 fourcc,
guint64 modifier, gboolean include_external)
{
const GArray *dma_modifiers;
guint i;
/* If no context provide, no further check. */
if (!context)
return TRUE;
if (!gst_gl_context_egl_get_format_modifiers (context, fourcc,
&dma_modifiers))
return FALSE;
if (!dma_modifiers) {
/* recognize the fourcc but no modifier info, consider it as linear */
if (modifier == DRM_FORMAT_MOD_LINEAR)
return TRUE;
return FALSE;
}
for (i = 0; i < dma_modifiers->len; i++) {
GstGLDmaModifier *mod = &g_array_index (dma_modifiers, GstGLDmaModifier, i);
if (!mod->external_only || include_external) {
if (mod->modifier == modifier)
return TRUE;
}
}
return FALSE;
}
static GstVideoFormat
_get_video_format_from_drm_format (GstGLContext * context,
const gchar * drm_format, gboolean include_external)
{
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;
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, 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, gboolean include_external, 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), include_external);
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), include_external);
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 GstCaps *
_dma_buf_upload_transform_caps (gpointer impl, GstGLContext * context,
GstPadDirection direction, GstCaps * caps)