From f3519820672d1320edc2cf5d6efb83e1097de8bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Thu, 12 May 2022 17:55:38 +0200 Subject: [PATCH] plugin: Handle premultiplied alpha in RAW frames Add support for premultiplied alpha flag detection when creating GdkMemoryTextures. Also check if overlays have premultiplied alpha and if they do set this flag for their video info, so it will be detected when creating a GdkMemoryTexture out of them. Fixes performance issues with karaoke subtitles, as now GTK does not have to perform unnecessary multiplication. --- lib/gst/plugin/gstclapperimporter.c | 3 +++ lib/gst/plugin/gstgtkutils.c | 28 +++++++++++++++++++--------- lib/gst/plugin/gstgtkutils.h | 2 -- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/lib/gst/plugin/gstclapperimporter.c b/lib/gst/plugin/gstclapperimporter.c index 035b0e44..2bc0f1d0 100644 --- a/lib/gst/plugin/gstclapperimporter.c +++ b/lib/gst/plugin/gstclapperimporter.c @@ -248,6 +248,9 @@ gst_clapper_importer_prepare_overlays_locked (GstClapperImporter *self) if ((v_meta = gst_buffer_get_video_meta (comp_buffer))) { gst_video_info_set_format (&v_info, v_meta->format, v_meta->width, v_meta->height); v_info.stride[0] = v_meta->stride[0]; + + if (alpha_flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA) + v_info.flags |= GST_VIDEO_FLAG_PREMULTIPLIED_ALPHA; } if (G_UNLIKELY (!gst_video_frame_map (&comp_frame, &v_info, comp_buffer, GST_MAP_READ))) diff --git a/lib/gst/plugin/gstgtkutils.c b/lib/gst/plugin/gstgtkutils.c index 4100a9d7..19cf233b 100644 --- a/lib/gst/plugin/gstgtkutils.c +++ b/lib/gst/plugin/gstgtkutils.c @@ -22,6 +22,8 @@ #include "gstgtkutils.h" +#define _IS_FRAME_PREMULTIPLIED(f) (GST_VIDEO_INFO_FLAG_IS_SET (&(f)->info, GST_VIDEO_FLAG_PREMULTIPLIED_ALPHA)) + struct invoke_context { GThreadFunc func; @@ -71,21 +73,29 @@ gst_gtk_invoke_on_main (GThreadFunc func, gpointer data) return info.res; } -/* For use with `GdkMemoryTexture` only! */ -GdkMemoryFormat -gst_video_format_to_gdk_memory_format (GstVideoFormat format) +static GdkMemoryFormat +gst_gdk_memory_format_from_frame (GstVideoFrame *frame) { - switch (format) { + switch (GST_VIDEO_FRAME_FORMAT (frame)) { case GST_VIDEO_FORMAT_RGBA64_LE: case GST_VIDEO_FORMAT_RGBA64_BE: - return GDK_MEMORY_R16G16B16A16_PREMULTIPLIED; + return (_IS_FRAME_PREMULTIPLIED (frame)) + ? GDK_MEMORY_R16G16B16A16_PREMULTIPLIED + : GDK_MEMORY_R16G16B16A16; case GST_VIDEO_FORMAT_RGBA: - return GDK_MEMORY_R8G8B8A8; + return (_IS_FRAME_PREMULTIPLIED (frame)) + ? GDK_MEMORY_R8G8B8A8_PREMULTIPLIED + : GDK_MEMORY_R8G8B8A8; case GST_VIDEO_FORMAT_BGRA: - return GDK_MEMORY_B8G8R8A8; + return (_IS_FRAME_PREMULTIPLIED (frame)) + ? GDK_MEMORY_B8G8R8A8_PREMULTIPLIED + : GDK_MEMORY_B8G8R8A8; case GST_VIDEO_FORMAT_ARGB: - return GDK_MEMORY_A8R8G8B8; + return (_IS_FRAME_PREMULTIPLIED (frame)) + ? GDK_MEMORY_A8R8G8B8_PREMULTIPLIED + : GDK_MEMORY_A8R8G8B8; case GST_VIDEO_FORMAT_ABGR: + /* GTK is missing premultiplied ABGR support */ return GDK_MEMORY_A8B8G8R8; case GST_VIDEO_FORMAT_RGBx: return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; @@ -122,7 +132,7 @@ gst_video_frame_into_gdk_texture (GstVideoFrame *frame) texture = gdk_memory_texture_new ( GST_VIDEO_FRAME_WIDTH (frame), GST_VIDEO_FRAME_HEIGHT (frame), - gst_video_format_to_gdk_memory_format (GST_VIDEO_FRAME_FORMAT (frame)), + gst_gdk_memory_format_from_frame (frame), bytes, GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0)); diff --git a/lib/gst/plugin/gstgtkutils.h b/lib/gst/plugin/gstgtkutils.h index 5ef26144..3e8fa5dc 100644 --- a/lib/gst/plugin/gstgtkutils.h +++ b/lib/gst/plugin/gstgtkutils.h @@ -30,8 +30,6 @@ G_BEGIN_DECLS gpointer gst_gtk_invoke_on_main (GThreadFunc func, gpointer data); -GdkMemoryFormat gst_video_format_to_gdk_memory_format (GstVideoFormat format); - GdkTexture * gst_video_frame_into_gdk_texture (GstVideoFrame *frame); G_END_DECLS