From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- dom/media/MediaMIMETypes.cpp | 267 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 dom/media/MediaMIMETypes.cpp (limited to 'dom/media/MediaMIMETypes.cpp') diff --git a/dom/media/MediaMIMETypes.cpp b/dom/media/MediaMIMETypes.cpp new file mode 100644 index 0000000000..a5da17ea44 --- /dev/null +++ b/dom/media/MediaMIMETypes.cpp @@ -0,0 +1,267 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "MediaMIMETypes.h" + +#include "nsContentTypeParser.h" +#include "mozilla/dom/MediaCapabilitiesBinding.h" + +namespace mozilla { + +template +static bool StartsWith(const nsACString& string, const char (&prefix)[N]) { + if (N - 1 > string.Length()) { + return false; + } + return memcmp(string.Data(), prefix, N - 1) == 0; +} + +bool MediaMIMEType::HasApplicationMajorType() const { + return StartsWith(mMIMEType, "application/"); +} + +bool MediaMIMEType::HasAudioMajorType() const { + return StartsWith(mMIMEType, "audio/"); +} + +bool MediaMIMEType::HasVideoMajorType() const { + return StartsWith(mMIMEType, "video/"); +} + +size_t MediaMIMEType::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { + return mMIMEType.SizeOfExcludingThisIfUnshared(aMallocSizeOf); +} + +MediaMIMEType::MediaMIMEType(const nsACString& aType) : mMIMEType(aType) {} + +Maybe MakeMediaMIMEType(const nsAString& aType) { + nsContentTypeParser parser(aType); + nsAutoString mime; + nsresult rv = parser.GetType(mime); + if (!NS_SUCCEEDED(rv) || mime.IsEmpty()) { + return Nothing(); + } + + NS_ConvertUTF16toUTF8 mime8{mime}; + if (!IsMediaMIMEType(mime8)) { + return Nothing(); + } + + return Some(MediaMIMEType(mime8)); +} + +Maybe MakeMediaMIMEType(const nsACString& aType) { + return MakeMediaMIMEType(NS_ConvertUTF8toUTF16(aType)); +} + +Maybe MakeMediaMIMEType(const char* aType) { + if (!aType) { + return Nothing(); + } + return MakeMediaMIMEType(nsDependentCString(aType)); +} + +bool MediaCodecs::Contains(const nsAString& aCodec) const { + for (const auto& myCodec : Range()) { + if (myCodec == aCodec) { + return true; + } + } + return false; +} + +bool MediaCodecs::ContainsAll(const MediaCodecs& aCodecs) const { + const auto& codecsToTest = aCodecs.Range(); + for (const auto& codecToTest : codecsToTest) { + if (!Contains(codecToTest)) { + return false; + } + } + return true; +} + +bool MediaCodecs::ContainsPrefix(const nsAString& aCodecPrefix) const { + const size_t prefixLength = aCodecPrefix.Length(); + for (const auto& myCodec : Range()) { + if (myCodec.Length() >= prefixLength && + memcmp(myCodec.Data(), aCodecPrefix.Data(), + prefixLength * sizeof(char16_t)) == 0) { + return true; + } + } + return false; +} + +size_t MediaCodecs::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { + return mCodecs.SizeOfExcludingThisIfUnshared(aMallocSizeOf); +} + +static int32_t GetParameterAsNumber(const nsContentTypeParser& aParser, + const char* aParameter, + const int32_t aErrorReturn) { + nsAutoString parameterString; + nsresult rv = aParser.GetParameter(aParameter, parameterString); + if (NS_FAILED_impl(rv)) { + return aErrorReturn; + } + int32_t number = parameterString.ToInteger(&rv); + if (MOZ_UNLIKELY(NS_FAILED_impl(rv))) { + return aErrorReturn; + } + return number; +} + +MediaExtendedMIMEType::MediaExtendedMIMEType( + const nsACString& aOriginalString, const nsACString& aMIMEType, + bool aHaveCodecs, const nsAString& aCodecs, int32_t aWidth, int32_t aHeight, + double aFramerate, int32_t aBitrate) + : mOriginalString(aOriginalString), + mMIMEType(aMIMEType), + mHaveCodecs(aHaveCodecs), + mCodecs(aCodecs), + mWidth(aWidth), + mHeight(aHeight), + mFramerate(aFramerate), + mBitrate(aBitrate) {} + +MediaExtendedMIMEType::MediaExtendedMIMEType( + const nsACString& aOriginalString, const nsACString& aMIMEType, + bool aHaveCodecs, const nsAString& aCodecs, int32_t aChannels, + int32_t aSamplerate, int32_t aBitrate) + : mOriginalString(aOriginalString), + mMIMEType(aMIMEType), + mHaveCodecs(aHaveCodecs), + mCodecs(aCodecs), + mChannels(aChannels), + mSamplerate(aSamplerate), + mBitrate(aBitrate) {} + +MediaExtendedMIMEType::MediaExtendedMIMEType(const MediaMIMEType& aType) + : mOriginalString(aType.AsString()), mMIMEType(aType) {} + +MediaExtendedMIMEType::MediaExtendedMIMEType(MediaMIMEType&& aType) + : mOriginalString(aType.AsString()), mMIMEType(std::move(aType)) {} + +Maybe MakeMediaExtendedMIMEType(const nsAString& aType) { + nsContentTypeParser parser(aType); + nsAutoString mime; + nsresult rv = parser.GetType(mime); + if (!NS_SUCCEEDED(rv) || mime.IsEmpty()) { + return Nothing(); + } + + NS_ConvertUTF16toUTF8 mime8{mime}; + if (!IsMediaMIMEType(mime8)) { + return Nothing(); + } + + nsAutoString codecs; + rv = parser.GetParameter("codecs", codecs); + bool haveCodecs = NS_SUCCEEDED(rv); + + int32_t width = GetParameterAsNumber(parser, "width", -1); + int32_t height = GetParameterAsNumber(parser, "height", -1); + double framerate = GetParameterAsNumber(parser, "framerate", -1); + int32_t bitrate = GetParameterAsNumber(parser, "bitrate", -1); + + return Some(MediaExtendedMIMEType(NS_ConvertUTF16toUTF8(aType), mime8, + haveCodecs, codecs, width, height, + framerate, bitrate)); +} + +Maybe MakeMediaExtendedMIMEType( + const dom::VideoConfiguration& aConfig) { + if (aConfig.mContentType.IsEmpty()) { + return Nothing(); + } + nsContentTypeParser parser(aConfig.mContentType); + nsAutoString mime; + nsresult rv = parser.GetType(mime); + if (!NS_SUCCEEDED(rv) || mime.IsEmpty()) { + return Nothing(); + } + + NS_ConvertUTF16toUTF8 mime8{mime}; + if (!IsMediaMIMEType(mime8)) { + return Nothing(); + } + + nsAutoString codecs; + rv = parser.GetParameter("codecs", codecs); + bool haveCodecs = NS_SUCCEEDED(rv); + + if (!std::isfinite(aConfig.mFramerate) || aConfig.mFramerate <= 0.0) { + return Nothing(); + } + + return Some(MediaExtendedMIMEType( + NS_ConvertUTF16toUTF8(aConfig.mContentType), mime8, haveCodecs, codecs, + aConfig.mWidth, aConfig.mHeight, aConfig.mFramerate, aConfig.mBitrate)); +} + +Maybe MakeMediaExtendedMIMEType( + const dom::AudioConfiguration& aConfig) { + if (aConfig.mContentType.IsEmpty()) { + return Nothing(); + } + nsContentTypeParser parser(aConfig.mContentType); + nsAutoString mime; + nsresult rv = parser.GetType(mime); + if (!NS_SUCCEEDED(rv) || mime.IsEmpty()) { + return Nothing(); + } + + NS_ConvertUTF16toUTF8 mime8{mime}; + if (!IsMediaMIMEType(mime8)) { + return Nothing(); + } + + nsAutoString codecs; + rv = parser.GetParameter("codecs", codecs); + bool haveCodecs = NS_SUCCEEDED(rv); + + int32_t channels = 2; // use a stereo config if not known. + if (aConfig.mChannels.WasPassed()) { + // A channels string was passed. Make sure it is valid. + nsresult error; + double value = aConfig.mChannels.Value().ToDouble(&error); + if (NS_FAILED(error)) { + return Nothing(); + } + // Value is a channel configuration such as 5.1. We want to treat this as 6. + channels = value; + double fp = value - channels; + // round up as .1 and .2 aren't exactly expressible in binary. + channels += (fp * 10) + .5; + } + + return Some(MediaExtendedMIMEType( + NS_ConvertUTF16toUTF8(aConfig.mContentType), mime8, haveCodecs, codecs, + channels, + aConfig.mSamplerate.WasPassed() ? aConfig.mSamplerate.Value() : 48000, + aConfig.mBitrate.WasPassed() ? aConfig.mBitrate.Value() : 131072)); +} + +size_t MediaExtendedMIMEType::SizeOfExcludingThis( + MallocSizeOf aMallocSizeOf) const { + return mOriginalString.SizeOfExcludingThisIfUnshared(aMallocSizeOf) + + mMIMEType.SizeOfExcludingThis(aMallocSizeOf) + + mCodecs.SizeOfExcludingThis(aMallocSizeOf); +} + +Maybe MakeMediaExtendedMIMEType( + const nsACString& aType) { + return MakeMediaExtendedMIMEType(NS_ConvertUTF8toUTF16(aType)); +} + +Maybe MakeMediaExtendedMIMEType(const char* aType) { + if (!aType) { + return Nothing(); + } + return MakeMediaExtendedMIMEType(nsDependentCString(aType)); +} + +} // namespace mozilla -- cgit v1.2.3