Changeset 177790 in webkit


Ignore:
Timestamp:
Dec 29, 2014 6:46:39 AM (9 years ago)
Author:
commit-queue@webkit.org
Message:

Source/WebCore:
[GStreamer] Rewrite MediaSource implementation
https://bugs.webkit.org/show_bug.cgi?id=139441

Patch by Sebastian Dröge <sebastian@centricular.com> on 2014-12-29
Reviewed by Philippe Normand.

This now is a clean reimplementation around appsrc that works good
enough for YouTube (except for seeking), but it still does not
implement the complete API correctly. Further work is required on
top of this and the Bugzilla ticket linked above contains some
further work in the right direction.

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:

(WebCore::MediaPlayerPrivateGStreamer::doSeek):
(WebCore::MediaPlayerPrivateGStreamer::didLoadingProgress):
(WebCore::MediaPlayerPrivateGStreamer::sourceChanged):
(WebCore::MediaPlayerPrivateGStreamer::canSaveMediaData):

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:

(WebCore::MediaPlayerPrivateGStreamer::totalVideoFrames):
(WebCore::MediaPlayerPrivateGStreamer::droppedVideoFrames):
(WebCore::MediaPlayerPrivateGStreamer::corruptedVideoFrames):
(WebCore::MediaPlayerPrivateGStreamer::totalFrameDelay):
(WebCore::MediaPlayerPrivateGStreamer::isMediaSource):

  • platform/graphics/gstreamer/MediaSourceGStreamer.cpp:

(WebCore::MediaSourceGStreamer::MediaSourceGStreamer):
(WebCore::MediaSourceGStreamer::addSourceBuffer):
(WebCore::MediaSourceGStreamer::durationChanged):
(WebCore::MediaSourceGStreamer::markEndOfStream):
(WebCore::MediaSourceGStreamer::unmarkEndOfStream):
(WebCore::MediaSourceGStreamer::readyState):
(WebCore::MediaSourceGStreamer::setReadyState):
(WebCore::MediaSourceGStreamer::waitForSeekCompleted):
(WebCore::MediaSourceGStreamer::seekCompleted):

  • platform/graphics/gstreamer/MediaSourceGStreamer.h:
  • platform/graphics/gstreamer/SourceBufferPrivateGStreamer.cpp:

(WebCore::SourceBufferPrivateGStreamer::SourceBufferPrivateGStreamer):
(WebCore::SourceBufferPrivateGStreamer::~SourceBufferPrivateGStreamer):
(WebCore::SourceBufferPrivateGStreamer::setClient):
(WebCore::SourceBufferPrivateGStreamer::append):
(WebCore::SourceBufferPrivateGStreamer::removedFromMediaSource):
(WebCore::SourceBufferPrivateGStreamer::readyState):
(WebCore::SourceBufferPrivateGStreamer::setReadyState):
(WebCore::SourceBufferPrivateGStreamer::flushAndEnqueueNonDisplayingSamples):
(WebCore::SourceBufferPrivateGStreamer::enqueueSample):
(WebCore::SourceBufferPrivateGStreamer::isReadyForMoreSamples):
(WebCore::SourceBufferPrivateGStreamer::setActive):
(WebCore::SourceBufferPrivateGStreamer::stopAskingForMoreSamples):
(WebCore::SourceBufferPrivateGStreamer::notifyClientWhenReadyForMoreSamples):

  • platform/graphics/gstreamer/SourceBufferPrivateGStreamer.h:
  • platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp:

(webkit_media_src_class_init):
(webkit_media_src_init):
(webKitMediaSrcFinalize):
(webKitMediaSrcSetProperty):
(webKitMediaSrcGetProperty):
(webKitMediaSrcDoAsyncStart):
(webKitMediaSrcDoAsyncDone):
(webKitMediaSrcChangeState):
(webKitMediaSrcQueryWithParent):
(webKitMediaSrcGetUri):
(webKitMediaSrcSetUri):
(WebCore::MediaSourceClientGStreamer::MediaSourceClientGStreamer):
(WebCore::MediaSourceClientGStreamer::~MediaSourceClientGStreamer):
(WebCore::MediaSourceClientGStreamer::addSourceBuffer):
(WebCore::MediaSourceClientGStreamer::durationChanged):
(WebCore::MediaSourceClientGStreamer::append):
(WebCore::MediaSourceClientGStreamer::markEndOfStream):
(WebCore::MediaSourceClientGStreamer::removedFromMediaSource):
(WTF::adoptGRef):
(WTF::refGPtr<WebKitMediaSrc>):
(WTF::derefGPtr<WebKitMediaSrc>):
(webKitMediaSrcAddSrc): Deleted.
(webKitMediaVideoSrcStop): Deleted.
(webKitMediaAudioSrcStop): Deleted.
(webKitMediaVideoSrcStart): Deleted.
(webKitMediaAudioSrcStart): Deleted.
(webKitMediaVideoSrcNeedDataMainCb): Deleted.
(webKitMediaAudioSrcNeedDataMainCb): Deleted.
(webKitMediaVideoSrcNeedDataCb): Deleted.
(webKitMediaAudioSrcNeedDataCb): Deleted.
(webKitMediaVideoSrcEnoughDataMainCb): Deleted.
(webKitMediaAudioSrcEnoughDataMainCb): Deleted.
(webKitMediaVideoSrcEnoughDataCb): Deleted.
(webKitMediaAudioSrcEnoughDataCb): Deleted.
(webKitMediaVideoSrcSeekMainCb): Deleted.
(webKitMediaAudioSrcSeekMainCb): Deleted.
(webKitMediaVideoSrcSeekDataCb): Deleted.
(webKitMediaAudioSrcSeekDataCb): Deleted.
(webKitMediaSrcSetMediaPlayer): Deleted.
(webKitMediaSrcSetPlayBin): Deleted.
(MediaSourceClientGstreamer::MediaSourceClientGstreamer): Deleted.
(MediaSourceClientGstreamer::~MediaSourceClientGstreamer): Deleted.
(MediaSourceClientGstreamer::didReceiveDuration): Deleted.
(MediaSourceClientGstreamer::didReceiveData): Deleted.
(MediaSourceClientGstreamer::didFinishLoading): Deleted.
(MediaSourceClientGstreamer::didFail): Deleted.

  • platform/graphics/gstreamer/WebKitMediaSourceGStreamer.h:

Rewrite MediaSource implementation for GStreamer. The old code was
overly complicated and did not work at all for anything I've tested
it with.

LayoutTests:
Enable MediaSource tests for the GTK port
https://bugs.webkit.org/show_bug.cgi?id=139441

Patch by Sebastian Dröge <sebastian@centricular.com> on 2014-12-29
Reviewed by Philippe Normand.

  • platform/gtk/TestExpectations:

Enable MediaSource tests that are actually succeeding for
the GTK port.

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r177785 r177790  
     12014-12-29  Sebastian Dröge  <sebastian@centricular.com>
     2
     3        Enable MediaSource tests for the GTK port
     4        https://bugs.webkit.org/show_bug.cgi?id=139441
     5
     6        Reviewed by Philippe Normand.
     7
     8        * platform/gtk/TestExpectations:
     9        Enable MediaSource tests that are actually succeeding for
     10        the GTK port.
     11
    1122014-12-28  Alexey Proskuryakov  <ap@apple.com>
    213
  • trunk/LayoutTests/platform/gtk/TestExpectations

    r177583 r177790  
    226226
    227227# Tests for MediaSource API. Feature is not totally functional.
    228 webkit.org/b/99065 http/tests/media/media-source [ Skip ]
    229 webkit.org/b/99065 media/media-source [ Skip ]
     228webkit.org/b/99065 http/tests/media/media-source/mediasource-append-buffer.html [ Skip ]
     229webkit.org/b/99065 http/tests/media/media-source/mediasource-append-stream.html [ Skip ]
     230webkit.org/b/99065 http/tests/media/media-source/mediasource-appendwindow.html [ Skip ]
     231webkit.org/b/99065 http/tests/media/media-source/mediasource-buffered.html [ Skip ]
     232webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-mp4-a-bitrate.html [ Skip ]
     233webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-mp4-av-audio-bitrate.html [ Skip ]
     234webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-mp4-av-framesize.html [ Skip ]
     235webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-mp4-av-video-bitrate.html [ Skip ]
     236webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-mp4-v-bitrate.html [ Skip ]
     237webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-mp4-v-framerate.html [ Skip ]
     238webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-mp4-v-framesize.html [ Skip ]
     239webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-webm-a-bitrate.html [ Skip ]
     240webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-webm-av-audio-bitrate.html [ Skip ]
     241webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-webm-av-framesize.html [ Skip ]
     242webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-webm-av-video-bitrate.html [ Skip ]
     243webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-webm-v-bitrate.html [ Skip ]
     244webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-webm-v-framerate.html [ Skip ]
     245webkit.org/b/99065 http/tests/media/media-source/mediasource-config-change-webm-v-framesize.html [ Skip ]
     246webkit.org/b/99065 http/tests/media/media-source/mediasource-duration.html [ Skip ]
     247webkit.org/b/99065 http/tests/media/media-source/mediasource-getvideoplaybackquality.html [ Skip ]
     248webkit.org/b/99065 http/tests/media/media-source/mediasource-is-type-supported.html [ Skip ]
     249webkit.org/b/99065 http/tests/media/media-source/mediasource-play.html [ Skip ]
     250webkit.org/b/99065 http/tests/media/media-source/mediasource-play-then-seek-back.html [ Skip ]
     251webkit.org/b/99065 http/tests/media/media-source/mediasource-redundant-seek.html [ Skip ]
     252webkit.org/b/99065 http/tests/media/media-source/mediasource-remove.html [ Skip ]
     253webkit.org/b/99065 http/tests/media/media-source/mediasource-seek-beyond-duration.html [ Skip ]
     254webkit.org/b/99065 http/tests/media/media-source/mediasource-seek-during-pending-seek.html [ Skip ]
     255webkit.org/b/99065 http/tests/media/media-source/mediasource-sourcebuffer-mode.html [ Skip ]
     256
     257webkit.org/b/99065 media/media-source/media-source-append-failed.html [ Skip ]
     258webkit.org/b/99065 media/media-source/media-source-multiple-initialization-segments.html [ Skip ]
     259webkit.org/b/99065 media/media-source/media-source-append-nonsync-sample-after-abort.html [ Skip ]
     260webkit.org/b/99065 media/media-source/media-source-duplicate-seeked.html [ Skip ]
     261webkit.org/b/99065 media/media-source/media-source-canplaythrough.html [ Skip ]
     262webkit.org/b/99065 media/media-source/media-source-duration-after-append.html [ Skip ]
     263webkit.org/b/99065 media/media-source/media-source-end-of-stream-buffered.html [ Skip ]
     264webkit.org/b/99065 media/media-source/media-source-end-of-stream.html [ Skip ]
     265webkit.org/b/99065 media/media-source/media-source-fudge-factor.html [ Skip ]
     266webkit.org/b/99065 media/media-source/media-source-monitor-source-buffers.html [ Skip ]
     267webkit.org/b/99065 media/media-source/media-source-overlapping-append.html [ Skip ]
     268webkit.org/b/99065 media/media-source/media-source-overlapping-decodetime.html [ Skip ]
     269webkit.org/b/99065 media/media-source/media-source-play.html [ Skip ]
     270webkit.org/b/99065 media/media-source/media-source-remove.html [ Skip ]
     271webkit.org/b/99065 media/media-source/media-source-seek-complete.html [ Skip ]
     272webkit.org/b/99065 media/media-source/media-source-track-enabled.html [ Skip ]
     273webkit.org/b/99065 media/media-source/media-source-tracks.html [ Skip ]
     274webkit.org/b/99065 media/media-source/media-source-video-playback-quality.html [ Skip ]
    230275
    231276# Encrypted Media Extensions are not enabled.
  • trunk/Source/WebCore/ChangeLog

    r177788 r177790  
     12014-12-29  Sebastian Dröge  <sebastian@centricular.com>
     2
     3        [GStreamer] Rewrite MediaSource implementation
     4        https://bugs.webkit.org/show_bug.cgi?id=139441
     5
     6        Reviewed by Philippe Normand.
     7
     8        This now is a clean reimplementation around appsrc that works good
     9        enough for YouTube (except for seeking), but it still does not
     10        implement the complete API correctly. Further work is required on
     11        top of this and the Bugzilla ticket linked above contains some
     12        further work in the right direction.
     13
     14        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
     15        (WebCore::MediaPlayerPrivateGStreamer::doSeek):
     16        (WebCore::MediaPlayerPrivateGStreamer::didLoadingProgress):
     17        (WebCore::MediaPlayerPrivateGStreamer::sourceChanged):
     18        (WebCore::MediaPlayerPrivateGStreamer::canSaveMediaData):
     19        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
     20        (WebCore::MediaPlayerPrivateGStreamer::totalVideoFrames):
     21        (WebCore::MediaPlayerPrivateGStreamer::droppedVideoFrames):
     22        (WebCore::MediaPlayerPrivateGStreamer::corruptedVideoFrames):
     23        (WebCore::MediaPlayerPrivateGStreamer::totalFrameDelay):
     24        (WebCore::MediaPlayerPrivateGStreamer::isMediaSource):
     25        * platform/graphics/gstreamer/MediaSourceGStreamer.cpp:
     26        (WebCore::MediaSourceGStreamer::MediaSourceGStreamer):
     27        (WebCore::MediaSourceGStreamer::addSourceBuffer):
     28        (WebCore::MediaSourceGStreamer::durationChanged):
     29        (WebCore::MediaSourceGStreamer::markEndOfStream):
     30        (WebCore::MediaSourceGStreamer::unmarkEndOfStream):
     31        (WebCore::MediaSourceGStreamer::readyState):
     32        (WebCore::MediaSourceGStreamer::setReadyState):
     33        (WebCore::MediaSourceGStreamer::waitForSeekCompleted):
     34        (WebCore::MediaSourceGStreamer::seekCompleted):
     35        * platform/graphics/gstreamer/MediaSourceGStreamer.h:
     36        * platform/graphics/gstreamer/SourceBufferPrivateGStreamer.cpp:
     37        (WebCore::SourceBufferPrivateGStreamer::SourceBufferPrivateGStreamer):
     38        (WebCore::SourceBufferPrivateGStreamer::~SourceBufferPrivateGStreamer):
     39        (WebCore::SourceBufferPrivateGStreamer::setClient):
     40        (WebCore::SourceBufferPrivateGStreamer::append):
     41        (WebCore::SourceBufferPrivateGStreamer::removedFromMediaSource):
     42        (WebCore::SourceBufferPrivateGStreamer::readyState):
     43        (WebCore::SourceBufferPrivateGStreamer::setReadyState):
     44        (WebCore::SourceBufferPrivateGStreamer::flushAndEnqueueNonDisplayingSamples):
     45        (WebCore::SourceBufferPrivateGStreamer::enqueueSample):
     46        (WebCore::SourceBufferPrivateGStreamer::isReadyForMoreSamples):
     47        (WebCore::SourceBufferPrivateGStreamer::setActive):
     48        (WebCore::SourceBufferPrivateGStreamer::stopAskingForMoreSamples):
     49        (WebCore::SourceBufferPrivateGStreamer::notifyClientWhenReadyForMoreSamples):
     50        * platform/graphics/gstreamer/SourceBufferPrivateGStreamer.h:
     51        * platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp:
     52        (webkit_media_src_class_init):
     53        (webkit_media_src_init):
     54        (webKitMediaSrcFinalize):
     55        (webKitMediaSrcSetProperty):
     56        (webKitMediaSrcGetProperty):
     57        (webKitMediaSrcDoAsyncStart):
     58        (webKitMediaSrcDoAsyncDone):
     59        (webKitMediaSrcChangeState):
     60        (webKitMediaSrcQueryWithParent):
     61        (webKitMediaSrcGetUri):
     62        (webKitMediaSrcSetUri):
     63        (WebCore::MediaSourceClientGStreamer::MediaSourceClientGStreamer):
     64        (WebCore::MediaSourceClientGStreamer::~MediaSourceClientGStreamer):
     65        (WebCore::MediaSourceClientGStreamer::addSourceBuffer):
     66        (WebCore::MediaSourceClientGStreamer::durationChanged):
     67        (WebCore::MediaSourceClientGStreamer::append):
     68        (WebCore::MediaSourceClientGStreamer::markEndOfStream):
     69        (WebCore::MediaSourceClientGStreamer::removedFromMediaSource):
     70        (WTF::adoptGRef):
     71        (WTF::refGPtr<WebKitMediaSrc>):
     72        (WTF::derefGPtr<WebKitMediaSrc>):
     73        (webKitMediaSrcAddSrc): Deleted.
     74        (webKitMediaVideoSrcStop): Deleted.
     75        (webKitMediaAudioSrcStop): Deleted.
     76        (webKitMediaVideoSrcStart): Deleted.
     77        (webKitMediaAudioSrcStart): Deleted.
     78        (webKitMediaVideoSrcNeedDataMainCb): Deleted.
     79        (webKitMediaAudioSrcNeedDataMainCb): Deleted.
     80        (webKitMediaVideoSrcNeedDataCb): Deleted.
     81        (webKitMediaAudioSrcNeedDataCb): Deleted.
     82        (webKitMediaVideoSrcEnoughDataMainCb): Deleted.
     83        (webKitMediaAudioSrcEnoughDataMainCb): Deleted.
     84        (webKitMediaVideoSrcEnoughDataCb): Deleted.
     85        (webKitMediaAudioSrcEnoughDataCb): Deleted.
     86        (webKitMediaVideoSrcSeekMainCb): Deleted.
     87        (webKitMediaAudioSrcSeekMainCb): Deleted.
     88        (webKitMediaVideoSrcSeekDataCb): Deleted.
     89        (webKitMediaAudioSrcSeekDataCb): Deleted.
     90        (webKitMediaSrcSetMediaPlayer): Deleted.
     91        (webKitMediaSrcSetPlayBin): Deleted.
     92        (MediaSourceClientGstreamer::MediaSourceClientGstreamer): Deleted.
     93        (MediaSourceClientGstreamer::~MediaSourceClientGstreamer): Deleted.
     94        (MediaSourceClientGstreamer::didReceiveDuration): Deleted.
     95        (MediaSourceClientGstreamer::didReceiveData): Deleted.
     96        (MediaSourceClientGstreamer::didFinishLoading): Deleted.
     97        (MediaSourceClientGstreamer::didFail): Deleted.
     98        * platform/graphics/gstreamer/WebKitMediaSourceGStreamer.h:
     99        Rewrite MediaSource implementation for GStreamer. The old code was
     100        overly complicated and did not work at all for anything I've tested
     101        it with.
     102
    11032014-12-28  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
    2104
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

    r177058 r177790  
    565565    gint64 startTime, endTime;
    566566
     567    // TODO: Should do more than that, need to notify the media source
     568    // and probably flush the pipeline at least.
     569    if (isMediaSource())
     570        return true;
     571
    567572    if (rate > 0) {
    568573        startTime = position;
     
    12451250bool MediaPlayerPrivateGStreamer::didLoadingProgress() const
    12461251{
    1247     if (!m_playBin || !m_mediaDuration || !totalBytes())
     1252    if (!m_playBin || !m_mediaDuration || (!isMediaSource() && !totalBytes()))
    12481253        return false;
    12491254    float currentMaxTimeLoaded = maxTimeLoaded();
     
    13191324    if (m_mediaSource && WEBKIT_IS_MEDIA_SRC(m_source.get())) {
    13201325        MediaSourceGStreamer::open(m_mediaSource.get(), WEBKIT_MEDIA_SRC(m_source.get()));
    1321         webKitMediaSrcSetPlayBin(WEBKIT_MEDIA_SRC(m_source.get()), m_playBin.get());
    13221326    }
    13231327#endif
     
    19972001    if (m_url.protocolIsInHTTPFamily())
    19982002        return true;
    1999    
     2003
    20002004    return false;
    20012005}
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h

    r177058 r177790  
    175175    virtual bool didPassCORSAccessCheck() const;
    176176    virtual bool canSaveMediaData() const override;
     177
     178#if ENABLE(MEDIA_SOURCE)
     179    // TODO: Implement
     180    virtual unsigned long totalVideoFrames() { return 0; }
     181    virtual unsigned long droppedVideoFrames() { return 0; }
     182    virtual unsigned long corruptedVideoFrames() { return 0; }
     183    virtual MediaTime totalFrameDelay() { return MediaTime::zeroTime(); }
     184#endif
    177185
    178186private:
     
    238246#if ENABLE(MEDIA_SOURCE)
    239247    RefPtr<MediaSourcePrivateClient> m_mediaSource;
     248    bool isMediaSource() const { return m_mediaSource; }
     249#else
     250    bool isMediaSource() const { return false; }
    240251#endif
    241252};
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaSourceGStreamer.cpp

    r173318 r177790  
    22 * Copyright (C) 2013 Google Inc. All rights reserved.
    33 * Copyright (C) 2013 Orange
     4 * Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
    45 *
    56 * Redistribution and use in source and binary forms, with or without
     
    3536#if ENABLE(MEDIA_SOURCE) && USE(GSTREAMER)
    3637
     38#include "NotImplemented.h"
    3739#include "SourceBufferPrivateGStreamer.h"
    3840#include "WebKitMediaSourceGStreamer.h"
     41
    3942#include <wtf/gobject/GRefPtr.h>
    4043
     
    4851
    4952MediaSourceGStreamer::MediaSourceGStreamer(MediaSourcePrivateClient* mediaSource, WebKitMediaSrc* src)
    50     : m_client(adoptRef(new MediaSourceClientGstreamer(src)))
     53    : m_client(adoptRef(new MediaSourceClientGStreamer(src)))
    5154    , m_mediaSource(mediaSource)
    5255    , m_readyState(MediaPlayer::HaveNothing)
     
    6164MediaSourceGStreamer::AddStatus MediaSourceGStreamer::addSourceBuffer(const ContentType& contentType, RefPtr<SourceBufferPrivate>& sourceBufferPrivate)
    6265{
    63     sourceBufferPrivate = adoptRef(new SourceBufferPrivateGStreamer(m_client.get(), contentType));
    64     return MediaSourceGStreamer::Ok;
     66    RefPtr<SourceBufferPrivateGStreamer> sourceBufferPrivateGStreamer = new SourceBufferPrivateGStreamer(m_client.get(), contentType);
     67
     68    sourceBufferPrivate = adoptRef(sourceBufferPrivateGStreamer.get());
     69    return m_client->addSourceBuffer(sourceBufferPrivateGStreamer, contentType);
    6570}
    6671
    6772void MediaSourceGStreamer::durationChanged()
    6873{
    69     m_client->didReceiveDuration(m_mediaSource->duration().toDouble());
     74    m_client->durationChanged(m_mediaSource->duration());
    7075}
    7176
    72 void MediaSourceGStreamer::markEndOfStream(EndOfStreamStatus)
     77void MediaSourceGStreamer::markEndOfStream(EndOfStreamStatus status)
    7378{
    74     m_client->didFinishLoading(0);
     79    m_client->markEndOfStream(status);
    7580}
    7681
    7782void MediaSourceGStreamer::unmarkEndOfStream()
    7883{
     84    notImplemented();
     85}
     86
     87MediaPlayer::ReadyState MediaSourceGStreamer::readyState() const
     88{
     89    return m_readyState;
     90}
     91
     92void MediaSourceGStreamer::setReadyState(MediaPlayer::ReadyState state)
     93{
     94    m_readyState = state;
     95}
     96
     97void MediaSourceGStreamer::waitForSeekCompleted()
     98{
     99    notImplemented();
     100}
     101
     102void MediaSourceGStreamer::seekCompleted()
     103{
     104    notImplemented();
    79105}
    80106
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaSourceGStreamer.h

    r171033 r177790  
    22 * Copyright (C) 2013 Google Inc. All rights reserved.
    33 * Copyright (C) 2013 Orange
     4 * Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
    45 *
    56 * Redistribution and use in source and binary forms, with or without
     
    3940namespace WebCore {
    4041
     42// FIXME: Should this be called MediaSourcePrivateGStreamer?
    4143class MediaSourceGStreamer final : public MediaSourcePrivate {
    4244public:
    4345    static void open(MediaSourcePrivateClient*, WebKitMediaSrc*);
    44     ~MediaSourceGStreamer();
     46    virtual ~MediaSourceGStreamer();
     47
     48    virtual AddStatus addSourceBuffer(const ContentType&, RefPtr<SourceBufferPrivate>&);
     49    virtual void durationChanged();
     50    virtual void markEndOfStream(EndOfStreamStatus);
     51    virtual void unmarkEndOfStream();
     52
     53    virtual MediaPlayer::ReadyState readyState() const;
     54    virtual void setReadyState(MediaPlayer::ReadyState);
     55
     56    virtual void waitForSeekCompleted();
     57    virtual void seekCompleted();
    4558
    4659private:
    47     // MediaSourcePrivate
    48     virtual AddStatus addSourceBuffer(const ContentType&, RefPtr<SourceBufferPrivate>&) override;
    49     virtual void durationChanged() override;
    50     virtual void markEndOfStream(EndOfStreamStatus) override;
    51     virtual void unmarkEndOfStream() override;
    52     virtual MediaPlayer::ReadyState readyState() const override { return m_readyState; }
    53     virtual void setReadyState(MediaPlayer::ReadyState readyState) override { m_readyState = readyState; }
    54     virtual void waitForSeekCompleted() override { }
    55     virtual void seekCompleted() override { }
     60    MediaSourceGStreamer(MediaSourcePrivateClient*, WebKitMediaSrc*);
    5661
    57     RefPtr<MediaSourceClientGstreamer> m_client;
     62    RefPtr<MediaSourceClientGStreamer> m_client;
    5863    MediaSourcePrivateClient* m_mediaSource;
    59     MediaSourceGStreamer(MediaSourcePrivateClient*, WebKitMediaSrc*);
    6064    MediaPlayer::ReadyState m_readyState;
    6165};
  • trunk/Source/WebCore/platform/graphics/gstreamer/SourceBufferPrivateGStreamer.cpp

    r168508 r177790  
    22 * Copyright (C) 2013 Google Inc. All rights reserved.
    33 * Copyright (C) 2013 Orange
     4 * Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
    45 *
    56 * Redistribution and use in source and binary forms, with or without
     
    4041namespace WebCore {
    4142
    42 SourceBufferPrivateGStreamer::SourceBufferPrivateGStreamer(PassRefPtr<MediaSourceClientGstreamer> client, const ContentType& contentType)
    43     : m_readyState(MediaPlayer::HaveNothing)
     43SourceBufferPrivateGStreamer::SourceBufferPrivateGStreamer(PassRefPtr<MediaSourceClientGStreamer> client, const ContentType& contentType)
     44    : m_type(contentType)
     45    , m_client(client)
     46    , m_readyState(MediaPlayer::HaveNothing)
    4447{
    45     m_client = client;
    46     m_type = contentType.type();
     48}
     49
     50SourceBufferPrivateGStreamer::~SourceBufferPrivateGStreamer()
     51{
     52}
     53
     54void SourceBufferPrivateGStreamer::setClient(SourceBufferPrivateClient* client)
     55{
     56    m_sourceBufferPrivateClient = client;
    4757}
    4858
     
    5060{
    5161    ASSERT(m_client);
    52     m_client->didReceiveData(reinterpret_cast_ptr<const char*>(data), length, m_type);
     62    ASSERT(m_sourceBufferPrivateClient);
    5363
    54     // FIXME: call SourceBufferPrivateClient::sourceBufferPrivateAppendComplete().
     64    SourceBufferPrivateClient::AppendResult result = m_client->append(this, data, length);
     65    m_sourceBufferPrivateClient->sourceBufferPrivateAppendComplete(this, result);
    5566}
    5667
     
    6273void SourceBufferPrivateGStreamer::removedFromMediaSource()
    6374{
     75    m_client->removedFromMediaSource(this);
     76}
     77
     78MediaPlayer::ReadyState SourceBufferPrivateGStreamer::readyState() const
     79{
     80    return m_readyState;
     81}
     82
     83void SourceBufferPrivateGStreamer::setReadyState(MediaPlayer::ReadyState state)
     84{
     85    m_readyState = state;
     86}
     87
     88// TODO: Implement these
     89void SourceBufferPrivateGStreamer::flushAndEnqueueNonDisplayingSamples(Vector<RefPtr<MediaSample>>, AtomicString)
     90{
     91    notImplemented();
     92}
     93
     94void SourceBufferPrivateGStreamer::enqueueSample(PassRefPtr<MediaSample>, AtomicString)
     95{
     96    notImplemented();
     97}
     98
     99bool SourceBufferPrivateGStreamer::isReadyForMoreSamples(AtomicString)
     100{
     101    notImplemented();
     102
     103    return false;
     104}
     105
     106void SourceBufferPrivateGStreamer::setActive(bool)
     107{
     108    notImplemented();
     109}
     110
     111void SourceBufferPrivateGStreamer::stopAskingForMoreSamples(AtomicString)
     112{
     113    notImplemented();
     114}
     115
     116void SourceBufferPrivateGStreamer::notifyClientWhenReadyForMoreSamples(AtomicString)
     117{
    64118    notImplemented();
    65119}
  • trunk/Source/WebCore/platform/graphics/gstreamer/SourceBufferPrivateGStreamer.h

    r168508 r177790  
    22 * Copyright (C) 2013 Google Inc. All rights reserved.
    33 * Copyright (C) 2013 Orange
     4 * Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
    45 *
    56 * Redistribution and use in source and binary forms, with or without
     
    3536#if ENABLE(MEDIA_SOURCE) && USE(GSTREAMER)
    3637
     38#include "ContentType.h"
    3739#include "SourceBufferPrivate.h"
    3840#include "WebKitMediaSourceGStreamer.h"
     
    4244class SourceBufferPrivateGStreamer final : public SourceBufferPrivate {
    4345public:
    44     SourceBufferPrivateGStreamer(PassRefPtr<MediaSourceClientGstreamer>, const ContentType&);
    45     ~SourceBufferPrivateGStreamer() { }
     46    SourceBufferPrivateGStreamer(PassRefPtr<MediaSourceClientGStreamer>, const ContentType&);
     47    virtual ~SourceBufferPrivateGStreamer();
    4648
    47     void setClient(SourceBufferPrivateClient*) { }
    48     void append(const unsigned char*, unsigned);
    49     void abort();
    50     void removedFromMediaSource();
    51     MediaPlayer::ReadyState readyState() const { return m_readyState; }
    52     void setReadyState(MediaPlayer::ReadyState readyState) { m_readyState = readyState; }
    53     void evictCodedFrames() { }
    54     bool isFull() { return false; }
     49    virtual void setClient(SourceBufferPrivateClient*);
     50
     51    virtual void append(const unsigned char* data, unsigned length);
     52    virtual void abort();
     53    virtual void removedFromMediaSource();
     54
     55    virtual MediaPlayer::ReadyState readyState() const;
     56    virtual void setReadyState(MediaPlayer::ReadyState);
     57
     58    virtual void flushAndEnqueueNonDisplayingSamples(Vector<RefPtr<MediaSample>>, AtomicString);
     59    virtual void enqueueSample(PassRefPtr<MediaSample>, AtomicString);
     60    virtual bool isReadyForMoreSamples(AtomicString);
     61    virtual void setActive(bool);
     62    virtual void stopAskingForMoreSamples(AtomicString);
     63    virtual void notifyClientWhenReadyForMoreSamples(AtomicString);
    5564
    5665private:
    57     String m_type;
    58     RefPtr<MediaSourceClientGstreamer> m_client;
     66    ContentType m_type;
     67    RefPtr<MediaSourceClientGStreamer> m_client;
     68    SourceBufferPrivateClient* m_sourceBufferPrivateClient;
    5969    MediaPlayer::ReadyState m_readyState;
    6070};
  • trunk/Source/WebCore/platform/graphics/gstreamer/WebKitMediaSourceGStreamer.cpp

    r176664 r177790  
    33 *  Copyright (C) 2013 Collabora Ltd.
    44 *  Copyright (C) 2013 Orange
     5 *  Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
    56 *
    67 *  This library is free software; you can redistribute it and/or
     
    2425#if ENABLE(VIDEO) && ENABLE(MEDIA_SOURCE) && USE(GSTREAMER)
    2526
    26 #include "GRefPtrGStreamer.h"
    2727#include "GStreamerUtilities.h"
    2828#include "NotImplemented.h"
    2929#include "TimeRanges.h"
     30
    3031#include <gst/app/gstappsrc.h>
    3132#include <gst/gst.h>
    3233#include <gst/pbutils/missing-plugins.h>
    33 #include <wtf/gobject/GThreadSafeMainLoopSource.h>
    3434#include <wtf/gobject/GUniquePtr.h>
    3535#include <wtf/text/CString.h>
    3636
    37 typedef struct _Source {
    38     GstElement* appsrc;
    39     guint sourceid;        /* To control the GSource */
    40     GstPad* srcpad;
    41     gboolean padAdded;
    42 
    43     guint64 offset;
    44     guint64 size;
    45     gboolean paused;
    46 
    47     GThreadSafeMainLoopSource start;
    48     GThreadSafeMainLoopSource stop;
    49     GThreadSafeMainLoopSource needData;
    50     GThreadSafeMainLoopSource enoughData;
    51     GThreadSafeMainLoopSource seek;
    52 
    53     guint64 requestedOffset;
    54 } Source;
    55 
     37typedef struct _Source Source;
     38struct _Source {
     39    GstElement* src;
     40    // Just for identification
     41    WebCore::SourceBufferPrivate* sourceBuffer;
     42};
     43
     44struct _WebKitMediaSrcPrivate {
     45    GList* sources;
     46    gchar* location;
     47    GstClockTime duration;
     48    bool haveAppsrc;
     49    bool asyncStart;
     50    bool noMorePads;
     51};
     52
     53enum {
     54    Prop0,
     55    PropLocation
     56};
     57
     58static GstStaticPadTemplate srcTemplate = GST_STATIC_PAD_TEMPLATE("src_%u", GST_PAD_SRC,
     59    GST_PAD_SOMETIMES, GST_STATIC_CAPS_ANY);
    5660
    5761#define WEBKIT_MEDIA_SRC_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_MEDIA_SRC, WebKitMediaSrcPrivate))
    58 
    59 struct _WebKitMediaSrcPrivate {
    60     gchar* uri;
    61     Source sourceVideo;
    62     Source sourceAudio;
    63     WebCore::MediaPlayer* player;
    64     GstElement* playbin;
    65     gint64 duration;
    66     gboolean seekable;
    67     gboolean noMorePad;
    68     // TRUE if appsrc's version is >= 0.10.27, see
    69     // https://bugzilla.gnome.org/show_bug.cgi?id=609423
    70     gboolean haveAppSrc27;
    71     guint nbSource;
    72 };
    73 
    74 enum {
    75     PropLocation = 1,
    76     ProLast
    77 };
    78 
    79 static GstStaticPadTemplate srcTemplate = GST_STATIC_PAD_TEMPLATE("src_%u", GST_PAD_SRC, GST_PAD_SOMETIMES, GST_STATIC_CAPS_ANY);
    8062
    8163GST_DEBUG_CATEGORY_STATIC(webkit_media_src_debug);
     
    8971static gboolean webKitMediaSrcQueryWithParent(GstPad*, GstObject*, GstQuery*);
    9072
    91 static void webKitMediaVideoSrcNeedDataCb(GstAppSrc*, guint, gpointer);
    92 static void webKitMediaVideoSrcEnoughDataCb(GstAppSrc*, gpointer);
    93 static gboolean webKitMediaVideoSrcSeekDataCb(GstAppSrc*, guint64, gpointer);
    94 static void webKitMediaAudioSrcNeedDataCb(GstAppSrc*, guint, gpointer);
    95 static void webKitMediaAudioSrcEnoughDataCb(GstAppSrc*, gpointer);
    96 static gboolean webKitMediaAudioSrcSeekDataCb(GstAppSrc*, guint64, gpointer);
    97 static GstAppSrcCallbacks appsrcCallbacksVideo = {
    98     webKitMediaVideoSrcNeedDataCb,
    99     webKitMediaVideoSrcEnoughDataCb,
    100     webKitMediaVideoSrcSeekDataCb,
    101     { 0 }
    102 };
    103 static GstAppSrcCallbacks appsrcCallbacksAudio = {
    104     webKitMediaAudioSrcNeedDataCb,
    105     webKitMediaAudioSrcEnoughDataCb,
    106     webKitMediaAudioSrcSeekDataCb,
    107     { 0 }
    108 };
    10973#define webkit_media_src_parent_class parent_class
    11074// We split this out into another macro to avoid a check-webkit-style error.
     
    12589    gst_element_class_add_pad_template(eklass, gst_static_pad_template_get(&srcTemplate));
    12690
    127     gst_element_class_set_metadata(eklass, "WebKit Media source element", "Source", "Handles Blob uris", "Stephane Jadaud <sjadaud@sii.fr>");
     91    gst_element_class_set_static_metadata(eklass, "WebKit Media source element", "Source", "Handles Blob uris", "Stephane Jadaud <sjadaud@sii.fr>, Sebastian Dröge <sebastian@centricular.com>");
    12892
    12993    /* Allows setting the uri using the 'location' property, which is used
     
    139103}
    140104
    141 static void webKitMediaSrcAddSrc(WebKitMediaSrc* src, GstElement* element)
    142 {
    143     GstPad* ghostPad;
    144     WebKitMediaSrcPrivate* priv = src->priv;
    145 
    146     if (!gst_bin_add(GST_BIN(src), element)) {
    147         GST_DEBUG_OBJECT(src, "Src element not added");
    148         return;
    149     }
    150     GRefPtr<GstPad> targetsrc = adoptGRef(gst_element_get_static_pad(element, "src"));
    151     if (!targetsrc) {
    152         GST_DEBUG_OBJECT(src, "Pad not found");
    153         return;
    154     }
    155 
    156     gst_element_sync_state_with_parent(element);
    157     GUniquePtr<gchar> name(g_strdup_printf("src_%u", priv->nbSource));
    158     ghostPad = WebCore::webkitGstGhostPadFromStaticTemplate(&srcTemplate, name.get(), targetsrc.get());
    159     gst_pad_set_active(ghostPad, TRUE);
    160 
    161     priv->nbSource++;
    162 
    163     if (priv->sourceVideo.appsrc == element)
    164         priv->sourceVideo.srcpad = ghostPad;
    165     else if (priv->sourceAudio.appsrc == element)
    166         priv->sourceAudio.srcpad = ghostPad;
    167 
    168     GST_OBJECT_FLAG_SET(ghostPad, GST_PAD_FLAG_NEED_PARENT);
    169     gst_pad_set_query_function(ghostPad, webKitMediaSrcQueryWithParent);
    170 }
    171 
    172105static void webkit_media_src_init(WebKitMediaSrc* src)
    173106{
    174     WebKitMediaSrcPrivate* priv = WEBKIT_MEDIA_SRC_GET_PRIVATE(src);
    175     src->priv = priv;
    176     new (priv) WebKitMediaSrcPrivate();
    177 
    178     priv->sourceVideo.appsrc = gst_element_factory_make("appsrc", "videoappsrc");
    179     gst_app_src_set_callbacks(GST_APP_SRC(priv->sourceVideo.appsrc), &appsrcCallbacksVideo, src, 0);
    180     gst_app_src_set_stream_type(GST_APP_SRC(priv->sourceVideo.appsrc), GST_APP_STREAM_TYPE_SEEKABLE);
    181     webKitMediaSrcAddSrc(src, priv->sourceVideo.appsrc);
    182 
    183     priv->sourceAudio.appsrc = gst_element_factory_make("appsrc", "audioappsrc");
    184     gst_app_src_set_callbacks(GST_APP_SRC(priv->sourceAudio.appsrc), &appsrcCallbacksAudio, src, 0);
    185     gst_app_src_set_stream_type(GST_APP_SRC(priv->sourceAudio.appsrc), GST_APP_STREAM_TYPE_SEEKABLE);
    186     webKitMediaSrcAddSrc(src, priv->sourceAudio.appsrc);
     107    src->priv = WEBKIT_MEDIA_SRC_GET_PRIVATE(src);
    187108}
    188109
     
    192113    WebKitMediaSrcPrivate* priv = src->priv;
    193114
    194     g_free(priv->uri);
    195     priv->~WebKitMediaSrcPrivate();
     115    // TODO: Free sources
     116    g_free(priv->location);
    196117
    197118    GST_CALL_PARENT(G_OBJECT_CLASS, finalize, (object));
     
    201122{
    202123    WebKitMediaSrc* src = WEBKIT_MEDIA_SRC(object);
     124
    203125    switch (propId) {
    204126    case PropLocation:
     
    219141    switch (propId) {
    220142    case PropLocation:
    221         g_value_set_string(value, priv->uri);
     143        g_value_set_string(value, priv->location);
    222144        break;
    223145    default:
     
    228150}
    229151
    230 // must be called on main thread and with object unlocked
    231 static void webKitMediaVideoSrcStop(WebKitMediaSrc* src)
    232 {
    233     WebKitMediaSrcPrivate* priv = src->priv;
    234     gboolean seeking;
    235 
    236     GST_OBJECT_LOCK(src);
    237 
    238     seeking = priv->sourceVideo.seek.isActive();
    239 
    240     priv->sourceVideo.start.cancel();
    241 
    242     priv->player = 0;
    243     priv->playbin = 0;
    244 
    245     priv->sourceVideo.needData.cancel();
    246     priv->sourceVideo.enoughData.cancel();
    247     priv->sourceVideo.seek.cancel();
    248 
    249     priv->sourceVideo.paused = FALSE;
    250     priv->sourceVideo.offset = 0;
    251     priv->seekable = FALSE;
    252 
    253     priv->duration = 0;
    254     priv->nbSource = 0;
    255 
    256     GST_OBJECT_UNLOCK(src);
    257 
    258     if (priv->sourceVideo.appsrc) {
    259         gst_app_src_set_caps(GST_APP_SRC(priv->sourceVideo.appsrc), 0);
    260         if (!seeking)
    261             gst_app_src_set_size(GST_APP_SRC(priv->sourceVideo.appsrc), -1);
    262     }
    263 
    264     GST_DEBUG_OBJECT(src, "Stopped request");
    265 }
    266 
    267 static void webKitMediaAudioSrcStop(WebKitMediaSrc* src)
    268 {
    269     WebKitMediaSrcPrivate* priv = src->priv;
    270     gboolean seeking;
    271 
    272     GST_OBJECT_LOCK(src);
    273 
    274     seeking = priv->sourceAudio.seek.isActive();
    275 
    276     priv->sourceAudio.start.cancel();
    277 
    278     priv->player = 0;
    279 
    280     priv->playbin = 0;
    281 
    282     priv->sourceAudio.needData.cancel();
    283     priv->sourceAudio.enoughData.cancel();
    284     priv->sourceAudio.seek.cancel();
    285 
    286     priv->sourceAudio.paused = FALSE;
    287 
    288     priv->sourceAudio.offset = 0;
    289 
    290     priv->seekable = FALSE;
    291 
    292     priv->duration = 0;
    293     priv->nbSource = 0;
    294 
    295     GST_OBJECT_UNLOCK(src);
    296 
    297     if (priv->sourceAudio.appsrc) {
    298         gst_app_src_set_caps(GST_APP_SRC(priv->sourceAudio.appsrc), 0);
    299         if (!seeking)
    300             gst_app_src_set_size(GST_APP_SRC(priv->sourceAudio.appsrc), -1);
    301     }
    302 
    303     GST_DEBUG_OBJECT(src, "Stopped request");
    304 }
    305 
    306 // must be called on main thread and with object unlocked
    307 static void webKitMediaVideoSrcStart(WebKitMediaSrc* src)
    308 {
    309     WebKitMediaSrcPrivate* priv = src->priv;
    310 
    311     GST_OBJECT_LOCK(src);
    312     if (!priv->uri) {
    313         GST_ERROR_OBJECT(src, "No URI provided");
    314         GST_OBJECT_UNLOCK(src);
    315         webKitMediaVideoSrcStop(src);
    316         return;
    317     }
    318 
    319     GST_OBJECT_UNLOCK(src);
    320     GST_DEBUG_OBJECT(src, "Started request");
    321 }
    322 
    323 // must be called on main thread and with object unlocked
    324 static void webKitMediaAudioSrcStart(WebKitMediaSrc* src)
    325 {
    326     WebKitMediaSrcPrivate* priv = src->priv;
    327 
    328     GST_OBJECT_LOCK(src);
    329     if (!priv->uri) {
    330         GST_ERROR_OBJECT(src, "No URI provided");
    331         GST_OBJECT_UNLOCK(src);
    332         webKitMediaAudioSrcStop(src);
    333         return;
    334     }
    335 
    336     GST_OBJECT_UNLOCK(src);
    337     GST_DEBUG_OBJECT(src, "Started request");
     152static void webKitMediaSrcDoAsyncStart(WebKitMediaSrc* src)
     153{
     154    WebKitMediaSrcPrivate* priv = src->priv;
     155    priv->asyncStart = true;
     156    GST_BIN_CLASS(parent_class)->handle_message(GST_BIN(src),
     157        gst_message_new_async_start(GST_OBJECT(src)));
     158}
     159
     160static void webKitMediaSrcDoAsyncDone(WebKitMediaSrc* src)
     161{
     162    WebKitMediaSrcPrivate* priv = src->priv;
     163    if (priv->asyncStart) {
     164        GST_BIN_CLASS(parent_class)->handle_message(GST_BIN(src),
     165            gst_message_new_async_done(GST_OBJECT(src), GST_CLOCK_TIME_NONE));
     166        priv->asyncStart = false;
     167    }
    338168}
    339169
     
    345175
    346176    switch (transition) {
    347     case GST_STATE_CHANGE_NULL_TO_READY:
    348         if (!priv->sourceVideo.appsrc && !priv->sourceAudio.appsrc) {
    349             gst_element_post_message(element,
    350                 gst_missing_element_message_new(element, "appsrc"));
    351             GST_ELEMENT_ERROR(src, CORE, MISSING_PLUGIN, (0), ("no appsrc"));
    352             return GST_STATE_CHANGE_FAILURE;
    353         }
     177    case GST_STATE_CHANGE_READY_TO_PAUSED:
     178        priv->noMorePads = false;
     179        webKitMediaSrcDoAsyncStart(src);
    354180        break;
    355181    default:
     
    360186    if (G_UNLIKELY(ret == GST_STATE_CHANGE_FAILURE)) {
    361187        GST_DEBUG_OBJECT(src, "State change failed");
     188        webKitMediaSrcDoAsyncDone(src);
    362189        return ret;
    363190    }
     
    365192    switch (transition) {
    366193    case GST_STATE_CHANGE_READY_TO_PAUSED:
    367         GST_DEBUG_OBJECT(src, "READY->PAUSED");
    368         GST_OBJECT_LOCK(src);
    369 
    370         gst_object_ref(src);
    371         priv->sourceVideo.start.schedule("[WebKit] webKitMediaVideoSrcStart", std::function<void()>(std::bind(webKitMediaVideoSrcStart, src)), G_PRIORITY_DEFAULT,
    372             [src] { gst_object_unref(src); });
    373 
    374         gst_object_ref(src);
    375         priv->sourceAudio.start.schedule("[WebKit] webKitMediaAudioSrcStart", std::function<void()>(std::bind(webKitMediaAudioSrcStart, src)), G_PRIORITY_DEFAULT,
    376             [src] { gst_object_unref(src); });
    377 
    378         GST_OBJECT_UNLOCK(src);
     194        ret = GST_STATE_CHANGE_ASYNC;
    379195        break;
    380196    case GST_STATE_CHANGE_PAUSED_TO_READY:
    381         GST_DEBUG_OBJECT(src, "PAUSED->READY");
    382         GST_OBJECT_LOCK(src);
    383 
    384         gst_object_ref(src);
    385         priv->sourceVideo.stop.schedule("[WebKit] webKitMediaVideoSrcStop", std::function<void()>(std::bind(webKitMediaVideoSrcStop, src)), G_PRIORITY_DEFAULT,
    386             [src] { gst_object_unref(src); });
    387 
    388         gst_object_ref(src);
    389         priv->sourceAudio.stop.schedule("[WebKit] webKitMediaAudioSrcStop", std::function<void()>(std::bind(webKitMediaAudioSrcStop, src)), G_PRIORITY_DEFAULT,
    390             [src] { gst_object_unref(src); });
    391 
    392         GST_OBJECT_UNLOCK(src);
     197        webKitMediaSrcDoAsyncDone(src);
     198        priv->noMorePads = false;
    393199        break;
    394200    default:
     
    420226    case GST_QUERY_URI: {
    421227        GST_OBJECT_LOCK(src);
    422         gst_query_set_uri(query, src->priv->uri);
     228        gst_query_set_uri(query, src->priv->location);
    423229        GST_OBJECT_UNLOCK(src);
    424230        result = TRUE;
     
    455261
    456262    GST_OBJECT_LOCK(src);
    457     ret = g_strdup(src->priv->uri);
     263    ret = g_strdup(src->priv->location);
    458264    GST_OBJECT_UNLOCK(src);
    459265    return ret;
     
    464270    WebKitMediaSrc* src = WEBKIT_MEDIA_SRC(handler);
    465271    WebKitMediaSrcPrivate* priv = src->priv;
     272
    466273    if (GST_STATE(src) >= GST_STATE_PAUSED) {
    467274        GST_ERROR_OBJECT(src, "URI can only be set in states < PAUSED");
     
    470277
    471278    GST_OBJECT_LOCK(src);
    472     g_free(priv->uri);
    473     priv->uri = 0;
     279    g_free(priv->location);
     280    priv->location = 0;
    474281    if (!uri) {
    475282        GST_OBJECT_UNLOCK(src);
     
    479286    WebCore::URL url(WebCore::URL(), uri);
    480287
    481     priv->uri = g_strdup(url.string().utf8().data());
     288    priv->location = g_strdup(url.string().utf8().data());
    482289    GST_OBJECT_UNLOCK(src);
    483290    return TRUE;
    484291}
    485 
    486292static void webKitMediaSrcUriHandlerInit(gpointer gIface, gpointer)
    487293{
     
    494300}
    495301
    496 // appsrc callbacks
    497 static void webKitMediaVideoSrcNeedDataMainCb(WebKitMediaSrc* src)
    498 {
    499     WebKitMediaSrcPrivate* priv = src->priv;
    500 
    501     GST_OBJECT_LOCK(src);
    502     priv->sourceVideo.paused = FALSE;
    503     GST_OBJECT_UNLOCK(src);
    504 }
    505 
    506 static void webKitMediaAudioSrcNeedDataMainCb(WebKitMediaSrc* src)
    507 {
    508     WebKitMediaSrcPrivate* priv = src->priv;
    509 
    510     GST_OBJECT_LOCK(src);
    511     priv->sourceAudio.paused = FALSE;
    512     GST_OBJECT_UNLOCK(src);
    513 }
    514 
    515 static void webKitMediaVideoSrcNeedDataCb(GstAppSrc*, guint length, gpointer userData)
    516 {
    517     WebKitMediaSrc* src = WEBKIT_MEDIA_SRC(userData);
    518     WebKitMediaSrcPrivate* priv = src->priv;
    519 
    520     GST_DEBUG_OBJECT(src, "Need more data: %u", length);
    521 
    522     GST_OBJECT_LOCK(src);
    523     if (priv->sourceVideo.needData.isScheduled() || !priv->sourceVideo.paused) {
    524         GST_OBJECT_UNLOCK(src);
    525         return;
    526     }
    527 
    528     gst_object_ref(src);
    529     priv->sourceVideo.needData.schedule("[WebKit] webKitMediaVideoSrcNeedDataMainCb", std::function<void()>(std::bind(webKitMediaVideoSrcNeedDataMainCb, src)), G_PRIORITY_DEFAULT,
    530         [src] { gst_object_unref(src); });
    531     GST_OBJECT_UNLOCK(src);
    532 }
    533 
    534 static void webKitMediaAudioSrcNeedDataCb(GstAppSrc*, guint length, gpointer userData)
    535 {
    536     WebKitMediaSrc* src = WEBKIT_MEDIA_SRC(userData);
    537     WebKitMediaSrcPrivate* priv = src->priv;
    538 
    539     GST_DEBUG_OBJECT(src, "Need more data: %u", length);
    540 
    541     GST_OBJECT_LOCK(src);
    542     if (priv->sourceAudio.needData.isScheduled() || !priv->sourceAudio.paused) {
    543         GST_OBJECT_UNLOCK(src);
    544         return;
    545     }
    546 
    547     gst_object_ref(src);
    548     priv->sourceAudio.needData.schedule("[WebKit] webKitMediaAudioSrcNeedDataMainCb", std::function<void()>(std::bind(webKitMediaAudioSrcNeedDataMainCb, src)), G_PRIORITY_DEFAULT,
    549         [src] { gst_object_unref(src); });
    550     GST_OBJECT_UNLOCK(src);
    551 }
    552 
    553 static void webKitMediaVideoSrcEnoughDataMainCb(WebKitMediaSrc* src)
    554 {
    555     WebKitMediaSrcPrivate* priv = src->priv;
    556 
    557     GST_OBJECT_LOCK(src);
    558     priv->sourceVideo.paused = TRUE;
    559     GST_OBJECT_UNLOCK(src);
    560 }
    561 
    562 static void webKitMediaAudioSrcEnoughDataMainCb(WebKitMediaSrc* src)
    563 {
    564     WebKitMediaSrcPrivate* priv = src->priv;
    565 
    566     GST_OBJECT_LOCK(src);
    567     priv->sourceAudio.paused = TRUE;
    568     GST_OBJECT_UNLOCK(src);
    569 }
    570 
    571 static void webKitMediaVideoSrcEnoughDataCb(GstAppSrc*, gpointer userData)
    572 {
    573     WebKitMediaSrc* src = WEBKIT_MEDIA_SRC(userData);
    574     WebKitMediaSrcPrivate* priv = src->priv;
    575 
    576     GST_DEBUG_OBJECT(src, "Have enough data");
    577 
    578     GST_OBJECT_LOCK(src);
    579     if (priv->sourceVideo.enoughData.isScheduled() || priv->sourceVideo.paused) {
    580         GST_OBJECT_UNLOCK(src);
    581         return;
    582     }
    583 
    584     gst_object_ref(src);
    585     priv->sourceVideo.enoughData.schedule("[WebKit] webKitMediaVideoSrcEnoughDataMainCb", std::function<void()>(std::bind(webKitMediaVideoSrcEnoughDataMainCb, src)), G_PRIORITY_DEFAULT,
    586         [src] { gst_object_unref(src); });
    587 
    588     GST_OBJECT_UNLOCK(src);
    589 }
    590 
    591 static void webKitMediaAudioSrcEnoughDataCb(GstAppSrc*, gpointer userData)
    592 {
    593     WebKitMediaSrc* src = WEBKIT_MEDIA_SRC(userData);
    594     WebKitMediaSrcPrivate* priv = src->priv;
    595 
    596     GST_DEBUG_OBJECT(src, "Have enough data");
    597 
    598     GST_OBJECT_LOCK(src);
    599     if (priv->sourceAudio.enoughData.isScheduled() || priv->sourceAudio.paused) {
    600         GST_OBJECT_UNLOCK(src);
    601         return;
    602     }
    603 
    604     gst_object_ref(src);
    605     priv->sourceAudio.enoughData.schedule("[WebKit] webKitMediaAudioSrcEnoughDataMainCb", std::function<void()>(std::bind(webKitMediaAudioSrcEnoughDataMainCb, src)), G_PRIORITY_DEFAULT,
    606         [src] { gst_object_unref(src); });
    607 
    608     GST_OBJECT_UNLOCK(src);
    609 }
    610 
    611 static void webKitMediaVideoSrcSeekMainCb(WebKitMediaSrc*)
    612 {
    613     notImplemented();
    614 }
    615 
    616 
    617 static void webKitMediaAudioSrcSeekMainCb(WebKitMediaSrc*)
    618 {
    619     notImplemented();
    620 }
    621 
    622 static gboolean webKitMediaVideoSrcSeekDataCb(GstAppSrc*, guint64 offset, gpointer userData)
    623 {
    624     WebKitMediaSrc* src = WEBKIT_MEDIA_SRC(userData);
    625     WebKitMediaSrcPrivate* priv = src->priv;
    626 
    627     GST_DEBUG_OBJECT(src, "Seeking to offset: %" G_GUINT64_FORMAT, offset);
    628     GST_OBJECT_LOCK(src);
    629     if (offset == priv->sourceVideo.offset && priv->sourceVideo.requestedOffset == priv->sourceVideo.offset) {
    630         GST_OBJECT_UNLOCK(src);
    631         return TRUE;
    632     }
    633 
    634     if (!priv->seekable) {
    635         GST_OBJECT_UNLOCK(src);
    636         return FALSE;
    637     }
    638     if (offset > priv->sourceVideo.size) {
    639         GST_OBJECT_UNLOCK(src);
    640         return FALSE;
    641     }
    642 
    643     GST_DEBUG_OBJECT(src, "Doing range-request seek");
    644     priv->sourceVideo.requestedOffset = offset;
    645 
    646     gst_object_ref(src);
    647     priv->sourceVideo.seek.schedule("[WebKit] webKitMediaVideoSrcSeekMainCb", std::function<void()>(std::bind(webKitMediaVideoSrcSeekMainCb, src)), G_PRIORITY_DEFAULT,
    648         [src] { gst_object_unref(src); });
    649 
    650     GST_OBJECT_UNLOCK(src);
    651 
    652     return TRUE;
    653 }
    654 
    655 static gboolean webKitMediaAudioSrcSeekDataCb(GstAppSrc*, guint64 offset, gpointer userData)
    656 {
    657     WebKitMediaSrc* src = WEBKIT_MEDIA_SRC(userData);
    658     WebKitMediaSrcPrivate* priv = src->priv;
    659 
    660     GST_DEBUG_OBJECT(src, "Seeking to offset: %" G_GUINT64_FORMAT, offset);
    661     GST_OBJECT_LOCK(src);
    662     if (offset == priv->sourceAudio.offset && priv->sourceAudio.requestedOffset == priv->sourceAudio.offset) {
    663         GST_OBJECT_UNLOCK(src);
    664         return TRUE;
    665     }
    666 
    667     if (!priv->seekable) {
    668         GST_OBJECT_UNLOCK(src);
    669         return FALSE;
    670     }
    671     if (offset > priv->sourceAudio.size) {
    672         GST_OBJECT_UNLOCK(src);
    673         return FALSE;
    674     }
    675 
    676     GST_DEBUG_OBJECT(src, "Doing range-request seek");
    677     priv->sourceAudio.requestedOffset = offset;
    678 
    679     gst_object_ref(src);
    680     priv->sourceAudio.seek.schedule("[WebKit] webKitMediaAudioSrcSeekMainCb", std::function<void()>(std::bind(webKitMediaAudioSrcSeekMainCb, src)), G_PRIORITY_DEFAULT,
    681         [src] { gst_object_unref(src); });
    682 
    683     GST_OBJECT_UNLOCK(src);
    684 
    685     return TRUE;
    686 }
    687 
    688 void webKitMediaSrcSetMediaPlayer(WebKitMediaSrc* src, WebCore::MediaPlayer* player)
    689 {
    690     WebKitMediaSrcPrivate* priv = src->priv;
    691     priv->player = player;
    692 }
    693 
    694 void webKitMediaSrcSetPlayBin(WebKitMediaSrc* src, GstElement* playBin)
    695 {
    696     WebKitMediaSrcPrivate* priv = src->priv;
    697     priv->playbin = playBin;
    698 }
    699 
    700 MediaSourceClientGstreamer::MediaSourceClientGstreamer(WebKitMediaSrc* src)
    701     : m_src(static_cast<WebKitMediaSrc*>(gst_object_ref(src)))
    702 {
    703 }
    704 
    705 MediaSourceClientGstreamer::~MediaSourceClientGstreamer()
    706 {
    707     gst_object_unref(m_src);
    708 }
    709 
    710 void MediaSourceClientGstreamer::didReceiveDuration(double duration)
     302namespace WebCore {
     303MediaSourceClientGStreamer::MediaSourceClientGStreamer(WebKitMediaSrc* src)
     304    : m_src(adoptGRef(static_cast<WebKitMediaSrc*>(gst_object_ref(src))))
     305{
     306}
     307
     308MediaSourceClientGStreamer::~MediaSourceClientGStreamer()
     309{
     310}
     311
     312MediaSourcePrivate::AddStatus MediaSourceClientGStreamer::addSourceBuffer(PassRefPtr<SourceBufferPrivate> sourceBufferPrivate, const ContentType&)
    711313{
    712314    WebKitMediaSrcPrivate* priv = m_src->priv;
    713     GST_DEBUG_OBJECT(m_src, "Received duration: %lf", duration);
    714 
    715     GST_OBJECT_LOCK(m_src);
    716     priv->duration = duration >= 0.0 ? static_cast<gint64>(duration*GST_SECOND) : 0;
    717     GST_OBJECT_UNLOCK(m_src);
    718 }
    719 
    720 void MediaSourceClientGstreamer::didReceiveData(const char* data, int length, String type)
     315
     316    if (priv->noMorePads) {
     317        GST_ERROR_OBJECT(m_src.get(), "Adding new source buffers after first data not supported yet");
     318        return MediaSourcePrivate::NotSupported;
     319    }
     320
     321    GST_DEBUG_OBJECT(m_src.get(), "State %d", static_cast<int>(GST_STATE(m_src.get())));
     322
     323    GST_OBJECT_LOCK(m_src.get());
     324
     325    Source* source = g_new0(Source, 1);
     326    guint numberOfSources = g_list_length(priv->sources);
     327    GUniquePtr<gchar> srcName(g_strdup_printf("src%u", numberOfSources));
     328
     329    source->src = gst_element_factory_make("appsrc", srcName.get());
     330    source->sourceBuffer = sourceBufferPrivate.get();
     331
     332    GUniquePtr<gchar> padName(g_strdup_printf("src_%u", numberOfSources));
     333    priv->sources = g_list_prepend(priv->sources, source);
     334    GST_OBJECT_UNLOCK(m_src.get());
     335
     336    priv->haveAppsrc = source->src;
     337
     338    gst_bin_add(GST_BIN(m_src.get()), source->src);
     339    GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(source->src, "src"));
     340    GRefPtr<GstPad> ghostPad = adoptGRef(gst_ghost_pad_new_from_template(padName.get(), pad.get(),
     341        gst_static_pad_template_get(&srcTemplate)));
     342    gst_pad_set_query_function(ghostPad.get(), webKitMediaSrcQueryWithParent);
     343    gst_pad_set_active(ghostPad.get(), TRUE);
     344    gst_element_add_pad(GST_ELEMENT(m_src.get()), ghostPad.leakRef());
     345
     346    gst_element_sync_state_with_parent(source->src);
     347
     348    return MediaSourcePrivate::Ok;
     349}
     350
     351void MediaSourceClientGStreamer::durationChanged(const MediaTime& duration)
     352{
     353    WebKitMediaSrcPrivate* priv = m_src->priv;
     354    GstClockTime gstDuration = gst_util_uint64_scale(duration.timeValue(), GST_SECOND, duration.timeScale());
     355
     356    GST_DEBUG_OBJECT(m_src.get(), "Received duration: %" GST_TIME_FORMAT, GST_TIME_ARGS(gstDuration));
     357
     358    GST_OBJECT_LOCK(m_src.get());
     359    priv->duration = gstDuration;
     360    GST_OBJECT_UNLOCK(m_src.get());
     361    gst_element_post_message(GST_ELEMENT(m_src.get()), gst_message_new_duration_changed(GST_OBJECT(m_src.get())));
     362}
     363
     364SourceBufferPrivateClient::AppendResult MediaSourceClientGStreamer::append(PassRefPtr<SourceBufferPrivate> sourceBufferPrivate, const unsigned char* data, unsigned length)
    721365{
    722366    WebKitMediaSrcPrivate* priv = m_src->priv;
    723367    GstFlowReturn ret = GST_FLOW_OK;
    724     GstBuffer * buffer;
    725 
    726     if (type.startsWith("video")) {
    727         if (priv->noMorePad == FALSE && priv->sourceVideo.padAdded == TRUE) {
    728             gst_element_no_more_pads(GST_ELEMENT(m_src));
    729             priv->noMorePad = TRUE;
     368    GstBuffer* buffer;
     369    Source* source = 0;
     370
     371    if (!priv->noMorePads) {
     372        priv->noMorePads = true;
     373        gst_element_no_more_pads(GST_ELEMENT(m_src.get()));
     374        webKitMediaSrcDoAsyncDone(m_src.get());
     375    }
     376
     377    for (GList* iter = priv->sources; iter; iter = iter->next) {
     378        Source* tmp = static_cast<Source*>(iter->data);
     379        if (tmp->sourceBuffer == sourceBufferPrivate.get()) {
     380            source = tmp;
     381            break;
    730382        }
    731         if (priv->noMorePad == FALSE && priv->sourceVideo.padAdded == FALSE) {
    732             gst_element_add_pad(GST_ELEMENT(m_src), priv->sourceVideo.srcpad);
    733             priv->sourceVideo.padAdded = TRUE;
     383    }
     384
     385    if (!source || !source->src)
     386        return SourceBufferPrivateClient::ReadStreamFailed;
     387
     388    buffer = gst_buffer_new_and_alloc(length);
     389    gst_buffer_fill(buffer, 0, data, length);
     390
     391    ret = gst_app_src_push_buffer(GST_APP_SRC(source->src), buffer);
     392    GST_DEBUG_OBJECT(m_src.get(), "push buffer %d\n", static_cast<int>(ret));
     393
     394    if (ret == GST_FLOW_OK)
     395        return SourceBufferPrivateClient::AppendSucceeded;
     396
     397    return SourceBufferPrivateClient::ReadStreamFailed;
     398}
     399
     400void MediaSourceClientGStreamer::markEndOfStream(MediaSourcePrivate::EndOfStreamStatus)
     401{
     402    WebKitMediaSrcPrivate* priv = m_src->priv;
     403
     404    GST_DEBUG_OBJECT(m_src.get(), "Have EOS");
     405
     406    if (!priv->noMorePads) {
     407        priv->noMorePads = true;
     408        gst_element_no_more_pads(GST_ELEMENT(m_src.get()));
     409        webKitMediaSrcDoAsyncDone(m_src.get());
     410    }
     411
     412    for (GList* iter = priv->sources; iter; iter = iter->next) {
     413        Source* source = static_cast<Source*>(iter->data);
     414        if (source->src)
     415            gst_app_src_end_of_stream(GST_APP_SRC(source->src));
     416    }
     417}
     418
     419void MediaSourceClientGStreamer::removedFromMediaSource(PassRefPtr<SourceBufferPrivate> sourceBufferPrivate)
     420{
     421    WebKitMediaSrcPrivate* priv = m_src->priv;
     422    Source* source = 0;
     423
     424    for (GList* iter = priv->sources; iter; iter = iter->next) {
     425        Source* tmp = static_cast<Source*>(iter->data);
     426        if (tmp->sourceBuffer == sourceBufferPrivate.get()) {
     427            source = tmp;
     428            break;
    734429        }
    735         GST_OBJECT_LOCK(m_src);
    736         buffer = WebCore::createGstBufferForData(data, length);
    737         GST_OBJECT_UNLOCK(m_src);
    738 
    739         ret = gst_app_src_push_buffer(GST_APP_SRC(priv->sourceVideo.appsrc), buffer);
    740     } else if (type.startsWith("audio")) {
    741         if (priv->noMorePad == FALSE && priv->sourceAudio.padAdded == TRUE) {
    742             gst_element_no_more_pads(GST_ELEMENT(m_src));
    743             priv->noMorePad = TRUE;
    744         }
    745         if (priv->noMorePad == FALSE && priv->sourceAudio.padAdded == FALSE) {
    746             gst_element_add_pad(GST_ELEMENT(m_src), priv->sourceAudio.srcpad);
    747             priv->sourceAudio.padAdded = TRUE;
    748         }
    749         GST_OBJECT_LOCK(m_src);
    750         buffer = WebCore::createGstBufferForData(data, length);
    751         GST_OBJECT_UNLOCK(m_src);
    752 
    753         ret = gst_app_src_push_buffer(GST_APP_SRC(priv->sourceAudio.appsrc), buffer);
    754     }
    755 
    756     if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS)
    757         GST_ELEMENT_ERROR(m_src, CORE, FAILED, (0), (0));
    758 }
    759 
    760 void MediaSourceClientGstreamer::didFinishLoading(double)
    761 {
    762     WebKitMediaSrcPrivate* priv = m_src->priv;
    763 
    764     GST_DEBUG_OBJECT(m_src, "Have EOS");
    765 
    766     GST_OBJECT_LOCK(m_src);
    767     if (!priv->sourceVideo.seek.isActive()) {
    768         GST_OBJECT_UNLOCK(m_src);
    769         gst_app_src_end_of_stream(GST_APP_SRC(priv->sourceVideo.appsrc));
    770     } else
    771         GST_OBJECT_UNLOCK(m_src);
    772 
    773     GST_OBJECT_LOCK(m_src);
    774     if (!priv->sourceAudio.seek.isActive()) {
    775         GST_OBJECT_UNLOCK(m_src);
    776         gst_app_src_end_of_stream(GST_APP_SRC(priv->sourceAudio.appsrc));
    777     } else
    778         GST_OBJECT_UNLOCK(m_src);
    779 }
    780 
    781 void MediaSourceClientGstreamer::didFail()
    782 {
    783     gst_app_src_end_of_stream(GST_APP_SRC(m_src->priv->sourceVideo.appsrc));
    784     gst_app_src_end_of_stream(GST_APP_SRC(m_src->priv->sourceAudio.appsrc));
    785 }
     430    }
     431
     432    ASSERT(source && source->src);
     433
     434    gst_app_src_end_of_stream(GST_APP_SRC(source->src));
     435}
     436
     437};
     438
     439namespace WTF {
     440template <> GRefPtr<WebKitMediaSrc> adoptGRef(WebKitMediaSrc* ptr)
     441{
     442    ASSERT(!ptr || !g_object_is_floating(G_OBJECT(ptr)));
     443    return GRefPtr<WebKitMediaSrc>(ptr, GRefPtrAdopt);
     444}
     445
     446template <> WebKitMediaSrc* refGPtr<WebKitMediaSrc>(WebKitMediaSrc* ptr)
     447{
     448    if (ptr)
     449        gst_object_ref_sink(GST_OBJECT(ptr));
     450
     451    return ptr;
     452}
     453
     454template <> void derefGPtr<WebKitMediaSrc>(WebKitMediaSrc* ptr)
     455{
     456    if (ptr)
     457        gst_object_unref(ptr);
     458}
     459};
    786460
    787461#endif // USE(GSTREAMER)
  • trunk/Source/WebCore/platform/graphics/gstreamer/WebKitMediaSourceGStreamer.h

    r159335 r177790  
    33 *  Copyright (C) 2013 Collabora Ltd.
    44 *  Copyright (C) 2013 Orange
     5 *  Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
    56 *
    67 *  This library is free software; you can redistribute it and/or
     
    2324#if ENABLE(VIDEO) && ENABLE(MEDIA_SOURCE) && USE(GSTREAMER)
    2425
     26#include "GRefPtrGStreamer.h"
    2527#include "MediaPlayer.h"
     28#include "MediaSource.h"
     29#include "SourceBufferPrivate.h"
     30#include "SourceBufferPrivateClient.h"
     31
    2632#include <gst/gst.h>
    2733
     
    4955
    5056GType webkit_media_src_get_type(void);
    51 void webKitMediaSrcSetMediaPlayer(WebKitMediaSrc*, WebCore::MediaPlayer*);
    52 void webKitMediaSrcSetPlayBin(WebKitMediaSrc*, GstElement*);
    5357
    5458G_END_DECLS
    5559
    56 class MediaSourceClientGstreamer: public RefCounted<MediaSourceClientGstreamer> {
     60namespace WTF {
     61template<> GRefPtr<WebKitMediaSrc> adoptGRef(WebKitMediaSrc* ptr);
     62template<> WebKitMediaSrc* refGPtr<WebKitMediaSrc>(WebKitMediaSrc* ptr);
     63template<> void derefGPtr<WebKitMediaSrc>(WebKitMediaSrc* ptr);
     64};
     65
     66namespace WebCore {
     67
     68class ContentType;
     69
     70class MediaSourceClientGStreamer: public RefCounted<MediaSourceClientGStreamer> {
    5771    public:
    58         MediaSourceClientGstreamer(WebKitMediaSrc*);
    59         ~MediaSourceClientGstreamer();
     72        MediaSourceClientGStreamer(WebKitMediaSrc*);
     73        virtual ~MediaSourceClientGStreamer();
    6074
    61         void didReceiveDuration(double);
    62         void didReceiveData(const char*, int, String);
    63         void didFinishLoading(double);
    64         void didFail();
     75        // From MediaSourceGStreamer
     76        MediaSourcePrivate::AddStatus addSourceBuffer(PassRefPtr<SourceBufferPrivate>, const ContentType&);
     77        void durationChanged(const MediaTime&);
     78        void markEndOfStream(MediaSourcePrivate::EndOfStreamStatus);
     79
     80        // From SourceBufferPrivateGStreamer
     81        SourceBufferPrivateClient::AppendResult append(PassRefPtr<SourceBufferPrivate>, const unsigned char*, unsigned);
     82        void removedFromMediaSource(PassRefPtr<SourceBufferPrivate>);
    6583
    6684    private:
    67         WebKitMediaSrc* m_src;
     85        GRefPtr<WebKitMediaSrc> m_src;
    6886};
    6987
     88};
    7089
    7190#endif // USE(GSTREAMER)
Note: See TracChangeset for help on using the changeset viewer.