Bug 1199032: [webm] P1. Explicitly differentiate WebM usage for mediasource. r=kinetik a=ritu
authorJean-Yves Avenard <jyavenard@mozilla.com>
Fri, 28 Aug 2015 10:47:51 +1000
changeset 289193 495cdcba0ad4a5c6cbfc703a5e34fc7ed3bd9da8
parent 289192 2aab115ee83f7c1a4c3bcee2771a1fce2b4cf8c6
child 289194 0c0bfde2f006e612c873698c8e5cd4b879985aff
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
bugs1199032
milestone42.0a2
Bug 1199032: [webm] P1. Explicitly differentiate WebM usage for mediasource. r=kinetik a=ritu Relying on the data being fully buffered or not turned out to not be such a great idea.
dom/media/webm/WebMDemuxer.cpp
dom/media/webm/WebMDemuxer.h
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -36,33 +36,27 @@ extern PRLogModuleInfo* gNesteggLog;
 // Functions for reading and seeking using WebMDemuxer required for
 // nestegg_io. The 'user data' passed to these functions is the
 // demuxer.
 static int webmdemux_read(void* aBuffer, size_t aLength, void* aUserData)
 {
   MOZ_ASSERT(aUserData);
   MOZ_ASSERT(aLength < UINT32_MAX);
   WebMDemuxer* demuxer = reinterpret_cast<WebMDemuxer*>(aUserData);
-  int64_t length = demuxer->GetEndDataOffset();
   uint32_t count = aLength;
-  int64_t position = demuxer->GetResource()->Tell();
-  if (position >= length) {
-    // GetLastBlockOffset was calculated after we had read past it.
-    // This condition can only occurs with plain webm, as with MSE,
-    // EnsureUpdateIndex would have been called first.
-    // Continue reading to the end instead.
-    length = demuxer->GetResource()->GetLength();
+  if (demuxer->IsMediaSource()) {
+    int64_t length = demuxer->GetEndDataOffset();
+    int64_t position = demuxer->GetResource()->Tell();
+    MOZ_ASSERT(position <= demuxer->GetResource()->GetLength());
+    MOZ_ASSERT(position <= length);
+    if (length >= 0 && count + position > length) {
+      count = length - position;
+    }
+    MOZ_ASSERT(count <= aLength);
   }
-  MOZ_ASSERT(position <= demuxer->GetResource()->GetLength());
-  MOZ_ASSERT(position <= length);
-  if (length >= 0 && count + position > length) {
-    count = length - position;
-  }
-  MOZ_ASSERT(count <= aLength);
-
   uint32_t bytes = 0;
   nsresult rv =
     demuxer->GetResource()->Read(static_cast<char*>(aBuffer), count, &bytes);
   bool eof = bytes < aLength;
   return NS_FAILED(rv) ? -1 : eof ? 0 : 1;
 }
 
 static int webmdemux_seek(int64_t aOffset, int aWhence, void* aUserData)
@@ -119,32 +113,37 @@ static void webmdemux_log(nestegg* aCont
   PR_vsnprintf(msg+strlen(msg), sizeof(msg)-strlen(msg), aFormat, args);
   MOZ_LOG(gNesteggLog, LogLevel::Debug, (msg));
 
   va_end(args);
 }
 
 
 WebMDemuxer::WebMDemuxer(MediaResource* aResource)
+  : WebMDemuxer(aResource, false)
+{
+}
+
+WebMDemuxer::WebMDemuxer(MediaResource* aResource, bool aIsMediaSource)
   : mResource(aResource)
   , mBufferedState(nullptr)
   , mInitData(nullptr)
   , mContext(nullptr)
   , mVideoTrack(0)
   , mAudioTrack(0)
   , mSeekPreroll(0)
   , mLastAudioFrameTime(0)
   , mLastVideoFrameTime(0)
   , mAudioCodec(-1)
   , mVideoCodec(-1)
   , mHasVideo(false)
   , mHasAudio(false)
   , mNeedReIndex(true)
   , mLastWebMBlockOffset(-1)
-  , mIsExpectingMoreData(true)
+  , mIsMediaSource(aIsMediaSource)
 {
   if (!gNesteggLog) {
     gNesteggLog = PR_NewLogModule("Nestegg");
   }
 }
 
 WebMDemuxer::~WebMDemuxer()
 {
@@ -435,20 +434,23 @@ WebMDemuxer::EnsureUpToDateIndex()
   nsresult rv = resource->GetCachedRanges(byteRanges);
   if (NS_FAILED(rv) || !byteRanges.Length()) {
     return;
   }
   mBufferedState->UpdateIndex(byteRanges, resource);
   if (!mInitData && mBufferedState->GetInitEndOffset() != -1) {
     mInitData = mResource.MediaReadAt(0, mBufferedState->GetInitEndOffset());
   }
+  mNeedReIndex = false;
+
+  if (!mIsMediaSource) {
+    return;
+  }
   mLastWebMBlockOffset = mBufferedState->GetLastBlockOffset();
-  mIsExpectingMoreData = mResource.GetResource()->IsExpectingMoreData();
   MOZ_ASSERT(mLastWebMBlockOffset <= mResource.GetLength());
-  mNeedReIndex = false;
 }
 
 void
 WebMDemuxer::NotifyDataArrived(uint32_t aLength, int64_t aOffset)
 {
   WEBM_DEBUG("length: %ld offset: %ld", aLength, aOffset);
   mNeedReIndex = true;
 }
@@ -464,17 +466,19 @@ UniquePtr<EncryptionInfo>
 WebMDemuxer::GetCrypto()
 {
   return nullptr;
 }
 
 bool
 WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSamples)
 {
-  EnsureUpToDateIndex();
+  if (mIsMediaSource) {
+    EnsureUpToDateIndex();
+  }
 
   nsRefPtr<NesteggPacketHolder> holder(NextPacket(aType));
 
   if (!holder) {
     return false;
   }
 
   int r = 0;
--- a/dom/media/webm/WebMDemuxer.h
+++ b/dom/media/webm/WebMDemuxer.h
@@ -49,17 +49,20 @@ private:
 };
 
 class WebMTrackDemuxer;
 
 class WebMDemuxer : public MediaDataDemuxer
 {
 public:
   explicit WebMDemuxer(MediaResource* aResource);
-
+  // Indicate if the WebMDemuxer is to be used with MediaSource. In which
+  // case the demuxer will stop reads to the last known complete block.
+  WebMDemuxer(MediaResource* aResource, bool aIsMediaSource);
+  
   nsRefPtr<InitPromise> Init() override;
 
   already_AddRefed<MediaDataDemuxer> Clone() const override;
 
   bool HasTrackType(TrackInfo::TrackType aType) const override;
 
   uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override;
 
@@ -86,21 +89,25 @@ public:
   virtual void PushVideoPacket(NesteggPacketHolder* aItem);
 
   // Public accessor for nestegg callbacks
   MediaResourceIndex* GetResource()
   {
     return &mResource;
   }
 
-  int64_t GetEndDataOffset()
+  int64_t GetEndDataOffset() const
   {
-    return mLastWebMBlockOffset < 0 || mIsExpectingMoreData
+    return (!mIsMediaSource || mLastWebMBlockOffset < 0)
       ? mResource.GetLength() : mLastWebMBlockOffset;
   }
+  int64_t IsMediaSource() const
+  {
+    return mIsMediaSource;
+  }
 
 private:
   friend class WebMTrackDemuxer;
 
   ~WebMDemuxer();
   void Cleanup();
   nsresult InitBufferedState();
   nsresult ReadMetadata();
@@ -164,17 +171,17 @@ private:
   bool mHasVideo;
   bool mHasAudio;
   bool mNeedReIndex;
 
   // The last complete block parsed by the WebMBufferedState. -1 if not set.
   // We cache those values rather than retrieving them for performance reasons
   // as nestegg only performs 1-byte read at a time.
   int64_t mLastWebMBlockOffset;
-  bool mIsExpectingMoreData;
+  const bool mIsMediaSource;
 };
 
 class WebMTrackDemuxer : public MediaTrackDemuxer
 {
 public:
   WebMTrackDemuxer(WebMDemuxer* aParent,
                   TrackInfo::TrackType aType,
                   uint32_t aTrackNumber);