2016-12-01 05:05:45 +03:00
|
|
|
/* -*- 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/. */
|
|
|
|
|
|
|
|
#ifndef MediaMIMETypes_h_
|
|
|
|
#define MediaMIMETypes_h_
|
|
|
|
|
2017-03-09 12:32:08 +03:00
|
|
|
#include "VideoUtils.h"
|
2016-12-01 05:05:45 +03:00
|
|
|
#include "mozilla/Maybe.h"
|
|
|
|
#include "nsString.h"
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
|
2018-06-07 17:18:08 +03:00
|
|
|
namespace dom {
|
|
|
|
struct AudioConfiguration;
|
|
|
|
struct VideoConfiguration;
|
|
|
|
} // namespace dom
|
|
|
|
|
2017-01-01 01:52:06 +03:00
|
|
|
// Class containing pointing at a media MIME "type/subtype" string literal.
|
|
|
|
// See IsMediaMIMEType for restrictions.
|
|
|
|
// Mainly used to help construct a MediaMIMEType through the statically-checked
|
2017-01-01 02:06:26 +03:00
|
|
|
// MEDIAMIMETYPE macro, or to compare a MediaMIMEType to a literal.
|
2017-01-01 01:52:06 +03:00
|
|
|
class DependentMediaMIMEType {
|
|
|
|
public:
|
|
|
|
// Construction from a literal. Checked in debug builds.
|
|
|
|
// Use MEDIAMIMETYPE macro instead, for static checking.
|
|
|
|
template <size_t N>
|
|
|
|
explicit DependentMediaMIMEType(const char (&aType)[N])
|
|
|
|
: mMIMEType(aType, N - 1) {
|
|
|
|
MOZ_ASSERT(IsMediaMIMEType(aType, N - 1), "Invalid media MIME type");
|
|
|
|
}
|
|
|
|
|
|
|
|
// MIME "type/subtype".
|
|
|
|
const nsDependentCString& AsDependentString() const { return mMIMEType; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
nsDependentCString mMIMEType;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Instantiate a DependentMediaMIMEType from a literal. Statically checked.
|
|
|
|
#define MEDIAMIMETYPE(LIT) \
|
|
|
|
static_cast<const DependentMediaMIMEType&>([]() { \
|
|
|
|
static_assert(IsMediaMIMEType(LIT), "Invalid media MIME type"); \
|
|
|
|
return DependentMediaMIMEType(LIT); \
|
|
|
|
}())
|
|
|
|
|
2016-12-01 08:57:31 +03:00
|
|
|
// Class containing only pre-parsed lowercase media MIME type/subtype.
|
|
|
|
class MediaMIMEType {
|
|
|
|
public:
|
2017-01-01 01:52:06 +03:00
|
|
|
// Construction from a DependentMediaMIMEType, with its inherent checks.
|
|
|
|
// Implicit so MEDIAMIMETYPE can be used wherever a MediaMIMEType is expected.
|
|
|
|
MOZ_IMPLICIT MediaMIMEType(const DependentMediaMIMEType& aType)
|
|
|
|
: mMIMEType(aType.AsDependentString()) {}
|
|
|
|
|
2016-12-01 08:57:31 +03:00
|
|
|
// MIME "type/subtype", always lowercase.
|
2017-09-04 23:43:12 +03:00
|
|
|
const nsCString& AsString() const { return mMIMEType; }
|
2016-12-01 08:57:31 +03:00
|
|
|
|
2017-01-01 02:06:26 +03:00
|
|
|
// Comparison with DependentMediaMIMEType.
|
|
|
|
// Useful to compare to MEDIAMIMETYPE literals.
|
|
|
|
bool operator==(const DependentMediaMIMEType& aOther) const {
|
|
|
|
return mMIMEType.Equals(aOther.AsDependentString());
|
|
|
|
}
|
|
|
|
bool operator!=(const DependentMediaMIMEType& aOther) const {
|
|
|
|
return !mMIMEType.Equals(aOther.AsDependentString());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const MediaMIMEType& aOther) const {
|
|
|
|
return mMIMEType.Equals(aOther.mMIMEType);
|
|
|
|
}
|
|
|
|
bool operator!=(const MediaMIMEType& aOther) const {
|
|
|
|
return !mMIMEType.Equals(aOther.mMIMEType);
|
|
|
|
}
|
|
|
|
|
2016-12-17 09:43:02 +03:00
|
|
|
// True if type starts with "application/".
|
|
|
|
bool HasApplicationMajorType() const;
|
|
|
|
// True if type starts with "audio/".
|
|
|
|
// Note that some audio content could be stored in a "video/..." container!
|
|
|
|
bool HasAudioMajorType() const;
|
|
|
|
// True if type starts with "video/".
|
|
|
|
// Note that this does not guarantee 100% that the content is actually video!
|
|
|
|
// (e.g., "video/webm" could contain a vorbis audio track.)
|
|
|
|
bool HasVideoMajorType() const;
|
|
|
|
|
2016-12-22 03:54:56 +03:00
|
|
|
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
|
|
|
|
2016-12-01 08:57:31 +03:00
|
|
|
private:
|
|
|
|
friend Maybe<MediaMIMEType> MakeMediaMIMEType(const nsAString& aType);
|
|
|
|
friend class MediaExtendedMIMEType;
|
|
|
|
explicit MediaMIMEType(const nsACString& aType);
|
|
|
|
|
|
|
|
nsCString mMIMEType; // UTF8 MIME "type/subtype".
|
|
|
|
};
|
|
|
|
|
|
|
|
Maybe<MediaMIMEType> MakeMediaMIMEType(const nsAString& aType);
|
|
|
|
Maybe<MediaMIMEType> MakeMediaMIMEType(const nsACString& aType);
|
|
|
|
Maybe<MediaMIMEType> MakeMediaMIMEType(const char* aType);
|
|
|
|
|
2017-06-29 21:17:56 +03:00
|
|
|
// A list of case-sensitive codecs attached to a MediaExtendedMIMEType.
|
2016-12-28 02:48:27 +03:00
|
|
|
class MediaCodecs {
|
|
|
|
public:
|
2020-03-04 18:39:20 +03:00
|
|
|
MediaCodecs() = default;
|
2016-12-28 02:48:27 +03:00
|
|
|
// Construction from a comma-separated list of codecs. Unchecked.
|
2017-03-09 12:32:08 +03:00
|
|
|
explicit MediaCodecs(const nsAString& aCodecs) : mCodecs(aCodecs) {}
|
2016-12-28 02:48:27 +03:00
|
|
|
// Construction from a literal comma-separated list of codecs. Unchecked.
|
|
|
|
template <size_t N>
|
|
|
|
explicit MediaCodecs(const char (&aCodecs)[N])
|
|
|
|
: mCodecs(NS_ConvertUTF8toUTF16(aCodecs, N - 1)) {}
|
|
|
|
|
|
|
|
bool IsEmpty() const { return mCodecs.IsEmpty(); }
|
2017-09-04 23:43:12 +03:00
|
|
|
const nsString& AsString() const { return mCodecs; }
|
2016-12-28 02:48:27 +03:00
|
|
|
|
|
|
|
using RangeType =
|
|
|
|
const StringListRange<nsString,
|
|
|
|
StringListRangeEmptyItems::ProcessEmptyItems>;
|
|
|
|
|
|
|
|
// Produces a range object with begin()&end(), can be used in range-for loops.
|
|
|
|
// This will iterate through all codecs, even empty ones (except if the
|
|
|
|
// original list was an empty string). Iterators dereference to
|
|
|
|
// 'const nsDependentString', valid for as long as this MediaCodecs object.
|
|
|
|
RangeType Range() const { return RangeType(mCodecs); };
|
|
|
|
|
2017-06-29 21:17:56 +03:00
|
|
|
// Does this list of codecs contain the given aCodec?
|
2016-12-28 02:48:27 +03:00
|
|
|
bool Contains(const nsAString& aCodec) const;
|
2017-06-29 21:17:56 +03:00
|
|
|
// Does this list of codecs contain *all* the codecs in the given list?
|
2016-12-28 02:48:27 +03:00
|
|
|
bool ContainsAll(const MediaCodecs& aCodecs) const;
|
|
|
|
|
2017-06-29 21:17:56 +03:00
|
|
|
// Does this list of codecs contain a codec starting with the given prefix?
|
|
|
|
bool ContainsPrefix(const nsAString& aCodecPrefix) const;
|
|
|
|
|
2017-01-24 07:42:48 +03:00
|
|
|
template <size_t N>
|
|
|
|
bool operator==(const char (&aType)[N]) const {
|
|
|
|
return mCodecs.EqualsASCII(aType, N - 1);
|
|
|
|
}
|
|
|
|
|
2016-12-22 03:54:56 +03:00
|
|
|
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
|
|
|
|
2016-12-28 02:48:27 +03:00
|
|
|
private:
|
|
|
|
// UTF16 comma-separated list of codecs.
|
|
|
|
// See http://www.rfc-editor.org/rfc/rfc4281.txt for the description
|
|
|
|
// of the 'codecs' parameter.
|
|
|
|
nsString mCodecs;
|
|
|
|
};
|
|
|
|
|
2016-12-01 05:05:45 +03:00
|
|
|
// Class containing pre-parsed media MIME type parameters, e.g.:
|
|
|
|
// MIME type/subtype, optional codecs, etc.
|
|
|
|
class MediaExtendedMIMEType {
|
|
|
|
public:
|
2016-12-01 08:57:31 +03:00
|
|
|
explicit MediaExtendedMIMEType(const MediaMIMEType& aType);
|
|
|
|
explicit MediaExtendedMIMEType(MediaMIMEType&& aType);
|
|
|
|
|
2016-12-01 05:05:45 +03:00
|
|
|
// MIME "type/subtype".
|
2016-12-01 08:57:31 +03:00
|
|
|
const MediaMIMEType& Type() const { return mMIMEType; }
|
2016-12-01 05:05:45 +03:00
|
|
|
|
|
|
|
// Was there an explicit 'codecs' parameter provided?
|
|
|
|
bool HaveCodecs() const { return mHaveCodecs; }
|
|
|
|
// Codecs. May be empty if not provided or explicitly provided as empty.
|
2016-12-28 02:48:27 +03:00
|
|
|
const MediaCodecs& Codecs() const { return mCodecs; }
|
2016-12-01 05:05:45 +03:00
|
|
|
|
|
|
|
// Sizes and rates.
|
|
|
|
Maybe<int32_t> GetWidth() const { return GetMaybeNumber(mWidth); }
|
|
|
|
Maybe<int32_t> GetHeight() const { return GetMaybeNumber(mHeight); }
|
2018-06-07 17:18:08 +03:00
|
|
|
Maybe<double> GetFramerate() const { return GetMaybeNumber(mFramerate); }
|
2016-12-01 05:05:45 +03:00
|
|
|
Maybe<int32_t> GetBitrate() const { return GetMaybeNumber(mBitrate); }
|
2018-06-07 17:18:08 +03:00
|
|
|
Maybe<int32_t> GetChannels() const { return GetMaybeNumber(mChannels); }
|
|
|
|
Maybe<int32_t> GetSamplerate() const { return GetMaybeNumber(mSamplerate); }
|
2016-12-01 05:05:45 +03:00
|
|
|
|
2016-12-28 10:56:22 +03:00
|
|
|
// Original string. Note that "type/subtype" may not be lowercase,
|
|
|
|
// use Type().AsString() instead to get the normalized "type/subtype".
|
2017-09-04 23:43:12 +03:00
|
|
|
const nsCString& OriginalString() const { return mOriginalString; }
|
2016-12-28 10:56:22 +03:00
|
|
|
|
2016-12-22 03:54:56 +03:00
|
|
|
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
|
|
|
|
2018-06-07 17:18:08 +03:00
|
|
|
// aFrac is either a floating-point number or a fraction made of two
|
|
|
|
// floating-point numbers.
|
|
|
|
static Maybe<double> ComputeFractionalString(const nsAString& aFrac);
|
|
|
|
|
2016-12-01 05:05:45 +03:00
|
|
|
private:
|
2018-06-07 17:18:08 +03:00
|
|
|
friend Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(
|
|
|
|
const nsAString& aType);
|
|
|
|
friend Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(
|
|
|
|
const dom::VideoConfiguration& aConfig);
|
|
|
|
friend Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(
|
|
|
|
const dom::AudioConfiguration& aConfig);
|
|
|
|
|
2016-12-28 10:56:22 +03:00
|
|
|
MediaExtendedMIMEType(const nsACString& aOriginalString,
|
2016-12-01 05:05:45 +03:00
|
|
|
const nsACString& aMIMEType, bool aHaveCodecs,
|
|
|
|
const nsAString& aCodecs, int32_t aWidth,
|
2019-10-25 01:50:35 +03:00
|
|
|
int32_t aHeight, double aFramerate, int32_t aBitrate);
|
2018-06-07 17:18:08 +03:00
|
|
|
MediaExtendedMIMEType(const nsACString& aOriginalString,
|
|
|
|
const nsACString& aMIMEType, bool aHaveCodecs,
|
|
|
|
const nsAString& aCodecs, int32_t aChannels,
|
|
|
|
int32_t aSamplerate, int32_t aBitrate);
|
2016-12-01 05:05:45 +03:00
|
|
|
|
2018-06-07 17:18:08 +03:00
|
|
|
template <typename T>
|
|
|
|
Maybe<T> GetMaybeNumber(T aNumber) const {
|
|
|
|
return (aNumber < 0) ? Maybe<T>(Nothing()) : Some(T(aNumber));
|
2016-12-01 05:05:45 +03:00
|
|
|
}
|
|
|
|
|
2016-12-28 10:56:22 +03:00
|
|
|
nsCString mOriginalString; // Original full string.
|
2016-12-01 08:57:31 +03:00
|
|
|
MediaMIMEType mMIMEType; // MIME type/subtype.
|
|
|
|
bool mHaveCodecs = false; // If false, mCodecs must be empty.
|
2016-12-28 02:48:27 +03:00
|
|
|
MediaCodecs mCodecs;
|
2018-06-07 17:18:08 +03:00
|
|
|
// For video
|
2016-12-01 08:57:31 +03:00
|
|
|
int32_t mWidth = -1; // -1 if not provided.
|
|
|
|
int32_t mHeight = -1; // -1 if not provided.
|
2018-06-07 17:18:08 +03:00
|
|
|
double mFramerate = -1; // -1 if not provided.
|
|
|
|
// For audio
|
|
|
|
int32_t mChannels = -1; // -1 if not provided.
|
|
|
|
int32_t mSamplerate = -1; // -1 if not provided.
|
|
|
|
// For both audio and video.
|
2016-12-01 08:57:31 +03:00
|
|
|
int32_t mBitrate = -1; // -1 if not provided.
|
2016-12-01 05:05:45 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(const nsAString& aType);
|
|
|
|
Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(const nsACString& aType);
|
|
|
|
Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(const char* aType);
|
2018-06-07 17:18:08 +03:00
|
|
|
Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(
|
|
|
|
const dom::VideoConfiguration& aConfig);
|
|
|
|
Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(
|
|
|
|
const dom::AudioConfiguration& aConfig);
|
2016-12-01 05:05:45 +03:00
|
|
|
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // MediaMIMETypes_h_
|