Bug 1195073: [MSE] P7. Determine a WebM Media Segment end as early as available information permits. r=kinetik
authorJean-Yves Avenard <jyavenard@mozilla.com>
Sun, 23 Aug 2015 20:51:05 +1000
changeset 259039 76f12bc3d57a1db88e71d71dfa4336e654b8a439
parent 259038 69619b7f188e2e1474c7e4da5ec23eda6de466d9
child 259040 85295a300ea2a205b841ae7e219760beedabdc27
push id29268
push userryanvm@gmail.com
push dateTue, 25 Aug 2015 00:37:23 +0000
treeherdermozilla-central@08015770c9d6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs1195073
milestone43.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 1195073: [MSE] P7. Determine a WebM Media Segment end as early as available information permits. r=kinetik Most cluster contains information about their size. When known, we don't need to wait until the next media segment is received to determine its size.
dom/media/mediasource/ContainerParser.cpp
--- a/dom/media/mediasource/ContainerParser.cpp
+++ b/dom/media/mediasource/ContainerParser.cpp
@@ -180,28 +180,30 @@ public:
     }
     return false;
   }
 
   bool ParseStartAndEndTimestamps(MediaByteBuffer* aData,
                                   int64_t& aStart, int64_t& aEnd) override
   {
     bool initSegment = IsInitSegmentPresent(aData);
+
+    if (mLastMapping && (initSegment || IsMediaSegmentPresent(aData))) {
+      // The last data contained a complete cluster but we can only detect it
+      // now that a new one is starting.
+      // We use mOffset as end position to ensure that any blocks not reported
+      // by WebMBufferParser are properly skipped.
+      mCompleteMediaSegmentRange = MediaByteRange(mLastMapping.ref().mSyncOffset,
+                                                  mOffset);
+      mLastMapping.reset();
+      MSE_DEBUG(WebMContainerParser, "New cluster found at start, ending previous one");
+      return false;
+    }
+
     if (initSegment) {
-      if (mLastMapping) {
-        // The last data contained a complete cluster but we can only detect it
-        // now that a new one is starting.
-        // We use mOffset as end position to ensure that any blocks not reported
-        // by WebMBufferParser are properly skipped.
-        mCompleteMediaSegmentRange = MediaByteRange(mLastMapping.ref().mSyncOffset,
-                                                    mOffset);
-        mLastMapping.reset();
-        MSE_DEBUG(WebMContainerParser, "New cluster found at start, ending previous one");
-        return false;
-      }
       mOffset = 0;
       mParser = WebMBufferedParser(0);
       mOverlappedMapping.Clear();
       mInitData = new MediaByteBuffer();
       mResource = new SourceBufferResource(NS_LITERAL_CSTRING("video/webm"));
       mCompleteMediaHeaderRange = MediaByteRange();
       mCompleteMediaSegmentRange = MediaByteRange();
     }
@@ -239,30 +241,16 @@ public:
       mHasInitData = true;
     }
     mOffset += aData->Length();
 
     if (mapping.IsEmpty()) {
       return false;
     }
 
-    if (mLastMapping &&
-        mLastMapping.ref().mSyncOffset != mapping[0].mSyncOffset) {
-      // The last data contained a complete cluster but we can only detect it
-      // now that a new one is starting.
-      // We use the start of the next cluster as end position to ensure that any
-      // blocks not reported by WebMBufferParser is properly skipped.
-      mCompleteMediaSegmentRange = MediaByteRange(mLastMapping.ref().mSyncOffset,
-                                                  mapping[0].mSyncOffset);
-      mOverlappedMapping.AppendElements(mapping);
-      mLastMapping.reset();
-      MSE_DEBUG(WebMContainerParser, "New cluster found at start, ending previous one");
-      return false;
-    }
-
     // Calculate media range for first media segment.
 
     // Check if we have a cluster finishing in the current data.
     uint32_t endIdx = mapping.Length() - 1;
     bool foundNewCluster = false;
     while (mapping[0].mSyncOffset != mapping[endIdx].mSyncOffset) {
       endIdx -= 1;
       foundNewCluster = true;
@@ -287,18 +275,27 @@ public:
     if (mCompleteMediaHeaderRange.IsNull()) {
       mCompleteMediaHeaderRange = MediaByteRange(mapping[0].mSyncOffset,
                                                  mapping[0].mEndOffset);
     }
     mLastMapping = Some(mapping[completeIdx]);
 
     if (foundNewCluster && mOffset >= mapping[endIdx].mEndOffset) {
       // We now have all information required to delimit a complete cluster.
+      int64_t endOffset = mapping[endIdx+1].mSyncOffset;
+      if (mapping[endIdx+1].mInitOffset > mapping[endIdx].mInitOffset) {
+        // We have a new init segment before this cluster.
+        endOffset = mapping[endIdx+1].mInitOffset;
+      }
       mCompleteMediaSegmentRange = MediaByteRange(mapping[endIdx].mSyncOffset,
-                                                  mapping[endIdx].mEndOffset);
+                                                  endOffset);
+    } else if (mapping[endIdx].mClusterEndOffset >= 0 &&
+               mOffset >= mapping[endIdx].mClusterEndOffset) {
+      mCompleteMediaSegmentRange = MediaByteRange(mapping[endIdx].mSyncOffset,
+                                                  mParser.EndSegmentOffset(mapping[endIdx].mClusterEndOffset));
     }
 
     if (!completeIdx) {
       return false;
     }
 
     uint64_t frameDuration =
       mapping[completeIdx].mTimecode - mapping[completeIdx - 1].mTimecode;