Bug 1366975 - MediaElement
MozReview-Commit-ID: HBJFjtCe8Eu
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -122,16 +122,17 @@ static mozilla::LazyLogModule gMediaElem
#include "nsIPermissionManager.h"
#include "nsDocShell.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/dom/HTMLVideoElement.h"
#include "mozilla/dom/VideoPlaybackQuality.h"
+#include "mozilla/dom/MediaCacheStatus.h"
#include "HTMLMediaElement.h"
#include "GMPCrashHelper.h"
using namespace mozilla::layers;
using mozilla::net::nsMediaFragmentURIParser;
namespace mozilla {
@@ -7526,10 +7527,33 @@ HTMLMediaElement::ReportCanPlayTelemetry
Telemetry::Accumulate(
Telemetry::HistogramID::VIDEO_CAN_CREATE_H264_DECODER, h264);
thread->AsyncShutdown();
}));
}),
NS_DISPATCH_NORMAL);
}
+already_AddRefed<MediaCacheStatus>
+HTMLMediaElement::GetMediaCacheStatus()
+{
+ int64_t totalBlocks = 0;
+ int64_t occupiedBlocks = 0;
+
+ if (Preferences::GetBool("media.mediaCacheStatus.enabled", false)) {
+ int32_t cacheSize = Preferences::GetInt("media.cache_size", 500*1024);
+ totalBlocks = static_cast<int64_t>(cacheSize)*1024/MediaCacheStream::BLOCK_SIZE;
+ totalBlocks = std::max<int64_t>(totalBlocks, 1);
+ if (mDecoder) {
+ MediaStatistics stats = mDecoder->GetStatistics();
+ occupiedBlocks = stats.mCachedBlocks;
+ }
+ }
+
+
+ RefPtr<MediaCacheStatus> mediaCacheStatus =
+ new MediaCacheStatus(this, MediaCacheStream::BLOCK_SIZE,
+ totalBlocks,occupiedBlocks);
+ return mediaCacheStatus.forget();
+}
+
} // namespace dom
} // namespace mozilla
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -100,16 +100,18 @@ public:
CORSMode GetCORSMode() {
return mCORSMode;
}
explicit HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
void ReportCanPlayTelemetry();
+ already_AddRefed<MediaCacheStatus> GetMediaCacheStatus();
+
/**
* This is used when the browser is constructing a video element to play
* a channel that we've already started loading. The src attribute and
* <source> children are ignored.
* @param aChannel the channel to use
* @param aListener returns a stream listener that should receive
* notifications for the stream
*/
--- a/dom/media/MediaCache.h
+++ b/dom/media/MediaCache.h
@@ -277,16 +277,18 @@ public:
// reset variables such as |mDidNotifyDataEnded|.
void NotifyChannelRecreated();
// These methods can be called on any thread.
// Cached blocks associated with this stream will not be evicted
// while the stream is pinned.
void Pin();
void Unpin();
+
+ uint64_t GetBlockCount() {return mBlocks.Length();}
// See comments above for NotifyDataLength about how the length
// can vary over time. Returns -1 if no length is known. Returns the
// reported length if we haven't got any better information. If
// the stream ended normally we return the length we actually got.
// If we've successfully read data beyond the originally reported length,
// we return the end of the data we've read.
int64_t GetLength();
// Returns the unique resource ID. Call only on the main thread or while
--- a/dom/media/MediaCacheStatus.cpp
+++ b/dom/media/MediaCacheStatus.cpp
@@ -12,17 +12,17 @@
#include "nsWrapperCache.h"
namespace mozilla {
namespace dom {
MediaCacheStatus::MediaCacheStatus(HTMLMediaElement* aElement,
uint32_t aBlockSize,
uint32_t aTotalBlocks,
- uint32_t mOccupiedBlocks)
+ uint32_t aOccupiedBlocks)
: mElement(aElement)
, mBlockSize(aBlockSize)
, mTotalBlocks(aTotalBlocks)
, mOccupiedBlocks(aOccupiedBlocks)
{
}
HTMLMediaElement*
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -991,16 +991,17 @@ MediaDecoder::GetStatistics()
result.mDownloadRate =
mResource->GetDownloadRate(&result.mDownloadRateReliable);
result.mDownloadPosition = mResource->GetCachedDataEnd(mDecoderPosition);
result.mTotalBytes = mResource->GetLength();
result.mPlaybackRate = mPlaybackBytesPerSecond;
result.mPlaybackRateReliable = mPlaybackRateReliable;
result.mDecoderPosition = mDecoderPosition;
result.mPlaybackPosition = mPlaybackPosition;
+ result.mCachedBlocks = mResource->GetCachedBlockCount();
return result;
}
void
MediaDecoder::ComputePlaybackRate()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mResource);
--- a/dom/media/MediaResource.cpp
+++ b/dom/media/MediaResource.cpp
@@ -1015,16 +1015,22 @@ ChannelMediaResource::IsDataCachedToEndO
}
void
ChannelMediaResource::EnsureCacheUpToDate()
{
mCacheStream.EnsureCacheUpdate();
}
+int64_t
+ChannelMediaResource::GetCachedBlockCount()
+{
+ return mCacheStream.GetBlockCount();
+}
+
bool
ChannelMediaResource::IsSuspendedByCache()
{
return mCacheStream.AreAllStreamsForResourceSuspended();
}
bool
ChannelMediaResource::IsSuspended()
--- a/dom/media/MediaResource.h
+++ b/dom/media/MediaResource.h
@@ -256,16 +256,17 @@ public:
// Moves any existing channel loads into or out of background. Background
// loads don't block the load event. This also determines whether or not any
// new loads initiated (for example to seek) will be in the background.
virtual void SetLoadInBackground(bool aLoadInBackground) {}
// Ensures that the value returned by IsSuspendedByCache below is up to date
// (i.e. the cache has examined this stream at least once).
virtual void EnsureCacheUpToDate() {}
+ virtual int64_t GetCachedBlockCount() { return 0;};
// These can be called on any thread.
// Cached blocks associated with this stream will not be evicted
// while the stream is pinned.
virtual void Pin() = 0;
virtual void Unpin() = 0;
// Get the estimated download rate in bytes per second (assuming no
// pausing of the channel is requested by Gecko).
// *aIsReliable is set to true if we think the estimate is useful.
@@ -573,16 +574,17 @@ public:
already_AddRefed<nsIPrincipal> GetCurrentPrincipal() override;
// Return true if the stream has been closed.
bool IsClosed() const { return mCacheStream.IsClosed(); }
bool CanClone() override;
already_AddRefed<MediaResource> CloneData(MediaResourceCallback* aDecoder) override;
nsresult ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount) override;
void EnsureCacheUpToDate() override;
+ int64_t GetCachedBlockCount() override;
// Other thread
void SetReadMode(MediaCacheStream::ReadMode aMode) override;
void SetPlaybackRate(uint32_t aBytesPerSecond) override;
nsresult ReadAt(int64_t offset, char* aBuffer,
uint32_t aCount, uint32_t* aBytes) override;
// Data stored in IO&lock-encumbered MediaCacheStream, caching recommended.
bool ShouldCacheReads() override { return true; }
already_AddRefed<MediaByteBuffer> MediaReadAt(int64_t aOffset, uint32_t aCount) override;
--- a/dom/media/MediaStatistics.h
+++ b/dom/media/MediaStatistics.h
@@ -29,16 +29,18 @@ struct MediaStatistics {
// estimate (probably because the download has only been running
// a short time).
bool mDownloadRateReliable;
// If false, then mPlaybackRate cannot be considered a reliable
// estimate (probably because playback has only been running
// a short time).
bool mPlaybackRateReliable;
+ int64_t mCachedBlocks;
+
bool CanPlayThrough()
{
// Number of estimated seconds worth of data we need to have buffered
// ahead of the current playback position before we allow the media decoder
// to report that it can play through the entire media without the decode
// catching up with the download. Having this margin make the
// CanPlayThrough() calculation more stable in the case of
// fluctuating bitrates.