Skip to content

Instantly share code, notes, and snippets.

@ObserverHerb
Created January 23, 2017 04:26
Show Gist options
  • Save ObserverHerb/f91fddcc01b380af84b7f8e7746cdafd to your computer and use it in GitHub Desktop.
Save ObserverHerb/f91fddcc01b380af84b7f8e7746cdafd to your computer and use it in GitHub Desktop.
Connect <video> tag to gstreamer vaapisink
diff --git a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
index f952ad6..c8249b2 100644
--- a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
+++ b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
@@ -60,7 +60,8 @@ class ImageGStreamer : public RefCounted<ImageGStreamer> {
}
private:
- ImageGStreamer(GstSample*);
+ ImageGStreamer(GstBuffer* buffer, GstCaps* caps);
+ ImageGStreamer(GstSample* sample) : ImageGStreamer(gst_sample_get_buffer(sample), gst_sample_get_caps(sample)) { }
RefPtr<BitmapImage> m_image;
FloatRect m_cropRect;
diff --git a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
index ee27277..ade6d2a 100644
--- a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
@@ -32,9 +32,8 @@
using namespace std;
using namespace WebCore;
-ImageGStreamer::ImageGStreamer(GstSample* sample)
+ImageGStreamer::ImageGStreamer(GstBuffer* buffer, GstCaps* caps)
{
- GstCaps* caps = gst_sample_get_caps(sample);
GstVideoInfo videoInfo;
gst_video_info_init(&videoInfo);
if (!gst_video_info_from_caps(&videoInfo, caps))
@@ -43,7 +42,6 @@ ImageGStreamer::ImageGStreamer(GstSample* sample)
// Right now the TextureMapper only supports chromas with one plane
ASSERT(GST_VIDEO_INFO_N_PLANES(&videoInfo) == 1);
- GstBuffer* buffer = gst_sample_get_buffer(sample);
if (!gst_video_frame_map(&m_videoFrame, &videoInfo, buffer, GST_MAP_READ))
return;
diff --git a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp
index 20ce58e..d252c06 100644
--- a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp
@@ -32,9 +32,8 @@
using namespace std;
using namespace WebCore;
-ImageGStreamer::ImageGStreamer(GstSample* sample)
+ImageGStreamer::ImageGStreamer(GstBuffer* buffer, GstCaps* caps)
{
- GstCaps* caps = gst_sample_get_caps(sample);
GstVideoInfo videoInfo;
gst_video_info_init(&videoInfo);
if (!gst_video_info_from_caps(&videoInfo, caps))
@@ -44,7 +43,6 @@ ImageGStreamer::ImageGStreamer(GstSample* sample)
// Right now the TextureMapper only supports chromas with one plane
ASSERT(GST_VIDEO_INFO_N_PLANES(&videoInfo) == 1);
- GstBuffer* buffer = gst_sample_get_buffer(sample);
if (!gst_video_frame_map(&m_videoFrame, &videoInfo, buffer, GST_MAP_READ))
return;
diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp
index 310a022..7ee25b3 100644
--- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp
@@ -589,6 +589,22 @@ gboolean MediaPlayerPrivateGStreamerBase::drawCallback(MediaPlayerPrivateGStream
}
#endif
+#if USE(VAAPI)
+void MediaPlayerPrivateGStreamerBase::handoffCallback(MediaPlayerPrivateGStreamerBase* player, GstBuffer* buffer)
+{
+ player->triggerRepaint(
+ adoptGRef(
+ gst_sample_new(
+ buffer,
+ gst_caps_from_string("video/x-raw(memory:VASurface, meta:GstVideoOverlayComposition), format=(string){ ENCODED, NV12, I420, YV12 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]"),
+ NULL,
+ NULL
+ )
+ ).get()
+ );
+}
+#endif
+
void MediaPlayerPrivateGStreamerBase::setSize(const IntSize& size)
{
m_size = size;
@@ -737,6 +753,14 @@ GstElement* MediaPlayerPrivateGStreamerBase::createVideoSink()
}
#endif
+#if USE(VAAPI)
+ m_videoSink = gst_element_factory_make("vaapisink", nullptr);
+ if (m_videoSink) {
+ g_signal_connect_swapped(m_videoSink.get(), "handoff", G_CALLBACK(handoffCallback), this);
+ videoSink = m_videoSink.get();
+ }
+#endif
+
if (!m_videoSink) {
m_usingFallbackVideoSink = true;
m_videoSink = webkitVideoSinkNew();
diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h
index 7eca22f..969419e 100644
--- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h
+++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h
@@ -135,6 +135,9 @@ protected:
#if USE(GSTREAMER_GL)
static gboolean drawCallback(MediaPlayerPrivateGStreamerBase*, GstGLContext*, GstSample*);
#endif
+#if USE(VAAPI)
+ static void handoffCallback(MediaPlayerPrivateGStreamerBase*, GstBuffer*);
+#endif
void notifyPlayerOfVolumeChange();
void notifyPlayerOfMute();
diff --git a/Source/cmake/OptionsQt.cmake b/Source/cmake/OptionsQt.cmake
index c22658f..75f5676 100644
--- a/Source/cmake/OptionsQt.cmake
+++ b/Source/cmake/OptionsQt.cmake
@@ -96,6 +96,8 @@ cmake_dependent_option(ENABLE_TEST_SUPPORT "Build tools for running layout tests
"DEVELOPER_MODE" OFF)
option(USE_STATIC_RUNTIME "Use static runtime (MSVC only)" OFF)
+WEBKIT_OPTION_DEFINE(USE_VAAPI "Whether to enable Intel VAAPI hardware video decoder." PRIVATE OFF)
+
# Public options shared with other WebKit ports. There must be strong reason
# to support changing the value of the option.
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_ALLINONE_BUILD PUBLIC ON)
@annulen
Copy link

annulen commented Jan 23, 2017

I guess it's better to store sample in local variable before calling get, e.g.

GRefPtr<GstSample> sample = gst_sample_new...
player->triggerRepaint(sample.get());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment