Bug 1199878: [webm] P2. Hold on frames for which the duration can't be known or estimated. r=kinetik a=sledru
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 01 Sep 2015 10:47:07 +1200
changeset 289201 07fc25608e50adaba4422e6a2c51cd1ca1220ac5
parent 289200 f34fb4e7d1525e76e8dc46cfc046615aed080d63
child 289202 7437f28133fc6679c1de658c50d3a13b86b852b7
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, sledru
bugs1199878
milestone42.0a2
Bug 1199878: [webm] P2. Hold on frames for which the duration can't be known or estimated. r=kinetik a=sledru
dom/media/webm/WebMDemuxer.cpp
dom/media/webm/WebMDemuxer.h
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -126,18 +126,16 @@ WebMDemuxer::WebMDemuxer(MediaResource* 
 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)
   , mIsMediaSource(aIsMediaSource)
 {
@@ -502,37 +500,47 @@ WebMDemuxer::GetNextPacket(TrackInfo::Tr
     return false;
   }
   int64_t tstamp = holder->Timestamp();
 
   // The end time of this frame is the start time of the next frame.  Fetch
   // the timestamp of the next packet for this track.  If we've reached the
   // end of the resource, use the file's duration as the end time of this
   // video frame.
-  int64_t next_tstamp = 0;
+  int64_t next_tstamp = INT64_MIN;
   if (aType == TrackInfo::kAudioTrack) {
     nsRefPtr<NesteggPacketHolder> next_holder(NextPacket(aType));
     if (next_holder) {
       next_tstamp = next_holder->Timestamp();
       PushAudioPacket(next_holder);
-    } else {
+    } else if (!mIsMediaSource ||
+               (mIsMediaSource && mLastAudioFrameTime.isSome())) {
       next_tstamp = tstamp;
-      next_tstamp += tstamp - mLastAudioFrameTime;
+      next_tstamp += tstamp - mLastAudioFrameTime.refOr(0);
+    } else {
+      PushAudioPacket(holder);
     }
-    mLastAudioFrameTime = tstamp;
+    mLastAudioFrameTime = Some(tstamp);
   } else if (aType == TrackInfo::kVideoTrack) {
     nsRefPtr<NesteggPacketHolder> next_holder(NextPacket(aType));
     if (next_holder) {
       next_tstamp = next_holder->Timestamp();
       PushVideoPacket(next_holder);
-    } else {
+    } else if (!mIsMediaSource ||
+               (mIsMediaSource && mLastVideoFrameTime.isSome())) {
       next_tstamp = tstamp;
-      next_tstamp += tstamp - mLastVideoFrameTime;
+      next_tstamp += tstamp - mLastVideoFrameTime.refOr(0);
+    } else {
+      PushVideoPacket(holder);
     }
-    mLastVideoFrameTime = tstamp;
+    mLastVideoFrameTime = Some(tstamp);
+  }
+
+  if (mIsMediaSource && next_tstamp == INT64_MIN) {
+    return false;
   }
 
   int64_t discardPadding = 0;
   (void) nestegg_packet_discard_padding(holder->Packet(), &discardPadding);
 
   for (uint32_t i = 0; i < count; ++i) {
     unsigned char* data;
     size_t length;
@@ -652,17 +660,17 @@ WebMDemuxer::DemuxPacket()
 }
 
 int64_t
 WebMDemuxer::GetNextKeyframeTime()
 {
   EnsureUpToDateIndex();
   uint64_t keyframeTime;
   uint64_t lastFrame =
-    media::TimeUnit::FromMicroseconds(mLastVideoFrameTime).ToNanoseconds();
+    media::TimeUnit::FromMicroseconds(mLastVideoFrameTime.refOr(0)).ToNanoseconds();
   if (!mBufferedState->GetNextKeyframeTime(lastFrame, &keyframeTime) ||
       keyframeTime <= lastFrame) {
     return -1;
   }
   return media::TimeUnit::FromNanoseconds(keyframeTime).ToMicroseconds();
 }
 
 void
@@ -720,18 +728,18 @@ WebMDemuxer::SeekInternal(const media::T
     r = nestegg_offset_seek(mContext, offset);
     if (r == -1) {
       WEBM_DEBUG("and nestegg_offset_seek to %" PRIu64 " failed", offset);
       return NS_ERROR_FAILURE;
     }
     WEBM_DEBUG("got offset from buffered state: %" PRIu64 "", offset);
   }
 
-  mLastAudioFrameTime = 0;
-  mLastVideoFrameTime = 0;
+  mLastAudioFrameTime.reset();
+  mLastVideoFrameTime.reset();
 
   return NS_OK;
 }
 
 media::TimeIntervals
 WebMDemuxer::GetBuffered()
 {
   EnsureUpToDateIndex();
--- a/dom/media/webm/WebMDemuxer.h
+++ b/dom/media/webm/WebMDemuxer.h
@@ -151,21 +151,20 @@ private:
   uint32_t mAudioTrack;
 
   // Number of microseconds that must be discarded from the start of the Stream.
   uint64_t mCodecDelay;
 
   // Nanoseconds to discard after seeking.
   uint64_t mSeekPreroll;
 
-  int64_t mLastAudioFrameTime;
-
   // Calculate the frame duration from the last decodeable frame using the
   // previous frame's timestamp.  In NS.
-  int64_t mLastVideoFrameTime;
+  Maybe<int64_t> mLastAudioFrameTime;
+  Maybe<int64_t> mLastVideoFrameTime;
 
   // Codec ID of audio track
   int mAudioCodec;
   // Codec ID of video track
   int mVideoCodec;
 
   // Booleans to indicate if we have audio and/or video data
   bool mHasVideo;