Changeset 242793 in webkit


Ignore:
Timestamp:
Mar 12, 2019 7:17:06 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

    r242792 r242793  
     12019-03-12  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-12  Ryosuke Niwa  <rniwa@webkit.org>
    242
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

    r242789 r242793  
    24012401    g_object_set(m_pipeline.get(), "mute", m_player->muted(), nullptr);
    24022402
     2403    g_signal_connect(GST_BIN_CAST(m_pipeline.get()), "deep-element-added", G_CALLBACK(+[](GstBin*, GstBin* subBin, GstElement* element, MediaPlayerPrivateGStreamer* player) {
     2404        GUniquePtr<char> binName(gst_element_get_name(GST_ELEMENT_CAST(subBin)));
     2405        if (!g_str_has_prefix(binName.get(), "decodebin"))
     2406            return;
     2407
     2408        GUniquePtr<char> elementName(gst_element_get_name(element));
     2409        player->m_isVideoDecoderVideo4Linux = g_str_has_prefix(elementName.get(), "v4l2");
     2410    }), this);
     2411
    24032412    g_signal_connect_swapped(m_pipeline.get(), "source-setup", G_CALLBACK(sourceSetupCallback), this);
    24042413    if (m_isLegacyPlaybin) {
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp

    r242789 r242793  
    270270MediaPlayerPrivateGStreamerBase::~MediaPlayerPrivateGStreamerBase()
    271271{
     272#if USE(GSTREAMER_GL)
     273    if (m_isVideoDecoderVideo4Linux)
     274        flushCurrentBuffer();
     275#endif
    272276#if USE(TEXTURE_MAPPER_GL) && USE(NICOSIA)
    273277    downcast<Nicosia::ContentLayerTextureMapperImpl>(m_nicosiaLayer->impl()).invalidateClient();
     
    847851void MediaPlayerPrivateGStreamerBase::flushCurrentBuffer()
    848852{
    849     GST_DEBUG_OBJECT(pipeline(), "Flushing video sample");
    850853    auto sampleLocker = holdLock(m_sampleMutex);
    851854
     
    859862
    860863    auto proxyOperation =
    861         [](TextureMapperPlatformLayerProxy& proxy)
     864        [shouldWait = m_isVideoDecoderVideo4Linux, pipeline = pipeline()](TextureMapperPlatformLayerProxy& proxy)
    862865        {
    863             LockHolder locker(proxy.lock());
     866            GST_DEBUG_OBJECT(pipeline, "Flushing video sample %s", shouldWait ? "synchronously" : "");
     867            LockHolder locker(!shouldWait ? &proxy.lock() : nullptr);
    864868
    865869            if (proxy.isActive())
    866                 proxy.dropCurrentBufferWhilePreservingTexture();
     870                proxy.dropCurrentBufferWhilePreservingTexture(shouldWait);
    867871        };
    868872
     
    10111015
    10121016    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 {
     1017    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 {
    10141018        // In some platforms (e.g. OpenMAX on the Raspberry Pi) when a resolution change occurs the
    10151019        // pipeline has to be drained before a frame with the new resolution can be decoded.
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h

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

    r242725 r242793  
    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

    r242725 r242793  
    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.