Bug 1414709 - use Span<> to replace low level pointer arithmetic in MediaCacheStream::NotifyDataReceived(). r=bechen,gerald
authorJW Wang <jwwang@mozilla.com>
Wed, 01 Nov 2017 23:20:11 +0800
changeset 390306 5915590f95004274e58c98e00d3df90ec209422c
parent 390305 25f6ee53ac1c078c48fdf1840a85a4a0c32dfadc
child 390307 f43442328ed98b47cdc1eddd14c064c9f6344ea5
push id32827
push userccoroiu@mozilla.com
push dateMon, 06 Nov 2017 23:02:00 +0000
treeherdermozilla-central@62aeebcc676e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbechen, gerald
bugs1414709
milestone58.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 1414709 - use Span<> to replace low level pointer arithmetic in MediaCacheStream::NotifyDataReceived(). r=bechen,gerald MozReview-Commit-ID: KIwws0qiCVK
dom/media/ChannelMediaResource.cpp
dom/media/MediaCache.cpp
dom/media/MediaCache.h
--- a/dom/media/ChannelMediaResource.cpp
+++ b/dom/media/ChannelMediaResource.cpp
@@ -433,17 +433,19 @@ ChannelMediaResource::CopySegmentToCache
                                          void* aClosure,
                                          const char* aFromSegment,
                                          uint32_t aToOffset,
                                          uint32_t aCount,
                                          uint32_t* aWriteCount)
 {
   Closure* closure = static_cast<Closure*>(aClosure);
   closure->mResource->mCacheStream.NotifyDataReceived(
-    closure->mLoadID, aCount, aFromSegment);
+    closure->mLoadID,
+    aCount,
+    reinterpret_cast<const uint8_t*>(aFromSegment));
   *aWriteCount = aCount;
   return NS_OK;
 }
 
 nsresult
 ChannelMediaResource::OnDataAvailable(uint32_t aLoadID,
                                       nsIInputStream* aStream,
                                       uint32_t aCount)
--- a/dom/media/MediaCache.cpp
+++ b/dom/media/MediaCache.cpp
@@ -1985,72 +1985,76 @@ MediaCacheStream::UpdatePrincipal(nsIPri
                                                   aPrincipal)) {
       stream->mClient->CacheClientNotifyPrincipalChanged();
     }
   }
 }
 
 void
 MediaCacheStream::NotifyDataReceived(uint32_t aLoadID,
-                                     int64_t aSize,
-                                     const char* aData)
+                                     uint32_t aCount,
+                                     const uint8_t* aData)
 {
   MOZ_ASSERT(aLoadID > 0);
   // This might happen off the main thread.
 
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
   if (mClosed) {
     // Nothing to do if the stream is closed.
     return;
   }
 
-  LOG("Stream %p DataReceived at %" PRId64 " count=%" PRId64 " aLoadID=%u",
+  LOG("Stream %p DataReceived at %" PRId64 " count=%u aLoadID=%u",
       this,
       mChannelOffset,
-      aSize,
+      aCount,
       aLoadID);
 
   if (mLoadID != aLoadID) {
     // mChannelOffset is updated to a new position when loading a new channel.
     // We should discard the data coming from the old channel so it won't be
     // stored to the wrong positoin.
     return;
   }
-  int64_t size = aSize;
-  const char* data = aData;
+
+  auto source = MakeSpan<const uint8_t>(aData, aCount);
 
   // We process the data one block (or part of a block) at a time
-  while (size > 0) {
-    uint32_t blockIndex = OffsetToBlockIndexUnchecked(mChannelOffset);
-    int32_t blockOffset = int32_t(mChannelOffset - blockIndex*BLOCK_SIZE);
-    int32_t chunkSize = std::min<int64_t>(BLOCK_SIZE - blockOffset, size);
+  while (!source.IsEmpty()) {
+    // The data we've collected so far in the partial block.
+    auto partial = MakeSpan<const uint8_t>(mPartialBlockBuffer.get(),
+                                           OffsetInBlock(mChannelOffset));
 
-    if (blockOffset == 0) {
+    if (partial.IsEmpty()) {
       // We've just started filling this buffer so now is a good time
       // to clear this flag.
       mMetadataInPartialBlockBuffer = false;
     }
 
-    ReadMode mode = mMetadataInPartialBlockBuffer
-      ? MODE_METADATA : MODE_PLAYBACK;
+    // The number of bytes needed to complete the partial block.
+    size_t remaining = BLOCK_SIZE - partial.Length();
 
-    if (blockOffset + chunkSize == BLOCK_SIZE) {
+    if (source.Length() >= remaining) {
       // We have a whole block now to write it out.
-      auto data1 = MakeSpan<const uint8_t>(
-        mPartialBlockBuffer.get(), blockOffset);
-      auto data2 = MakeSpan<const uint8_t>(
-        reinterpret_cast<const uint8_t*>(data), chunkSize);
-      mMediaCache->AllocateAndWriteBlock(this, blockIndex, mode, data1, data2);
+      mMediaCache->AllocateAndWriteBlock(
+        this,
+        OffsetToBlockIndexUnchecked(mChannelOffset),
+        mMetadataInPartialBlockBuffer ? MODE_METADATA : MODE_PLAYBACK,
+        partial,
+        source.First(remaining));
+      source = source.From(remaining);
+      mChannelOffset += remaining;
     } else {
-      memcpy(mPartialBlockBuffer.get() + blockOffset, data, chunkSize);
+      // The buffer to be filled in the partial block.
+      auto buf = MakeSpan<uint8_t>(mPartialBlockBuffer.get() + partial.Length(),
+                                   remaining);
+      memcpy(buf.Elements(), source.Elements(), source.Length());
+      mChannelOffset += source.Length();
+      break;
     }
-
-    mChannelOffset += chunkSize;
-    size -= chunkSize;
-    data += chunkSize;
   }
 
   MediaCache::ResourceStreamIterator iter(mMediaCache, mResourceID);
   while (MediaCacheStream* stream = iter.Next()) {
     if (stream->mStreamLength >= 0) {
       // The stream is at least as long as what we've read
       stream->mStreamLength = std::max(stream->mStreamLength, mChannelOffset);
     }
--- a/dom/media/MediaCache.h
+++ b/dom/media/MediaCache.h
@@ -259,17 +259,19 @@ public:
   // we do an HTTP load the seekability may be different (and sometimes
   // is, in practice, due to the effects of caching proxies).
   void NotifyDataStarted(uint32_t aLoadID, int64_t aOffset, bool aSeekable);
   // Notifies the cache that data has been received. The stream already
   // knows the offset because data is received in sequence and
   // the starting offset is known via NotifyDataStarted or because
   // the cache requested the offset in
   // ChannelMediaResource::CacheClientSeek, or because it defaulted to 0.
-  void NotifyDataReceived(uint32_t aLoadID, int64_t aSize, const char* aData);
+  void NotifyDataReceived(uint32_t aLoadID,
+                          uint32_t aCount,
+                          const uint8_t* aData);
   // Notifies the cache that the current bytes should be written to disk.
   // Called on the main thread.
   void FlushPartialBlock();
   // Notifies the cache that the channel has closed with the given status.
   void NotifyDataEnded(nsresult aStatus);
 
   // Notifies the stream that the channel is reopened. The stream should
   // reset variables such as |mDidNotifyDataEnded|.