tor-browser

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

MediaMIMETypes.h (9336B)


      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 MediaMIMETypes_h_
      8 #define MediaMIMETypes_h_
      9 
     10 #include "VideoUtils.h"
     11 #include "mozilla/Maybe.h"
     12 #include "nsString.h"
     13 
     14 namespace mozilla {
     15 
     16 namespace dom {
     17 struct AudioConfiguration;
     18 struct VideoConfiguration;
     19 }  // namespace dom
     20 
     21 // Class containing pointing at a media MIME "type/subtype" string literal.
     22 // See IsMediaMIMEType for restrictions.
     23 // Mainly used to help construct a MediaMIMEType through the statically-checked
     24 // MEDIAMIMETYPE macro, or to compare a MediaMIMEType to a literal.
     25 class DependentMediaMIMEType {
     26 public:
     27  // Construction from a literal. Checked in debug builds.
     28  // Use MEDIAMIMETYPE macro instead, for static checking.
     29  template <size_t N>
     30  explicit DependentMediaMIMEType(const char (&aType)[N])
     31      : mMIMEType(aType, N - 1) {
     32    MOZ_ASSERT(IsMediaMIMEType(aType, N - 1), "Invalid media MIME type");
     33  }
     34 
     35  // MIME "type/subtype".
     36  const nsDependentCString& AsDependentString() const { return mMIMEType; }
     37 
     38 private:
     39  nsDependentCString mMIMEType;
     40 };
     41 
     42 // Instantiate a DependentMediaMIMEType from a literal. Statically checked.
     43 #define MEDIAMIMETYPE(LIT)                                          \
     44  static_cast<const DependentMediaMIMEType&>([]() {                 \
     45    static_assert(IsMediaMIMEType(LIT), "Invalid media MIME type"); \
     46    return DependentMediaMIMEType(LIT);                             \
     47  }())
     48 
     49 // Class containing only pre-parsed lowercase media MIME type/subtype.
     50 class MediaMIMEType {
     51 public:
     52  // Construction from a DependentMediaMIMEType, with its inherent checks.
     53  // Implicit so MEDIAMIMETYPE can be used wherever a MediaMIMEType is expected.
     54  MOZ_IMPLICIT MediaMIMEType(const DependentMediaMIMEType& aType)
     55      : mMIMEType(aType.AsDependentString()) {}
     56 
     57  // MIME "type/subtype", always lowercase.
     58  const nsCString& AsString() const { return mMIMEType; }
     59 
     60  // Comparison with DependentMediaMIMEType.
     61  // Useful to compare to MEDIAMIMETYPE literals.
     62  bool operator==(const DependentMediaMIMEType& aOther) const {
     63    return mMIMEType.Equals(aOther.AsDependentString());
     64  }
     65  bool operator!=(const DependentMediaMIMEType& aOther) const {
     66    return !mMIMEType.Equals(aOther.AsDependentString());
     67  }
     68 
     69  bool operator==(const MediaMIMEType& aOther) const {
     70    return mMIMEType.Equals(aOther.mMIMEType);
     71  }
     72  bool operator!=(const MediaMIMEType& aOther) const {
     73    return !mMIMEType.Equals(aOther.mMIMEType);
     74  }
     75 
     76  // True if type starts with "application/".
     77  bool HasApplicationMajorType() const;
     78  // True if type starts with "audio/".
     79  // Note that some audio content could be stored in a "video/..." container!
     80  bool HasAudioMajorType() const;
     81  // True if type starts with "video/".
     82  // Note that this does not guarantee 100% that the content is actually video!
     83  // (e.g., "video/webm" could contain a vorbis audio track.)
     84  bool HasVideoMajorType() const;
     85 
     86  size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     87 
     88 private:
     89  friend Maybe<MediaMIMEType> MakeMediaMIMEType(const nsAString& aType);
     90  friend class MediaExtendedMIMEType;
     91  explicit MediaMIMEType(const nsACString& aType);
     92 
     93  nsCString mMIMEType;  // UTF8 MIME "type/subtype".
     94 };
     95 
     96 Maybe<MediaMIMEType> MakeMediaMIMEType(const nsAString& aType);
     97 Maybe<MediaMIMEType> MakeMediaMIMEType(const nsACString& aType);
     98 Maybe<MediaMIMEType> MakeMediaMIMEType(const char* aType);
     99 
    100 // A list of case-sensitive codecs attached to a MediaExtendedMIMEType.
    101 class MediaCodecs {
    102 public:
    103  MediaCodecs() = default;
    104  // Construction from a comma-separated list of codecs. Unchecked.
    105  explicit MediaCodecs(const nsAString& aCodecs) : mCodecs(aCodecs) {}
    106  // Construction from a literal comma-separated list of codecs. Unchecked.
    107  template <size_t N>
    108  explicit MediaCodecs(const char (&aCodecs)[N])
    109      : mCodecs(NS_ConvertUTF8toUTF16(aCodecs, N - 1)) {}
    110 
    111  bool IsEmpty() const { return mCodecs.IsEmpty(); }
    112  const nsString& AsString() const { return mCodecs; }
    113 
    114  using RangeType =
    115      const StringListRange<nsString,
    116                            StringListRangeEmptyItems::ProcessEmptyItems>;
    117 
    118  // Produces a range object with begin()&end(), can be used in range-for loops.
    119  // This will iterate through all codecs, even empty ones (except if the
    120  // original list was an empty string). Iterators dereference to
    121  // 'const nsDependentString', valid for as long as this MediaCodecs object.
    122  RangeType Range() const { return RangeType(mCodecs); };
    123 
    124  // Does this list of codecs contain the given aCodec?
    125  bool Contains(const nsAString& aCodec) const;
    126  // Does this list of codecs contain *all* the codecs in the given list?
    127  bool ContainsAll(const MediaCodecs& aCodecs) const;
    128 
    129  // Does this list of codecs contain a codec starting with the given prefix?
    130  bool ContainsPrefix(const nsAString& aCodecPrefix) const;
    131 
    132  template <size_t N>
    133  bool operator==(const char (&aType)[N]) const {
    134    return mCodecs.EqualsASCII(aType, N - 1);
    135  }
    136 
    137  size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    138 
    139 private:
    140  // UTF16 comma-separated list of codecs.
    141  // See http://www.rfc-editor.org/rfc/rfc4281.txt for the description
    142  // of the 'codecs' parameter.
    143  nsString mCodecs;
    144 };
    145 
    146 // Class containing pre-parsed media MIME type parameters, e.g.:
    147 // MIME type/subtype, optional codecs, etc.
    148 class MediaExtendedMIMEType {
    149 public:
    150  explicit MediaExtendedMIMEType(const MediaMIMEType& aType);
    151  explicit MediaExtendedMIMEType(MediaMIMEType&& aType);
    152 
    153  // MIME "type/subtype".
    154  const MediaMIMEType& Type() const { return mMIMEType; }
    155 
    156  // Was there an explicit 'codecs' parameter provided?
    157  bool HaveCodecs() const { return mHaveCodecs; }
    158  // Codecs. May be empty if not provided or explicitly provided as empty.
    159  const MediaCodecs& Codecs() const { return mCodecs; }
    160 
    161  // Sizes and rates.
    162  Maybe<int32_t> GetWidth() const { return GetMaybeNumber(mWidth); }
    163  Maybe<int32_t> GetHeight() const { return GetMaybeNumber(mHeight); }
    164  Maybe<double> GetFramerate() const { return GetMaybeNumber(mFramerate); }
    165  Maybe<int32_t> GetBitrate() const { return GetMaybeNumber(mBitrate); }
    166  Maybe<int32_t> GetChannels() const { return GetMaybeNumber(mChannels); }
    167  Maybe<int32_t> GetSamplerate() const { return GetMaybeNumber(mSamplerate); }
    168 
    169  // Total number of parameters, including non-media parameters. Lazily init'd -
    170  // mutates mNumParams and numParamsCached on first use. Callable from any
    171  // thread, not thread safe.
    172  size_t GetParameterCount() const;
    173 
    174  // Original string. Note that "type/subtype" may not be lowercase,
    175  // use Type().AsString() instead to get the normalized "type/subtype"
    176  const nsCString& OriginalString() const { return mOriginalString; }
    177 
    178  size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    179 
    180 private:
    181  friend Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(
    182      const nsAString& aType);
    183  friend Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(
    184      const dom::VideoConfiguration& aConfig);
    185  friend Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(
    186      const dom::AudioConfiguration& aConfig);
    187 
    188  MediaExtendedMIMEType(const nsACString& aOriginalString,
    189                        const nsACString& aMIMEType, bool aHaveCodecs,
    190                        const nsAString& aCodecs, int32_t aWidth,
    191                        int32_t aHeight, double aFramerate, int32_t aBitrate);
    192  MediaExtendedMIMEType(const nsACString& aOriginalString,
    193                        const nsACString& aMIMEType, bool aHaveCodecs,
    194                        const nsAString& aCodecs, int32_t aChannels,
    195                        int32_t aSamplerate, int32_t aBitrate);
    196 
    197  template <typename T>
    198  Maybe<T> GetMaybeNumber(T aNumber) const {
    199    return (aNumber < 0) ? Maybe<T>(Nothing()) : Some(T(aNumber));
    200  }
    201 
    202  nsCString mOriginalString;  // Original full string.
    203  MediaMIMEType mMIMEType;    // MIME type/subtype.
    204  bool mHaveCodecs = false;   // If false, mCodecs must be empty.
    205  MediaCodecs mCodecs;
    206  // For video
    207  int32_t mWidth = -1;     // -1 if not provided.
    208  int32_t mHeight = -1;    // -1 if not provided.
    209  double mFramerate = -1;  // -1 if not provided.
    210  // For audio
    211  int32_t mChannels = -1;    // -1 if not provided.
    212  int32_t mSamplerate = -1;  // -1 if not provided.
    213  // For both audio and video.
    214  int32_t mBitrate = -1;  // -1 if not provided.
    215  // General parameter information
    216  mutable size_t mNumParams = 0;          // lazily init'd since counting params
    217  mutable bool mNumParamsCached = false;  // needs additional parser (CMimeType)
    218 };
    219 
    220 Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(const nsAString& aType);
    221 Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(const nsACString& aType);
    222 Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(const char* aType);
    223 Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(
    224    const dom::VideoConfiguration& aConfig);
    225 Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(
    226    const dom::AudioConfiguration& aConfig);
    227 
    228 }  // namespace mozilla
    229 
    230 #endif  // MediaMIMETypes_h_