Bug 1515658 - ChannelMediaResource should use the BlobURLs' length when known, r=jya
authorAndrea Marchesini <amarchesini@mozilla.com>
Thu, 03 Jan 2019 19:22:49 +0100
changeset 509554 9c9f8232272eda52a244059234f6f3ca9fc2afdd
parent 509553 42156d5817a6ef502138d88f9ab38d2f460c7ade
child 509555 2a5bc7dcd7a83334d18728e9402d083fc6caef78
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1515658
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1515658 - ChannelMediaResource should use the BlobURLs' length when known, r=jya
dom/media/BaseMediaResource.cpp
dom/media/ChannelMediaResource.cpp
dom/media/ChannelMediaResource.h
--- a/dom/media/BaseMediaResource.cpp
+++ b/dom/media/BaseMediaResource.cpp
@@ -43,16 +43,18 @@ already_AddRefed<BaseMediaResource> Base
   // Let's try to create a FileMediaResource in case the channel is a nsIFile
   nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(aChannel);
   if (fc) {
     RefPtr<BaseMediaResource> resource =
         new FileMediaResource(aCallback, aChannel, uri);
     return resource.forget();
   }
 
+  int64_t streamLength = -1;
+
   RefPtr<mozilla::dom::BlobImpl> blobImpl;
   if (dom::IsBlobURI(uri) &&
       NS_SUCCEEDED(NS_GetBlobForBlobURI(uri, getter_AddRefs(blobImpl))) &&
       blobImpl) {
     IgnoredErrorResult rv;
 
     nsCOMPtr<nsIInputStream> stream;
     blobImpl->CreateInputStream(getter_AddRefs(stream), rv);
@@ -82,20 +84,23 @@ already_AddRefed<BaseMediaResource> Base
     // Maybe this blob URL can be cloned with a range.
     nsCOMPtr<nsICloneableInputStreamWithRange> cloneableWithRange =
         do_QueryInterface(stream);
     if (cloneableWithRange) {
       RefPtr<BaseMediaResource> resource = new CloneableWithRangeMediaResource(
           aCallback, aChannel, uri, stream, size);
       return resource.forget();
     }
+
+    // We know the size of the stream for blobURLs, let's use it.
+    streamLength = size;
   }
 
-  RefPtr<BaseMediaResource> resource =
-      new ChannelMediaResource(aCallback, aChannel, uri, aIsPrivateBrowsing);
+  RefPtr<BaseMediaResource> resource = new ChannelMediaResource(
+      aCallback, aChannel, uri, streamLength, aIsPrivateBrowsing);
   return resource.forget();
 }
 
 void BaseMediaResource::SetLoadInBackground(bool aLoadInBackground) {
   if (aLoadInBackground == mLoadInBackground) {
     return;
   }
   mLoadInBackground = aLoadInBackground;
--- a/dom/media/ChannelMediaResource.cpp
+++ b/dom/media/ChannelMediaResource.cpp
@@ -22,20 +22,22 @@ mozilla::LazyLogModule gMediaResourceLog
 // Debug logging macro with object pointer and class name.
 #define LOG(msg, ...) \
   DDMOZ_LOG(gMediaResourceLog, mozilla::LogLevel::Debug, msg, ##__VA_ARGS__)
 
 namespace mozilla {
 
 ChannelMediaResource::ChannelMediaResource(MediaResourceCallback* aCallback,
                                            nsIChannel* aChannel, nsIURI* aURI,
+                                           int64_t aStreamLength,
                                            bool aIsPrivateBrowsing)
     : BaseMediaResource(aCallback, aChannel, aURI),
       mCacheStream(this, aIsPrivateBrowsing),
-      mSuspendAgent(mCacheStream) {}
+      mSuspendAgent(mCacheStream),
+      mKnownStreamLength(aStreamLength) {}
 
 ChannelMediaResource::~ChannelMediaResource() {
   MOZ_ASSERT(mClosed);
   MOZ_ASSERT(!mChannel);
   MOZ_ASSERT(!mListener);
   if (mSharedInfo) {
     mSharedInfo->mResources.RemoveElement(this);
   }
@@ -509,17 +511,18 @@ int64_t ChannelMediaResource::CalculateS
   return contentLength;
 }
 
 nsresult ChannelMediaResource::Open(nsIStreamListener** aStreamListener) {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
   MOZ_ASSERT(aStreamListener);
   MOZ_ASSERT(mChannel);
 
-  int64_t streamLength = CalculateStreamLength();
+  int64_t streamLength =
+      mKnownStreamLength < 0 ? CalculateStreamLength() : mKnownStreamLength;
   nsresult rv = mCacheStream.Init(streamLength);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   mSharedInfo = new SharedInfo;
   mSharedInfo->mResources.AppendElement(this);
 
@@ -608,17 +611,17 @@ bool ChannelMediaResource::CanClone() {
 }
 
 already_AddRefed<BaseMediaResource> ChannelMediaResource::CloneData(
     MediaResourceCallback* aCallback) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(CanClone(), "Stream can't be cloned");
 
   RefPtr<ChannelMediaResource> resource =
-      new ChannelMediaResource(aCallback, nullptr, mURI);
+      new ChannelMediaResource(aCallback, nullptr, mURI, mKnownStreamLength);
 
   resource->mIsLiveStream = mIsLiveStream;
   resource->mIsTransportSeekable = mIsTransportSeekable;
   resource->mSharedInfo = mSharedInfo;
   mSharedInfo->mResources.AppendElement(resource.get());
 
   // Initially the clone is treated as suspended by the cache, because
   // we don't have a channel. If the cache needs to read data from the clone
--- a/dom/media/ChannelMediaResource.h
+++ b/dom/media/ChannelMediaResource.h
@@ -71,17 +71,18 @@ class ChannelMediaResource
 
    private:
     ~SharedInfo() = default;
   };
   RefPtr<SharedInfo> mSharedInfo;
 
  public:
   ChannelMediaResource(MediaResourceCallback* aDecoder, nsIChannel* aChannel,
-                       nsIURI* aURI, bool aIsPrivateBrowsing = false);
+                       nsIURI* aURI, int64_t aStreamLength,
+                       bool aIsPrivateBrowsing = false);
   ~ChannelMediaResource();
 
   // These are called on the main thread by MediaCache. These must
   // not block or grab locks, because the media cache is holding its lock.
   // Notify that data is available from the cache. This can happen even
   // if this stream didn't read any data, since another stream might have
   // received data for the same resource.
   void CacheClientNotifyDataReceived();
@@ -246,13 +247,16 @@ class ChannelMediaResource
   // A mono-increasing integer to uniquely identify the channel we are loading.
   uint32_t mLoadID = 0;
   bool mIsLiveStream = false;
 
   // Any thread access
   MediaCacheStream mCacheStream;
 
   ChannelSuspendAgent mSuspendAgent;
+
+  // The size of the stream if known at construction time (such as with blob)
+  const int64_t mKnownStreamLength;
 };
 
 }  // namespace mozilla
 
 #endif  // mozilla_dom_media_ChannelMediaResource_h