Bug 1257107: set video seek thresohld on mac PDM. r=jya
MozReview-Commit-ID: 1nlO0cyXBEb
--- 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
@@ -82,16 +82,18 @@ private:
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()
@@ -135,16 +137,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