Backed out 15 changesets (bug 1852806) for causing mda failures on test_video_low_pow...
[gecko.git] / dom / media / MediaMIMETypes.cpp
bloba5da17ea44e730870bb3473f475d8605c1dd7d42
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/. */
7 #include "MediaMIMETypes.h"
9 #include "nsContentTypeParser.h"
10 #include "mozilla/dom/MediaCapabilitiesBinding.h"
12 namespace mozilla {
14 template <int N>
15 static bool StartsWith(const nsACString& string, const char (&prefix)[N]) {
16 if (N - 1 > string.Length()) {
17 return false;
19 return memcmp(string.Data(), prefix, N - 1) == 0;
22 bool MediaMIMEType::HasApplicationMajorType() const {
23 return StartsWith(mMIMEType, "application/");
26 bool MediaMIMEType::HasAudioMajorType() const {
27 return StartsWith(mMIMEType, "audio/");
30 bool MediaMIMEType::HasVideoMajorType() const {
31 return StartsWith(mMIMEType, "video/");
34 size_t MediaMIMEType::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
35 return mMIMEType.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
38 MediaMIMEType::MediaMIMEType(const nsACString& aType) : mMIMEType(aType) {}
40 Maybe<MediaMIMEType> MakeMediaMIMEType(const nsAString& aType) {
41 nsContentTypeParser parser(aType);
42 nsAutoString mime;
43 nsresult rv = parser.GetType(mime);
44 if (!NS_SUCCEEDED(rv) || mime.IsEmpty()) {
45 return Nothing();
48 NS_ConvertUTF16toUTF8 mime8{mime};
49 if (!IsMediaMIMEType(mime8)) {
50 return Nothing();
53 return Some(MediaMIMEType(mime8));
56 Maybe<MediaMIMEType> MakeMediaMIMEType(const nsACString& aType) {
57 return MakeMediaMIMEType(NS_ConvertUTF8toUTF16(aType));
60 Maybe<MediaMIMEType> MakeMediaMIMEType(const char* aType) {
61 if (!aType) {
62 return Nothing();
64 return MakeMediaMIMEType(nsDependentCString(aType));
67 bool MediaCodecs::Contains(const nsAString& aCodec) const {
68 for (const auto& myCodec : Range()) {
69 if (myCodec == aCodec) {
70 return true;
73 return false;
76 bool MediaCodecs::ContainsAll(const MediaCodecs& aCodecs) const {
77 const auto& codecsToTest = aCodecs.Range();
78 for (const auto& codecToTest : codecsToTest) {
79 if (!Contains(codecToTest)) {
80 return false;
83 return true;
86 bool MediaCodecs::ContainsPrefix(const nsAString& aCodecPrefix) const {
87 const size_t prefixLength = aCodecPrefix.Length();
88 for (const auto& myCodec : Range()) {
89 if (myCodec.Length() >= prefixLength &&
90 memcmp(myCodec.Data(), aCodecPrefix.Data(),
91 prefixLength * sizeof(char16_t)) == 0) {
92 return true;
95 return false;
98 size_t MediaCodecs::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
99 return mCodecs.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
102 static int32_t GetParameterAsNumber(const nsContentTypeParser& aParser,
103 const char* aParameter,
104 const int32_t aErrorReturn) {
105 nsAutoString parameterString;
106 nsresult rv = aParser.GetParameter(aParameter, parameterString);
107 if (NS_FAILED_impl(rv)) {
108 return aErrorReturn;
110 int32_t number = parameterString.ToInteger(&rv);
111 if (MOZ_UNLIKELY(NS_FAILED_impl(rv))) {
112 return aErrorReturn;
114 return number;
117 MediaExtendedMIMEType::MediaExtendedMIMEType(
118 const nsACString& aOriginalString, const nsACString& aMIMEType,
119 bool aHaveCodecs, const nsAString& aCodecs, int32_t aWidth, int32_t aHeight,
120 double aFramerate, int32_t aBitrate)
121 : mOriginalString(aOriginalString),
122 mMIMEType(aMIMEType),
123 mHaveCodecs(aHaveCodecs),
124 mCodecs(aCodecs),
125 mWidth(aWidth),
126 mHeight(aHeight),
127 mFramerate(aFramerate),
128 mBitrate(aBitrate) {}
130 MediaExtendedMIMEType::MediaExtendedMIMEType(
131 const nsACString& aOriginalString, const nsACString& aMIMEType,
132 bool aHaveCodecs, const nsAString& aCodecs, int32_t aChannels,
133 int32_t aSamplerate, int32_t aBitrate)
134 : mOriginalString(aOriginalString),
135 mMIMEType(aMIMEType),
136 mHaveCodecs(aHaveCodecs),
137 mCodecs(aCodecs),
138 mChannels(aChannels),
139 mSamplerate(aSamplerate),
140 mBitrate(aBitrate) {}
142 MediaExtendedMIMEType::MediaExtendedMIMEType(const MediaMIMEType& aType)
143 : mOriginalString(aType.AsString()), mMIMEType(aType) {}
145 MediaExtendedMIMEType::MediaExtendedMIMEType(MediaMIMEType&& aType)
146 : mOriginalString(aType.AsString()), mMIMEType(std::move(aType)) {}
148 Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(const nsAString& aType) {
149 nsContentTypeParser parser(aType);
150 nsAutoString mime;
151 nsresult rv = parser.GetType(mime);
152 if (!NS_SUCCEEDED(rv) || mime.IsEmpty()) {
153 return Nothing();
156 NS_ConvertUTF16toUTF8 mime8{mime};
157 if (!IsMediaMIMEType(mime8)) {
158 return Nothing();
161 nsAutoString codecs;
162 rv = parser.GetParameter("codecs", codecs);
163 bool haveCodecs = NS_SUCCEEDED(rv);
165 int32_t width = GetParameterAsNumber(parser, "width", -1);
166 int32_t height = GetParameterAsNumber(parser, "height", -1);
167 double framerate = GetParameterAsNumber(parser, "framerate", -1);
168 int32_t bitrate = GetParameterAsNumber(parser, "bitrate", -1);
170 return Some(MediaExtendedMIMEType(NS_ConvertUTF16toUTF8(aType), mime8,
171 haveCodecs, codecs, width, height,
172 framerate, bitrate));
175 Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(
176 const dom::VideoConfiguration& aConfig) {
177 if (aConfig.mContentType.IsEmpty()) {
178 return Nothing();
180 nsContentTypeParser parser(aConfig.mContentType);
181 nsAutoString mime;
182 nsresult rv = parser.GetType(mime);
183 if (!NS_SUCCEEDED(rv) || mime.IsEmpty()) {
184 return Nothing();
187 NS_ConvertUTF16toUTF8 mime8{mime};
188 if (!IsMediaMIMEType(mime8)) {
189 return Nothing();
192 nsAutoString codecs;
193 rv = parser.GetParameter("codecs", codecs);
194 bool haveCodecs = NS_SUCCEEDED(rv);
196 if (!std::isfinite(aConfig.mFramerate) || aConfig.mFramerate <= 0.0) {
197 return Nothing();
200 return Some(MediaExtendedMIMEType(
201 NS_ConvertUTF16toUTF8(aConfig.mContentType), mime8, haveCodecs, codecs,
202 aConfig.mWidth, aConfig.mHeight, aConfig.mFramerate, aConfig.mBitrate));
205 Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(
206 const dom::AudioConfiguration& aConfig) {
207 if (aConfig.mContentType.IsEmpty()) {
208 return Nothing();
210 nsContentTypeParser parser(aConfig.mContentType);
211 nsAutoString mime;
212 nsresult rv = parser.GetType(mime);
213 if (!NS_SUCCEEDED(rv) || mime.IsEmpty()) {
214 return Nothing();
217 NS_ConvertUTF16toUTF8 mime8{mime};
218 if (!IsMediaMIMEType(mime8)) {
219 return Nothing();
222 nsAutoString codecs;
223 rv = parser.GetParameter("codecs", codecs);
224 bool haveCodecs = NS_SUCCEEDED(rv);
226 int32_t channels = 2; // use a stereo config if not known.
227 if (aConfig.mChannels.WasPassed()) {
228 // A channels string was passed. Make sure it is valid.
229 nsresult error;
230 double value = aConfig.mChannels.Value().ToDouble(&error);
231 if (NS_FAILED(error)) {
232 return Nothing();
234 // Value is a channel configuration such as 5.1. We want to treat this as 6.
235 channels = value;
236 double fp = value - channels;
237 // round up as .1 and .2 aren't exactly expressible in binary.
238 channels += (fp * 10) + .5;
241 return Some(MediaExtendedMIMEType(
242 NS_ConvertUTF16toUTF8(aConfig.mContentType), mime8, haveCodecs, codecs,
243 channels,
244 aConfig.mSamplerate.WasPassed() ? aConfig.mSamplerate.Value() : 48000,
245 aConfig.mBitrate.WasPassed() ? aConfig.mBitrate.Value() : 131072));
248 size_t MediaExtendedMIMEType::SizeOfExcludingThis(
249 MallocSizeOf aMallocSizeOf) const {
250 return mOriginalString.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
251 mMIMEType.SizeOfExcludingThis(aMallocSizeOf) +
252 mCodecs.SizeOfExcludingThis(aMallocSizeOf);
255 Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(
256 const nsACString& aType) {
257 return MakeMediaExtendedMIMEType(NS_ConvertUTF8toUTF16(aType));
260 Maybe<MediaExtendedMIMEType> MakeMediaExtendedMIMEType(const char* aType) {
261 if (!aType) {
262 return Nothing();
264 return MakeMediaExtendedMIMEType(nsDependentCString(aType));
267 } // namespace mozilla