tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MediaDataDemuxer.h (8683B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      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 MediaDataDemuxer_h
      8 #define MediaDataDemuxer_h
      9 
     10 #include "DecoderDoctorLogger.h"
     11 #include "MediaData.h"
     12 #include "MediaInfo.h"
     13 #include "MediaResult.h"
     14 #include "TimeUnits.h"
     15 #include "mozilla/MozPromise.h"
     16 #include "mozilla/RefPtr.h"
     17 #include "mozilla/UniquePtr.h"
     18 #include "nsISupportsImpl.h"
     19 #include "nsTArray.h"
     20 
     21 namespace mozilla {
     22 
     23 class MediaTrackDemuxer;
     24 class TrackMetadataHolder;
     25 
     26 DDLoggedTypeDeclName(MediaDataDemuxer);
     27 DDLoggedTypeName(MediaTrackDemuxer);
     28 
     29 inline mozilla::LazyLogModule gMediaDemuxerLog("MediaDemuxer");
     30 
     31 // Allows reading the media data: to retrieve the metadata and demux samples.
     32 // MediaDataDemuxer isn't designed to be thread safe.
     33 // When used by the MediaFormatDecoder, care is taken to ensure that the demuxer
     34 // will never be called from more than one thread at once.
     35 class MediaDataDemuxer : public DecoderDoctorLifeLogger<MediaDataDemuxer> {
     36 public:
     37  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDataDemuxer)
     38 
     39  typedef MozPromise<MediaResult, MediaResult, /* IsExclusive = */ false>
     40      InitPromise;
     41 
     42  // Initializes the demuxer. Other methods cannot be called unless
     43  // initialization has completed and succeeded.
     44  // Typically a demuxer will wait to parse the metadata before resolving the
     45  // promise. The promise must not be resolved until sufficient data is
     46  // supplied. For example, an incomplete metadata would cause the promise to be
     47  // rejected should no more data be coming, while the demuxer would wait
     48  // otherwise.
     49  virtual RefPtr<InitPromise> Init() = 0;
     50 
     51  // Returns the number of tracks of aType type available. A value of
     52  // 0 indicates that no such type is available.
     53  virtual uint32_t GetNumberTracks(TrackInfo::TrackType aType) const = 0;
     54 
     55  // Returns the MediaTrackDemuxer associated with aTrackNumber aType track.
     56  // aTrackNumber is not to be confused with the Track ID.
     57  // aTrackNumber must be constrained between  0 and  GetNumberTracks(aType) - 1
     58  // The actual Track ID is to be retrieved by calling
     59  // MediaTrackDemuxer::TrackInfo.
     60  virtual already_AddRefed<MediaTrackDemuxer> GetTrackDemuxer(
     61      TrackInfo::TrackType aType, uint32_t aTrackNumber) = 0;
     62 
     63  // Returns true if the underlying resource allows seeking.
     64  virtual bool IsSeekable() const = 0;
     65 
     66  // Returns true if the underlying resource can only seek within buffered
     67  // ranges.
     68  virtual bool IsSeekableOnlyInBufferedRanges() const { return false; }
     69 
     70  // Returns the media's crypto information, or nullptr if media isn't
     71  // encrypted.
     72  virtual UniquePtr<EncryptionInfo> GetCrypto() { return nullptr; }
     73 
     74  // Notifies the demuxer that the underlying resource has received more data
     75  // since the demuxer was initialized.
     76  // The demuxer can use this mechanism to inform all track demuxers that new
     77  // data is available and to refresh its buffered range.
     78  virtual void NotifyDataArrived() {}
     79 
     80  // Notifies the demuxer that the underlying resource has had data removed
     81  // since the demuxer was initialized.
     82  // The demuxer can use this mechanism to inform all track demuxers to update
     83  // its buffered range.
     84  // This will be called should the demuxer be used with MediaSource.
     85  virtual void NotifyDataRemoved() {}
     86 
     87  // Indicate to MediaFormatReader if it should compute the start time
     88  // of the demuxed data. If true (default) the first sample returned will be
     89  // used as reference time base.
     90  virtual bool ShouldComputeStartTime() const { return true; }
     91 
     92 protected:
     93  virtual ~MediaDataDemuxer() = default;
     94 };
     95 
     96 class MediaTrackDemuxer : public DecoderDoctorLifeLogger<MediaTrackDemuxer> {
     97 public:
     98  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaTrackDemuxer)
     99 
    100  class SamplesHolder {
    101   public:
    102    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SamplesHolder)
    103 
    104    void AppendSample(RefPtr<MediaRawData> aSample) {
    105      MOZ_DIAGNOSTIC_ASSERT(aSample->HasValidTime());
    106      mSamples.AppendElement(std::move(aSample));
    107    }
    108 
    109    const nsTArray<RefPtr<MediaRawData>>& GetSamples() const {
    110      return mSamples;
    111    }
    112 
    113    // This method is only used to do the move semantic for mSamples, do not
    114    // append any element to the samples we returns. We should always append new
    115    // sample to mSamples via `AppendSample()`.
    116    nsTArray<RefPtr<MediaRawData>>&& GetMovableSamples() {
    117      return std::move(mSamples);
    118    }
    119 
    120   private:
    121    ~SamplesHolder() = default;
    122    nsTArray<RefPtr<MediaRawData>> mSamples;
    123  };
    124 
    125  class SkipFailureHolder {
    126   public:
    127    SkipFailureHolder(const MediaResult& aFailure, uint32_t aSkipped)
    128        : mFailure(aFailure), mSkipped(aSkipped) {}
    129    MediaResult mFailure;
    130    uint32_t mSkipped;
    131  };
    132 
    133  typedef MozPromise<media::TimeUnit, MediaResult, /* IsExclusive = */ true>
    134      SeekPromise;
    135  typedef MozPromise<RefPtr<SamplesHolder>, MediaResult,
    136                     /* IsExclusive = */ true>
    137      SamplesPromise;
    138  typedef MozPromise<uint32_t, SkipFailureHolder, /* IsExclusive = */ true>
    139      SkipAccessPointPromise;
    140 
    141  // Returns the TrackInfo (a.k.a Track Description) for this track.
    142  // The TrackInfo returned will be:
    143  // TrackInfo::kVideoTrack -> VideoInfo.
    144  // TrackInfo::kAudioTrack -> AudioInfo.
    145  // respectively.
    146  virtual UniquePtr<TrackInfo> GetInfo() const = 0;
    147 
    148  // Seeks to aTime. Upon success, SeekPromise will be resolved with the
    149  // actual time seeked to. Typically the random access point time
    150  virtual RefPtr<SeekPromise> Seek(const media::TimeUnit& aTime) = 0;
    151 
    152  // Returns the next aNumSamples sample(s) available.
    153  // If only a lesser amount of samples is available, only those will be
    154  // returned.
    155  // A aNumSamples value of -1 indicates to return all remaining samples.
    156  // NS_ERROR_DOM_MEDIA_END_OF_STREAM and NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA
    157  // are returned only if no more samples can be returned.
    158  // Other errors encountered while parsing the requested number of samples
    159  // are reported immediately without returning any samples, even if a smaller
    160  // number of samples could be parsed successfully.
    161  // A video sample is typically made of a single video frame while an audio
    162  // sample will contains multiple audio frames.
    163  virtual RefPtr<SamplesPromise> GetSamples(int32_t aNumSamples = 1) = 0;
    164 
    165  // Returns true if a call to GetSamples() may block while waiting on the
    166  // underlying resource to return the data.
    167  // This is used by the MediaFormatReader to determine if buffering heuristics
    168  // should be used.
    169  virtual bool GetSamplesMayBlock() const { return true; }
    170 
    171  // Cancel all pending actions (Seek, GetSamples) and reset current state
    172  // All pending promises are to be rejected with CANCEL.
    173  // The next call to GetSamples would return the first sample available in the
    174  // track.
    175  virtual void Reset() = 0;
    176 
    177  // Returns timestamp of next random access point or an error if the demuxer
    178  // can't report this.
    179  virtual nsresult GetNextRandomAccessPoint(media::TimeUnit* aTime) {
    180    return NS_ERROR_NOT_IMPLEMENTED;
    181  }
    182 
    183  // Returns timestamp of previous random access point or an error if the
    184  // demuxer can't report this.
    185  virtual nsresult GetPreviousRandomAccessPoint(media::TimeUnit* aTime) {
    186    return NS_ERROR_NOT_IMPLEMENTED;
    187  }
    188 
    189  // Skip frames until the next Random Access Point located after
    190  // aTimeThreshold.
    191  // The first frame returned by the next call to GetSamples() will be the
    192  // first random access point found after aTimeThreshold.
    193  // Upon success, returns the number of frames skipped.
    194  virtual RefPtr<SkipAccessPointPromise> SkipToNextRandomAccessPoint(
    195      const media::TimeUnit& aTimeThreshold) = 0;
    196 
    197  // Gets the resource's offset used for the last Seek() or GetSample().
    198  // A negative value indicates that this functionality isn't supported.
    199  virtual int64_t GetResourceOffset() const { return -1; }
    200 
    201  virtual TrackInfo::TrackType GetType() const { return GetInfo()->GetType(); }
    202 
    203  virtual media::TimeIntervals GetBuffered() = 0;
    204 
    205  // By default, it is assumed that the entire resource can be evicted once
    206  // all samples have been demuxed.
    207  virtual int64_t GetEvictionOffset(const media::TimeUnit& aTime) {
    208    return INT64_MAX;
    209  }
    210 
    211  // If the MediaTrackDemuxer and MediaDataDemuxer hold cross references.
    212  // BreakCycles must be overridden.
    213  virtual void BreakCycles() {}
    214 
    215 protected:
    216  virtual ~MediaTrackDemuxer() = default;
    217 };
    218 
    219 }  // namespace mozilla
    220 
    221 #endif  // MediaDataDemuxer_h