[GStreamer] Add support to copy YUV video textures into images
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Sep 2019 14:58:38 +0000 (14:58 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Sep 2019 14:58:38 +0000 (14:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200922

Patch by Chris Lord <clord@igalia.com> on 2019-09-03
Reviewed by Philippe Normand and Xabier Rodriguez-Calvar.

Use gst_gl_color_convert to convert to RGB before using ImageGStreamer
with gstreamer-gl.

No new tests, not changing behavior.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
(WebCore::MediaPlayerPrivateGStreamerBase::paint):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249429 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp
Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h

index 4009258..3a5e187 100644 (file)
@@ -1,5 +1,21 @@
 2019-09-03  Chris Lord  <clord@igalia.com>
 
+        [GStreamer] Add support to copy YUV video textures into images
+        https://bugs.webkit.org/show_bug.cgi?id=200922
+
+        Reviewed by Philippe Normand and Xabier Rodriguez-Calvar.
+
+        Use gst_gl_color_convert to convert to RGB before using ImageGStreamer
+        with gstreamer-gl.
+
+        No new tests, not changing behavior.
+
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
+        (WebCore::MediaPlayerPrivateGStreamerBase::paint):
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
+
+2019-09-03  Chris Lord  <clord@igalia.com>
+
         [GStreamer] Add support to copy YUV video textures into platform textures
         https://bugs.webkit.org/show_bug.cgi?id=200914
 
index 79052a1..77b7e43 100644 (file)
@@ -969,6 +969,50 @@ void MediaPlayerPrivateGStreamerBase::paint(GraphicsContext& context, const Floa
     if (!GST_IS_SAMPLE(m_sample.get()))
         return;
 
+#if USE(GSTREAMER_GL)
+    // Ensure the input is RGBA. We handle YUV video natively, so we need to do
+    // this conversion on-demand here.
+    GstBuffer* buffer = gst_sample_get_buffer(m_sample.get());
+    if (UNLIKELY(!GST_IS_BUFFER(buffer)))
+        return;
+
+    GstCaps* caps = gst_sample_get_caps(m_sample.get());
+
+    GstVideoInfo videoInfo;
+    gst_video_info_init(&videoInfo);
+    if (!gst_video_info_from_caps(&videoInfo, caps))
+        return;
+
+    if (!GST_VIDEO_INFO_IS_RGB(&videoInfo)) {
+        if (!m_colorConvert) {
+            GstMemory* mem = gst_buffer_peek_memory(buffer, 0);
+            GstGLContext* context = ((GstGLBaseMemory*)mem)->context;
+            m_colorConvert = adoptGRef(gst_gl_color_convert_new(context));
+        }
+
+        if (!m_colorConvertInputCaps || !gst_caps_is_equal(m_colorConvertInputCaps.get(), caps)) {
+            m_colorConvertInputCaps = caps;
+            m_colorConvertOutputCaps = adoptGRef(gst_caps_copy(caps));
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+            const gchar* formatString = GST_VIDEO_INFO_HAS_ALPHA(&videoInfo) ? "RGBA" : "BGRx";
+#else
+            const gchar* formatString = GST_VIDEO_INFO_HAS_ALPHA(&videoInfo) ? "RGBA" : "RGBx";
+#endif
+            gst_caps_set_simple(m_colorConvertOutputCaps.get(), "format", G_TYPE_STRING, formatString, nullptr);
+            if (!gst_gl_color_convert_set_caps(m_colorConvert.get(), caps, m_colorConvertOutputCaps.get()))
+                return;
+        }
+
+        GRefPtr<GstBuffer> rgbBuffer = adoptGRef(gst_gl_color_convert_perform(m_colorConvert.get(), buffer));
+        if (UNLIKELY(!GST_IS_BUFFER(rgbBuffer.get())))
+            return;
+
+        const GstStructure* info = gst_sample_get_info(m_sample.get());
+        m_sample = adoptGRef(gst_sample_new(rgbBuffer.get(), m_colorConvertOutputCaps.get(),
+            gst_sample_get_segment(m_sample.get()), info ? gst_structure_copy(info) : nullptr));
+    }
+#endif
+
     auto gstImage = ImageGStreamer::createImage(m_sample.get());
     if (!gstImage)
         return;
index 82929cf..3ea1d10 100644 (file)
@@ -296,6 +296,10 @@ protected:
     GRefPtr<GstContext> m_glDisplayElementContext;
     GRefPtr<GstContext> m_glAppElementContext;
     std::unique_ptr<VideoTextureCopierGStreamer> m_videoTextureCopier;
+
+    GRefPtr<GstGLColorConvert> m_colorConvert;
+    GRefPtr<GstCaps> m_colorConvertInputCaps;
+    GRefPtr<GstCaps> m_colorConvertOutputCaps;
 #endif
 
     ImageOrientation m_videoSourceOrientation;