Bug 1123269: Better fix for bug 1121876 r=cpearce a=sledru
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 20 Jan 2015 10:45:07 +1100
changeset 242985 56b7a3953db2
parent 242984 677c75e4d519
child 242986 a48f8c55a98c
push id4354
push userrgiles@mozilla.com
push date2015-01-22 18:52 +0000
treeherdermozilla-beta@a48f8c55a98c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce, sledru
bugs1123269, 1121876
milestone36.0
Bug 1123269: Better fix for bug 1121876 r=cpearce a=sledru
dom/media/fmp4/wmf/MFTDecoder.cpp
dom/media/fmp4/wmf/MFTDecoder.h
dom/media/fmp4/wmf/WMFAudioMFTManager.cpp
dom/media/fmp4/wmf/WMFVideoMFTManager.cpp
--- a/dom/media/fmp4/wmf/MFTDecoder.cpp
+++ b/dom/media/fmp4/wmf/MFTDecoder.cpp
@@ -43,19 +43,19 @@ MFTDecoder::Create(const GUID& aMFTClsID
                         reinterpret_cast<void**>(static_cast<IMFTransform**>(byRef(mDecoder))));
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   return S_OK;
 }
 
 HRESULT
 MFTDecoder::SetMediaTypes(IMFMediaType* aInputType,
-                          const GUID& aOutputSubType)
+                          IMFMediaType* aOutputType)
 {
-  mOutputSubtype = aOutputSubType;
+  mOutputType = aOutputType;
 
   // Set the input type to the one the caller gave us...
   HRESULT hr = mDecoder->SetInputType(0, aInputType, 0);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   hr = SetDecoderOutputType();
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
@@ -91,31 +91,24 @@ MFTDecoder::SetDecoderOutputType()
   NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
 
   // Iterate the enumerate the output types, until we find one compatible
   // with what we need.
   HRESULT hr;
   RefPtr<IMFMediaType> outputType;
   UINT32 typeIndex = 0;
   while (SUCCEEDED(mDecoder->GetOutputAvailableType(0, typeIndex++, byRef(outputType)))) {
-    GUID subtype;
-    hr = outputType->GetGUID(MF_MT_SUBTYPE, &subtype);
-    if (FAILED(hr)) {
-      continue;
-    }
-    if (subtype == mOutputSubtype) {
-      if (subtype == MFAudioFormat_PCM) {
-        // Set output to PCM 16 bits, we can ignore errors.
-        outputType->SetUINT32(MF_MT_SAMPLE_SIZE, 2);
-        outputType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16);
-      }
+    BOOL resultMatch;
+    hr = mOutputType->Compare(outputType, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &resultMatch);
+    if (SUCCEEDED(hr) && resultMatch == TRUE) {
       hr = mDecoder->SetOutputType(0, outputType, 0);
       NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
       return S_OK;
     }
+    outputType = nullptr;
   }
   return E_FAIL;
 }
 
 HRESULT
 MFTDecoder::SendMFTMessage(MFT_MESSAGE_TYPE aMsg, ULONG_PTR aData)
 {
   NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
--- a/dom/media/fmp4/wmf/MFTDecoder.h
+++ b/dom/media/fmp4/wmf/MFTDecoder.h
@@ -28,21 +28,21 @@ public:
   //  - aMFTClsID the clsid used by CoCreateInstance to instantiate the
   //    decoder MFT.
   HRESULT Create(const GUID& aMFTClsID);
 
   // Sets the input and output media types. Call after Init().
   //
   // Params:
   //  - aInputType needs at least major and minor types set.
-  //  - aOutputSubType is the minor type of the same major type e.g.
-  //    MFVideoFormat_H264. This is used to select the output type out
+  //  - aOutputType needs at least major and minor types set.
+  //    This is used to select the matching output type out
   //    of all the available output types of the MFT.
   HRESULT SetMediaTypes(IMFMediaType* aInputType,
-                        const GUID& aOutputSubType);
+                        IMFMediaType* aOutputType);
 
   // Returns the MFT's IMFAttributes object.
   TemporaryRef<IMFAttributes> GetAttributes();
 
   // Retrieves the media type being output. This may not be valid until
   //  the first sample is decoded.
   HRESULT GetOutputMediaType(RefPtr<IMFMediaType>& aMediaType);
 
@@ -87,17 +87,17 @@ private:
 
   HRESULT CreateOutputSample(RefPtr<IMFSample>* aOutSample);
 
   MFT_INPUT_STREAM_INFO mInputStreamInfo;
   MFT_OUTPUT_STREAM_INFO mOutputStreamInfo;
 
   RefPtr<IMFTransform> mDecoder;
 
-  GUID mOutputSubtype;
+  RefPtr<IMFMediaType> mOutputType;
 
   // True if the IMFTransform allocates the samples that it returns.
   bool mMFTProvidesOutputSamples;
 
   // True if we need to mark the next sample as a discontinuity.
   bool mDiscontinuity;
 };
 
--- a/dom/media/fmp4/wmf/WMFAudioMFTManager.cpp
+++ b/dom/media/fmp4/wmf/WMFAudioMFTManager.cpp
@@ -123,44 +123,57 @@ WMFAudioMFTManager::Init()
   NS_ENSURE_TRUE(mStreamType != Unknown, nullptr);
 
   RefPtr<MFTDecoder> decoder(new MFTDecoder());
 
   HRESULT hr = decoder->Create(GetMFTGUID());
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
   // Setup input/output media types
-  RefPtr<IMFMediaType> type;
+  RefPtr<IMFMediaType> inputType;
 
-  hr = wmf::MFCreateMediaType(byRef(type));
+  hr = wmf::MFCreateMediaType(byRef(inputType));
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
-  hr = type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
+  hr = inputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
-  hr = type->SetGUID(MF_MT_SUBTYPE, GetMediaSubtypeGUID());
+  hr = inputType->SetGUID(MF_MT_SUBTYPE, GetMediaSubtypeGUID());
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
-  hr = type->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, mAudioRate);
+  hr = inputType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, mAudioRate);
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
-  hr = type->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, mAudioChannels);
+  hr = inputType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, mAudioChannels);
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
   if (mStreamType == AAC) {
-    hr = type->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 0x0); // Raw AAC packet
+    hr = inputType->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 0x0); // Raw AAC packet
     NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
-    hr = type->SetBlob(MF_MT_USER_DATA,
-                       mUserData.Elements(),
-                       mUserData.Length());
+    hr = inputType->SetBlob(MF_MT_USER_DATA,
+                            mUserData.Elements(),
+                            mUserData.Length());
     NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
   }
 
-  hr = decoder->SetMediaTypes(type, MFAudioFormat_PCM);
+  RefPtr<IMFMediaType> outputType;
+  hr = wmf::MFCreateMediaType(byRef(outputType));
+  NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
+
+  hr = outputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
+  NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
+
+  hr = outputType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
+  NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
+
+  hr = outputType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16);
+  NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
+
+  hr = decoder->SetMediaTypes(inputType, outputType);
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
   mDecoder = decoder;
 
   return decoder.forget();
 }
 
 HRESULT
--- a/dom/media/fmp4/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/fmp4/wmf/WMFVideoMFTManager.cpp
@@ -183,31 +183,41 @@ WMFVideoMFTManager::Init()
       hr = decoder->SendMFTMessage(MFT_MESSAGE_SET_D3D_MANAGER, manager);
       if (SUCCEEDED(hr)) {
         mUseHwAccel = true;
       }
     }
   }
 
   // Setup the input/output media types.
-  RefPtr<IMFMediaType> type;
-  hr = wmf::MFCreateMediaType(byRef(type));
+  RefPtr<IMFMediaType> inputType;
+  hr = wmf::MFCreateMediaType(byRef(inputType));
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
-  hr = type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
+  hr = inputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
+  NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
+
+  hr = inputType->SetGUID(MF_MT_SUBTYPE, GetMediaSubtypeGUID());
+  NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
+
+  hr = inputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_MixedInterlaceOrProgressive);
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
-  hr = type->SetGUID(MF_MT_SUBTYPE, GetMediaSubtypeGUID());
+  RefPtr<IMFMediaType> outputType;
+  hr = wmf::MFCreateMediaType(byRef(outputType));
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
-  hr = type->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_MixedInterlaceOrProgressive);
+  hr = outputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
-  GUID outputType = mUseHwAccel ? MFVideoFormat_NV12 : MFVideoFormat_YV12;
-  hr = decoder->SetMediaTypes(type, outputType);
+  GUID outputSubType = mUseHwAccel ? MFVideoFormat_NV12 : MFVideoFormat_YV12;
+  hr = outputType->SetGUID(MF_MT_SUBTYPE, outputSubType);
+  NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
+
+  hr = decoder->SetMediaTypes(inputType, outputType);
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
   mDecoder = decoder;
   LOG("Video Decoder initialized, Using DXVA: %s", (mUseHwAccel ? "Yes" : "No"));
 
   return decoder.forget();
 }