1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_AppleVTDecoder_h 8 #define mozilla_AppleVTDecoder_h 9 10 #include <CoreFoundation/CFDictionary.h> // For CFDictionaryRef 11 #include <CoreMedia/CoreMedia.h> // For CMVideoFormatDescriptionRef 12 #include <VideoToolbox/VideoToolbox.h> // For VTDecompressionSessionRef 13 #include "PlatformDecoderModule.h" 14 #include "ReorderQueue.h" 15 #include "TimeUnits.h" 16 #include "mozilla/Atomics.h" 17 #include "mozilla/gfx/Types.h" 18 19 namespace mozilla { 20 21 DDLoggedTypeDeclNameAndBase(AppleVTDecoder, MediaDataDecoder); 22 23 class AppleVTDecoder : public MediaDataDecoder, 24 public DecoderDoctorLifeLogger<AppleVTDecoder> { 25 public: 26 AppleVTDecoder(const VideoInfo& aConfig, TaskQueue* aTaskQueue, 27 layers::ImageContainer* aImageContainer, 28 CreateDecoderParams::OptionSet aOptions); 29 30 class AppleFrameRef { 31 public: 32 media::TimeUnit decode_timestamp; 33 media::TimeUnit composition_timestamp; 34 media::TimeUnit duration; 35 int64_t byte_offset; 36 bool is_sync_point; 37 AppleFrameRef(const MediaRawData & aSample)38 explicit AppleFrameRef(const MediaRawData& aSample) 39 : decode_timestamp(aSample.mTimecode), 40 composition_timestamp(aSample.mTime), 41 duration(aSample.mDuration), 42 byte_offset(aSample.mOffset), 43 is_sync_point(aSample.mKeyframe) {} 44 }; 45 46 RefPtr<InitPromise> Init() override; 47 RefPtr<DecodePromise> Decode(MediaRawData* aSample) override; 48 RefPtr<DecodePromise> Drain() override; 49 RefPtr<FlushPromise> Flush() override; 50 RefPtr<ShutdownPromise> Shutdown() override; 51 void SetSeekThreshold(const media::TimeUnit& aTime) override; 52 IsHardwareAccelerated(nsACString & aFailureReason)53 bool IsHardwareAccelerated(nsACString& aFailureReason) const override { 54 return mIsHardwareAccelerated; 55 } 56 GetDescriptionName()57 nsCString GetDescriptionName() const override { 58 return mIsHardwareAccelerated 59 ? NS_LITERAL_CSTRING("apple hardware VT decoder") 60 : NS_LITERAL_CSTRING("apple software VT decoder"); 61 } 62 NeedsConversion()63 ConversionRequired NeedsConversion() const override { 64 return ConversionRequired::kNeedAVCC; 65 } 66 67 // Access from the taskqueue and the decoder's thread. 68 // OutputFrame is thread-safe. 69 void OutputFrame(CVPixelBufferRef aImage, AppleFrameRef aFrameRef); 70 void OnDecodeError(OSStatus aError); 71 72 private: 73 virtual ~AppleVTDecoder(); 74 RefPtr<FlushPromise> ProcessFlush(); 75 RefPtr<DecodePromise> ProcessDrain(); 76 void ProcessShutdown(); 77 void ProcessDecode(MediaRawData* aSample); 78 void MaybeResolveBufferedFrames(); 79 AssertOnTaskQueueThread()80 void AssertOnTaskQueueThread() { 81 MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); 82 } 83 84 AppleFrameRef* CreateAppleFrameRef(const MediaRawData* aSample); 85 CFDictionaryRef CreateOutputConfiguration(); 86 87 const RefPtr<MediaByteBuffer> mExtraData; 88 const uint32_t mPictureWidth; 89 const uint32_t mPictureHeight; 90 const uint32_t mDisplayWidth; 91 const uint32_t mDisplayHeight; 92 const gfx::YUVColorSpace mColorSpace; 93 const gfx::ColorRange mColorRange; 94 95 // Method to set up the decompression session. 96 MediaResult InitializeSession(); 97 nsresult WaitForAsynchronousFrames(); 98 CFDictionaryRef CreateDecoderSpecification(); 99 CFDictionaryRef CreateDecoderExtensions(); 100 101 const RefPtr<TaskQueue> mTaskQueue; 102 const uint32_t mMaxRefFrames; 103 const RefPtr<layers::ImageContainer> mImageContainer; 104 const bool mUseSoftwareImages; 105 106 // Set on reader/decode thread calling Flush() to indicate that output is 107 // not required and so input samples on mTaskQueue need not be processed. 108 // Cleared on mTaskQueue in ProcessDrain(). 109 Atomic<bool> mIsFlushing; 110 // Protects mReorderQueue and mPromise. 111 Monitor mMonitor; 112 ReorderQueue mReorderQueue; 113 MozMonitoredPromiseHolder<DecodePromise> mPromise; 114 115 // Decoded frame will be dropped if its pts is smaller than this 116 // value. It shold be initialized before Input() or after Flush(). So it is 117 // safe to access it in OutputFrame without protecting. 118 Maybe<media::TimeUnit> mSeekTargetThreshold; 119 120 CMVideoFormatDescriptionRef mFormat; 121 VTDecompressionSessionRef mSession; 122 Atomic<bool> mIsHardwareAccelerated; 123 }; 124 125 } // namespace mozilla 126 127 #endif // mozilla_AppleVTDecoder_h 128