Bug 1208348 - Check whether DirectShow can decode MP3 before assuming it will work. r=jya
authorChris Pearce <cpearce@mozilla.com>
Mon, 28 Sep 2015 17:57:10 +1300
changeset 264614 107f8e63982d6aadbe8e7fa54ce444603310f6fb
parent 264613 22e54267e6c9c684bfb782a3c5bb35b38cf3ac24
child 264615 967c555a595c9dee70b058fee7e4412eb068d23f
push id65695
push usercpearce@mozilla.com
push dateMon, 28 Sep 2015 04:57:21 +0000
treeherdermozilla-inbound@efcfe0c08c24 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1208348
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1208348 - Check whether DirectShow can decode MP3 before assuming it will work. r=jya
dom/media/directshow/DirectShowDecoder.cpp
dom/media/directshow/DirectShowUtils.cpp
dom/media/directshow/DirectShowUtils.h
--- a/dom/media/directshow/DirectShowDecoder.cpp
+++ b/dom/media/directshow/DirectShowDecoder.cpp
@@ -40,17 +40,18 @@ DirectShowDecoder::GetSupportedCodecs(co
 
   return false;
 }
 
 /* static */
 bool
 DirectShowDecoder::IsEnabled()
 {
-  return Preferences::GetBool("media.directshow.enabled");
+  return CanDecodeMP3UsingDirectShow() &&
+         Preferences::GetBool("media.directshow.enabled");
 }
 
 DirectShowDecoder::DirectShowDecoder()
 {
   MOZ_COUNT_CTOR(DirectShowDecoder);
 }
 
 DirectShowDecoder::~DirectShowDecoder()
--- a/dom/media/directshow/DirectShowUtils.cpp
+++ b/dom/media/directshow/DirectShowUtils.cpp
@@ -203,20 +203,18 @@ CreateAndAddFilter(IGraphBuilder* aGraph
   }
 
   filter.forget(aOutFilter);
 
   return S_OK;
 }
 
 HRESULT
-AddMP3DMOWrapperFilter(IGraphBuilder* aGraph,
-                       IBaseFilter **aOutFilter)
+CreateMP3DMOWrapperFilter(IBaseFilter **aOutFilter)
 {
-  NS_ENSURE_TRUE(aGraph, E_POINTER);
   NS_ENSURE_TRUE(aOutFilter, E_POINTER);
   HRESULT hr;
 
   // Create the wrapper filter.
   nsRefPtr<IBaseFilter> filter;
   hr = CoCreateInstance(CLSID_DMOWrapperFilter,
                         nullptr,
                         CLSCTX_INPROC_SERVER,
@@ -240,28 +238,75 @@ AddMP3DMOWrapperFilter(IGraphBuilder* aG
   if (FAILED(hr)) {
     // Can't instantiate MP3 DMO. It doesn't exist on Windows XP, we're
     // probably hitting that. Don't log warning to console, this is an
     // expected error.
     WARN("dmoWrapper Init failed, hr=%x", hr);
     return hr;
   }
 
+  filter.forget(aOutFilter);
+
+  return S_OK;
+}
+
+HRESULT
+AddMP3DMOWrapperFilter(IGraphBuilder* aGraph,
+                       IBaseFilter **aOutFilter)
+{
+  NS_ENSURE_TRUE(aGraph, E_POINTER);
+  NS_ENSURE_TRUE(aOutFilter, E_POINTER);
+  HRESULT hr;
+
+  // Create the wrapper filter.
+  nsRefPtr<IBaseFilter> filter;
+  hr = CreateMP3DMOWrapperFilter(getter_AddRefs(filter));
+  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
+
   // Add the wrapper filter to graph.
   hr = aGraph->AddFilter(filter, L"MP3 Decoder DMO");
   if (FAILED(hr)) {
     WARN("AddFilter failed, hr=%x", hr);
     return hr;
   }
 
   filter.forget(aOutFilter);
 
   return S_OK;
 }
 
+bool
+CanDecodeMP3UsingDirectShow()
+{
+  nsRefPtr<IBaseFilter> filter;
+
+  // Can we create the MP3 demuxer filter?
+  if (FAILED(CoCreateInstance(CLSID_MPEG1Splitter,
+                              nullptr,
+                              CLSCTX_INPROC_SERVER,
+                              IID_IBaseFilter,
+                              getter_AddRefs(filter)))) {
+    return false;
+  }
+
+  // Can we create either the WinXP MP3 decoder filter or the MP3 DMO decoder?
+  if (FAILED(CoCreateInstance(CLSID_MPEG_LAYER_3_DECODER_FILTER,
+                              nullptr,
+                              CLSCTX_INPROC_SERVER,
+                              IID_IBaseFilter,
+                              getter_AddRefs(filter))) &&
+      FAILED(CreateMP3DMOWrapperFilter(getter_AddRefs(filter)))) {
+    return false;
+  }
+
+  // Else, we can create all of the components we need. Assume
+  // DirectShow is going to work...
+  return true;
+}
+
 // Match a pin by pin direction and connection state.
 HRESULT
 MatchUnconnectedPin(IPin* aPin,
                     PIN_DIRECTION aPinDir,
                     bool *aOutMatches)
 {
   NS_ENSURE_TRUE(aPin, E_POINTER);
   NS_ENSURE_TRUE(aOutMatches, E_POINTER);
--- a/dom/media/directshow/DirectShowUtils.h
+++ b/dom/media/directshow/DirectShowUtils.h
@@ -110,11 +110,16 @@ inline double
 RefTimeToSeconds(const REFERENCE_TIME aRefTime)
 {
   return double(aRefTime) / 10000000;
 }
 
 const char*
 GetDirectShowGuidName(const GUID& aGuid);
 
+// Returns true if we can instantiate an MP3 demuxer and decoder filters.
+// Use this to detect whether MP3 support is installed.
+bool
+CanDecodeMP3UsingDirectShow();
+
 } // namespace mozilla
 
 #endif