summaryrefslogtreecommitdiffstats
path: root/dom/media/hls/HLSDemuxer.h
blob: 679faa759f89102f27e65119be280d5feca71305 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* -*- 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<HLSDemuxer> {
  class HLSDemuxerCallbacksSupport;

 public:
  explicit HLSDemuxer(int aPlayerId);

  RefPtr<InitPromise> Init() override;

  uint32_t GetNumberTracks(TrackInfo::TrackType aType) const override;

  already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(
      TrackInfo::TrackType aType, uint32_t aTrackNumber) override;

  bool IsSeekable() const override;

  UniquePtr<EncryptionInfo> 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<TaskQueue> mTaskQueue;
  RefPtr<HLSTrackDemuxer> mAudioDemuxer;
  RefPtr<HLSTrackDemuxer> mVideoDemuxer;

  MozPromiseHolder<InitPromise> mInitPromise;
  RefPtr<HLSDemuxerCallbacksSupport> mCallbackSupport;

  java::GeckoHLSDemuxerWrapper::Callbacks::GlobalRef mJavaCallbacks;
  java::GeckoHLSDemuxerWrapper::GlobalRef mHLSDemuxerWrapper;
};

class HLSTrackDemuxer : public MediaTrackDemuxer,
                        public DecoderDoctorLifeLogger<HLSTrackDemuxer> {
 public:
  HLSTrackDemuxer(HLSDemuxer* aParent, TrackInfo::TrackType aType,
                  UniquePtr<TrackInfo> aTrackInfo);
  ~HLSTrackDemuxer();
  UniquePtr<TrackInfo> GetInfo() const override;

  RefPtr<SeekPromise> Seek(const media::TimeUnit& aTime) override;

  RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) override;

  void UpdateMediaInfo(int index);

  void Reset() override;

  nsresult GetNextRandomAccessPoint(media::TimeUnit* aTime) override;

  RefPtr<SkipAccessPointPromise> 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<SeekPromise> DoSeek(const media::TimeUnit& aTime);
  RefPtr<SamplesPromise> DoGetSamples(int32_t aNumSamples);
  RefPtr<SkipAccessPointPromise> DoSkipToNextRandomAccessPoint(
      const media::TimeUnit& aTimeThreshold);

  CryptoSample ExtractCryptoSample(
      size_t aSampleSize,
      java::sdk::MediaCodec::CryptoInfo::LocalRef aCryptoInfo);
  RefPtr<MediaRawData> ConvertToMediaRawData(
      java::GeckoHLSSample::LocalRef aSample);

  RefPtr<HLSDemuxer> mParent;
  TrackInfo::TrackType mType;
  Maybe<media::TimeUnit> mNextKeyframeTime;
  int32_t mLastFormatIndex = -1;
  // Queued samples extracted by the demuxer, but not yet returned.
  RefPtr<MediaRawData> mQueuedSample;

  // Mutex to protect members below across multiple threads.
  mutable Mutex mMutex MOZ_UNANNOTATED;
  UniquePtr<TrackInfo> mTrackInfo;
};

}  // namespace mozilla

#endif