1 From: Alessandro Decina <alessandro.d@gmail.com> |
1 # HG changeset patch |
|
2 # Parent 9fe99f8a584f2369a88bfb5281fd6bc95eb2593c |
2 Bug 760140 - Query the GstRegistry for the required demuxers/decoders from canPlayType |
3 Bug 760140 - Query the GstRegistry for the required demuxers/decoders from canPlayType |
3 |
4 |
4 diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp |
5 |
5 --- a/content/base/src/nsContentUtils.cpp |
6 diff --git a/content/media/DecoderTraits.cpp b/content/media/DecoderTraits.cpp |
6 +++ b/content/base/src/nsContentUtils.cpp |
7 --- a/content/media/DecoderTraits.cpp |
7 @@ -143,16 +143,19 @@ |
8 +++ b/content/media/DecoderTraits.cpp |
8 #include "xpcprivate.h" // nsXPConnect |
9 @@ -7,16 +7,18 @@ |
9 #include "nsScriptSecurityManager.h" |
10 #include "DecoderTraits.h" |
10 #include "nsIChannelPolicy.h" |
11 #include "MediaDecoder.h" |
11 #include "nsChannelPolicy.h" |
12 #include "nsCharSeparatedTokenizer.h" |
12 #include "nsIContentSecurityPolicy.h" |
13 #ifdef MOZ_MEDIA_PLUGINS |
13 #include "nsContentDLF.h" |
14 #include "MediaPluginHost.h" |
14 #ifdef MOZ_MEDIA |
15 #endif |
15 #include "nsHTMLMediaElement.h" |
16 #ifdef MOZ_GSTREAMER |
16 +#ifdef MOZ_GSTREAMER |
17 #include "mozilla/Preferences.h" |
17 +#include "GStreamerDecoder.h" |
18 +#include "GStreamerDecoder.h" |
18 +#endif |
19 +#include "nsXPCOMStrings.h" |
19 #endif |
20 #endif |
20 #include "nsDOMTouchEvent.h" |
21 #ifdef MOZ_WMF |
21 #include "nsIContentViewer.h" |
22 #include "WMFDecoder.h" |
22 #include "nsIObjectLoadingContent.h" |
23 #endif |
23 #include "nsCCUncollectableMarker.h" |
24 |
24 #include "mozilla/Base64.h" |
25 namespace mozilla |
25 #include "mozilla/Preferences.h" |
26 { |
26 #include "nsDOMMutationObserver.h" |
27 |
27 diff --git a/content/html/content/public/nsHTMLMediaElement.h b/content/html/content/public/nsHTMLMediaElement.h |
28 @@ -137,48 +139,35 @@ |
28 --- a/content/html/content/public/nsHTMLMediaElement.h |
29 return false; |
29 +++ b/content/html/content/public/nsHTMLMediaElement.h |
30 } |
30 @@ -259,17 +259,19 @@ public: |
31 |
31 void UpdateMediaSize(nsIntSize size); |
32 return CodecListContains(gWebMTypes, aType); |
32 |
33 } |
33 // Returns the CanPlayStatus indicating if we can handle this |
34 #endif |
34 // MIME type. The MIME type should not include the codecs parameter. |
35 |
35 // If it returns anything other than CANPLAY_NO then it also |
36 #ifdef MOZ_GSTREAMER |
36 // returns a null-terminated list of supported codecs |
37 -static const char* const gH264Types[4] = { |
37 // in *aSupportedCodecs. This list should not be freed, it is static data. |
38 - "video/mp4", |
38 static CanPlayStatus CanHandleMediaType(const char* aMIMEType, |
39 - "video/3gpp", |
39 - char const *const ** aSupportedCodecs); |
40 - "video/quicktime", |
40 + const char* aCodecs, |
41 - nullptr |
41 + char const *const ** aSupportedCodecs, |
42 -}; |
42 + bool* aCheckSupportedCodecs); |
43 - |
43 |
44 bool |
44 // Returns the CanPlayStatus indicating if we can handle the |
45 DecoderTraits::IsGStreamerSupportedType(const nsACString& aMimeType) |
45 // full MIME type including the optional codecs parameter. |
46 { |
46 static CanPlayStatus GetCanPlay(const nsAString& aType); |
47 if (!MediaDecoder::IsGStreamerEnabled()) |
47 |
48 return false; |
48 // Returns true if we should handle this MIME type when it appears |
49 - if (IsH264Type(aMimeType)) |
49 // as an <object> or as a toplevel page. If, in practice, our support |
50 + if (GStreamerDecoder::CanHandleMediaType(aMimeType, nullptr)) |
50 // for the type is more limited than appears in the wild, we should return |
51 return true; |
51 @@ -292,18 +294,16 @@ public: |
52 if (!Preferences::GetBool("media.prefer-gstreamer", false)) |
|
53 return false; |
52 #ifdef MOZ_WEBM |
54 #ifdef MOZ_WEBM |
53 static bool IsWebMType(const nsACString& aType); |
55 if (IsWebMType(aMimeType)) |
54 static const char gWebMTypes[2][11]; |
56 return true; |
55 static char const *const gWebMCodecs[4]; |
57 #endif |
56 #endif |
58 #ifdef MOZ_OGG |
57 |
59 if (IsOggType(aMimeType)) |
58 #ifdef MOZ_GSTREAMER |
60 return true; |
59 static bool IsGStreamerSupportedType(const nsACString& aType); |
61 #endif |
60 - static bool IsH264Type(const nsACString& aType); |
|
61 - static const char gH264Types[3][16]; |
|
62 #endif |
|
63 |
|
64 #ifdef MOZ_WIDGET_GONK |
|
65 static bool IsOmxSupportedType(const nsACString& aType); |
|
66 static const char gOmxTypes[5][16]; |
|
67 #endif |
|
68 |
|
69 #if defined(MOZ_GSTREAMER) || defined(MOZ_WIDGET_GONK) |
|
70 diff --git a/content/html/content/src/nsHTMLMediaElement.cpp b/content/html/content/src/nsHTMLMediaElement.cpp |
|
71 --- a/content/html/content/src/nsHTMLMediaElement.cpp |
|
72 +++ b/content/html/content/src/nsHTMLMediaElement.cpp |
|
73 @@ -2213,50 +2213,29 @@ nsHTMLMediaElement::IsWebMType(const nsA |
|
74 return true; |
|
75 } |
|
76 } |
|
77 |
|
78 return false; |
62 return false; |
79 } |
63 } |
80 #endif |
64 - |
|
65 -bool |
|
66 -DecoderTraits::IsH264Type(const nsACString& aType) |
|
67 -{ |
|
68 - return CodecListContains(gH264Types, aType); |
|
69 -} |
|
70 #endif |
|
71 |
|
72 #ifdef MOZ_WIDGET_GONK |
|
73 static const char* const gOmxTypes[6] = { |
|
74 "audio/mpeg", |
|
75 "audio/mp4", |
|
76 "video/mp4", |
|
77 "video/3gpp", |
|
78 @@ -190,19 +179,17 @@ |
|
79 DecoderTraits::IsOmxSupportedType(const nsACString& aType) |
|
80 { |
|
81 if (!MediaDecoder::IsOmxEnabled()) { |
|
82 return false; |
|
83 } |
|
84 |
|
85 return CodecListContains(gOmxTypes, aType); |
|
86 } |
|
87 -#endif |
81 |
88 |
82 -#if defined(MOZ_GSTREAMER) || defined(MOZ_WIDGET_GONK) |
89 -#if defined(MOZ_GSTREAMER) || defined(MOZ_WIDGET_GONK) |
83 +#ifdef MOZ_WIDGET_GONK |
90 static char const *const gH264Codecs[9] = { |
84 char const *const nsHTMLMediaElement::gH264Codecs[9] = { |
|
85 "avc1.42E01E", // H.264 Constrained Baseline Profile Level 3.0 |
91 "avc1.42E01E", // H.264 Constrained Baseline Profile Level 3.0 |
86 "avc1.42001E", // H.264 Baseline Profile Level 3.0 |
92 "avc1.42001E", // H.264 Baseline Profile Level 3.0 |
87 "avc1.58A01E", // H.264 Extended Profile Level 3.0 |
93 "avc1.58A01E", // H.264 Extended Profile Level 3.0 |
88 "avc1.4D401E", // H.264 Main Profile Level 3.0 |
94 "avc1.4D401E", // H.264 Main Profile Level 3.0 |
89 "avc1.64001E", // H.264 High Profile Level 3.0 |
95 "avc1.64001E", // H.264 High Profile Level 3.0 |
90 "avc1.64001F", // H.264 High Profile Level 3.1 |
96 "avc1.64001F", // H.264 High Profile Level 3.1 |
91 "mp4v.20.3", // 3GPP |
97 "mp4v.20.3", // 3GPP |
92 "mp4a.40.2", // AAC-LC |
98 @@ -303,19 +290,19 @@ |
93 nullptr |
99 #ifdef MOZ_DASH |
94 }; |
|
95 -#endif |
|
96 - |
|
97 -#ifdef MOZ_GSTREAMER |
|
98 -const char nsHTMLMediaElement::gH264Types[3][16] = { |
|
99 - "video/mp4", |
|
100 - "video/3gpp", |
|
101 - "video/quicktime", |
|
102 -}; |
|
103 - |
|
104 -bool |
|
105 -nsHTMLMediaElement::IsH264Type(const nsACString& aType) |
|
106 -{ |
|
107 - for (uint32_t i = 0; i < ArrayLength(gH264Types); ++i) { |
|
108 - if (aType.EqualsASCII(gH264Types[i])) { |
|
109 - return true; |
|
110 - } |
|
111 - } |
|
112 - return false; |
|
113 -} |
|
114 -#endif |
|
115 - |
|
116 -#ifdef MOZ_WIDGET_GONK |
|
117 + |
|
118 const char nsHTMLMediaElement::gOmxTypes[5][16] = { |
|
119 "audio/mpeg", |
|
120 "audio/mp4", |
|
121 "video/mp4", |
|
122 "video/3gpp", |
|
123 "video/quicktime", |
|
124 }; |
|
125 |
|
126 @@ -2319,18 +2298,22 @@ nsHTMLMediaElement::IsDASHMPDType(const |
|
127 |
|
128 return false; |
|
129 } |
|
130 #endif |
|
131 |
|
132 /* static */ |
|
133 nsHTMLMediaElement::CanPlayStatus |
|
134 nsHTMLMediaElement::CanHandleMediaType(const char* aMIMEType, |
|
135 - char const *const ** aCodecList) |
|
136 + const char *aCodecs, |
|
137 + char const *const ** aCodecList, |
|
138 + bool* aCheckCodecList) |
|
139 { |
|
140 + if (aCheckCodecList) |
|
141 + *aCheckCodecList = true; |
|
142 #ifdef MOZ_RAW |
|
143 if (IsRawType(nsDependentCString(aMIMEType))) { |
|
144 *aCodecList = gRawCodecs; |
|
145 return CANPLAY_MAYBE; |
|
146 } |
|
147 #endif |
|
148 #ifdef MOZ_OGG |
|
149 if (IsOggType(nsDependentCString(aMIMEType))) { |
|
150 @@ -2354,20 +2337,22 @@ nsHTMLMediaElement::CanHandleMediaType(c |
|
151 if (IsDASHMPDType(nsDependentCString(aMIMEType))) { |
100 if (IsDASHMPDType(nsDependentCString(aMIMEType))) { |
152 // DASH manifest uses WebM codecs only. |
101 // DASH manifest uses WebM codecs only. |
153 *aCodecList = gWebMCodecs; |
102 codecList = gWebMCodecs; |
154 return CANPLAY_YES; |
103 result = CANPLAY_YES; |
155 } |
104 } |
156 #endif |
105 #endif |
157 |
|
158 #ifdef MOZ_GSTREAMER |
106 #ifdef MOZ_GSTREAMER |
159 - if (IsH264Type(nsDependentCString(aMIMEType))) { |
107 - if (IsH264Type(nsDependentCString(aMIMEType))) { |
160 - *aCodecList = gH264Codecs; |
108 - codecList = gH264Codecs; |
161 - return CANPLAY_MAYBE; |
109 - result = CANPLAY_MAYBE; |
162 - } |
110 + if (GStreamerDecoder::CanHandleMediaType(nsDependentCString(aMIMEType), |
163 + if (aCheckCodecList) |
111 + aHaveRequestedCodecs ? &aRequestedCodecs : nullptr)) { |
164 + *aCheckCodecList = false; |
|
165 + if (aCodecList) |
|
166 + *aCodecList = nullptr; |
|
167 + if (GStreamerDecoder::CanHandleMediaType(aMIMEType, aCodecs)) |
|
168 + return CANPLAY_YES; |
112 + return CANPLAY_YES; |
|
113 } |
169 #endif |
114 #endif |
170 #ifdef MOZ_WIDGET_GONK |
115 #ifdef MOZ_WIDGET_GONK |
171 if (IsOmxSupportedType(nsDependentCString(aMIMEType))) { |
116 if (IsOmxSupportedType(nsDependentCString(aMIMEType))) { |
172 *aCodecList = gH264Codecs; |
117 codecList = gH264Codecs; |
173 return CANPLAY_MAYBE; |
118 result = CANPLAY_MAYBE; |
|
119 } |
|
120 #endif |
|
121 @@ -324,17 +311,17 @@ |
|
122 result = CANPLAY_MAYBE; |
174 } |
123 } |
175 #endif |
124 #endif |
176 #ifdef MOZ_MEDIA_PLUGINS |
125 #ifdef MOZ_MEDIA_PLUGINS |
177 @@ -2388,17 +2373,17 @@ bool nsHTMLMediaElement::ShouldHandleMed |
126 if (MediaDecoder::IsMediaPluginsEnabled() && |
178 if (IsOggType(nsDependentCString(aMIMEType))) |
127 GetMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), &codecList)) |
179 return true; |
128 result = CANPLAY_MAYBE; |
180 #endif |
129 #endif |
181 #ifdef MOZ_WEBM |
130 - if (result == CANPLAY_NO || !aHaveRequestedCodecs) { |
182 if (IsWebMType(nsDependentCString(aMIMEType))) |
131 + if (result == CANPLAY_NO || !aHaveRequestedCodecs || !codecList) { |
183 return true; |
132 return result; |
184 #endif |
133 } |
185 #ifdef MOZ_GSTREAMER |
134 |
186 - if (IsH264Type(nsDependentCString(aMIMEType))) |
|
187 + if (GStreamerDecoder::CanHandleMediaType(aMIMEType, nullptr)) |
|
188 return true; |
|
189 #endif |
|
190 #ifdef MOZ_WIDGET_GONK |
|
191 if (IsOmxSupportedType(nsDependentCString(aMIMEType))) { |
|
192 return true; |
|
193 } |
|
194 #endif |
|
195 #ifdef MOZ_MEDIA_PLUGINS |
|
196 @@ -2429,26 +2414,31 @@ nsHTMLMediaElement::GetCanPlay(const nsA |
|
197 { |
|
198 nsContentTypeParser parser(aType); |
|
199 nsAutoString mimeType; |
|
200 nsresult rv = parser.GetType(mimeType); |
|
201 if (NS_FAILED(rv)) |
|
202 return CANPLAY_NO; |
|
203 |
|
204 NS_ConvertUTF16toUTF8 mimeTypeUTF8(mimeType); |
|
205 + nsAutoString codecs; |
|
206 + rv = parser.GetParameter("codecs", codecs); |
|
207 + NS_ConvertUTF16toUTF8 codecsUTF8(codecs); |
|
208 char const *const * supportedCodecs; |
|
209 + bool checkSupportedCodecs = true; |
|
210 CanPlayStatus status = CanHandleMediaType(mimeTypeUTF8.get(), |
|
211 - &supportedCodecs); |
|
212 + codecsUTF8.get(), |
|
213 + &supportedCodecs, |
|
214 + &checkSupportedCodecs); |
|
215 if (status == CANPLAY_NO) |
|
216 return CANPLAY_NO; |
|
217 |
|
218 - nsAutoString codecs; |
|
219 - rv = parser.GetParameter("codecs", codecs); |
|
220 - if (NS_FAILED(rv)) { |
|
221 - // Parameter not found or whatever |
|
222 + if (codecs.IsEmpty() || !checkSupportedCodecs) { |
|
223 + /* no codecs to check for or they were already checked in CanHandleMediaType |
|
224 + * above */ |
|
225 return status; |
|
226 } |
|
227 |
|
228 CanPlayStatus result = CANPLAY_YES; |
|
229 // See http://www.rfc-editor.org/rfc/rfc4281.txt for the description |
135 // See http://www.rfc-editor.org/rfc/rfc4281.txt for the description |
230 // of the 'codecs' parameter |
136 // of the 'codecs' parameter |
231 nsCharSeparatedTokenizer tokenizer(codecs, ','); |
137 nsCharSeparatedTokenizer tokenizer(aRequestedCodecs, ','); |
232 bool expectMoreTokens = false; |
138 bool expectMoreTokens = false; |
233 @@ -2487,43 +2477,39 @@ nsHTMLMediaElement::CanPlayType(const ns |
139 while (tokenizer.hasMoreTokens()) { |
234 } |
140 diff --git a/content/media/DecoderTraits.h b/content/media/DecoderTraits.h |
|
141 --- a/content/media/DecoderTraits.h |
|
142 +++ b/content/media/DecoderTraits.h |
|
143 @@ -49,17 +49,16 @@ |
|
144 #endif |
|
145 |
|
146 #ifdef MOZ_WEBM |
|
147 static bool IsWebMType(const nsACString& aType); |
|
148 #endif |
235 |
149 |
236 #ifdef MOZ_GSTREAMER |
150 #ifdef MOZ_GSTREAMER |
237 bool |
151 static bool IsGStreamerSupportedType(const nsACString& aType); |
238 nsHTMLMediaElement::IsGStreamerSupportedType(const nsACString& aMimeType) |
152 - static bool IsH264Type(const nsACString& aType); |
239 { |
153 #endif |
240 if (!MediaDecoder::IsGStreamerEnabled()) |
154 |
241 return false; |
155 #ifdef MOZ_WIDGET_GONK |
242 - if (IsH264Type(aMimeType)) |
156 static bool IsOmxSupportedType(const nsACString& aType); |
243 + |
157 #endif |
244 + const char *type; |
158 |
245 + NS_CStringGetData(aMimeType, &type, nullptr); |
159 #ifdef MOZ_MEDIA_PLUGINS |
246 + if (GStreamerDecoder::CanHandleMediaType(type, nullptr)) |
160 static bool IsMediaPluginsType(const nsACString& aType); |
247 return true; |
|
248 - if (!Preferences::GetBool("media.prefer-gstreamer", false)) |
|
249 - return false; |
|
250 -#ifdef MOZ_WEBM |
|
251 - if (IsWebMType(aMimeType)) |
|
252 - return true; |
|
253 -#endif |
|
254 -#ifdef MOZ_OGG |
|
255 - if (IsOggType(aMimeType)) |
|
256 - return true; |
|
257 -#endif |
|
258 + |
|
259 return false; |
|
260 } |
|
261 #endif |
|
262 |
|
263 already_AddRefed<MediaDecoder> |
|
264 nsHTMLMediaElement::CreateDecoder(const nsACString& aType) |
|
265 { |
|
266 |
|
267 #ifdef MOZ_GSTREAMER |
|
268 // When enabled, use GStreamer for H.264, but not for codecs handled by our |
|
269 // bundled decoders, unless the "media.prefer-gstreamer" pref is set. |
|
270 - if (IsGStreamerSupportedType(aType)) { |
|
271 - nsRefPtr<GStreamerDecoder> decoder = new GStreamerDecoder(); |
|
272 - if (decoder->Init(this)) { |
|
273 - return decoder.forget(); |
|
274 + if (!Preferences::GetBool("media.prefer-gstreamer", false)) { |
|
275 + if (IsGStreamerSupportedType(aType)) { |
|
276 + nsRefPtr<GStreamerDecoder> decoder = new GStreamerDecoder(); |
|
277 + if (decoder->Init(this)) { |
|
278 + return decoder.forget(); |
|
279 + } |
|
280 } |
|
281 } |
|
282 #endif |
|
283 |
|
284 #ifdef MOZ_RAW |
|
285 if (IsRawType(aType)) { |
|
286 nsRefPtr<RawDecoder> decoder = new RawDecoder(); |
|
287 if (decoder->Init(this)) { |
|
288 @@ -2576,16 +2562,26 @@ nsHTMLMediaElement::CreateDecoder(const |
|
289 if (IsDASHMPDType(aType)) { |
|
290 nsRefPtr<DASHDecoder> decoder = new DASHDecoder(); |
|
291 if (decoder->Init(this)) { |
|
292 return decoder.forget(); |
|
293 } |
|
294 } |
|
295 #endif |
|
296 |
|
297 +#ifdef MOZ_GSTREAMER |
|
298 + // use GStreamer as fallback if not preferred |
|
299 + if (IsGStreamerSupportedType(aType)) { |
|
300 + nsRefPtr<GStreamerDecoder> decoder = new GStreamerDecoder(); |
|
301 + if (decoder->Init(this)) { |
|
302 + return decoder.forget(); |
|
303 + } |
|
304 + } |
|
305 +#endif |
|
306 + |
|
307 return nullptr; |
|
308 } |
|
309 |
|
310 nsresult nsHTMLMediaElement::InitializeDecoderAsClone(MediaDecoder* aOriginal) |
|
311 { |
|
312 NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set"); |
|
313 NS_ASSERTION(mDecoder == nullptr, "Shouldn't have a decoder"); |
|
314 |
|
315 diff --git a/content/media/gstreamer/GStreamerDecoder.cpp b/content/media/gstreamer/GStreamerDecoder.cpp |
161 diff --git a/content/media/gstreamer/GStreamerDecoder.cpp b/content/media/gstreamer/GStreamerDecoder.cpp |
316 --- a/content/media/gstreamer/GStreamerDecoder.cpp |
162 --- a/content/media/gstreamer/GStreamerDecoder.cpp |
317 +++ b/content/media/gstreamer/GStreamerDecoder.cpp |
163 +++ b/content/media/gstreamer/GStreamerDecoder.cpp |
318 @@ -2,18 +2,23 @@ |
164 @@ -2,18 +2,26 @@ |
319 /* vim:set ts=2 sw=2 sts=2 et cindent: */ |
165 /* vim:set ts=2 sw=2 sts=2 et cindent: */ |
320 /* This Source Code Form is subject to the terms of the Mozilla Public |
166 /* This Source Code Form is subject to the terms of the Mozilla Public |
321 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
167 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
322 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
168 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
323 |
169 |
324 #include "MediaDecoderStateMachine.h" |
170 #include "MediaDecoderStateMachine.h" |
325 #include "GStreamerReader.h" |
171 #include "GStreamerReader.h" |
326 #include "GStreamerDecoder.h" |
172 #include "GStreamerDecoder.h" |
327 +#include "nsGStreamerFormatHelper.h" |
173 +#include "GStreamerFormatHelper.h" |
328 |
174 |
329 namespace mozilla { |
175 namespace mozilla { |
330 |
176 |
331 MediaDecoderStateMachine* GStreamerDecoder::CreateStateMachine() |
177 MediaDecoderStateMachine* GStreamerDecoder::CreateStateMachine() |
332 { |
178 { |
333 return new MediaDecoderStateMachine(this, new GStreamerReader(this)); |
179 return new MediaDecoderStateMachine(this, new GStreamerReader(this)); |
334 } |
180 } |
335 |
181 |
336 +bool GStreamerDecoder::CanHandleMediaType(const char* aMIMEType, |
182 +bool |
337 + const char* aCodecs) { |
183 +GStreamerDecoder::CanHandleMediaType(const nsACString& aMIMEType, |
|
184 + const nsAString* aCodecs) |
|
185 +{ |
338 + return GStreamerFormatHelper::Instance()->CanHandleMediaType(aMIMEType, aCodecs); |
186 + return GStreamerFormatHelper::Instance()->CanHandleMediaType(aMIMEType, aCodecs); |
339 +} |
187 +} |
|
188 + |
340 } // namespace mozilla |
189 } // namespace mozilla |
341 |
190 |
342 diff --git a/content/media/gstreamer/GStreamerDecoder.h b/content/media/gstreamer/GStreamerDecoder.h |
191 diff --git a/content/media/gstreamer/GStreamerDecoder.h b/content/media/gstreamer/GStreamerDecoder.h |
343 --- a/content/media/gstreamer/GStreamerDecoder.h |
192 --- a/content/media/gstreamer/GStreamerDecoder.h |
344 +++ b/content/media/gstreamer/GStreamerDecoder.h |
193 +++ b/content/media/gstreamer/GStreamerDecoder.h |
345 @@ -11,13 +11,14 @@ |
194 @@ -3,21 +3,23 @@ |
|
195 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
196 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
197 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
198 |
|
199 #if !defined(GStreamerDecoder_h_) |
|
200 #define GStreamerDecoder_h_ |
|
201 |
|
202 #include "MediaDecoder.h" |
|
203 +#include "nsXPCOMStrings.h" |
346 |
204 |
347 namespace mozilla { |
205 namespace mozilla { |
348 |
206 |
349 class GStreamerDecoder : public MediaDecoder |
207 class GStreamerDecoder : public MediaDecoder |
350 { |
208 { |
351 public: |
209 public: |
352 virtual MediaDecoder* Clone() { return new GStreamerDecoder(); } |
210 virtual MediaDecoder* Clone() { return new GStreamerDecoder(); } |
353 virtual MediaDecoderStateMachine* CreateStateMachine(); |
211 virtual MediaDecoderStateMachine* CreateStateMachine(); |
354 + static bool CanHandleMediaType(const char* aMIMEType, const char* aCodecs); |
212 + static bool CanHandleMediaType(const nsACString& aMIMEType, const nsAString* aCodecs); |
355 }; |
213 }; |
356 |
214 |
357 } // namespace mozilla |
215 } // namespace mozilla |
358 |
216 |
359 #endif |
217 #endif |
360 diff --git a/content/media/gstreamer/Makefile.in b/content/media/gstreamer/Makefile.in |
218 diff --git a/content/media/gstreamer/GStreamerFormatHelper.cpp b/content/media/gstreamer/GStreamerFormatHelper.cpp |
361 --- a/content/media/gstreamer/Makefile.in |
|
362 +++ b/content/media/gstreamer/Makefile.in |
|
363 @@ -17,16 +17,17 @@ LIBXUL_LIBRARY = 1 |
|
364 |
|
365 EXPORTS += \ |
|
366 GStreamerDecoder.h \ |
|
367 $(NULL) |
|
368 |
|
369 CPPSRCS = \ |
|
370 GStreamerReader.cpp \ |
|
371 GStreamerDecoder.cpp \ |
|
372 + nsGStreamerFormatHelper.cpp \ |
|
373 $(NULL) |
|
374 |
|
375 FORCE_STATIC_LIB = 1 |
|
376 |
|
377 include $(topsrcdir)/config/rules.mk |
|
378 |
|
379 CFLAGS += $(GSTREAMER_CFLAGS) |
|
380 CXXFLAGS += $(GSTREAMER_CFLAGS) |
|
381 diff --git a/content/media/gstreamer/nsGStreamerFormatHelper.cpp b/content/media/gstreamer/nsGStreamerFormatHelper.cpp |
|
382 new file mode 100644 |
219 new file mode 100644 |
383 --- /dev/null |
220 --- /dev/null |
384 +++ b/content/media/gstreamer/nsGStreamerFormatHelper.cpp |
221 +++ b/content/media/gstreamer/GStreamerFormatHelper.cpp |
385 @@ -0,0 +1,149 @@ |
222 @@ -0,0 +1,159 @@ |
386 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
223 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
387 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ |
224 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ |
388 +/* This Source Code Form is subject to the terms of the Mozilla Public |
225 +/* This Source Code Form is subject to the terms of the Mozilla Public |
389 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
226 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
390 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
227 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
391 + |
228 + |
392 +#include "nsGStreamerFormatHelper.h" |
229 +#include "GStreamerFormatHelper.h" |
393 +#include "nsCharSeparatedTokenizer.h" |
230 +#include "nsCharSeparatedTokenizer.h" |
394 +#include "nsXPCOMStrings.h" |
231 +#include "nsXPCOMStrings.h" |
395 + |
232 + |
396 +#define ENTRY_FORMAT(entry) entry[0] |
233 +#define ENTRY_FORMAT(entry) entry[0] |
397 +#define ENTRY_CAPS(entry) entry[1] |
234 +#define ENTRY_CAPS(entry) entry[1] |
398 + |
235 + |
399 +GStreamerFormatHelper* GStreamerFormatHelper::gInstance = nullptr; |
236 +GStreamerFormatHelper* GStreamerFormatHelper::gInstance = nullptr; |
400 + |
237 + |
401 +GStreamerFormatHelper *GStreamerFormatHelper::Instance() { |
238 +GStreamerFormatHelper* GStreamerFormatHelper::Instance() { |
402 + if (!gInstance) { |
239 + if (!gInstance) { |
403 + gst_init(nullptr, nullptr); |
240 + gst_init(nullptr, nullptr); |
404 + gInstance = new GStreamerFormatHelper(); |
241 + gInstance = new GStreamerFormatHelper(); |
405 + } |
242 + } |
406 + |
243 + |
407 + return gInstance; |
244 + return gInstance; |
408 +} |
245 +} |
409 + |
246 + |
|
247 +void GStreamerFormatHelper::Shutdown() { |
|
248 + if (gInstance) { |
|
249 + delete gInstance; |
|
250 + gInstance = nullptr; |
|
251 + } |
|
252 +} |
|
253 + |
|
254 +char const *const GStreamerFormatHelper::mContainers[4][2] = { |
|
255 + {"video/mp4", "video/quicktime"}, |
|
256 + {"video/quicktime", "video/quicktime"}, |
|
257 + {"audio/mp4", "audio/mpeg, mpegversion=(int)4"}, |
|
258 + {"audio/mpeg", "audio/mpeg, mpegversion=(int)1"}, |
|
259 +}; |
|
260 + |
|
261 +char const *const GStreamerFormatHelper::mCodecs[8][2] = { |
|
262 + {"avc1.42E01E", "video/x-h264"}, |
|
263 + {"avc1.42001E", "video/x-h264"}, |
|
264 + {"avc1.58A01E", "video/x-h264"}, |
|
265 + {"avc1.4D401E", "video/x-h264"}, |
|
266 + {"avc1.64001E", "video/x-h264"}, |
|
267 + {"avc1.64001F", "video/x-h264"}, |
|
268 + {"mp4v.20.3", "video/3gpp"}, |
|
269 + {"mp4a.40.2", "audio/mpeg, mpegversion=(int)4"}, |
|
270 +}; |
|
271 + |
410 +GStreamerFormatHelper::GStreamerFormatHelper() |
272 +GStreamerFormatHelper::GStreamerFormatHelper() |
411 + : mFactories(nullptr), |
273 + : mFactories(nullptr), |
412 + mCookie(0) |
274 + mCookie(static_cast<uint32_t>(-1)) |
413 +{ |
275 +{ |
414 + const char *containers[3][2] = { |
|
415 + {"video/mp4", "video/quicktime"}, |
|
416 + {"audio/mp4", "audio/mpeg, mpegversion=(int)4"}, |
|
417 + {"audio/mpeg", "audio/mpeg, mpegversion=(int)1"}, |
|
418 + }; |
|
419 + memcpy(mContainers, containers, sizeof(containers)); |
|
420 + |
|
421 + const char *codecs[7][2] = { |
|
422 + {"avc1.42E01E", "video/x-h264"}, |
|
423 + {"avc1.42001E", "video/x-h264"}, |
|
424 + {"avc1.58A01E", "video/x-h264"}, |
|
425 + {"avc1.4D401E", "video/x-h264"}, |
|
426 + {"avc1.64001E", "video/x-h264"}, |
|
427 + {"mp4a.40.2", "audio/mpeg, mpegversion=(int)4"}, |
|
428 + {"mp3", "audio/mpeg, mpegversion=(int)1"}, |
|
429 + }; |
|
430 + memcpy(mCodecs, codecs, sizeof(codecs)); |
|
431 +} |
276 +} |
432 + |
277 + |
433 +GStreamerFormatHelper::~GStreamerFormatHelper() { |
278 +GStreamerFormatHelper::~GStreamerFormatHelper() { |
434 + if (mFactories) |
279 + if (mFactories) |
435 + g_list_free(mFactories); |
280 + g_list_free(mFactories); |
436 +} |
281 +} |
437 + |
282 + |
438 +bool GStreamerFormatHelper::CanHandleMediaType(const char* aMIMEType, |
283 +bool GStreamerFormatHelper::CanHandleMediaType(const nsACString& aMIMEType, |
439 + const char *aCodecs) { |
284 + const nsAString* aCodecs) { |
440 + GstCaps *caps = ConvertFormatsToCaps(aMIMEType, aCodecs); |
285 + const char *type; |
|
286 + NS_CStringGetData(aMIMEType, &type, NULL); |
|
287 + |
|
288 + GstCaps* caps = ConvertFormatsToCaps(type, aCodecs); |
441 + if (!caps) { |
289 + if (!caps) { |
442 + return false; |
290 + return false; |
443 + } |
291 + } |
444 + |
292 + |
445 + bool ret = HaveElementsToProcessCaps(caps); |
293 + bool ret = HaveElementsToProcessCaps(caps); |
446 + gst_caps_unref(caps); |
294 + gst_caps_unref(caps); |
447 + |
295 + |
448 + return ret; |
296 + return ret; |
449 +} |
297 +} |
450 + |
298 + |
451 +GstCaps *GStreamerFormatHelper::ConvertFormatsToCaps(const char *aMIMEType, |
299 +GstCaps* GStreamerFormatHelper::ConvertFormatsToCaps(const char* aMIMEType, |
452 + const char *aCodecs) { |
300 + const nsAString* aCodecs) { |
453 + unsigned int i; |
301 + unsigned int i; |
454 + |
302 + |
455 + /* convert aMIMEType to gst container caps */ |
303 + /* convert aMIMEType to gst container caps */ |
456 + const char *capsString = nullptr; |
304 + const char* capsString = nullptr; |
457 + for (i = 0; i < G_N_ELEMENTS(mContainers); i++) { |
305 + for (i = 0; i < G_N_ELEMENTS(mContainers); i++) { |
458 + if (!strcmp(ENTRY_FORMAT(mContainers[i]), aMIMEType)) { |
306 + if (!strcmp(ENTRY_FORMAT(mContainers[i]), aMIMEType)) { |
459 + capsString = ENTRY_CAPS(mContainers[i]); |
307 + capsString = ENTRY_CAPS(mContainers[i]); |
460 + break; |
308 + break; |
461 + } |
309 + } |
530 + mCookie = cookie; |
377 + mCookie = cookie; |
531 + } |
378 + } |
532 + |
379 + |
533 + return mFactories; |
380 + return mFactories; |
534 +} |
381 +} |
535 diff --git a/content/media/gstreamer/nsGStreamerFormatHelper.h b/content/media/gstreamer/nsGStreamerFormatHelper.h |
382 diff --git a/content/media/gstreamer/GStreamerFormatHelper.h b/content/media/gstreamer/GStreamerFormatHelper.h |
536 new file mode 100644 |
383 new file mode 100644 |
537 --- /dev/null |
384 --- /dev/null |
538 +++ b/content/media/gstreamer/nsGStreamerFormatHelper.h |
385 +++ b/content/media/gstreamer/GStreamerFormatHelper.h |
539 @@ -0,0 +1,37 @@ |
386 @@ -0,0 +1,60 @@ |
540 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
387 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
541 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ |
388 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ |
542 +/* This Source Code Form is subject to the terms of the Mozilla Public |
389 +/* This Source Code Form is subject to the terms of the Mozilla Public |
543 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
390 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
544 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
391 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
545 + |
392 + |
546 +#if !defined(nsGStreamerFormatHelper_h_) |
393 +#if !defined(GStreamerFormatHelper_h_) |
547 +#define nsGStreamerFormatHelper_h_ |
394 +#define GStreamerFormatHelper_h_ |
548 + |
395 + |
549 +#include <gst/gst.h> |
396 +#include <gst/gst.h> |
550 +#include <mozilla/Types.h> |
397 +#include <mozilla/Types.h> |
|
398 +#include "nsXPCOMStrings.h" |
551 + |
399 + |
552 +class GStreamerFormatHelper { |
400 +class GStreamerFormatHelper { |
|
401 + /* This class can be used to query the GStreamer registry for the required |
|
402 + * demuxers/decoders from nsHTMLMediaElement::CanPlayType. |
|
403 + * It implements looking at the GstRegistry to check if elements to |
|
404 + * demux/decode the formats passed to CanPlayType() are actually installed. |
|
405 + */ |
553 + public: |
406 + public: |
554 + static GStreamerFormatHelper *Instance(); |
407 + static GStreamerFormatHelper* Instance(); |
555 + ~GStreamerFormatHelper(); |
408 + ~GStreamerFormatHelper(); |
556 + |
409 + |
557 + bool CanHandleMediaType(const char *aMIMEType, |
410 + bool CanHandleMediaType(const nsACString& aMIMEType, |
558 + const char *aCodecs); |
411 + const nsAString* aCodecs); |
|
412 + |
|
413 + static void Shutdown(); |
559 + |
414 + |
560 + private: |
415 + private: |
561 + GStreamerFormatHelper(); |
416 + GStreamerFormatHelper(); |
562 + GstCaps *ConvertFormatsToCaps(const char *aMIMEType, |
417 + GstCaps* ConvertFormatsToCaps(const char* aMIMEType, |
563 + const char *aCodecs); |
418 + const nsAString* aCodecs); |
564 + char * const *CodecListFromCaps(GstCaps *aCaps); |
419 + char* const *CodecListFromCaps(GstCaps* aCaps); |
565 + bool HaveElementsToProcessCaps(GstCaps *aCaps); |
420 + bool HaveElementsToProcessCaps(GstCaps* aCaps); |
566 + GList *GetFactories(); |
421 + GList* GetFactories(); |
567 + |
422 + |
568 + static GStreamerFormatHelper *gInstance; |
423 + static GStreamerFormatHelper* gInstance; |
569 + |
424 + |
570 + const char *mContainers[3][2]; |
425 + /* table to convert from container MIME types to GStreamer elements */ |
571 + const char *mCodecs[7][2]; |
426 + static char const *const mContainers[4][2]; |
572 + GList *mFactories; |
427 + |
|
428 + /* table to convert from codec MIME types to GStreamer elements */ |
|
429 + static char const *const mCodecs[8][2]; |
|
430 + |
|
431 + /* list of GStreamer element factories |
|
432 + * Element factories are the basic types retrieved from the GStreamer |
|
433 + * registry, they describe all plugins and elements that GStreamer can |
|
434 + * create. |
|
435 + * This means that element factories are useful for automated element |
|
436 + * instancing, such as what autopluggers do, |
|
437 + * and for creating lists of available elements. */ |
|
438 + GList* mFactories; |
|
439 + |
|
440 + /* Storage for the default registrys feature list cookie. |
|
441 + * It changes every time a feature is added to or removed from the |
|
442 + * GStreamer registry. */ |
573 + uint32_t mCookie; |
443 + uint32_t mCookie; |
574 +}; |
444 +}; |
575 + |
445 + |
576 +#endif |
446 +#endif |
|
447 diff --git a/content/media/gstreamer/Makefile.in b/content/media/gstreamer/Makefile.in |
|
448 --- a/content/media/gstreamer/Makefile.in |
|
449 +++ b/content/media/gstreamer/Makefile.in |
|
450 @@ -13,21 +13,23 @@ |
|
451 MODULE = content |
|
452 LIBRARY_NAME = gkcongstreamer_s |
|
453 LIBXUL_LIBRARY = 1 |
|
454 |
|
455 |
|
456 EXPORTS += \ |
|
457 GStreamerDecoder.h \ |
|
458 GStreamerReader.h \ |
|
459 + GStreamerFormatHelper.h \ |
|
460 $(NULL) |
|
461 |
|
462 CPPSRCS = \ |
|
463 GStreamerReader.cpp \ |
|
464 GStreamerDecoder.cpp \ |
|
465 + GStreamerFormatHelper.cpp \ |
|
466 $(NULL) |
|
467 |
|
468 FORCE_STATIC_LIB = 1 |
|
469 |
|
470 include $(topsrcdir)/config/rules.mk |
|
471 |
|
472 CFLAGS += $(GSTREAMER_CFLAGS) |
|
473 CXXFLAGS += $(GSTREAMER_CFLAGS) |
|
474 diff --git a/layout/build/Makefile.in b/layout/build/Makefile.in |
|
475 --- a/layout/build/Makefile.in |
|
476 +++ b/layout/build/Makefile.in |
|
477 @@ -316,16 +316,20 @@ |
|
478 -I$(topsrcdir)/js/xpconnect/loader \ |
|
479 -I$(topsrcdir)/caps/include \ |
|
480 -I$(topsrcdir)/netwerk/base/src \ |
|
481 -I$(topsrcdir)/content/svg/content/src \ |
|
482 -I$(topsrcdir)/extensions/cookie \ |
|
483 -I$(topsrcdir)/netwerk/cookie \ |
|
484 $(NULL) |
|
485 |
|
486 +ifdef MOZ_GSTREAMER |
|
487 +LOCAL_INCLUDES += $(GSTREAMER_CFLAGS) |
|
488 +endif |
|
489 + |
|
490 ifdef MOZ_B2G_RIL #{ |
|
491 LOCAL_INCLUDES += -I$(topsrcdir)/dom/system/gonk |
|
492 endif #} |
|
493 |
|
494 ifdef MOZ_B2G_FM #{ |
|
495 LOCAL_INCLUDES += -I$(topsrcdir)/dom/fm |
|
496 endif #} |
|
497 |
|
498 diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp |
|
499 --- a/layout/build/nsLayoutStatics.cpp |
|
500 +++ b/layout/build/nsLayoutStatics.cpp |
|
501 @@ -78,16 +78,20 @@ |
|
502 #ifdef MOZ_MEDIA_PLUGINS |
|
503 #include "MediaPluginHost.h" |
|
504 #endif |
|
505 |
|
506 #ifdef MOZ_WMF |
|
507 #include "WMFDecoder.h" |
|
508 #endif |
|
509 |
|
510 +#ifdef MOZ_GSTREAMER |
|
511 +#include "GStreamerFormatHelper.h" |
|
512 +#endif |
|
513 + |
|
514 #ifdef MOZ_SYDNEYAUDIO |
|
515 #include "AudioStream.h" |
|
516 #endif |
|
517 |
|
518 #include "nsError.h" |
|
519 |
|
520 #include "nsCycleCollector.h" |
|
521 #include "nsJSEnvironment.h" |
|
522 @@ -336,16 +340,20 @@ |
|
523 nsXBLService::Shutdown(); |
|
524 nsAutoCopyListener::Shutdown(); |
|
525 FrameLayerBuilder::Shutdown(); |
|
526 |
|
527 #ifdef MOZ_MEDIA_PLUGINS |
|
528 MediaPluginHost::Shutdown(); |
|
529 #endif |
|
530 |
|
531 +#ifdef MOZ_GSTREAMER |
|
532 + GStreamerFormatHelper::Shutdown(); |
|
533 +#endif |
|
534 + |
|
535 #ifdef MOZ_SYDNEYAUDIO |
|
536 AudioStream::ShutdownLibrary(); |
|
537 #endif |
|
538 |
|
539 #ifdef MOZ_WMF |
|
540 WMFDecoder::UnloadDLLs(); |
|
541 #endif |
|
542 |