Skip to content
Permalink
Browse files
[GTK] Use GMainLoopSource for idle and timeout sources in WebCore
https://bugs.webkit.org/show_bug.cgi?id=130078

Reviewed by Philippe Normand.

* platform/audio/gstreamer/AudioFileReaderGStreamer.cpp:
* platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
* platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
* platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp:
* platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h:
* platform/graphics/gstreamer/VideoSinkGStreamer.cpp:
* platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp:
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
* platform/gtk/GtkDragAndDropHelper.cpp:
* platform/gtk/SharedTimerGtk.cpp:

Canonical link: https://commits.webkit.org/149007@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@166496 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
carlosgcampos committed Mar 31, 2014
1 parent 380668a commit 69069462caca7ff69526f04d9e91c23268c5c00d
Showing 15 changed files with 206 additions and 464 deletions.
@@ -1,3 +1,25 @@
2014-03-20 Carlos Garcia Campos <cgarcia@igalia.com>

[GTK] Use GMainLoopSource for idle and timeout sources in WebCore
https://bugs.webkit.org/show_bug.cgi?id=130078

Reviewed by Philippe Normand.

* platform/audio/gstreamer/AudioFileReaderGStreamer.cpp:
* platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
* platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
* platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp:
* platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h:
* platform/graphics/gstreamer/VideoSinkGStreamer.cpp:
* platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp:
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
* platform/gtk/GtkDragAndDropHelper.cpp:
* platform/gtk/SharedTimerGtk.cpp:

2014-03-31 Andrei Bucur <abucur@adobe.com>

Wrong layout while animating content in regions
@@ -27,14 +27,14 @@

#include <gio/gio.h>
#include <gst/app/gstappsink.h>
#include <gst/audio/audio.h>
#include <gst/gst.h>
#include <gst/pbutils/pbutils.h>
#include <wtf/Noncopyable.h>
#include <wtf/gobject/GMainLoopSource.h>
#include <wtf/gobject/GRefPtr.h>
#include <wtf/gobject/GUniquePtr.h>

#include <gst/audio/audio.h>

namespace WebCore {

class AudioFileReader {
@@ -108,13 +108,6 @@ static void onGStreamerDecodebinPadAddedCallback(GstElement*, GstPad* pad, Audio
reader->plugDeinterleave(pad);
}

gboolean enteredMainLoopCallback(gpointer userData)
{
AudioFileReader* reader = reinterpret_cast<AudioFileReader*>(userData);
reader->decodeAudioForBusCreation();
return FALSE;
}

AudioFileReader::AudioFileReader(const char* filePath)
: m_data(0)
, m_dataSize(0)
@@ -341,9 +334,8 @@ PassRefPtr<AudioBus> AudioFileReader::createBus(float sampleRate, bool mixToMono
m_loop = adoptGRef(g_main_loop_new(context.get(), FALSE));

// Start the pipeline processing just after the loop is started.
GRefPtr<GSource> timeoutSource = adoptGRef(g_timeout_source_new(0));
g_source_attach(timeoutSource.get(), context.get());
g_source_set_callback(timeoutSource.get(), reinterpret_cast<GSourceFunc>(enteredMainLoopCallback), this, 0);
GMainLoopSource source;
source.schedule("[WebKit] AudioFileReader::decodeAudioForBusCreation", std::bind(&AudioFileReader::decodeAudioForBusCreation, this), G_PRIORITY_DEFAULT, nullptr, context.get());

g_main_loop_run(m_loop.get());
g_main_context_pop_thread_default(context.get());
@@ -52,22 +52,8 @@ static GstPadProbeReturn textTrackPrivateEventCallback(GstPad*, GstPadProbeInfo*
return GST_PAD_PROBE_OK;
}

static gboolean textTrackPrivateSampleTimeoutCallback(InbandTextTrackPrivateGStreamer* track)
{
track->notifyTrackOfSample();
return FALSE;
}

static gboolean textTrackPrivateStreamTimeoutCallback(InbandTextTrackPrivateGStreamer* track)
{
track->notifyTrackOfStreamChanged();
return FALSE;
}

InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad> pad)
: InbandTextTrackPrivate(WebVTT), TrackPrivateBaseGStreamer(this, index, pad)
, m_sampleTimerHandler(0)
, m_streamTimerHandler(0)
{
m_eventProbe = gst_pad_add_probe(m_pad.get(), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
reinterpret_cast<GstPadProbeCallback>(textTrackPrivateEventCallback), this, 0);
@@ -82,36 +68,28 @@ void InbandTextTrackPrivateGStreamer::disconnect()

gst_pad_remove_probe(m_pad.get(), m_eventProbe);

if (m_streamTimerHandler)
g_source_remove(m_streamTimerHandler);
m_streamTimerHandler.cancel();

TrackPrivateBaseGStreamer::disconnect();
}

void InbandTextTrackPrivateGStreamer::handleSample(GRefPtr<GstSample> sample)
{
if (m_sampleTimerHandler)
g_source_remove(m_sampleTimerHandler);
m_sampleTimerHandler.cancel();
{
MutexLocker lock(m_sampleMutex);
m_pendingSamples.append(sample);
}
m_sampleTimerHandler = g_timeout_add(0,
reinterpret_cast<GSourceFunc>(textTrackPrivateSampleTimeoutCallback), this);
m_sampleTimerHandler.schedule("[WebKit] InbandTextTrackPrivateGStreamer::notifyTrackOfSample", std::bind(&InbandTextTrackPrivateGStreamer::notifyTrackOfSample, this));
}

void InbandTextTrackPrivateGStreamer::streamChanged()
{
if (m_streamTimerHandler)
g_source_remove(m_streamTimerHandler);
m_streamTimerHandler = g_timeout_add(0,
reinterpret_cast<GSourceFunc>(textTrackPrivateStreamTimeoutCallback), this);
m_streamTimerHandler.schedule("[WebKit] InbandTextTrackPrivateGStreamer::notifyTrackOfStreamChanged", std::bind(&InbandTextTrackPrivateGStreamer::notifyTrackOfStreamChanged, this));
}

void InbandTextTrackPrivateGStreamer::notifyTrackOfSample()
{
m_sampleTimerHandler = 0;

Vector<GRefPtr<GstSample> > samples;
{
MutexLocker lock(m_sampleMutex);
@@ -142,8 +120,6 @@ void InbandTextTrackPrivateGStreamer::notifyTrackOfSample()

void InbandTextTrackPrivateGStreamer::notifyTrackOfStreamChanged()
{
m_streamTimerHandler = 0;

GRefPtr<GstEvent> event = adoptGRef(gst_pad_get_sticky_event(m_pad.get(),
GST_EVENT_STREAM_START, 0));
if (!event)
@@ -31,6 +31,7 @@
#include "GRefPtrGStreamer.h"
#include "InbandTextTrackPrivate.h"
#include "TrackPrivateBaseGStreamer.h"
#include <wtf/gobject/GMainLoopSource.h>

namespace WebCore {

@@ -61,8 +62,8 @@ class InbandTextTrackPrivateGStreamer : public InbandTextTrackPrivate, public Tr
private:
InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad>);

guint m_sampleTimerHandler;
guint m_streamTimerHandler;
GMainLoopSource m_sampleTimerHandler;
GMainLoopSource m_streamTimerHandler;
gulong m_eventProbe;
Vector<GRefPtr<GstSample> > m_pendingSamples;
String m_streamId;
@@ -58,7 +58,7 @@

// Max interval in seconds to stay in the READY state on manual
// state change requests.
static const guint gReadyStateTimerInterval = 60;
static const unsigned gReadyStateTimerInterval = 60;

GST_DEBUG_CATEGORY_EXTERN(webkit_media_player_debug);
#define GST_CAT_DEFAULT webkit_media_player_debug
@@ -92,61 +92,25 @@ static void mediaPlayerPrivateAudioChangedCallback(GObject*, MediaPlayerPrivateG
player->audioChanged();
}

static gboolean mediaPlayerPrivateAudioChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
{
// This is the callback of the timeout source created in ::audioChanged.
player->notifyPlayerOfAudio();
return FALSE;
}

static void setAudioStreamPropertiesCallback(GstChildProxy*, GObject* object, gchar*,
MediaPlayerPrivateGStreamer* player)
{
player->setAudioStreamProperties(object);
}

static gboolean mediaPlayerPrivateVideoChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
{
// This is the callback of the timeout source created in ::videoChanged.
player->notifyPlayerOfVideo();
return FALSE;
}

static gboolean mediaPlayerPrivateVideoCapsChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
{
// This is the callback of the timeout source created in ::videoCapsChanged.
player->notifyPlayerOfVideoCaps();
return FALSE;
}

#if ENABLE(VIDEO_TRACK)
static void mediaPlayerPrivateTextChangedCallback(GObject*, MediaPlayerPrivateGStreamer* player)
{
player->textChanged();
}

static gboolean mediaPlayerPrivateTextChangeTimeoutCallback(MediaPlayerPrivateGStreamer* player)
{
// This is the callback of the timeout source created in ::textChanged.
player->notifyPlayerOfText();
return FALSE;
}

static GstFlowReturn mediaPlayerPrivateNewTextSampleCallback(GObject*, MediaPlayerPrivateGStreamer* player)
{
player->newTextSample();
return GST_FLOW_OK;
}
#endif

static gboolean mediaPlayerPrivateReadyStateTimeoutCallback(MediaPlayerPrivateGStreamer* player)
{
// This is the callback of the timeout source created in ::changePipelineState.
// Reset pipeline if we are sitting on READY state when timeout is reached
player->changePipelineState(GST_STATE_NULL);
return FALSE;
}

static void mediaPlayerPrivatePluginInstallerResultFunction(GstInstallPluginsReturn result, gpointer userData)
{
MediaPlayerPrivateGStreamer* player = reinterpret_cast<MediaPlayerPrivateGStreamer*>(userData);
@@ -249,11 +213,6 @@ MediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer(MediaPlayer* player)
, m_volumeAndMuteInitialized(false)
, m_hasVideo(false)
, m_hasAudio(false)
, m_audioTimerHandler(0)
, m_textTimerHandler(0)
, m_videoTimerHandler(0)
, m_videoCapsTimerHandler(0)
, m_readyTimerHandler(0)
, m_totalBytes(-1)
, m_preservesPitch(false)
, m_requestedState(GST_STATE_VOID_PENDING)
@@ -285,8 +244,7 @@ MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer()
g_signal_handlers_disconnect_by_func(G_OBJECT(m_autoAudioSink.get()),
reinterpret_cast<gpointer>(setAudioStreamPropertiesCallback), this);

if (m_readyTimerHandler)
g_source_remove(m_readyTimerHandler);
m_readyTimerHandler.cancel();

if (m_playBin) {
GRefPtr<GstBus> bus = adoptGRef(gst_pipeline_get_bus(GST_PIPELINE(m_playBin.get())));
@@ -308,18 +266,6 @@ MediaPlayerPrivateGStreamer::~MediaPlayerPrivateGStreamer()

GRefPtr<GstPad> videoSinkPad = adoptGRef(gst_element_get_static_pad(m_webkitVideoSink.get(), "sink"));
g_signal_handlers_disconnect_by_func(videoSinkPad.get(), reinterpret_cast<gpointer>(mediaPlayerPrivateVideoSinkCapsChangedCallback), this);

if (m_videoTimerHandler)
g_source_remove(m_videoTimerHandler);

if (m_audioTimerHandler)
g_source_remove(m_audioTimerHandler);

if (m_textTimerHandler)
g_source_remove(m_textTimerHandler);

if (m_videoCapsTimerHandler)
g_source_remove(m_videoCapsTimerHandler);
}

void MediaPlayerPrivateGStreamer::load(const String& url)
@@ -443,12 +389,11 @@ bool MediaPlayerPrivateGStreamer::changePipelineState(GstState newState)
// if we stay for too long on READY.
// Also lets remove the timer if we request a state change for any state other than READY.
// See also https://bugs.webkit.org/show_bug.cgi?id=117354
if (newState == GST_STATE_READY && !m_readyTimerHandler) {
m_readyTimerHandler = g_timeout_add_seconds(gReadyStateTimerInterval, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateReadyStateTimeoutCallback), this);
g_source_set_name_by_id(m_readyTimerHandler, "[WebKit] mediaPlayerPrivateReadyStateTimeoutCallback");
} else if (newState != GST_STATE_READY && m_readyTimerHandler) {
g_source_remove(m_readyTimerHandler);
m_readyTimerHandler = 0;
if (newState == GST_STATE_READY && !m_readyTimerHandler.isScheduled()) {
m_readyTimerHandler.scheduleAfterDelay("[WebKit] mediaPlayerPrivateReadyStateTimeoutCallback", [this] { changePipelineState(GST_STATE_NULL); },
std::chrono::seconds(gReadyStateTimerInterval));
} else if (newState != GST_STATE_READY && m_readyTimerHandler.isScheduled()) {
m_readyTimerHandler.cancel();
}

return true;
@@ -669,24 +614,16 @@ bool MediaPlayerPrivateGStreamer::seeking() const

void MediaPlayerPrivateGStreamer::videoChanged()
{
if (m_videoTimerHandler)
g_source_remove(m_videoTimerHandler);
m_videoTimerHandler = g_idle_add_full(G_PRIORITY_DEFAULT, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateVideoChangeTimeoutCallback), this, 0);
g_source_set_name_by_id(m_videoTimerHandler, "[WebKit] mediaPlayerPrivateVideoChangeTimeoutCallback");
m_videoTimerHandler.schedule("[WebKit] MediaPlayerPrivateGStreamer::videoChanged", std::bind(&MediaPlayerPrivateGStreamer::notifyPlayerOfVideo, this));
}

void MediaPlayerPrivateGStreamer::videoCapsChanged()
{
if (m_videoCapsTimerHandler)
g_source_remove(m_videoCapsTimerHandler);
m_videoCapsTimerHandler = g_timeout_add(0, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateVideoCapsChangeTimeoutCallback), this);
g_source_set_name_by_id(m_videoCapsTimerHandler, "[WebKit] mediaPlayerPrivateVideoCapsChangeTimeoutCallback");
m_videoCapsTimerHandler.schedule("[WebKit] MediaPlayerPrivateGStreamer::videoCapsChanged", std::bind(&MediaPlayerPrivateGStreamer::notifyPlayerOfVideoCaps, this));
}

void MediaPlayerPrivateGStreamer::notifyPlayerOfVideo()
{
m_videoTimerHandler = 0;

gint numTracks = 0;
if (m_playBin)
g_object_get(m_playBin.get(), "n-video", &numTracks, NULL);
@@ -724,23 +661,17 @@ void MediaPlayerPrivateGStreamer::notifyPlayerOfVideo()

void MediaPlayerPrivateGStreamer::notifyPlayerOfVideoCaps()
{
m_videoCapsTimerHandler = 0;
m_videoSize = IntSize();
m_player->mediaPlayerClient()->mediaPlayerEngineUpdated(m_player);
}

void MediaPlayerPrivateGStreamer::audioChanged()
{
if (m_audioTimerHandler)
g_source_remove(m_audioTimerHandler);
m_audioTimerHandler = g_idle_add_full(G_PRIORITY_DEFAULT, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateAudioChangeTimeoutCallback), this, 0);
g_source_set_name_by_id(m_audioTimerHandler, "[WebKit] mediaPlayerPrivateAudioChangeTimeoutCallback");
m_audioTimerHandler.schedule("[WebKit] MediaPlayerPrivateGStreamer::audioChanged", std::bind(&MediaPlayerPrivateGStreamer::notifyPlayerOfAudio, this));
}

void MediaPlayerPrivateGStreamer::notifyPlayerOfAudio()
{
m_audioTimerHandler = 0;

gint numTracks = 0;
if (m_playBin)
g_object_get(m_playBin.get(), "n-audio", &numTracks, NULL);
@@ -779,16 +710,11 @@ void MediaPlayerPrivateGStreamer::notifyPlayerOfAudio()
#if ENABLE(VIDEO_TRACK)
void MediaPlayerPrivateGStreamer::textChanged()
{
if (m_textTimerHandler)
g_source_remove(m_textTimerHandler);
m_textTimerHandler = g_timeout_add(0, reinterpret_cast<GSourceFunc>(mediaPlayerPrivateTextChangeTimeoutCallback), this);
g_source_set_name_by_id(m_textTimerHandler, "[WebKit] mediaPlayerPrivateTextChangeTimeoutCallback");
m_textTimerHandler.schedule("[WebKit] MediaPlayerPrivateGStreamer::textChanged", std::bind(&MediaPlayerPrivateGStreamer::notifyPlayerOfText, this));
}

void MediaPlayerPrivateGStreamer::notifyPlayerOfText()
{
m_textTimerHandler = 0;

gint numTracks = 0;
if (m_playBin)
g_object_get(m_playBin.get(), "n-text", &numTracks, NULL);
@@ -1640,10 +1566,7 @@ void MediaPlayerPrivateGStreamer::loadingFailed(MediaPlayer::NetworkState error)
}

// Loading failed, remove ready timer.
if (m_readyTimerHandler) {
g_source_remove(m_readyTimerHandler);
m_readyTimerHandler = 0;
}
m_readyTimerHandler.cancel();
}

static HashSet<String> mimeTypeCache()
@@ -32,6 +32,7 @@
#include <gst/gst.h>
#include <gst/pbutils/install-plugins.h>
#include <wtf/Forward.h>
#include <wtf/gobject/GMainLoopSource.h>

#if ENABLE(MEDIA_SOURCE)
#include "MediaSourceGStreamer.h"
@@ -189,11 +190,11 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateGStreamerBase {
bool m_volumeAndMuteInitialized;
bool m_hasVideo;
bool m_hasAudio;
guint m_audioTimerHandler;
guint m_textTimerHandler;
guint m_videoTimerHandler;
guint m_videoCapsTimerHandler;
guint m_readyTimerHandler;
GMainLoopSource m_audioTimerHandler;
GMainLoopSource m_textTimerHandler;
GMainLoopSource m_videoTimerHandler;
GMainLoopSource m_videoCapsTimerHandler;
GMainLoopSource m_readyTimerHandler;
mutable long m_totalBytes;
URL m_url;
bool m_preservesPitch;

0 comments on commit 6906946

Please sign in to comment.