From 6dd3d6f1c1123e12ac7f314dc7bccdecc1722ac1 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Fri, 19 May 2023 16:25:28 +0800 Subject: [PATCH] glupload: add a helper function to convert gst formats into drm formats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Víctor Manuel Jáquez Leal Part-of: --- .../gst-libs/gst/gl/gstglupload.c | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglupload.c b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglupload.c index 15530a12da..a45ef76009 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglupload.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglupload.c @@ -38,6 +38,7 @@ #if GST_GL_HAVE_DMABUF #include +#include #endif #if GST_GL_HAVE_VIV_DIRECTVIV @@ -638,6 +639,104 @@ _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, gboolean include_external, 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, we just consider it as linear and external_only. */ + if (!dma_modifiers) { + if (include_external) { + drm_format = + gst_video_dma_drm_fourcc_to_string (fourcc, DRM_FORMAT_MOD_LINEAR); + g_ptr_array_add (drm_formats, drm_format); + } + return; + } + + for (i = 0; i < dma_modifiers->len; i++) { + GstGLDmaModifier *mod = &g_array_index (dma_modifiers, GstGLDmaModifier, i); + + if (!mod->external_only || include_external) { + 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, gboolean include_external, 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, + include_external, 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, + include_external, 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 GstCaps * _dma_buf_upload_transform_caps (gpointer impl, GstGLContext * context, GstPadDirection direction, GstCaps * caps)