[GStreamer] Consolidate more code into TrackPrivateBaseGStreamer
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 10 Nov 2013 14:52:53 +0000 (14:52 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 10 Nov 2013 14:52:53 +0000 (14:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=124020

Patch by Brendan Long <b.long@cablelabs.com> on 2013-11-10
Reviewed by Philippe Normand.

No new tests because this is just refactoring.

* platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp:
(WebCore::AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer): Don't pass playbin to TrackPrivateBaseGStreamer, and do pass a pointer to "this".
(WebCore::AudioTrackPrivateGStreamer::disconnect): Clear m_playbin().
* platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h: Move labelChanged() and languageChanged() to TrackPrivateBaseGStreamer. Move m_playbin to this class (along with disconnect() to clear it).
* platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp: Move tag handling, pad and index to TrackPrivateBaseGStreamer.
(WebCore::textTrackPrivateEventCallback):
(WebCore::InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer):
(WebCore::InbandTextTrackPrivateGStreamer::disconnect):
* platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
* platform/graphics/gstreamer/TextCombinerGStreamer.cpp: Add WebKitTextCombinerPad with "tags" property, set in the same was as input-selector's pads.
(webkit_text_combiner_pad_init): Initialize tags to 0.
(webkitTextCombinerPadFinalize): Clear tags.
(webkitTextCombinerPadGetProperty): Handling "tags" property.
(webkitTextCombinerPadEvent): Changed to be a pad event function instead of a pad probe, and now intercepts tags and merges them (like input-selector pads do).
(webkitTextCombinerRequestNewPad): Using WebKitTextCombinerPad instead of just GhostPad.
(webkit_text_combiner_pad_class_init): Setup WebKitTextCombinerPad.
* platform/graphics/gstreamer/TextCombinerGStreamer.h: Remove superfluous code.
* platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp:
(WebCore::TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer): Use "notify::active" so we don't need a playbin, and immediately check for tags after the constructor.
(WebCore::TrackPrivateBaseGStreamer::disconnect): Remove m_playbin.
(WebCore::TrackPrivateBaseGStreamer::getTag): Refactored out from notifyTrackOfTagsChanged.
(WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): Simplify using m_owner (so we can call labelChanged() and languageChanged() directly), and use getTag() above.
* platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h: Add m_owner to we can access the owning track, and change some functions to match our needs better.
(WebCore::TrackPrivateBaseGStreamer::setActive): Add empty default since InbandTextTrackPrivateGStreamer doesn't need this.
* platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp: Same as AudioTrackPrivateGStreamer.
(WebCore::VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer):
(WebCore::VideoTrackPrivateGStreamer::disconnect):
* platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h: Same as AudioTrackPrivateGStreamer.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@159024 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp
Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h
Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp
Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h
Source/WebCore/platform/graphics/gstreamer/TextCombinerGStreamer.cpp
Source/WebCore/platform/graphics/gstreamer/TextCombinerGStreamer.h
Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp
Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h
Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp
Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h

index 699222f..ddd9204 100644 (file)
@@ -1,3 +1,41 @@
+2013-11-10  Brendan Long  <b.long@cablelabs.com>
+
+        [GStreamer] Consolidate more code into TrackPrivateBaseGStreamer
+        https://bugs.webkit.org/show_bug.cgi?id=124020
+
+        Reviewed by Philippe Normand.
+
+        No new tests because this is just refactoring.
+
+        * platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp:
+        (WebCore::AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer): Don't pass playbin to TrackPrivateBaseGStreamer, and do pass a pointer to "this".
+        (WebCore::AudioTrackPrivateGStreamer::disconnect): Clear m_playbin().
+        * platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h: Move labelChanged() and languageChanged() to TrackPrivateBaseGStreamer. Move m_playbin to this class (along with disconnect() to clear it).
+        * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp: Move tag handling, pad and index to TrackPrivateBaseGStreamer.
+        (WebCore::textTrackPrivateEventCallback):
+        (WebCore::InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer):
+        (WebCore::InbandTextTrackPrivateGStreamer::disconnect):
+        * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
+        * platform/graphics/gstreamer/TextCombinerGStreamer.cpp: Add WebKitTextCombinerPad with "tags" property, set in the same was as input-selector's pads.
+        (webkit_text_combiner_pad_init): Initialize tags to 0.
+        (webkitTextCombinerPadFinalize): Clear tags.
+        (webkitTextCombinerPadGetProperty): Handling "tags" property.
+        (webkitTextCombinerPadEvent): Changed to be a pad event function instead of a pad probe, and now intercepts tags and merges them (like input-selector pads do).
+        (webkitTextCombinerRequestNewPad): Using WebKitTextCombinerPad instead of just GhostPad.
+        (webkit_text_combiner_pad_class_init): Setup WebKitTextCombinerPad.
+        * platform/graphics/gstreamer/TextCombinerGStreamer.h: Remove superfluous code.
+        * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp:
+        (WebCore::TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer): Use "notify::active" so we don't need a playbin, and immediately check for tags after the constructor.
+        (WebCore::TrackPrivateBaseGStreamer::disconnect): Remove m_playbin.
+        (WebCore::TrackPrivateBaseGStreamer::getTag): Refactored out from notifyTrackOfTagsChanged.
+        (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged): Simplify using m_owner (so we can call labelChanged() and languageChanged() directly), and use getTag() above.
+        * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h: Add m_owner to we can access the owning track, and change some functions to match our needs better.
+        (WebCore::TrackPrivateBaseGStreamer::setActive): Add empty default since InbandTextTrackPrivateGStreamer doesn't need this.
+        * platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp: Same as AudioTrackPrivateGStreamer.
+        (WebCore::VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer):
+        (WebCore::VideoTrackPrivateGStreamer::disconnect):
+        * platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h: Same as AudioTrackPrivateGStreamer.
+
 2013-11-10  Andreas Kling  <akling@apple.com>
 
         Generate type casting helpers for Widget classes.
index fa55967..90d30a6 100644 (file)
 namespace WebCore {
 
 AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(GRefPtr<GstElement> playbin, gint index, GRefPtr<GstPad> pad)
-    : TrackPrivateBaseGStreamer("notify::current-audio", playbin, index, pad)
+    : TrackPrivateBaseGStreamer(this, index, pad)
+    , m_playbin(playbin)
 {
-    activeChanged();
-    tagsChanged();
+    notifyTrackOfActiveChanged();
+}
+
+void AudioTrackPrivateGStreamer::disconnect()
+{
+    m_playbin.clear();
+    TrackPrivateBaseGStreamer::disconnect();
 }
 
 void AudioTrackPrivateGStreamer::setEnabled(bool enabled)
@@ -50,18 +56,6 @@ void AudioTrackPrivateGStreamer::setEnabled(bool enabled)
         g_object_set(m_playbin.get(), "current-audio", m_index, NULL);
 }
 
-void AudioTrackPrivateGStreamer::labelChanged(const String& label)
-{
-    if (client())
-        client()->labelChanged(this, label);
-}
-
-void AudioTrackPrivateGStreamer::languageChanged(const String& language)
-{
-    if (client())
-        client()->languageChanged(this, language);
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK) && defined(GST_API_VERSION_1)
index 5d02043..b1e8a48 100644 (file)
@@ -41,6 +41,8 @@ public:
         return adoptRef(new AudioTrackPrivateGStreamer(playbin, index, pad));
     }
 
+    virtual void disconnect() OVERRIDE;
+
     virtual void setEnabled(bool) OVERRIDE;
     virtual void setActive(bool enabled) OVERRIDE { setEnabled(enabled); }
 
@@ -49,11 +51,10 @@ public:
     virtual AtomicString label() const OVERRIDE { return m_label; }
     virtual AtomicString language() const OVERRIDE { return m_language; }
 
-    virtual void labelChanged(const String&) OVERRIDE;
-    virtual void languageChanged(const String&) OVERRIDE;
-
 private:
     AudioTrackPrivateGStreamer(GRefPtr<GstElement> playbin, gint index, GRefPtr<GstPad>);
+
+    GRefPtr<GstElement> m_playbin;
 };
 
 } // namespace WebCore
index 70d838c..c849b8c 100644 (file)
@@ -43,9 +43,6 @@ static GstPadProbeReturn textTrackPrivateEventCallback(GstPad*, GstPadProbeInfo*
 {
     GstEvent* event = gst_pad_probe_info_get_event(info);
     switch (GST_EVENT_TYPE(event)) {
-    case GST_EVENT_TAG:
-        track->tagsChanged();
-        break;
     case GST_EVENT_STREAM_START:
         track->streamChanged();
         break;
@@ -67,32 +64,15 @@ static gboolean textTrackPrivateStreamTimeoutCallback(InbandTextTrackPrivateGStr
     return FALSE;
 }
 
-static gboolean textTrackPrivateTagsChangeTimeoutCallback(InbandTextTrackPrivateGStreamer* track)
-{
-    track->notifyTrackOfTagsChanged();
-    return FALSE;
-}
-
 InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad> pad)
-    : InbandTextTrackPrivate(WebVTT)
-    , m_index(index)
-    , m_pad(pad)
+    : InbandTextTrackPrivate(WebVTT), TrackPrivateBaseGStreamer(this, index, pad)
     , m_sampleTimerHandler(0)
     , m_streamTimerHandler(0)
-    , m_tagTimerHandler(0)
 {
-    ASSERT(m_pad);
     m_eventProbe = gst_pad_add_probe(m_pad.get(), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
         reinterpret_cast<GstPadProbeCallback>(textTrackPrivateEventCallback), this, 0);
 
-    /* We want to check these in case we got events before the track was created */
-    streamChanged();
-    tagsChanged();
-}
-
-InbandTextTrackPrivateGStreamer::~InbandTextTrackPrivateGStreamer()
-{
-    disconnect();
+    notifyTrackOfStreamChanged();
 }
 
 void InbandTextTrackPrivateGStreamer::disconnect()
@@ -101,13 +81,11 @@ void InbandTextTrackPrivateGStreamer::disconnect()
         return;
 
     gst_pad_remove_probe(m_pad.get(), m_eventProbe);
-    g_signal_handlers_disconnect_by_func(m_pad.get(),
-        reinterpret_cast<gpointer>(textTrackPrivateEventCallback), this);
 
-    if (m_tagTimerHandler)
-        g_source_remove(m_tagTimerHandler);
+    if (m_streamTimerHandler)
+        g_source_remove(m_streamTimerHandler);
 
-    m_pad.clear();
+    TrackPrivateBaseGStreamer::disconnect();
 }
 
 void InbandTextTrackPrivateGStreamer::handleSample(GRefPtr<GstSample> sample)
@@ -130,14 +108,6 @@ void InbandTextTrackPrivateGStreamer::streamChanged()
         reinterpret_cast<GSourceFunc>(textTrackPrivateStreamTimeoutCallback), this);
 }
 
-void InbandTextTrackPrivateGStreamer::tagsChanged()
-{
-    if (m_tagTimerHandler)
-        g_source_remove(m_tagTimerHandler);
-    m_tagTimerHandler = g_timeout_add(0,
-        reinterpret_cast<GSourceFunc>(textTrackPrivateTagsChangeTimeoutCallback), this);
-}
-
 void InbandTextTrackPrivateGStreamer::notifyTrackOfSample()
 {
     m_sampleTimerHandler = 0;
@@ -185,45 +155,6 @@ void InbandTextTrackPrivateGStreamer::notifyTrackOfStreamChanged()
     m_streamId = streamId;
 }
 
-void InbandTextTrackPrivateGStreamer::notifyTrackOfTagsChanged()
-{
-    m_tagTimerHandler = 0;
-    if (!m_pad)
-        return;
-
-    String label;
-    String language;
-    GRefPtr<GstEvent> event;
-    for (guint i = 0; (event = adoptGRef(gst_pad_get_sticky_event(m_pad.get(), GST_EVENT_TAG, i))); ++i) {
-        GstTagList* tags = 0;
-        gst_event_parse_tag(event.get(), &tags);
-        ASSERT(tags);
-
-        gchar* tagValue;
-        if (gst_tag_list_get_string(tags, GST_TAG_TITLE, &tagValue)) {
-            INFO_MEDIA_MESSAGE("Text track %d got title %s.", m_index, tagValue);
-            label = tagValue;
-            g_free(tagValue);
-        }
-
-        if (gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &tagValue)) {
-            INFO_MEDIA_MESSAGE("Text track %d got language %s.", m_index, tagValue);
-            language = tagValue;
-            g_free(tagValue);
-        }
-    }
-
-    if (m_label != label) {
-        m_label = label;
-        client()->labelChanged(this, m_label);
-    }
-
-    if (m_language != language) {
-        m_language = language;
-        client()->languageChanged(this, m_language);
-    }
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK) && defined(GST_API_VERSION_1)
index 274a784..4388f98 100644 (file)
 
 #include "GRefPtrGStreamer.h"
 #include "InbandTextTrackPrivate.h"
+#include "TrackPrivateBaseGStreamer.h"
 
 namespace WebCore {
 
 class MediaPlayerPrivateGStreamer;
 typedef struct _GstSample GstSample;
 
-class InbandTextTrackPrivateGStreamer : public InbandTextTrackPrivate {
+class InbandTextTrackPrivateGStreamer : public InbandTextTrackPrivate, public TrackPrivateBaseGStreamer {
 public:
     static PassRefPtr<InbandTextTrackPrivateGStreamer> create(gint index, GRefPtr<GstPad> pad)
     {
         return adoptRef(new InbandTextTrackPrivateGStreamer(index, pad));
     }
 
-    ~InbandTextTrackPrivateGStreamer();
-
-    GstPad* pad() const { return m_pad.get(); }
-
-    void disconnect();
+    virtual void disconnect() OVERRIDE;
 
     virtual AtomicString label() const OVERRIDE { return m_label; }
     virtual AtomicString language() const OVERRIDE { return m_language; }
 
-    void setIndex(int index) { m_index =  index; }
     virtual int trackIndex() const OVERRIDE { return m_index; }
     String streamId() const { return m_streamId; }
 
     void handleSample(GRefPtr<GstSample>);
     void streamChanged();
-    void tagsChanged();
+
     void notifyTrackOfSample();
     void notifyTrackOfStreamChanged();
-    void notifyTrackOfTagsChanged();
 
 private:
     InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad>);
 
-    gint m_index;
-    GRefPtr<GstPad> m_pad;
-    AtomicString m_label;
-    AtomicString m_language;
     guint m_sampleTimerHandler;
     guint m_streamTimerHandler;
-    guint m_tagTimerHandler;
     gulong m_eventProbe;
     Vector<GRefPtr<GstSample> > m_pendingSamples;
     String m_streamId;
index 763b3e3..f922845 100644 (file)
@@ -44,6 +44,35 @@ G_DEFINE_TYPE_WITH_CODE(WebKitTextCombiner, webkit_text_combiner, GST_TYPE_BIN,
     GST_DEBUG_CATEGORY_INIT(webkitTextCombinerDebug, "webkittextcombiner", 0,
         "webkit text combiner"));
 
+enum {
+    PROP_PAD_0,
+    PROP_PAD_TAGS
+};
+
+#define WEBKIT_TYPE_TEXT_COMBINER_PAD webkit_text_combiner_pad_get_type()
+
+#define WEBKIT_TEXT_COMBINER_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_TEXT_COMBINER_PAD, WebKitTextCombinerPad))
+#define WEBKIT_TEXT_COMBINER_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_TEXT_COMBINER_PAD, WebKitTextCombinerPadClass))
+#define WEBKIT_IS_TEXT_COMBINER_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_TEXT_COMBINER_PAD))
+#define WEBKIT_IS_TEXT_COMBINER_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_TEXT_COMBINER_PAD))
+#define WEBKIT_TEXT_COMBINER_PAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_TEXT_COMBINER_PAD, WebKitTextCombinerPadClass))
+
+typedef struct _WebKitTextCombinerPad WebKitTextCombinerPad;
+typedef struct _WebKitTextCombinerPadClass WebKitTextCombinerPadClass;
+
+struct _WebKitTextCombinerPad {
+    GstGhostPad parent;
+
+    GstTagList* tags;
+};
+
+struct _WebKitTextCombinerPadClass {
+    GstGhostPadClass parent;
+};
+
+G_DEFINE_TYPE(WebKitTextCombinerPad, webkit_text_combiner_pad, GST_TYPE_GHOST_PAD);
+
+static gboolean webkitTextCombinerPadEvent(GstPad*, GstObject* parent, GstEvent*);
 
 static void webkit_text_combiner_init(WebKitTextCombiner* combiner)
 {
@@ -61,17 +90,46 @@ static void webkit_text_combiner_init(WebKitTextCombiner* combiner)
     ASSERT(ret);
 }
 
-static GstPadProbeReturn webkitTextCombinerPadEvent(GstPad* pad, GstPadProbeInfo *info, gpointer)
+static void webkit_text_combiner_pad_init(WebKitTextCombinerPad* pad)
+{
+    pad->tags = 0;
+
+    gst_pad_set_event_function(GST_PAD(pad), webkitTextCombinerPadEvent);
+}
+
+static void webkitTextCombinerPadFinalize(GObject* object)
+{
+    WebKitTextCombinerPad* pad = WEBKIT_TEXT_COMBINER_PAD(object);
+    if (pad->tags)
+        gst_tag_list_unref(pad->tags);
+    G_OBJECT_CLASS(webkit_text_combiner_pad_parent_class)->finalize(object);
+}
+
+static void webkitTextCombinerPadGetProperty(GObject* object, guint propertyId, GValue* value, GParamSpec* pspec)
+{
+    WebKitTextCombinerPad* pad = WEBKIT_TEXT_COMBINER_PAD(object);
+    switch (propertyId) {
+    case PROP_PAD_TAGS:
+        GST_OBJECT_LOCK(object);
+        g_value_set_boxed(value, pad->tags);
+        GST_OBJECT_UNLOCK(object);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec);
+        break;
+    }
+}
+
+static gboolean webkitTextCombinerPadEvent(GstPad* pad, GstObject* parent, GstEvent* event)
 {
     gboolean ret;
     UNUSED_PARAM(ret);
-    WebKitTextCombiner* combiner = WEBKIT_TEXT_COMBINER(gst_pad_get_parent(pad));
+    WebKitTextCombiner* combiner = WEBKIT_TEXT_COMBINER(parent);
+    WebKitTextCombinerPad* combinerPad = WEBKIT_TEXT_COMBINER_PAD(pad);
     ASSERT(combiner);
 
-    GstEvent* event = gst_pad_probe_info_get_event(info);
-    ASSERT(event);
-
-    if (GST_EVENT_TYPE(event) == GST_EVENT_CAPS) {
+    switch (GST_EVENT_TYPE(event)) {
+    case GST_EVENT_CAPS: {
         GstCaps* caps;
         gst_event_parse_caps(event, &caps);
         ASSERT(caps);
@@ -137,10 +195,21 @@ static GstPadProbeReturn webkitTextCombinerPadEvent(GstPad* pad, GstPadProbeInfo
         gst_caps_unref(textCaps);
         gst_object_unref(targetParent);
         gst_object_unref(target);
+        break;
     }
-    gst_object_unref(combiner);
-
-    return GST_PAD_PROBE_OK;
+    case GST_EVENT_TAG: {
+        GstTagList* tags;
+        gst_event_parse_tag(event, &tags);
+        ASSERT(tags);
+
+        combinerPad->tags = gst_tag_list_merge(combinerPad->tags, tags, GST_TAG_MERGE_REPLACE);
+        g_object_notify(G_OBJECT(pad), "tags");
+        break;
+    }
+    default:
+        break;
+    }
+    return gst_pad_event_default(pad, parent, event);
 }
 
 static GstPad* webkitTextCombinerRequestNewPad(GstElement * element,
@@ -156,10 +225,14 @@ static GstPad* webkitTextCombinerRequestNewPad(GstElement * element,
     GstPad* pad = gst_element_request_pad(combiner->funnel, templ, name, caps);
     ASSERT(pad);
 
-    GstPad* ghostPad = gst_ghost_pad_new(NULL, pad);
+    GstPad* ghostPad = GST_PAD(g_object_new(WEBKIT_TYPE_TEXT_COMBINER_PAD, "direction", gst_pad_get_direction(pad), NULL));
     ASSERT(ghostPad);
 
-    gst_pad_add_probe(ghostPad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, webkitTextCombinerPadEvent, NULL, NULL);
+    ret = gst_ghost_pad_construct(GST_GHOST_PAD(ghostPad));
+    ASSERT(ret);
+
+    ret = gst_ghost_pad_set_target(GST_GHOST_PAD(ghostPad), pad);
+    ASSERT(ret);
 
     ret = gst_pad_set_active(ghostPad, true);
     ASSERT(ret);
@@ -201,6 +274,18 @@ static void webkit_text_combiner_class_init(WebKitTextCombinerClass* klass)
         GST_DEBUG_FUNCPTR(webkitTextCombinerReleasePad);
 }
 
+static void webkit_text_combiner_pad_class_init(WebKitTextCombinerPadClass* klass)
+{
+    GObjectClass* gobjectClass = G_OBJECT_CLASS(klass);
+
+    gobjectClass->finalize = GST_DEBUG_FUNCPTR(webkitTextCombinerPadFinalize);
+    gobjectClass->get_property = GST_DEBUG_FUNCPTR(webkitTextCombinerPadGetProperty);
+
+    g_object_class_install_property(gobjectClass, PROP_PAD_TAGS,
+        g_param_spec_boxed("tags", "Tags", "The currently active tags on the pad", GST_TYPE_TAG_LIST,
+            static_cast<GParamFlags>(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
+}
+
 GstElement* webkitTextCombinerNew()
 {
     return GST_ELEMENT(g_object_new(WEBKIT_TYPE_TEXT_COMBINER, 0));
index cf44423..a19303d 100644 (file)
@@ -46,8 +46,6 @@ struct _WebKitTextCombiner {
     GstBin parent;
 
     GstElement *funnel;
-private:
-
 };
 
 struct _WebKitTextCombinerClass {
index a3c45ef..b320157 100644 (file)
 
 #include "GStreamerUtilities.h"
 #include "Logging.h"
+#include "TrackPrivateBase.h"
 #include <glib-object.h>
 #include <gst/gst.h>
+#include <wtf/gobject/GOwnPtr.h>
 
 GST_DEBUG_CATEGORY_EXTERN(webkit_media_player_debug);
 #define GST_CAT_DEFAULT webkit_media_player_debug
@@ -61,16 +63,19 @@ static gboolean trackPrivateTagsChangeTimeoutCallback(TrackPrivateBaseGStreamer*
     return FALSE;
 }
 
-TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(const char* notifyActiveSignal, GRefPtr<GstElement> playbin, gint index, GRefPtr<GstPad> pad)
+TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstPad> pad)
     : m_index(index)
-    , m_playbin(playbin)
     , m_pad(pad)
+    , m_owner(owner)
     , m_activeTimerHandler(0)
     , m_tagTimerHandler(0)
 {
     ASSERT(m_pad);
-    g_signal_connect(m_playbin.get(), notifyActiveSignal, G_CALLBACK(trackPrivateActiveChangedCallback), this);
+
+    g_signal_connect(m_pad.get(), "notify::active", G_CALLBACK(trackPrivateActiveChangedCallback), this);
     g_signal_connect(m_pad.get(), "notify::tags", G_CALLBACK(trackPrivateTagsChangedCallback), this);
+
+    notifyTrackOfTagsChanged();
 }
 
 TrackPrivateBaseGStreamer::~TrackPrivateBaseGStreamer()
@@ -95,7 +100,6 @@ void TrackPrivateBaseGStreamer::disconnect()
         g_source_remove(m_tagTimerHandler);
 
     m_pad.clear();
-    m_playbin.clear();
 }
 
 void TrackPrivateBaseGStreamer::activeChanged()
@@ -126,40 +130,34 @@ void TrackPrivateBaseGStreamer::notifyTrackOfActiveChanged()
     setActive(active);
 }
 
+bool TrackPrivateBaseGStreamer::getTag(GstTagList* tags, const gchar* tagName, String& value)
+{
+    GOwnPtr<gchar> tagValue;
+    if (gst_tag_list_get_string(tags, tagName, &tagValue.outPtr())) {
+        INFO_MEDIA_MESSAGE("Track %d got %s %s.", m_index, tagName, tagValue.get());
+        value = tagValue.get();
+        return true;
+    }
+    return false;
+}
+
 void TrackPrivateBaseGStreamer::notifyTrackOfTagsChanged()
 {
     m_tagTimerHandler = 0;
     if (!m_pad)
         return;
 
-    String label;
-    String language;
+    TrackPrivateBaseClient* client = m_owner->client();
     GRefPtr<GstTagList> tags;
     g_object_get(m_pad.get(), "tags", &tags.outPtr(), NULL);
-    if (tags) {
-        gchar* tagValue;
-        if (gst_tag_list_get_string(tags.get(), GST_TAG_TITLE, &tagValue)) {
-            INFO_MEDIA_MESSAGE("Video track %d got title %s.", m_index, tagValue);
-            label = tagValue;
-            g_free(tagValue);
-        }
-
-        if (gst_tag_list_get_string(tags.get(), GST_TAG_LANGUAGE_CODE, &tagValue)) {
-            INFO_MEDIA_MESSAGE("Video track %d got language %s.", m_index, tagValue);
-            language = tagValue;
-            g_free(tagValue);
-        }
-    }
+    if (!tags)
+        return;
 
-    if (m_label != label) {
-        m_label = label;
-        labelChanged(m_label);
-    }
+    if (getTag(tags.get(), GST_TAG_TITLE, m_label) && client)
+        client->labelChanged(m_owner, m_label);
 
-    if (m_language != language) {
-        m_language = language;
-        languageChanged(m_language);
-    }
+    if (getTag(tags.get(), GST_TAG_LANGUAGE_CODE, m_language) && client)
+        client->languageChanged(m_owner, m_language);
 }
 
 } // namespace WebCore
index 4e52bbe..995da4f 100644 (file)
 
 namespace WebCore {
 
+class TrackPrivateBase;
+
 class TrackPrivateBaseGStreamer {
 public:
     virtual ~TrackPrivateBaseGStreamer();
 
-    virtual void labelChanged(const String&) = 0;
-    virtual void languageChanged(const String&) = 0;
-
     GstPad* pad() const { return m_pad.get(); }
 
-    void disconnect();
+    virtual void disconnect();
 
-    virtual void setActive(bool) = 0;
+    virtual void setActive(bool) { }
 
     void setIndex(int index) { m_index =  index; }
 
@@ -55,16 +54,17 @@ public:
     void notifyTrackOfTagsChanged();
 
 protected:
-    TrackPrivateBaseGStreamer(const char* notifyActiveSignal, GRefPtr<GstElement> playbin, gint index, GRefPtr<GstPad>);
+    TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstPad>);
 
     gint m_index;
-    GRefPtr<GstElement> m_playbin;
-
     String m_label;
     String m_language;
+    GRefPtr<GstPad> m_pad;
 
 private:
-    GRefPtr<GstPad> m_pad;
+    bool getTag(GstTagList* tags, const gchar* tagName, String& value);
+
+    TrackPrivateBase* m_owner;
     guint m_activeTimerHandler;
     guint m_tagTimerHandler;
 };
index 958c929..27de57f 100644 (file)
 namespace WebCore {
 
 VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(GRefPtr<GstElement> playbin, gint index, GRefPtr<GstPad> pad)
-    : TrackPrivateBaseGStreamer("notify::current-video", playbin, index, pad)
+    : TrackPrivateBaseGStreamer(this, index, pad)
+    , m_playbin(playbin)
 {
-    activeChanged();
-    tagsChanged();
+    notifyTrackOfActiveChanged();
+}
+
+void VideoTrackPrivateGStreamer::disconnect()
+{
+    m_playbin.clear();
+    TrackPrivateBaseGStreamer::disconnect();
 }
 
 void VideoTrackPrivateGStreamer::setSelected(bool selected)
@@ -50,18 +56,6 @@ void VideoTrackPrivateGStreamer::setSelected(bool selected)
         g_object_set(m_playbin.get(), "current-video", m_index, NULL);
 }
 
-void VideoTrackPrivateGStreamer::labelChanged(const String& label)
-{
-    if (client())
-        client()->labelChanged(this, label);
-}
-
-void VideoTrackPrivateGStreamer::languageChanged(const String& language)
-{
-    if (client())
-        client()->languageChanged(this, language);
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(VIDEO_TRACK) && defined(GST_API_VERSION_1)
index e7df3a4..aef1f58 100644 (file)
@@ -41,6 +41,8 @@ public:
         return adoptRef(new VideoTrackPrivateGStreamer(playbin, index, pad));
     }
 
+    virtual void disconnect() OVERRIDE;
+
     virtual void setSelected(bool) OVERRIDE;
     virtual void setActive(bool enabled) OVERRIDE { setSelected(enabled); }
 
@@ -49,11 +51,10 @@ public:
     virtual AtomicString label() const OVERRIDE { return m_label; }
     virtual AtomicString language() const OVERRIDE { return m_language; }
 
-    virtual void labelChanged(const String&) OVERRIDE;
-    virtual void languageChanged(const String&) OVERRIDE;
-
 private:
     VideoTrackPrivateGStreamer(GRefPtr<GstElement> playbin, gint index, GRefPtr<GstPad>);
+
+    GRefPtr<GstElement> m_playbin;
 };
 
 } // namespace WebCore