Changeset 208676 in webkit


Ignore:
Timestamp:
Nov 14, 2016 1:56:06 AM (7 years ago)
Author:
Philippe Normand
Message:

[GStreamer][OWR] poor video rendering in apprtc
https://bugs.webkit.org/show_bug.cgi?id=164585

Reviewed by Xabier Rodriguez-Calvar.

The apprtc service uses 3 video elements in total, one for local, one
for remote and one called preview. During a call only remote and
preview are displayed, preview being linked to the same mediastream as
local. The consequence is that 2 OWR video renderers of the same
source are created. When gst-gl is enabled this isn't a problem but
when it is disabled a performance issue appears and the webkit video
sink starts dropping frames.

The solution is to have the video renderer shared between the 2
media players in this scenario.

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:

(WebCore::MediaPlayerPrivateGStreamerBase::videoSink): Add video sink getter.

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp:

(WebCore::MediaPlayerPrivateGStreamerOwr::load): Make sure the m_streamPrivate is
set before creating the video sink.
(WebCore::MediaPlayerPrivateGStreamerOwr::createVideoSink): Re-use video renderer
and sink if they have previously been created for another media player.

  • platform/mediastream/MediaStreamPrivate.h: Store GStreamer sink and renderer so

they can be potentially used by multiple media players.
(WebCore::MediaStreamPrivate::setVideoRenderer):
(WebCore::MediaStreamPrivate::getVideoSinkElement):
(WebCore::MediaStreamPrivate::getVideoRenderer):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r208675 r208676  
     12016-11-10  Philippe Normand  <pnormand@igalia.com>
     2
     3        [GStreamer][OWR] poor video rendering in apprtc
     4        https://bugs.webkit.org/show_bug.cgi?id=164585
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        The apprtc service uses 3 video elements in total, one for local, one
     9        for remote and one called preview. During a call only remote and
     10        preview are displayed, preview being linked to the same mediastream as
     11        local. The consequence is that 2 OWR video renderers of the same
     12        source are created. When gst-gl is enabled this isn't a problem but
     13        when it is disabled a performance issue appears and the webkit video
     14        sink starts dropping frames.
     15
     16        The solution is to have the video renderer shared between the 2
     17        media players in this scenario.
     18
     19        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
     20        (WebCore::MediaPlayerPrivateGStreamerBase::videoSink): Add video sink getter.
     21        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp:
     22        (WebCore::MediaPlayerPrivateGStreamerOwr::load): Make sure the m_streamPrivate is
     23        set before creating the video sink.
     24        (WebCore::MediaPlayerPrivateGStreamerOwr::createVideoSink): Re-use video renderer
     25        and sink if they have previously been created for another media player.
     26        * platform/mediastream/MediaStreamPrivate.h: Store GStreamer sink and renderer so
     27        they can be potentially used by multiple media players.
     28        (WebCore::MediaStreamPrivate::setVideoRenderer):
     29        (WebCore::MediaStreamPrivate::getVideoSinkElement):
     30        (WebCore::MediaStreamPrivate::getVideoRenderer):
     31
    1322016-11-13  Fujii Hironori  <Hironori.Fujii@sony.com>
    233
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h

    r207884 r208676  
    157157#endif
    158158
     159    GstElement* videoSink() const { return m_videoSink.get(); }
     160
    159161    void setStreamVolumeElement(GstStreamVolume*);
    160162    virtual GstElement* createAudioSink() { return 0; }
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp

    r206866 r208676  
    143143        return;
    144144
    145     if (streamPrivate.hasVideo() && !m_videoSink)
    146         createVideoSink();
    147 
    148     if (streamPrivate.hasAudio() && !m_audioSink)
    149         createGSTAudioSinkBin();
    150 
    151     GST_DEBUG("Loading MediaStreamPrivate %p video: %s, audio: %s", &streamPrivate, streamPrivate.hasVideo() ? "yes":"no", streamPrivate.hasAudio() ? "yes":"no");
    152 
    153145    m_streamPrivate = &streamPrivate;
    154146    if (!m_streamPrivate->active()) {
     
    156148        return;
    157149    }
     150
     151    if (streamPrivate.hasVideo() && !m_videoSink)
     152        createVideoSink();
     153
     154    if (streamPrivate.hasAudio() && !m_audioSink)
     155        createGSTAudioSinkBin();
     156
     157    GST_DEBUG("Loading MediaStreamPrivate %p video: %s, audio: %s", &streamPrivate, streamPrivate.hasVideo() ? "yes":"no", streamPrivate.hasAudio() ? "yes":"no");
    158158
    159159    m_readyState = MediaPlayer::HaveNothing;
     
    341341GstElement* MediaPlayerPrivateGStreamerOwr::createVideoSink()
    342342{
     343    GstElement* sink;
    343344#if USE(GSTREAMER_GL)
    344345    // No need to create glupload and glcolorconvert here because they are
    345346    // already created by the video renderer.
    346     GstElement* sink = MediaPlayerPrivateGStreamerBase::createGLAppSink();
     347    // FIXME: This should probably return a RefPtr. See https://bugs.webkit.org/show_bug.cgi?id=164709.
     348    sink = MediaPlayerPrivateGStreamerBase::createGLAppSink();
    347349    m_videoSink = sink;
    348350#else
    349     GstElement* sink = gst_bin_new(nullptr);
    350     GstElement* gldownload = gst_element_factory_make("gldownload", nullptr);
    351     GstElement* videoconvert = gst_element_factory_make("videoconvert", nullptr);
    352     GstElement* webkitSink = MediaPlayerPrivateGStreamerBase::createVideoSink();
    353     gst_bin_add_many(GST_BIN(sink), gldownload, videoconvert, webkitSink, nullptr);
    354     gst_element_link_many(gldownload, videoconvert, webkitSink, nullptr);
    355     GRefPtr<GstPad> pad = gst_element_get_static_pad(gldownload, "sink");
    356     gst_element_add_pad(sink, gst_ghost_pad_new("sink", pad.get()));
     351    if (m_streamPrivate->getVideoRenderer()) {
     352        m_videoRenderer = m_streamPrivate->getVideoRenderer();
     353        m_videoSink = m_streamPrivate->getVideoSinkElement();
     354        g_signal_connect_swapped(m_videoSink.get(), "repaint-requested", G_CALLBACK(MediaPlayerPrivateGStreamerBase::repaintCallback), this);
     355        g_object_get(m_videoRenderer.get(), "sink", &sink, nullptr);
     356    } else {
     357        GstElement* gldownload = gst_element_factory_make("gldownload", nullptr);
     358        GstElement* videoconvert = gst_element_factory_make("videoconvert", nullptr);
     359        GstElement* webkitSink = MediaPlayerPrivateGStreamerBase::createVideoSink();
     360        sink = gst_bin_new(nullptr);
     361        gst_bin_add_many(GST_BIN(sink), gldownload, videoconvert, webkitSink, nullptr);
     362        gst_element_link_many(gldownload, videoconvert, webkitSink, nullptr);
     363        GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(gldownload, "sink"));
     364        gst_element_add_pad(sink, gst_ghost_pad_new("sink", pad.get()));
     365    }
    357366#endif
    358 
    359     m_videoRenderer = adoptGRef(owr_gst_video_renderer_new(sink));
     367    if (!m_videoRenderer) {
     368        m_videoRenderer = adoptGRef(owr_gst_video_renderer_new(sink));
    360369#if USE(GSTREAMER_GL)
    361     owr_video_renderer_set_request_context_callback(OWR_VIDEO_RENDERER(m_videoRenderer.get()), (OwrVideoRendererRequestContextCallback) MediaPlayerPrivateGStreamerBase::requestGLContext, this, nullptr);
     370        owr_video_renderer_set_request_context_callback(OWR_VIDEO_RENDERER(m_videoRenderer.get()), (OwrVideoRendererRequestContextCallback) MediaPlayerPrivateGStreamerBase::requestGLContext, this, nullptr);
    362371#endif
     372        m_streamPrivate->setVideoRenderer(m_videoRenderer.get(), videoSink());
     373    }
    363374    return sink;
    364375}
  • trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h

    r202439 r208676  
    4747#include <wtf/Vector.h>
    4848#include <wtf/WeakPtr.h>
     49
     50#if USE(GSTREAMER)
     51#include "GRefPtrGStreamer.h"
     52#include <owr/owr_gst_video_renderer.h>
     53#endif
    4954
    5055namespace WebCore {
     
    101106    WeakPtr<MediaStreamPrivate> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
    102107
     108#if USE(GSTREAMER)
     109    void setVideoRenderer(OwrGstVideoRenderer* renderer, GstElement* sink) { m_gstVideoRenderer = renderer; m_gstVideoSinkElement = sink; }
     110    GRefPtr<GstElement> getVideoSinkElement() const { return m_gstVideoSinkElement; }
     111    GRefPtr<OwrGstVideoRenderer> getVideoRenderer() const { return m_gstVideoRenderer; }
     112
     113private:
     114    GRefPtr<GstElement> m_gstVideoSinkElement;
     115    GRefPtr<OwrGstVideoRenderer> m_gstVideoRenderer;
     116#endif
     117
    103118private:
    104119    MediaStreamPrivate(const String&, const MediaStreamTrackPrivateVector&);
Note: See TracChangeset for help on using the changeset viewer.