Bug 1219142. Part 1 - add AbstractMediaDecoder::DataArrivedEvent() to publish events. r=jya.
--- a/dom/media/AbstractMediaDecoder.h
+++ b/dom/media/AbstractMediaDecoder.h
@@ -5,16 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef AbstractMediaDecoder_h_
#define AbstractMediaDecoder_h_
#include "mozilla/Attributes.h"
#include "mozilla/StateMirroring.h"
+#include "MediaEventSource.h"
#include "MediaInfo.h"
#include "nsISupports.h"
#include "nsDataHashtable.h"
#include "nsThreadUtils.h"
namespace mozilla
{
@@ -63,16 +64,25 @@ public:
// Increments the parsed, decoded and dropped frame counters by the passed in
// counts.
// Can be called on any thread.
virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded,
uint32_t aDropped) = 0;
virtual AbstractCanonical<media::NullableTimeUnit>* CanonicalDurationOrNull() { return nullptr; };
+ // Return an event that will be notified when data arrives in MediaResource.
+ // MediaDecoderReader will register with this event to receive notifications
+ // in order to udpate buffer ranges.
+ // Return null if this decoder doesn't support the event.
+ virtual MediaEventSource<void>* DataArrivedEvent()
+ {
+ return nullptr;
+ }
+
protected:
virtual void UpdateEstimatedMediaDuration(int64_t aDuration) {};
public:
void DispatchUpdateEstimatedMediaDuration(int64_t aDuration)
{
nsCOMPtr<nsIRunnable> r =
NS_NewRunnableMethodWithArg<int64_t>(this, &AbstractMediaDecoder::UpdateEstimatedMediaDuration,
aDuration);
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -1442,20 +1442,23 @@ void MediaDecoder::AddSizeOfResources(Re
aSizes->mByteSize += GetResource()->SizeOfIncludingThis(aSizes->mMallocSizeOf);
}
}
void
MediaDecoder::NotifyDataArrived() {
MOZ_ASSERT(NS_IsMainThread());
- if (mDecoderStateMachine) {
- mDecoderStateMachine->DispatchNotifyDataArrived();
+ // Don't publish events since task queues might be shutting down.
+ if (mShuttingDown) {
+ return;
}
+ mDataArrivedEvent.Notify();
+
// ReadyState computation depends on MediaDecoder::CanPlayThrough, which
// depends on the download rate.
UpdateReadyState();
}
// Provide access to the state machine object
MediaDecoderStateMachine*
MediaDecoder::GetStateMachine() const {
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -815,16 +815,21 @@ protected:
/******
* The following member variables can be accessed from any thread.
******/
// Media data resource.
RefPtr<MediaResource> mResource;
private:
+ MediaEventSource<void>*
+ DataArrivedEvent() override { return &mDataArrivedEvent; }
+
+ MediaEventProducer<void> mDataArrivedEvent;
+
// The state machine object for handling the decoding. It is safe to
// call methods of this object from other threads. Its internal data
// is synchronised on a monitor. The lifetime of this object is
// after mPlayState is LOADING and before mPlayState is SHUTDOWN. It
// is safe to access it during this period.
//
// Explicitly prievate to force access via accessors.
RefPtr<MediaDecoderStateMachine> mDecoderStateMachine;
--- a/dom/media/MediaDecoderReader.cpp
+++ b/dom/media/MediaDecoderReader.cpp
@@ -74,16 +74,21 @@ MediaDecoderReader::MediaDecoderReader(A
, mHitAudioDecodeError(false)
, mShutdown(false)
, mAudioDiscontinuity(false)
, mVideoDiscontinuity(false)
{
MOZ_COUNT_CTOR(MediaDecoderReader);
MOZ_ASSERT(NS_IsMainThread());
+ if (mDecoder && mDecoder->DataArrivedEvent()) {
+ mDataArrivedListener = mDecoder->DataArrivedEvent()->Connect(
+ mTaskQueue, this, &MediaDecoderReader::NotifyDataArrived);
+ }
+
// Dispatch initialization that needs to happen on that task queue.
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(this, &MediaDecoderReader::InitializationTask);
mTaskQueue->Dispatch(r.forget());
}
void
MediaDecoderReader::InitializationTask()
{
@@ -355,16 +360,18 @@ RefPtr<ShutdownPromise>
MediaDecoderReader::Shutdown()
{
MOZ_ASSERT(OnTaskQueue());
mShutdown = true;
mBaseAudioPromise.RejectIfExists(END_OF_STREAM, __func__);
mBaseVideoPromise.RejectIfExists(END_OF_STREAM, __func__);
+ mDataArrivedListener.DisconnectIfExists();
+
ReleaseMediaResources();
mDuration.DisconnectIfConnected();
mBuffered.DisconnectAll();
// Shut down the watch manager before shutting down our task queue.
mWatchManager.Shutdown();
RefPtr<ShutdownPromise> p;
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -423,13 +423,15 @@ private:
// of Request{Audio,Video}Data.
MozPromiseHolder<AudioDataPromise> mBaseAudioPromise;
MozPromiseHolder<VideoDataPromise> mBaseVideoPromise;
// Flags whether a the next audio/video sample comes after a "gap" or
// "discontinuity" in the stream. For example after a seek.
bool mAudioDiscontinuity;
bool mVideoDiscontinuity;
+
+ MediaEventListener mDataArrivedListener;
};
} // namespace mozilla
#endif