mozilla-gstreamer-760140.patch
changeset 612 3006d73ad2fa
parent 606 9d39369e1b4c
child 637 73640b76d6c3
equal deleted inserted replaced
611:bcb3d1af73f7 612:3006d73ad2fa
     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 +    }
   464 +  if (!capsString) {
   312 +  if (!capsString) {
   465 +    /* we couldn't find any matching caps */
   313 +    /* we couldn't find any matching caps */
   466 +    return nullptr;
   314 +    return nullptr;
   467 +  }
   315 +  }
   468 +
   316 +
   469 +  GstCaps *caps = gst_caps_from_string(capsString);
   317 +  GstCaps* caps = gst_caps_from_string(capsString);
   470 +  /* container only */
   318 +  /* container only */
   471 +  if (!aCodecs) {
   319 +  if (!aCodecs) {
   472 +    return caps;
   320 +    return caps;
   473 +  }
   321 +  }
   474 +
   322 +
   475 +  nsDependentCSubstring codecs(aCodecs, strlen(aCodecs));
   323 +  nsCharSeparatedTokenizer tokenizer(*aCodecs, ',');
   476 +  nsCCharSeparatedTokenizer tokenizer(codecs, ',');
       
   477 +  while (tokenizer.hasMoreTokens()) {
   324 +  while (tokenizer.hasMoreTokens()) {
   478 +    const nsCSubstring& codec = tokenizer.nextToken();
   325 +    const nsSubstring& codec = tokenizer.nextToken();
   479 +    capsString = nullptr;
   326 +    capsString = nullptr;
   480 +
   327 +
   481 +    for (i = 0; i < G_N_ELEMENTS(mCodecs); i++) {
   328 +    for (i = 0; i < G_N_ELEMENTS(mCodecs); i++) {
   482 +      if (codec.Equals(ENTRY_FORMAT(mCodecs[i]))) {
   329 +      if (codec.EqualsASCII(ENTRY_FORMAT(mCodecs[i]))) {
   483 +        capsString = ENTRY_CAPS(mCodecs[i]);
   330 +        capsString = ENTRY_CAPS(mCodecs[i]);
   484 +        break;
   331 +        break;
   485 +      }
   332 +      }
   486 +    }
   333 +    }
   487 +
   334 +
   488 +    if (!capsString) {
   335 +    if (!capsString) {
   489 +      gst_caps_unref(caps);
   336 +      gst_caps_unref(caps);
   490 +      return nullptr;
   337 +      return nullptr;
   491 +    }
   338 +    }
   492 +
   339 +
   493 +    GstCaps *tmp = gst_caps_from_string(capsString);
   340 +    GstCaps* tmp = gst_caps_from_string(capsString);
   494 +    /* appends and frees tmp */
   341 +    /* appends and frees tmp */
   495 +    gst_caps_append(caps, tmp);
   342 +    gst_caps_append(caps, tmp);
   496 +  }
   343 +  }
   497 +
   344 +
   498 +  return caps;
   345 +  return caps;
   499 +}
   346 +}
   500 +
   347 +
   501 +bool GStreamerFormatHelper::HaveElementsToProcessCaps(GstCaps *aCaps) {
   348 +bool GStreamerFormatHelper::HaveElementsToProcessCaps(GstCaps* aCaps) {
   502 +
   349 +
   503 +  GList *factories = GetFactories();
   350 +  GList* factories = GetFactories();
   504 +
   351 +
   505 +  GList *list;
   352 +  GList* list;
   506 +  /* here aCaps contains [containerCaps, [codecCaps1, [codecCaps2, ...]]] so process
   353 +  /* here aCaps contains [containerCaps, [codecCaps1, [codecCaps2, ...]]] so process
   507 +   * caps structures individually as we want one element for _each_
   354 +   * caps structures individually as we want one element for _each_
   508 +   * structure */
   355 +   * structure */
   509 +  for (unsigned int i = 0; i < gst_caps_get_size(aCaps); i++) {
   356 +  for (unsigned int i = 0; i < gst_caps_get_size(aCaps); i++) {
   510 +    GstStructure *s = gst_caps_get_structure(aCaps, i);
   357 +    GstStructure* s = gst_caps_get_structure(aCaps, i);
   511 +    GstCaps *caps = gst_caps_new_full(gst_structure_copy(s), nullptr);
   358 +    GstCaps* caps = gst_caps_new_full(gst_structure_copy(s), nullptr);
   512 +    list = gst_element_factory_list_filter (factories, caps, GST_PAD_SINK, FALSE);
   359 +    list = gst_element_factory_list_filter (factories, caps, GST_PAD_SINK, FALSE);
   513 +    gst_caps_unref(caps);
   360 +    gst_caps_unref(caps);
   514 +    if (!list) {
   361 +    if (!list) {
   515 +      return false;
   362 +      return false;
   516 +    }
   363 +    }
   518 +  }
   365 +  }
   519 +
   366 +
   520 +  return true;
   367 +  return true;
   521 +}
   368 +}
   522 +
   369 +
   523 +GList * GStreamerFormatHelper::GetFactories() {
   370 +GList* GStreamerFormatHelper::GetFactories() {
   524 +  uint32_t cookie = gst_default_registry_get_feature_list_cookie ();
   371 +  uint32_t cookie = gst_default_registry_get_feature_list_cookie ();
   525 +  if (cookie != mCookie) {
   372 +  if (cookie != mCookie) {
   526 +    g_list_free(mFactories);
   373 +    g_list_free(mFactories);
   527 +    mFactories = gst_element_factory_list_get_elements
   374 +    mFactories = gst_element_factory_list_get_elements
   528 +        (GST_ELEMENT_FACTORY_TYPE_DEMUXER | GST_ELEMENT_FACTORY_TYPE_DECODER,
   375 +        (GST_ELEMENT_FACTORY_TYPE_DEMUXER | GST_ELEMENT_FACTORY_TYPE_DECODER,
   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