mozilla-gstreamer-760140.patch
changeset 650 e8c83b144fd1
parent 649 de1740022f78
child 651 19262ba479c4
child 653 38c67b6b2f37
equal deleted inserted replaced
649:de1740022f78 650:e8c83b144fd1
     1 # HG changeset patch
       
     2 # Parent 74ba8ebd0dc72be84280bd4806f84d9ec1f4e130
       
     3 Bug 760140 - Query the GstRegistry for the required demuxers/decoders from canPlayType (TM: 22)
       
     4 
       
     5 diff --git a/content/media/DecoderTraits.cpp b/content/media/DecoderTraits.cpp
       
     6 --- a/content/media/DecoderTraits.cpp
       
     7 +++ b/content/media/DecoderTraits.cpp
       
     8 @@ -7,16 +7,18 @@
       
     9  #include "DecoderTraits.h"
       
    10  #include "MediaDecoder.h"
       
    11  #include "nsCharSeparatedTokenizer.h"
       
    12  #ifdef MOZ_MEDIA_PLUGINS
       
    13  #include "MediaPluginHost.h"
       
    14  #endif
       
    15  #ifdef MOZ_GSTREAMER
       
    16  #include "mozilla/Preferences.h"
       
    17 +#include "GStreamerDecoder.h"
       
    18 +#include "nsXPCOMStrings.h"
       
    19  #endif
       
    20  #ifdef MOZ_WMF
       
    21  #include "WMFDecoder.h"
       
    22  #endif
       
    23  
       
    24  namespace mozilla
       
    25  {
       
    26  
       
    27 @@ -137,48 +139,35 @@ DecoderTraits::IsWebMType(const nsACStri
       
    28      return false;
       
    29    }
       
    30  
       
    31    return CodecListContains(gWebMTypes, aType);
       
    32  }
       
    33  #endif
       
    34  
       
    35  #ifdef MOZ_GSTREAMER
       
    36 -static const char* const gH264Types[4] = {
       
    37 -  "video/mp4",
       
    38 -  "video/3gpp",
       
    39 -  "video/quicktime",
       
    40 -  nullptr
       
    41 -};
       
    42 -
       
    43  bool
       
    44  DecoderTraits::IsGStreamerSupportedType(const nsACString& aMimeType)
       
    45  {
       
    46    if (!MediaDecoder::IsGStreamerEnabled())
       
    47      return false;
       
    48 -  if (IsH264Type(aMimeType))
       
    49 +  if (GStreamerDecoder::CanHandleMediaType(aMimeType, nullptr))
       
    50      return true;
       
    51    if (!Preferences::GetBool("media.prefer-gstreamer", false))
       
    52      return false;
       
    53  #ifdef MOZ_WEBM
       
    54    if (IsWebMType(aMimeType))
       
    55      return true;
       
    56  #endif
       
    57  #ifdef MOZ_OGG
       
    58    if (IsOggType(aMimeType))
       
    59      return true;
       
    60  #endif
       
    61    return false;
       
    62  }
       
    63 -
       
    64 -bool
       
    65 -DecoderTraits::IsH264Type(const nsACString& aType)
       
    66 -{
       
    67 -  return CodecListContains(gH264Types, aType);
       
    68 -}
       
    69  #endif
       
    70  
       
    71  #ifdef MOZ_WIDGET_GONK
       
    72  static const char* const gOmxTypes[6] = {
       
    73    "audio/mpeg",
       
    74    "audio/mp4",
       
    75    "video/mp4",
       
    76    "video/3gpp",
       
    77 @@ -190,19 +179,17 @@ bool
       
    78  DecoderTraits::IsOmxSupportedType(const nsACString& aType)
       
    79  {
       
    80    if (!MediaDecoder::IsOmxEnabled()) {
       
    81      return false;
       
    82    }
       
    83  
       
    84    return CodecListContains(gOmxTypes, aType);
       
    85  }
       
    86 -#endif
       
    87  
       
    88 -#if defined(MOZ_GSTREAMER) || defined(MOZ_WIDGET_GONK)
       
    89  static char const *const gH264Codecs[9] = {
       
    90    "avc1.42E01E",  // H.264 Constrained Baseline Profile Level 3.0
       
    91    "avc1.42001E",  // H.264 Baseline Profile Level 3.0
       
    92    "avc1.58A01E",  // H.264 Extended Profile Level 3.0
       
    93    "avc1.4D401E",  // H.264 Main Profile Level 3.0
       
    94    "avc1.64001E",  // H.264 High Profile Level 3.0
       
    95    "avc1.64001F",  // H.264 High Profile Level 3.1
       
    96    "mp4v.20.3",    // 3GPP
       
    97 @@ -303,19 +290,19 @@ DecoderTraits::CanHandleMediaType(const 
       
    98  #ifdef MOZ_DASH
       
    99    if (IsDASHMPDType(nsDependentCString(aMIMEType))) {
       
   100      // DASH manifest uses WebM codecs only.
       
   101      codecList = gWebMCodecs;
       
   102      result = CANPLAY_YES;
       
   103    }
       
   104  #endif
       
   105  #ifdef MOZ_GSTREAMER
       
   106 -  if (IsH264Type(nsDependentCString(aMIMEType))) {
       
   107 -    codecList = gH264Codecs;
       
   108 -    result = CANPLAY_MAYBE;
       
   109 +  if (GStreamerDecoder::CanHandleMediaType(nsDependentCString(aMIMEType),
       
   110 +                                           aHaveRequestedCodecs ? &aRequestedCodecs : nullptr)) {
       
   111 +    return CANPLAY_YES;
       
   112    }
       
   113  #endif
       
   114  #ifdef MOZ_WIDGET_GONK
       
   115    if (IsOmxSupportedType(nsDependentCString(aMIMEType))) {
       
   116      codecList = gH264Codecs;
       
   117      result = CANPLAY_MAYBE;
       
   118    }
       
   119  #endif
       
   120 @@ -324,17 +311,17 @@ DecoderTraits::CanHandleMediaType(const 
       
   121      result = CANPLAY_MAYBE;
       
   122    }
       
   123  #endif
       
   124  #ifdef MOZ_MEDIA_PLUGINS
       
   125    if (MediaDecoder::IsMediaPluginsEnabled() &&
       
   126        GetMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), &codecList))
       
   127      result = CANPLAY_MAYBE;
       
   128  #endif
       
   129 -  if (result == CANPLAY_NO || !aHaveRequestedCodecs) {
       
   130 +  if (result == CANPLAY_NO || !aHaveRequestedCodecs || !codecList) {
       
   131      return result;
       
   132    }
       
   133  
       
   134    // See http://www.rfc-editor.org/rfc/rfc4281.txt for the description
       
   135    // of the 'codecs' parameter
       
   136    nsCharSeparatedTokenizer tokenizer(aRequestedCodecs, ',');
       
   137    bool expectMoreTokens = false;
       
   138    while (tokenizer.hasMoreTokens()) {
       
   139 diff --git a/content/media/DecoderTraits.h b/content/media/DecoderTraits.h
       
   140 --- a/content/media/DecoderTraits.h
       
   141 +++ b/content/media/DecoderTraits.h
       
   142 @@ -51,17 +51,16 @@ public:
       
   143  #ifdef MOZ_WEBM
       
   144    static bool IsWebMType(const nsACString& aType);
       
   145  #endif
       
   146  
       
   147  #ifdef MOZ_GSTREAMER
       
   148    // When enabled, use GStreamer for H.264, but not for codecs handled by our
       
   149    // bundled decoders, unless the "media.prefer-gstreamer" pref is set.
       
   150    static bool IsGStreamerSupportedType(const nsACString& aType);
       
   151 -  static bool IsH264Type(const nsACString& aType);
       
   152  #endif
       
   153  
       
   154  #ifdef MOZ_WIDGET_GONK
       
   155    static bool IsOmxSupportedType(const nsACString& aType);
       
   156  #endif
       
   157  
       
   158  #ifdef MOZ_MEDIA_PLUGINS
       
   159    static bool IsMediaPluginsType(const nsACString& aType);
       
   160 diff --git a/content/media/gstreamer/GStreamerDecoder.cpp b/content/media/gstreamer/GStreamerDecoder.cpp
       
   161 --- a/content/media/gstreamer/GStreamerDecoder.cpp
       
   162 +++ b/content/media/gstreamer/GStreamerDecoder.cpp
       
   163 @@ -2,18 +2,26 @@
       
   164  /* vim:set ts=2 sw=2 sts=2 et cindent: */
       
   165  /* This Source Code Form is subject to the terms of the Mozilla Public
       
   166   * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       
   167   * You can obtain one at http://mozilla.org/MPL/2.0/. */
       
   168  
       
   169  #include "MediaDecoderStateMachine.h"
       
   170  #include "GStreamerReader.h"
       
   171  #include "GStreamerDecoder.h"
       
   172 +#include "GStreamerFormatHelper.h"
       
   173  
       
   174  namespace mozilla {
       
   175  
       
   176  MediaDecoderStateMachine* GStreamerDecoder::CreateStateMachine()
       
   177  {
       
   178    return new MediaDecoderStateMachine(this, new GStreamerReader(this));
       
   179  }
       
   180  
       
   181 +bool
       
   182 +GStreamerDecoder::CanHandleMediaType(const nsACString& aMIMEType,
       
   183 +                                     const nsAString* aCodecs)
       
   184 +{
       
   185 +  return GStreamerFormatHelper::Instance()->CanHandleMediaType(aMIMEType, aCodecs);
       
   186 +}
       
   187 +
       
   188  } // namespace mozilla
       
   189  
       
   190 diff --git a/content/media/gstreamer/GStreamerDecoder.h b/content/media/gstreamer/GStreamerDecoder.h
       
   191 --- a/content/media/gstreamer/GStreamerDecoder.h
       
   192 +++ b/content/media/gstreamer/GStreamerDecoder.h
       
   193 @@ -3,21 +3,23 @@
       
   194  /* This Source Code Form is subject to the terms of the Mozilla Public
       
   195   * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       
   196   * You can obtain one at http://mozilla.org/MPL/2.0/. */
       
   197  
       
   198  #if !defined(GStreamerDecoder_h_)
       
   199  #define GStreamerDecoder_h_
       
   200  
       
   201  #include "MediaDecoder.h"
       
   202 +#include "nsXPCOMStrings.h"
       
   203  
       
   204  namespace mozilla {
       
   205  
       
   206  class GStreamerDecoder : public MediaDecoder
       
   207  {
       
   208  public:
       
   209    virtual MediaDecoder* Clone() { return new GStreamerDecoder(); }
       
   210    virtual MediaDecoderStateMachine* CreateStateMachine();
       
   211 +  static bool CanHandleMediaType(const nsACString& aMIMEType, const nsAString* aCodecs);
       
   212  };
       
   213  
       
   214  } // namespace mozilla
       
   215  
       
   216  #endif
       
   217 diff --git a/content/media/gstreamer/GStreamerFormatHelper.cpp b/content/media/gstreamer/GStreamerFormatHelper.cpp
       
   218 new file mode 100644
       
   219 --- /dev/null
       
   220 +++ b/content/media/gstreamer/GStreamerFormatHelper.cpp
       
   221 @@ -0,0 +1,159 @@
       
   222 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       
   223 +/* vim:set ts=2 sw=2 sts=2 et cindent: */
       
   224 +/* This Source Code Form is subject to the terms of the Mozilla Public
       
   225 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       
   226 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
       
   227 +
       
   228 +#include "GStreamerFormatHelper.h"
       
   229 +#include "nsCharSeparatedTokenizer.h"
       
   230 +#include "nsXPCOMStrings.h"
       
   231 +
       
   232 +#define ENTRY_FORMAT(entry) entry[0]
       
   233 +#define ENTRY_CAPS(entry) entry[1]
       
   234 +
       
   235 +GStreamerFormatHelper* GStreamerFormatHelper::gInstance = nullptr;
       
   236 +
       
   237 +GStreamerFormatHelper* GStreamerFormatHelper::Instance() {
       
   238 +  if (!gInstance) {
       
   239 +    gst_init(nullptr, nullptr);
       
   240 +    gInstance = new GStreamerFormatHelper();
       
   241 +  }
       
   242 +
       
   243 +  return gInstance;
       
   244 +}
       
   245 +
       
   246 +void GStreamerFormatHelper::Shutdown() {
       
   247 +  if (gInstance) {
       
   248 +    delete gInstance;
       
   249 +    gInstance = nullptr;
       
   250 +  }
       
   251 +}
       
   252 +
       
   253 +char const *const GStreamerFormatHelper::mContainers[4][2] = {
       
   254 +  {"video/mp4", "video/quicktime"},
       
   255 +  {"video/quicktime", "video/quicktime"},
       
   256 +  {"audio/mp4", "audio/mpeg, mpegversion=(int)4"},
       
   257 +  {"audio/mpeg", "audio/mpeg, mpegversion=(int)1"},
       
   258 +};
       
   259 +
       
   260 +char const *const GStreamerFormatHelper::mCodecs[8][2] = {
       
   261 +  {"avc1.42E01E", "video/x-h264"},
       
   262 +  {"avc1.42001E", "video/x-h264"},
       
   263 +  {"avc1.58A01E", "video/x-h264"},
       
   264 +  {"avc1.4D401E", "video/x-h264"},
       
   265 +  {"avc1.64001E", "video/x-h264"},
       
   266 +  {"avc1.64001F", "video/x-h264"},
       
   267 +  {"mp4v.20.3", "video/3gpp"},
       
   268 +  {"mp4a.40.2", "audio/mpeg, mpegversion=(int)4"},
       
   269 +};
       
   270 +
       
   271 +GStreamerFormatHelper::GStreamerFormatHelper()
       
   272 +  : mFactories(nullptr),
       
   273 +    mCookie(static_cast<uint32_t>(-1))
       
   274 +{
       
   275 +}
       
   276 +
       
   277 +GStreamerFormatHelper::~GStreamerFormatHelper() {
       
   278 +  if (mFactories)
       
   279 +    g_list_free(mFactories);
       
   280 +}
       
   281 +
       
   282 +bool GStreamerFormatHelper::CanHandleMediaType(const nsACString& aMIMEType,
       
   283 +                                               const nsAString* aCodecs) {
       
   284 +  const char *type;
       
   285 +  NS_CStringGetData(aMIMEType, &type, NULL);
       
   286 +
       
   287 +  GstCaps* caps = ConvertFormatsToCaps(type, aCodecs);
       
   288 +  if (!caps) {
       
   289 +    return false;
       
   290 +  }
       
   291 +
       
   292 +  bool ret = HaveElementsToProcessCaps(caps);
       
   293 +  gst_caps_unref(caps);
       
   294 +
       
   295 +  return ret;
       
   296 +}
       
   297 +
       
   298 +GstCaps* GStreamerFormatHelper::ConvertFormatsToCaps(const char* aMIMEType,
       
   299 +                                                     const nsAString* aCodecs) {
       
   300 +  unsigned int i;
       
   301 +
       
   302 +  /* convert aMIMEType to gst container caps */
       
   303 +  const char* capsString = nullptr;
       
   304 +  for (i = 0; i < G_N_ELEMENTS(mContainers); i++) {
       
   305 +    if (!strcmp(ENTRY_FORMAT(mContainers[i]), aMIMEType)) {
       
   306 +      capsString = ENTRY_CAPS(mContainers[i]);
       
   307 +      break;
       
   308 +    }
       
   309 +  }
       
   310 +
       
   311 +  if (!capsString) {
       
   312 +    /* we couldn't find any matching caps */
       
   313 +    return nullptr;
       
   314 +  }
       
   315 +
       
   316 +  GstCaps* caps = gst_caps_from_string(capsString);
       
   317 +  /* container only */
       
   318 +  if (!aCodecs) {
       
   319 +    return caps;
       
   320 +  }
       
   321 +
       
   322 +  nsCharSeparatedTokenizer tokenizer(*aCodecs, ',');
       
   323 +  while (tokenizer.hasMoreTokens()) {
       
   324 +    const nsSubstring& codec = tokenizer.nextToken();
       
   325 +    capsString = nullptr;
       
   326 +
       
   327 +    for (i = 0; i < G_N_ELEMENTS(mCodecs); i++) {
       
   328 +      if (codec.EqualsASCII(ENTRY_FORMAT(mCodecs[i]))) {
       
   329 +        capsString = ENTRY_CAPS(mCodecs[i]);
       
   330 +        break;
       
   331 +      }
       
   332 +    }
       
   333 +
       
   334 +    if (!capsString) {
       
   335 +      gst_caps_unref(caps);
       
   336 +      return nullptr;
       
   337 +    }
       
   338 +
       
   339 +    GstCaps* tmp = gst_caps_from_string(capsString);
       
   340 +    /* appends and frees tmp */
       
   341 +    gst_caps_append(caps, tmp);
       
   342 +  }
       
   343 +
       
   344 +  return caps;
       
   345 +}
       
   346 +
       
   347 +bool GStreamerFormatHelper::HaveElementsToProcessCaps(GstCaps* aCaps) {
       
   348 +
       
   349 +  GList* factories = GetFactories();
       
   350 +
       
   351 +  GList* list;
       
   352 +  /* here aCaps contains [containerCaps, [codecCaps1, [codecCaps2, ...]]] so process
       
   353 +   * caps structures individually as we want one element for _each_
       
   354 +   * structure */
       
   355 +  for (unsigned int i = 0; i < gst_caps_get_size(aCaps); i++) {
       
   356 +    GstStructure* s = gst_caps_get_structure(aCaps, i);
       
   357 +    GstCaps* caps = gst_caps_new_full(gst_structure_copy(s), nullptr);
       
   358 +    list = gst_element_factory_list_filter (factories, caps, GST_PAD_SINK, FALSE);
       
   359 +    gst_caps_unref(caps);
       
   360 +    if (!list) {
       
   361 +      return false;
       
   362 +    }
       
   363 +    g_list_free(list);
       
   364 +  }
       
   365 +
       
   366 +  return true;
       
   367 +}
       
   368 +
       
   369 +GList* GStreamerFormatHelper::GetFactories() {
       
   370 +  uint32_t cookie = gst_default_registry_get_feature_list_cookie ();
       
   371 +  if (cookie != mCookie) {
       
   372 +    g_list_free(mFactories);
       
   373 +    mFactories = gst_element_factory_list_get_elements
       
   374 +        (GST_ELEMENT_FACTORY_TYPE_DEMUXER | GST_ELEMENT_FACTORY_TYPE_DECODER,
       
   375 +         GST_RANK_MARGINAL);
       
   376 +    mCookie = cookie;
       
   377 +  }
       
   378 +
       
   379 +  return mFactories;
       
   380 +}
       
   381 diff --git a/content/media/gstreamer/GStreamerFormatHelper.h b/content/media/gstreamer/GStreamerFormatHelper.h
       
   382 new file mode 100644
       
   383 --- /dev/null
       
   384 +++ b/content/media/gstreamer/GStreamerFormatHelper.h
       
   385 @@ -0,0 +1,60 @@
       
   386 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       
   387 +/* vim:set ts=2 sw=2 sts=2 et cindent: */
       
   388 +/* 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,
       
   390 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
       
   391 +
       
   392 +#if !defined(GStreamerFormatHelper_h_)
       
   393 +#define GStreamerFormatHelper_h_
       
   394 +
       
   395 +#include <gst/gst.h>
       
   396 +#include <mozilla/Types.h>
       
   397 +#include "nsXPCOMStrings.h"
       
   398 +
       
   399 +class GStreamerFormatHelper {
       
   400 +  /* This class can be used to query the GStreamer registry for the required
       
   401 +   * demuxers/decoders from nsHTMLMediaElement::CanPlayType.
       
   402 +   * It implements looking at the GstRegistry to check if elements to
       
   403 +   * demux/decode the formats passed to CanPlayType() are actually installed.
       
   404 +   */
       
   405 +  public:
       
   406 +    static GStreamerFormatHelper* Instance();
       
   407 +    ~GStreamerFormatHelper();
       
   408 +
       
   409 +    bool CanHandleMediaType(const nsACString& aMIMEType,
       
   410 +                            const nsAString* aCodecs);
       
   411 +
       
   412 +   static void Shutdown();
       
   413 +
       
   414 +  private:
       
   415 +    GStreamerFormatHelper();
       
   416 +    GstCaps* ConvertFormatsToCaps(const char* aMIMEType,
       
   417 +                                  const nsAString* aCodecs);
       
   418 +    char* const *CodecListFromCaps(GstCaps* aCaps);
       
   419 +    bool HaveElementsToProcessCaps(GstCaps* aCaps);
       
   420 +    GList* GetFactories();
       
   421 +
       
   422 +    static GStreamerFormatHelper* gInstance;
       
   423 +
       
   424 +    /* table to convert from container MIME types to GStreamer elements */
       
   425 +    static char const *const mContainers[4][2];
       
   426 +
       
   427 +    /* table to convert from codec MIME types to GStreamer elements */
       
   428 +    static char const *const mCodecs[8][2];
       
   429 +
       
   430 +    /* list of GStreamer element factories
       
   431 +     * Element factories are the basic types retrieved from the GStreamer
       
   432 +     * registry, they describe all plugins and elements that GStreamer can
       
   433 +     * create.
       
   434 +     * This means that element factories are useful for automated element
       
   435 +     * instancing, such as what autopluggers do,
       
   436 +     * and for creating lists of available elements. */
       
   437 +    GList* mFactories;
       
   438 +
       
   439 +    /* Storage for the default registrys feature list cookie.
       
   440 +     * It changes every time a feature is added to or removed from the
       
   441 +     * GStreamer registry. */
       
   442 +    uint32_t mCookie;
       
   443 +};
       
   444 +
       
   445 +#endif
       
   446 diff --git a/content/media/gstreamer/Makefile.in b/content/media/gstreamer/Makefile.in
       
   447 --- a/content/media/gstreamer/Makefile.in
       
   448 +++ b/content/media/gstreamer/Makefile.in
       
   449 @@ -13,21 +13,23 @@ include $(DEPTH)/config/autoconf.mk
       
   450  MODULE		= content
       
   451  LIBRARY_NAME	= gkcongstreamer_s
       
   452  LIBXUL_LIBRARY 	= 1
       
   453  
       
   454  
       
   455  EXPORTS		+= \
       
   456  		GStreamerDecoder.h \
       
   457  		GStreamerReader.h \
       
   458 +		GStreamerFormatHelper.h \
       
   459  		$(NULL)
       
   460  
       
   461  CPPSRCS		= \
       
   462  		GStreamerReader.cpp \
       
   463  		GStreamerDecoder.cpp \
       
   464 +		GStreamerFormatHelper.cpp \
       
   465  		$(NULL)
       
   466  
       
   467  FORCE_STATIC_LIB = 1
       
   468  
       
   469  include $(topsrcdir)/config/rules.mk
       
   470  
       
   471  CFLAGS		+= $(GSTREAMER_CFLAGS)
       
   472  CXXFLAGS	+= $(GSTREAMER_CFLAGS)
       
   473 diff --git a/layout/build/Makefile.in b/layout/build/Makefile.in
       
   474 --- a/layout/build/Makefile.in
       
   475 +++ b/layout/build/Makefile.in
       
   476 @@ -318,16 +318,20 @@ LOCAL_INCLUDES	+= -I$(srcdir)/../base \
       
   477  		   -I$(topsrcdir)/js/xpconnect/loader \
       
   478  		   -I$(topsrcdir)/caps/include \
       
   479  		   -I$(topsrcdir)/netwerk/base/src \
       
   480  		   -I$(topsrcdir)/content/svg/content/src \
       
   481  		   -I$(topsrcdir)/extensions/cookie \
       
   482  		   -I$(topsrcdir)/netwerk/cookie \
       
   483  		   $(NULL)
       
   484  
       
   485 +ifdef MOZ_GSTREAMER
       
   486 +LOCAL_INCLUDES	+= $(GSTREAMER_CFLAGS)
       
   487 +endif
       
   488 +
       
   489  ifdef MOZ_B2G_RIL #{
       
   490  LOCAL_INCLUDES	+= -I$(topsrcdir)/dom/system/gonk
       
   491  endif #}
       
   492  
       
   493  ifdef MOZ_B2G_FM #{
       
   494  LOCAL_INCLUDES	+= -I$(topsrcdir)/dom/fm
       
   495  endif #}
       
   496  
       
   497 diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp
       
   498 --- a/layout/build/nsLayoutStatics.cpp
       
   499 +++ b/layout/build/nsLayoutStatics.cpp
       
   500 @@ -79,16 +79,20 @@
       
   501  #ifdef MOZ_MEDIA_PLUGINS
       
   502  #include "MediaPluginHost.h"
       
   503  #endif
       
   504  
       
   505  #ifdef MOZ_WMF
       
   506  #include "WMFDecoder.h"
       
   507  #endif
       
   508  
       
   509 +#ifdef MOZ_GSTREAMER
       
   510 +#include "GStreamerFormatHelper.h"
       
   511 +#endif
       
   512 +
       
   513  #ifdef MOZ_SYDNEYAUDIO
       
   514  #include "AudioStream.h"
       
   515  #endif
       
   516  
       
   517  #ifdef MOZ_WIDGET_GONK
       
   518  #include "nsVolumeService.h"
       
   519  using namespace mozilla::system;
       
   520  #endif
       
   521 @@ -344,16 +348,20 @@ nsLayoutStatics::Shutdown()
       
   522    nsXBLService::Shutdown();
       
   523    nsAutoCopyListener::Shutdown();
       
   524    FrameLayerBuilder::Shutdown();
       
   525  
       
   526  #ifdef MOZ_MEDIA_PLUGINS
       
   527    MediaPluginHost::Shutdown();
       
   528  #endif
       
   529  
       
   530 +#ifdef MOZ_GSTREAMER
       
   531 +  GStreamerFormatHelper::Shutdown();
       
   532 +#endif
       
   533 +
       
   534  #ifdef MOZ_SYDNEYAUDIO
       
   535    AudioStream::ShutdownLibrary();
       
   536  #endif
       
   537  
       
   538  #ifdef MOZ_WMF
       
   539    WMFDecoder::UnloadDLLs();
       
   540  #endif
       
   541