void MFPlayer::init(const OTextureRef& pRenderTarget) { m_pRenderTarget = pRenderTarget; auto pRendererD3D11 = std::dynamic_pointer_cast<ORendererD3D11>(oRenderer); HRESULT ret; // Initialize M$ bullshit //ret = CoInitializeEx(NULL, COINIT_MULTITHREADED); //assert(ret == S_OK); ret = MFStartup(MF_VERSION); assert(ret == S_OK); // Create factory IMFMediaEngineClassFactory *pMediaEngineClassFactory = nullptr; ret = CoCreateInstance(CLSID_MFMediaEngineClassFactory, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&pMediaEngineClassFactory)); assert(ret == S_OK); // Create notify m_pPlayerNodify = new MFPlayerNotify(shared_from_this()); // Create attributes IMFAttributes *pAttributes = nullptr; ret = MFCreateAttributes(&pAttributes, 1); assert(ret == S_OK); ret = pAttributes->SetUnknown(MF_MEDIA_ENGINE_CALLBACK, m_pPlayerNodify); assert(ret == S_OK); ID3D10Multithread *pMultithread = nullptr; ID3D11Device *pDevice = pRendererD3D11->getDevice(); ret = pDevice->QueryInterface(IID_PPV_ARGS(&pMultithread)); assert(ret == S_OK); pMultithread->SetMultithreadProtected(TRUE); pMultithread->Release(); UINT resetToken = 0; ret = MFCreateDXGIDeviceManager(&resetToken, &m_pDXGIManager); assert(ret == S_OK); ret = m_pDXGIManager->ResetDevice(pRendererD3D11->getDevice(), resetToken); assert(ret == S_OK); ret = pAttributes->SetUnknown(MF_MEDIA_ENGINE_DXGI_MANAGER, m_pDXGIManager); assert(ret == S_OK); ret = pAttributes->SetUINT32(MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, DXGI_FORMAT_R8G8B8A8_UNORM); assert(ret == S_OK); // Create player ret = pMediaEngineClassFactory->CreateInstance(MF_MEDIA_ENGINE_WAITFORSTABLE_STATE, pAttributes, &m_pMediaEngine); assert(ret == S_OK); // Release bullshits pAttributes->Release(); pMediaEngineClassFactory->Release(); }
HRESULT CCapture::OpenMediaSource(IMFMediaSource *pSource) { HRESULT hr = S_OK; IMFAttributes *pAttributes = NULL; hr = MFCreateAttributes(&pAttributes, 2); if (SUCCEEDED(hr)) { hr = pAttributes->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, this); } if (SUCCEEDED(hr)) { hr = MFCreateSourceReaderFromMediaSource( pSource, pAttributes, &m_pReader ); } SafeRelease(&pAttributes); return hr; }
void MFPlayer::init(HWND handle) { HRESULT ret; // Initialize M$ bullshit //ret = CoInitializeEx(NULL, COINIT_MULTITHREADED); //assert(ret == S_OK); ret = MFStartup(MF_VERSION); assert(ret == S_OK); // Create factory IMFMediaEngineClassFactory *pMediaEngineClassFactory = nullptr; ret = CoCreateInstance(CLSID_MFMediaEngineClassFactory, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&pMediaEngineClassFactory)); assert(ret == S_OK); // Create notify m_pPlayerNodify = new MFPlayerNotify(shared_from_this()); // Create attributes IMFAttributes *pAttributes = nullptr; ret = MFCreateAttributes(&pAttributes, 1); assert(ret == S_OK); ret = pAttributes->SetUnknown(MF_MEDIA_ENGINE_CALLBACK, m_pPlayerNodify); assert(ret == S_OK); ret = pAttributes->SetUINT64(MF_MEDIA_ENGINE_PLAYBACK_HWND, reinterpret_cast<UINT64>(handle)); assert(ret == S_OK); // Create player ret = pMediaEngineClassFactory->CreateInstance(0, pAttributes, &m_pMediaEngine); assert(ret == S_OK); // Release bullshits pAttributes->Release(); pMediaEngineClassFactory->Release(); }
bool VideoCapture::CreateSourceReaderAsync() { HRESULT hr; HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (hEvent == NULL) { MFUtil::ShowMessage(TEXT("CreateEvent Failed."), ML_ERROR); return false; } this->CallBack = new SourceReaderCallBack(hEvent); if (this->CallBack == NULL) { MFUtil::ShowMessage(TEXT("CreateCallBack Failed."), ML_ERROR); return false; } IMFAttributes *pAttributes = NULL; hr = MFCreateAttributes(&pAttributes, 1); if (hr != S_OK) { MFUtil::ShowMessage(TEXT("CreateAttributes Failed."), ML_ERROR); this->ReleaseDevices(); return false; } hr = pAttributes->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, this->CallBack); if (hr != S_OK) { MFUtil::ShowMessage(TEXT("AttributeSetting Failed."), ML_ERROR); this->ReleaseDevices(); return false; } pin_ptr<IMFSourceReader *> pSourceReader = &(this->SourceReader); hr = MFCreateSourceReaderFromMediaSource(this->Source, pAttributes, pSourceReader); if (hr != S_OK) { MFUtil::ShowMessage(TEXT("CreateSourceReader Failed."), ML_ERROR); this->ReleaseDevices(); return false; } hr = this->ConfigureSourceReader(); if (hr != S_OK) { MFUtil::ShowMessage(TEXT("ConfigureDecoder Failed."), ML_ERROR); MFUtil::ShowErrorNameFromCode(hr); return false; } // 二回目以降の ReadSample() はコールバック内で呼ぶため、 // SourceReaderCallBack クラスにも SourceReader が必要。 this->CallBack->SourceReader = this->SourceReader; return true; }
IMFMediaType* MFDecoderSourceReader::setSource(IMFMediaSource *source, const QAudioFormat &audioFormat) { IMFMediaType *mediaType = NULL; if (m_source == source) return mediaType; if (m_source) { m_source->Release(); m_source = NULL; } if (m_sourceReader) { m_sourceReader->Release(); m_sourceReader = NULL; } if (!source) return mediaType; IMFAttributes *attr = NULL; MFCreateAttributes(&attr, 1); if (SUCCEEDED(attr->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, this))) { if (SUCCEEDED(MFCreateSourceReaderFromMediaSource(source, attr, &m_sourceReader))) { m_source = source; m_source->AddRef(); m_sourceReader->SetStreamSelection(DWORD(MF_SOURCE_READER_ALL_STREAMS), FALSE); m_sourceReader->SetStreamSelection(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), TRUE); IMFMediaType *pPartialType = NULL; MFCreateMediaType(&pPartialType); pPartialType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio); if (audioFormat.sampleType() == QAudioFormat::Float) { pPartialType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_Float); } else { pPartialType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM); } m_sourceReader->SetCurrentMediaType(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), NULL, pPartialType); pPartialType->Release(); m_sourceReader->GetCurrentMediaType(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), &mediaType); // Ensure the stream is selected. m_sourceReader->SetStreamSelection(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), TRUE); } attr->Release(); } return mediaType; }
HRESULT CaptureClass::initCapture(int aDevice) { mWhoAmI = aDevice; HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); DO_OR_DIE; hr = MFStartup(MF_VERSION); DO_OR_DIE; // choose device IMFAttributes *attributes = NULL; hr = MFCreateAttributes(&attributes, 1); ScopedRelease<IMFAttributes> attributes_s(attributes); DO_OR_DIE; hr = attributes->SetGUID( MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID ); DO_OR_DIE; ChooseDeviceParam param = { 0 }; hr = MFEnumDeviceSources(attributes, ¶m.mDevices, ¶m.mCount); DO_OR_DIE; if ((signed)param.mCount > aDevice) { // use param.ppDevices[0] IMFAttributes *attributes = NULL; IMFMediaType *type = NULL; EnterCriticalSection(&mCritsec); hr = param.mDevices[aDevice]->ActivateObject( __uuidof(IMFMediaSource), (void**)&mSource ); DO_OR_DIE_CRITSECTION; hr = MFCreateAttributes(&attributes, 3); ScopedRelease<IMFAttributes> attributes_s(attributes); DO_OR_DIE_CRITSECTION; hr = attributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, TRUE); DO_OR_DIE_CRITSECTION; hr = attributes->SetUnknown( MF_SOURCE_READER_ASYNC_CALLBACK, this ); DO_OR_DIE_CRITSECTION; hr = MFCreateSourceReaderFromMediaSource( mSource, attributes, &mReader ); DO_OR_DIE_CRITSECTION; int preferredmode = scanMediaTypes(gParams[mWhoAmI].mWidth, gParams[mWhoAmI].mHeight); mUsedIndex = preferredmode; hr = mReader->GetNativeMediaType( (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, preferredmode, &type ); ScopedRelease<IMFMediaType> type_s(type); DO_OR_DIE_CRITSECTION; hr = setVideoType(type); DO_OR_DIE_CRITSECTION; hr = mReader->SetCurrentMediaType( (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, type ); DO_OR_DIE_CRITSECTION; hr = mReader->ReadSample( (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, NULL, NULL, NULL ); DO_OR_DIE_CRITSECTION; LeaveCriticalSection(&mCritsec); } else { return MF_E_INVALIDINDEX; } /* for (i = 0; i < 16; i++) { char temp[128]; float v; int f; int r = GetProperty(i, v, f); sprintf(temp, "%d: %3.3f %d (%d)\n", i, v, f, r); OutputDebugStringA(temp); } */ return 0; }
HRESULT CaptureManager::InitializeCaptureManager(HWND hwndPreview, IUnknown* pUnk) { HRESULT hr = S_OK; IMFAttributes* pAttributes = NULL; IMFCaptureEngineClassFactory* pFactory = NULL; DestroyCaptureEngine(); m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (NULL == m_hEvent) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; } m_pCallback = new (std::nothrow) CaptureEngineCB(m_hwndEvent); if (m_pCallback == NULL) { hr = E_OUTOFMEMORY; goto Exit; } m_pCallback->m_pManager = this; m_hwndPreview = hwndPreview; //Create a D3D Manager hr = CreateD3DManager(); if (FAILED(hr)) { goto Exit; } hr = MFCreateAttributes(&pAttributes, 1); if (FAILED(hr)) { goto Exit; } hr = pAttributes->SetUnknown(MF_CAPTURE_ENGINE_D3D_MANAGER, g_pDXGIMan); if (FAILED(hr)) { goto Exit; } // Create the factory object for the capture engine. hr = CoCreateInstance(CLSID_MFCaptureEngineClassFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pFactory)); if (FAILED(hr)) { goto Exit; } // Create and initialize the capture engine. hr = pFactory->CreateInstance(CLSID_MFCaptureEngine, IID_PPV_ARGS(&m_pEngine)); if (FAILED(hr)) { goto Exit; } hr = m_pEngine->Initialize(m_pCallback, pAttributes, NULL, pUnk); if (FAILED(hr)) { goto Exit; } Exit: if (NULL != pAttributes) { pAttributes->Release(); pAttributes = NULL; } if (NULL != pFactory) { pFactory->Release(); pFactory = NULL; } return hr; }
HRESULT CPlayer::CreateSession() { TRACE((L"CPlayer::CreateSession\n")); HRESULT hr = S_OK; IMFAttributes *pAttributes = NULL; IMFActivate *pEnablerActivate = NULL; // Close the old session, if any. CHECK_HR(hr = CloseSession()); assert(m_state == Closed); // Create a new attribute store. CHECK_HR(hr = MFCreateAttributes(&pAttributes, 1)); // Create the content protection manager. assert(m_pContentProtectionManager == NULL); // Was released in CloseSession CHECK_HR(hr = ContentProtectionManager::CreateInstance( m_hwndEvent, &m_pContentProtectionManager )); // Set the MF_SESSION_CONTENT_PROTECTION_MANAGER attribute with a pointer // to the content protection manager. CHECK_HR(hr = pAttributes->SetUnknown( MF_SESSION_CONTENT_PROTECTION_MANAGER, (IMFContentProtectionManager*)m_pContentProtectionManager )); // Create the PMP media session. CHECK_HR(hr = MFCreatePMPMediaSession( 0, // Can use this flag: MFPMPSESSION_UNPROTECTED_PROCESS pAttributes, &m_pSession, &pEnablerActivate )); // TODO: // If MFCreatePMPMediaSession fails it might return an IMFActivate pointer. // This indicates that a trusted binary failed to load in the protected process. // An application can use the IMFActivate pointer to create an enabler object, which // provides revocation and renewal information for the component that failed to // load. // This sample does not demonstrate that feature. Instead, we simply treat this // case as a playback failure. // Start pulling events from the media session CHECK_HR(hr = m_pSession->BeginGetEvent((IMFAsyncCallback*)this, NULL)); done: SAFE_RELEASE(pAttributes); SAFE_RELEASE(pEnablerActivate); return hr; }
HRESULT CPreview::SetDevice(IMFActivate *pActivate) { HRESULT hr = S_OK; IMFMediaSource *pSource = NULL; IMFAttributes *pAttributes = NULL; IMFMediaType *pType = NULL; EnterCriticalSection(&m_critsec); // Release the current device, if any. hr = CloseDevice(); // Create the media source for the device. if (SUCCEEDED(hr)) { hr = pActivate->ActivateObject( __uuidof(IMFMediaSource), (void**)&pSource ); } // Get the symbolic link. if (SUCCEEDED(hr)) { hr = pActivate->GetAllocatedString( MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &m_pwszSymbolicLink, &m_cchSymbolicLink ); } // // Create the source reader. // // Create an attribute store to hold initialization settings. if (SUCCEEDED(hr)) { hr = MFCreateAttributes(&pAttributes, 2); } if (SUCCEEDED(hr)) { hr = pAttributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, TRUE); } // Set the callback pointer. if (SUCCEEDED(hr)) { hr = pAttributes->SetUnknown( MF_SOURCE_READER_ASYNC_CALLBACK, this ); } if (SUCCEEDED(hr)) { hr = MFCreateSourceReaderFromMediaSource( pSource, pAttributes, &m_pReader ); } // Try to find a suitable output type. if (SUCCEEDED(hr)) { for (DWORD i = 0; ; i++) { hr = m_pReader->GetNativeMediaType( (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, i, &pType ); if (FAILED(hr)) { break; } hr = TryMediaType(pType); SafeRelease(&pType); if (SUCCEEDED(hr)) { // Found an output type. break; } } } if (SUCCEEDED(hr)) { // Ask for the first sample. hr = m_pReader->ReadSample( (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, NULL, NULL, NULL ); } if (FAILED(hr)) { if (pSource) { pSource->Shutdown(); // NOTE: The source reader shuts down the media source // by default, but we might not have gotten that far. } CloseDevice(); } SafeRelease(&pSource); SafeRelease(&pAttributes); SafeRelease(&pType); LeaveCriticalSection(&m_critsec); return hr; }
bool WinCaptureDevice::InitializeFirst(std::string& error) { HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (!SUCCEEDED(hr)) { return false; error = "CoInitializeEx failed"; } hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); if (!SUCCEEDED(hr)) { error = "MFStartup failed"; return false; } Close(); memset(&InputType, 0, sizeof(InputType)); IMFActivate* activate = WinCaptureDevice::ChooseFirst(error); if (!activate) return false; IMFMediaSource *pSource = NULL; IMFAttributes *pAttributes = NULL; IMFMediaType *pType = NULL; UINT32 m_cchSymbolicLink = 0; // Create the media source for the device. if (SUCCEEDED(hr)) hr = activate->ActivateObject(__uuidof(IMFMediaSource), (void**) &pSource); // Get the symbolic link. if (SUCCEEDED(hr)) hr = activate->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &SymbolicLink, &m_cchSymbolicLink); // // Create the source reader. // // Create an attribute store to hold initialization settings. if (SUCCEEDED(hr)) hr = MFCreateAttributes(&pAttributes, 2); if (SUCCEEDED(hr)) hr = pAttributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, TRUE); // Set the callback pointer. if (SUCCEEDED(hr)) hr = pAttributes->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, this); if (SUCCEEDED(hr)) hr = MFCreateSourceReaderFromMediaSource(pSource, pAttributes, &Reader); // Try to find a suitable input type. if (SUCCEEDED(hr)) { for (uint i = 0; ; i++) { hr = Reader->GetNativeMediaType((DWORD) MF_SOURCE_READER_FIRST_VIDEO_STREAM, i, &pType); if (FAILED(hr)) { error = "Failed to find a supported output format (ie RGB24)"; break; } memset(&InputType, 0, sizeof(InputType)); bool isTypeOK = IsMediaTypeSupported(pType, InputType); if (isTypeOK) { // Get the frame size. hr = MFGetAttributeSize(pType, MF_MT_FRAME_SIZE, &InputWidth, &InputHeight); // Get the image stride. hr = GetDefaultStride(pType, &InputDefaultStride); // Get the interlace mode. Default: assume progressive. InputInterlaceMode = (MFVideoInterlaceMode) MFGetAttributeUINT32(pType, MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); } SafeRelease(&pType); if (isTypeOK) break; } } if (SUCCEEDED(hr)) { // Ask for the first sample. EnableCapture = 1; hr = Reader->ReadSample((DWORD) MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, NULL, NULL, NULL); } if (FAILED(hr)) { if (pSource) { pSource->Shutdown(); // NOTE: The source reader shuts down the media source by default, but we might not have gotten that far. } Close(); } SafeRelease(&pSource); SafeRelease(&pAttributes); SafeRelease(&pType); SafeRelease(&activate); if (FAILED(hr) && error.length() == 0) error = ErrorMessage(L"Failed to initialize video capture device", hr); return SUCCEEDED(hr); }