nsresult WMFReader::Init(MediaDecoderReader* aCloneDonor) { NS_ASSERTION(NS_IsMainThread(), "Must be on main thread."); nsresult rv = WMFDecoder::LoadDLLs(); NS_ENSURE_SUCCESS(rv, rv); if (FAILED(wmf::MFStartup())) { NS_WARNING("Failed to initialize Windows Media Foundation"); return NS_ERROR_FAILURE; } mSourceReaderCallback = new WMFSourceReaderCallback(); // Must be created on main thread. mByteStream = new WMFByteStream(mDecoder->GetResource(), mSourceReaderCallback); rv = mByteStream->Init(); NS_ENSURE_SUCCESS(rv, rv); if (mDecoder->GetImageContainer() != nullptr && IsVideoContentType(mDecoder->GetResource()->GetContentType())) { mUseHwAccel = InitializeDXVA(); } else { mUseHwAccel = false; } return NS_OK; }
bool WMFVideoMFTManager::InitInternal(bool aForceD3D9) { mUseHwAccel = false; // default value; changed if D3D setup succeeds. bool useDxva = InitializeDXVA(aForceD3D9); RefPtr<MFTDecoder> decoder(new MFTDecoder()); HRESULT hr = decoder->Create(GetMFTGUID()); NS_ENSURE_TRUE(SUCCEEDED(hr), false); RefPtr<IMFAttributes> attr(decoder->GetAttributes()); UINT32 aware = 0; if (attr) { attr->GetUINT32(MF_SA_D3D_AWARE, &aware); attr->SetUINT32(CODECAPI_AVDecNumWorkerThreads, WMFDecoderModule::GetNumDecoderThreads()); if (WMFDecoderModule::LowLatencyMFTEnabled()) { hr = attr->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE); if (SUCCEEDED(hr)) { LOG("Enabling Low Latency Mode"); } else { LOG("Couldn't enable Low Latency Mode"); } } } if (useDxva) { if (aware) { // TODO: Test if I need this anywhere... Maybe on Vista? //hr = attr->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE); //NS_ENSURE_TRUE(SUCCEEDED(hr), hr); MOZ_ASSERT(mDXVA2Manager); ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager()); hr = decoder->SendMFTMessage(MFT_MESSAGE_SET_D3D_MANAGER, manager); if (SUCCEEDED(hr)) { mUseHwAccel = true; } else { mDXVA2Manager = nullptr; mDXVAFailureReason = nsPrintfCString("MFT_MESSAGE_SET_D3D_MANAGER failed with code %X", hr); } } else { mDXVAFailureReason.AssignLiteral("Decoder returned false for MF_SA_D3D_AWARE"); } } if (!mUseHwAccel) { Telemetry::Accumulate(Telemetry::MEDIA_DECODER_BACKEND_USED, uint32_t(media::MediaDecoderBackend::WMFSoftware)); } mDecoder = decoder; hr = SetDecoderMediaTypes(); NS_ENSURE_TRUE(SUCCEEDED(hr), false); LOG("Video Decoder initialized, Using DXVA: %s", (mUseHwAccel ? "Yes" : "No")); return true; }
nsresult WMFVideoDecoder::Init(mozilla::layers::LayersBackend aLayersBackend, mozilla::layers::ImageContainer* aImageContainer) { NS_ENSURE_ARG_POINTER(aImageContainer); bool useDxva= InitializeDXVA(aLayersBackend); mDecoder = new MFTDecoder(); HRESULT hr = mDecoder->Create(CLSID_CMSH264DecoderMFT); NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); if (useDxva) { RefPtr<IMFAttributes> attr(mDecoder->GetAttributes()); UINT32 aware = 0; if (attr) { attr->GetUINT32(MF_SA_D3D_AWARE, &aware); } if (aware) { // TODO: Test if I need this anywhere... Maybe on Vista? //hr = attr->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE); //NS_ENSURE_TRUE(SUCCEEDED(hr), hr); MOZ_ASSERT(mDXVA2Manager); ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager()); hr = mDecoder->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)); NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); hr = type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); hr = type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); hr = type->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_MixedInterlaceOrProgressive); NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); GUID outputType = mUseHwAccel ? MFVideoFormat_NV12 : MFVideoFormat_YV12; hr = mDecoder->SetMediaTypes(type, outputType); NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); mImageContainer = aImageContainer; LOG("Video Decoder initialized, Using DXVA: %s", (mUseHwAccel ? "Yes" : "No")); return NS_OK; }
TemporaryRef<MFTDecoder> WMFVideoOutputSource::Init() { bool useDxva = InitializeDXVA(); RefPtr<MFTDecoder> decoder(new MFTDecoder()); HRESULT hr = decoder->Create(CLSID_CMSH264DecoderMFT); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); if (useDxva) { RefPtr<IMFAttributes> attr(decoder->GetAttributes()); UINT32 aware = 0; if (attr) { attr->GetUINT32(MF_SA_D3D_AWARE, &aware); } if (aware) { // TODO: Test if I need this anywhere... Maybe on Vista? //hr = attr->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE); //NS_ENSURE_TRUE(SUCCEEDED(hr), hr); MOZ_ASSERT(mDXVA2Manager); ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager()); 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)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); hr = type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); hr = type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); hr = type->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_MixedInterlaceOrProgressive); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); GUID outputType = mUseHwAccel ? MFVideoFormat_NV12 : MFVideoFormat_YV12; hr = decoder->SetMediaTypes(type, outputType); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); mDecoder = decoder; LOG("Video Decoder initialized, Using DXVA: %s", (mUseHwAccel ? "Yes" : "No")); return decoder.forget(); }
already_AddRefed<MFTDecoder> WMFVideoMFTManager::InitInternal(bool aForceD3D9) { mUseHwAccel = false; // default value; changed if D3D setup succeeds. bool useDxva = InitializeDXVA(aForceD3D9); RefPtr<MFTDecoder> decoder(new MFTDecoder()); HRESULT hr = decoder->Create(GetMFTGUID()); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr<IMFAttributes> attr(decoder->GetAttributes()); UINT32 aware = 0; if (attr) { attr->GetUINT32(MF_SA_D3D_AWARE, &aware); attr->SetUINT32(CODECAPI_AVDecNumWorkerThreads, WMFDecoderModule::GetNumDecoderThreads()); } if (useDxva) { if (aware) { // TODO: Test if I need this anywhere... Maybe on Vista? //hr = attr->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE); //NS_ENSURE_TRUE(SUCCEEDED(hr), hr); MOZ_ASSERT(mDXVA2Manager); ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager()); hr = decoder->SendMFTMessage(MFT_MESSAGE_SET_D3D_MANAGER, manager); if (SUCCEEDED(hr)) { mUseHwAccel = true; } } } // Setup the input/output media types. RefPtr<IMFMediaType> inputType; hr = wmf::MFCreateMediaType(byRef(inputType)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); 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); RefPtr<IMFMediaType> outputType; hr = wmf::MFCreateMediaType(byRef(outputType)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); hr = outputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); 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")); // Just in case ConfigureVideoFrameGeometry() does not set these mVideoInfo = VideoInfo(); mVideoStride = 0; mVideoWidth = 0; mVideoHeight = 0; mPictureRegion.SetEmpty(); return decoder.forget(); }
bool WMFVideoMFTManager::InitInternal(bool aForceD3D9) { mUseHwAccel = false; // default value; changed if D3D setup succeeds. bool useDxva = InitializeDXVA(aForceD3D9); RefPtr<MFTDecoder> decoder(new MFTDecoder()); HRESULT hr = decoder->Create(GetMFTGUID()); NS_ENSURE_TRUE(SUCCEEDED(hr), false); RefPtr<IMFAttributes> attr(decoder->GetAttributes()); UINT32 aware = 0; if (attr) { attr->GetUINT32(MF_SA_D3D_AWARE, &aware); attr->SetUINT32(CODECAPI_AVDecNumWorkerThreads, WMFDecoderModule::GetNumDecoderThreads()); hr = attr->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE); if (SUCCEEDED(hr)) { LOG("Enabling Low Latency Mode"); } else { LOG("Couldn't enable Low Latency Mode"); } } if (useDxva) { if (aware) { // TODO: Test if I need this anywhere... Maybe on Vista? //hr = attr->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE); //NS_ENSURE_TRUE(SUCCEEDED(hr), hr); MOZ_ASSERT(mDXVA2Manager); ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager()); hr = decoder->SendMFTMessage(MFT_MESSAGE_SET_D3D_MANAGER, manager); if (SUCCEEDED(hr)) { mUseHwAccel = true; } else { mDXVA2Manager = nullptr; mDXVAFailureReason = nsPrintfCString("MFT_MESSAGE_SET_D3D_MANAGER failed with code %X", hr); } } else { mDXVAFailureReason.AssignLiteral("Decoder returned false for MF_SA_D3D_AWARE"); } } mDecoder = decoder; hr = SetDecoderMediaTypes(); NS_ENSURE_TRUE(SUCCEEDED(hr), false); LOG("Video Decoder initialized, Using DXVA: %s", (mUseHwAccel ? "Yes" : "No")); // Just in case ConfigureVideoFrameGeometry() does not set these mVideoInfo = VideoInfo(); mVideoStride = 0; mVideoWidth = 0; mVideoHeight = 0; mPictureRegion.SetEmpty(); return true; }