// Copyright 2021 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef MEDIA_FORMATS_HLS_TYPES_H_ #define MEDIA_FORMATS_HLS_TYPES_H_ #include <cstdint> #include <optional> #include "base/containers/span.h" #include "base/memory/raw_span.h" #include "base/time/time.h" #include "media/formats/hls/parse_status.h" #include "media/formats/hls/source_string.h" #include "media/formats/hls/variable_dictionary.h" namespace media::hls::types { namespace { template <size_t count, typename impl, typename... types> struct repeat_t { … }; repeat_t<0, impl, types...>; } // namespace // A `DecimalInteger` is an unsigned integer value. // https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#:~:text=of%20the%20following%3A%0A%0A%20%20%20o-,decimal%2Dinteger,-%3A%20an%20unquoted%20string DecimalInteger; namespace parsing { // A substituting parser functions as a super-struct parser which provides the // entry points for raw SourceStrings to either be consumed raw or resolved by // the sub-struct's Parse method. It is specialized with: // Subtype: The substruct implementation, which provides the method // `static T Parse(ResolvedSourceString, ParseArgs...)` // T: The type that should result from successful parsing. // ParseArgs...: Additional arguments that might be passed to the Parse // function declared on `Subtype`. For example, some quoted // strings are required to be non-empty, so the quoted string // parser should have an optional bool parameter to require it. template <typename Subtype, typename T, typename... ParseArgs> struct MEDIA_EXPORT SubstitutingParser { … }; // A wrapping parser that will parse some other type T which is contained // withing quotation marks. Quoted<RawStr>::ParseWithoutSubstitution will ensure // that the SourceString starts and ends with quotation marks, and will return // a ResolvedSourceString representing the content inside those quotes. template <typename T> struct MEDIA_EXPORT Quoted : public SubstitutingParser<Quoted<T>, typename T::ParseInto> { … }; // Parser struct for a plain ResolvedSourceString. This is usually used // for things like URIs. struct MEDIA_EXPORT RawStr : SubstitutingParser<RawStr, ResolvedSourceString> { … }; struct MEDIA_EXPORT YesOrNo : SubstitutingParser<YesOrNo, bool> { … }; // Parser struct for floating point representations of TimeDelta instances. struct MEDIA_EXPORT TimeDelta : SubstitutingParser<TimeDelta, base::TimeDelta> { … }; // A `ByteRangeExpression` represents the 'length[@offset]' syntax that appears // in tags describing byte ranges of a resource. // https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#section-4.4.4.2 struct MEDIA_EXPORT ByteRangeExpression : public SubstitutingParser<ByteRangeExpression, ByteRangeExpression> { … }; // Calculate chunk sizes for the hex parser. This needs to be separated so that // the SubstitutingParser template can be specialized on the proper return type // of HexRepr::Parse. template <int64_t bits> struct HexPackInfo { … }; // Represents a hexadecimal string in the form 0xXXXXXX... // where this might require more than sizeof(size_t) bytes. // HexRepr<X>::Container can be used to get the tuple format for the // underlying container that HexRepr<X>::Parse should return. template <int64_t bits> struct MEDIA_EXPORT HexRepr : public SubstitutingParser<HexRepr<bits>, typename HexPackInfo<bits>::Container> { … }; } // namespace parsing MEDIA_EXPORT ParseStatus::Or<DecimalInteger> ParseDecimalInteger( ResolvedSourceString source_str); // A `DecimalFloatingPoint` is an unsigned floating-point value. // https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#:~:text=on%20its%20AttributeNames.%0A%0A%20%20%20o-,decimal%2Dfloating%2Dpoint,-%3A%20an%20unquoted%20string DecimalFloatingPoint; MEDIA_EXPORT ParseStatus::Or<DecimalFloatingPoint> ParseDecimalFloatingPoint( ResolvedSourceString source_str); // A `SignedDecimalFloatingPoint` is a signed floating-point value. // https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#:~:text=decimal%20positional%20notation.%0A%0A%20%20%20o-,signed%2Ddecimal%2Dfloating%2Dpoint,-%3A%20an%20unquoted%20string SignedDecimalFloatingPoint; MEDIA_EXPORT ParseStatus::Or<SignedDecimalFloatingPoint> ParseSignedDecimalFloatingPoint(ResolvedSourceString source_str); // A `DecimalResolution` is a set of two `DecimalInteger`s describing width and // height. // https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#:~:text=enumerated%2Dstring%2Dlist.%0A%0A%20%20%20o-,decimal%2Dresolution,-%3A%20two%20decimal%2Dintegers struct MEDIA_EXPORT DecimalResolution { … }; // This is similar to `ByteRangeExpression`, but with a stronger contract: // - `length` is non-zero // - `offset` is non-optional // - `offset+length` may not overflow `types::DecimalInteger` class MEDIA_EXPORT ByteRange { … }; // Parses a string surrounded by double-quotes ("), returning the inner string. // These appear in the context of attribute-lists, and are subject to variable // substitution. `sub_buffer` must outlive the returned string. // `allow_empty` determines whether an empty quoted string is accepted, (after // variable substitution) which isn't the case for most attributes. MEDIA_EXPORT ParseStatus::Or<ResolvedSourceString> ParseQuotedString( SourceString source_str, const VariableDictionary& variable_dict, VariableDictionary::SubstitutionBuffer& sub_buffer, bool allow_empty = false); // Parses a string surrounded by double-quotes ("), returning the interior // string. These appear in the context of attribute-lists, however certain tags // disallow variable substitution so this function exists to serve those. // `allow_empty` determines whether an empty quoted string is accepted, which // isn't the case for most attributes. MEDIA_EXPORT ParseStatus::Or<SourceString> ParseQuotedStringWithoutSubstitution( SourceString source_str, bool allow_empty = false); // Provides an iterator-style interface over attribute-lists. // Since the number of attributes expected in an attribute-list for a tag varies // (most have 2-4, the highest has 15), rather than prescribing a specific data // structure to use, callers can iterate over the list and build their own. // `AttributeMap` exists which can match items against a pre-determined set of // keys, which may be stored on the stack. struct MEDIA_EXPORT AttributeListIterator { … }; // Represents a map of attributes with a fixed set of keys. // This is essentially a `base::fixed_flat_map`, with the advantage of erasing // the size of the map from its type. struct MEDIA_EXPORT AttributeMap { … }; // Represents a string that is guaranteed to be a non-empty, and consisting only // of characters in the set {[a-z], [A-Z], [0-9], _, -}. Variable names are // case-sensitive. class MEDIA_EXPORT VariableName { … }; // Represents a string that is guaranteed to be non-empty, and consisting only // of characters in the set {[a-z], [A-Z], [0-9], +, /, =, ., -, _}. // This is used in the 'STABLE-VARIANT-ID' and 'STABLE-RENDITION-ID' attributes // of the EXT-X-STREAM-INF and EXT-X-MEDIA tags, respectively. class MEDIA_EXPORT StableId { … }; inline bool operator==(const StableId& lhs, const StableId& rhs) { … } inline bool operator!=(const StableId& lhs, const StableId& rhs) { … } inline bool operator<(const StableId& lhs, const StableId& rhs) { … } inline bool operator>(const StableId& lhs, const StableId& rhs) { … } // Represents the contents of the 'INSTREAM-ID' attribute on the 'EXT-X-MEDIA' // tag. class MEDIA_EXPORT InstreamId { … }; // Represents the contents of the 'CHANNELS' attribute on the 'EXT-X-MEDIA' tag // for an audio stream. // https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#section-4.4.6.1:~:text=If%20the%20TYPE%20attribute%20is%20AUDIO%2C%20then%20the%20first%20parameter%20is%20a class MEDIA_EXPORT AudioChannels { … }; } // namespace media::hls::types #endif // MEDIA_FORMATS_HLS_TYPES_H_