SourceBufferPrivateGStreamer.cpp [plain text]
#include "config.h"
#include "SourceBufferPrivateGStreamer.h"
#if ENABLE(MEDIA_SOURCE) && USE(GSTREAMER)
#include "AppendPipeline.h"
#include "ContentType.h"
#include "GStreamerCommon.h"
#include "MediaPlayerPrivateGStreamerMSE.h"
#include "MediaSample.h"
#include "MediaSourcePrivateGStreamer.h"
#include "NotImplemented.h"
#include "PlaybackPipeline.h"
#include "WebKitMediaSourceGStreamer.h"
namespace WebCore {
Ref<SourceBufferPrivateGStreamer> SourceBufferPrivateGStreamer::create(MediaSourcePrivateGStreamer* mediaSource, const ContentType& contentType, MediaPlayerPrivateGStreamerMSE& playerPrivate)
{
return adoptRef(*new SourceBufferPrivateGStreamer(mediaSource, contentType, playerPrivate));
}
SourceBufferPrivateGStreamer::SourceBufferPrivateGStreamer(MediaSourcePrivateGStreamer* mediaSource, const ContentType& contentType, MediaPlayerPrivateGStreamerMSE& playerPrivate)
: SourceBufferPrivate()
, m_mediaSource(mediaSource)
, m_type(contentType)
, m_playerPrivate(playerPrivate)
, m_appendPipeline(makeUniqueRef<AppendPipeline>(*this, playerPrivate))
#if !RELEASE_LOG_DISABLED
, m_logger(mediaSource->logger())
, m_logIdentifier(mediaSource->nextSourceBufferLogIdentifier())
#endif
{
}
void SourceBufferPrivateGStreamer::append(Vector<unsigned char>&& data)
{
ASSERT(isMainThread());
ASSERT(m_mediaSource);
ASSERT(m_client);
GST_DEBUG("Appending %zu bytes", data.size());
auto* bufferData = data.data();
auto bufferLength = data.size();
GRefPtr<GstBuffer> buffer = adoptGRef(gst_buffer_new_wrapped_full(static_cast<GstMemoryFlags>(0), bufferData, bufferLength, 0, bufferLength, new Vector<unsigned char>(WTFMove(data)),
[](gpointer data)
{
delete static_cast<Vector<unsigned char>*>(data);
}));
m_appendPipeline->pushNewBuffer(WTFMove(buffer));
}
void SourceBufferPrivateGStreamer::abort()
{
ASSERT(isMainThread());
GST_DEBUG("aborting");
m_appendPipeline->resetParserState();
}
void SourceBufferPrivateGStreamer::resetParserState()
{
ASSERT(isMainThread());
GST_DEBUG("resetting parser state");
m_appendPipeline->resetParserState();
}
void SourceBufferPrivateGStreamer::removedFromMediaSource()
{
ASSERT(isMainThread());
clearTrackBuffers();
m_mediaSource->removeSourceBuffer(this);
m_playerPrivate.playbackPipeline()->removeSourceBuffer(this);
ASSERT(refCount() == 1);
}
MediaPlayer::ReadyState SourceBufferPrivateGStreamer::readyState() const
{
return m_mediaSource->readyState();
}
void SourceBufferPrivateGStreamer::setReadyState(MediaPlayer::ReadyState state)
{
m_mediaSource->setReadyState(state);
}
void SourceBufferPrivateGStreamer::flush(const AtomString& trackId)
{
ASSERT(isMainThread());
if (!m_playerPrivate.seeking())
m_playerPrivate.playbackPipeline()->flush(trackId);
}
void SourceBufferPrivateGStreamer::enqueueSample(Ref<MediaSample>&& sample, const AtomString&)
{
ASSERT(isMainThread());
m_notifyWhenReadyForMoreSamples = false;
m_playerPrivate.playbackPipeline()->enqueueSample(WTFMove(sample));
}
void SourceBufferPrivateGStreamer::allSamplesInTrackEnqueued(const AtomString& trackId)
{
ASSERT(isMainThread());
m_playerPrivate.playbackPipeline()->allSamplesInTrackEnqueued(trackId);
}
bool SourceBufferPrivateGStreamer::isReadyForMoreSamples(const AtomString&)
{
return m_isReadyForMoreSamples;
}
void SourceBufferPrivateGStreamer::setReadyForMoreSamples(bool isReady)
{
ASSERT(WTF::isMainThread());
m_isReadyForMoreSamples = isReady;
}
void SourceBufferPrivateGStreamer::notifyReadyForMoreSamples()
{
ASSERT(WTF::isMainThread());
setReadyForMoreSamples(true);
if (m_notifyWhenReadyForMoreSamples)
provideMediaData(m_trackId);
}
void SourceBufferPrivateGStreamer::setActive(bool isActive)
{
m_isActive = isActive;
m_mediaSource->sourceBufferPrivateDidChangeActiveState(this, isActive);
}
bool SourceBufferPrivateGStreamer::isActive() const
{
return m_isActive;
}
void SourceBufferPrivateGStreamer::notifyClientWhenReadyForMoreSamples(const AtomString& trackId)
{
ASSERT(WTF::isMainThread());
m_notifyWhenReadyForMoreSamples = true;
m_trackId = trackId;
}
void SourceBufferPrivateGStreamer::didReceiveInitializationSegment(SourceBufferPrivateClient::InitializationSegment&& initializationSegment, CompletionHandler<void()>&& completionHandler)
{
SourceBufferPrivate::didReceiveInitializationSegment(WTFMove(initializationSegment), WTFMove(completionHandler));
}
void SourceBufferPrivateGStreamer::didReceiveSample(MediaSample& sample)
{
SourceBufferPrivate::didReceiveSample(sample);
}
void SourceBufferPrivateGStreamer::didReceiveAllPendingSamples()
{
SourceBufferPrivate::appendCompleted(true, m_mediaSource ? m_mediaSource->isEnded() : true);
}
void SourceBufferPrivateGStreamer::appendParsingFailed()
{
SourceBufferPrivate::appendCompleted(false, m_mediaSource ? m_mediaSource->isEnded() : true);
}
bool SourceBufferPrivateGStreamer::isSeeking() const
{
return m_mediaSource && m_mediaSource->isSeeking();
}
MediaTime SourceBufferPrivateGStreamer::currentMediaTime() const
{
if (!m_mediaSource)
return { };
return m_mediaSource->currentMediaTime();
}
MediaTime SourceBufferPrivateGStreamer::duration() const
{
if (!m_mediaSource)
return { };
return m_mediaSource->duration();
}
#if !RELEASE_LOG_DISABLED
WTFLogChannel& SourceBufferPrivateGStreamer::logChannel() const
{
return LogMediaSource;
}
#endif
}
#endif