Bug 1194884: [webm] P1. Use MediaResourceIndex. r=j^ a=sylvestre
authorJean-Yves Avenard <jyavenard@mozilla.com>
Sun, 16 Aug 2015 00:49:46 +1000
changeset 288811 91624ae2b989b83ff3a80a5fba8b8c6fa451f5ac
parent 288810 eb7622882d750ae1923fe1160ca50ef1ae7cc425
child 288812 2bac25974183b0b48faf5513d4de2ef124dfefec
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)
reviewersj, sylvestre
bugs1194884
milestone42.0a2
Bug 1194884: [webm] P1. Use MediaResourceIndex. r=j^ a=sylvestre Remove duplicated code.
dom/media/webm/WebMDemuxer.cpp
dom/media/webm/WebMDemuxer.h
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -13,57 +13,67 @@
 #include "gfx2DGlue.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/SharedThreadPool.h"
 #include "MediaDataDemuxer.h"
 #include "nsAutoRef.h"
 #include "NesteggPacketHolder.h"
 
 #include <algorithm>
+#include <stdint.h>
 
 #define VPX_DONT_DEFINE_STDINT_TYPES
 #include "vpx/vp8dx.h"
 #include "vpx/vpx_decoder.h"
 
 #define WEBM_DEBUG(arg, ...) MOZ_LOG(gMediaDecoderLog, mozilla::LogLevel::Debug, ("WebMDemuxer(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 
 namespace mozilla {
 
 using namespace gfx;
 
 extern PRLogModuleInfo* gMediaDecoderLog;
 extern PRLogModuleInfo* gNesteggLog;
 
 // Functions for reading and seeking using WebMDemuxer required for
-// nestegg_io. The 'user data' passed to these functions is the demuxer
+// nestegg_io. The 'user data' passed to these functions is the
+// demuxer's MediaResourceIndex
 static int webmdemux_read(void* aBuffer, size_t aLength, void* aUserData)
 {
   MOZ_ASSERT(aUserData);
-  WebMDemuxer* demuxer = reinterpret_cast<WebMDemuxer*>(aUserData);
+  MediaResourceIndex* resource =
+    reinterpret_cast<MediaResourceIndex*>(aUserData);
+  int64_t length = resource->GetLength();
+  MOZ_ASSERT(aLength < UINT32_MAX);
+  uint32_t count = aLength;
+  if (length >= 0 && count + resource->Tell() > length) {
+    count = uint32_t(length - resource->Tell());
+  }
+
   uint32_t bytes = 0;
-  bool eof = false;
-  char* p = static_cast<char*>(aBuffer);
-  nsresult rv = demuxer->Read(p, aLength, &bytes);
-  eof = bytes < aLength;
+  nsresult rv = resource->Read(static_cast<char*>(aBuffer), count, &bytes);
+  bool eof = !bytes;
   return NS_FAILED(rv) ? -1 : eof ? 0 : 1;
 }
 
 static int webmdemux_seek(int64_t aOffset, int aWhence, void* aUserData)
 {
   MOZ_ASSERT(aUserData);
-  WebMDemuxer* demuxer = reinterpret_cast<WebMDemuxer*>(aUserData);
-  nsresult rv = demuxer->Seek(aWhence, aOffset);
+  MediaResourceIndex* resource =
+    reinterpret_cast<MediaResourceIndex*>(aUserData);
+  nsresult rv = resource->Seek(aWhence, aOffset);
   return NS_SUCCEEDED(rv) ? 0 : -1;
 }
 
 static int64_t webmdemux_tell(void* aUserData)
 {
   MOZ_ASSERT(aUserData);
-  WebMDemuxer* demuxer = reinterpret_cast<WebMDemuxer*>(aUserData);
-  return demuxer->Tell();
+  MediaResourceIndex* resource =
+    reinterpret_cast<MediaResourceIndex*>(aUserData);
+  return resource->Tell();
 }
 
 static void webmdemux_log(nestegg* aContext,
                           unsigned int aSeverity,
                           char const* aFormat, ...)
 {
   if (!MOZ_LOG_TEST(gNesteggLog, LogLevel::Debug)) {
     return;
@@ -104,17 +114,16 @@ static void webmdemux_log(nestegg* aCont
 }
 
 
 WebMDemuxer::WebMDemuxer(MediaResource* aResource)
   : mResource(aResource)
   , mBufferedState(nullptr)
   , mInitData(nullptr)
   , mContext(nullptr)
-  , mOffset(0)
   , mVideoTrack(0)
   , mAudioTrack(0)
   , mSeekPreroll(0)
   , mLastVideoFrameTime(0)
   , mAudioCodec(-1)
   , mVideoCodec(-1)
   , mHasVideo(false)
   , mHasAudio(false)
@@ -157,17 +166,17 @@ WebMDemuxer::InitBufferedState()
   }
   EnsureUpToDateIndex();
   return NS_OK;
 }
 
 already_AddRefed<MediaDataDemuxer>
 WebMDemuxer::Clone() const
 {
-  nsRefPtr<WebMDemuxer> demuxer = new WebMDemuxer(mResource);
+  nsRefPtr<WebMDemuxer> demuxer = new WebMDemuxer(mResource.GetResource());
   demuxer->mInitData = mInitData;
   if (demuxer->InitBufferedState() != NS_OK ||
       demuxer->ReadMetadata() != NS_OK) {
     NS_WARNING("Couldn't recreate WebMDemuxer");
     return nullptr;
   }
   return demuxer.forget();
 }
@@ -238,20 +247,20 @@ WebMDemuxer::Cleanup()
 
 nsresult
 WebMDemuxer::ReadMetadata()
 {
   nestegg_io io;
   io.read = webmdemux_read;
   io.seek = webmdemux_seek;
   io.tell = webmdemux_tell;
-  io.userdata = this;
+  io.userdata = &mResource;
   int64_t maxOffset = mBufferedState->GetInitEndOffset();
   if (maxOffset == -1) {
-    maxOffset = mResource->GetLength();
+    maxOffset = mResource.GetLength();
   }
   int r = nestegg_init(&mContext, io, &webmdemux_log, maxOffset);
   if (r == -1) {
     return NS_ERROR_FAILURE;
   }
 
   unsigned int ntracks = 0;
   r = nestegg_track_count(mContext, &ntracks);
@@ -389,84 +398,40 @@ WebMDemuxer::ReadMetadata()
       if (!r) {
         mInfo.mAudio.mDuration = media::TimeUnit::FromNanoseconds(duration).ToMicroseconds();
       }
     }
   }
   return NS_OK;
 }
 
-nsresult
-WebMDemuxer::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
-{
-  int64_t length = mResource->GetLength();
-  if (length >= 0 && aCount + mOffset > length) {
-    WEBM_DEBUG("requested to large amount, trying to get %ld bytes at %ld (length: %ld)", aCount, mOffset, length);
-    aCount = length - mOffset;
-    WEBM_DEBUG("will only return %ld", aCount);
-  }
-  nsRefPtr<MediaByteBuffer> bytes = mResource->MediaReadAt(mOffset, aCount);
-  if (!bytes) {
-    return NS_ERROR_FAILURE;
-  }
-  mOffset += bytes->Length();
-  *aBytes = bytes->Length();
-  memcpy(aBuffer, bytes->Elements(), bytes->Length());
-  return NS_OK;
-}
-
-nsresult
-WebMDemuxer::Seek(int32_t aWhence, int64_t aOffset)
-{
-  if (aWhence == SEEK_CUR) {
-    aOffset += mOffset;
-  } else if (aWhence == SEEK_END) {
-    int64_t length = mResource->GetLength();
-    if (length == -1 || length - aOffset < 0) {
-      return NS_ERROR_FAILURE;
-    }
-    aOffset = mResource->GetLength() - aOffset;
-  }
-  if (aOffset > mResource->GetLength()) {
-    return NS_ERROR_FAILURE;
-  }
-  mOffset = aOffset;
-  return NS_OK;
-}
-
-int64_t
-WebMDemuxer::Tell()
-{
-  return mOffset;
-}
-
 bool
 WebMDemuxer::IsSeekable() const
 {
   return mContext && nestegg_has_cues(mContext);
 }
 
 void
 WebMDemuxer::EnsureUpToDateIndex()
 {
   if (!mNeedReIndex) {
     return;
   }
   if (mInitData && mBufferedState->GetInitEndOffset() == -1) {
     mBufferedState->NotifyDataArrived(mInitData->Elements(), mInitData->Length(), 0);
   }
-  AutoPinned<MediaResource> resource(mResource);
+  AutoPinned<MediaResource> resource(mResource.GetResource());
   nsTArray<MediaByteRange> byteRanges;
   nsresult rv = resource->GetCachedRanges(byteRanges);
   if (NS_FAILED(rv) || !byteRanges.Length()) {
     return;
   }
-  mBufferedState->UpdateIndex(byteRanges, mResource);
+  mBufferedState->UpdateIndex(byteRanges, resource);
   if (!mInitData && mBufferedState->GetInitEndOffset() != -1) {
-    mInitData = mResource->MediaReadAt(0, mBufferedState->GetInitEndOffset());
+    mInitData = mResource.MediaReadAt(0, mBufferedState->GetInitEndOffset());
   }
   mNeedReIndex = false;
 }
 
 void
 WebMDemuxer::NotifyDataArrived(uint32_t aLength, int64_t aOffset)
 {
   WEBM_DEBUG("length: %ld offset: %ld", aLength, aOffset);
@@ -637,17 +602,17 @@ WebMDemuxer::DemuxPacket()
   }
 
   unsigned int track = 0;
   r = nestegg_packet_track(packet, &track);
   if (r == -1) {
     return nullptr;
   }
 
-  int64_t offset = Tell();
+  int64_t offset = mResource.Tell();
   nsRefPtr<NesteggPacketHolder> holder = new NesteggPacketHolder();
   if (!holder->Init(packet, offset, track, false)) {
     return nullptr;
   }
 
   return holder;
 }
 
@@ -726,17 +691,17 @@ WebMDemuxer::SeekInternal(const media::T
   }
   return NS_OK;
 }
 
 media::TimeIntervals
 WebMDemuxer::GetBuffered()
 {
   EnsureUpToDateIndex();
-  AutoPinned<MediaResource> resource(mResource);
+  AutoPinned<MediaResource> resource(mResource.GetResource());
 
   media::TimeIntervals buffered;
 
   nsTArray<MediaByteRange> ranges;
   nsresult rv = resource->GetCachedRanges(ranges);
   if (NS_FAILED(rv)) {
     return media::TimeIntervals();
   }
--- a/dom/media/webm/WebMDemuxer.h
+++ b/dom/media/webm/WebMDemuxer.h
@@ -80,20 +80,16 @@ public:
   nsresult Reset();
 
   // Pushes a packet to the front of the audio packet queue.
   virtual void PushAudioPacket(NesteggPacketHolder* aItem);
 
   // Pushes a packet to the front of the video packet queue.
   virtual void PushVideoPacket(NesteggPacketHolder* aItem);
 
-  nsresult Read(char* aBuffer, uint32_t aCount, uint32_t * aBytes);
-  nsresult Seek(int32_t aWhence, int64_t aOffset);
-  int64_t Tell();
-
 private:
   friend class WebMTrackDemuxer;
 
   ~WebMDemuxer();
   void Cleanup();
   nsresult InitBufferedState();
   nsresult ReadMetadata();
   void NotifyDataArrived(uint32_t aLength, int64_t aOffset) override;
@@ -108,30 +104,29 @@ private:
   // the particular track have been read. Pass TrackInfo::kVideoTrack or
   // TrackInfo::kVideoTrack to indicate the type of the packet we want to read.
   nsRefPtr<NesteggPacketHolder> NextPacket(TrackInfo::TrackType aType);
 
   // Internal method that demuxes the next packet from the stream. The caller
   // is responsible for making sure it doesn't get lost.
   nsRefPtr<NesteggPacketHolder> DemuxPacket();
 
-  nsRefPtr<MediaResource> mResource;
+  MediaResourceIndex mResource;
   MediaInfo mInfo;
   nsTArray<nsRefPtr<WebMTrackDemuxer>> mDemuxers;
 
   // Parser state and computed offset-time mappings.  Shared by multiple
   // readers when decoder has been cloned.  Main thread only.
   nsRefPtr<WebMBufferedState> mBufferedState;
   nsRefPtr<MediaByteBuffer> mInitData;
 
   // libnestegg context for webm container.
   // Access on reader's thread for main demuxer,
   // or main thread for cloned demuxer
   nestegg* mContext;
-  int64_t mOffset;
 
   // Queue of video and audio packets that have been read but not decoded.
   WebMPacketQueue mVideoPackets;
   WebMPacketQueue mAudioPackets;
 
   // Index of video and audio track to play
   uint32_t mVideoTrack;
   uint32_t mAudioTrack;