Bug 1257107 - set video seek thresohld on mac PDM. r=jya
authorAlfredo Yang <ayang@mozilla.com>
Wed, 08 Jun 2016 10:59:57 +0800
changeset 301061 8dd290590f9ee819ea90974f81e90e93aa4c5430
parent 301060 5133065436e28e7b0a1e686c54e05d0ab756addf
child 301062 a7334430aef015b0bb3644101ed0b2739c7d186f
push id30325
push userkwierso@gmail.com
push dateWed, 08 Jun 2016 23:17:01 +0000
treeherdermozilla-central@051765f8237d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1257107
milestone50.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 1257107 - set video seek thresohld on mac PDM. r=jya MozReview-Commit-ID: 1nlO0cyXBEb
dom/media/platforms/apple/AppleVDADecoder.cpp
dom/media/platforms/apple/AppleVDADecoder.h
dom/media/platforms/apple/ReorderQueue.h
--- a/dom/media/platforms/apple/AppleVDADecoder.cpp
+++ b/dom/media/platforms/apple/AppleVDADecoder.cpp
@@ -148,16 +148,19 @@ AppleVDADecoder::Flush()
   MOZ_ASSERT(mCallback->OnReaderTaskQueue());
   mIsFlushing = true;
   nsCOMPtr<nsIRunnable> runnable =
     NewRunnableMethod(this, &AppleVDADecoder::ProcessFlush);
   SyncRunnable::DispatchToThread(mTaskQueue, runnable);
   mIsFlushing = false;
   // All ProcessDecode() tasks should be done.
   MOZ_ASSERT(mInputIncoming == 0);
+
+  mSeekTargetThreshold.reset();
+
   return NS_OK;
 }
 
 nsresult
 AppleVDADecoder::Drain()
 {
   MOZ_ASSERT(mCallback->OnReaderTaskQueue());
   nsCOMPtr<nsIRunnable> runnable =
@@ -285,16 +288,23 @@ AppleVDADecoder::ClearReorderedFrames()
 {
   MonitorAutoLock mon(mMonitor);
   while (!mReorderQueue.IsEmpty()) {
     mReorderQueue.Pop();
   }
   mQueuedSamples = 0;
 }
 
+void
+AppleVDADecoder::SetSeekThreshold(const media::TimeUnit& aTime)
+{
+  LOG("SetSeekThreshold %lld", aTime.ToMicroseconds());
+  mSeekTargetThreshold = Some(aTime);
+}
+
 // Copy and return a decoded frame.
 nsresult
 AppleVDADecoder::OutputFrame(CVPixelBufferRef aImage,
                              AppleVDADecoder::AppleFrameRef aFrameRef)
 {
   if (mIsShutDown || mIsFlushing) {
     // We are in the process of flushing or shutting down; ignore frame.
     return NS_OK;
@@ -316,27 +326,40 @@ AppleVDADecoder::OutputFrame(CVPixelBuff
   MOZ_ASSERT(mQueuedSamples);
   mQueuedSamples--;
 
   if (!aImage) {
     // Image was dropped by decoder.
     return NS_OK;
   }
 
+  bool useNullSample = false;
+  if (mSeekTargetThreshold.isSome()) {
+    if ((aFrameRef.composition_timestamp + aFrameRef.duration) < mSeekTargetThreshold.ref()) {
+      useNullSample = true;
+    } else {
+      mSeekTargetThreshold.reset();
+    }
+  }
+
   // Where our resulting image will end up.
-  RefPtr<VideoData> data;
+  RefPtr<MediaData> data;
   // Bounds.
   VideoInfo info;
   info.mDisplay = nsIntSize(mDisplayWidth, mDisplayHeight);
   gfx::IntRect visible = gfx::IntRect(0,
                                       0,
                                       mPictureWidth,
                                       mPictureHeight);
 
-  if (mUseSoftwareImages) {
+  if (useNullSample) {
+    data = new NullData(aFrameRef.byte_offset,
+                        aFrameRef.composition_timestamp.ToMicroseconds(),
+                        aFrameRef.duration.ToMicroseconds());
+  } else if (mUseSoftwareImages) {
     size_t width = CVPixelBufferGetWidth(aImage);
     size_t height = CVPixelBufferGetHeight(aImage);
     DebugOnly<size_t> planes = CVPixelBufferGetPlaneCount(aImage);
     MOZ_ASSERT(planes == 2, "Likely not NV12 format and it must be.");
 
     VideoData::YCbCrBuffer buffer;
 
     // Lock the returned image data.
--- a/dom/media/platforms/apple/AppleVDADecoder.h
+++ b/dom/media/platforms/apple/AppleVDADecoder.h
@@ -81,16 +81,18 @@ public:
     return true;
   }
 
   const char* GetDescriptionName() const override
   {
     return "apple VDA decoder";
   }
 
+  void SetSeekThreshold(const media::TimeUnit& aTime) override;
+
 protected:
   AppleVDADecoder(const VideoInfo& aConfig,
                   TaskQueue* aTaskQueue,
                   MediaDataDecoderCallback* aCallback,
                   layers::ImageContainer* aImageContainer);
   virtual ~AppleVDADecoder();
 
   void AssertOnTaskQueueThread()
@@ -134,16 +136,20 @@ private:
 
   // Protects mReorderQueue.
   Monitor mMonitor;
   // Set on reader/decode thread calling Flush() to indicate that output is
   // not required and so input samples on mTaskQueue need not be processed.
   // Cleared on mTaskQueue in ProcessDrain().
   Atomic<bool> mIsFlushing;
   ReorderQueue mReorderQueue;
+  // Decoded frame will be dropped if its pts is smaller than this
+  // value. It shold be initialized before Input() or after Flush(). So it is
+  // safe to access it in OutputFrame without protecting.
+  Maybe<media::TimeUnit> mSeekTargetThreshold;
 
   // Method to set up the decompression session.
   nsresult InitializeSession();
 
   // Method to pass a frame to VideoToolbox for decoding.
   nsresult ProcessDecode(MediaRawData* aSample);
   virtual nsresult DoDecode(MediaRawData* aSample);
   CFDictionaryRef CreateDecoderSpecification();
--- a/dom/media/platforms/apple/ReorderQueue.h
+++ b/dom/media/platforms/apple/ReorderQueue.h
@@ -11,19 +11,19 @@
 
 #include <MediaData.h>
 #include <nsTPriorityQueue.h>
 
 namespace mozilla {
 
 struct ReorderQueueComparator
 {
-  bool LessThan(VideoData* const& a, VideoData* const& b) const
+  bool LessThan(MediaData* const& a, MediaData* const& b) const
   {
     return a->mTime < b->mTime;
   }
 };
 
-typedef nsTPriorityQueue<RefPtr<VideoData>, ReorderQueueComparator> ReorderQueue;
+typedef nsTPriorityQueue<RefPtr<MediaData>, ReorderQueueComparator> ReorderQueue;
 
 } // namespace mozilla
 
 #endif // mozilla_ReorderQueue_h