Bug 1405697 - Move MediaResourceIndex implementation to MediaResource.cpp. r=jwwang draft
authorChris Pearce <cpearce@mozilla.com>
Wed, 04 Oct 2017 21:25:19 +0200
changeset 675490 7125dcf91c360e783f6ea6c4e425071c39cd85cf
parent 675489 4cb940008abb62c43759689cdc9e034d25b7e36f
child 675491 57c02d153d3800bfbd5bf62bad01646824147384
child 675498 84f9b98e3c64dc1a337a12b714fd4c8bc45429a1
push id83131
push userbmo:cpearce@mozilla.com
push dateThu, 05 Oct 2017 09:31:51 +0000
reviewersjwwang
bugs1405697
milestone58.0a1
Bug 1405697 - Move MediaResourceIndex implementation to MediaResource.cpp. r=jwwang MozReview-Commit-ID: 7GCgaA8jJmU
dom/media/MediaResource.cpp
dom/media/MediaResource.h
--- a/dom/media/MediaResource.cpp
+++ b/dom/media/MediaResource.cpp
@@ -36,16 +36,28 @@ MediaResource::Destroy()
     NewNonOwningRunnableMethod(
       "MediaResource::Destroy", this, &MediaResource::Destroy));
   MOZ_ALWAYS_SUCCEEDS(rv);
 }
 
 NS_IMPL_ADDREF(MediaResource)
 NS_IMPL_RELEASE_WITH_DESTROY(MediaResource, Destroy())
 
+MediaResourceIndex::MediaResourceIndex(MediaResource* aResource)
+  : mResource(aResource)
+  , mOffset(0)
+  , mCacheBlockSize(aResource->ShouldCacheReads()
+                      ? SelectCacheSize(MediaPrefs::MediaResourceIndexCache())
+                      : 0)
+  , mCachedOffset(0)
+  , mCachedBytes(0)
+  , mCachedBlock(MakeUnique<char[]>(mCacheBlockSize))
+{
+}
+
 nsresult
 MediaResourceIndex::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
 
   // We purposefuly don't check that we may attempt to read past
   // mResource->GetLength() as the resource's length may change over time.
 
@@ -495,12 +507,108 @@ MediaResourceIndex::Seek(int32_t aWhence
   if (aOffset < 0) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
   mOffset = aOffset;
 
   return NS_OK;
 }
 
+already_AddRefed<MediaByteBuffer>
+MediaResourceIndex::MediaReadAt(int64_t aOffset, uint32_t aCount) const
+{
+  RefPtr<MediaByteBuffer> bytes = new MediaByteBuffer();
+  if (aOffset < 0) {
+    return bytes.forget();
+  }
+  bool ok = bytes->SetLength(aCount, fallible);
+  NS_ENSURE_TRUE(ok, nullptr);
+  char* curr = reinterpret_cast<char*>(bytes->Elements());
+  const char* start = curr;
+  while (aCount > 0) {
+    uint32_t bytesRead;
+    nsresult rv = mResource->ReadAt(aOffset, curr, aCount, &bytesRead);
+    NS_ENSURE_SUCCESS(rv, nullptr);
+    if (!bytesRead) {
+      break;
+    }
+    aOffset += bytesRead;
+    if (aOffset < 0) {
+      // Very unlikely overflow.
+      break;
+    }
+    aCount -= bytesRead;
+    curr += bytesRead;
+  }
+  bytes->SetLength(curr - start);
+  return bytes.forget();
+}
+
+already_AddRefed<MediaByteBuffer>
+MediaResourceIndex::CachedMediaReadAt(int64_t aOffset, uint32_t aCount) const
+{
+  RefPtr<MediaByteBuffer> bytes = new MediaByteBuffer();
+  bool ok = bytes->SetLength(aCount, fallible);
+  NS_ENSURE_TRUE(ok, nullptr);
+  char* curr = reinterpret_cast<char*>(bytes->Elements());
+  nsresult rv = mResource->ReadFromCache(curr, aOffset, aCount);
+  NS_ENSURE_SUCCESS(rv, nullptr);
+  return bytes.forget();
+}
+
+// Get the length of the stream in bytes. Returns -1 if not known.
+// This can change over time; after a seek operation, a misbehaving
+// server may give us a resource of a different length to what it had
+// reported previously --- or it may just lie in its Content-Length
+// header and give us more or less data than it reported. We will adjust
+// the result of GetLength to reflect the data that's actually arriving.
+int64_t
+MediaResourceIndex::GetLength() const
+{
+  return mResource->GetLength();
+}
+
+// Select the next power of 2 (in range 32B-128KB, or 0 -> no cache)
+/* static */
+uint32_t
+MediaResourceIndex::SelectCacheSize(uint32_t aHint)
+{
+  if (aHint == 0) {
+    return 0;
+  }
+  if (aHint <= 32) {
+    return 32;
+  }
+  if (aHint > 64 * 1024) {
+    return 128 * 1024;
+  }
+  // 32-bit next power of 2, from:
+  // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
+  aHint--;
+  aHint |= aHint >> 1;
+  aHint |= aHint >> 2;
+  aHint |= aHint >> 4;
+  aHint |= aHint >> 8;
+  aHint |= aHint >> 16;
+  aHint++;
+  return aHint;
+}
+
+uint32_t
+MediaResourceIndex::IndexInCache(int64_t aOffsetInFile) const
+{
+  const uint32_t index = uint32_t(aOffsetInFile) & (mCacheBlockSize - 1);
+  MOZ_ASSERT(index == aOffsetInFile % mCacheBlockSize);
+  return index;
+}
+
+int64_t
+MediaResourceIndex::CacheOffsetContaining(int64_t aOffsetInFile) const
+{
+  const int64_t offset = aOffsetInFile & ~(int64_t(mCacheBlockSize) - 1);
+  MOZ_ASSERT(offset == aOffsetInFile - IndexInCache(aOffsetInFile));
+  return offset;
+}
+
 } // namespace mozilla
 
 // avoid redefined macro in unified build
 #undef ILOG
--- a/dom/media/MediaResource.h
+++ b/dom/media/MediaResource.h
@@ -151,30 +151,20 @@ private:
 
 /*
  * MediaResourceIndex provides a way to access MediaResource objects.
  * Read, Seek and Tell must only be called on non-main threads.
  * In the case of the Ogg Decoder they are called on the Decode thread for
  * example. You must ensure that no threads are calling these methods once
  * the MediaResource has been Closed.
  */
-
 class MediaResourceIndex
 {
 public:
-  explicit MediaResourceIndex(MediaResource* aResource)
-    : mResource(aResource)
-    , mOffset(0)
-    , mCacheBlockSize(aResource->ShouldCacheReads()
-                      ? SelectCacheSize(MediaPrefs::MediaResourceIndexCache())
-                      : 0 )
-    , mCachedOffset(0)
-    , mCachedBytes(0)
-    , mCachedBlock(MakeUnique<char[]>(mCacheBlockSize))
-  {}
+  explicit MediaResourceIndex(MediaResource* aResource);
 
   // Read up to aCount bytes from the stream. The buffer must have
   // enough room for at least aCount bytes. Stores the number of
   // actual bytes read in aBytes (0 on end of file).
   // May read less than aCount bytes if the number of
   // available bytes is less than aCount. Always check *aBytes after
   // read, and call again if necessary.
   nsresult Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes);
@@ -246,115 +236,49 @@ public:
                                 uint32_t aExtraCount,
                                 uint32_t* aBytes) const;
 
   // This method returns nullptr if anything fails.
   // Otherwise, it returns an owned buffer.
   // MediaReadAt may return fewer bytes than requested if end of stream is
   // encountered. There is no need to call it again to get more data.
   // Note this method will not update mOffset.
-  already_AddRefed<MediaByteBuffer> MediaReadAt(int64_t aOffset, uint32_t aCount) const
-  {
-    RefPtr<MediaByteBuffer> bytes = new MediaByteBuffer();
-    if (aOffset < 0) {
-      return bytes.forget();
-    }
-    bool ok = bytes->SetLength(aCount, fallible);
-    NS_ENSURE_TRUE(ok, nullptr);
-    char* curr = reinterpret_cast<char*>(bytes->Elements());
-    const char* start = curr;
-    while (aCount > 0) {
-      uint32_t bytesRead;
-      nsresult rv = mResource->ReadAt(aOffset, curr, aCount, &bytesRead);
-      NS_ENSURE_SUCCESS(rv, nullptr);
-      if (!bytesRead) {
-        break;
-      }
-      aOffset += bytesRead;
-      if (aOffset < 0) {
-        // Very unlikely overflow.
-        break;
-      }
-      aCount -= bytesRead;
-      curr += bytesRead;
-    }
-    bytes->SetLength(curr - start);
-    return bytes.forget();
-  }
+  already_AddRefed<MediaByteBuffer> MediaReadAt(int64_t aOffset,
+                                                uint32_t aCount) const;
 
   already_AddRefed<MediaByteBuffer> CachedMediaReadAt(int64_t aOffset,
-                                                      uint32_t aCount) const
-  {
-    RefPtr<MediaByteBuffer> bytes = new MediaByteBuffer();
-    bool ok = bytes->SetLength(aCount, fallible);
-    NS_ENSURE_TRUE(ok, nullptr);
-    char* curr = reinterpret_cast<char*>(bytes->Elements());
-    nsresult rv = mResource->ReadFromCache(curr, aOffset, aCount);
-    NS_ENSURE_SUCCESS(rv, nullptr);
-    return bytes.forget();
-  }
+                                                      uint32_t aCount) const;
 
   // Get the length of the stream in bytes. Returns -1 if not known.
   // This can change over time; after a seek operation, a misbehaving
   // server may give us a resource of a different length to what it had
   // reported previously --- or it may just lie in its Content-Length
   // header and give us more or less data than it reported. We will adjust
   // the result of GetLength to reflect the data that's actually arriving.
-  int64_t GetLength() const { return mResource->GetLength(); }
+  int64_t GetLength() const;
 
 private:
   // If the resource has cached data past the requested range, try to grab it
   // into our local cache.
   // If there is no cached data, or attempting to read it fails, fallback on
   // a (potentially-blocking) read of just what was requested, so that we don't
   // get unexpected side-effects by trying to read more than intended.
   nsresult CacheOrReadAt(int64_t aOffset,
                          char* aBuffer,
                          uint32_t aCount,
                          uint32_t* aBytes);
 
   // Select the next power of 2 (in range 32B-128KB, or 0 -> no cache)
-  static uint32_t SelectCacheSize(uint32_t aHint)
-  {
-    if (aHint == 0) {
-      return 0;
-    }
-    if (aHint <= 32) {
-      return 32;
-    }
-    if (aHint > 64*1024) {
-      return 128*1024;
-    }
-    // 32-bit next power of 2, from:
-    // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
-    aHint--;
-    aHint |= aHint >> 1;
-    aHint |= aHint >> 2;
-    aHint |= aHint >> 4;
-    aHint |= aHint >> 8;
-    aHint |= aHint >> 16;
-    aHint++;
-    return aHint;
-  }
+  static uint32_t SelectCacheSize(uint32_t aHint);
 
   // Maps a file offset to a mCachedBlock index.
-  uint32_t IndexInCache(int64_t aOffsetInFile) const
-  {
-    const uint32_t index = uint32_t(aOffsetInFile) & (mCacheBlockSize - 1);
-    MOZ_ASSERT(index == aOffsetInFile % mCacheBlockSize);
-    return index;
-  }
+  uint32_t IndexInCache(int64_t aOffsetInFile) const;
 
   // Starting file offset of the cache block that contains a given file offset.
-  int64_t CacheOffsetContaining(int64_t aOffsetInFile) const
-  {
-    const int64_t offset = aOffsetInFile & ~(int64_t(mCacheBlockSize) - 1);
-    MOZ_ASSERT(offset == aOffsetInFile - IndexInCache(aOffsetInFile));
-    return offset;
-  }
+  int64_t CacheOffsetContaining(int64_t aOffsetInFile) const;
 
   RefPtr<MediaResource> mResource;
   int64_t mOffset;
 
   // Local cache used by ReadAt().
   // mCachedBlock is valid when mCachedBytes != 0, in which case it contains
   // data of length mCachedBytes, starting at offset `mCachedOffset` in the
   // resource, located at index `IndexInCache(mCachedOffset)` in mCachedBlock.