summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrav90 <travawine@openmailbox.org>2017-10-20 18:20:01 -0500
committertrav90 <travawine@openmailbox.org>2017-10-20 18:52:30 -0500
commit124b2d57db4cb8c3d3941611ae6fa226477b0cdc (patch)
treee4a69ed4c02fed2686080d879baea97e0a07d42e
parentc09757d59d8807fdf5e0b9a6faf8fc592340a772 (diff)
downloadpalemoon-gre-124b2d57db4cb8c3d3941611ae6fa226477b0cdc.tar.gz
Move MediaDecoder::DecodedStreamData and related code to its own file
-rw-r--r--dom/media/DecodedStream.cpp186
-rw-r--r--dom/media/DecodedStream.h96
-rw-r--r--dom/media/MediaDecoder.cpp131
-rw-r--r--dom/media/MediaDecoder.h110
-rw-r--r--dom/media/MediaDecoderStateMachine.cpp1
-rw-r--r--dom/media/MediaDecoderStateMachine.h6
-rw-r--r--dom/media/moz.build2
7 files changed, 289 insertions, 243 deletions
diff --git a/dom/media/DecodedStream.cpp b/dom/media/DecodedStream.cpp
new file mode 100644
index 000000000..f60c61c57
--- /dev/null
+++ b/dom/media/DecodedStream.cpp
@@ -0,0 +1,186 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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 "DecodedStream.h"
+#include "MediaStreamGraph.h"
+#include "MediaDecoder.h"
+
+namespace mozilla {
+
+class DecodedStreamGraphListener : public MediaStreamListener {
+ typedef MediaStreamListener::MediaStreamGraphEvent MediaStreamGraphEvent;
+public:
+ DecodedStreamGraphListener(MediaStream* aStream, DecodedStreamData* aData)
+ : mData(aData)
+ , mMutex("DecodedStreamGraphListener::mMutex")
+ , mStream(aStream)
+ , mLastOutputTime(aStream->StreamTimeToMicroseconds(aStream->GetCurrentTime()))
+ , mStreamFinishedOnMainThread(false) {}
+
+ void NotifyOutput(MediaStreamGraph* aGraph, GraphTime aCurrentTime) override
+ {
+ MutexAutoLock lock(mMutex);
+ if (mStream) {
+ mLastOutputTime = mStream->StreamTimeToMicroseconds(mStream->GraphTimeToStreamTime(aCurrentTime));
+ }
+ }
+
+ void NotifyEvent(MediaStreamGraph* aGraph, MediaStreamGraphEvent event) override
+ {
+ if (event == EVENT_FINISHED) {
+ nsCOMPtr<nsIRunnable> event =
+ NS_NewRunnableMethod(this, &DecodedStreamGraphListener::DoNotifyFinished);
+ aGraph->DispatchToMainThreadAfterStreamStateUpdate(event.forget());
+ }
+ }
+
+ void DoNotifyFinished()
+ {
+ MutexAutoLock lock(mMutex);
+ mStreamFinishedOnMainThread = true;
+ }
+
+ int64_t GetLastOutputTime()
+ {
+ MutexAutoLock lock(mMutex);
+ return mLastOutputTime;
+ }
+
+ void Forget()
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+ mData = nullptr;
+ MutexAutoLock lock(mMutex);
+ mStream = nullptr;
+ }
+
+ bool IsFinishedOnMainThread()
+ {
+ MutexAutoLock lock(mMutex);
+ return mStreamFinishedOnMainThread;
+ }
+
+private:
+ // Main thread only
+ DecodedStreamData* mData;
+
+ Mutex mMutex;
+ // Members below are protected by mMutex.
+ nsRefPtr<MediaStream> mStream;
+ int64_t mLastOutputTime; // microseconds
+ bool mStreamFinishedOnMainThread;
+};
+
+DecodedStreamData::DecodedStreamData(MediaDecoder* aDecoder,
+ int64_t aInitialTime,
+ SourceMediaStream* aStream)
+ : mAudioFramesWritten(0)
+ , mInitialTime(aInitialTime)
+ , mNextVideoTime(-1)
+ , mNextAudioTime(-1)
+ , mDecoder(aDecoder)
+ , mStreamInitialized(false)
+ , mHaveSentFinish(false)
+ , mHaveSentFinishAudio(false)
+ , mHaveSentFinishVideo(false)
+ , mStream(aStream)
+ , mHaveBlockedForPlayState(false)
+ , mHaveBlockedForStateMachineNotPlaying(false)
+{
+ mListener = new DecodedStreamGraphListener(mStream, this);
+ mStream->AddListener(mListener);
+}
+
+DecodedStreamData::~DecodedStreamData()
+{
+ mListener->Forget();
+ mStream->Destroy();
+}
+
+bool
+DecodedStreamData::IsFinished() const
+{
+ return mListener->IsFinishedOnMainThread();
+}
+
+int64_t
+DecodedStreamData::GetClock() const
+{
+ return mInitialTime + mListener->GetLastOutputTime();
+}
+
+class OutputStreamListener : public MediaStreamListener {
+ typedef MediaStreamListener::MediaStreamGraphEvent MediaStreamGraphEvent;
+public:
+ OutputStreamListener(MediaDecoder* aDecoder, MediaStream* aStream)
+ : mDecoder(aDecoder), mStream(aStream) {}
+
+ void NotifyEvent(MediaStreamGraph* aGraph, MediaStreamGraphEvent event) override
+ {
+ if (event == EVENT_FINISHED) {
+ nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(
+ this, &OutputStreamListener::DoNotifyFinished);
+ aGraph->DispatchToMainThreadAfterStreamStateUpdate(r.forget());
+ }
+ }
+
+ void Forget()
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+ mDecoder = nullptr;
+ }
+
+private:
+ void DoNotifyFinished()
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+ if (!mDecoder) {
+ return;
+ }
+
+ // Remove the finished stream so it won't block the decoded stream.
+ ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
+ auto& streams = mDecoder->OutputStreams();
+ // Don't read |mDecoder| in the loop since removing the element will lead
+ // to ~OutputStreamData() which will call Forget() to reset |mDecoder|.
+ for (int32_t i = streams.Length() - 1; i >= 0; --i) {
+ auto& os = streams[i];
+ MediaStream* p = os.mStream.get();
+ if (p == mStream.get()) {
+ if (os.mPort) {
+ os.mPort->Destroy();
+ os.mPort = nullptr;
+ }
+ streams.RemoveElementAt(i);
+ break;
+ }
+ }
+ }
+
+ // Main thread only
+ MediaDecoder* mDecoder;
+ nsRefPtr<MediaStream> mStream;
+};
+
+OutputStreamData::OutputStreamData()
+{
+ //
+}
+
+OutputStreamData::~OutputStreamData()
+{
+ mListener->Forget();
+}
+
+void
+OutputStreamData::Init(MediaDecoder* aDecoder, ProcessedMediaStream* aStream)
+{
+ mStream = aStream;
+ mListener = new OutputStreamListener(aDecoder, aStream);
+ aStream->AddListener(mListener);
+}
+
+} // namespace mozilla
diff --git a/dom/media/DecodedStream.h b/dom/media/DecodedStream.h
new file mode 100644
index 000000000..823419fea
--- /dev/null
+++ b/dom/media/DecodedStream.h
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+#ifndef DecodedStream_h_
+#define DecodedStream_h_
+
+#include "nsRefPtr.h"
+#include "mozilla/gfx/Point.h"
+
+namespace mozilla {
+
+class MediaDecoder;
+class MediaInputPort;
+class SourceMediaStream;
+class ProcessedMediaStream;
+class DecodedStreamGraphListener;
+class OutputStreamData;
+class OutputStreamListener;
+
+namespace layers {
+class Image;
+}
+
+/*
+ * All MediaStream-related data is protected by the decoder's monitor.
+ * We have at most one DecodedStreamDaata per MediaDecoder. Its stream
+ * is used as the input for each ProcessedMediaStream created by calls to
+ * captureStream(UntilEnded). Seeking creates a new source stream, as does
+ * replaying after the input as ended. In the latter case, the new source is
+ * not connected to streams created by captureStreamUntilEnded.
+ */
+class DecodedStreamData {
+public:
+ DecodedStreamData(MediaDecoder* aDecoder, int64_t aInitialTime,
+ SourceMediaStream* aStream);
+ ~DecodedStreamData();
+ bool IsFinished() const;
+ int64_t GetClock() const;
+
+ /* The following group of fields are protected by the decoder's monitor
+ * and can be read or written on any thread.
+ */
+ // Count of audio frames written to the stream
+ int64_t mAudioFramesWritten;
+ // Saved value of aInitialTime. Timestamp of the first audio and/or
+ // video packet written.
+ const int64_t mInitialTime; // microseconds
+ // mNextVideoTime is the end timestamp for the last packet sent to the stream.
+ // Therefore video packets starting at or after this time need to be copied
+ // to the output stream.
+ int64_t mNextVideoTime; // microseconds
+ int64_t mNextAudioTime; // microseconds
+ MediaDecoder* mDecoder;
+ // The last video image sent to the stream. Useful if we need to replicate
+ // the image.
+ nsRefPtr<layers::Image> mLastVideoImage;
+ gfx::IntSize mLastVideoImageDisplaySize;
+ // This is set to true when the stream is initialized (audio and
+ // video tracks added).
+ bool mStreamInitialized;
+ bool mHaveSentFinish;
+ bool mHaveSentFinishAudio;
+ bool mHaveSentFinishVideo;
+
+ // The decoder is responsible for calling Destroy() on this stream.
+ const nsRefPtr<SourceMediaStream> mStream;
+ nsRefPtr<DecodedStreamGraphListener> mListener;
+ // True when we've explicitly blocked this stream because we're
+ // not in PLAY_STATE_PLAYING. Used on the main thread only.
+ bool mHaveBlockedForPlayState;
+ // We also have an explicit blocker on the stream when
+ // mDecoderStateMachine is non-null and MediaDecoderStateMachine is false.
+ bool mHaveBlockedForStateMachineNotPlaying;
+};
+
+class OutputStreamData {
+public:
+ // Compiler-generated default constructor needs the complete definition
+ // of OutputStreamListener when constructing OutputStreamData. Provide our
+ // own default constructor for forward declaration of OutputStreamListener
+ // to work.
+ OutputStreamData();
+ ~OutputStreamData();
+ void Init(MediaDecoder* aDecoder, ProcessedMediaStream* aStream);
+ nsRefPtr<ProcessedMediaStream> mStream;
+ // mPort connects DecodedStreamData::mStream to our mStream.
+ nsRefPtr<MediaInputPort> mPort;
+ nsRefPtr<OutputStreamListener> mListener;
+};
+
+} // namespace mozilla
+
+#endif // DecodedStream_h_
diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp
index da170820d..d09095ac9 100644
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -313,137 +313,6 @@ void MediaDecoder::ConnectDecodedStreamToOutputStream(OutputStreamData* aStream)
aStream->mStream->ChangeExplicitBlockerCount(-1);
}
-MediaDecoder::DecodedStreamData::DecodedStreamData(MediaDecoder* aDecoder,
- int64_t aInitialTime,
- SourceMediaStream* aStream)
- : mAudioFramesWritten(0),
- mInitialTime(aInitialTime),
- mNextVideoTime(-1),
- mNextAudioTime(-1),
- mDecoder(aDecoder),
- mStreamInitialized(false),
- mHaveSentFinish(false),
- mHaveSentFinishAudio(false),
- mHaveSentFinishVideo(false),
- mStream(aStream),
- mHaveBlockedForPlayState(false),
- mHaveBlockedForStateMachineNotPlaying(false)
-{
- mListener = new DecodedStreamGraphListener(mStream, this);
- mStream->AddListener(mListener);
-}
-
-MediaDecoder::DecodedStreamData::~DecodedStreamData()
-{
- mListener->Forget();
- mStream->Destroy();
-}
-
-MediaDecoder::DecodedStreamGraphListener::DecodedStreamGraphListener(MediaStream* aStream,
- DecodedStreamData* aData)
- : mData(aData),
- mMutex("MediaDecoder::DecodedStreamData::mMutex"),
- mStream(aStream),
- mLastOutputTime(aStream->
- StreamTimeToMicroseconds(aStream->GetCurrentTime())),
- mStreamFinishedOnMainThread(false)
-{
-}
-
-void
-MediaDecoder::DecodedStreamGraphListener::NotifyOutput(MediaStreamGraph* aGraph,
- GraphTime aCurrentTime)
-{
- MutexAutoLock lock(mMutex);
- if (mStream) {
- mLastOutputTime = mStream->
- StreamTimeToMicroseconds(mStream->GraphTimeToStreamTime(aCurrentTime));
- }
-}
-
-void
-MediaDecoder::DecodedStreamGraphListener::DoNotifyFinished()
-{
- MutexAutoLock lock(mMutex);
- mStreamFinishedOnMainThread = true;
-}
-
-void
-MediaDecoder::DecodedStreamGraphListener::NotifyEvent(MediaStreamGraph* aGraph,
- MediaStreamListener::MediaStreamGraphEvent event)
-{
- if (event == EVENT_FINISHED) {
- nsCOMPtr<nsIRunnable> event =
- NS_NewRunnableMethod(this, &DecodedStreamGraphListener::DoNotifyFinished);
- aGraph->DispatchToMainThreadAfterStreamStateUpdate(event.forget());
- }
-}
-
-class MediaDecoder::OutputStreamListener : public MediaStreamListener {
-public:
- OutputStreamListener(MediaDecoder* aDecoder, MediaStream* aStream)
- : mDecoder(aDecoder), mStream(aStream) {}
-
- virtual void NotifyEvent(
- MediaStreamGraph* aGraph,
- MediaStreamListener::MediaStreamGraphEvent event) override {
- if (event == EVENT_FINISHED) {
- nsRefPtr<nsIRunnable> r = NS_NewRunnableMethod(
- this, &OutputStreamListener::DoNotifyFinished);
- aGraph->DispatchToMainThreadAfterStreamStateUpdate(r.forget());
- }
- }
-
- void Forget() {
- MOZ_ASSERT(NS_IsMainThread());
- mDecoder = nullptr;
- }
-
-private:
- void DoNotifyFinished() {
- MOZ_ASSERT(NS_IsMainThread());
- if (!mDecoder) {
- return;
- }
-
- // Remove the finished stream so it won't block the decoded stream.
- ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
- auto& streams = mDecoder->OutputStreams();
- // Don't read |mDecoder| in the loop since removing the element will lead
- // to ~OutputStreamData() which will call Forget() to reset |mDecoder|.
- for (int32_t i = streams.Length() - 1; i >= 0; --i) {
- auto& os = streams[i];
- MediaStream* p = os.mStream.get();
- if (p == mStream.get()) {
- if (os.mPort) {
- os.mPort->Destroy();
- os.mPort = nullptr;
- }
- streams.RemoveElementAt(i);
- break;
- }
- }
- }
-
- // Main thread only
- MediaDecoder* mDecoder;
- nsRefPtr<MediaStream> mStream;
-};
-
-void
-MediaDecoder::OutputStreamData::Init(MediaDecoder* aDecoder,
- ProcessedMediaStream* aStream)
-{
- mStream = aStream;
- mListener = new OutputStreamListener(aDecoder, aStream);
- aStream->AddListener(mListener);
-}
-
-MediaDecoder::OutputStreamData::~OutputStreamData()
-{
- mListener->Forget();
-}
-
void MediaDecoder::UpdateDecodedStream()
{
MOZ_ASSERT(NS_IsMainThread());
diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h
index 9d82f99de..34008ed82 100644
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -192,11 +192,11 @@ destroying the MediaDecoder object.
#include "MediaPromise.h"
#include "MediaResource.h"
#include "mozilla/dom/AudioChannelBinding.h"
-#include "mozilla/gfx/Rect.h"
#include "mozilla/ReentrantMonitor.h"
#include "MediaDecoderOwner.h"
#include "MediaStreamGraph.h"
#include "AbstractMediaDecoder.h"
+#include "DecodedStream.h"
#include "StateMirroring.h"
#include "StateWatching.h"
#include "necko-config.h"
@@ -206,9 +206,6 @@ class nsIStreamListener;
class nsIPrincipal;
namespace mozilla {
-namespace layers {
-class Image;
-} //namespace layers
class VideoFrameContainer;
class MediaDecoderStateMachine;
@@ -275,7 +272,6 @@ public:
};
typedef MediaPromise<SeekResolveValue, bool /* aIgnored */, /* IsExclusive = */ true> SeekPromise;
- class DecodedStreamGraphListener;
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIOBSERVER
@@ -395,110 +391,6 @@ public:
// replaying after the input as ended. In the latter case, the new source is
// not connected to streams created by captureStreamUntilEnded.
- struct DecodedStreamData {
- typedef gfx::IntSize IntSize;
-
- DecodedStreamData(MediaDecoder* aDecoder,
- int64_t aInitialTime, SourceMediaStream* aStream);
- ~DecodedStreamData();
-
- // microseconds
- bool IsFinished() const {
- return mListener->IsFinishedOnMainThread();
- }
-
- int64_t GetClock() const {
- return mInitialTime + mListener->GetLastOutputTime();
- }
-
- // The following group of fields are protected by the decoder's monitor
- // and can be read or written on any thread.
- // Count of audio frames written to the stream
- int64_t mAudioFramesWritten;
- // Saved value of aInitialTime. Timestamp of the first audio and/or
- // video packet written.
- const int64_t mInitialTime; // microseconds
- // mNextVideoTime is the end timestamp for the last packet sent to the stream.
- // Therefore video packets starting at or after this time need to be copied
- // to the output stream.
- int64_t mNextVideoTime; // microseconds
- int64_t mNextAudioTime; // microseconds
- MediaDecoder* mDecoder;
- // The last video image sent to the stream. Useful if we need to replicate
- // the image.
- nsRefPtr<layers::Image> mLastVideoImage;
- IntSize mLastVideoImageDisplaySize;
- // This is set to true when the stream is initialized (audio and
- // video tracks added).
- bool mStreamInitialized;
- bool mHaveSentFinish;
- bool mHaveSentFinishAudio;
- bool mHaveSentFinishVideo;
-
- // The decoder is responsible for calling Destroy() on this stream.
- // Can be read from any thread.
- const nsRefPtr<SourceMediaStream> mStream;
- // Can be read from any thread.
- nsRefPtr<DecodedStreamGraphListener> mListener;
- // True when we've explicitly blocked this stream because we're
- // not in PLAY_STATE_PLAYING. Used on the main thread only.
- bool mHaveBlockedForPlayState;
- // We also have an explicit blocker on the stream when
- // mDecoderStateMachine is non-null and MediaDecoderStateMachine is false.
- bool mHaveBlockedForStateMachineNotPlaying;
- };
-
- class DecodedStreamGraphListener : public MediaStreamListener {
- public:
- DecodedStreamGraphListener(MediaStream* aStream, DecodedStreamData* aData);
- virtual void NotifyOutput(MediaStreamGraph* aGraph, GraphTime aCurrentTime) override;
- virtual void NotifyEvent(MediaStreamGraph* aGraph,
- MediaStreamListener::MediaStreamGraphEvent event) override;
-
- void DoNotifyFinished();
-
- int64_t GetLastOutputTime() // microseconds
- {
- MutexAutoLock lock(mMutex);
- return mLastOutputTime;
- }
- void Forget()
- {
- NS_ASSERTION(NS_IsMainThread(), "Main thread only");
- mData = nullptr;
-
- MutexAutoLock lock(mMutex);
- mStream = nullptr;
- }
- bool IsFinishedOnMainThread()
- {
- MutexAutoLock lock(mMutex);
- return mStreamFinishedOnMainThread;
- }
- private:
- // Main thread only
- DecodedStreamData* mData;
-
- Mutex mMutex;
- // Protected by mMutex
- nsRefPtr<MediaStream> mStream;
- // Protected by mMutex
- int64_t mLastOutputTime; // microseconds
- // Protected by mMutex
- bool mStreamFinishedOnMainThread;
- };
-
- class OutputStreamListener;
-
- struct OutputStreamData {
- void Init(MediaDecoder* aDecoder, ProcessedMediaStream* aStream);
- ~OutputStreamData();
- nsRefPtr<ProcessedMediaStream> mStream;
- // mPort connects mDecodedStream->mStream to our mStream.
- nsRefPtr<MediaInputPort> mPort;
- nsRefPtr<OutputStreamListener> mListener;
- };
-
/**
* Connects mDecodedStream->mStream to aStream->mStream.
*/
diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp
index 274a42b4e..fcda25116 100644
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -38,6 +38,7 @@
#include "gfx2DGlue.h"
#include "nsPrintfCString.h"
#include "DOMMediaStream.h"
+#include "DecodedStream.h"
#include <algorithm>
diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h
index d6abb13e4..89ee36c01 100644
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -102,6 +102,7 @@ class VideoSegment;
class MediaTaskQueue;
class SharedThreadPool;
class AudioSink;
+class DecodedStreamData;
class MediaDecoderStateMachineScheduler;
/*
@@ -122,10 +123,9 @@ class MediaDecoderStateMachine
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderStateMachine)
public:
typedef MediaDecoderOwner::NextFrameStatus NextFrameStatus;
- typedef MediaDecoder::DecodedStreamData DecodedStreamData;
MediaDecoderStateMachine(MediaDecoder* aDecoder,
- MediaDecoderReader* aReader,
- bool aRealTime = false);
+ MediaDecoderReader* aReader,
+ bool aRealTime = false);
nsresult Init(MediaDecoderStateMachine* aCloneDonor);
diff --git a/dom/media/moz.build b/dom/media/moz.build
index d7f8e0909..776cd600c 100644
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -87,6 +87,7 @@ EXPORTS += [
'AudioStream.h',
'BufferMediaResource.h',
'CubebUtils.h',
+ 'DecodedStream.h',
'DecoderTraits.h',
'DOMMediaStream.h',
'EncodedBufferCache.h',
@@ -175,6 +176,7 @@ UNIFIED_SOURCES += [
'AudioTrack.cpp',
'AudioTrackList.cpp',
'CubebUtils.cpp',
+ 'DecodedStream.cpp',
'DOMMediaStream.cpp',
'EncodedBufferCache.cpp',
'FileBlockCache.cpp',