author | Alfredo Yang <ayang@mozilla.com> |
Wed, 08 Jun 2016 10:59:57 +0800 | |
changeset 301061 | 8dd290590f9ee819ea90974f81e90e93aa4c5430 |
parent 301060 | 5133065436e28e7b0a1e686c54e05d0ab756addf |
child 301062 | a7334430aef015b0bb3644101ed0b2739c7d186f |
push id | 30325 |
push user | kwierso@gmail.com |
push date | Wed, 08 Jun 2016 23:17:01 +0000 |
treeherder | mozilla-central@051765f8237d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jya |
bugs | 1257107 |
milestone | 50.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
|
--- 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