Changeset 242701 in webkit


Ignore:
Timestamp:
Mar 11, 2019 7:41:39 AM (5 years ago)
Author:
Philippe Normand
Message:

[GStreamer][v4l2] Synchronous video texture flushing support
https://bugs.webkit.org/show_bug.cgi?id=195453

Reviewed by Xabier Rodriguez-Calvar.

The v4l2 video decoder currently requires that downstream users of
the graphics resources complete any pending draw call and release
resources before returning from the DRAIN query.

To accomplish this the player monitors the pipeline and whenever a
v4l2 decoder is added, synchronous video texture flushing support
is enabled. Additionally and for all decoder configurations, a
flush is performed before disposing of the player.

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:

(WebCore::MediaPlayerPrivateGStreamer::playbinDeepElementAddedCallback):
Monitor elements added to the decodebin bin.
(WebCore::MediaPlayerPrivateGStreamer::decodebinElementAdded): Set
a flag if a v4l2 decoder was added in decodebin.
(WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin): Connect
to the deep-element-added signal so as to monitor pipeline
topology updates.

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:

(WebCore::MediaPlayerPrivateGStreamerBase::~MediaPlayerPrivateGStreamerBase):
Flush video texture before disposing of the player.
(WebCore::MediaPlayerPrivateGStreamerBase::flushCurrentBuffer):
Synchronously flush if the pipeline contains a v4l2 decoder.
(WebCore::MediaPlayerPrivateGStreamerBase::createGLAppSink): Monitor push events only.

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
  • platform/graphics/texmap/TextureMapperPlatformLayerProxy.cpp:

(WebCore::TextureMapperPlatformLayerProxy::pushNextBuffer): New
boolean flag used mostly to trigger synchronous flush conditions.
(WebCore::TextureMapperPlatformLayerProxy::dropCurrentBufferWhilePreservingTexture):
Optionally drop the current buffer in a synchronous manner. By
default the method keeps operating asynchronously.

  • platform/graphics/texmap/TextureMapperPlatformLayerProxy.h:
Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r242700 r242701  
     12019-03-11  Philippe Normand  <pnormand@igalia.com>
     2
     3        [GStreamer][v4l2] Synchronous video texture flushing support
     4        https://bugs.webkit.org/show_bug.cgi?id=195453
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        The v4l2 video decoder currently requires that downstream users of
     9        the graphics resources complete any pending draw call and release
     10        resources before returning from the DRAIN query.
     11
     12        To accomplish this the player monitors the pipeline and whenever a
     13        v4l2 decoder is added, synchronous video texture flushing support
     14        is enabled. Additionally and for all decoder configurations, a
     15        flush is performed before disposing of the player.
     16
     17        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
     18        (WebCore::MediaPlayerPrivateGStreamer::playbinDeepElementAddedCallback):
     19        Monitor elements added to the decodebin bin.
     20        (WebCore::MediaPlayerPrivateGStreamer::decodebinElementAdded): Set
     21        a flag if a v4l2 decoder was added in decodebin.
     22        (WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin): Connect
     23        to the deep-element-added signal so as to monitor pipeline
     24        topology updates.
     25        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
     26        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
     27        (WebCore::MediaPlayerPrivateGStreamerBase::~MediaPlayerPrivateGStreamerBase):
     28        Flush video texture before disposing of the player.
     29        (WebCore::MediaPlayerPrivateGStreamerBase::flushCurrentBuffer):
     30        Synchronously flush if the pipeline contains a v4l2 decoder.
     31        (WebCore::MediaPlayerPrivateGStreamerBase::createGLAppSink): Monitor push events only.
     32        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
     33        * platform/graphics/texmap/TextureMapperPlatformLayerProxy.cpp:
     34        (WebCore::TextureMapperPlatformLayerProxy::pushNextBuffer): New
     35        boolean flag used mostly to trigger synchronous flush conditions.
     36        (WebCore::TextureMapperPlatformLayerProxy::dropCurrentBufferWhilePreservingTexture):
     37        Optionally drop the current buffer in a synchronous manner. By
     38        default the method keeps operating asynchronously.
     39        * platform/graphics/texmap/TextureMapperPlatformLayerProxy.h:
     40
    1412019-03-11  Antti Koivisto  <antti@apple.com>
    242
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

    r241751 r242701  
    24462446    g_object_set(m_pipeline.get(), "mute", m_player->muted(), nullptr);
    24472447
     2448    g_signal_connect(GST_BIN_CAST(m_pipeline.get()), "deep-element-added", G_CALLBACK(+[](GstBin*, GstBin* subBin, GstElement* element, MediaPlayerPrivateGStreamer* player) {
     2449        GUniquePtr<char> binName(gst_element_get_name(GST_ELEMENT_CAST(subBin)));
     2450        if (!g_str_has_prefix(binName.get(), "decodebin"))
     2451            return;
     2452
     2453        GUniquePtr<char> elementName(gst_element_get_name(element));
     2454        player->m_isVideoDecoderVideo4Linux = g_str_has_prefix(elementName.get(), "v4l2");
     2455    }), this);
     2456
    24482457    g_signal_connect_swapped(m_pipeline.get(), "source-setup", G_CALLBACK(sourceSetupCallback), this);
    24492458    if (m_isLegacyPlaybin) {
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp

    r241120 r242701  
    270270MediaPlayerPrivateGStreamerBase::~MediaPlayerPrivateGStreamerBase()
    271271{
     272    flushCurrentBuffer();
    272273#if USE(TEXTURE_MAPPER_GL) && USE(NICOSIA)
    273274    downcast<Nicosia::ContentLayerTextureMapperImpl>(m_nicosiaLayer->impl()).invalidateClient();
     
    847848void MediaPlayerPrivateGStreamerBase::flushCurrentBuffer()
    848849{
    849     GST_DEBUG_OBJECT(pipeline(), "Flushing video sample");
    850850    auto sampleLocker = holdLock(m_sampleMutex);
    851851
     
    859859
    860860    auto proxyOperation =
    861         [](TextureMapperPlatformLayerProxy& proxy)
     861        [shouldWait = m_isVideoDecoderVideo4Linux, pipeline = pipeline()](TextureMapperPlatformLayerProxy& proxy)
    862862        {
    863             LockHolder locker(proxy.lock());
     863            GST_DEBUG_OBJECT(pipeline, "Flushing video sample %s", shouldWait ? "synchronously" : "");
     864            if (!shouldWait)
     865                proxy.lock().lock();
    864866
    865867            if (proxy.isActive())
    866                 proxy.dropCurrentBufferWhilePreservingTexture();
     868                proxy.dropCurrentBufferWhilePreservingTexture(shouldWait);
    867869        };
    868870
     
    10111013
    10121014    GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(appsink, "sink"));
    1013     gst_pad_add_probe(pad.get(), static_cast<GstPadProbeType>(GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH), [] (GstPad*, GstPadProbeInfo* info,  gpointer userData) -> GstPadProbeReturn {
     1015    gst_pad_add_probe(pad.get(), static_cast<GstPadProbeType>(GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH), [] (GstPad*, GstPadProbeInfo* info,  gpointer userData) -> GstPadProbeReturn {
    10141016        // In some platforms (e.g. OpenMAX on the Raspberry Pi) when a resolution change occurs the
    10151017        // pipeline has to be drained before a frame with the new resolution can be decoded.
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h

    r241120 r242701  
    283283    bool m_waitingForKey { false };
    284284#endif
     285
     286    mutable bool m_isVideoDecoderVideo4Linux { false };
    285287};
    286288
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxy.cpp

    r242205 r242701  
    3737#include <wtf/glib/RunLoopSourcePriority.h>
    3838#endif
     39#include <wtf/Scope.h>
    3940
    4041static const Seconds releaseUnusedSecondsTolerance { 1_s };
     
    114115    ASSERT(m_lock.isHeld());
    115116    m_pendingBuffer = WTFMove(newBuffer);
     117    m_wasBufferDropped = false;
    116118
    117119    if (m_compositor)
     
    188190}
    189191
    190 void TextureMapperPlatformLayerProxy::dropCurrentBufferWhilePreservingTexture()
    191 {
    192     ASSERT(m_lock.isHeld());
     192void TextureMapperPlatformLayerProxy::dropCurrentBufferWhilePreservingTexture(bool shouldWait)
     193{
     194    if (!shouldWait)
     195        ASSERT(m_lock.isHeld());
    193196
    194197    if (m_pendingBuffer && m_pendingBuffer->hasManagedTexture()) {
     
    201204
    202205    m_compositorThreadUpdateFunction =
    203         [this] {
     206        [this, shouldWait] {
    204207            LockHolder locker(m_lock);
     208
     209            auto maybeNotifySynchronousOperation = WTF::makeScopeExit([this, shouldWait]() {
     210                if (shouldWait) {
     211                    LockHolder holder(m_wasBufferDroppedLock);
     212                    m_wasBufferDropped = true;
     213                    m_wasBufferDroppedCondition.notifyAll();
     214                }
     215            });
    205216
    206217            if (!m_compositor || !m_targetLayer || !m_currentBuffer)
     
    215226                appendToUnusedBuffers(WTFMove(prevBuffer));
    216227        };
     228
     229    if (shouldWait) {
     230        LockHolder holder(m_wasBufferDroppedLock);
     231        m_wasBufferDropped = false;
     232    }
     233
    217234    m_compositorThreadUpdateTimer->startOneShot(0_s);
     235    if (shouldWait) {
     236        LockHolder holder(m_wasBufferDroppedLock);
     237        m_wasBufferDroppedCondition.wait(m_wasBufferDroppedLock, [this] {
     238            return m_wasBufferDropped;
     239        });
     240    }
    218241}
    219242
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerProxy.h

    r242205 r242701  
    2929
    3030#include "TextureMapperGLHeaders.h"
     31#include <wtf/Condition.h>
    3132#include <wtf/Function.h>
    3233#include <wtf/Lock.h>
     
    6970
    7071    WEBCORE_EXPORT void swapBuffer();
    71     void dropCurrentBufferWhilePreservingTexture();
     72    void dropCurrentBufferWhilePreservingTexture(bool shouldWait = false);
    7273
    7374    bool scheduleUpdateOnCompositorThread(Function<void()>&&);
     
    8687    Lock m_lock;
    8788
     89    Lock m_wasBufferDroppedLock;
     90    Condition m_wasBufferDroppedCondition;
     91    bool m_wasBufferDropped { false };
     92
    8893    Vector<std::unique_ptr<TextureMapperPlatformLayerBuffer>> m_usedBuffers;
    8994    std::unique_ptr<RunLoop::Timer<TextureMapperPlatformLayerProxy>> m_releaseUnusedBuffersTimer;
Note: See TracChangeset for help on using the changeset viewer.