| Differences between
and this patch
- a/ChangeLog +11 lines
Lines 1-3 a/ChangeLog_sec1
1
2014-12-09  Philippe Normand  <pnormand@igalia.com>
2
3
        [GStreamer] GstGL support in the video sink
4
        https://bugs.webkit.org/show_bug.cgi?id=138562
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * Source/cmake/FindGStreamer.cmake: Lookup the GstGL library and headers.
9
        * Source/cmake/OptionsGTK.cmake: Turn on the USE(GSTREAMER_GL)
10
        macro if GstGL was found.
11
1
2014-12-09  Bem Jones-Bey  <bjonesbe@adobe.com>
12
2014-12-09  Bem Jones-Bey  <bjonesbe@adobe.com>
2
13
3
        REGRESSION(r155906): Page content disappears on Tuaw article after loading
14
        REGRESSION(r155906): Page content disappears on Tuaw article after loading
- a/Source/WebCore/ChangeLog +37 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2014-12-09  Philippe Normand  <pnormand@igalia.com>
2
3
        [GStreamer] GstGL support in the video sink
4
        https://bugs.webkit.org/show_bug.cgi?id=138562
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        If a recent enough (>= 1.5) GStreamer version is available then
9
        the video sink will use the GstGL library to embed a GL texture in
10
        each GstBuffer to be rendered via the TextureMapper. In this
11
        scenario a GPU-GPU texture copy will be performed. For this to be
12
        possible the GL context used within WebKit needs to be shared with
13
        the GL context used by GstGL. For now we support only the GLX/X11
14
        sharing context.
15
16
        No new tests, existing media tests will cover this change once the
17
        buildbots have GStreamer >= 1.5.
18
19
        * PlatformGTK.cmake: Use GstGL library for the build.
20
        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
21
        (WebCore::MediaPlayerPrivateGStreamerBase::updateTexture): Do a
22
        GPU-GPU texture if the buffer already has a GL texture available.
23
        * platform/graphics/gstreamer/VideoSinkGStreamer.cpp:
24
        (_WebKitVideoSinkPrivate::_WebKitVideoSinkPrivate): Use a mutex
25
        and condition so as to get the WebKit GL context from the main thread.
26
        (_WebKitVideoSinkPrivate::~_WebKitVideoSinkPrivate):
27
        (wrapGLContextCallback): Wrap the WebKit GL context in a GstGL context.
28
        (webkitVideoSinkStop): Free buffer pool and pre-allocated buffer.
29
        (webkitVideoSinkSetCaps): Create the GstGLUpload that will take
30
        care of updating the buffer's texture and update caps accordingly.
31
        (webkitVideoSinkPrepare): Update the buffer's texture before rendering.
32
        (webkitVideoSinkProposeAllocation): Prepare a buffer pool, set the
33
        GL context up and update the meta informations supported by the sink.
34
        (webkitVideoSinkSetContext): Pass-through the context to GstGL.
35
        (webkitVideoSinkQuery): Basic support for context queries.
36
        (webkit_video_sink_class_init):
37
1
2014-12-08  Philippe Normand  <pnormand@igalia.com>
38
2014-12-08  Philippe Normand  <pnormand@igalia.com>
2
39
3
        [GStreamer] AudioSourceProvider support in the MediaPlayer
40
        [GStreamer] AudioSourceProvider support in the MediaPlayer
- a/Source/WebCore/PlatformGTK.cmake +10 lines
Lines 352-357 if (ENABLE_VIDEO) a/Source/WebCore/PlatformGTK.cmake_sec1
352
            ${GSTREAMER_MPEGTS_LIBRARIES}
352
            ${GSTREAMER_MPEGTS_LIBRARIES}
353
        )
353
        )
354
    endif ()
354
    endif ()
355
356
    if (USE_GSTREAMER_GL)
357
        list(APPEND WebCore_INCLUDE_DIRECTORIES
358
            ${GSTREAMER_GL_INCLUDE_DIRS}
359
        )
360
361
        list(APPEND WebCore_LIBRARIES
362
            ${GSTREAMER_GL_LIBRARIES}
363
        )
364
    endif ()
355
endif ()
365
endif ()
356
366
357
if (ENABLE_WEB_AUDIO)
367
if (ENABLE_WEB_AUDIO)
- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp +29 lines
Lines 44-49 a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp_sec1
44
#include <gst/audio/streamvolume.h>
44
#include <gst/audio/streamvolume.h>
45
#include <gst/video/gstvideometa.h>
45
#include <gst/video/gstvideometa.h>
46
46
47
#if USE(GSTREAMER_GL)
48
#define GST_USE_UNSTABLE_API
49
#include <gst/gl/gstglmemory.h>
50
#undef GST_USE_UNSTABLE_API
51
#endif
52
47
#if GST_CHECK_VERSION(1, 1, 0) && USE(TEXTURE_MAPPER_GL)
53
#if GST_CHECK_VERSION(1, 1, 0) && USE(TEXTURE_MAPPER_GL)
48
#include "TextureMapperGL.h"
54
#include "TextureMapperGL.h"
49
#endif
55
#endif
Lines 295-300 PassRefPtr<BitmapTexture> MediaPlayerPrivateGStreamerBase::updateTexture(Texture a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp_sec2
295
    IntSize size = IntSize(GST_VIDEO_INFO_WIDTH(&videoInfo), GST_VIDEO_INFO_HEIGHT(&videoInfo));
301
    IntSize size = IntSize(GST_VIDEO_INFO_WIDTH(&videoInfo), GST_VIDEO_INFO_HEIGHT(&videoInfo));
296
    RefPtr<BitmapTexture> texture = textureMapper->acquireTextureFromPool(size, GST_VIDEO_INFO_HAS_ALPHA(&videoInfo) ? BitmapTexture::SupportsAlpha : BitmapTexture::NoFlag);
302
    RefPtr<BitmapTexture> texture = textureMapper->acquireTextureFromPool(size, GST_VIDEO_INFO_HAS_ALPHA(&videoInfo) ? BitmapTexture::SupportsAlpha : BitmapTexture::NoFlag);
297
    GstBuffer* buffer = gst_sample_get_buffer(m_sample);
303
    GstBuffer* buffer = gst_sample_get_buffer(m_sample);
304
    const BitmapTextureGL* textureGL = static_cast<const BitmapTextureGL*>(texture.get());
305
    uint32_t textureID = textureGL->id();
306
307
#if USE(GSTREAMER_GL)
308
    GstMemory* bufferMemory;
309
    if (gst_buffer_n_memory(buffer) >= 1) {
310
        if ((bufferMemory = gst_buffer_peek_memory(buffer, 0)) && gst_is_gl_memory(bufferMemory)) {
311
            GstGLMemory* glMemory = reinterpret_cast<GstGLMemory*>(bufferMemory);
312
            GstVideoGLTextureType textureType = gst_gl_texture_type_from_format(glMemory->context, GST_VIDEO_INFO_FORMAT(&videoInfo), 0);
313
            GstMapInfo mapInfo;
314
315
            if (!gst_memory_map(bufferMemory, &mapInfo, static_cast<GstMapFlags>(GST_MAP_READ | GST_MAP_GL))) {
316
                gst_gl_context_set_error(glMemory->context, "Failed to map intermediate memory");
317
                return nullptr;
318
            }
319
            gboolean copied = gst_gl_memory_copy_into_texture(glMemory, textureID, textureType, size.width(), size.height(), GST_VIDEO_INFO_PLANE_STRIDE(&videoInfo, 0), true /* respecify */);
320
            gst_memory_unmap(bufferMemory, &mapInfo);
321
            if (copied)
322
                return texture;
323
            WARN_MEDIA_MESSAGE("Texture copy failed, trying fallback slow path.");
324
        }
325
    }
326
#endif
298
327
299
#if GST_CHECK_VERSION(1, 1, 0)
328
#if GST_CHECK_VERSION(1, 1, 0)
300
    GstVideoGLTextureUploadMeta* meta;
329
    GstVideoGLTextureUploadMeta* meta;
- a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp -10 / +306 lines
Lines 35-43 a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp_sec1
35
#include <glib.h>
35
#include <glib.h>
36
#include <gst/gst.h>
36
#include <gst/gst.h>
37
#include <gst/video/gstvideometa.h>
37
#include <gst/video/gstvideometa.h>
38
#include <gst/video/gstvideopool.h>
38
#include <wtf/OwnPtr.h>
39
#include <wtf/OwnPtr.h>
39
#include <wtf/gobject/GMutexLocker.h>
40
#include <wtf/gobject/GMutexLocker.h>
40
#include <wtf/gobject/GThreadSafeMainLoopSource.h>
41
#include <wtf/gobject/GThreadSafeMainLoopSource.h>
42
#include <wtf/gobject/GUniquePtr.h>
43
44
#if USE(GSTREAMER_GL)
45
#define GST_USE_UNSTABLE_API
46
#include <gst/gl/gstglcontext.h>
47
#include <gst/gl/gstgldisplay.h>
48
#undef GST_USE_UNSTABLE_API
49
50
#if GST_GL_HAVE_PLATFORM_EGL
51
#include <gst/gl/egl/gsteglimagememory.h>
52
#endif
53
#include <gst/gl/gstglutils.h>
54
55
#if PLATFORM(X11)
56
#include <gst/gl/x11/gstgldisplay_x11.h>
57
#endif
58
59
#include "GLContext.h"
60
#if USE(GLX)
61
#include "GLContextGLX.h"
62
#endif
63
#endif // USE(GSTREAMER_GL)
41
64
42
using namespace WebCore;
65
using namespace WebCore;
43
66
Lines 47-53 using namespace WebCore; a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp_sec2
47
#else
70
#else
48
#define GST_CAPS_FORMAT "{ xRGB, ARGB }"
71
#define GST_CAPS_FORMAT "{ xRGB, ARGB }"
49
#endif
72
#endif
50
#if GST_CHECK_VERSION(1, 1, 0)
73
74
#if USE(GSTREAMER_GL)
75
76
#if GST_GL_HAVE_PLATFORM_EGL
77
#define EGL_CAPS GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_EGL_IMAGE, GST_CAPS_FORMAT) "; "
78
#else
79
#define EGL_CAPS
80
#endif
81
82
#define GST_FEATURED_CAPS GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_MEMORY_GL_MEMORY, GST_CAPS_FORMAT) "; " EGL_CAPS GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, GST_CAPS_FORMAT) ";"
83
84
#elif GST_CHECK_VERSION(1, 1, 0)
51
#define GST_FEATURED_CAPS GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, GST_CAPS_FORMAT) ";"
85
#define GST_FEATURED_CAPS GST_VIDEO_CAPS_MAKE_WITH_FEATURES(GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, GST_CAPS_FORMAT) ";"
52
#else
86
#else
53
#define GST_FEATURED_CAPS
87
#define GST_FEATURED_CAPS
Lines 73-78 struct _WebKitVideoSinkPrivate { a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp_sec3
73
    {
107
    {
74
        g_mutex_init(&sampleMutex);
108
        g_mutex_init(&sampleMutex);
75
        g_cond_init(&dataCondition);
109
        g_cond_init(&dataCondition);
110
#if USE(GSTREAMER_GL)
111
        g_mutex_init(&contextMutex);
112
        g_cond_init(&contextCondition);
113
#endif
76
        gst_video_info_init(&info);
114
        gst_video_info_init(&info);
77
    }
115
    }
78
116
Lines 80-85 struct _WebKitVideoSinkPrivate { a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp_sec4
80
    {
118
    {
81
        g_mutex_clear(&sampleMutex);
119
        g_mutex_clear(&sampleMutex);
82
        g_cond_clear(&dataCondition);
120
        g_cond_clear(&dataCondition);
121
#if USE(GSTREAMER_GL)
122
        g_mutex_clear(&contextMutex);
123
        g_cond_clear(&contextCondition);
124
#endif
83
    }
125
    }
84
126
85
    GstSample* sample;
127
    GstSample* sample;
Lines 100-115 struct _WebKitVideoSinkPrivate { a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp_sec5
100
    //
142
    //
101
    // Protected by the sample mutex
143
    // Protected by the sample mutex
102
    bool unlocked;
144
    bool unlocked;
145
146
#if USE(GSTREAMER_GL)
147
    GstCaps* glCaps;
148
    GstBufferPool* pool;
149
    GstGLDisplay* display;
150
    GstGLContext* context;
151
    GstGLContext* otherContext;
152
    GMutex contextMutex;
153
    GCond contextCondition;
154
155
    GstGLUpload* upload;
156
    GstBuffer* nextBuffer;
157
#endif
103
};
158
};
104
159
105
#define webkit_video_sink_parent_class parent_class
160
#define webkit_video_sink_parent_class parent_class
106
G_DEFINE_TYPE_WITH_CODE(WebKitVideoSink, webkit_video_sink, GST_TYPE_VIDEO_SINK, GST_DEBUG_CATEGORY_INIT(webkitVideoSinkDebug, "webkitsink", 0, "webkit video sink"));
161
G_DEFINE_TYPE_WITH_CODE(WebKitVideoSink, webkit_video_sink, GST_TYPE_VIDEO_SINK, GST_DEBUG_CATEGORY_INIT(webkitVideoSinkDebug, "webkitsink", 0, "webkit video sink"));
107
162
163
#if USE(GSTREAMER_GL)
164
gboolean wrapGLContextCallback(gpointer userData)
165
{
166
    WebKitVideoSink* sink = reinterpret_cast<WebKitVideoSink*>(userData);
167
    WebKitVideoSinkPrivate* priv = sink->priv;
168
169
    GMutexLocker<GMutex> lock(priv->contextMutex);
170
171
    GError* error = nullptr;
172
173
    if (!priv->display)
174
        priv->display = gst_gl_display_new();
175
176
    if (!priv->otherContext) {
177
        GLContext* webkitContext = GLContext::sharingContext();
178
#if PLATFORM(X11)
179
        Display* display = GLContext::sharedX11Display();
180
        GLXContext* glxSharingContext = reinterpret_cast<GLXContext*>(webkitContext->platformContext());
181
        GstGLDisplayX11* gstGLDisplay = gst_gl_display_x11_new_with_display(display);
182
        GstGLPlatform platform = GST_GL_PLATFORM_GLX;
183
        GstGLAPI glApi = gst_gl_context_get_current_gl_api(nullptr, nullptr);
184
        if (glxSharingContext)
185
            priv->otherContext = gst_gl_context_new_wrapped(GST_GL_DISPLAY(gstGLDisplay), reinterpret_cast<guintptr>(glxSharingContext), platform, glApi);
186
#endif
187
    }
188
189
    if (!priv->context) {
190
        priv->context = gst_gl_context_new(priv->display);
191
        if (!gst_gl_context_create(priv->context, priv->otherContext, &error)) {
192
            GST_ELEMENT_ERROR(sink, RESOURCE, NOT_FOUND, ("%s", error->message), (nullptr));
193
            gst_object_unref(priv->context);
194
            priv->context = nullptr;
195
            g_cond_signal(&priv->contextCondition);
196
            return FALSE;
197
        }
198
    }
199
200
    g_cond_signal(&priv->contextCondition);
201
    return FALSE;
202
}
203
#endif
108
204
109
static void webkit_video_sink_init(WebKitVideoSink* sink)
205
static void webkit_video_sink_init(WebKitVideoSink* sink)
110
{
206
{
111
    sink->priv = G_TYPE_INSTANCE_GET_PRIVATE(sink, WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkPrivate);
207
    sink->priv = G_TYPE_INSTANCE_GET_PRIVATE(sink, WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkPrivate);
112
    g_object_set(GST_BASE_SINK(sink), "enable-last-sample", FALSE, NULL);
208
    g_object_set(GST_BASE_SINK(sink), "enable-last-sample", FALSE, nullptr);
113
    new (sink->priv) WebKitVideoSinkPrivate();
209
    new (sink->priv) WebKitVideoSinkPrivate();
114
}
210
}
115
211
Lines 119-125 static void webkitVideoSinkTimeoutCallback(WebKitVideoSink* sink) a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp_sec6
119
215
120
    GMutexLocker<GMutex> lock(priv->sampleMutex);
216
    GMutexLocker<GMutex> lock(priv->sampleMutex);
121
    GstSample* sample = priv->sample;
217
    GstSample* sample = priv->sample;
122
    priv->sample = 0;
218
    priv->sample = nullptr;
123
219
124
    if (!sample || priv->unlocked || UNLIKELY(!GST_IS_SAMPLE(sample))) {
220
    if (!sample || priv->unlocked || UNLIKELY(!GST_IS_SAMPLE(sample))) {
125
        g_cond_signal(&priv->dataCondition);
221
        g_cond_signal(&priv->dataCondition);
Lines 219-226 static GstFlowReturn webkitVideoSinkRender(GstBaseSink* baseSink, GstBuffer* buf a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp_sec7
219
    // lower priority sources.
315
    // lower priority sources.
220
    // See: https://bugzilla.gnome.org/show_bug.cgi?id=610830.
316
    // See: https://bugzilla.gnome.org/show_bug.cgi?id=610830.
221
    gst_object_ref(sink);
317
    gst_object_ref(sink);
222
    priv->timeoutSource.schedule("[WebKit] webkitVideoSinkTimeoutCallback", std::function<void()>(std::bind(webkitVideoSinkTimeoutCallback, sink)), G_PRIORITY_DEFAULT,
318
    priv->timeoutSource.schedule("[WebKit] webkitVideoSinkTimeoutCallback",
223
        [sink] { gst_object_unref(sink); });
319
        std::function<void()>(std::bind(webkitVideoSinkTimeoutCallback, sink)),
320
        G_PRIORITY_DEFAULT, [sink] {
321
            gst_object_unref(sink);
322
        });
224
323
225
    g_cond_wait(&priv->dataCondition, &priv->sampleMutex);
324
    g_cond_wait(&priv->dataCondition, &priv->sampleMutex);
226
    return GST_FLOW_OK;
325
    return GST_FLOW_OK;
Lines 238-244 static void unlockSampleMutex(WebKitVideoSinkPrivate* priv) a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp_sec8
238
337
239
    if (priv->sample) {
338
    if (priv->sample) {
240
        gst_sample_unref(priv->sample);
339
        gst_sample_unref(priv->sample);
241
        priv->sample = 0;
340
        priv->sample = nullptr;
242
    }
341
    }
243
342
244
    priv->unlocked = true;
343
    priv->unlocked = true;
Lines 269-282 static gboolean webkitVideoSinkUnlockStop(GstBaseSink* baseSink) a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp_sec9
269
368
270
static gboolean webkitVideoSinkStop(GstBaseSink* baseSink)
369
static gboolean webkitVideoSinkStop(GstBaseSink* baseSink)
271
{
370
{
272
    WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(baseSink)->priv;
371
    WebKitVideoSink* sink = reinterpret_cast_ptr<WebKitVideoSink*>(baseSink);
372
    WebKitVideoSinkPrivate* priv = sink->priv;
273
373
274
    unlockSampleMutex(priv);
374
    unlockSampleMutex(priv);
275
375
276
    if (priv->currentCaps) {
376
    if (priv->currentCaps) {
277
        gst_caps_unref(priv->currentCaps);
377
        gst_caps_unref(priv->currentCaps);
278
        priv->currentCaps = 0;
378
        priv->currentCaps = nullptr;
379
    }
380
381
#if USE(GSTREAMER_GL)
382
    GST_OBJECT_LOCK(sink);
383
    if (priv->pool)
384
        gst_object_unref(priv->pool);
385
    priv->pool = nullptr;
386
    GST_OBJECT_UNLOCK(sink);
387
388
    gst_buffer_replace(&priv->nextBuffer, nullptr);
389
390
    if (priv->upload) {
391
        gst_object_unref(priv->upload);
392
        priv->upload = nullptr;
279
    }
393
    }
394
#endif
280
395
281
    return TRUE;
396
    return TRUE;
282
}
397
}
Lines 306-318 static gboolean webkitVideoSinkSetCaps(GstBaseSink* baseSink, GstCaps* caps) a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp_sec10
306
421
307
    priv->info = videoInfo;
422
    priv->info = videoInfo;
308
    gst_caps_replace(&priv->currentCaps, caps);
423
    gst_caps_replace(&priv->currentCaps, caps);
424
425
#if USE(GSTREAMER_GL)
426
    GMutexLocker<GMutex> lock(priv->contextMutex);
427
428
    GThreadSafeMainLoopSource timeoutSource;
429
    gst_object_ref(sink);
430
    timeoutSource.schedule("[WebKit][gst] GL context wrap", std::function<void()>(std::bind(wrapGLContextCallback, sink)), G_PRIORITY_DEFAULT, [sink] {
431
        gst_object_unref(sink);
432
    });
433
434
    g_cond_wait(&sink->priv->contextCondition, &sink->priv->contextMutex);
435
436
    if (priv->upload)
437
        gst_object_unref(priv->upload);
438
    priv->upload = gst_gl_upload_new(priv->context);
439
440
    GstCapsFeatures* glFeatures = gst_caps_features_from_string(GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
441
    if (priv->glCaps)
442
        gst_caps_unref(priv->glCaps);
443
    priv->glCaps = gst_caps_copy(caps);
444
    gst_caps_set_features(priv->glCaps, 0, glFeatures);
445
446
    gst_gl_upload_set_caps(priv->upload, caps, priv->glCaps);
447
#endif
309
    return TRUE;
448
    return TRUE;
310
}
449
}
311
450
451
#if USE(GSTREAMER_GL)
452
static GstFlowReturn webkitVideoSinkPrepare(GstBaseSink* baseSink, GstBuffer* buffer)
453
{
454
    WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(baseSink);
455
    WebKitVideoSinkPrivate* priv = sink->priv;
456
457
    GstBuffer* nextBuffer = nullptr;
458
    GstVideoFrame glFrame;
459
    GstVideoInfo glInfo;
460
461
    if (!gst_gl_upload_perform_with_buffer(priv->upload, buffer, &nextBuffer)) {
462
        GST_ELEMENT_ERROR(sink, RESOURCE, NOT_FOUND, ("%s", "Failed to upload buffer"), (nullptr));
463
        return GST_FLOW_ERROR;
464
    }
465
466
    gst_video_info_from_caps(&glInfo, priv->glCaps);
467
468
    if (!gst_video_frame_map(&glFrame, &glInfo, nextBuffer, static_cast<GstMapFlags>(GST_MAP_READ | GST_MAP_GL))) {
469
        gst_buffer_unref(nextBuffer);
470
        GST_ELEMENT_ERROR(sink, RESOURCE, NOT_FOUND, ("%s", "Failed to upload buffer"), (nullptr));
471
        return GST_FLOW_ERROR;
472
    }
473
474
    gst_buffer_replace(&priv->nextBuffer, nextBuffer);
475
    gst_buffer_unref(nextBuffer);
476
477
    gst_video_frame_unmap(&glFrame);
478
    return GST_FLOW_OK;
479
}
480
#endif
481
312
static gboolean webkitVideoSinkProposeAllocation(GstBaseSink* baseSink, GstQuery* query)
482
static gboolean webkitVideoSinkProposeAllocation(GstBaseSink* baseSink, GstQuery* query)
313
{
483
{
314
    GstCaps* caps;
484
    GstCaps* caps;
315
    gst_query_parse_allocation(query, &caps, 0);
485
    gboolean needPool;
486
487
    gst_query_parse_allocation(query, &caps, &needPool);
316
    if (!caps)
488
    if (!caps)
317
        return FALSE;
489
        return FALSE;
318
490
Lines 320-333 static gboolean webkitVideoSinkProposeAllocation(GstBaseSink* baseSink, GstQuery a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp_sec11
320
    if (!gst_video_info_from_caps(&sink->priv->info, caps))
492
    if (!gst_video_info_from_caps(&sink->priv->info, caps))
321
        return FALSE;
493
        return FALSE;
322
494
495
    GstStructure* glContext = nullptr;
496
#if USE(GSTREAMER_GL)
497
    GST_DEBUG_OBJECT(sink, "propose allocation");
498
    GMutexLocker<GMutex> lock(sink->priv->contextMutex);
499
500
    GThreadSafeMainLoopSource timeoutSource;
501
    gst_object_ref(sink);
502
    timeoutSource.schedule("[WebKit][gst] GL context wrap", std::function<void()>(std::bind(wrapGLContextCallback, sink)), G_PRIORITY_DEFAULT, [sink] {
503
        gst_object_unref(sink);
504
    });
505
506
    g_cond_wait(&sink->priv->contextCondition, &sink->priv->contextMutex);
507
508
    GstBufferPool* pool;
509
    GstAllocator* allocator = nullptr;
510
    GstAllocationParams params;
511
    GstStructure* config;
512
    guint size;
513
514
    if ((pool = sink->priv->pool))
515
        gst_object_ref(pool);
516
517
    if (pool) {
518
        GstCaps* pcaps;
519
520
        // We had a pool, check its caps.
521
        GST_DEBUG_OBJECT(sink, "check existing pool caps");
522
        config = gst_buffer_pool_get_config(pool);
523
        gst_buffer_pool_config_get_params(config, &pcaps, &size, 0, 0);
524
525
        if (!gst_caps_is_equal(caps, pcaps)) {
526
            GST_DEBUG_OBJECT(sink, "pool has different caps");
527
            // Different caps, we can't use this pool.
528
            gst_object_unref(pool);
529
            pool = nullptr;
530
        }
531
        gst_structure_free(config);
532
    }
533
534
    if (needPool && !pool) {
535
        GstVideoInfo info;
536
537
        if (!gst_video_info_from_caps(&info, caps)) {
538
            GST_DEBUG_OBJECT(sink, "invalid caps specified");
539
            return FALSE;
540
        }
541
542
        GST_DEBUG_OBJECT(sink, "create new pool with caps %" GST_PTR_FORMAT, caps);
543
        pool = gst_gl_buffer_pool_new(sink->priv->context);
544
545
        // The normal size of a frame.
546
        size = info.size;
547
548
        config = gst_buffer_pool_get_config(pool);
549
        gst_buffer_pool_config_set_params(config, caps, size, 0, 0);
550
        if (!gst_buffer_pool_set_config(pool, config)) {
551
            GST_DEBUG_OBJECT(sink, "failed setting config");
552
            return FALSE;
553
        }
554
    }
555
556
    if (pool) {
557
        gst_query_add_allocation_pool(query, pool, size, 2, 0);
558
        gst_object_unref(pool);
559
    }
560
561
    GUniquePtr<gchar> platform(gst_gl_platform_to_string(gst_gl_context_get_gl_platform(sink->priv->context)));
562
    GUniquePtr<gchar> glApis(gst_gl_api_to_string(gst_gl_context_get_gl_api(sink->priv->context)));
563
    gpointer handle = reinterpret_cast_ptr<gpointer>(gst_gl_context_get_gl_context(sink->priv->context));
564
565
    glContext = gst_structure_new("GstVideoGLTextureUploadMeta", "gst.gl.GstGLContext",
566
        GST_GL_TYPE_CONTEXT, sink->priv->context, "gst.gl.context.handle",
567
        G_TYPE_POINTER, handle, "gst.gl.context.type", G_TYPE_STRING, platform.get(),
568
        "gst.gl.context.apis", G_TYPE_STRING, glApis.get(), nullptr);
569
#endif
570
323
    gst_query_add_allocation_meta(query, GST_VIDEO_META_API_TYPE, 0);
571
    gst_query_add_allocation_meta(query, GST_VIDEO_META_API_TYPE, 0);
324
    gst_query_add_allocation_meta(query, GST_VIDEO_CROP_META_API_TYPE, 0);
572
    gst_query_add_allocation_meta(query, GST_VIDEO_CROP_META_API_TYPE, 0);
325
#if GST_CHECK_VERSION(1, 1, 0)
573
#if GST_CHECK_VERSION(1, 1, 0)
326
    gst_query_add_allocation_meta(query, GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, 0);
574
    gst_query_add_allocation_meta(query, GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, glContext);
575
#endif
576
577
    if (glContext)
578
        gst_structure_free(glContext);
579
580
#if USE(GSTREAMER_GL)
581
    gst_allocation_params_init(&params);
582
    allocator = gst_allocator_find(GST_GL_MEMORY_ALLOCATOR);
583
    gst_query_add_allocation_param(query, allocator, &params);
584
    gst_object_unref(allocator);
585
#if GST_GL_HAVE_PLATFORM_EGL
586
    if (gst_gl_context_check_feature(sink->priv->context, "EGL_KHR_image_base")) {
587
        allocator = gst_allocator_find(GST_EGL_IMAGE_MEMORY_TYPE);
588
        gst_query_add_allocation_param(query, allocator, &params);
589
        gst_object_unref(allocator);
590
    }
591
#endif
327
#endif
592
#endif
328
    return TRUE;
593
    return TRUE;
329
}
594
}
330
595
596
#if USE(GSTREAMER_GL)
597
static void webkitVideoSinkSetContext(GstElement* element, GstContext* context)
598
{
599
    WebKitVideoSink* sink =  WEBKIT_VIDEO_SINK(element);
600
    gst_gl_handle_set_context(element, context, &sink->priv->display, &sink->priv->context);
601
}
602
603
static gboolean webkitVideoSinkQuery(GstBaseSink* baseSink, GstQuery* query)
604
{
605
    WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(baseSink);
606
    gboolean result = FALSE;
607
608
    switch (GST_QUERY_TYPE(query)) {
609
    case GST_QUERY_CONTEXT: {
610
        result = gst_gl_handle_context_query(reinterpret_cast<GstElement*>(sink), query, &sink->priv->display, &sink->priv->otherContext);
611
        break;
612
    }
613
    default:
614
        result = GST_BASE_SINK_CLASS(parent_class)->query(baseSink, query);
615
        break;
616
    }
617
618
    return result;
619
}
620
#endif
621
331
static void webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
622
static void webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
332
{
623
{
333
    GObjectClass* gobjectClass = G_OBJECT_CLASS(klass);
624
    GObjectClass* gobjectClass = G_OBJECT_CLASS(klass);
Lines 349-354 static void webkit_video_sink_class_init(WebKitVideoSinkClass* klass) a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp_sec12
349
    baseSinkClass->start = webkitVideoSinkStart;
640
    baseSinkClass->start = webkitVideoSinkStart;
350
    baseSinkClass->set_caps = webkitVideoSinkSetCaps;
641
    baseSinkClass->set_caps = webkitVideoSinkSetCaps;
351
    baseSinkClass->propose_allocation = webkitVideoSinkProposeAllocation;
642
    baseSinkClass->propose_allocation = webkitVideoSinkProposeAllocation;
643
#if USE(GSTREAMER_GL)
644
    baseSinkClass->prepare = webkitVideoSinkPrepare;
645
    baseSinkClass->query = webkitVideoSinkQuery;
646
    elementClass->set_context = webkitVideoSinkSetContext;
647
#endif
352
648
353
    webkitVideoSinkSignals[REPAINT_REQUESTED] = g_signal_new("repaint-requested",
649
    webkitVideoSinkSignals[REPAINT_REQUESTED] = g_signal_new("repaint-requested",
354
            G_TYPE_FROM_CLASS(klass),
650
            G_TYPE_FROM_CLASS(klass),
- a/Source/cmake/FindGStreamer.cmake +4 lines
Lines 19-24 a/Source/cmake/FindGStreamer.cmake_sec1
19
#  gstreamer-app:        GSTREAMER_APP_INCLUDE_DIRS and GSTREAMER_APP_LIBRARIES
19
#  gstreamer-app:        GSTREAMER_APP_INCLUDE_DIRS and GSTREAMER_APP_LIBRARIES
20
#  gstreamer-audio:      GSTREAMER_AUDIO_INCLUDE_DIRS and GSTREAMER_AUDIO_LIBRARIES
20
#  gstreamer-audio:      GSTREAMER_AUDIO_INCLUDE_DIRS and GSTREAMER_AUDIO_LIBRARIES
21
#  gstreamer-fft:        GSTREAMER_FFT_INCLUDE_DIRS and GSTREAMER_FFT_LIBRARIES
21
#  gstreamer-fft:        GSTREAMER_FFT_INCLUDE_DIRS and GSTREAMER_FFT_LIBRARIES
22
#  gstreamer-gl:         GSTREAMER_GL_INCLUDE_DIRS and GSTREAMER_GL_LIBRARIES
22
#  gstreamer-mpegts:     GSTREAMER_MPEGTS_INCLUDE_DIRS and GSTREAMER_MPEGTS_LIBRARIES
23
#  gstreamer-mpegts:     GSTREAMER_MPEGTS_INCLUDE_DIRS and GSTREAMER_MPEGTS_LIBRARIES
23
#  gstreamer-pbutils:    GSTREAMER_PBUTILS_INCLUDE_DIRS and GSTREAMER_PBUTILS_LIBRARIES
24
#  gstreamer-pbutils:    GSTREAMER_PBUTILS_INCLUDE_DIRS and GSTREAMER_PBUTILS_LIBRARIES
24
#  gstreamer-tag:        GSTREAMER_TAG_INCLUDE_DIRS and GSTREAMER_TAG_LIBRARIES
25
#  gstreamer-tag:        GSTREAMER_TAG_INCLUDE_DIRS and GSTREAMER_TAG_LIBRARIES
Lines 84-89 FIND_GSTREAMER_COMPONENT(GSTREAMER_BASE gstreamer-base-1.0 gstbase-1.0) a/Source/cmake/FindGStreamer.cmake_sec2
84
FIND_GSTREAMER_COMPONENT(GSTREAMER_APP gstreamer-app-1.0 gstapp-1.0)
85
FIND_GSTREAMER_COMPONENT(GSTREAMER_APP gstreamer-app-1.0 gstapp-1.0)
85
FIND_GSTREAMER_COMPONENT(GSTREAMER_AUDIO gstreamer-audio-1.0 gstaudio-1.0)
86
FIND_GSTREAMER_COMPONENT(GSTREAMER_AUDIO gstreamer-audio-1.0 gstaudio-1.0)
86
FIND_GSTREAMER_COMPONENT(GSTREAMER_FFT gstreamer-fft-1.0 gstfft-1.0)
87
FIND_GSTREAMER_COMPONENT(GSTREAMER_FFT gstreamer-fft-1.0 gstfft-1.0)
88
FIND_GSTREAMER_COMPONENT(GSTREAMER_GL gstreamer-gl-1.0>=1.5.0 gstgl-1.0)
87
FIND_GSTREAMER_COMPONENT(GSTREAMER_MPEGTS gstreamer-mpegts-1.0>=1.4.0 gstmpegts-1.0)
89
FIND_GSTREAMER_COMPONENT(GSTREAMER_MPEGTS gstreamer-mpegts-1.0>=1.4.0 gstmpegts-1.0)
88
FIND_GSTREAMER_COMPONENT(GSTREAMER_PBUTILS gstreamer-pbutils-1.0 gstpbutils-1.0)
90
FIND_GSTREAMER_COMPONENT(GSTREAMER_PBUTILS gstreamer-pbutils-1.0 gstpbutils-1.0)
89
FIND_GSTREAMER_COMPONENT(GSTREAMER_TAG gstreamer-tag-1.0 gsttag-1.0)
91
FIND_GSTREAMER_COMPONENT(GSTREAMER_TAG gstreamer-tag-1.0 gsttag-1.0)
Lines 114-119 mark_as_advanced( a/Source/cmake/FindGStreamer.cmake_sec3
114
    GSTREAMER_BASE_LIBRARIES
116
    GSTREAMER_BASE_LIBRARIES
115
    GSTREAMER_FFT_INCLUDE_DIRS
117
    GSTREAMER_FFT_INCLUDE_DIRS
116
    GSTREAMER_FFT_LIBRARIES
118
    GSTREAMER_FFT_LIBRARIES
119
    GSTREAMER_GL_INCLUDE_DIRS
120
    GSTREAMER_GL_LIBRARIES
117
    GSTREAMER_INCLUDE_DIRS
121
    GSTREAMER_INCLUDE_DIRS
118
    GSTREAMER_LIBRARIES
122
    GSTREAMER_LIBRARIES
119
    GSTREAMER_MPEGTS_INCLUDE_DIRS
123
    GSTREAMER_MPEGTS_INCLUDE_DIRS
- a/Source/cmake/OptionsGTK.cmake -2 / +6 lines
Lines 225-231 if (ENABLE_VIDEO OR ENABLE_WEB_AUDIO) a/Source/cmake/OptionsGTK.cmake_sec1
225
    set(GSTREAMER_COMPONENTS app pbutils)
225
    set(GSTREAMER_COMPONENTS app pbutils)
226
    add_definitions(-DWTF_USE_GSTREAMER)
226
    add_definitions(-DWTF_USE_GSTREAMER)
227
    if (ENABLE_VIDEO)
227
    if (ENABLE_VIDEO)
228
        list(APPEND GSTREAMER_COMPONENTS video mpegts tag)
228
        list(APPEND GSTREAMER_COMPONENTS video mpegts tag gl)
229
    endif ()
229
    endif ()
230
230
231
    if (ENABLE_WEB_AUDIO)
231
    if (ENABLE_WEB_AUDIO)
Lines 239-244 if (ENABLE_VIDEO OR ENABLE_WEB_AUDIO) a/Source/cmake/OptionsGTK.cmake_sec2
239
        add_definitions(-DWTF_USE_GSTREAMER_MPEGTS)
239
        add_definitions(-DWTF_USE_GSTREAMER_MPEGTS)
240
        set(USE_GSTREAMER_MPEGTS TRUE)
240
        set(USE_GSTREAMER_MPEGTS TRUE)
241
    endif ()
241
    endif ()
242
243
    if (PC_GSTREAMER_GL_FOUND)
244
        add_definitions(-DWTF_USE_GSTREAMER_GL)
245
        set(USE_GSTREAMER_GL TRUE)
246
    endif ()
242
endif ()
247
endif ()
243
248
244
if (ENABLE_WAYLAND_TARGET)
249
if (ENABLE_WAYLAND_TARGET)
245
- 

Return to Bug 138562