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 #if !defined(HLSDemuxer_h_)
8 #  define HLSDemuxer_h_
9 
10 #  include "MediaCodec.h"
11 #  include "MediaDataDemuxer.h"
12 #  include "MediaDecoder.h"
13 #  include "mozilla/Atomics.h"
14 #  include "mozilla/java/GeckoHLSDemuxerWrapperWrappers.h"
15 #  include "mozilla/java/GeckoHLSSampleWrappers.h"
16 #  include "mozilla/Maybe.h"
17 #  include "mozilla/Mutex.h"
18 #  include "mozilla/TaskQueue.h"
19 
20 #  include "VideoUtils.h"
21 
22 namespace mozilla {
23 
24 class AbstractThread;
25 class MediaResult;
26 class HLSTrackDemuxer;
27 
28 DDLoggedTypeDeclNameAndBase(HLSDemuxer, MediaDataDemuxer);
29 DDLoggedTypeNameAndBase(HLSTrackDemuxer, MediaTrackDemuxer);
30 
31 class HLSDemuxer final : public MediaDataDemuxer,
32                          public DecoderDoctorLifeLogger<HLSDemuxer> {
33   class HLSDemuxerCallbacksSupport;
34 
35  public:
36   explicit HLSDemuxer(int aPlayerId);
37 
38   RefPtr<InitPromise> Init() override;
39 
40   uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override;
41 
42   already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(
43       TrackInfo::TrackType aType, uint32_t aTrackNumber) override;
44 
45   bool IsSeekable() const override;
46 
47   UniquePtr<EncryptionInfo> GetCrypto() override;
48 
ShouldComputeStartTime()49   bool ShouldComputeStartTime() const override { return true; }
50 
51   void NotifyDataArrived() override;
52 
GetTaskQueue()53   TaskQueue* GetTaskQueue() const { return mTaskQueue; }
54   void OnInitialized(bool aHasAudio, bool aHasVideo);
55   void OnError(int aErrorCode);
56 
57  private:
58   media::TimeUnit GetNextKeyFrameTime();
59 
60   bool OnTaskQueue() const;
61   ~HLSDemuxer();
62   friend class HLSTrackDemuxer;
63 
64   const RefPtr<TaskQueue> mTaskQueue;
65   RefPtr<HLSTrackDemuxer> mAudioDemuxer;
66   RefPtr<HLSTrackDemuxer> mVideoDemuxer;
67 
68   MozPromiseHolder<InitPromise> mInitPromise;
69   RefPtr<HLSDemuxerCallbacksSupport> mCallbackSupport;
70 
71   java::GeckoHLSDemuxerWrapper::Callbacks::GlobalRef mJavaCallbacks;
72   java::GeckoHLSDemuxerWrapper::GlobalRef mHLSDemuxerWrapper;
73 };
74 
75 class HLSTrackDemuxer : public MediaTrackDemuxer,
76                         public DecoderDoctorLifeLogger<HLSTrackDemuxer> {
77  public:
78   HLSTrackDemuxer(HLSDemuxer* aParent, TrackInfo::TrackType aType,
79                   UniquePtr<TrackInfo> aTrackInfo);
80   ~HLSTrackDemuxer();
81   UniquePtr<TrackInfo> GetInfo() const override;
82 
83   RefPtr<SeekPromise> Seek(const media::TimeUnit& aTime) override;
84 
85   RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) override;
86 
87   void UpdateMediaInfo(int index);
88 
89   void Reset() override;
90 
91   nsresult GetNextRandomAccessPoint(media::TimeUnit* aTime) override;
92 
93   RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint(
94       const media::TimeUnit& aTimeThreshold) override;
95 
96   media::TimeIntervals GetBuffered() override;
97 
98   void BreakCycles() override;
99 
GetSamplesMayBlock()100   bool GetSamplesMayBlock() const override { return false; }
101 
IsTrackValid()102   bool IsTrackValid() const {
103     MutexAutoLock lock(mMutex);
104     return mTrackInfo->IsValid();
105   }
106 
107  private:
108   // Update the timestamp of the next keyframe if there's one.
109   void UpdateNextKeyFrameTime();
110 
111   // Runs on HLSDemuxer's task queue.
112   RefPtr<SeekPromise> DoSeek(const media::TimeUnit& aTime);
113   RefPtr<SamplesPromise> DoGetSamples(int32_t aNumSamples);
114   RefPtr<SkipAccessPointPromise> DoSkipToNextRandomAccessPoint(
115       const media::TimeUnit& aTimeThreshold);
116 
117   CryptoSample ExtractCryptoSample(size_t aSampleSize,
118                                    java::sdk::CryptoInfo::LocalRef aCryptoInfo);
119   RefPtr<MediaRawData> ConvertToMediaRawData(
120       java::GeckoHLSSample::LocalRef aSample);
121 
122   RefPtr<HLSDemuxer> mParent;
123   TrackInfo::TrackType mType;
124   Maybe<media::TimeUnit> mNextKeyframeTime;
125   int32_t mLastFormatIndex = -1;
126   // Queued samples extracted by the demuxer, but not yet returned.
127   RefPtr<MediaRawData> mQueuedSample;
128 
129   // Mutex to protect members below across multiple threads.
130   mutable Mutex mMutex;
131   UniquePtr<TrackInfo> mTrackInfo;
132 };
133 
134 }  // namespace mozilla
135 
136 #endif
137