Bug 1050652 - Implement GetEvictionOffset for WebM reader. r=cajbir
authorMatthew Gregan <kinetik@flim.org>
Sun, 10 Aug 2014 18:21:00 +1200
changeset 198993 1150a58d8b3a38cb15ce99ee53b036dfc33dcd6c
parent 198992 445f556f7a98e691670f99220e6e035a612bc09a
child 198994 71a31a3e83878458a5a6fc36909297259fabd3be
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerscajbir
bugs1050652
milestone34.0a1
Bug 1050652 - Implement GetEvictionOffset for WebM reader. r=cajbir
content/media/webm/WebMBufferedParser.cpp
content/media/webm/WebMBufferedParser.h
content/media/webm/WebMReader.cpp
content/media/webm/WebMReader.h
--- a/content/media/webm/WebMBufferedParser.cpp
+++ b/content/media/webm/WebMBufferedParser.cpp
@@ -221,29 +221,29 @@ bool WebMBufferedState::CalculateBuffere
   // normalized in the range [0,duration].
 
   *aStartTime = mTimeMapping[start].mTimecode;
   *aEndTime = mTimeMapping[end].mTimecode;
   *aEndTime += mTimeMapping[end].mTimecode - mTimeMapping[end - 1].mTimecode;
   return true;
 }
 
-bool WebMBufferedState::GetOffsetForTime(uint64_t aTime, int64_t* aOffset)
+bool WebMBufferedState::GetOffsetForTime(uint64_t aTime, int64_t* aOffset, enum OffsetType aType)
 {
   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   WebMTimeDataOffset result(0, 0, 0);
 
   for (uint32_t i = 0; i < mTimeMapping.Length(); ++i) {
     WebMTimeDataOffset o = mTimeMapping[i];
     if (o.mTimecode < aTime && o.mTimecode > result.mTimecode) {
       result = o;
     }
   }
 
-  *aOffset = result.mOffset;
+  *aOffset = aType == CLUSTER_START ? result.mSyncOffset : result.mOffset;
   return true;
 }
 
 void WebMBufferedState::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   uint32_t idx = mRangeParsers.IndexOfFirstElementGt(aOffset - 1);
   if (idx == 0 || !(mRangeParsers[idx-1] == aOffset)) {
--- a/content/media/webm/WebMBufferedParser.h
+++ b/content/media/webm/WebMBufferedParser.h
@@ -195,17 +195,21 @@ class WebMBufferedState MOZ_FINAL
 public:
   WebMBufferedState() : mReentrantMonitor("WebMBufferedState") {
     MOZ_COUNT_CTOR(WebMBufferedState);
   }
 
   void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
   bool CalculateBufferedForRange(int64_t aStartOffset, int64_t aEndOffset,
                                  uint64_t* aStartTime, uint64_t* aEndTime);
-  bool GetOffsetForTime(uint64_t aTime, int64_t* aOffset);
+  enum OffsetType {
+    CLUSTER_START,
+    BLOCK_START
+  };
+  bool GetOffsetForTime(uint64_t aTime, int64_t* aOffset, enum OffsetType aType);
 
 private:
   // Private destructor, to discourage deletion outside of Release():
   ~WebMBufferedState() {
     MOZ_COUNT_DTOR(WebMBufferedState);
   }
 
   // Synchronizes access to the mTimeMapping array.
--- a/content/media/webm/WebMReader.cpp
+++ b/content/media/webm/WebMReader.cpp
@@ -986,17 +986,17 @@ bool WebMReader::DecodeVideoFrame(bool &
 
 void
 WebMReader::PushVideoPacket(NesteggPacketHolder* aItem)
 {
     mVideoPackets.PushFront(aItem);
 }
 
 nsresult WebMReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime,
-                            int64_t aCurrentTime)
+                          int64_t aCurrentTime)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   LOG(PR_LOG_DEBUG, ("Reader [%p] for Decoder [%p]: About to seek to %fs",
                      this, mDecoder, aTarget/1000000.0));
   if (NS_FAILED(ResetDecode())) {
     return NS_ERROR_FAILURE;
   }
@@ -1004,17 +1004,18 @@ nsresult WebMReader::Seek(int64_t aTarge
   uint64_t target = aTarget * NS_PER_USEC;
   if (mSeekPreroll) {
     target = std::max(static_cast<uint64_t>(aStartTime * NS_PER_USEC), target - mSeekPreroll);
   }
   int r = nestegg_track_seek(mContext, trackToSeek, target);
   if (r != 0) {
     // Try seeking directly based on cluster information in memory.
     int64_t offset = 0;
-    bool rv = mBufferedState->GetOffsetForTime((aTarget - aStartTime)/NS_PER_USEC, &offset);
+    bool rv = mBufferedState->GetOffsetForTime((aTarget - aStartTime)/NS_PER_USEC, &offset,
+                                               WebMBufferedState::CLUSTER_START);
     if (!rv) {
       return NS_ERROR_FAILURE;
     }
 
     r = nestegg_offset_seek(mContext, offset);
     if (r != 0) {
       return NS_ERROR_FAILURE;
     }
@@ -1076,9 +1077,20 @@ nsresult WebMReader::GetBuffered(dom::Ti
   return NS_OK;
 }
 
 void WebMReader::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset)
 {
   mBufferedState->NotifyDataArrived(aBuffer, aLength, aOffset);
 }
 
+int64_t WebMReader::GetEvictionOffset(double aTime)
+{
+  int64_t offset;
+  if (!mBufferedState->GetOffsetForTime(aTime / NS_PER_USEC, &offset,
+                                        WebMBufferedState::CLUSTER_START)) {
+    return -1;
+  }
+
+  return offset;
+}
+
 } // namespace mozilla
--- a/content/media/webm/WebMReader.h
+++ b/content/media/webm/WebMReader.h
@@ -132,16 +132,17 @@ public:
     return mHasVideo;
   }
 
   virtual nsresult ReadMetadata(MediaInfo* aInfo,
                                 MetadataTags** aTags);
   virtual nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
   virtual nsresult GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime);
   virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
+  virtual int64_t GetEvictionOffset(double aTime);
 
   virtual bool IsMediaSeekable() MOZ_OVERRIDE;
 
 protected:
   // Value passed to NextPacket to determine if we are reading a video or an
   // audio packet.
   enum TrackType {
     VIDEO = 0,