/* -*- 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/. */ #if !defined(HLSDemuxer_h_) # define HLSDemuxer_h_ # include "MediaCodec.h" # include "MediaDataDemuxer.h" # include "MediaDecoder.h" # include "mozilla/Atomics.h" # include "mozilla/java/GeckoHLSDemuxerWrapperWrappers.h" # include "mozilla/java/GeckoHLSSampleWrappers.h" # include "mozilla/Maybe.h" # include "mozilla/Mutex.h" # include "mozilla/TaskQueue.h" # include "VideoUtils.h" namespace mozilla { class AbstractThread; class MediaResult; class HLSTrackDemuxer; DDLoggedTypeDeclNameAndBase(HLSDemuxer, MediaDataDemuxer); DDLoggedTypeNameAndBase(HLSTrackDemuxer, MediaTrackDemuxer); class HLSDemuxer final : public MediaDataDemuxer, public DecoderDoctorLifeLogger { class HLSDemuxerCallbacksSupport; public: explicit HLSDemuxer(int aPlayerId); RefPtr Init() override; uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override; already_AddRefed GetTrackDemuxer( TrackInfo::TrackType aType, uint32_t aTrackNumber) override; bool IsSeekable() const override; UniquePtr GetCrypto() override; bool ShouldComputeStartTime() const override { return true; } void NotifyDataArrived() override; TaskQueue* GetTaskQueue() const { return mTaskQueue; } void OnInitialized(bool aHasAudio, bool aHasVideo); void OnError(int aErrorCode); private: media::TimeUnit GetNextKeyFrameTime(); bool OnTaskQueue() const; ~HLSDemuxer(); friend class HLSTrackDemuxer; const RefPtr mTaskQueue; RefPtr mAudioDemuxer; RefPtr mVideoDemuxer; MozPromiseHolder mInitPromise; RefPtr mCallbackSupport; java::GeckoHLSDemuxerWrapper::Callbacks::GlobalRef mJavaCallbacks; java::GeckoHLSDemuxerWrapper::GlobalRef mHLSDemuxerWrapper; }; class HLSTrackDemuxer : public MediaTrackDemuxer, public DecoderDoctorLifeLogger { public: HLSTrackDemuxer(HLSDemuxer* aParent, TrackInfo::TrackType aType, UniquePtr aTrackInfo); ~HLSTrackDemuxer(); UniquePtr GetInfo() const override; RefPtr Seek(const media::TimeUnit& aTime) override; RefPtr GetSamples(int32_t aNumSamples = 1) override; void UpdateMediaInfo(int index); void Reset() override; nsresult GetNextRandomAccessPoint(media::TimeUnit* aTime) override; RefPtr SkipToNextRandomAccessPoint( const media::TimeUnit& aTimeThreshold) override; media::TimeIntervals GetBuffered() override; void BreakCycles() override; bool GetSamplesMayBlock() const override { return false; } bool IsTrackValid() const { MutexAutoLock lock(mMutex); return mTrackInfo->IsValid(); } private: // Update the timestamp of the next keyframe if there's one. void UpdateNextKeyFrameTime(); // Runs on HLSDemuxer's task queue. RefPtr DoSeek(const media::TimeUnit& aTime); RefPtr DoGetSamples(int32_t aNumSamples); RefPtr DoSkipToNextRandomAccessPoint( const media::TimeUnit& aTimeThreshold); CryptoSample ExtractCryptoSample(size_t aSampleSize, java::sdk::CryptoInfo::LocalRef aCryptoInfo); RefPtr ConvertToMediaRawData( java::GeckoHLSSample::LocalRef aSample); RefPtr mParent; TrackInfo::TrackType mType; Maybe mNextKeyframeTime; int32_t mLastFormatIndex = -1; // Queued samples extracted by the demuxer, but not yet returned. RefPtr mQueuedSample; // Mutex to protect members below across multiple threads. mutable Mutex mMutex; UniquePtr mTrackInfo; }; } // namespace mozilla #endif