mozilla-gstreamer-760140.patch
changeset 606 9d39369e1b4c
parent 573 71cf05d3ee57
child 612 3006d73ad2fa
equal deleted inserted replaced
605:36ec036ad04d 606:9d39369e1b4c
     2 Bug 760140 - Query the GstRegistry for the required demuxers/decoders from canPlayType
     2 Bug 760140 - Query the GstRegistry for the required demuxers/decoders from canPlayType
     3 
     3 
     4 diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp
     4 diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp
     5 --- a/content/base/src/nsContentUtils.cpp
     5 --- a/content/base/src/nsContentUtils.cpp
     6 +++ b/content/base/src/nsContentUtils.cpp
     6 +++ b/content/base/src/nsContentUtils.cpp
     7 @@ -147,16 +147,19 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
     7 @@ -143,16 +143,19 @@
     8  #include "xpcprivate.h" // nsXPConnect
     8  #include "xpcprivate.h" // nsXPConnect
     9  #include "nsScriptSecurityManager.h"
     9  #include "nsScriptSecurityManager.h"
    10  #include "nsIChannelPolicy.h"
    10  #include "nsIChannelPolicy.h"
    11  #include "nsChannelPolicy.h"
    11  #include "nsChannelPolicy.h"
    12  #include "nsIContentSecurityPolicy.h"
    12  #include "nsIContentSecurityPolicy.h"
    13  #include "nsContentDLF.h"
    13  #include "nsContentDLF.h"
    14  #ifdef MOZ_MEDIA
    14  #ifdef MOZ_MEDIA
    15  #include "nsHTMLMediaElement.h"
    15  #include "nsHTMLMediaElement.h"
    16 +#ifdef MOZ_GSTREAMER
    16 +#ifdef MOZ_GSTREAMER
    17 +#include "nsGStreamerDecoder.h"
    17 +#include "GStreamerDecoder.h"
    18 +#endif
    18 +#endif
    19  #endif
    19  #endif
    20  #include "nsDOMTouchEvent.h"
    20  #include "nsDOMTouchEvent.h"
    21  #include "nsIContentViewer.h"
    21  #include "nsIContentViewer.h"
    22  #include "nsIObjectLoadingContent.h"
    22  #include "nsIObjectLoadingContent.h"
    25  #include "mozilla/Preferences.h"
    25  #include "mozilla/Preferences.h"
    26  #include "nsDOMMutationObserver.h"
    26  #include "nsDOMMutationObserver.h"
    27 diff --git a/content/html/content/public/nsHTMLMediaElement.h b/content/html/content/public/nsHTMLMediaElement.h
    27 diff --git a/content/html/content/public/nsHTMLMediaElement.h b/content/html/content/public/nsHTMLMediaElement.h
    28 --- a/content/html/content/public/nsHTMLMediaElement.h
    28 --- a/content/html/content/public/nsHTMLMediaElement.h
    29 +++ b/content/html/content/public/nsHTMLMediaElement.h
    29 +++ b/content/html/content/public/nsHTMLMediaElement.h
    30 @@ -263,17 +263,19 @@ public:
    30 @@ -259,17 +259,19 @@ public:
    31    void UpdateMediaSize(nsIntSize size);
    31    void UpdateMediaSize(nsIntSize size);
    32  
    32  
    33    // Returns the CanPlayStatus indicating if we can handle this
    33    // Returns the CanPlayStatus indicating if we can handle this
    34    // MIME type. The MIME type should not include the codecs parameter.
    34    // MIME type. The MIME type should not include the codecs parameter.
    35    // If it returns anything other than CANPLAY_NO then it also
    35    // If it returns anything other than CANPLAY_NO then it also
    46    static CanPlayStatus GetCanPlay(const nsAString& aType);
    46    static CanPlayStatus GetCanPlay(const nsAString& aType);
    47  
    47  
    48    // Returns true if we should handle this MIME type when it appears
    48    // Returns true if we should handle this MIME type when it appears
    49    // as an <object> or as a toplevel page. If, in practice, our support
    49    // as an <object> or as a toplevel page. If, in practice, our support
    50    // for the type is more limited than appears in the wild, we should return
    50    // for the type is more limited than appears in the wild, we should return
    51 @@ -305,19 +307,16 @@ public:
    51 @@ -292,18 +294,16 @@ public:
       
    52  #ifdef MOZ_WEBM
    52    static bool IsWebMType(const nsACString& aType);
    53    static bool IsWebMType(const nsACString& aType);
    53    static const char gWebMTypes[2][11];
    54    static const char gWebMTypes[2][11];
    54    static char const *const gWebMCodecs[4];
    55    static char const *const gWebMCodecs[4];
    55  #endif
    56  #endif
    56  
    57  
    57  #ifdef MOZ_GSTREAMER
    58  #ifdef MOZ_GSTREAMER
    58    static bool IsGStreamerEnabled();
       
    59    static bool IsGStreamerSupportedType(const nsACString& aType);
    59    static bool IsGStreamerSupportedType(const nsACString& aType);
    60 -  static bool IsH264Type(const nsACString& aType);
    60 -  static bool IsH264Type(const nsACString& aType);
    61 -  static const char gH264Types[3][16];
    61 -  static const char gH264Types[3][16];
    62 -  static char const *const gH264Codecs[7];
       
    63  #endif
    62  #endif
    64  
    63  
    65  #ifdef MOZ_WIDGET_GONK
    64  #ifdef MOZ_WIDGET_GONK
    66    static bool IsOmxEnabled();
       
    67    static bool IsOmxSupportedType(const nsACString& aType);
    65    static bool IsOmxSupportedType(const nsACString& aType);
    68    static const char gOmxTypes[5][16];
    66    static const char gOmxTypes[5][16];
    69    static char const *const gH264Codecs[7];
    67  #endif
    70  #endif
    68  
       
    69  #if defined(MOZ_GSTREAMER) || defined(MOZ_WIDGET_GONK)
    71 diff --git a/content/html/content/src/nsHTMLMediaElement.cpp b/content/html/content/src/nsHTMLMediaElement.cpp
    70 diff --git a/content/html/content/src/nsHTMLMediaElement.cpp b/content/html/content/src/nsHTMLMediaElement.cpp
    72 --- a/content/html/content/src/nsHTMLMediaElement.cpp
    71 --- a/content/html/content/src/nsHTMLMediaElement.cpp
    73 +++ b/content/html/content/src/nsHTMLMediaElement.cpp
    72 +++ b/content/html/content/src/nsHTMLMediaElement.cpp
    74 @@ -2128,51 +2128,34 @@ nsHTMLMediaElement::IsWebMType(const nsA
    73 @@ -2213,50 +2213,29 @@ nsHTMLMediaElement::IsWebMType(const nsA
    75        return true;
    74        return true;
    76      }
    75      }
    77    }
    76    }
    78  
    77  
    79    return false;
    78    return false;
    80  }
    79  }
    81  #endif
    80  #endif
    82  
    81  
    83 -#if defined(MOZ_GSTREAMER) || defined(MOZ_WIDGET_GONK)
    82 -#if defined(MOZ_GSTREAMER) || defined(MOZ_WIDGET_GONK)
    84 +#ifdef MOZ_WIDGET_GONK
    83 +#ifdef MOZ_WIDGET_GONK
    85  char const *const nsHTMLMediaElement::gH264Codecs[7] = {
    84  char const *const nsHTMLMediaElement::gH264Codecs[9] = {
    86    "avc1.42E01E",
    85    "avc1.42E01E",  // H.264 Constrained Baseline Profile Level 3.0
    87    "avc1.42001E",
    86    "avc1.42001E",  // H.264 Baseline Profile Level 3.0
    88    "avc1.58A01E",
    87    "avc1.58A01E",  // H.264 Extended Profile Level 3.0
    89    "avc1.4D401E",
    88    "avc1.4D401E",  // H.264 Main Profile Level 3.0
    90    "avc1.64001E",
    89    "avc1.64001E",  // H.264 High Profile Level 3.0
    91    "mp4a.40.2",
    90    "avc1.64001F",  // H.264 High Profile Level 3.1
       
    91    "mp4v.20.3",    // 3GPP
       
    92    "mp4a.40.2",    // AAC-LC
    92    nullptr
    93    nullptr
    93  };
    94  };
    94  #endif
    95 -#endif
    95  
    96 -
    96  #ifdef MOZ_GSTREAMER
    97 -#ifdef MOZ_GSTREAMER
    97 -const char nsHTMLMediaElement::gH264Types[3][16] = {
    98 -const char nsHTMLMediaElement::gH264Types[3][16] = {
    98 -  "video/mp4",
    99 -  "video/mp4",
    99 -  "video/3gpp",
   100 -  "video/3gpp",
   100 -  "video/quicktime",
   101 -  "video/quicktime",
   101 -};
   102 -};
   102 -
       
   103  bool
       
   104  nsHTMLMediaElement::IsGStreamerEnabled()
       
   105  {
       
   106    return Preferences::GetBool("media.gstreamer.enabled");
       
   107  }
       
   108 -
   103 -
   109 -bool
   104 -bool
   110 -nsHTMLMediaElement::IsH264Type(const nsACString& aType)
   105 -nsHTMLMediaElement::IsH264Type(const nsACString& aType)
   111 -{
   106 -{
   112 -  for (uint32_t i = 0; i < ArrayLength(gH264Types); ++i) {
   107 -  for (uint32_t i = 0; i < ArrayLength(gH264Types); ++i) {
   114 -      return true;
   109 -      return true;
   115 -    }
   110 -    }
   116 -  }
   111 -  }
   117 -  return false;
   112 -  return false;
   118 -}
   113 -}
   119  #endif
   114 -#endif
   120  
   115 -
   121  #ifdef MOZ_WIDGET_GONK
   116 -#ifdef MOZ_WIDGET_GONK
       
   117 +
   122  const char nsHTMLMediaElement::gOmxTypes[5][16] = {
   118  const char nsHTMLMediaElement::gOmxTypes[5][16] = {
   123    "audio/mpeg",
   119    "audio/mpeg",
   124    "audio/mp4",
   120    "audio/mp4",
   125    "video/mp4",
   121    "video/mp4",
   126    "video/3gpp",
   122    "video/3gpp",
   127 @@ -2257,18 +2240,22 @@ nsHTMLMediaElement::IsDASHMPDType(const 
   123    "video/quicktime",
       
   124  };
       
   125  
       
   126 @@ -2319,18 +2298,22 @@ nsHTMLMediaElement::IsDASHMPDType(const 
   128  
   127  
   129    return false;
   128    return false;
   130  }
   129  }
   131  #endif
   130  #endif
   132  
   131  
   133  /* static */
   132  /* static */
   134  nsHTMLMediaElement::CanPlayStatus 
   133  nsHTMLMediaElement::CanPlayStatus
   135  nsHTMLMediaElement::CanHandleMediaType(const char* aMIMEType,
   134  nsHTMLMediaElement::CanHandleMediaType(const char* aMIMEType,
   136 -                                       char const *const ** aCodecList)
   135 -                                       char const *const ** aCodecList)
   137 +                                       const char *aCodecs,
   136 +                                       const char *aCodecs,
   138 +                                       char const *const ** aCodecList,
   137 +                                       char const *const ** aCodecList,
   139 +                                       bool* aCheckCodecList)
   138 +                                       bool* aCheckCodecList)
   146      return CANPLAY_MAYBE;
   145      return CANPLAY_MAYBE;
   147    }
   146    }
   148  #endif
   147  #endif
   149  #ifdef MOZ_OGG
   148  #ifdef MOZ_OGG
   150    if (IsOggType(nsDependentCString(aMIMEType))) {
   149    if (IsOggType(nsDependentCString(aMIMEType))) {
   151 @@ -2292,20 +2279,22 @@ nsHTMLMediaElement::CanHandleMediaType(c
   150 @@ -2354,20 +2337,22 @@ nsHTMLMediaElement::CanHandleMediaType(c
   152    if (IsDASHMPDType(nsDependentCString(aMIMEType))) {
   151    if (IsDASHMPDType(nsDependentCString(aMIMEType))) {
   153      // DASH manifest uses WebM codecs only.
   152      // DASH manifest uses WebM codecs only.
   154      *aCodecList = gWebMCodecs;
   153      *aCodecList = gWebMCodecs;
   155      return CANPLAY_YES;
   154      return CANPLAY_YES;
   156    }
   155    }
   163 -  }
   162 -  }
   164 +  if (aCheckCodecList)
   163 +  if (aCheckCodecList)
   165 +    *aCheckCodecList = false;
   164 +    *aCheckCodecList = false;
   166 +  if (aCodecList)
   165 +  if (aCodecList)
   167 +    *aCodecList = nullptr;
   166 +    *aCodecList = nullptr;
   168 +  if (nsGStreamerDecoder::CanHandleMediaType(aMIMEType, aCodecs))
   167 +  if (GStreamerDecoder::CanHandleMediaType(aMIMEType, aCodecs))
   169 +    return CANPLAY_YES;
   168 +    return CANPLAY_YES;
   170  #endif
   169  #endif
   171  #ifdef MOZ_WIDGET_GONK
   170  #ifdef MOZ_WIDGET_GONK
   172    if (IsOmxSupportedType(nsDependentCString(aMIMEType))) {
   171    if (IsOmxSupportedType(nsDependentCString(aMIMEType))) {
   173      *aCodecList = gH264Codecs;
   172      *aCodecList = gH264Codecs;
   174      return CANPLAY_MAYBE;
   173      return CANPLAY_MAYBE;
   175    }
   174    }
   176  #endif
   175  #endif
   177  #ifdef MOZ_MEDIA_PLUGINS
   176  #ifdef MOZ_MEDIA_PLUGINS
   178 @@ -2326,17 +2315,17 @@ bool nsHTMLMediaElement::ShouldHandleMed
   177 @@ -2388,17 +2373,17 @@ bool nsHTMLMediaElement::ShouldHandleMed
   179    if (IsOggType(nsDependentCString(aMIMEType)))
   178    if (IsOggType(nsDependentCString(aMIMEType)))
   180      return true;
   179      return true;
   181  #endif
   180  #endif
   182  #ifdef MOZ_WEBM
   181  #ifdef MOZ_WEBM
   183    if (IsWebMType(nsDependentCString(aMIMEType)))
   182    if (IsWebMType(nsDependentCString(aMIMEType)))
   184      return true;
   183      return true;
   185  #endif
   184  #endif
   186  #ifdef MOZ_GSTREAMER
   185  #ifdef MOZ_GSTREAMER
   187 -  if (IsH264Type(nsDependentCString(aMIMEType)))
   186 -  if (IsH264Type(nsDependentCString(aMIMEType)))
   188 +  if (nsGStreamerDecoder::CanHandleMediaType(aMIMEType, nullptr))
   187 +  if (GStreamerDecoder::CanHandleMediaType(aMIMEType, nullptr))
   189      return true;
   188      return true;
   190  #endif
   189  #endif
   191  #ifdef MOZ_WIDGET_GONK
   190  #ifdef MOZ_WIDGET_GONK
   192    if (IsOmxSupportedType(nsDependentCString(aMIMEType))) {
   191    if (IsOmxSupportedType(nsDependentCString(aMIMEType))) {
   193      return true;
   192      return true;
   194    }
   193    }
   195  #endif
   194  #endif
   196  #ifdef MOZ_MEDIA_PLUGINS
   195  #ifdef MOZ_MEDIA_PLUGINS
   197 @@ -2367,26 +2356,31 @@ nsHTMLMediaElement::GetCanPlay(const nsA
   196 @@ -2429,26 +2414,31 @@ nsHTMLMediaElement::GetCanPlay(const nsA
   198  {
   197  {
   199    nsContentTypeParser parser(aType);
   198    nsContentTypeParser parser(aType);
   200    nsAutoString mimeType;
   199    nsAutoString mimeType;
   201    nsresult rv = parser.GetType(mimeType);
   200    nsresult rv = parser.GetType(mimeType);
   202    if (NS_FAILED(rv))
   201    if (NS_FAILED(rv))
   229    CanPlayStatus result = CANPLAY_YES;
   228    CanPlayStatus result = CANPLAY_YES;
   230    // See http://www.rfc-editor.org/rfc/rfc4281.txt for the description
   229    // See http://www.rfc-editor.org/rfc/rfc4281.txt for the description
   231    // of the 'codecs' parameter
   230    // of the 'codecs' parameter
   232    nsCharSeparatedTokenizer tokenizer(codecs, ',');
   231    nsCharSeparatedTokenizer tokenizer(codecs, ',');
   233    bool expectMoreTokens = false;
   232    bool expectMoreTokens = false;
   234 @@ -2425,46 +2419,41 @@ nsHTMLMediaElement::CanPlayType(const ns
   233 @@ -2487,43 +2477,39 @@ nsHTMLMediaElement::CanPlayType(const ns
   235  }
   234  }
   236  
   235  
   237  #ifdef MOZ_GSTREAMER
   236  #ifdef MOZ_GSTREAMER
   238  bool
   237  bool
   239  nsHTMLMediaElement::IsGStreamerSupportedType(const nsACString& aMimeType)
   238  nsHTMLMediaElement::IsGStreamerSupportedType(const nsACString& aMimeType)
   240  {
   239  {
   241    if (!IsGStreamerEnabled())
   240    if (!MediaDecoder::IsGStreamerEnabled())
   242      return false;
   241      return false;
   243 -  if (IsH264Type(aMimeType))
   242 -  if (IsH264Type(aMimeType))
   244 +
   243 +
   245 +  const char *type;
   244 +  const char *type;
   246 +  NS_CStringGetData(aMimeType, &type, nullptr);
   245 +  NS_CStringGetData(aMimeType, &type, nullptr);
   247 +  if (nsGStreamerDecoder::CanHandleMediaType(type, nullptr))
   246 +  if (GStreamerDecoder::CanHandleMediaType(type, nullptr))
   248      return true;
   247      return true;
   249 -  if (!Preferences::GetBool("media.prefer-gstreamer", false))
   248 -  if (!Preferences::GetBool("media.prefer-gstreamer", false))
   250 -    return false;
   249 -    return false;
   251 -#ifdef MOZ_WEBM
   250 -#ifdef MOZ_WEBM
   252 -  if (IsWebMType(aMimeType))
   251 -  if (IsWebMType(aMimeType))
   259 +
   258 +
   260    return false;
   259    return false;
   261  }
   260  }
   262  #endif
   261  #endif
   263  
   262  
   264  already_AddRefed<nsMediaDecoder>
   263  already_AddRefed<MediaDecoder>
   265  nsHTMLMediaElement::CreateDecoder(const nsACString& aType)
   264  nsHTMLMediaElement::CreateDecoder(const nsACString& aType)
   266  {
   265  {
       
   266  
   267  #ifdef MOZ_GSTREAMER
   267  #ifdef MOZ_GSTREAMER
   268    // When enabled, use GStreamer for H.264, but not for codecs handled by our
   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.
   269    // bundled decoders, unless the "media.prefer-gstreamer" pref is set.
   270 -  if (IsGStreamerSupportedType(aType)) {
   270 -  if (IsGStreamerSupportedType(aType)) {
   271 -    nsRefPtr<nsGStreamerDecoder> decoder = new nsGStreamerDecoder();
   271 -    nsRefPtr<GStreamerDecoder> decoder = new GStreamerDecoder();
   272 -    if (decoder->Init(this)) {
   272 -    if (decoder->Init(this)) {
   273 -      return decoder.forget();
   273 -      return decoder.forget();
   274 +  if (!Preferences::GetBool("media.prefer-gstreamer", false)) {
   274 +  if (!Preferences::GetBool("media.prefer-gstreamer", false)) {
   275 +    if (IsGStreamerSupportedType(aType)) {
   275 +    if (IsGStreamerSupportedType(aType)) {
   276 +      nsRefPtr<nsGStreamerDecoder> decoder = new nsGStreamerDecoder();
   276 +      nsRefPtr<GStreamerDecoder> decoder = new GStreamerDecoder();
   277 +      if (decoder->Init(this)) {
   277 +      if (decoder->Init(this)) {
   278 +        return decoder.forget();
   278 +        return decoder.forget();
   279 +      }
   279 +      }
   280      }
   280      }
   281    }
   281    }
   282  #endif
   282  #endif
   283 -
   283  
   284  #ifdef MOZ_RAW
   284  #ifdef MOZ_RAW
   285    if (IsRawType(aType)) {
   285    if (IsRawType(aType)) {
   286      nsRefPtr<nsRawDecoder> decoder = new nsRawDecoder();
   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();
   287      if (decoder->Init(this)) {
   291      if (decoder->Init(this)) {
   288        return decoder.forget();
   292        return decoder.forget();
   289      }
   293      }
   290    }
   294    }
   291  #endif
   295  #endif
   292 @@ -2503,25 +2492,33 @@ nsHTMLMediaElement::CreateDecoder(const 
   296  
   293  #ifdef MOZ_WEBM
       
   294    if (IsWebMType(aType)) {
       
   295      nsRefPtr<nsWebMDecoder> decoder = new nsWebMDecoder();
       
   296      if (decoder->Init(this)) {
       
   297        return decoder.forget();
       
   298      }
       
   299    }
       
   300  #endif
       
   301 -
       
   302  #ifdef MOZ_DASH
       
   303    if (IsDASHMPDType(aType)) {
       
   304      nsRefPtr<nsDASHDecoder> decoder = new nsDASHDecoder();
       
   305      if (decoder->Init(this)) {
       
   306        return decoder.forget();
       
   307      }
       
   308    }
       
   309  #endif
       
   310 +#ifdef MOZ_GSTREAMER
   297 +#ifdef MOZ_GSTREAMER
   311 +  // use GStreamer as fallback if not preferred
   298 +  // use GStreamer as fallback if not preferred
   312 +  if (IsGStreamerSupportedType(aType)) {
   299 +  if (IsGStreamerSupportedType(aType)) {
   313 +    nsRefPtr<nsGStreamerDecoder> decoder = new nsGStreamerDecoder();
   300 +    nsRefPtr<GStreamerDecoder> decoder = new GStreamerDecoder();
   314 +    if (decoder->Init(this)) {
   301 +    if (decoder->Init(this)) {
   315 +      return decoder.forget();
   302 +      return decoder.forget();
   316 +    }
   303 +    }
   317 +  }
   304 +  }
   318 +#endif
   305 +#endif
   319  
   306 +
   320    return nullptr;
   307    return nullptr;
   321  }
   308  }
   322  
   309  
   323  nsresult nsHTMLMediaElement::InitializeDecoderAsClone(nsMediaDecoder* aOriginal)
   310  nsresult nsHTMLMediaElement::InitializeDecoderAsClone(MediaDecoder* aOriginal)
   324  {
   311  {
   325    NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set");
   312    NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set");
   326    NS_ASSERTION(mDecoder == nullptr, "Shouldn't have a decoder");
   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
       
   316 --- a/content/media/gstreamer/GStreamerDecoder.cpp
       
   317 +++ b/content/media/gstreamer/GStreamerDecoder.cpp
       
   318 @@ -2,18 +2,23 @@
       
   319  /* vim:set ts=2 sw=2 sts=2 et cindent: */
       
   320  /* 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,
       
   322   * You can obtain one at http://mozilla.org/MPL/2.0/. */
       
   323  
       
   324  #include "MediaDecoderStateMachine.h"
       
   325  #include "GStreamerReader.h"
       
   326  #include "GStreamerDecoder.h"
       
   327 +#include "nsGStreamerFormatHelper.h"
       
   328  
       
   329  namespace mozilla {
       
   330  
       
   331  MediaDecoderStateMachine* GStreamerDecoder::CreateStateMachine()
       
   332  {
       
   333    return new MediaDecoderStateMachine(this, new GStreamerReader(this));
       
   334  }
       
   335  
       
   336 +bool GStreamerDecoder::CanHandleMediaType(const char* aMIMEType,
       
   337 +                                            const char* aCodecs) {
       
   338 +  return GStreamerFormatHelper::Instance()->CanHandleMediaType(aMIMEType, aCodecs);
       
   339 +}
       
   340  } // namespace mozilla
       
   341  
       
   342 diff --git a/content/media/gstreamer/GStreamerDecoder.h b/content/media/gstreamer/GStreamerDecoder.h
       
   343 --- a/content/media/gstreamer/GStreamerDecoder.h
       
   344 +++ b/content/media/gstreamer/GStreamerDecoder.h
       
   345 @@ -11,13 +11,14 @@
       
   346  
       
   347  namespace mozilla {
       
   348  
       
   349  class GStreamerDecoder : public MediaDecoder
       
   350  {
       
   351  public:
       
   352    virtual MediaDecoder* Clone() { return new GStreamerDecoder(); }
       
   353    virtual MediaDecoderStateMachine* CreateStateMachine();
       
   354 +  static bool CanHandleMediaType(const char* aMIMEType, const char* aCodecs);
       
   355  };
       
   356  
       
   357  } // namespace mozilla
       
   358  
       
   359  #endif
   327 diff --git a/content/media/gstreamer/Makefile.in b/content/media/gstreamer/Makefile.in
   360 diff --git a/content/media/gstreamer/Makefile.in b/content/media/gstreamer/Makefile.in
   328 --- a/content/media/gstreamer/Makefile.in
   361 --- a/content/media/gstreamer/Makefile.in
   329 +++ b/content/media/gstreamer/Makefile.in
   362 +++ b/content/media/gstreamer/Makefile.in
   330 @@ -17,16 +17,17 @@ LIBXUL_LIBRARY 	= 1
   363 @@ -17,16 +17,17 @@ LIBXUL_LIBRARY 	= 1
   331  
   364  
   332  EXPORTS		+= \
   365  EXPORTS		+= \
   333  		nsGStreamerDecoder.h \
   366  		GStreamerDecoder.h \
   334  		$(NULL)
   367  		$(NULL)
   335  
   368  
   336  CPPSRCS		= \
   369  CPPSRCS		= \
   337  		nsGStreamerReader.cpp \
   370  		GStreamerReader.cpp \
   338  		nsGStreamerDecoder.cpp \
   371  		GStreamerDecoder.cpp \
   339 +		nsGStreamerFormatHelper.cpp \
   372 +		nsGStreamerFormatHelper.cpp \
   340  		$(NULL)
   373  		$(NULL)
   341  
   374  
   342  FORCE_STATIC_LIB = 1
   375  FORCE_STATIC_LIB = 1
   343  
   376  
   344  include $(topsrcdir)/config/rules.mk
   377  include $(topsrcdir)/config/rules.mk
   345  
   378  
   346  CFLAGS		+= $(GSTREAMER_CFLAGS)
   379  CFLAGS		+= $(GSTREAMER_CFLAGS)
   347  CXXFLAGS	+= $(GSTREAMER_CFLAGS)
   380  CXXFLAGS	+= $(GSTREAMER_CFLAGS)
   348 diff --git a/content/media/gstreamer/nsGStreamerDecoder.cpp b/content/media/gstreamer/nsGStreamerDecoder.cpp
       
   349 --- a/content/media/gstreamer/nsGStreamerDecoder.cpp
       
   350 +++ b/content/media/gstreamer/nsGStreamerDecoder.cpp
       
   351 @@ -2,13 +2,19 @@
       
   352  /* vim:set ts=2 sw=2 sts=2 et cindent: */
       
   353  /* This Source Code Form is subject to the terms of the Mozilla Public
       
   354   * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       
   355   * You can obtain one at http://mozilla.org/MPL/2.0/. */
       
   356  
       
   357  #include "nsBuiltinDecoderStateMachine.h"
       
   358  #include "nsGStreamerReader.h"
       
   359  #include "nsGStreamerDecoder.h"
       
   360 +#include "nsGStreamerFormatHelper.h"
       
   361  
       
   362  nsDecoderStateMachine* nsGStreamerDecoder::CreateStateMachine()
       
   363  {
       
   364    return new nsBuiltinDecoderStateMachine(this, new nsGStreamerReader(this));
       
   365  }
       
   366 +
       
   367 +bool nsGStreamerDecoder::CanHandleMediaType(const char* aMIMEType,
       
   368 +                                            const char* aCodecs) {
       
   369 +  return nsGStreamerFormatHelper::Instance()->CanHandleMediaType(aMIMEType, aCodecs);
       
   370 +}
       
   371 diff --git a/content/media/gstreamer/nsGStreamerDecoder.h b/content/media/gstreamer/nsGStreamerDecoder.h
       
   372 --- a/content/media/gstreamer/nsGStreamerDecoder.h
       
   373 +++ b/content/media/gstreamer/nsGStreamerDecoder.h
       
   374 @@ -9,11 +9,12 @@
       
   375  
       
   376  #include "nsBuiltinDecoder.h"
       
   377  
       
   378  class nsGStreamerDecoder : public nsBuiltinDecoder
       
   379  {
       
   380  public:
       
   381    virtual nsMediaDecoder* Clone() { return new nsGStreamerDecoder(); }
       
   382    virtual nsDecoderStateMachine* CreateStateMachine();
       
   383 +  static bool CanHandleMediaType(const char* aMIMEType, const char* aCodecs);
       
   384  };
       
   385  
       
   386  #endif
       
   387 diff --git a/content/media/gstreamer/nsGStreamerFormatHelper.cpp b/content/media/gstreamer/nsGStreamerFormatHelper.cpp
   381 diff --git a/content/media/gstreamer/nsGStreamerFormatHelper.cpp b/content/media/gstreamer/nsGStreamerFormatHelper.cpp
   388 new file mode 100644
   382 new file mode 100644
   389 --- /dev/null
   383 --- /dev/null
   390 +++ b/content/media/gstreamer/nsGStreamerFormatHelper.cpp
   384 +++ b/content/media/gstreamer/nsGStreamerFormatHelper.cpp
   391 @@ -0,0 +1,149 @@
   385 @@ -0,0 +1,149 @@
   400 +#include "nsXPCOMStrings.h"
   394 +#include "nsXPCOMStrings.h"
   401 +
   395 +
   402 +#define ENTRY_FORMAT(entry) entry[0]
   396 +#define ENTRY_FORMAT(entry) entry[0]
   403 +#define ENTRY_CAPS(entry) entry[1]
   397 +#define ENTRY_CAPS(entry) entry[1]
   404 +
   398 +
   405 +nsGStreamerFormatHelper* nsGStreamerFormatHelper::gInstance = nullptr;
   399 +GStreamerFormatHelper* GStreamerFormatHelper::gInstance = nullptr;
   406 +
   400 +
   407 +nsGStreamerFormatHelper *nsGStreamerFormatHelper::Instance() {
   401 +GStreamerFormatHelper *GStreamerFormatHelper::Instance() {
   408 +  if (!gInstance) {
   402 +  if (!gInstance) {
   409 +    gst_init(nullptr, nullptr);
   403 +    gst_init(nullptr, nullptr);
   410 +    gInstance = new nsGStreamerFormatHelper();
   404 +    gInstance = new GStreamerFormatHelper();
   411 +  }
   405 +  }
   412 +
   406 +
   413 +  return gInstance;
   407 +  return gInstance;
   414 +}
   408 +}
   415 +
   409 +
   416 +nsGStreamerFormatHelper::nsGStreamerFormatHelper()
   410 +GStreamerFormatHelper::GStreamerFormatHelper()
   417 +  : mFactories(nullptr),
   411 +  : mFactories(nullptr),
   418 +    mCookie(0)
   412 +    mCookie(0)
   419 +{
   413 +{
   420 +  const char *containers[3][2] = {
   414 +  const char *containers[3][2] = {
   421 +    {"video/mp4", "video/quicktime"},
   415 +    {"video/mp4", "video/quicktime"},
   434 +    {"mp3", "audio/mpeg, mpegversion=(int)1"},
   428 +    {"mp3", "audio/mpeg, mpegversion=(int)1"},
   435 +  };
   429 +  };
   436 +  memcpy(mCodecs, codecs, sizeof(codecs));
   430 +  memcpy(mCodecs, codecs, sizeof(codecs));
   437 +}
   431 +}
   438 +
   432 +
   439 +nsGStreamerFormatHelper::~nsGStreamerFormatHelper() {
   433 +GStreamerFormatHelper::~GStreamerFormatHelper() {
   440 +  if (mFactories)
   434 +  if (mFactories)
   441 +    g_list_free(mFactories);
   435 +    g_list_free(mFactories);
   442 +}
   436 +}
   443 +
   437 +
   444 +bool nsGStreamerFormatHelper::CanHandleMediaType(const char* aMIMEType,
   438 +bool GStreamerFormatHelper::CanHandleMediaType(const char* aMIMEType,
   445 +                                                 const char *aCodecs) {
   439 +                                                 const char *aCodecs) {
   446 +  GstCaps *caps = ConvertFormatsToCaps(aMIMEType, aCodecs);
   440 +  GstCaps *caps = ConvertFormatsToCaps(aMIMEType, aCodecs);
   447 +  if (!caps) {
   441 +  if (!caps) {
   448 +    return false;
   442 +    return false;
   449 +  }
   443 +  }
   452 +  gst_caps_unref(caps);
   446 +  gst_caps_unref(caps);
   453 +
   447 +
   454 +  return ret;
   448 +  return ret;
   455 +}
   449 +}
   456 +
   450 +
   457 +GstCaps *nsGStreamerFormatHelper::ConvertFormatsToCaps(const char *aMIMEType,
   451 +GstCaps *GStreamerFormatHelper::ConvertFormatsToCaps(const char *aMIMEType,
   458 +                                                       const char *aCodecs) {
   452 +                                                       const char *aCodecs) {
   459 +  unsigned int i;
   453 +  unsigned int i;
   460 +
   454 +
   461 +  /* convert aMIMEType to gst container caps */
   455 +  /* convert aMIMEType to gst container caps */
   462 +  const char *capsString = nullptr;
   456 +  const char *capsString = nullptr;
   502 +  }
   496 +  }
   503 +
   497 +
   504 +  return caps;
   498 +  return caps;
   505 +}
   499 +}
   506 +
   500 +
   507 +bool nsGStreamerFormatHelper::HaveElementsToProcessCaps(GstCaps *aCaps) {
   501 +bool GStreamerFormatHelper::HaveElementsToProcessCaps(GstCaps *aCaps) {
   508 +
   502 +
   509 +  GList *factories = GetFactories();
   503 +  GList *factories = GetFactories();
   510 +
   504 +
   511 +  GList *list;
   505 +  GList *list;
   512 +  /* here aCaps contains [containerCaps, [codecCaps1, [codecCaps2, ...]]] so process
   506 +  /* here aCaps contains [containerCaps, [codecCaps1, [codecCaps2, ...]]] so process
   524 +  }
   518 +  }
   525 +
   519 +
   526 +  return true;
   520 +  return true;
   527 +}
   521 +}
   528 +
   522 +
   529 +GList * nsGStreamerFormatHelper::GetFactories() {
   523 +GList * GStreamerFormatHelper::GetFactories() {
   530 +  uint32_t cookie = gst_default_registry_get_feature_list_cookie ();
   524 +  uint32_t cookie = gst_default_registry_get_feature_list_cookie ();
   531 +  if (cookie != mCookie) {
   525 +  if (cookie != mCookie) {
   532 +    g_list_free(mFactories);
   526 +    g_list_free(mFactories);
   533 +    mFactories = gst_element_factory_list_get_elements
   527 +    mFactories = gst_element_factory_list_get_elements
   534 +        (GST_ELEMENT_FACTORY_TYPE_DEMUXER | GST_ELEMENT_FACTORY_TYPE_DECODER,
   528 +        (GST_ELEMENT_FACTORY_TYPE_DEMUXER | GST_ELEMENT_FACTORY_TYPE_DECODER,
   553 +#define nsGStreamerFormatHelper_h_
   547 +#define nsGStreamerFormatHelper_h_
   554 +
   548 +
   555 +#include <gst/gst.h>
   549 +#include <gst/gst.h>
   556 +#include <mozilla/Types.h>
   550 +#include <mozilla/Types.h>
   557 +
   551 +
   558 +class nsGStreamerFormatHelper {
   552 +class GStreamerFormatHelper {
   559 +  public:
   553 +  public:
   560 +    static nsGStreamerFormatHelper *Instance();
   554 +    static GStreamerFormatHelper *Instance();
   561 +    ~nsGStreamerFormatHelper();
   555 +    ~GStreamerFormatHelper();
   562 +
   556 +
   563 +    bool CanHandleMediaType(const char *aMIMEType,
   557 +    bool CanHandleMediaType(const char *aMIMEType,
   564 +                            const char *aCodecs);
   558 +                            const char *aCodecs);
   565 +
   559 +
   566 +  private:
   560 +  private:
   567 +    nsGStreamerFormatHelper();
   561 +    GStreamerFormatHelper();
   568 +    GstCaps *ConvertFormatsToCaps(const char *aMIMEType,
   562 +    GstCaps *ConvertFormatsToCaps(const char *aMIMEType,
   569 +                                  const char *aCodecs);
   563 +                                  const char *aCodecs);
   570 +    char * const *CodecListFromCaps(GstCaps *aCaps);
   564 +    char * const *CodecListFromCaps(GstCaps *aCaps);
   571 +    bool HaveElementsToProcessCaps(GstCaps *aCaps);
   565 +    bool HaveElementsToProcessCaps(GstCaps *aCaps);
   572 +    GList *GetFactories();
   566 +    GList *GetFactories();
   573 +
   567 +
   574 +    static nsGStreamerFormatHelper *gInstance;
   568 +    static GStreamerFormatHelper *gInstance;
   575 +
   569 +
   576 +    const char *mContainers[3][2];
   570 +    const char *mContainers[3][2];
   577 +    const char *mCodecs[7][2];
   571 +    const char *mCodecs[7][2];
   578 +    GList *mFactories;
   572 +    GList *mFactories;
   579 +    uint32_t mCookie;
   573 +    uint32_t mCookie;