/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_AppleVTDecoder_h #define mozilla_AppleVTDecoder_h #include // For CFDictionaryRef #include // For CMVideoFormatDescriptionRef #include // For VTDecompressionSessionRef #include "PlatformDecoderModule.h" #include "ReorderQueue.h" #include "TimeUnits.h" #include "mozilla/Atomics.h" #include "mozilla/gfx/Types.h" #include "nsIThread.h" namespace mozilla { DDLoggedTypeDeclNameAndBase(AppleVTDecoder, MediaDataDecoder); class AppleVTDecoder : public MediaDataDecoder, public DecoderDoctorLifeLogger { public: AppleVTDecoder(const VideoInfo& aConfig, TaskQueue* aTaskQueue, layers::ImageContainer* aImageContainer, CreateDecoderParams::OptionSet aOptions); class AppleFrameRef { public: media::TimeUnit decode_timestamp; media::TimeUnit composition_timestamp; media::TimeUnit duration; int64_t byte_offset; bool is_sync_point; explicit AppleFrameRef(const MediaRawData& aSample) : decode_timestamp(aSample.mTimecode), composition_timestamp(aSample.mTime), duration(aSample.mDuration), byte_offset(aSample.mOffset), is_sync_point(aSample.mKeyframe) {} }; RefPtr Init() override; RefPtr Decode(MediaRawData* aSample) override; RefPtr Drain() override; RefPtr Flush() override; RefPtr Shutdown() override; void SetSeekThreshold(const media::TimeUnit& aTime) override; bool IsHardwareAccelerated(nsACString& aFailureReason) const override { return mIsHardwareAccelerated; } nsCString GetDescriptionName() const override { return mIsHardwareAccelerated ? NS_LITERAL_CSTRING("apple hardware VT decoder") : NS_LITERAL_CSTRING("apple software VT decoder"); } ConversionRequired NeedsConversion() const override { return ConversionRequired::kNeedAVCC; } // Access from the taskqueue and the decoder's thread. // OutputFrame is thread-safe. void OutputFrame(CVPixelBufferRef aImage, AppleFrameRef aFrameRef); private: virtual ~AppleVTDecoder(); RefPtr ProcessFlush(); RefPtr ProcessDrain(); void ProcessShutdown(); void ProcessDecode(MediaRawData* aSample); void AssertOnTaskQueueThread() { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); } AppleFrameRef* CreateAppleFrameRef(const MediaRawData* aSample); CFDictionaryRef CreateOutputConfiguration(); const RefPtr mExtraData; const uint32_t mPictureWidth; const uint32_t mPictureHeight; const uint32_t mDisplayWidth; const uint32_t mDisplayHeight; const gfx::YUVColorSpace mColorSpace; // Method to set up the decompression session. MediaResult InitializeSession(); nsresult WaitForAsynchronousFrames(); CFDictionaryRef CreateDecoderSpecification(); CFDictionaryRef CreateDecoderExtensions(); const RefPtr mTaskQueue; const uint32_t mMaxRefFrames; const RefPtr mImageContainer; const bool mUseSoftwareImages; // 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 mIsFlushing; // Protects mReorderQueue and mPromise. Monitor mMonitor; ReorderQueue mReorderQueue; MozPromiseHolder mPromise; // 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 mSeekTargetThreshold; CMVideoFormatDescriptionRef mFormat; VTDecompressionSessionRef mSession; Atomic mIsHardwareAccelerated; }; } // namespace mozilla #endif // mozilla_AppleVTDecoder_h