Bug 1388604 - move SetReadMode() from MediaResource to BaseMediaResource.
It would be less accurate to call SetReadMode(MediaCacheStream::MODE_PLAYBACK)
in ChannelMediaDecoder::MetadataLoaded() instead of DecodeMetadataState::OnMetadataRead()
because MDSM might have started decoding by the time 'metadata loaded' event arrives
in the main thread. However this little inaccuracy should be fine since it only
affects a small amount of data concerning the eviction algorithm.
MozReview-Commit-ID: JoQMGr5Fvge
--- a/dom/media/BufferMediaResource.h
+++ b/dom/media/BufferMediaResource.h
@@ -38,18 +38,16 @@ protected:
private:
// Get the current principal for the channel
already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override
{
nsCOMPtr<nsIPrincipal> principal = mPrincipal;
return principal.forget();
}
// These methods are called off the main thread.
- // The mode is initially MODE_PLAYBACK.
- void SetReadMode(MediaCacheStream::ReadMode aMode) override {}
nsresult ReadAt(int64_t aOffset, char* aBuffer,
uint32_t aCount, uint32_t* aBytes) override
{
if (aOffset < 0 || aOffset > mLength) {
return NS_ERROR_FAILURE;
}
*aBytes = std::min(mLength - static_cast<uint32_t>(aOffset), aCount);
memcpy(aBuffer, mBuffer + aOffset, *aBytes);
--- a/dom/media/ChannelMediaDecoder.cpp
+++ b/dom/media/ChannelMediaDecoder.cpp
@@ -249,16 +249,19 @@ ChannelMediaDecoder::Load(nsIChannel* aC
nsresult rv = MediaShutdownManager::Instance().Register(this);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = OpenResource(aStreamListener);
NS_ENSURE_SUCCESS(rv, rv);
+ // Set mode to METADATA since we are about to read metadata.
+ mResource->SetReadMode(MediaCacheStream::MODE_METADATA);
+
SetStateMachine(CreateStateMachine());
NS_ENSURE_TRUE(GetStateMachine(), NS_ERROR_FAILURE);
return InitializeStateMachine();
}
nsresult
ChannelMediaDecoder::Load(BaseMediaResource* aOriginal)
@@ -496,12 +499,23 @@ void
ChannelMediaDecoder::Resume()
{
MOZ_ASSERT(NS_IsMainThread());
if (mResource) {
mResource->Resume();
}
}
+void
+ChannelMediaDecoder::MetadataLoaded(
+ UniquePtr<MediaInfo> aInfo,
+ UniquePtr<MetadataTags> aTags,
+ MediaDecoderEventVisibility aEventVisibility)
+{
+ MediaDecoder::MetadataLoaded(Move(aInfo), Move(aTags), aEventVisibility);
+ // Set mode to PLAYBACK after reading metadata.
+ mResource->SetReadMode(MediaCacheStream::MODE_PLAYBACK);
+}
+
} // namespace mozilla
// avoid redefined macro in unified build
#undef LOG
--- a/dom/media/ChannelMediaDecoder.h
+++ b/dom/media/ChannelMediaDecoder.h
@@ -52,16 +52,20 @@ class ChannelMediaDecoder : public Media
bool mTimerArmed = false;
const RefPtr<AbstractThread> mAbstractMainThread;
};
protected:
void OnPlaybackEvent(MediaEventType aEvent) override;
void DurationChanged() override;
void DownloadProgressed() override;
+ void MetadataLoaded(UniquePtr<MediaInfo> aInfo,
+ UniquePtr<MetadataTags> aTags,
+ MediaDecoderEventVisibility aEventVisibility) override;
+
RefPtr<ResourceCallback> mResourceCallback;
RefPtr<BaseMediaResource> mResource;
public:
explicit ChannelMediaDecoder(MediaDecoderInit& aInit);
MediaDecoderStateMachine* CreateStateMachine() override;
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -451,16 +451,22 @@ protected:
// We Invoke DurationChanged explicitly, rather than using a watcher, so
// that it takes effect immediately, rather than at the end of the current task.
DurationChanged();
}
virtual void OnPlaybackEvent(MediaEventType aEvent);
+ // Called when the metadata from the media file has been loaded by the
+ // state machine. Call on the main thread only.
+ virtual void MetadataLoaded(UniquePtr<MediaInfo> aInfo,
+ UniquePtr<MetadataTags> aTags,
+ MediaDecoderEventVisibility aEventVisibility);
+
/******
* The following members should be accessed with the decoder lock held.
******/
// The logical playback position of the media resource in units of
// seconds. This corresponds to the "official position" in HTML5. Note that
// we need to store this as a double, rather than an int64_t (like
// mCurrentPosition), so that |v.currentTime = foo; v.currentTime == foo|
@@ -491,22 +497,16 @@ protected:
// the next frame is available.
// An arbitrary value of 250ms is used.
static constexpr auto DEFAULT_NEXT_FRAME_AVAILABLE_BUFFERED =
media::TimeUnit::FromMicroseconds(250000);
private:
nsCString GetDebugInfo();
- // Called when the metadata from the media file has been loaded by the
- // state machine. Call on the main thread only.
- void MetadataLoaded(UniquePtr<MediaInfo> aInfo,
- UniquePtr<MetadataTags> aTags,
- MediaDecoderEventVisibility aEventVisibility);
-
// Called when the owner's activity changed.
void NotifyCompositor();
void OnPlaybackErrorEvent(const MediaResult& aError);
void OnDecoderDoctorEvent(DecoderDoctorEvent aEvent);
void OnMediaNotSeekable()
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -336,19 +336,16 @@ public:
explicit DecodeMetadataState(Master* aPtr) : StateObject(aPtr) { }
void Enter()
{
MOZ_ASSERT(!mMaster->mVideoDecodeSuspended);
MOZ_ASSERT(!mMetadataRequest.Exists());
SLOG("Dispatching AsyncReadMetadata");
- // Set mode to METADATA since we are about to read metadata.
- Resource()->SetReadMode(MediaCacheStream::MODE_METADATA);
-
// We disconnect mMetadataRequest in Exit() so it is fine to capture
// a raw pointer here.
Reader()->ReadMetadata()
->Then(OwnerThread(), __func__,
[this] (MetadataHolder&& aMetadata) {
OnMetadataRead(Move(aMetadata));
},
[this] (const MediaResult& aError) {
@@ -2219,19 +2216,16 @@ StateObject::SetSeekingState(SeekJob&& a
}
void
MediaDecoderStateMachine::
DecodeMetadataState::OnMetadataRead(MetadataHolder&& aMetadata)
{
mMetadataRequest.Complete();
- // Set mode to PLAYBACK after reading metadata.
- Resource()->SetReadMode(MediaCacheStream::MODE_PLAYBACK);
-
mMaster->mInfo.emplace(*aMetadata.mInfo);
mMaster->mMediaSeekable = Info().mMediaSeekable;
mMaster->mMediaSeekableOnlyInBufferedRanges =
Info().mMediaSeekableOnlyInBufferedRanges;
if (Info().mMetadataDuration.isSome()) {
mMaster->mDuration = Info().mMetadataDuration;
} else if (Info().mUnadjustedMetadataEndTime.isSome()) {
--- a/dom/media/MediaResource.h
+++ b/dom/media/MediaResource.h
@@ -159,18 +159,16 @@ public:
// released on a non main thread, but the destructor will always run on
// the main thread.
NS_DECL_THREADSAFE_ISUPPORTS
// Get the current principal for the channel
virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() = 0;
// These methods are called off the main thread.
- // The mode is initially MODE_PLAYBACK.
- virtual void SetReadMode(MediaCacheStream::ReadMode aMode) = 0;
// Read up to aCount bytes from the stream. The read starts at
// aOffset in the stream, seeking to that location initially if
// it is not the current stream offset. The remaining arguments,
// results and requirements are the same as per the Read method.
virtual nsresult ReadAt(int64_t aOffset, char* aBuffer,
uint32_t aCount, uint32_t* aBytes) = 0;
// Indicate whether caching data in advance of reads is worth it.
// E.g. Caching lockless and memory-based MediaResource subclasses would be a
@@ -320,16 +318,19 @@ public:
// since we don't expect to resume again any time soon. Otherwise we
// may resume again soon so resources should be held for a little
// while.
virtual void Suspend(bool aCloseImmediately) = 0;
// Resume any downloads that have been suspended.
virtual void Resume() = 0;
+ // The mode is initially MODE_PLAYBACK.
+ virtual void SetReadMode(MediaCacheStream::ReadMode aMode) = 0;
+
/**
* Open the stream. This creates a stream listener and returns it in
* aStreamListener; this listener needs to be notified of incoming data.
*/
virtual nsresult Open(nsIStreamListener** aStreamListener) = 0;
// If this returns false, then we shouldn't try to clone this MediaResource
// because its underlying resources are not suitable for reuse (e.g.
--- a/dom/media/gtest/MockMediaResource.h
+++ b/dom/media/gtest/MockMediaResource.h
@@ -15,17 +15,16 @@ namespace mozilla
class MockMediaResource : public MediaResource
{
public:
explicit MockMediaResource(const char* aFileName);
already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override
{
return nullptr;
}
- void SetReadMode(MediaCacheStream::ReadMode aMode) override {}
nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount,
uint32_t* aBytes) override;
// Data stored in file, caching recommended.
bool ShouldCacheReads() override { return true; }
int64_t Tell() override { return 0; }
void Pin() override {}
void Unpin() override {}
int64_t GetLength() override;
--- a/dom/media/hls/HLSResource.h
+++ b/dom/media/hls/HLSResource.h
@@ -43,17 +43,16 @@ private:
class HLSResource final : public MediaResource
{
public:
HLSResource(HLSDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI);
~HLSResource();
void Suspend();
void Resume();
- void SetReadMode(MediaCacheStream::ReadMode aMode) override { UNIMPLEMENTED(); }
nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes) override { UNIMPLEMENTED(); return NS_ERROR_FAILURE; }
bool ShouldCacheReads() override { UNIMPLEMENTED(); return false; }
int64_t Tell() override { UNIMPLEMENTED(); return -1; }
void Pin() override { UNIMPLEMENTED(); }
void Unpin() override { UNIMPLEMENTED(); }
int64_t GetLength() override { UNIMPLEMENTED(); return -1; }
int64_t GetNextCachedData(int64_t aOffset) override { UNIMPLEMENTED(); return -1; }
int64_t GetCachedDataEnd(int64_t aOffset) override { UNIMPLEMENTED(); return -1; }
--- a/dom/media/mediasource/MediaSourceResource.h
+++ b/dom/media/mediasource/MediaSourceResource.h
@@ -27,17 +27,16 @@ class MediaSourceResource final : public
{
public:
explicit MediaSourceResource(nsIPrincipal* aPrincipal = nullptr)
: mPrincipal(aPrincipal)
, mMonitor("MediaSourceResource")
, mEnded(false)
{}
- void SetReadMode(MediaCacheStream::ReadMode aMode) override { UNIMPLEMENTED(); }
nsresult ReadAt(int64_t aOffset, char* aBuffer, uint32_t aCount, uint32_t* aBytes) override { UNIMPLEMENTED(); return NS_ERROR_FAILURE; }
bool ShouldCacheReads() override { UNIMPLEMENTED(); return false; }
int64_t Tell() override { UNIMPLEMENTED(); return -1; }
void Pin() override { UNIMPLEMENTED(); }
void Unpin() override { UNIMPLEMENTED(); }
int64_t GetLength() override { UNIMPLEMENTED(); return -1; }
int64_t GetNextCachedData(int64_t aOffset) override { UNIMPLEMENTED(); return -1; }
int64_t GetCachedDataEnd(int64_t aOffset) override { UNIMPLEMENTED(); return -1; }
--- a/dom/media/mediasource/SourceBufferResource.h
+++ b/dom/media/mediasource/SourceBufferResource.h
@@ -40,20 +40,16 @@ class SourceBufferResource final : publi
public:
SourceBufferResource();
nsresult Close();
already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override
{
UNIMPLEMENTED();
return nullptr;
}
- void SetReadMode(MediaCacheStream::ReadMode aMode) override
- {
- UNIMPLEMENTED();
- }
nsresult ReadAt(int64_t aOffset,
char* aBuffer,
uint32_t aCount,
uint32_t* aBytes) override;
// Memory-based and no locks, caching discouraged.
bool ShouldCacheReads() override { return false; }
int64_t Tell() override { return mOffset; }
void Pin() override { UNIMPLEMENTED(); }