mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-23 18:26:15 +00:00
Bug 1199155. Part 1 - move dom/media/DecodedStream.* to dom/media/mediasink/ and implement the interface of MediaSink. r=roc.
--HG-- rename : dom/media/DecodedStream.cpp => dom/media/mediasink/DecodedStream.cpp rename : dom/media/DecodedStream.h => dom/media/mediasink/DecodedStream.h
This commit is contained in:
parent
de80bc12fe
commit
e5956970d2
@ -4,6 +4,9 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/gfx/Point.h"
|
||||
|
||||
#include "AudioSegment.h"
|
||||
#include "DecodedStream.h"
|
||||
#include "MediaData.h"
|
||||
@ -358,7 +361,6 @@ DecodedStream::DecodedStream(AbstractThread* aOwnerThread,
|
||||
: mOwnerThread(aOwnerThread)
|
||||
, mShuttingDown(false)
|
||||
, mPlaying(false)
|
||||
, mVolume(1.0)
|
||||
, mSameOrigin(false)
|
||||
, mAudioQueue(aAudioQueue)
|
||||
, mVideoQueue(aVideoQueue)
|
||||
@ -370,21 +372,52 @@ DecodedStream::~DecodedStream()
|
||||
MOZ_ASSERT(mStartTime.isNothing(), "playback should've ended.");
|
||||
}
|
||||
|
||||
const media::MediaSink::PlaybackParams&
|
||||
DecodedStream::GetPlaybackParams() const
|
||||
{
|
||||
AssertOwnerThread();
|
||||
return mParams;
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::Shutdown()
|
||||
DecodedStream::SetPlaybackParams(const PlaybackParams& aParams)
|
||||
{
|
||||
AssertOwnerThread();
|
||||
mParams = aParams;
|
||||
}
|
||||
|
||||
nsRefPtr<GenericPromise>
|
||||
DecodedStream::OnEnded(TrackType aType)
|
||||
{
|
||||
AssertOwnerThread();
|
||||
MOZ_ASSERT(mStartTime.isSome());
|
||||
|
||||
if (aType == TrackInfo::kAudioTrack) {
|
||||
// TODO: we should return a promise which is resolved when the audio track
|
||||
// is finished. For now this promise is resolved when the whole stream is
|
||||
// finished.
|
||||
return mFinishPromise;
|
||||
}
|
||||
// TODO: handle video track.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::BeginShutdown()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mShuttingDown = true;
|
||||
}
|
||||
|
||||
nsRefPtr<GenericPromise>
|
||||
DecodedStream::StartPlayback(int64_t aStartTime, const MediaInfo& aInfo)
|
||||
void
|
||||
DecodedStream::Start(int64_t aStartTime, const MediaInfo& aInfo)
|
||||
{
|
||||
AssertOwnerThread();
|
||||
MOZ_ASSERT(mStartTime.isNothing(), "playback already started.");
|
||||
|
||||
mStartTime.emplace(aStartTime);
|
||||
mInfo = aInfo;
|
||||
mPlaying = true;
|
||||
ConnectListener();
|
||||
|
||||
class R : public nsRunnable {
|
||||
@ -408,30 +441,33 @@ DecodedStream::StartPlayback(int64_t aStartTime, const MediaInfo& aInfo)
|
||||
};
|
||||
|
||||
MozPromiseHolder<GenericPromise> promise;
|
||||
nsRefPtr<GenericPromise> rv = promise.Ensure(__func__);
|
||||
mFinishPromise = promise.Ensure(__func__);
|
||||
nsCOMPtr<nsIRunnable> r = new R(this, &DecodedStream::CreateData, Move(promise));
|
||||
AbstractThread::MainThread()->Dispatch(r.forget());
|
||||
|
||||
return rv.forget();
|
||||
}
|
||||
|
||||
void DecodedStream::StopPlayback()
|
||||
void
|
||||
DecodedStream::Stop()
|
||||
{
|
||||
AssertOwnerThread();
|
||||
|
||||
// Playback didn't even start at all.
|
||||
if (mStartTime.isNothing()) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(mStartTime.isSome(), "playback not started.");
|
||||
|
||||
mStartTime.reset();
|
||||
DisconnectListener();
|
||||
mFinishPromise = nullptr;
|
||||
|
||||
// Clear mData immediately when this playback session ends so we won't
|
||||
// send data to the wrong stream in SendData() in next playback session.
|
||||
DestroyData(Move(mData));
|
||||
}
|
||||
|
||||
bool
|
||||
DecodedStream::IsStarted() const
|
||||
{
|
||||
AssertOwnerThread();
|
||||
return mStartTime.isSome();
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::DestroyData(UniquePtr<DecodedStreamData> aData)
|
||||
{
|
||||
@ -531,6 +567,12 @@ void
|
||||
DecodedStream::SetPlaying(bool aPlaying)
|
||||
{
|
||||
AssertOwnerThread();
|
||||
|
||||
// Resume/pause matters only when playback started.
|
||||
if (mStartTime.isNothing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mPlaying = aPlaying;
|
||||
if (mData) {
|
||||
mData->SetPlaying(aPlaying);
|
||||
@ -541,7 +583,21 @@ void
|
||||
DecodedStream::SetVolume(double aVolume)
|
||||
{
|
||||
AssertOwnerThread();
|
||||
mVolume = aVolume;
|
||||
mParams.volume = aVolume;
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::SetPlaybackRate(double aPlaybackRate)
|
||||
{
|
||||
AssertOwnerThread();
|
||||
mParams.playbackRate = aPlaybackRate;
|
||||
}
|
||||
|
||||
void
|
||||
DecodedStream::SetPreservesPitch(bool aPreservesPitch)
|
||||
{
|
||||
AssertOwnerThread();
|
||||
mParams.preservesPitch = aPreservesPitch;
|
||||
}
|
||||
|
||||
void
|
||||
@ -815,7 +871,7 @@ DecodedStream::SendData()
|
||||
}
|
||||
|
||||
InitTracks();
|
||||
SendAudio(mVolume, mSameOrigin);
|
||||
SendAudio(mParams.volume, mSameOrigin);
|
||||
SendVideo(mSameOrigin);
|
||||
AdvanceTracks();
|
||||
|
||||
@ -829,26 +885,31 @@ DecodedStream::SendData()
|
||||
}
|
||||
|
||||
int64_t
|
||||
DecodedStream::AudioEndTime() const
|
||||
DecodedStream::GetEndTime(TrackType aType) const
|
||||
{
|
||||
AssertOwnerThread();
|
||||
if (mStartTime.isSome() && mInfo.HasAudio() && mData) {
|
||||
if (aType == TrackInfo::kAudioTrack && mInfo.HasAudio() && mData) {
|
||||
CheckedInt64 t = mStartTime.ref() +
|
||||
FramesToUsecs(mData->mAudioFramesWritten, mInfo.mAudio.mRate);
|
||||
if (t.isValid()) {
|
||||
return t.value();
|
||||
}
|
||||
} else if (aType == TrackInfo::kVideoTrack && mData) {
|
||||
return mData->mNextVideoTime;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t
|
||||
DecodedStream::GetPosition() const
|
||||
DecodedStream::GetPosition(TimeStamp* aTimeStamp) const
|
||||
{
|
||||
AssertOwnerThread();
|
||||
// This is only called after MDSM starts playback. So mStartTime is
|
||||
// guaranteed to be something.
|
||||
MOZ_ASSERT(mStartTime.isSome());
|
||||
if (aTimeStamp) {
|
||||
*aTimeStamp = TimeStamp::Now();
|
||||
}
|
||||
return mStartTime.ref() + (mData ? mData->GetPosition() : 0);
|
||||
}
|
||||
|
@ -10,15 +10,13 @@
|
||||
#include "nsTArray.h"
|
||||
#include "MediaEventSource.h"
|
||||
#include "MediaInfo.h"
|
||||
#include "MediaSink.h"
|
||||
|
||||
#include "mozilla/AbstractThread.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/nsRefPtr.h"
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/gfx/Point.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -31,7 +29,7 @@ class MediaStreamGraph;
|
||||
class OutputStreamListener;
|
||||
class OutputStreamManager;
|
||||
class ProcessedMediaStream;
|
||||
class ReentrantMonitor;
|
||||
class TimeStamp;
|
||||
|
||||
template <class T> class MediaQueue;
|
||||
|
||||
@ -99,34 +97,41 @@ private:
|
||||
nsTArray<OutputStreamData> mStreams;
|
||||
};
|
||||
|
||||
class DecodedStream {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DecodedStream);
|
||||
class DecodedStream : public media::MediaSink {
|
||||
using media::MediaSink::PlaybackParams;
|
||||
|
||||
public:
|
||||
DecodedStream(AbstractThread* aOwnerThread,
|
||||
MediaQueue<MediaData>& aAudioQueue,
|
||||
MediaQueue<MediaData>& aVideoQueue);
|
||||
|
||||
void Shutdown();
|
||||
// MediaSink functions.
|
||||
const PlaybackParams& GetPlaybackParams() const override;
|
||||
void SetPlaybackParams(const PlaybackParams& aParams) override;
|
||||
|
||||
// Mimic MDSM::StartAudioThread.
|
||||
// Must be called before any calls to SendData().
|
||||
//
|
||||
// Return a promise which will be resolved when the stream is finished
|
||||
// or rejected if any error.
|
||||
nsRefPtr<GenericPromise> StartPlayback(int64_t aStartTime,
|
||||
const MediaInfo& aInfo);
|
||||
// Mimic MDSM::StopAudioThread.
|
||||
void StopPlayback();
|
||||
nsRefPtr<GenericPromise> OnEnded(TrackType aType) override;
|
||||
int64_t GetEndTime(TrackType aType) const override;
|
||||
int64_t GetPosition(TimeStamp* aTimeStamp = nullptr) const override;
|
||||
bool HasUnplayedFrames(TrackType aType) const override
|
||||
{
|
||||
// TODO: implement this.
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetVolume(double aVolume) override;
|
||||
void SetPlaybackRate(double aPlaybackRate) override;
|
||||
void SetPreservesPitch(bool aPreservesPitch) override;
|
||||
void SetPlaying(bool aPlaying) override;
|
||||
|
||||
void Start(int64_t aStartTime, const MediaInfo& aInfo) override;
|
||||
void Stop() override;
|
||||
bool IsStarted() const override;
|
||||
|
||||
// TODO: fix these functions that don't fit into the interface of MediaSink.
|
||||
void BeginShutdown();
|
||||
void AddOutput(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
|
||||
void RemoveOutput(MediaStream* aStream);
|
||||
|
||||
void SetPlaying(bool aPlaying);
|
||||
void SetVolume(double aVolume);
|
||||
void SetSameOrigin(bool aSameOrigin);
|
||||
|
||||
int64_t AudioEndTime() const;
|
||||
int64_t GetPosition() const;
|
||||
bool IsFinished() const;
|
||||
bool HasConsumers() const;
|
||||
|
||||
@ -164,10 +169,11 @@ private:
|
||||
* Worker thread only members.
|
||||
*/
|
||||
UniquePtr<DecodedStreamData> mData;
|
||||
nsRefPtr<GenericPromise> mFinishPromise;
|
||||
|
||||
bool mPlaying;
|
||||
double mVolume;
|
||||
bool mSameOrigin;
|
||||
PlaybackParams mParams;
|
||||
|
||||
Maybe<int64_t> mStartTime;
|
||||
MediaInfo mInfo;
|
Loading…
Reference in New Issue
Block a user