Bug 1195073: [MSE] P7. Determine a WebM Media Segment end as early as available information permits. r=kinetik a=ritu
☠☠ backed out by 5bb661db5c6c ☠ ☠
authorJean-Yves Avenard <jyavenard@mozilla.com>
Sun, 23 Aug 2015 20:51:05 +1000
changeset 288984 1fb0a72a7fca8a839412752013851e2c57d48482
parent 288983 cbbb8dbd27450cbbfff4b8edb4360ba72aaab2de
child 288985 4c993f78e9f018c5576999a0512e0791151cc6d6
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik, ritu
bugs1195073
milestone42.0a2
Bug 1195073: [MSE] P7. Determine a WebM Media Segment end as early as available information permits. r=kinetik a=ritu 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;