Bug 1049326 - Partially implement EndOfStream. r=cajbir
authorMatthew Gregan <kinetik@flim.org>
Mon, 11 Aug 2014 13:21:18 +1200
changeset 198816 9d08e8efdd42b77deb77ec700c2802097de5ad4c
parent 198815 20bdca5301b06b58b67e7303195d4a90b029efcb
child 198817 ad31e026b098da534ce0dc48a5218c959153609f
push id47494
push usermgregan@mozilla.com
push dateMon, 11 Aug 2014 02:06:55 +0000
treeherdermozilla-inbound@c9c9e94945fe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscajbir
bugs1049326
milestone34.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 1049326 - Partially implement EndOfStream. r=cajbir
content/media/mediasource/MediaSource.cpp
content/media/mediasource/SourceBuffer.cpp
content/media/mediasource/SourceBuffer.h
content/media/mediasource/SourceBufferList.cpp
content/media/mediasource/SourceBufferList.h
--- a/content/media/mediasource/MediaSource.cpp
+++ b/content/media/mediasource/MediaSource.cpp
@@ -260,23 +260,22 @@ MediaSource::EndOfStream(const Optional<
       mSourceBuffers->AnyUpdating()) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 
   SetReadyState(MediaSourceReadyState::Ended);
   mSourceBuffers->Ended();
   if (!aError.WasPassed()) {
+    DurationChange(mSourceBuffers->GetHighestBufferedEndTime(), aRv);
+    if (aRv.Failed()) {
+      return;
+    }
     // TODO:
-    // Run duration change algorithm.
-    // DurationChange(highestDurationOfSourceBuffers, aRv);
-    // if (aRv.Failed()) {
-    //   return;
-    // }
-    // Notify media element that all data is now available.
+    //   Notify media element that all data is now available.
     return;
   }
   switch (aError.Value()) {
   case MediaSourceEndOfStreamError::Network:
     // TODO: If media element has a readyState of:
     //   HAVE_NOTHING -> run resource fetch algorithm
     // > HAVE_NOTHING -> run "interrupted" steps of resource fetch
     break;
--- a/content/media/mediasource/SourceBuffer.cpp
+++ b/content/media/mediasource/SourceBuffer.cpp
@@ -575,18 +575,18 @@ SourceBuffer::GetBufferedStartEndTime(do
 {
   MOZ_ASSERT(NS_IsMainThread());
   ErrorResult dummy;
   nsRefPtr<TimeRanges> ranges = GetBuffered(dummy);
   if (!ranges || ranges->Length() == 0) {
     *aStart = *aEnd = 0.0;
     return;
   }
-  *aStart = ranges->Start(0, dummy);
-  *aEnd = ranges->End(ranges->Length() - 1, dummy);
+  *aStart = ranges->GetStartTime();
+  *aEnd = ranges->GetEndTime();
 }
 
 void
 SourceBuffer::Evict(double aStart, double aEnd)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MSE_DEBUG("SourceBuffer(%p)::Evict(aStart=%f, aEnd=%f)", this, aStart, aEnd);
   if (!mDecoder) {
--- a/content/media/mediasource/SourceBuffer.h
+++ b/content/media/mediasource/SourceBuffer.h
@@ -106,16 +106,20 @@ public:
   void Ended();
 
   // Evict data in the source buffer in the given time range.
   void Evict(double aStart, double aEnd);
 
   // Returns true if the data in the source buffer contains the given time.
   bool ContainsTime(double aTime);
 
+    // Provide the minimum start time and maximum end time that is available
+  // in the data buffered by this SourceBuffer.
+  void GetBufferedStartEndTime(double* aStart, double* aEnd);
+
 private:
   ~SourceBuffer();
 
   SourceBuffer(MediaSource* aMediaSource, const nsACString& aType);
 
   friend class AsyncEventRunner<SourceBuffer>;
   void DispatchSimpleEvent(const char* aName);
   void QueueAsyncSimpleEvent(const char* aName);
@@ -130,20 +134,16 @@ private:
   // Update mUpdating and fire the appropriate events.
   void StartUpdating();
   void StopUpdating();
   void AbortUpdating();
 
   // Shared implementation of AppendBuffer overloads.
   void AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv);
 
-  // Provide the minimum start time and maximum end time that is available
-  // in the data buffered by this SourceBuffer.
-  void GetBufferedStartEndTime(double* aStart, double* aEnd);
-
   nsRefPtr<MediaSource> mMediaSource;
 
   const nsCString mType;
 
   nsAutoPtr<ContainerParser> mParser;
 
   nsRefPtr<SubBufferDecoder> mDecoder;
 
--- a/content/media/mediasource/SourceBufferList.cpp
+++ b/content/media/mediasource/SourceBufferList.cpp
@@ -147,16 +147,29 @@ void
 SourceBufferList::Ended()
 {
   MOZ_ASSERT(NS_IsMainThread());
   for (uint32_t i = 0; i < mSourceBuffers.Length(); ++i) {
     mSourceBuffers[i]->Ended();
   }
 }
 
+double
+SourceBufferList::GetHighestBufferedEndTime()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  double highestEnd = 0;
+  for (uint32_t i = 0; i < mSourceBuffers.Length(); ++i) {
+    double start, end;
+    mSourceBuffers[i]->GetBufferedStartEndTime(&start, &end);
+    highestEnd = std::max(highestEnd, end);
+  }
+  return highestEnd;
+}
+
 void
 SourceBufferList::DispatchSimpleEvent(const char* aName)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MSE_API("SourceBufferList(%p) Dispatch event '%s'", this, aName);
   DispatchTrustedEvent(NS_ConvertUTF8toUTF16(aName));
 }
 
--- a/content/media/mediasource/SourceBufferList.h
+++ b/content/media/mediasource/SourceBufferList.h
@@ -74,16 +74,19 @@ public:
   void Ended();
 
   // Evicts data for the given time range from each SourceBuffer in the list.
   void Evict(double aStart, double aEnd);
 
   // Returns true if all SourceBuffers in the list contain data for the given time.
   bool AllContainsTime(double aTime);
 
+  // Returns the highest end time of any of the Sourcebuffers.
+  double GetHighestBufferedEndTime();
+
 private:
   ~SourceBufferList();
 
   friend class AsyncEventRunner<SourceBufferList>;
   void DispatchSimpleEvent(const char* aName);
   void QueueAsyncSimpleEvent(const char* aName);
 
   nsRefPtr<MediaSource> mMediaSource;