summaryrefslogtreecommitdiffstats
path: root/plugins/pluginWinMF/internals
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pluginWinMF/internals')
-rwxr-xr-xplugins/pluginWinMF/internals/mf_codec.cxx1161
-rwxr-xr-xplugins/pluginWinMF/internals/mf_codec.h163
-rwxr-xr-xplugins/pluginWinMF/internals/mf_codec_topology.cxx619
-rwxr-xr-xplugins/pluginWinMF/internals/mf_codec_topology.h66
-rwxr-xr-xplugins/pluginWinMF/internals/mf_custom_src.cxx821
-rwxr-xr-xplugins/pluginWinMF/internals/mf_custom_src.h126
-rwxr-xr-xplugins/pluginWinMF/internals/mf_devices.cxx95
-rwxr-xr-xplugins/pluginWinMF/internals/mf_devices.h12
-rwxr-xr-xplugins/pluginWinMF/internals/mf_display_watcher.cxx181
-rwxr-xr-xplugins/pluginWinMF/internals/mf_display_watcher.h32
-rwxr-xr-xplugins/pluginWinMF/internals/mf_sample_grabber.cxx99
-rwxr-xr-xplugins/pluginWinMF/internals/mf_sample_grabber.h18
-rwxr-xr-xplugins/pluginWinMF/internals/mf_sample_queue.cxx75
-rwxr-xr-xplugins/pluginWinMF/internals/mf_sample_queue.h37
-rwxr-xr-xplugins/pluginWinMF/internals/mf_utils.cxx2792
-rwxr-xr-xplugins/pluginWinMF/internals/mf_utils.h383
16 files changed, 3121 insertions, 3559 deletions
diff --git a/plugins/pluginWinMF/internals/mf_codec.cxx b/plugins/pluginWinMF/internals/mf_codec.cxx
index e2968f4..27fb903 100755
--- a/plugins/pluginWinMF/internals/mf_codec.cxx
+++ b/plugins/pluginWinMF/internals/mf_codec.cxx
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -40,13 +40,13 @@
#endif
// Make sure usable on Win7 SDK targeting Win8 OS
-#if !defined(CODECAPI_AVLowLatencyMode)
+#if !defined(CODECAPI_AVLowLatencyMode)
DEFINE_GUID(CODECAPI_AVLowLatencyMode,
- 0x9c27891a, 0xed7a, 0x40e1, 0x88, 0xe8, 0xb2, 0x27, 0x27, 0xa0, 0x24, 0xee);
+ 0x9c27891a, 0xed7a, 0x40e1, 0x88, 0xe8, 0xb2, 0x27, 0x27, 0xa0, 0x24, 0xee);
#endif
#if !defined(CODECAPI_AVDecVideoH264ErrorConcealment)
DEFINE_GUID(CODECAPI_AVDecVideoH264ErrorConcealment,
-0xececace8, 0x3436, 0x462c, 0x92, 0x94, 0xcd, 0x7b, 0xac, 0xd7, 0x58, 0xa9);
+ 0xececace8, 0x3436, 0x462c, 0x92, 0x94, 0xcd, 0x7b, 0xac, 0xd7, 0x58, 0xa9);
#endif
//
@@ -54,117 +54,105 @@ DEFINE_GUID(CODECAPI_AVDecVideoH264ErrorConcealment,
//
MFCodec::MFCodec(MFCodecId_t eId, MFCodecType_t eType, IMFTransform *pMFT /*= NULL*/)
-: m_nRefCount(1)
-, m_eId(eId)
-, m_eType(eType)
-, m_pMFT(NULL)
-, m_pCodecAPI(NULL)
-, m_pOutputType(NULL)
-, m_pInputType(NULL)
-, m_dwInputID(0)
-, m_dwOutputID(0)
-, m_rtStart(0)
-, m_rtDuration(0)
-, m_pSampleIn(NULL)
-, m_pSampleOut(NULL)
-, m_pEventGenerator(NULL)
-, m_bIsAsync(FALSE)
-, m_bIsFirstFrame(TRUE)
-, m_bIsBundled(FALSE)
-, m_nMETransformNeedInputCount(0)
-, m_nMETransformHaveOutputCount(0)
-, m_pSampleQueueAsyncInput(NULL)
+ : m_nRefCount(1)
+ , m_eId(eId)
+ , m_eType(eType)
+ , m_pMFT(NULL)
+ , m_pCodecAPI(NULL)
+ , m_pOutputType(NULL)
+ , m_pInputType(NULL)
+ , m_dwInputID(0)
+ , m_dwOutputID(0)
+ , m_rtStart(0)
+ , m_rtDuration(0)
+ , m_pSampleIn(NULL)
+ , m_pSampleOut(NULL)
+ , m_pEventGenerator(NULL)
+ , m_bIsAsync(FALSE)
+ , m_bIsFirstFrame(TRUE)
+ , m_bIsBundled(FALSE)
+ , m_nMETransformNeedInputCount(0)
+ , m_nMETransformHaveOutputCount(0)
+ , m_pSampleQueueAsyncInput(NULL)
{
- MFUtils::Startup();
-
- HRESULT hr = S_OK;
-
- switch(eId)
- {
- case MFCodecId_H264Base:
- case MFCodecId_H264Main:
- {
- m_eMediaType = MFCodecMediaType_Video;
- m_guidCompressedFormat = MFVideoFormat_H264;
- break;
- }
- case MFCodecId_AAC:
- {
- m_eMediaType = MFCodecMediaType_Audio;
- m_guidCompressedFormat = MFAudioFormat_AAC;
- break;
- }
- default:
- {
- assert(false);
- break;
- }
- }
- CHECK_HR(hr = MFCreateMediaType(&m_pOutputType));
- CHECK_HR(hr = MFCreateMediaType(&m_pInputType));
- if(pMFT) // up to the caller to make sure all parameters are corrrect
- {
- m_pMFT = pMFT;
- m_pMFT->AddRef();
- }
- else
- {
- CHECK_HR(hr = MFUtils::GetBestCodec(
- (m_eType == MFCodecType_Encoder) ? TRUE : FALSE, // Encoder ?
- (m_eMediaType == MFCodecMediaType_Video) ? MFMediaType_Video : MFMediaType_Audio, // Media Type
- (m_eType == MFCodecType_Encoder) ? kMFCodecUncompressedFormat : m_guidCompressedFormat/*GUID_NULL*/, // Input
- (m_eType == MFCodecType_Encoder) ? m_guidCompressedFormat : kMFCodecUncompressedFormat, // Output
- &m_pMFT));
- }
- hr = m_pMFT->QueryInterface(IID_PPV_ARGS(&m_pCodecAPI));
- if(FAILED(hr) && m_eType == MFCodecType_Encoder) // Required only for Encoders
- {
- CHECK_HR(hr);
- }
-
-
- CHECK_HR(hr = MFUtils::IsAsyncMFT(m_pMFT, &m_bIsAsync));
- if(m_bIsAsync)
- {
- m_pSampleQueueAsyncInput = new MFSampleQueue();
- if(!m_pSampleQueueAsyncInput)
- {
- CHECK_HR(hr = E_OUTOFMEMORY);
- }
- CHECK_HR(hr = MFUtils::UnlockAsyncMFT(m_pMFT));
- CHECK_HR(hr = m_pMFT->QueryInterface(IID_PPV_ARGS(&m_pEventGenerator)));
- }
+ MFUtils::Startup();
+
+ HRESULT hr = S_OK;
+
+ switch(eId) {
+ case MFCodecId_H264Base:
+ case MFCodecId_H264Main: {
+ m_eMediaType = MFCodecMediaType_Video;
+ m_guidCompressedFormat = MFVideoFormat_H264;
+ break;
+ }
+ case MFCodecId_AAC: {
+ m_eMediaType = MFCodecMediaType_Audio;
+ m_guidCompressedFormat = MFAudioFormat_AAC;
+ break;
+ }
+ default: {
+ assert(false);
+ break;
+ }
+ }
+ CHECK_HR(hr = MFCreateMediaType(&m_pOutputType));
+ CHECK_HR(hr = MFCreateMediaType(&m_pInputType));
+ if(pMFT) { // up to the caller to make sure all parameters are corrrect
+ m_pMFT = pMFT;
+ m_pMFT->AddRef();
+ }
+ else {
+ CHECK_HR(hr = MFUtils::GetBestCodec(
+ (m_eType == MFCodecType_Encoder) ? TRUE : FALSE, // Encoder ?
+ (m_eMediaType == MFCodecMediaType_Video) ? MFMediaType_Video : MFMediaType_Audio, // Media Type
+ (m_eType == MFCodecType_Encoder) ? kMFCodecUncompressedFormat : m_guidCompressedFormat/*GUID_NULL*/, // Input
+ (m_eType == MFCodecType_Encoder) ? m_guidCompressedFormat : kMFCodecUncompressedFormat, // Output
+ &m_pMFT));
+ }
+ hr = m_pMFT->QueryInterface(IID_PPV_ARGS(&m_pCodecAPI));
+ if(FAILED(hr) && m_eType == MFCodecType_Encoder) { // Required only for Encoders
+ CHECK_HR(hr);
+ }
+
+
+ CHECK_HR(hr = MFUtils::IsAsyncMFT(m_pMFT, &m_bIsAsync));
+ if(m_bIsAsync) {
+ m_pSampleQueueAsyncInput = new MFSampleQueue();
+ if(!m_pSampleQueueAsyncInput) {
+ CHECK_HR(hr = E_OUTOFMEMORY);
+ }
+ CHECK_HR(hr = MFUtils::UnlockAsyncMFT(m_pMFT));
+ CHECK_HR(hr = m_pMFT->QueryInterface(IID_PPV_ARGS(&m_pEventGenerator)));
+ }
bail:
- if(FAILED(hr))
- {
- SafeRelease(&m_pMFT);
- SafeRelease(&m_pCodecAPI);
- }
- if(!IsValid())
- {
- TSK_DEBUG_ERROR("Failed to create codec with id = %d", m_eId);
- }
-}
+ if(FAILED(hr)) {
+ SafeRelease(&m_pMFT);
+ SafeRelease(&m_pCodecAPI);
+ }
+ if(!IsValid()) {
+ TSK_DEBUG_ERROR("Failed to create codec with id = %d", m_eId);
+ }
+}
MFCodec::~MFCodec()
{
- assert(m_nRefCount == 0);
+ assert(m_nRefCount == 0);
- if(m_bIsAsync && m_pMFT)
- {
- m_pMFT->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, NULL);
- m_pMFT->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, NULL);
- }
+ if(m_bIsAsync && m_pMFT) {
+ m_pMFT->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, NULL);
+ m_pMFT->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, NULL);
+ }
- SafeRelease(&m_pMFT);
- SafeRelease(&m_pCodecAPI);
+ SafeRelease(&m_pMFT);
+ SafeRelease(&m_pCodecAPI);
SafeRelease(&m_pOutputType);
- SafeRelease(&m_pInputType);
- SafeRelease(&m_pSampleIn);
- SafeRelease(&m_pSampleOut);
- SafeRelease(&m_pEventGenerator);
- SafeRelease(&m_pSampleQueueAsyncInput);
+ SafeRelease(&m_pInputType);
+ SafeRelease(&m_pSampleIn);
+ SafeRelease(&m_pSampleOut);
+ SafeRelease(&m_pEventGenerator);
+ SafeRelease(&m_pSampleQueueAsyncInput);
}
ULONG MFCodec::AddRef()
@@ -175,8 +163,7 @@ ULONG MFCodec::AddRef()
ULONG MFCodec::Release()
{
ULONG uCount = InterlockedDecrement(&m_nRefCount);
- if (uCount == 0)
- {
+ if (uCount == 0) {
delete this;
}
// For thread safety, return a temporary variable.
@@ -185,242 +172,210 @@ ULONG MFCodec::Release()
HRESULT MFCodec::QueryInterface(REFIID iid, void** ppv)
{
- if(!IsValid())
- {
- return E_FAIL;
- }
- return m_pMFT->QueryInterface(iid, ppv);
+ if(!IsValid()) {
+ return E_FAIL;
+ }
+ return m_pMFT->QueryInterface(iid, ppv);
}
// IMFAsyncCallback
STDMETHODIMP MFCodec::GetParameters(DWORD *pdwFlags, DWORD *pdwQueue)
{
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
STDMETHODIMP MFCodec::Invoke(IMFAsyncResult *pAsyncResult)
{
- HRESULT hr = S_OK, hrStatus = S_OK;
+ HRESULT hr = S_OK, hrStatus = S_OK;
IMFMediaEvent* pEvent = NULL;
MediaEventType meType = MEUnknown;
-
+
CHECK_HR(hr = m_pEventGenerator->EndGetEvent(pAsyncResult, &pEvent));
- CHECK_HR(hr = pEvent->GetType(&meType));
+ CHECK_HR(hr = pEvent->GetType(&meType));
CHECK_HR(hr = pEvent->GetStatus(&hrStatus));
- if (SUCCEEDED(hrStatus))
- {
- switch(meType)
- {
- case METransformNeedInput:
- {
- InterlockedIncrement(&m_nMETransformNeedInputCount);
- break;
- }
-
- case METransformHaveOutput:
- {
- InterlockedIncrement(&m_nMETransformHaveOutputCount);
- break;
- }
- }
- }
-
+ if (SUCCEEDED(hrStatus)) {
+ switch(meType) {
+ case METransformNeedInput: {
+ InterlockedIncrement(&m_nMETransformNeedInputCount);
+ break;
+ }
+
+ case METransformHaveOutput: {
+ InterlockedIncrement(&m_nMETransformHaveOutputCount);
+ break;
+ }
+ }
+ }
+
CHECK_HR(hr = m_pEventGenerator->BeginGetEvent(this, NULL));
bail:
- SafeRelease(&pEvent);
+ SafeRelease(&pEvent);
return hr;
}
HRESULT MFCodec::ProcessInput(IMFSample* pSample)
{
- assert(IsReady());
-
- HRESULT hr = S_OK;
-
- if(m_bIsFirstFrame)
- {
- if(m_bIsAsync && !m_bIsBundled)
- {
- CHECK_HR(hr = m_pMFT->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, NULL));
- CHECK_HR(hr = m_pEventGenerator->BeginGetEvent(this, NULL));
- }
- m_bIsFirstFrame = FALSE;
- }
-
- if(m_bIsAsync)
- {
- if(m_nMETransformNeedInputCount == 1 && m_pSampleQueueAsyncInput->IsEmpty())
- {
- InterlockedDecrement(&m_nMETransformNeedInputCount);
- return m_pMFT->ProcessInput(m_dwInputID, pSample, 0);
- }
-
- if(m_pSampleQueueAsyncInput->Count() > kMFCodecQueuedFramesMax)
- {
- m_pSampleQueueAsyncInput->Clear();
- CHECK_HR(hr = E_UNEXPECTED);
- }
-
- // Input sample holds shared memory (also used by other samples)
- IMFSample *pSampleCopy = NULL;
- IMFMediaBuffer *pMediaBuffer = NULL, *pMediaBufferCopy = NULL;
- BYTE *pBufferPtr = NULL, *pBufferPtrCopy = NULL;
- DWORD dwDataLength = 0;
- BOOL bMediaBufferLocked = FALSE, bMediaBufferLockedCopy = FALSE;
-
- CHECK_HR(hr = pSample->GetBufferByIndex(0, &pMediaBuffer));
- hr = pMediaBuffer->GetCurrentLength(&dwDataLength);
- if(FAILED(hr))
- {
- goto endofcopy;
- }
- hr = pMediaBuffer->Lock(&pBufferPtr, NULL, NULL);
- if(FAILED(hr))
- {
- goto endofcopy;
- }
- bMediaBufferLocked = TRUE;
-
- hr = MFUtils::CreateMediaSample(dwDataLength, &pSampleCopy);
- if(FAILED(hr))
- {
- goto endofcopy;
- }
- hr = pSampleCopy->GetBufferByIndex(0, &pMediaBufferCopy);
- if(FAILED(hr))
- {
- goto endofcopy;
- }
- hr = pMediaBufferCopy->Lock(&pBufferPtrCopy, NULL, NULL);
- if(FAILED(hr))
- {
- goto endofcopy;
- }
- bMediaBufferLockedCopy = TRUE;
-
- memcpy(pBufferPtrCopy, pBufferPtr, dwDataLength);
- hr = pMediaBufferCopy->SetCurrentLength(dwDataLength);
- if(FAILED(hr))
- {
- goto endofcopy;
- }
-
- LONGLONG hnsSampleTime = 0;
- LONGLONG hnsSampleDuration = 0;
- hr = pSample->GetSampleTime(&hnsSampleTime);
- if(SUCCEEDED(hr))
- {
- hr = pSampleCopy->SetSampleTime(hnsSampleTime);
- }
- hr = pSample->GetSampleDuration(&hnsSampleDuration);
- if(SUCCEEDED(hr))
- {
- hr = pSampleCopy->SetSampleDuration(hnsSampleDuration);
- }
-
- // EnQueue
- hr = m_pSampleQueueAsyncInput->Queue(pSampleCopy);
+ assert(IsReady());
+
+ HRESULT hr = S_OK;
+
+ if(m_bIsFirstFrame) {
+ if(m_bIsAsync && !m_bIsBundled) {
+ CHECK_HR(hr = m_pMFT->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, NULL));
+ CHECK_HR(hr = m_pEventGenerator->BeginGetEvent(this, NULL));
+ }
+ m_bIsFirstFrame = FALSE;
+ }
+
+ if(m_bIsAsync) {
+ if(m_nMETransformNeedInputCount == 1 && m_pSampleQueueAsyncInput->IsEmpty()) {
+ InterlockedDecrement(&m_nMETransformNeedInputCount);
+ return m_pMFT->ProcessInput(m_dwInputID, pSample, 0);
+ }
+
+ if(m_pSampleQueueAsyncInput->Count() > kMFCodecQueuedFramesMax) {
+ m_pSampleQueueAsyncInput->Clear();
+ CHECK_HR(hr = E_UNEXPECTED);
+ }
+
+ // Input sample holds shared memory (also used by other samples)
+ IMFSample *pSampleCopy = NULL;
+ IMFMediaBuffer *pMediaBuffer = NULL, *pMediaBufferCopy = NULL;
+ BYTE *pBufferPtr = NULL, *pBufferPtrCopy = NULL;
+ DWORD dwDataLength = 0;
+ BOOL bMediaBufferLocked = FALSE, bMediaBufferLockedCopy = FALSE;
+
+ CHECK_HR(hr = pSample->GetBufferByIndex(0, &pMediaBuffer));
+ hr = pMediaBuffer->GetCurrentLength(&dwDataLength);
+ if(FAILED(hr)) {
+ goto endofcopy;
+ }
+ hr = pMediaBuffer->Lock(&pBufferPtr, NULL, NULL);
+ if(FAILED(hr)) {
+ goto endofcopy;
+ }
+ bMediaBufferLocked = TRUE;
+
+ hr = MFUtils::CreateMediaSample(dwDataLength, &pSampleCopy);
+ if(FAILED(hr)) {
+ goto endofcopy;
+ }
+ hr = pSampleCopy->GetBufferByIndex(0, &pMediaBufferCopy);
+ if(FAILED(hr)) {
+ goto endofcopy;
+ }
+ hr = pMediaBufferCopy->Lock(&pBufferPtrCopy, NULL, NULL);
+ if(FAILED(hr)) {
+ goto endofcopy;
+ }
+ bMediaBufferLockedCopy = TRUE;
+
+ memcpy(pBufferPtrCopy, pBufferPtr, dwDataLength);
+ hr = pMediaBufferCopy->SetCurrentLength(dwDataLength);
+ if(FAILED(hr)) {
+ goto endofcopy;
+ }
+
+ LONGLONG hnsSampleTime = 0;
+ LONGLONG hnsSampleDuration = 0;
+ hr = pSample->GetSampleTime(&hnsSampleTime);
+ if(SUCCEEDED(hr)) {
+ hr = pSampleCopy->SetSampleTime(hnsSampleTime);
+ }
+ hr = pSample->GetSampleDuration(&hnsSampleDuration);
+ if(SUCCEEDED(hr)) {
+ hr = pSampleCopy->SetSampleDuration(hnsSampleDuration);
+ }
+
+ // EnQueue
+ hr = m_pSampleQueueAsyncInput->Queue(pSampleCopy);
endofcopy:
- if(pMediaBuffer && bMediaBufferLocked)
- {
- pMediaBuffer->Unlock();
- }
- if(pMediaBufferCopy && bMediaBufferLockedCopy)
- {
- pMediaBufferCopy->Unlock();
- }
- SafeRelease(&pSampleCopy);
- SafeRelease(&pMediaBuffer);
- CHECK_HR(hr);
-
- while(m_nMETransformNeedInputCount > 0)
- {
- if(m_pSampleQueueAsyncInput->IsEmpty())
- {
- break;
- }
- IMFSample *_pSample = NULL;
- hr = m_pSampleQueueAsyncInput->Dequeue(&_pSample);
- if(SUCCEEDED(hr))
- {
- InterlockedDecrement(&m_nMETransformNeedInputCount);
- hr = m_pMFT->ProcessInput(m_dwInputID, _pSample, 0);
- }
- SafeRelease(&_pSample);
- CHECK_HR(hr);
- }
- }
- else
- {
- CHECK_HR(hr = m_pMFT->ProcessInput(m_dwInputID, pSample, 0));
- }
+ if(pMediaBuffer && bMediaBufferLocked) {
+ pMediaBuffer->Unlock();
+ }
+ if(pMediaBufferCopy && bMediaBufferLockedCopy) {
+ pMediaBufferCopy->Unlock();
+ }
+ SafeRelease(&pSampleCopy);
+ SafeRelease(&pMediaBuffer);
+ CHECK_HR(hr);
+
+ while(m_nMETransformNeedInputCount > 0) {
+ if(m_pSampleQueueAsyncInput->IsEmpty()) {
+ break;
+ }
+ IMFSample *_pSample = NULL;
+ hr = m_pSampleQueueAsyncInput->Dequeue(&_pSample);
+ if(SUCCEEDED(hr)) {
+ InterlockedDecrement(&m_nMETransformNeedInputCount);
+ hr = m_pMFT->ProcessInput(m_dwInputID, _pSample, 0);
+ }
+ SafeRelease(&_pSample);
+ CHECK_HR(hr);
+ }
+ }
+ else {
+ CHECK_HR(hr = m_pMFT->ProcessInput(m_dwInputID, pSample, 0));
+ }
bail:
- return hr;
+ return hr;
}
HRESULT MFCodec::ProcessOutput(IMFSample **ppSample)
{
- assert(IsReady());
+ assert(IsReady());
- if(m_bIsAsync)
- {
- if(m_nMETransformHaveOutputCount == 0)
- {
- return S_OK;
- }
- InterlockedDecrement(&m_nMETransformHaveOutputCount);
- }
+ if(m_bIsAsync) {
+ if(m_nMETransformHaveOutputCount == 0) {
+ return S_OK;
+ }
+ InterlockedDecrement(&m_nMETransformHaveOutputCount);
+ }
- *ppSample = NULL;
+ *ppSample = NULL;
IMFMediaBuffer* pBufferOut = NULL;
DWORD dwStatus;
- HRESULT hr = S_OK;
-
+ HRESULT hr = S_OK;
+
MFT_OUTPUT_STREAM_INFO mftStreamInfo = { 0 };
MFT_OUTPUT_DATA_BUFFER mftOutputData = { 0 };
- CHECK_HR(hr = m_pMFT->GetOutputStreamInfo(m_dwOutputID, &mftStreamInfo));
-
- BOOL bOutputStreamProvidesSamples = (mftStreamInfo.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) == MFT_OUTPUT_STREAM_PROVIDES_SAMPLES;
-
- if(!bOutputStreamProvidesSamples)
- {
- if(!m_pSampleOut)
- {
- CHECK_HR(hr = MFUtils::CreateMediaSample(mftStreamInfo.cbSize, &m_pSampleOut));
- hr = m_pSampleOut->GetBufferByIndex(0, &pBufferOut);
- if(FAILED(hr))
- {
- SafeRelease(&m_pSampleOut);
- CHECK_HR(hr);
- }
- }
- else
- {
- DWORD dwMaxLength = 0;
- CHECK_HR(hr = m_pSampleOut->GetBufferByIndex(0, &pBufferOut));
- CHECK_HR(hr = pBufferOut->GetMaxLength(&dwMaxLength));
- if(dwMaxLength < mftStreamInfo.cbSize)
- {
- CHECK_HR(hr = m_pSampleOut->RemoveAllBuffers());
- SafeRelease(&pBufferOut);
- CHECK_HR(hr = MFCreateMemoryBuffer(mftStreamInfo.cbSize, &pBufferOut));
- CHECK_HR(hr = m_pSampleOut->AddBuffer(pBufferOut));
- }
- }
- }
-
- if(pBufferOut)
- {
- CHECK_HR(hr = pBufferOut->SetCurrentLength(0));
- }
-
+ CHECK_HR(hr = m_pMFT->GetOutputStreamInfo(m_dwOutputID, &mftStreamInfo));
+
+ BOOL bOutputStreamProvidesSamples = (mftStreamInfo.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) == MFT_OUTPUT_STREAM_PROVIDES_SAMPLES;
+
+ if(!bOutputStreamProvidesSamples) {
+ if(!m_pSampleOut) {
+ CHECK_HR(hr = MFUtils::CreateMediaSample(mftStreamInfo.cbSize, &m_pSampleOut));
+ hr = m_pSampleOut->GetBufferByIndex(0, &pBufferOut);
+ if(FAILED(hr)) {
+ SafeRelease(&m_pSampleOut);
+ CHECK_HR(hr);
+ }
+ }
+ else {
+ DWORD dwMaxLength = 0;
+ CHECK_HR(hr = m_pSampleOut->GetBufferByIndex(0, &pBufferOut));
+ CHECK_HR(hr = pBufferOut->GetMaxLength(&dwMaxLength));
+ if(dwMaxLength < mftStreamInfo.cbSize) {
+ CHECK_HR(hr = m_pSampleOut->RemoveAllBuffers());
+ SafeRelease(&pBufferOut);
+ CHECK_HR(hr = MFCreateMemoryBuffer(mftStreamInfo.cbSize, &pBufferOut));
+ CHECK_HR(hr = m_pSampleOut->AddBuffer(pBufferOut));
+ }
+ }
+ }
+
+ if(pBufferOut) {
+ CHECK_HR(hr = pBufferOut->SetCurrentLength(0));
+ }
+
//Set the output sample
mftOutputData.pSample = bOutputStreamProvidesSamples ? NULL : m_pSampleOut;
//Set the output id
@@ -428,167 +383,145 @@ HRESULT MFCodec::ProcessOutput(IMFSample **ppSample)
//Generate the output sample
hr = m_pMFT->ProcessOutput(0, 1, &mftOutputData, &dwStatus);
- if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT)
- {
+ if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
hr = S_OK;
goto bail;
}
- if (FAILED(hr))
- {
+ if (FAILED(hr)) {
goto bail;
}
*ppSample = mftOutputData.pSample;
- if(*ppSample)
- {
- (*ppSample)->AddRef();
- }
+ if(*ppSample) {
+ (*ppSample)->AddRef();
+ }
bail:
- if(bOutputStreamProvidesSamples)
- {
- SafeRelease(&mftOutputData.pSample);
- }
+ if(bOutputStreamProvidesSamples) {
+ SafeRelease(&mftOutputData.pSample);
+ }
SafeRelease(&pBufferOut);
return hr;
}
bool MFCodec::IsValid()
{
- return (m_pMFT && (m_eType == MFCodecType_Decoder || m_pCodecAPI));
+ return (m_pMFT && (m_eType == MFCodecType_Decoder || m_pCodecAPI));
}
bool MFCodec::IsReady()
{
- return (IsValid() && m_pOutputType && m_pInputType);
+ return (IsValid() && m_pOutputType && m_pInputType);
}
HRESULT MFCodec::Process(const void* pcInputPtr, UINT32 nInputSize, IMFSample **ppSampleOut)
{
- if(!pcInputPtr || !nInputSize || !ppSampleOut)
- {
- TSK_DEBUG_ERROR("Invalid parameter");
- return E_INVALIDARG;
- }
-
- *ppSampleOut = NULL;
-
- HRESULT hr = S_OK;
-
- IMFMediaBuffer* pBufferIn = NULL;
- BYTE* pBufferPtr = NULL;
- BOOL bMediaChangeHandled = FALSE; // Endless loop guard
-
- if(!m_pSampleIn)
- {
- CHECK_HR(hr = MFUtils::CreateMediaSample(nInputSize, &m_pSampleIn));
- hr = m_pSampleIn->GetBufferByIndex(0, &pBufferIn);
- if(FAILED(hr))
- {
- SafeRelease(&m_pSampleIn);
- CHECK_HR(hr);
- }
- }
- else
- {
- DWORD dwMaxLength = 0;
- CHECK_HR(hr = m_pSampleIn->GetBufferByIndex(0, &pBufferIn));
- CHECK_HR(hr = pBufferIn->GetMaxLength(&dwMaxLength));
- if(dwMaxLength < nInputSize)
- {
- CHECK_HR(hr = m_pSampleIn->RemoveAllBuffers());
- SafeRelease(&pBufferIn);
- CHECK_HR(hr = MFCreateMemoryBuffer(nInputSize, &pBufferIn));
- CHECK_HR(hr = m_pSampleIn->AddBuffer(pBufferIn));
- }
- }
-
- CHECK_HR(hr = pBufferIn->Lock(&pBufferPtr, NULL, NULL));
- memcpy(pBufferPtr, pcInputPtr, nInputSize);
- CHECK_HR(hr = pBufferIn->Unlock());
- CHECK_HR(hr = pBufferIn->SetCurrentLength(nInputSize));
-
- if(m_eType == MFCodecType_Encoder)
- {
- CHECK_HR(hr = m_pSampleIn->SetSampleDuration(m_rtDuration));
- CHECK_HR(hr = m_pSampleIn->SetSampleTime(m_rtStart)); // FIXME: use clock(), Same for custom source
- }
+ if(!pcInputPtr || !nInputSize || !ppSampleOut) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return E_INVALIDARG;
+ }
+
+ *ppSampleOut = NULL;
+
+ HRESULT hr = S_OK;
+
+ IMFMediaBuffer* pBufferIn = NULL;
+ BYTE* pBufferPtr = NULL;
+ BOOL bMediaChangeHandled = FALSE; // Endless loop guard
+
+ if(!m_pSampleIn) {
+ CHECK_HR(hr = MFUtils::CreateMediaSample(nInputSize, &m_pSampleIn));
+ hr = m_pSampleIn->GetBufferByIndex(0, &pBufferIn);
+ if(FAILED(hr)) {
+ SafeRelease(&m_pSampleIn);
+ CHECK_HR(hr);
+ }
+ }
+ else {
+ DWORD dwMaxLength = 0;
+ CHECK_HR(hr = m_pSampleIn->GetBufferByIndex(0, &pBufferIn));
+ CHECK_HR(hr = pBufferIn->GetMaxLength(&dwMaxLength));
+ if(dwMaxLength < nInputSize) {
+ CHECK_HR(hr = m_pSampleIn->RemoveAllBuffers());
+ SafeRelease(&pBufferIn);
+ CHECK_HR(hr = MFCreateMemoryBuffer(nInputSize, &pBufferIn));
+ CHECK_HR(hr = m_pSampleIn->AddBuffer(pBufferIn));
+ }
+ }
+
+ CHECK_HR(hr = pBufferIn->Lock(&pBufferPtr, NULL, NULL));
+ memcpy(pBufferPtr, pcInputPtr, nInputSize);
+ CHECK_HR(hr = pBufferIn->Unlock());
+ CHECK_HR(hr = pBufferIn->SetCurrentLength(nInputSize));
+
+ if(m_eType == MFCodecType_Encoder) {
+ CHECK_HR(hr = m_pSampleIn->SetSampleDuration(m_rtDuration));
+ CHECK_HR(hr = m_pSampleIn->SetSampleTime(m_rtStart)); // FIXME: use clock(), Same for custom source
+ }
Label_ProcessInput:
- hr = ProcessInput(m_pSampleIn);
- while(hr == MF_E_NOTACCEPTING)
- {
- TSK_DEBUG_INFO("MF_E_NOTACCEPTING");
- IMFSample* pSample = NULL;
- hr = ProcessOutput(&pSample);
- if(SUCCEEDED(hr) && pSample)
- {
- SafeRelease(ppSampleOut);
- *ppSampleOut = pSample, pSample = NULL;
-
- hr = m_pSampleIn->SetUINT32(MFSampleExtension_Discontinuity, TRUE);
- hr = ProcessInput(m_pSampleIn);
- }
- }
- if(!*ppSampleOut)
- {
- hr = ProcessOutput(ppSampleOut);
- if(hr == MF_E_TRANSFORM_STREAM_CHANGE) /* Handling Stream Changes: http://msdn.microsoft.com/en-us/library/windows/desktop/ee663587(v=vs.85).aspx */
- {
- TSK_DEBUG_INFO("[MF Codec] Stream changed");
- if(m_eType == MFCodecType_Decoder)
- {
- IMFMediaType *pTypeOut = NULL;
- hr = m_pMFT->GetOutputAvailableType(m_dwOutputID, 0, &pTypeOut);
- if(SUCCEEDED(hr))
- {
- UINT32 uWidth = 0, uHeight = 0;
- hr = MFGetAttributeSize(pTypeOut, MF_MT_FRAME_SIZE, &uWidth, &uHeight);
- if(SUCCEEDED(hr))
- {
- TSK_DEBUG_INFO("[MF Decoder] New size: width=%u, height=%u", uWidth, uHeight);
- hr = m_pMFT->SetOutputType(m_dwOutputID, pTypeOut, 0);
- if(SUCCEEDED(hr))
- {
- SafeRelease(&m_pOutputType);
- pTypeOut->AddRef();
- m_pOutputType = pTypeOut;
- if(m_eMediaType == MFCodecMediaType_Video)
- {
- dynamic_cast<MFCodecVideo*>(this)->m_nWidth = uWidth;
- dynamic_cast<MFCodecVideo*>(this)->m_nHeight = uHeight;
- }
- }
- }
- }
- SafeRelease(&pTypeOut);
- if(SUCCEEDED(hr))
- {
- if(!bMediaChangeHandled)
- {
- bMediaChangeHandled = TRUE;
- goto Label_ProcessInput;
- }
- }
- }
- }
- }
-
- m_rtStart += m_rtDuration;
-
+ hr = ProcessInput(m_pSampleIn);
+ while(hr == MF_E_NOTACCEPTING) {
+ TSK_DEBUG_INFO("MF_E_NOTACCEPTING");
+ IMFSample* pSample = NULL;
+ hr = ProcessOutput(&pSample);
+ if(SUCCEEDED(hr) && pSample) {
+ SafeRelease(ppSampleOut);
+ *ppSampleOut = pSample, pSample = NULL;
+
+ hr = m_pSampleIn->SetUINT32(MFSampleExtension_Discontinuity, TRUE);
+ hr = ProcessInput(m_pSampleIn);
+ }
+ }
+ if(!*ppSampleOut) {
+ hr = ProcessOutput(ppSampleOut);
+ if(hr == MF_E_TRANSFORM_STREAM_CHANGE) { /* Handling Stream Changes: http://msdn.microsoft.com/en-us/library/windows/desktop/ee663587(v=vs.85).aspx */
+ TSK_DEBUG_INFO("[MF Codec] Stream changed");
+ if(m_eType == MFCodecType_Decoder) {
+ IMFMediaType *pTypeOut = NULL;
+ hr = m_pMFT->GetOutputAvailableType(m_dwOutputID, 0, &pTypeOut);
+ if(SUCCEEDED(hr)) {
+ UINT32 uWidth = 0, uHeight = 0;
+ hr = MFGetAttributeSize(pTypeOut, MF_MT_FRAME_SIZE, &uWidth, &uHeight);
+ if(SUCCEEDED(hr)) {
+ TSK_DEBUG_INFO("[MF Decoder] New size: width=%u, height=%u", uWidth, uHeight);
+ hr = m_pMFT->SetOutputType(m_dwOutputID, pTypeOut, 0);
+ if(SUCCEEDED(hr)) {
+ SafeRelease(&m_pOutputType);
+ pTypeOut->AddRef();
+ m_pOutputType = pTypeOut;
+ if(m_eMediaType == MFCodecMediaType_Video) {
+ dynamic_cast<MFCodecVideo*>(this)->m_nWidth = uWidth;
+ dynamic_cast<MFCodecVideo*>(this)->m_nHeight = uHeight;
+ }
+ }
+ }
+ }
+ SafeRelease(&pTypeOut);
+ if(SUCCEEDED(hr)) {
+ if(!bMediaChangeHandled) {
+ bMediaChangeHandled = TRUE;
+ goto Label_ProcessInput;
+ }
+ }
+ }
+ }
+ }
+
+ m_rtStart += m_rtDuration;
+
bail:
- SafeRelease(&pBufferIn);
- return hr;
+ SafeRelease(&pBufferIn);
+ return hr;
}
enum tmedia_chroma_e MFCodec::GetUncompressedChroma()
{
- if(kMFCodecUncompressedFormat == MFVideoFormat_NV12)
- {
- return tmedia_chroma_nv12;
- }
- assert(false);
- return tmedia_chroma_none;
+ if(kMFCodecUncompressedFormat == MFVideoFormat_NV12) {
+ return tmedia_chroma_nv12;
+ }
+ assert(false);
+ return tmedia_chroma_none;
}
//
@@ -596,12 +529,12 @@ enum tmedia_chroma_e MFCodec::GetUncompressedChroma()
//
MFCodecVideo::MFCodecVideo(MFCodecId_t eId, MFCodecType_t eType, IMFTransform *pMFT /*= NULL*/)
-: MFCodec(eId, eType, pMFT)
-, m_nFrameRate(0)
-, m_nWidth(0)
-, m_nHeight(0)
+ : MFCodec(eId, eType, pMFT)
+ , m_nFrameRate(0)
+ , m_nWidth(0)
+ , m_nHeight(0)
{
- assert(m_eMediaType == MFCodecMediaType_Video);
+ assert(m_eMediaType == MFCodecMediaType_Video);
}
MFCodecVideo::~MFCodecVideo()
@@ -610,279 +543,261 @@ MFCodecVideo::~MFCodecVideo()
}
HRESULT MFCodecVideo::Initialize(
- UINT32 nFrameRate,
- UINT32 nWidth,
- UINT32 nHeight,
- UINT32 nOutputBitRateInBps /*= 0*/
- )
+ UINT32 nFrameRate,
+ UINT32 nWidth,
+ UINT32 nHeight,
+ UINT32 nOutputBitRateInBps /*= 0*/
+)
{
- assert(IsValid());
-
- HRESULT hr = S_OK;
+ assert(IsValid());
- VARIANT var = {0};
+ HRESULT hr = S_OK;
- // make sure identifiers are zero-based (other layouts not supported yet)
- hr = m_pMFT->GetStreamIDs(1, &m_dwInputID, 1, &m_dwOutputID);
- if (hr == E_NOTIMPL)
- {
+ VARIANT var = {0};
+
+ // make sure identifiers are zero-based (other layouts not supported yet)
+ hr = m_pMFT->GetStreamIDs(1, &m_dwInputID, 1, &m_dwOutputID);
+ if (hr == E_NOTIMPL) {
m_dwInputID = 0;
m_dwOutputID = 0;
hr = S_OK;
}
- else if (FAILED(hr))
- {
- TSK_DEBUG_ERROR("The stream identifiers are not zero-based");
+ else if (FAILED(hr)) {
+ TSK_DEBUG_ERROR("The stream identifiers are not zero-based");
return hr;
}
- m_rtStart = 0;
- CHECK_HR(hr = MFFrameRateToAverageTimePerFrame(nFrameRate, 1, &m_rtDuration));
+ m_rtStart = 0;
+ CHECK_HR(hr = MFFrameRateToAverageTimePerFrame(nFrameRate, 1, &m_rtDuration));
+
+ CHECK_HR(hr = m_pOutputType->SetGUID(MF_MT_MAJOR_TYPE, (m_eMediaType == MFCodecMediaType_Video) ? MFMediaType_Video : MFMediaType_Audio));
+ CHECK_HR(hr = m_pInputType->SetGUID(MF_MT_MAJOR_TYPE, (m_eMediaType == MFCodecMediaType_Video) ? MFMediaType_Video : MFMediaType_Audio));
- CHECK_HR(hr = m_pOutputType->SetGUID(MF_MT_MAJOR_TYPE, (m_eMediaType == MFCodecMediaType_Video) ? MFMediaType_Video : MFMediaType_Audio));
- CHECK_HR(hr = m_pInputType->SetGUID(MF_MT_MAJOR_TYPE, (m_eMediaType == MFCodecMediaType_Video) ? MFMediaType_Video : MFMediaType_Audio));
+ CHECK_HR(hr = m_pOutputType->SetGUID(MF_MT_SUBTYPE, (m_eType == MFCodecType_Encoder) ? m_guidCompressedFormat : kMFCodecUncompressedFormat));
+ CHECK_HR(hr = m_pInputType->SetGUID(MF_MT_SUBTYPE, (m_eType == MFCodecType_Encoder) ? kMFCodecUncompressedFormat : m_guidCompressedFormat));
- CHECK_HR(hr = m_pOutputType->SetGUID(MF_MT_SUBTYPE, (m_eType == MFCodecType_Encoder) ? m_guidCompressedFormat : kMFCodecUncompressedFormat));
- CHECK_HR(hr = m_pInputType->SetGUID(MF_MT_SUBTYPE, (m_eType == MFCodecType_Encoder) ? kMFCodecUncompressedFormat : m_guidCompressedFormat));
-
- CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, (m_eType == MFCodecType_Encoder) ? FALSE : TRUE));
- CHECK_HR(hr = m_pInputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, (m_eType == MFCodecType_Encoder) ? TRUE : FALSE));
+ CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, (m_eType == MFCodecType_Encoder) ? FALSE : TRUE));
+ CHECK_HR(hr = m_pInputType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, (m_eType == MFCodecType_Encoder) ? TRUE : FALSE));
+
+ CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, (m_eType == MFCodecType_Encoder) ? FALSE : TRUE));
+ CHECK_HR(hr = m_pInputType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, (m_eType == MFCodecType_Encoder) ? TRUE : FALSE));
+
+ // Set bitrate
+ // Set (MF_MT_AVG_BITRATE) for MediaType
+ // Set (CODECAPI_AVEncCommonMeanBitRate) for H.264
+ hr = SetBitRate(nOutputBitRateInBps);
- CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, (m_eType == MFCodecType_Encoder) ? FALSE : TRUE));
- CHECK_HR(hr = m_pInputType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, (m_eType == MFCodecType_Encoder) ? TRUE : FALSE));
-
- // Set bitrate
- // Set (MF_MT_AVG_BITRATE) for MediaType
- // Set (CODECAPI_AVEncCommonMeanBitRate) for H.264
- hr = SetBitRate(nOutputBitRateInBps);
-
CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
- CHECK_HR(hr = m_pInputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
+ CHECK_HR(hr = m_pInputType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
CHECK_HR(hr = MFSetAttributeSize(m_pOutputType, MF_MT_FRAME_SIZE, nWidth, nHeight));
- CHECK_HR(hr = MFSetAttributeSize(m_pInputType, MF_MT_FRAME_SIZE, nWidth, nHeight));
+ CHECK_HR(hr = MFSetAttributeSize(m_pInputType, MF_MT_FRAME_SIZE, nWidth, nHeight));
CHECK_HR(hr = MFSetAttributeRatio(m_pOutputType, MF_MT_FRAME_RATE, nFrameRate, 1));
- CHECK_HR(hr = MFSetAttributeRatio(m_pInputType, MF_MT_FRAME_RATE, nFrameRate, 1));
+ CHECK_HR(hr = MFSetAttributeRatio(m_pInputType, MF_MT_FRAME_RATE, nFrameRate, 1));
CHECK_HR(hr = MFSetAttributeRatio(m_pOutputType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1));
- CHECK_HR(hr = MFSetAttributeRatio(m_pInputType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1));
-
- // Encoder: Output format must be set before input
- // Decoder: Input format must be set before output
- if(m_eType == MFCodecType_Encoder)
- {
- CHECK_HR(hr = m_pMFT->SetOutputType(m_dwOutputID, m_pOutputType, 0));
- CHECK_HR(hr = m_pMFT->SetInputType(m_dwInputID, m_pInputType, 0));
- }
- else
- {
- CHECK_HR(hr = m_pMFT->SetInputType(m_dwInputID, m_pInputType, 0));
- CHECK_HR(hr = m_pMFT->SetOutputType(m_dwOutputID, m_pOutputType, 0));
- }
-
- if(m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)
- {
- if(m_eType == MFCodecType_Decoder)
- {
- // Only decoder support GetAttributes()
- IMFAttributes* pAttributes = NULL;
- hr = m_pMFT->GetAttributes(&pAttributes);
- if(SUCCEEDED(hr))
- {
- // FIXME: Very strange that "CODECAPI_AVLowLatencyMode" only works with "IMFAttributes->" and not "ICodecAPI->SetValue()"
- hr = pAttributes->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE);
- }
- SafeRelease(&pAttributes);
- }
- else
- {
- var.vt = VT_BOOL;
- var.boolVal = VARIANT_TRUE;
- hr = m_pCodecAPI->SetValue(&CODECAPI_AVLowLatencyMode, &var);
-
- var.vt = VT_BOOL;
- var.boolVal = VARIANT_TRUE;
- hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncCommonLowLatency, &var); // Correct for the decoder
-
- // Disable B-Frames
- var.vt = VT_UI4;
- var.ulVal = 0;
- hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncMPVDefaultBPictureCount, &var);
-
- // Constant bitrate (updated using RTCP)
- var.vt = VT_UI4;
- var.ulVal = eAVEncCommonRateControlMode_CBR;
- hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var);
- }
-
- hr = S_OK; // Not mandatory features
- }
+ CHECK_HR(hr = MFSetAttributeRatio(m_pInputType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1));
+
+ // Encoder: Output format must be set before input
+ // Decoder: Input format must be set before output
+ if(m_eType == MFCodecType_Encoder) {
+ CHECK_HR(hr = m_pMFT->SetOutputType(m_dwOutputID, m_pOutputType, 0));
+ CHECK_HR(hr = m_pMFT->SetInputType(m_dwInputID, m_pInputType, 0));
+ }
+ else {
+ CHECK_HR(hr = m_pMFT->SetInputType(m_dwInputID, m_pInputType, 0));
+ CHECK_HR(hr = m_pMFT->SetOutputType(m_dwOutputID, m_pOutputType, 0));
+ }
+
+ if(m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main) {
+ if(m_eType == MFCodecType_Decoder) {
+ // Only decoder support GetAttributes()
+ IMFAttributes* pAttributes = NULL;
+ hr = m_pMFT->GetAttributes(&pAttributes);
+ if(SUCCEEDED(hr)) {
+ // FIXME: Very strange that "CODECAPI_AVLowLatencyMode" only works with "IMFAttributes->" and not "ICodecAPI->SetValue()"
+ hr = pAttributes->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE);
+ }
+ SafeRelease(&pAttributes);
+ }
+ else {
+ var.vt = VT_BOOL;
+ var.boolVal = VARIANT_TRUE;
+ hr = m_pCodecAPI->SetValue(&CODECAPI_AVLowLatencyMode, &var);
+
+ var.vt = VT_BOOL;
+ var.boolVal = VARIANT_TRUE;
+ hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncCommonLowLatency, &var); // Correct for the decoder
+
+ // Disable B-Frames
+ var.vt = VT_UI4;
+ var.ulVal = 0;
+ hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncMPVDefaultBPictureCount, &var);
+
+ // Constant bitrate (updated using RTCP)
+ var.vt = VT_UI4;
+ var.ulVal = eAVEncCommonRateControlMode_CBR;
+ hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncCommonRateControlMode, &var);
+ }
+
+ hr = S_OK; // Not mandatory features
+ }
bail:
- if(SUCCEEDED(hr))
- {
- m_nFrameRate = nFrameRate;
- m_nWidth = nWidth;
- m_nHeight = nHeight;
- }
+ if(SUCCEEDED(hr)) {
+ m_nFrameRate = nFrameRate;
+ m_nWidth = nWidth;
+ m_nHeight = nHeight;
+ }
- return hr;
+ return hr;
}
HRESULT MFCodecVideo::SetGOPSize(UINT32 nFramesCount)
{
- assert(IsValid());
+ assert(IsValid());
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK;
- if(m_eType == MFCodecType_Encoder && (m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main))
- {
- VARIANT var = {0};
- var.vt = VT_UI4;
- var.ullVal = nFramesCount;
- CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncMPVGOPSize, &var));
- }
+ if(m_eType == MFCodecType_Encoder && (m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) {
+ VARIANT var = {0};
+ var.vt = VT_UI4;
+ var.ullVal = nFramesCount;
+ CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncMPVGOPSize, &var));
+ }
bail:
- return hr;
+ return hr;
}
HRESULT MFCodecVideo::SetBitRate(UINT32 nBitRateInBps)
{
- assert(IsValid());
+ assert(IsValid());
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK;
- if(nBitRateInBps > 0 && m_eType == MFCodecType_Encoder)
- {
- CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_AVG_BITRATE, nBitRateInBps));
+ if(nBitRateInBps > 0 && m_eType == MFCodecType_Encoder) {
+ CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_AVG_BITRATE, nBitRateInBps));
- if((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main))
- {
- VARIANT var = {0};
+ if((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) {
+ VARIANT var = {0};
- // Set BitRate
- var.vt = VT_UI4;
- var.ullVal = nBitRateInBps;
- CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var));
- }
- }
+ // Set BitRate
+ var.vt = VT_UI4;
+ var.ullVal = nBitRateInBps;
+ CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var));
+ }
+ }
bail:
- return hr;
+ return hr;
}
HRESULT MFCodecVideo::IsSetSliceMaxSizeInBytesSupported(BOOL &supported)
{
- HRESULT hr = S_OK;
- supported = FALSE;
+ HRESULT hr = S_OK;
+ supported = FALSE;
- if ((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main))
- {
+ if ((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) {
#if defined(CODECAPI_AVEncSliceControlMode) && defined(CODECAPI_AVEncSliceControlSize)
- if (m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlMode) == S_OK && m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlSize) == S_OK) {
- supported = TRUE;
- }
+ if (m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlMode) == S_OK && m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlSize) == S_OK) {
+ supported = TRUE;
+ }
#endif
- }
- return hr;
+ }
+ return hr;
}
HRESULT MFCodecVideo::SetSliceMaxSizeInBytes(UINT32 nSliceMaxSizeInBytes)
{
- assert(IsValid() && nSliceMaxSizeInBytes > 0);
+ assert(IsValid() && nSliceMaxSizeInBytes > 0);
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK;
- if ((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main))
- {
+ if ((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) {
#if defined(CODECAPI_AVEncSliceControlMode) && defined(CODECAPI_AVEncSliceControlSize)
- if (m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlMode) == S_OK && m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlSize) == S_OK) {
- VARIANT var = { 0 };
- var.vt = VT_UI4;
+ if (m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlMode) == S_OK && m_pCodecAPI->IsSupported(&CODECAPI_AVEncSliceControlSize) == S_OK) {
+ VARIANT var = { 0 };
+ var.vt = VT_UI4;
- var.ulVal = 1; // Bits
- CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncSliceControlMode, &var));
+ var.ulVal = 1; // Bits
+ CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncSliceControlMode, &var));
- var.ulVal = (nSliceMaxSizeInBytes << 3); // From Bytes to Bits
- CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncSliceControlSize, &var));
- }
+ var.ulVal = (nSliceMaxSizeInBytes << 3); // From Bytes to Bits
+ CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncSliceControlSize, &var));
+ }
#else
- CHECK_HR(hr = S_OK);
+ CHECK_HR(hr = S_OK);
#endif
- }
+ }
bail:
- return hr;
+ return hr;
}
HRESULT MFCodecVideo::RequestKeyFrame()
{
- assert(IsValid());
-
- HRESULT hr = S_OK;
+ assert(IsValid());
+
+ HRESULT hr = S_OK;
- if ((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main))
- {
+ if ((m_eId == MFCodecId_H264Base || m_eId == MFCodecId_H264Main)) {
#if defined(CODECAPI_AVEncVideoForceKeyFrame)
- if (m_pCodecAPI->IsSupported(&CODECAPI_AVEncVideoForceKeyFrame) == S_OK) {
- VARIANT var = { 0 };
+ if (m_pCodecAPI->IsSupported(&CODECAPI_AVEncVideoForceKeyFrame) == S_OK) {
+ VARIANT var = { 0 };
- var.vt = VT_UI4;
- var.ulVal = 1;
- CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncVideoForceKeyFrame, &var));
- }
+ var.vt = VT_UI4;
+ var.ulVal = 1;
+ CHECK_HR(hr = m_pCodecAPI->SetValue(&CODECAPI_AVEncVideoForceKeyFrame, &var));
+ }
#else
- CHECK_HR(hr = S_OK);
+ CHECK_HR(hr = S_OK);
#endif
- }
+ }
bail:
- return hr;
+ return hr;
}
//
// MFCodecVideo
//
MFCodecVideoH264::MFCodecVideoH264(MFCodecId_t eId, MFCodecType_t eType, IMFTransform *pMFT /*= NULL*/)
-: MFCodecVideo(eId, eType, pMFT)
+ : MFCodecVideo(eId, eType, pMFT)
{
- assert(eId == MFCodecId_H264Base || eId == MFCodecId_H264Main);
-
- HRESULT hr = S_OK;
+ assert(eId == MFCodecId_H264Base || eId == MFCodecId_H264Main);
- if(m_pOutputType)
- {
- CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_MPEG2_PROFILE, (m_eId == MFCodecId_H264Base) ? eAVEncH264VProfile_Base : eAVEncH264VProfile_Main));
- }
+ HRESULT hr = S_OK;
+
+ if(m_pOutputType) {
+ CHECK_HR(hr = m_pOutputType->SetUINT32(MF_MT_MPEG2_PROFILE, (m_eId == MFCodecId_H264Base) ? eAVEncH264VProfile_Base : eAVEncH264VProfile_Main));
+ }
bail:
- assert(SUCCEEDED(hr));
+ assert(SUCCEEDED(hr));
}
MFCodecVideoH264::~MFCodecVideoH264()
{
-
+
}
MFCodecVideoH264* MFCodecVideoH264::CreateCodecH264Base(MFCodecType_t eType, IMFTransform *pMFT /*= NULL*/)
{
- MFCodecVideoH264* pCodec = new MFCodecVideoH264(MFCodecId_H264Base, eType, pMFT);
- if(pCodec && !pCodec->IsValid())
- {
- SafeRelease(&pCodec);
- }
- return pCodec;
+ MFCodecVideoH264* pCodec = new MFCodecVideoH264(MFCodecId_H264Base, eType, pMFT);
+ if(pCodec && !pCodec->IsValid()) {
+ SafeRelease(&pCodec);
+ }
+ return pCodec;
}
MFCodecVideoH264* MFCodecVideoH264::CreateCodecH264Main(MFCodecType_t eType, IMFTransform *pMFT /*= NULL*/)
{
- MFCodecVideoH264* pCodec = new MFCodecVideoH264(MFCodecId_H264Main, eType, pMFT);
- if(pCodec && !pCodec->IsValid())
- {
- SafeRelease(&pCodec);
- }
- return pCodec;
+ MFCodecVideoH264* pCodec = new MFCodecVideoH264(MFCodecId_H264Main, eType, pMFT);
+ if(pCodec && !pCodec->IsValid()) {
+ SafeRelease(&pCodec);
+ }
+ return pCodec;
}
diff --git a/plugins/pluginWinMF/internals/mf_codec.h b/plugins/pluginWinMF/internals/mf_codec.h
index 51b06dc..d4f00c7 100755
--- a/plugins/pluginWinMF/internals/mf_codec.h
+++ b/plugins/pluginWinMF/internals/mf_codec.h
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -30,125 +30,136 @@
class MFSampleQueue;
-typedef enum MFCodecId_e
-{
- MFCodecId_H264Base,
- MFCodecId_H264Main,
- MFCodecId_AAC
+typedef enum MFCodecId_e {
+ MFCodecId_H264Base,
+ MFCodecId_H264Main,
+ MFCodecId_AAC
}
MFCodecId_t;
-typedef enum MFCodecType_e
-{
- MFCodecType_Encoder,
- MFCodecType_Decoder
+typedef enum MFCodecType_e {
+ MFCodecType_Encoder,
+ MFCodecType_Decoder
}
MFCodecType_t;
-typedef enum MFCodecMediaType_e
-{
- MFCodecMediaType_Audio,
- MFCodecMediaType_Video
+typedef enum MFCodecMediaType_e {
+ MFCodecMediaType_Audio,
+ MFCodecMediaType_Video
}
MFCodecMediaType_t;
-class MFCodec : IMFAsyncCallback
+class MFCodec : IMFAsyncCallback
{
protected:
- MFCodec(MFCodecId_t eId, MFCodecType_t eType, IMFTransform *pMFT = NULL);
- virtual ~MFCodec();
- HRESULT ProcessInput(IMFSample* pSample);
- HRESULT ProcessOutput(IMFSample **ppSample);
+ MFCodec(MFCodecId_t eId, MFCodecType_t eType, IMFTransform *pMFT = NULL);
+ virtual ~MFCodec();
+ HRESULT ProcessInput(IMFSample* pSample);
+ HRESULT ProcessOutput(IMFSample **ppSample);
public:
- virtual bool IsValid();
- virtual bool IsReady();
- virtual HRESULT Process(const void* pcInputPtr, UINT32 nInputSize, IMFSample **ppSampleOut);
- static enum tmedia_chroma_e GetUncompressedChroma();
- inline IMFTransform* GetMFT(){ return m_pMFT; }
- inline MFCodecId_t GetId() { return m_eId; }
- inline MFCodecType_t GetType() { return m_eType; }
- inline void setBundled(BOOL bBundled) { m_bIsBundled = bBundled; }
-
- // IUnknown
+ virtual bool IsValid();
+ virtual bool IsReady();
+ virtual HRESULT Process(const void* pcInputPtr, UINT32 nInputSize, IMFSample **ppSampleOut);
+ static enum tmedia_chroma_e GetUncompressedChroma();
+ inline IMFTransform* GetMFT() {
+ return m_pMFT;
+ }
+ inline MFCodecId_t GetId() {
+ return m_eId;
+ }
+ inline MFCodecType_t GetType() {
+ return m_eType;
+ }
+ inline void setBundled(BOOL bBundled) {
+ m_bIsBundled = bBundled;
+ }
+
+ // IUnknown
STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
- // IMFAsyncCallback
- STDMETHODIMP GetParameters(DWORD *pdwFlags, DWORD *pdwQueue);
- STDMETHODIMP Invoke(IMFAsyncResult *pAsyncResult);
+ // IMFAsyncCallback
+ STDMETHODIMP GetParameters(DWORD *pdwFlags, DWORD *pdwQueue);
+ STDMETHODIMP Invoke(IMFAsyncResult *pAsyncResult);
private:
- long m_nRefCount;
+ long m_nRefCount;
protected:
- MFCodecId_t m_eId; // Codec Id
- MFCodecType_t m_eType; // Codec type.
- MFCodecMediaType_t m_eMediaType; // Codec Media type.
- DWORD m_dwInputID; // Input stream ID.
+ MFCodecId_t m_eId; // Codec Id
+ MFCodecType_t m_eType; // Codec type.
+ MFCodecMediaType_t m_eMediaType; // Codec Media type.
+ DWORD m_dwInputID; // Input stream ID.
DWORD m_dwOutputID; // Output stream ID.
- GUID m_guidCompressedFormat; // Compressed Media format (e.g. MFVideoFormat_H264)
+ GUID m_guidCompressedFormat; // Compressed Media format (e.g. MFVideoFormat_H264)
IMFTransform *m_pMFT; // Pointer to the encoder MFT.
- ICodecAPI *m_pCodecAPI; // Pointer to CodecAPI.
+ ICodecAPI *m_pCodecAPI; // Pointer to CodecAPI.
IMFMediaType *m_pOutputType; // Output media type of the codec.
- IMFMediaType *m_pInputType; // Input media type of the codec.
+ IMFMediaType *m_pInputType; // Input media type of the codec.
- LONGLONG m_rtStart;
+ LONGLONG m_rtStart;
UINT64 m_rtDuration;
- IMFSample *m_pSampleIn;
- IMFSample *m_pSampleOut;
+ IMFSample *m_pSampleIn;
+ IMFSample *m_pSampleOut;
- MFSampleQueue *m_pSampleQueueAsyncInput;
- BOOL m_bIsBundled; // Bundled with a producer or cosumer -> do not monitor events
- BOOL m_bIsAsync;
- IMFMediaEventGenerator *m_pEventGenerator;
- BOOL m_bIsFirstFrame;
- long m_nMETransformNeedInputCount, m_nMETransformHaveOutputCount;
+ MFSampleQueue *m_pSampleQueueAsyncInput;
+ BOOL m_bIsBundled; // Bundled with a producer or cosumer -> do not monitor events
+ BOOL m_bIsAsync;
+ IMFMediaEventGenerator *m_pEventGenerator;
+ BOOL m_bIsFirstFrame;
+ long m_nMETransformNeedInputCount, m_nMETransformHaveOutputCount;
};
class MFCodecVideo : public MFCodec
{
- friend class MFCodec;
+ friend class MFCodec;
protected:
- MFCodecVideo(MFCodecId_t eId, MFCodecType_t eType, IMFTransform *pMFT = NULL);
- virtual ~MFCodecVideo();
+ MFCodecVideo(MFCodecId_t eId, MFCodecType_t eType, IMFTransform *pMFT = NULL);
+ virtual ~MFCodecVideo();
public:
- virtual HRESULT Initialize(
- UINT32 nFrameRate,
- UINT32 nWidth,
- UINT32 nHeight,
- UINT32 nOutputBitRateInBps = 0 // Only for encoders
- );
- virtual HRESULT SetGOPSize(UINT32 nFramesCount);
- virtual HRESULT SetBitRate(UINT32 nBitRateInBps);
- virtual HRESULT SetSliceMaxSizeInBytes(UINT32 nSliceMaxSizeInBytes);
- virtual HRESULT RequestKeyFrame();
-
- virtual HRESULT IsSetSliceMaxSizeInBytesSupported(BOOL &supported);
- virtual inline UINT32 GetFrameRate() { return m_nFrameRate; }
- virtual inline UINT32 GetWidth() { return m_nWidth; }
- virtual inline UINT32 GetHeight() { return m_nHeight; }
+ virtual HRESULT Initialize(
+ UINT32 nFrameRate,
+ UINT32 nWidth,
+ UINT32 nHeight,
+ UINT32 nOutputBitRateInBps = 0 // Only for encoders
+ );
+ virtual HRESULT SetGOPSize(UINT32 nFramesCount);
+ virtual HRESULT SetBitRate(UINT32 nBitRateInBps);
+ virtual HRESULT SetSliceMaxSizeInBytes(UINT32 nSliceMaxSizeInBytes);
+ virtual HRESULT RequestKeyFrame();
+
+ virtual HRESULT IsSetSliceMaxSizeInBytesSupported(BOOL &supported);
+ virtual inline UINT32 GetFrameRate() {
+ return m_nFrameRate;
+ }
+ virtual inline UINT32 GetWidth() {
+ return m_nWidth;
+ }
+ virtual inline UINT32 GetHeight() {
+ return m_nHeight;
+ }
protected:
- UINT32 m_nFrameRate;
- UINT32 m_nWidth;
- UINT32 m_nHeight;
+ UINT32 m_nFrameRate;
+ UINT32 m_nWidth;
+ UINT32 m_nHeight;
};
class MFCodecVideoH264 : public MFCodecVideo
{
protected:
- MFCodecVideoH264(MFCodecId_t eId, MFCodecType_t eType, IMFTransform *pMFT = NULL);
+ MFCodecVideoH264(MFCodecId_t eId, MFCodecType_t eType, IMFTransform *pMFT = NULL);
public:
- virtual ~MFCodecVideoH264();
- static MFCodecVideoH264* CreateCodecH264Base(MFCodecType_t eType, IMFTransform *pMFT = NULL);
- static MFCodecVideoH264* CreateCodecH264Main(MFCodecType_t eType, IMFTransform *pMFT = NULL);
+ virtual ~MFCodecVideoH264();
+ static MFCodecVideoH264* CreateCodecH264Base(MFCodecType_t eType, IMFTransform *pMFT = NULL);
+ static MFCodecVideoH264* CreateCodecH264Main(MFCodecType_t eType, IMFTransform *pMFT = NULL);
protected:
diff --git a/plugins/pluginWinMF/internals/mf_codec_topology.cxx b/plugins/pluginWinMF/internals/mf_codec_topology.cxx
index 1ee2a16..1f63466 100755
--- a/plugins/pluginWinMF/internals/mf_codec_topology.cxx
+++ b/plugins/pluginWinMF/internals/mf_codec_topology.cxx
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -25,134 +25,117 @@
// MFCodecTopologySampleGrabberCB
//
-class MFCodecTopologySampleGrabberCB : public IMFSampleGrabberSinkCallback
+class MFCodecTopologySampleGrabberCB : public IMFSampleGrabberSinkCallback
{
long m_cRef;
MFCodecTopology *m_pCodecTopology;
MFCodecTopologySampleGrabberCB(MFCodecTopology *pCodecTopology)
- : m_cRef(1)
- {
- m_pCodecTopology = pCodecTopology;
- m_pCodecTopology->AddRef();
- }
- virtual ~MFCodecTopologySampleGrabberCB()
- {
- SafeRelease(&m_pCodecTopology);
- }
+ : m_cRef(1) {
+ m_pCodecTopology = pCodecTopology;
+ m_pCodecTopology->AddRef();
+ }
+ virtual ~MFCodecTopologySampleGrabberCB() {
+ SafeRelease(&m_pCodecTopology);
+ }
public:
// Create a new instance of the object.
- static HRESULT MFCodecTopologySampleGrabberCB::CreateInstance(MFCodecTopology *pCodecTopology, MFCodecTopologySampleGrabberCB **ppCB)
- {
- *ppCB = new (std::nothrow) MFCodecTopologySampleGrabberCB(pCodecTopology);
-
- if (ppCB == NULL)
- {
- return E_OUTOFMEMORY;
- }
- return S_OK;
- }
-
- STDMETHODIMP MFCodecTopologySampleGrabberCB::QueryInterface(REFIID riid, void** ppv)
- {
- static const QITAB qit[] =
- {
- QITABENT(MFCodecTopologySampleGrabberCB, IMFSampleGrabberSinkCallback),
- QITABENT(MFCodecTopologySampleGrabberCB, IMFClockStateSink),
- { 0 }
- };
- return QISearch(this, qit, riid, ppv);
- }
-
- STDMETHODIMP_(ULONG) MFCodecTopologySampleGrabberCB::AddRef()
- {
- return InterlockedIncrement(&m_cRef);
- }
-
- STDMETHODIMP_(ULONG) MFCodecTopologySampleGrabberCB::Release()
- {
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- {
- delete this;
- }
- return cRef;
-
- }
-
- // IMFClockStateSink methods
-
- STDMETHODIMP MFCodecTopologySampleGrabberCB::OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset)
- {
- TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnClockStart(%lld, %lld)", hnsSystemTime, llClockStartOffset);
- return S_OK;
- }
-
- STDMETHODIMP MFCodecTopologySampleGrabberCB::OnClockStop(MFTIME hnsSystemTime)
- {
- TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnClockStop(%lld)", hnsSystemTime);
- return S_OK;
- }
-
- STDMETHODIMP MFCodecTopologySampleGrabberCB::OnClockPause(MFTIME hnsSystemTime)
- {
- TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnClockPause(%lld)", hnsSystemTime);
- return S_OK;
- }
-
- STDMETHODIMP MFCodecTopologySampleGrabberCB::OnClockRestart(MFTIME hnsSystemTime)
- {
- TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnClockRestart(%lld)", hnsSystemTime);
- return S_OK;
- }
-
- STDMETHODIMP MFCodecTopologySampleGrabberCB::OnClockSetRate(MFTIME hnsSystemTime, float flRate)
- {
- TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnClockSetRate(%lld, %f)", hnsSystemTime, flRate);
- return S_OK;
- }
-
- // IMFSampleGrabberSink methods.
-
- STDMETHODIMP MFCodecTopologySampleGrabberCB::OnSetPresentationClock(IMFPresentationClock* pClock)
- {
- TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnSetPresentationClock");
- return S_OK;
- }
-
- STDMETHODIMP MFCodecTopologySampleGrabberCB::OnProcessSample(
- REFGUID guidMajorMediaType, DWORD dwSampleFlags,
- LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer,
- DWORD dwSampleSize)
- {
- HRESULT hr = S_OK;
- IMFSample *pSample = NULL;
- IMFMediaBuffer* pMediaBuffer = NULL;
- BYTE* _pcBufferPtr = NULL;
-
- CHECK_HR(hr = MFUtils::CreateMediaSample(dwSampleSize, &pSample));
- CHECK_HR(hr = pSample->SetSampleTime(llSampleTime));
- CHECK_HR(hr = pSample->SetSampleDuration(llSampleDuration));
- CHECK_HR(hr = pSample->GetBufferByIndex(0, &pMediaBuffer));
- CHECK_HR(hr = pMediaBuffer->Lock(&_pcBufferPtr, NULL, NULL));
- memcpy(_pcBufferPtr, pSampleBuffer, dwSampleSize);
- CHECK_HR(hr = pMediaBuffer->SetCurrentLength(dwSampleSize));
- CHECK_HR(hr = pMediaBuffer->Unlock());
-
- m_pCodecTopology->m_SampleQueue.Queue(pSample); // thread-safe
-
+ static HRESULT MFCodecTopologySampleGrabberCB::CreateInstance(MFCodecTopology *pCodecTopology, MFCodecTopologySampleGrabberCB **ppCB) {
+ *ppCB = new (std::nothrow) MFCodecTopologySampleGrabberCB(pCodecTopology);
+
+ if (ppCB == NULL) {
+ return E_OUTOFMEMORY;
+ }
+ return S_OK;
+ }
+
+ STDMETHODIMP MFCodecTopologySampleGrabberCB::QueryInterface(REFIID riid, void** ppv) {
+ static const QITAB qit[] = {
+ QITABENT(MFCodecTopologySampleGrabberCB, IMFSampleGrabberSinkCallback),
+ QITABENT(MFCodecTopologySampleGrabberCB, IMFClockStateSink),
+ { 0 }
+ };
+ return QISearch(this, qit, riid, ppv);
+ }
+
+ STDMETHODIMP_(ULONG) MFCodecTopologySampleGrabberCB::AddRef() {
+ return InterlockedIncrement(&m_cRef);
+ }
+
+ STDMETHODIMP_(ULONG) MFCodecTopologySampleGrabberCB::Release() {
+ ULONG cRef = InterlockedDecrement(&m_cRef);
+ if (cRef == 0) {
+ delete this;
+ }
+ return cRef;
+
+ }
+
+ // IMFClockStateSink methods
+
+ STDMETHODIMP MFCodecTopologySampleGrabberCB::OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset) {
+ TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnClockStart(%lld, %lld)", hnsSystemTime, llClockStartOffset);
+ return S_OK;
+ }
+
+ STDMETHODIMP MFCodecTopologySampleGrabberCB::OnClockStop(MFTIME hnsSystemTime) {
+ TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnClockStop(%lld)", hnsSystemTime);
+ return S_OK;
+ }
+
+ STDMETHODIMP MFCodecTopologySampleGrabberCB::OnClockPause(MFTIME hnsSystemTime) {
+ TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnClockPause(%lld)", hnsSystemTime);
+ return S_OK;
+ }
+
+ STDMETHODIMP MFCodecTopologySampleGrabberCB::OnClockRestart(MFTIME hnsSystemTime) {
+ TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnClockRestart(%lld)", hnsSystemTime);
+ return S_OK;
+ }
+
+ STDMETHODIMP MFCodecTopologySampleGrabberCB::OnClockSetRate(MFTIME hnsSystemTime, float flRate) {
+ TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnClockSetRate(%lld, %f)", hnsSystemTime, flRate);
+ return S_OK;
+ }
+
+ // IMFSampleGrabberSink methods.
+
+ STDMETHODIMP MFCodecTopologySampleGrabberCB::OnSetPresentationClock(IMFPresentationClock* pClock) {
+ TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnSetPresentationClock");
+ return S_OK;
+ }
+
+ STDMETHODIMP MFCodecTopologySampleGrabberCB::OnProcessSample(
+ REFGUID guidMajorMediaType, DWORD dwSampleFlags,
+ LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer,
+ DWORD dwSampleSize) {
+ HRESULT hr = S_OK;
+ IMFSample *pSample = NULL;
+ IMFMediaBuffer* pMediaBuffer = NULL;
+ BYTE* _pcBufferPtr = NULL;
+
+ CHECK_HR(hr = MFUtils::CreateMediaSample(dwSampleSize, &pSample));
+ CHECK_HR(hr = pSample->SetSampleTime(llSampleTime));
+ CHECK_HR(hr = pSample->SetSampleDuration(llSampleDuration));
+ CHECK_HR(hr = pSample->GetBufferByIndex(0, &pMediaBuffer));
+ CHECK_HR(hr = pMediaBuffer->Lock(&_pcBufferPtr, NULL, NULL));
+ memcpy(_pcBufferPtr, pSampleBuffer, dwSampleSize);
+ CHECK_HR(hr = pMediaBuffer->SetCurrentLength(dwSampleSize));
+ CHECK_HR(hr = pMediaBuffer->Unlock());
+
+ m_pCodecTopology->m_SampleQueue.Queue(pSample); // thread-safe
+
bail:
- SafeRelease(&pSample);
- SafeRelease(&pMediaBuffer);
- return hr;
- }
-
- STDMETHODIMP MFCodecTopologySampleGrabberCB::OnShutdown()
- {
- TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnShutdown");
- return S_OK;
- }
+ SafeRelease(&pSample);
+ SafeRelease(&pMediaBuffer);
+ return hr;
+ }
+
+ STDMETHODIMP MFCodecTopologySampleGrabberCB::OnShutdown() {
+ TSK_DEBUG_INFO("MFCodecTopologySampleGrabberCB::OnShutdown");
+ return S_OK;
+ }
};
//
@@ -161,36 +144,36 @@ bail:
MFCodecTopology::MFCodecTopology(MFCodec* pCodec, HRESULT &hr)
-: m_nRefCount(1)
-, m_bInitialized(FALSE)
-, m_bStarted(FALSE)
-, m_pCodec(NULL)
-, m_pSource(NULL)
-, m_pSession(NULL)
-, m_pTopologyFull(NULL)
-, m_pTopologyPartial(NULL)
-, m_pOutputType(NULL)
-, m_pInputType(NULL)
-, m_pGrabberCallback(NULL)
-, m_pGrabberActivate(NULL)
-, m_pTread(NULL)
+ : m_nRefCount(1)
+ , m_bInitialized(FALSE)
+ , m_bStarted(FALSE)
+ , m_pCodec(NULL)
+ , m_pSource(NULL)
+ , m_pSession(NULL)
+ , m_pTopologyFull(NULL)
+ , m_pTopologyPartial(NULL)
+ , m_pOutputType(NULL)
+ , m_pInputType(NULL)
+ , m_pGrabberCallback(NULL)
+ , m_pGrabberActivate(NULL)
+ , m_pTread(NULL)
{
- hr = S_OK;
+ hr = S_OK;
- if(!pCodec)
- {
- CHECK_HR(hr = E_POINTER);
- }
+ if(!pCodec) {
+ CHECK_HR(hr = E_POINTER);
+ }
- m_pCodec = pCodec;
- m_pCodec->AddRef();
+ m_pCodec = pCodec;
+ m_pCodec->AddRef();
-bail: ;
+bail:
+ ;
}
MFCodecTopology::~MFCodecTopology()
{
- DeInitialize();
+ DeInitialize();
}
ULONG MFCodecTopology::AddRef()
@@ -201,8 +184,7 @@ ULONG MFCodecTopology::AddRef()
ULONG MFCodecTopology::Release()
{
ULONG uCount = InterlockedDecrement(&m_nRefCount);
- if (uCount == 0)
- {
+ if (uCount == 0) {
delete this;
}
// For thread safety, return a temporary variable.
@@ -211,245 +193,226 @@ ULONG MFCodecTopology::Release()
HRESULT MFCodecTopology::QueryInterface(REFIID iid, void** ppv)
{
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
HRESULT MFCodecTopology::Start()
{
- HRESULT hr = S_OK;
-
- if(m_bStarted)
- {
- return S_OK;
- }
-
- if(!m_bInitialized)
- {
- CHECK_HR(hr = E_FAIL);
- }
-
- CHECK_HR(hr = MFUtils::RunSession(m_pSession, m_pTopologyFull));
-
- // Start asynchronous watcher thread
- m_bStarted = TRUE;
- int ret = tsk_thread_create(&m_pTread, MFCodecTopology::RunSessionThread, this);
- if(ret != 0)
- {
- TSK_DEBUG_ERROR("Failed to create thread");
- m_bStarted = FALSE;
- if(m_pTread)
- {
- tsk_thread_join(&m_pTread);
- }
- MFUtils::ShutdownSession(m_pSession, m_pSource);
- CHECK_HR(hr = E_FAIL);
- }
-
- // FIXME
- Sleep(2000);
+ HRESULT hr = S_OK;
+
+ if(m_bStarted) {
+ return S_OK;
+ }
+
+ if(!m_bInitialized) {
+ CHECK_HR(hr = E_FAIL);
+ }
+
+ CHECK_HR(hr = MFUtils::RunSession(m_pSession, m_pTopologyFull));
+
+ // Start asynchronous watcher thread
+ m_bStarted = TRUE;
+ int ret = tsk_thread_create(&m_pTread, MFCodecTopology::RunSessionThread, this);
+ if(ret != 0) {
+ TSK_DEBUG_ERROR("Failed to create thread");
+ m_bStarted = FALSE;
+ if(m_pTread) {
+ tsk_thread_join(&m_pTread);
+ }
+ MFUtils::ShutdownSession(m_pSession, m_pSource);
+ CHECK_HR(hr = E_FAIL);
+ }
+
+ // FIXME
+ Sleep(2000);
bail:
- return hr;
+ return hr;
}
HRESULT MFCodecTopology::Stop()
{
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK;
- if(!m_bStarted)
- {
- return S_OK;
- }
+ if(!m_bStarted) {
+ return S_OK;
+ }
- m_bStarted = FALSE;
+ m_bStarted = FALSE;
hr = MFUtils::ShutdownSession(m_pSession, NULL); // stop session to wakeup the asynchronous thread
- if(m_pTread)
- {
+ if(m_pTread) {
tsk_thread_join(&m_pTread);
}
hr = MFUtils::ShutdownSession(NULL, m_pSource);
-
- return hr;
+
+ return hr;
}
HRESULT MFCodecTopology::Initialize()
{
- HRESULT hr = S_OK;
- IMFAttributes* pSessionAttributes = NULL;
+ HRESULT hr = S_OK;
+ IMFAttributes* pSessionAttributes = NULL;
- if(m_bInitialized)
- {
- CHECK_HR(hr = E_FAIL);
- }
+ if(m_bInitialized) {
+ CHECK_HR(hr = E_FAIL);
+ }
- // Set session attributes
- CHECK_HR(hr = MFCreateAttributes(&pSessionAttributes, 1));
- CHECK_HR(hr = pSessionAttributes->SetUINT32(PLUGIN_MF_LOW_LATENCY, 1));
+ // Set session attributes
+ CHECK_HR(hr = MFCreateAttributes(&pSessionAttributes, 1));
+ CHECK_HR(hr = pSessionAttributes->SetUINT32(PLUGIN_MF_LOW_LATENCY, 1));
- // Get input and output type
- CHECK_HR(hr = m_pCodec->GetInputType(&m_pInputType));
- CHECK_HR(hr = m_pCodec->GetOutputType(&m_pOutputType));
+ // Get input and output type
+ CHECK_HR(hr = m_pCodec->GetInputType(&m_pInputType));
+ CHECK_HR(hr = m_pCodec->GetOutputType(&m_pOutputType));
- // Create custom source
- CHECK_HR(hr = CMFSource::CreateInstanceEx(IID_IMFMediaSource, (void**)&m_pSource, m_pInputType));
+ // Create custom source
+ CHECK_HR(hr = CMFSource::CreateInstanceEx(IID_IMFMediaSource, (void**)&m_pSource, m_pInputType));
- // Create the sample grabber sink.
- CHECK_HR(hr = MFCodecTopologySampleGrabberCB::CreateInstance(this, &m_pGrabberCallback));
- CHECK_HR(hr = MFCreateSampleGrabberSinkActivate(m_pOutputType, m_pGrabberCallback, &m_pGrabberActivate));
+ // Create the sample grabber sink.
+ CHECK_HR(hr = MFCodecTopologySampleGrabberCB::CreateInstance(this, &m_pGrabberCallback));
+ CHECK_HR(hr = MFCreateSampleGrabberSinkActivate(m_pOutputType, m_pGrabberCallback, &m_pGrabberActivate));
- // To run as fast as possible, set this attribute (requires Windows 7 or later):
- CHECK_HR(hr = m_pGrabberActivate->SetUINT32(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, TRUE));
+ // To run as fast as possible, set this attribute (requires Windows 7 or later):
+ CHECK_HR(hr = m_pGrabberActivate->SetUINT32(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, TRUE));
- // Create the Media Session.
- CHECK_HR(hr = MFCreateMediaSession(pSessionAttributes, &m_pSession));
+ // Create the Media Session.
+ CHECK_HR(hr = MFCreateMediaSession(pSessionAttributes, &m_pSession));
- // Create the topology.
- CHECK_HR(hr = MFUtils::CreateTopology(
- m_pSource,
- m_pCodec->GetMFT(),
- m_pGrabberActivate,
- NULL, // no preview
- m_pOutputType,
- &m_pTopologyPartial));
- // Resolve topology (adds video processors if needed).
- CHECK_HR(hr = MFUtils::ResolveTopology(m_pTopologyPartial, &m_pTopologyFull));
+ // Create the topology.
+ CHECK_HR(hr = MFUtils::CreateTopology(
+ m_pSource,
+ m_pCodec->GetMFT(),
+ m_pGrabberActivate,
+ NULL, // no preview
+ m_pOutputType,
+ &m_pTopologyPartial));
+ // Resolve topology (adds video processors if needed).
+ CHECK_HR(hr = MFUtils::ResolveTopology(m_pTopologyPartial, &m_pTopologyFull));
- m_bInitialized = TRUE;
+ m_bInitialized = TRUE;
bail:
- SafeRelease(&pSessionAttributes);
+ SafeRelease(&pSessionAttributes);
- if(FAILED(hr))
- {
- DeInitialize();
- }
+ if(FAILED(hr)) {
+ DeInitialize();
+ }
- return hr;
+ return hr;
}
void* TSK_STDCALL MFCodecTopology::RunSessionThread(void *pArg)
{
- MFCodecTopology *pSelf = (MFCodecTopology *)pArg;
- HRESULT hrStatus = S_OK;
- HRESULT hr = S_OK;
- IMFMediaEvent *pEvent = NULL;
- MediaEventType met;
-
- TSK_DEBUG_INFO("RunSessionThread (MFCodecTopology) - ENTER");
-
- while(pSelf->isStarted())
- {
- CHECK_HR(hr = pSelf->m_pSession->GetEvent(0, &pEvent));
- CHECK_HR(hr = pEvent->GetStatus(&hrStatus));
- CHECK_HR(hr = pEvent->GetType(&met));
-
- if (FAILED(hrStatus) /*&& hrStatus != MF_E_NO_SAMPLE_TIMESTAMP*/)
- {
- TSK_DEBUG_ERROR("Session error: 0x%x (event id: %d)\n", hrStatus, met);
- hr = hrStatus;
- goto bail;
- }
- if (met == MESessionEnded)
- {
- break;
- }
- SafeRelease(&pEvent);
- }
+ MFCodecTopology *pSelf = (MFCodecTopology *)pArg;
+ HRESULT hrStatus = S_OK;
+ HRESULT hr = S_OK;
+ IMFMediaEvent *pEvent = NULL;
+ MediaEventType met;
+
+ TSK_DEBUG_INFO("RunSessionThread (MFCodecTopology) - ENTER");
+
+ while(pSelf->isStarted()) {
+ CHECK_HR(hr = pSelf->m_pSession->GetEvent(0, &pEvent));
+ CHECK_HR(hr = pEvent->GetStatus(&hrStatus));
+ CHECK_HR(hr = pEvent->GetType(&met));
+
+ if (FAILED(hrStatus) /*&& hrStatus != MF_E_NO_SAMPLE_TIMESTAMP*/) {
+ TSK_DEBUG_ERROR("Session error: 0x%x (event id: %d)\n", hrStatus, met);
+ hr = hrStatus;
+ goto bail;
+ }
+ if (met == MESessionEnded) {
+ break;
+ }
+ SafeRelease(&pEvent);
+ }
bail:
- TSK_DEBUG_INFO("RunSessionThread (MFCodecTopology) - EXIT");
+ TSK_DEBUG_INFO("RunSessionThread (MFCodecTopology) - EXIT");
- return NULL;
+ return NULL;
}
HRESULT MFCodecTopology::DeInitialize()
{
- Stop();
-
- SafeRelease(&m_pCodec);
- SafeRelease(&m_pSource);
- SafeRelease(&m_pCodec);
- SafeRelease(&m_pSession);
- SafeRelease(&m_pTopologyFull);
- SafeRelease(&m_pTopologyPartial);
- SafeRelease(&m_pOutputType);
- SafeRelease(&m_pInputType);
- SafeRelease(&m_pGrabberCallback);
- SafeRelease(&m_pGrabberActivate);
-
- if(m_pTread)
- {
- tsk_thread_join(&m_pTread);
- }
+ Stop();
+
+ SafeRelease(&m_pCodec);
+ SafeRelease(&m_pSource);
+ SafeRelease(&m_pCodec);
+ SafeRelease(&m_pSession);
+ SafeRelease(&m_pTopologyFull);
+ SafeRelease(&m_pTopologyPartial);
+ SafeRelease(&m_pOutputType);
+ SafeRelease(&m_pInputType);
+ SafeRelease(&m_pGrabberCallback);
+ SafeRelease(&m_pGrabberActivate);
+
+ if(m_pTread) {
+ tsk_thread_join(&m_pTread);
+ }
- m_SampleQueue.Clear();
+ m_SampleQueue.Clear();
- m_bInitialized = FALSE;
+ m_bInitialized = FALSE;
- return S_OK;
+ return S_OK;
}
HRESULT MFCodecTopology::ProcessInput(IMFSample* pSample)
{
- HRESULT hr = S_OK;
- IMFMediaBuffer* pMediaBuffer = NULL;
- BYTE* _pcBufferPtr = NULL;
-
- if(!pSample)
- {
- CHECK_HR(hr = E_POINTER);
- }
-
- if(m_pCodec->GetMediaType() != MFCodecMediaType_Video)
- {
- CHECK_HR(hr = E_NOTIMPL);
- }
-
- if(!m_bStarted)
- {
- CHECK_HR(hr = Start());
- }
-
- CHECK_HR(hr = pSample->GetBufferByIndex(0, &pMediaBuffer));
-
- DWORD dwDataLength = 0;
- BOOL bLocked = FALSE;
- CHECK_HR(hr = pMediaBuffer->GetCurrentLength(&dwDataLength));
- bLocked = TRUE;
- if(dwDataLength > 0)
- {
- CHECK_HR(hr = pMediaBuffer->Lock(&_pcBufferPtr, NULL, NULL));
- CHECK_HR(hr = m_pSource->CopyVideoBuffer(
- dynamic_cast<MFCodecVideo*>(m_pCodec)->GetWidth(),
- dynamic_cast<MFCodecVideo*>(m_pCodec)->GetHeight(),
- _pcBufferPtr, dwDataLength));
- }
+ HRESULT hr = S_OK;
+ IMFMediaBuffer* pMediaBuffer = NULL;
+ BYTE* _pcBufferPtr = NULL;
+
+ if(!pSample) {
+ CHECK_HR(hr = E_POINTER);
+ }
+
+ if(m_pCodec->GetMediaType() != MFCodecMediaType_Video) {
+ CHECK_HR(hr = E_NOTIMPL);
+ }
+
+ if(!m_bStarted) {
+ CHECK_HR(hr = Start());
+ }
+
+ CHECK_HR(hr = pSample->GetBufferByIndex(0, &pMediaBuffer));
+
+ DWORD dwDataLength = 0;
+ BOOL bLocked = FALSE;
+ CHECK_HR(hr = pMediaBuffer->GetCurrentLength(&dwDataLength));
+ bLocked = TRUE;
+ if(dwDataLength > 0) {
+ CHECK_HR(hr = pMediaBuffer->Lock(&_pcBufferPtr, NULL, NULL));
+ CHECK_HR(hr = m_pSource->CopyVideoBuffer(
+ dynamic_cast<MFCodecVideo*>(m_pCodec)->GetWidth(),
+ dynamic_cast<MFCodecVideo*>(m_pCodec)->GetHeight(),
+ _pcBufferPtr, dwDataLength));
+ }
bail:
- if(bLocked)
- {
- pMediaBuffer->Unlock();
- }
- SafeRelease(&pMediaBuffer);
- return hr;
+ if(bLocked) {
+ pMediaBuffer->Unlock();
+ }
+ SafeRelease(&pMediaBuffer);
+ return hr;
}
HRESULT MFCodecTopology::ProcessOutput(IMFSample **ppSample)
{
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK;
- if(!ppSample)
- {
- CHECK_HR(hr = E_POINTER);
- }
+ if(!ppSample) {
+ CHECK_HR(hr = E_POINTER);
+ }
- if(!m_SampleQueue.IsEmpty())
- {
- CHECK_HR(hr = m_SampleQueue.Dequeue(ppSample)); // thread-safe
- }
+ if(!m_SampleQueue.IsEmpty()) {
+ CHECK_HR(hr = m_SampleQueue.Dequeue(ppSample)); // thread-safe
+ }
bail:
- return hr;
+ return hr;
}
//
@@ -458,11 +421,11 @@ bail:
MFCodecVideoTopology::MFCodecVideoTopology(MFCodec* pCodec, HRESULT &hr)
-: MFCodecTopology(pCodec, hr)
-, m_nWidth(0)
-, m_nHeight(0)
+ : MFCodecTopology(pCodec, hr)
+ , m_nWidth(0)
+ , m_nHeight(0)
{
- assert(pCodec->GetMediaType() == MFCodecMediaType_Video);
+ assert(pCodec->GetMediaType() == MFCodecMediaType_Video);
}
MFCodecVideoTopology::~MFCodecVideoTopology()
diff --git a/plugins/pluginWinMF/internals/mf_codec_topology.h b/plugins/pluginWinMF/internals/mf_codec_topology.h
index c5d2f34..6a4bb94 100755
--- a/plugins/pluginWinMF/internals/mf_codec_topology.h
+++ b/plugins/pluginWinMF/internals/mf_codec_topology.h
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -28,59 +28,63 @@ class MFCodecTopologySampleGrabberCB;
class MFCodecTopology : IUnknown
{
- friend class MFCodecTopologySampleGrabberCB;
+ friend class MFCodecTopologySampleGrabberCB;
public:
- MFCodecTopology(MFCodec* pCodec, HRESULT &hr);
- virtual ~MFCodecTopology();
+ MFCodecTopology(MFCodec* pCodec, HRESULT &hr);
+ virtual ~MFCodecTopology();
- virtual HRESULT Initialize();
- virtual HRESULT DeInitialize();
+ virtual HRESULT Initialize();
+ virtual HRESULT DeInitialize();
- virtual HRESULT ProcessInput(IMFSample* pSample);
- virtual HRESULT ProcessOutput(IMFSample **ppSample);
+ virtual HRESULT ProcessInput(IMFSample* pSample);
+ virtual HRESULT ProcessOutput(IMFSample **ppSample);
- // IUnknown
+ // IUnknown
STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
- inline BOOL isStarted() { return m_bStarted; }
- inline BOOL isInitialized() { return m_bInitialized; }
+ inline BOOL isStarted() {
+ return m_bStarted;
+ }
+ inline BOOL isInitialized() {
+ return m_bInitialized;
+ }
private:
- static void* TSK_STDCALL RunSessionThread(void *pArg);
+ static void* TSK_STDCALL RunSessionThread(void *pArg);
protected:
- HRESULT Start();
- HRESULT Stop();
+ HRESULT Start();
+ HRESULT Stop();
private:
- long m_nRefCount;
+ long m_nRefCount;
protected:
- BOOL m_bInitialized;
- BOOL m_bStarted;
- MFCodec* m_pCodec;
- CMFSource *m_pSource;
- IMFMediaSession *m_pSession;
+ BOOL m_bInitialized;
+ BOOL m_bStarted;
+ MFCodec* m_pCodec;
+ CMFSource *m_pSource;
+ IMFMediaSession *m_pSession;
IMFTopology *m_pTopologyFull;
- IMFTopology *m_pTopologyPartial;
- IMFMediaType *m_pOutputType;
- IMFMediaType *m_pInputType;
- MFCodecTopologySampleGrabberCB *m_pGrabberCallback;
+ IMFTopology *m_pTopologyPartial;
+ IMFMediaType *m_pOutputType;
+ IMFMediaType *m_pInputType;
+ MFCodecTopologySampleGrabberCB *m_pGrabberCallback;
IMFActivate *m_pGrabberActivate;
- tsk_thread_handle_t* m_pTread;
- SampleQueue m_SampleQueue;
+ tsk_thread_handle_t* m_pTread;
+ SampleQueue m_SampleQueue;
};
class MFCodecVideoTopology : public MFCodecTopology
{
public:
- MFCodecVideoTopology(MFCodec* pCodec, HRESULT &hr);
- virtual ~MFCodecVideoTopology();
+ MFCodecVideoTopology(MFCodec* pCodec, HRESULT &hr);
+ virtual ~MFCodecVideoTopology();
private:
- UINT32 m_nWidth, m_nHeight;
+ UINT32 m_nWidth, m_nHeight;
};
diff --git a/plugins/pluginWinMF/internals/mf_custom_src.cxx b/plugins/pluginWinMF/internals/mf_custom_src.cxx
index 1de9904..186887e 100755
--- a/plugins/pluginWinMF/internals/mf_custom_src.cxx
+++ b/plugins/pluginWinMF/internals/mf_custom_src.cxx
@@ -1,20 +1,20 @@
-/*
+/*
* Copyright (C) Microsoft Corporation. All rights reserved.
* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -63,7 +63,7 @@ LONGLONG BufferSizeFromAudioDuration(const WAVEFORMATEX *pWav, LONGLONG duration
HRESULT CMFSource_CreateInstance(REFIID iid, void **ppMFT)
{
- return CMFSource::CreateInstance(iid, ppMFT);
+ return CMFSource::CreateInstance(iid, ppMFT);
}
@@ -77,30 +77,26 @@ HRESULT CMFSource_CreateInstance(REFIID iid, void **ppMFT)
HRESULT CMFSource::CreateInstance(REFIID iid, void **ppSource) // Called when source used as plugin
{
- return CreateInstanceEx(iid, ppSource, NULL);
+ return CreateInstanceEx(iid, ppSource, NULL);
}
HRESULT CMFSource::CreateInstanceEx(REFIID iid, void **ppSource, IMFMediaType *pMediaType) // Called when source directly called
{
- if (ppSource == NULL)
- {
+ if (ppSource == NULL) {
return E_POINTER;
}
HRESULT hr = S_OK;
CMFSource *pSource = new (std::nothrow) CMFSource(hr, pMediaType); // Created with ref count = 1.
- if (pSource == NULL)
- {
+ if (pSource == NULL) {
return E_OUTOFMEMORY;
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pSource->QueryInterface(iid, ppSource);
- if(SUCCEEDED(hr))
- {
- ((CMFSource*)(*ppSource))->AddRef();
- }
+ if(SUCCEEDED(hr)) {
+ ((CMFSource*)(*ppSource))->AddRef();
+ }
}
SafeRelease(&pSource);
@@ -115,22 +111,21 @@ HRESULT CMFSource::CreateInstanceEx(REFIID iid, void **ppSource, IMFMediaType *p
//-------------------------------------------------------------------
CMFSource::CMFSource(HRESULT& hr, IMFMediaType *pMediaType)
- : m_nRefCount(1),
- m_pEventQueue(NULL),
- m_pPresentationDescriptor(NULL),
- m_IsShutdown(FALSE),
- m_state(STATE_STOPPED),
- m_pStream(NULL),
- m_pMediaType(NULL)
+ : m_nRefCount(1),
+ m_pEventQueue(NULL),
+ m_pPresentationDescriptor(NULL),
+ m_IsShutdown(FALSE),
+ m_state(STATE_STOPPED),
+ m_pStream(NULL),
+ m_pMediaType(NULL)
{
// Create the media event queue.
hr = MFCreateEventQueue(&m_pEventQueue);
- if(pMediaType)
- {
- m_pMediaType = pMediaType;
- pMediaType->AddRef();
- }
+ if(pMediaType) {
+ m_pMediaType = pMediaType;
+ pMediaType->AddRef();
+ }
InitializeCriticalSection(&m_critSec);
}
@@ -145,7 +140,7 @@ CMFSource::~CMFSource()
{
assert(m_IsShutdown);
assert(m_nRefCount == 0);
- SafeRelease(&m_pMediaType);
+ SafeRelease(&m_pMediaType);
DeleteCriticalSection(&m_critSec);
}
@@ -154,26 +149,22 @@ CMFSource::~CMFSource()
HRESULT CMFSource::CopyVideoBuffer(UINT32 nWidth, UINT32 nHeight, const void* pBufferPtr, UINT32 nBufferSize)
{
- if(!pBufferPtr)
- {
- TSK_DEBUG_ERROR("Invalid buffer pointer");
- return E_POINTER;
- }
-
- if(!nWidth || !nHeight || !nBufferSize)
- {
- TSK_DEBUG_ERROR("Invalid parameter");
- return E_INVALIDARG;
- }
- if(m_pStream)
- {
- return m_pStream->CopyVideoBuffer(nWidth, nHeight, pBufferPtr, nBufferSize);
- }
- else
- {
- TSK_DEBUG_ERROR("No stream associated to this source");
- return E_NOT_VALID_STATE;
- }
+ if(!pBufferPtr) {
+ TSK_DEBUG_ERROR("Invalid buffer pointer");
+ return E_POINTER;
+ }
+
+ if(!nWidth || !nHeight || !nBufferSize) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return E_INVALIDARG;
+ }
+ if(m_pStream) {
+ return m_pStream->CopyVideoBuffer(nWidth, nHeight, pBufferPtr, nBufferSize);
+ }
+ else {
+ TSK_DEBUG_ERROR("No stream associated to this source");
+ return E_NOT_VALID_STATE;
+ }
}
// IUnknown methods
@@ -186,8 +177,7 @@ ULONG CMFSource::AddRef()
ULONG CMFSource::Release()
{
ULONG uCount = InterlockedDecrement(&m_nRefCount);
- if (uCount == 0)
- {
+ if (uCount == 0) {
delete this;
}
// For thread safety, return a temporary variable.
@@ -196,8 +186,7 @@ ULONG CMFSource::Release()
HRESULT CMFSource::QueryInterface(REFIID iid, void** ppv)
{
- static const QITAB qit[] =
- {
+ static const QITAB qit[] = {
QITABENT(CMFSource, IMFMediaEventGenerator),
QITABENT(CMFSource, IMFMediaSource),
{ 0 }
@@ -220,8 +209,7 @@ HRESULT CMFSource::BeginGetEvent(IMFAsyncCallback* pCallback, IUnknown* punkStat
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = m_pEventQueue->BeginGetEvent(pCallback, punkState);
}
@@ -238,8 +226,7 @@ HRESULT CMFSource::EndGetEvent(IMFAsyncResult* pResult, IMFMediaEvent** ppEvent)
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = m_pEventQueue->EndGetEvent(pResult, ppEvent);
}
@@ -263,16 +250,14 @@ HRESULT CMFSource::GetEvent(DWORD dwFlags, IMFMediaEvent** ppEvent)
// Check shutdown
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
pQueue = m_pEventQueue;
pQueue->AddRef();
}
LeaveCriticalSection(&m_critSec);
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pQueue->GetEvent(dwFlags, ppEvent);
}
@@ -288,8 +273,7 @@ HRESULT CMFSource::QueueEvent(MediaEventType met, REFGUID guidExtendedType, HRES
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = m_pEventQueue->QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue);
}
@@ -309,8 +293,7 @@ HRESULT CMFSource::QueueEvent(MediaEventType met, REFGUID guidExtendedType, HRES
HRESULT CMFSource::CreatePresentationDescriptor(IMFPresentationDescriptor** ppPresentationDescriptor)
{
- if (ppPresentationDescriptor == NULL)
- {
+ if (ppPresentationDescriptor == NULL) {
return E_POINTER;
}
@@ -320,17 +303,14 @@ HRESULT CMFSource::CreatePresentationDescriptor(IMFPresentationDescriptor** ppPr
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
- if (m_pPresentationDescriptor == NULL)
- {
+ if (SUCCEEDED(hr)) {
+ if (m_pPresentationDescriptor == NULL) {
hr = CreatePresentationDescriptor();
}
}
// Clone our default presentation descriptor.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = m_pPresentationDescriptor->Clone(ppPresentationDescriptor);
}
@@ -347,8 +327,7 @@ HRESULT CMFSource::CreatePresentationDescriptor(IMFPresentationDescriptor** ppPr
HRESULT CMFSource::GetCharacteristics(DWORD* pdwCharacteristics)
{
- if (pdwCharacteristics == NULL)
- {
+ if (pdwCharacteristics == NULL) {
return E_POINTER;
}
@@ -358,8 +337,7 @@ HRESULT CMFSource::GetCharacteristics(DWORD* pdwCharacteristics)
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
*pdwCharacteristics = MFMEDIASOURCE_CAN_PAUSE | MFMEDIASOURCE_IS_LIVE;
}
@@ -377,7 +355,7 @@ HRESULT CMFSource::Start(
IMFPresentationDescriptor* pPresentationDescriptor,
const GUID* pguidTimeFormat,
const PROPVARIANT* pvarStartPosition
- )
+)
{
HRESULT hr = S_OK;
LONGLONG llStartOffset = 0;
@@ -392,14 +370,12 @@ HRESULT CMFSource::Start(
// Check parameters.
// Start position and presentation descriptor cannot be NULL.
- if (pvarStartPosition == NULL || pPresentationDescriptor == NULL)
- {
+ if (pvarStartPosition == NULL || pPresentationDescriptor == NULL) {
return E_INVALIDARG;
}
// Check the time format. Must be "reference time" units.
- if ((pguidTimeFormat != NULL) && (*pguidTimeFormat != GUID_NULL))
- {
+ if ((pguidTimeFormat != NULL) && (*pguidTimeFormat != GUID_NULL)) {
// Unrecognized time format GUID.
return MF_E_UNSUPPORTED_TIME_FORMAT;
}
@@ -410,33 +386,27 @@ HRESULT CMFSource::Start(
CHECK_HR(hr = CheckShutdown());
// Check the start position.
- if (pvarStartPosition->vt == VT_I8)
- {
+ if (pvarStartPosition->vt == VT_I8) {
// Start position is given in pvarStartPosition in 100-ns units.
llStartOffset = pvarStartPosition->hVal.QuadPart;
- if (m_state != STATE_STOPPED)
- {
+ if (m_state != STATE_STOPPED) {
// Source is running or paused, so this is a seek.
bIsSeek = TRUE;
}
}
- else if (pvarStartPosition->vt == VT_EMPTY)
- {
+ else if (pvarStartPosition->vt == VT_EMPTY) {
// Start position is "current position".
// For stopped, that means 0. Otherwise, use the current position.
- if (m_state == STATE_STOPPED)
- {
+ if (m_state == STATE_STOPPED) {
llStartOffset = 0;
}
- else
- {
+ else {
llStartOffset = GetCurrentPosition();
bIsRestartFromCurrentPosition = TRUE;
}
}
- else
- {
+ else {
// We don't support this time format.
hr = MF_E_UNSUPPORTED_TIME_FORMAT;
goto bail;
@@ -457,12 +427,10 @@ HRESULT CMFSource::Start(
var.hVal.QuadPart = llStartOffset;
// Send the source event.
- if (bIsSeek)
- {
+ if (bIsSeek) {
CHECK_HR(hr = QueueEvent(MESourceSeeked, GUID_NULL, hr, &var));
}
- else
- {
+ else {
// For starting, if we are RESTARTING from the current position and our
// previous state was running/paused, then we need to add the
// MF_EVENT_SOURCE_ACTUAL_START attribute to the event. This requires
@@ -472,8 +440,7 @@ HRESULT CMFSource::Start(
CHECK_HR(hr = MFCreateMediaEvent(MESourceStarted, GUID_NULL, hr, &var, &pEvent));
// For restarts, set the actual start time as an attribute.
- if (bIsRestartFromCurrentPosition)
- {
+ if (bIsRestartFromCurrentPosition) {
CHECK_HR(hr = pEvent->SetUINT64(MF_EVENT_SOURCE_ACTUAL_START, llStartOffset));
}
@@ -484,31 +451,26 @@ HRESULT CMFSource::Start(
bQueuedStartEvent = TRUE;
// Send the stream event.
- if (m_pStream)
- {
- if (bIsSeek)
- {
+ if (m_pStream) {
+ if (bIsSeek) {
CHECK_HR(hr = m_pStream->QueueEvent(MEStreamSeeked, GUID_NULL, hr, &var));
}
- else
- {
+ else {
CHECK_HR(hr = m_pStream->QueueEvent(MEStreamStarted, GUID_NULL, hr, &var));
}
}
- if (bIsSeek)
- {
+ if (bIsSeek) {
// For seek requests, flush any queued samples.
CHECK_HR(hr = m_pStream->Flush());
}
- else
- {
+ else {
// Otherwise, deliver any queued samples.
CHECK_HR(hr = m_pStream->DeliverQueuedSamples());
}
- // Initialize Stream parameters
- CHECK_HR(hr = m_pStream->InitializeParams());
+ // Initialize Stream parameters
+ CHECK_HR(hr = m_pStream->InitializeParams());
m_state = STATE_STARTED;
@@ -522,8 +484,7 @@ bail:
// event (with a success code), then we need to raise an
// MEError event.
- if (FAILED(hr) && bQueuedStartEvent)
- {
+ if (FAILED(hr) && bQueuedStartEvent) {
hr = QueueEvent(MEError, GUID_NULL, hr, &var);
}
@@ -531,7 +492,7 @@ bail:
SafeRelease(&pEvent);
LeaveCriticalSection(&m_critSec);
-
+
return hr;
}
@@ -550,31 +511,25 @@ HRESULT CMFSource::Pause()
hr = CheckShutdown();
// Pause is only allowed from started state.
- if (SUCCEEDED(hr))
- {
- if (m_state != STATE_STARTED)
- {
+ if (SUCCEEDED(hr)) {
+ if (m_state != STATE_STARTED) {
hr = MF_E_INVALID_STATE_TRANSITION;
}
}
// Send the appropriate events.
- if (SUCCEEDED(hr))
- {
- if (m_pStream)
- {
+ if (SUCCEEDED(hr)) {
+ if (m_pStream) {
hr = m_pStream->QueueEvent(MEStreamPaused, GUID_NULL, S_OK, NULL);
}
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = QueueEvent(MESourcePaused, GUID_NULL, S_OK, NULL);
}
// Update our state.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
m_state = STATE_PAUSED;
}
@@ -597,8 +552,7 @@ HRESULT CMFSource::Stop()
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
// Update our state.
m_state = STATE_STOPPED;
@@ -610,15 +564,12 @@ HRESULT CMFSource::Stop()
// Queue events.
//
- if (SUCCEEDED(hr))
- {
- if (m_pStream)
- {
+ if (SUCCEEDED(hr)) {
+ if (m_pStream) {
hr = m_pStream->QueueEvent(MEStreamStopped, GUID_NULL, S_OK, NULL);
}
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = QueueEvent(MESourceStopped, GUID_NULL, S_OK, NULL);
}
@@ -645,17 +596,14 @@ HRESULT CMFSource::Shutdown()
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
// Shut down the stream object.
- if (m_pStream)
- {
+ if (m_pStream) {
(void)m_pStream->Shutdown();
}
// Shut down the event queue.
- if (m_pEventQueue)
- {
+ if (m_pEventQueue) {
(void)m_pEventQueue->Shutdown();
}
@@ -694,44 +642,39 @@ HRESULT CMFSource::CreatePresentationDescriptor()
// Create the stream descriptor.
hr = MFCreateStreamDescriptor(
- 0, // stream identifier
- 1, // Number of media types.
- &m_pMediaType, // Array of media types
- &pStreamDescriptor
- );
+ 0, // stream identifier
+ 1, // Number of media types.
+ &m_pMediaType, // Array of media types
+ &pStreamDescriptor
+ );
// Set the default media type on the media type handler.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pStreamDescriptor->GetMediaTypeHandler(&pHandler);
}
-
- if (SUCCEEDED(hr))
- {
- hr = pHandler->SetCurrentMediaType(m_pMediaType);
+
+ if (SUCCEEDED(hr)) {
+ hr = pHandler->SetCurrentMediaType(m_pMediaType);
}
// Create the presentation descriptor.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = MFCreatePresentationDescriptor(
- 1, // Number of stream descriptors
- &pStreamDescriptor, // Array of stream descriptors
- &m_pPresentationDescriptor
- );
+ 1, // Number of stream descriptors
+ &pStreamDescriptor, // Array of stream descriptors
+ &m_pPresentationDescriptor
+ );
}
// Select the first stream
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = m_pPresentationDescriptor->SelectStream(0);
}
// Set the file/stream duration as an attribute on the presentation descriptor.
- if (SUCCEEDED(hr))
- {
- hr = m_pPresentationDescriptor->SetUINT64(MF_PD_DURATION, (UINT64)ULLONG_MAX);
+ if (SUCCEEDED(hr)) {
+ hr = m_pPresentationDescriptor->SetUINT64(MF_PD_DURATION, (UINT64)ULLONG_MAX);
}
-
+
SafeRelease(&pStreamDescriptor);
SafeRelease(&pHandler);
return hr;
@@ -764,7 +707,7 @@ HRESULT CMFSource::ValidatePresentationDescriptor(IMFPresentationDescriptor *pPD
IMFStreamDescriptor *pStreamDescriptor = NULL;
IMFMediaTypeHandler *pHandler = NULL;
IMFMediaType *pMediaType = NULL;
- GUID majorType;
+ GUID majorType;
DWORD cStreamDescriptors = 0;
BOOL fSelected = FALSE;
@@ -772,85 +715,71 @@ HRESULT CMFSource::ValidatePresentationDescriptor(IMFPresentationDescriptor *pPD
// Make sure there is only one stream.
hr = pPD->GetStreamDescriptorCount(&cStreamDescriptors);
- if (SUCCEEDED(hr))
- {
- if (cStreamDescriptors != 1)
- {
+ if (SUCCEEDED(hr)) {
+ if (cStreamDescriptors != 1) {
hr = MF_E_UNSUPPORTED_REPRESENTATION;
}
}
// Get the stream descriptor.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pStreamDescriptor);
}
// Make sure it's selected. (This media source has only one stream, so it
// is not useful to deselect the only stream.)
- if (SUCCEEDED(hr))
- {
- if (!fSelected)
- {
+ if (SUCCEEDED(hr)) {
+ if (!fSelected) {
hr = MF_E_UNSUPPORTED_REPRESENTATION;
}
}
// Get the media type handler, so that we can get the media type.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pStreamDescriptor->GetMediaTypeHandler(&pHandler);
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pHandler->GetCurrentMediaType(&pMediaType);
}
- hr = pMediaType->GetMajorType(&majorType);
-
- if (SUCCEEDED(hr))
- {
- if(majorType == MFMediaType_Video)
- {
- if (SUCCEEDED(hr))
- {
- hr = MFUtils::ValidateVideoFormat(pMediaType);
- }
- }
- else
- {
- WAVEFORMATEX *pFormat = NULL;
- UINT32 cbWaveFormat = 0;
-
- if (SUCCEEDED(hr))
- {
- hr = MFCreateWaveFormatExFromMFMediaType(
- pMediaType,
- &pFormat,
- &cbWaveFormat);
- }
- if (SUCCEEDED(hr))
- {
- /*assert(this->WaveFormat() != NULL);
-
- if (cbWaveFormat < this->WaveFormatSize())
- {
- hr = MF_E_INVALIDMEDIATYPE;
- }*/
- }
-
- if (SUCCEEDED(hr))
- {
- /*if (memcmp(pFormat, WaveFormat(), WaveFormatSize()) != 0)
- {
- hr = MF_E_INVALIDMEDIATYPE;
- }*/
- }
-
- CoTaskMemFree(pFormat);
- }
- }
+ hr = pMediaType->GetMajorType(&majorType);
+
+ if (SUCCEEDED(hr)) {
+ if(majorType == MFMediaType_Video) {
+ if (SUCCEEDED(hr)) {
+ hr = MFUtils::ValidateVideoFormat(pMediaType);
+ }
+ }
+ else {
+ WAVEFORMATEX *pFormat = NULL;
+ UINT32 cbWaveFormat = 0;
+
+ if (SUCCEEDED(hr)) {
+ hr = MFCreateWaveFormatExFromMFMediaType(
+ pMediaType,
+ &pFormat,
+ &cbWaveFormat);
+ }
+ if (SUCCEEDED(hr)) {
+ /*assert(this->WaveFormat() != NULL);
+
+ if (cbWaveFormat < this->WaveFormatSize())
+ {
+ hr = MF_E_INVALIDMEDIATYPE;
+ }*/
+ }
+
+ if (SUCCEEDED(hr)) {
+ /*if (memcmp(pFormat, WaveFormat(), WaveFormatSize()) != 0)
+ {
+ hr = MF_E_INVALIDMEDIATYPE;
+ }*/
+ }
+
+ CoTaskMemFree(pFormat);
+ }
+ }
SafeRelease(&pStreamDescriptor);
SafeRelease(&pHandler);
@@ -882,27 +811,23 @@ HRESULT CMFSource::QueueNewStreamEvent(IMFPresentationDescriptor *pPD)
hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD);
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
// The stream must be selected, because we don't allow the app
// to de-select the stream. See ValidatePresentationDescriptor.
assert(fSelected);
- if (m_pStream)
- {
+ if (m_pStream) {
// The stream already exists, and is still selected.
// Send the MEUpdatedStream event.
hr = QueueEventWithIUnknown(this, MEUpdatedStream, S_OK, m_pStream);
}
- else
- {
+ else {
// The stream does not exist, and is now selected.
// Create a new stream.
hr = CreateCMFStreamSource(pSD);
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
// CreateCMFStreamSource creates the stream, so m_pStream is no longer NULL.
assert(m_pStream != NULL);
@@ -926,13 +851,11 @@ HRESULT CMFSource::CreateCMFStreamSource(IMFStreamDescriptor *pSD)
HRESULT hr = S_OK;
m_pStream = new (std::nothrow) CMFStreamSource(this, pSD, hr);
- if (m_pStream == NULL)
- {
+ if (m_pStream == NULL) {
hr = E_OUTOFMEMORY;
}
- if (FAILED(hr))
- {
+ if (FAILED(hr)) {
SafeRelease(&m_pStream);
}
@@ -948,12 +871,10 @@ HRESULT CMFSource::CreateCMFStreamSource(IMFStreamDescriptor *pSD)
LONGLONG CMFSource::GetCurrentPosition() const
{
- if (m_pStream)
- {
+ if (m_pStream) {
return m_pStream->GetCurrentPosition();
}
- else
- {
+ else {
// If no stream is selected, we are at time 0 by definition.
return 0;
}
@@ -977,11 +898,11 @@ CMFStreamSource::CMFStreamSource(CMFSource *pSource, IMFStreamDescriptor *pSD,
m_pEventQueue(NULL),
m_IsShutdown(FALSE),
m_rtCurrentPosition(0),
- m_rtDuration(0),
+ m_rtDuration(0),
m_discontinuity(FALSE),
m_EOS(FALSE),
- m_pMediaBuffer(NULL),
- m_nBufferSize(0)
+ m_pMediaBuffer(NULL),
+ m_nBufferSize(0)
{
m_pSource = pSource;
m_pSource->AddRef();
@@ -992,12 +913,12 @@ CMFStreamSource::CMFStreamSource(CMFSource *pSource, IMFStreamDescriptor *pSD,
// Create the media event queue.
CHECK_HR(hr = MFCreateEventQueue(&m_pEventQueue));
- //CHECK_HR(hr = InitializeParams());
-
+ //CHECK_HR(hr = InitializeParams());
+
InitializeCriticalSection(&m_critSec);
bail:
- return;
+ return;
}
@@ -1010,7 +931,7 @@ CMFStreamSource::~CMFStreamSource()
assert(m_IsShutdown);
assert(m_nRefCount == 0);
- SafeRelease(&m_pMediaBuffer);
+ SafeRelease(&m_pMediaBuffer);
DeleteCriticalSection(&m_critSec);
}
@@ -1020,38 +941,36 @@ CMFStreamSource::~CMFStreamSource()
HRESULT CMFStreamSource::CopyVideoBuffer(UINT32 nWidth, UINT32 nHeight, const void* pBufferPtr, UINT32 nBufferSize)
{
- // Buffer pointer and size validity already checked by source (caller)
- if(m_guidMajorType != MFMediaType_Video)
- {
- TSK_DEBUG_ERROR("Calling CopyVideoBuffer on no-video stream");
+ // Buffer pointer and size validity already checked by source (caller)
+ if(m_guidMajorType != MFMediaType_Video) {
+ TSK_DEBUG_ERROR("Calling CopyVideoBuffer on no-video stream");
#if defined(E_ILLEGAL_METHOD_CALL)
- return E_ILLEGAL_METHOD_CALL;
+ return E_ILLEGAL_METHOD_CALL;
#else
- return _HRESULT_TYPEDEF_(0x8000000EL);
+ return _HRESULT_TYPEDEF_(0x8000000EL);
#endif
- }
- if(nWidth != m_structVideoParams.nWidth || nHeight != m_structVideoParams.nHeigh || nBufferSize != m_nBufferSize)
- {
- TSK_DEBUG_ERROR("Invalid argument %u#%u or %u#%u or %u#%u. If the call is from a video consumer then, you can safely ignore this message.", nWidth, m_structVideoParams.nWidth, nHeight, m_structVideoParams.nHeigh, nBufferSize, m_nBufferSize);
+ }
+ if(nWidth != m_structVideoParams.nWidth || nHeight != m_structVideoParams.nHeigh || nBufferSize != m_nBufferSize) {
+ TSK_DEBUG_ERROR("Invalid argument %u#%u or %u#%u or %u#%u. If the call is from a video consumer then, you can safely ignore this message.", nWidth, m_structVideoParams.nWidth, nHeight, m_structVideoParams.nHeigh, nBufferSize, m_nBufferSize);
#if defined(E_BOUNDS)
- return E_BOUNDS;
+ return E_BOUNDS;
#else
- return _HRESULT_TYPEDEF_(0x8000000BL);
+ return _HRESULT_TYPEDEF_(0x8000000BL);
#endif
- }
-
- HRESULT hr = S_OK;
-
- BYTE* pMediaBufferPtr = NULL;
- DWORD cbMaxLength = nBufferSize, cbCurrentLength = nBufferSize;
- CHECK_HR(hr = m_pMediaBuffer->Lock(&pMediaBufferPtr, &cbMaxLength, &cbCurrentLength));
-
- memcpy(pMediaBufferPtr, pBufferPtr, nBufferSize);
- CHECK_HR(hr = m_pMediaBuffer->SetCurrentLength(nBufferSize));
- CHECK_HR(hr = m_pMediaBuffer->Unlock());
-
+ }
+
+ HRESULT hr = S_OK;
+
+ BYTE* pMediaBufferPtr = NULL;
+ DWORD cbMaxLength = nBufferSize, cbCurrentLength = nBufferSize;
+ CHECK_HR(hr = m_pMediaBuffer->Lock(&pMediaBufferPtr, &cbMaxLength, &cbCurrentLength));
+
+ memcpy(pMediaBufferPtr, pBufferPtr, nBufferSize);
+ CHECK_HR(hr = m_pMediaBuffer->SetCurrentLength(nBufferSize));
+ CHECK_HR(hr = m_pMediaBuffer->Unlock());
+
bail:
- return hr;
+ return hr;
}
// IUnknown methods
@@ -1064,8 +983,7 @@ ULONG CMFStreamSource::AddRef()
ULONG CMFStreamSource::Release()
{
ULONG uCount = InterlockedDecrement(&m_nRefCount);
- if (uCount == 0)
- {
+ if (uCount == 0) {
delete this;
}
// For thread safety, return a temporary variable.
@@ -1074,8 +992,7 @@ ULONG CMFStreamSource::Release()
HRESULT CMFStreamSource::QueryInterface(REFIID iid, void** ppv)
{
- static const QITAB qit[] =
- {
+ static const QITAB qit[] = {
QITABENT(CMFStreamSource, IMFMediaEventGenerator),
QITABENT(CMFStreamSource, IMFMediaStream),
{ 0 }
@@ -1094,8 +1011,7 @@ HRESULT CMFStreamSource::BeginGetEvent(IMFAsyncCallback* pCallback, IUnknown* pu
EnterCriticalSection(&m_critSec);
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = m_pEventQueue->BeginGetEvent(pCallback, punkState);
}
@@ -1110,8 +1026,7 @@ HRESULT CMFStreamSource::EndGetEvent(IMFAsyncResult* pResult, IMFMediaEvent** pp
EnterCriticalSection(&m_critSec);
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = m_pEventQueue->EndGetEvent(pResult, ppEvent);
}
@@ -1129,16 +1044,14 @@ HRESULT CMFStreamSource::GetEvent(DWORD dwFlags, IMFMediaEvent** ppEvent)
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
pQueue = m_pEventQueue;
pQueue->AddRef();
}
LeaveCriticalSection(&m_critSec);
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pQueue->GetEvent(dwFlags, ppEvent);
}
@@ -1153,8 +1066,7 @@ HRESULT CMFStreamSource::QueueEvent(MediaEventType met, REFGUID guidExtendedType
EnterCriticalSection(&m_critSec);
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = m_pEventQueue->QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue);
}
@@ -1173,8 +1085,7 @@ HRESULT CMFStreamSource::QueueEvent(MediaEventType met, REFGUID guidExtendedType
HRESULT CMFStreamSource::GetMediaSource(IMFMediaSource** ppMediaSource)
{
- if (ppMediaSource == NULL)
- {
+ if (ppMediaSource == NULL) {
return E_POINTER;
}
@@ -1187,16 +1098,13 @@ HRESULT CMFStreamSource::GetMediaSource(IMFMediaSource** ppMediaSource)
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
- if (m_pSource == NULL)
- {
+ if (SUCCEEDED(hr)) {
+ if (m_pSource == NULL) {
hr = E_UNEXPECTED;
}
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = m_pSource->QueryInterface(IID_PPV_ARGS(ppMediaSource));
}
@@ -1212,13 +1120,11 @@ HRESULT CMFStreamSource::GetMediaSource(IMFMediaSource** ppMediaSource)
HRESULT CMFStreamSource::GetStreamDescriptor(IMFStreamDescriptor** ppStreamDescriptor)
{
- if (ppStreamDescriptor == NULL)
- {
+ if (ppStreamDescriptor == NULL) {
return E_POINTER;
}
- if (m_pStreamDescriptor == NULL)
- {
+ if (m_pStreamDescriptor == NULL) {
return E_UNEXPECTED;
}
@@ -1228,8 +1134,7 @@ HRESULT CMFStreamSource::GetStreamDescriptor(IMFStreamDescriptor** ppStreamDescr
hr = CheckShutdown();
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
*ppStreamDescriptor = m_pStreamDescriptor;
(*ppStreamDescriptor)->AddRef();
}
@@ -1250,8 +1155,7 @@ HRESULT CMFStreamSource::GetStreamDescriptor(IMFStreamDescriptor** ppStreamDescr
HRESULT CMFStreamSource::RequestSample(IUnknown* pToken)
{
- if (m_pSource == NULL)
- {
+ if (m_pSource == NULL) {
return E_UNEXPECTED;
}
@@ -1266,60 +1170,49 @@ HRESULT CMFStreamSource::RequestSample(IUnknown* pToken)
hr = CheckShutdown();
// Check if we already reached the end of the stream.
- if (SUCCEEDED(hr))
- {
- if (m_EOS)
- {
+ if (SUCCEEDED(hr)) {
+ if (m_EOS) {
hr = MF_E_END_OF_STREAM;
}
}
// Check the source is stopped.
// GetState does not hold the source's critical section. Safe to call.
- if (SUCCEEDED(hr))
- {
- if (m_pSource->GetState() == CMFSource::STATE_STOPPED)
- {
+ if (SUCCEEDED(hr)) {
+ if (m_pSource->GetState() == CMFSource::STATE_STOPPED) {
hr = MF_E_INVALIDREQUEST;
}
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
// Create a new audio sample.
hr = CreateSample(&pSample);
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
// If the caller provided a token, attach it to the sample as
// an attribute.
// NOTE: If we processed sample requests asynchronously, we would
// need to call AddRef on the token and put the token onto a FIFO
// queue. See documenation for IMFMediaStream::RequestSample.
- if (pToken && pSample)
- {
+ if (pToken && pSample) {
hr = pSample->SetUnknown(MFSampleExtension_Token, pToken);
}
}
// If paused, queue the sample for later delivery. Otherwise, deliver the sample now.
- if (SUCCEEDED(hr) && pSample)
- {
- if (m_pSource->GetState() == CMFSource::STATE_PAUSED)
- {
+ if (SUCCEEDED(hr) && pSample) {
+ if (m_pSource->GetState() == CMFSource::STATE_PAUSED) {
hr = m_sampleQueue.Queue(pSample);
}
- else
- {
+ else {
hr = DeliverSample(pSample);
}
}
// Cache a pointer to the source, prior to leaving the critical section.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
pSource = m_pSource;
pSource->AddRef();
}
@@ -1334,10 +1227,8 @@ HRESULT CMFStreamSource::RequestSample(IUnknown* pToken)
// source's critical section while holding the stream's critical section, at
// risk of deadlock.
- if (SUCCEEDED(hr))
- {
- if (m_EOS)
- {
+ if (SUCCEEDED(hr)) {
+ if (m_EOS) {
hr = pSource->QueueEvent(MEEndOfPresentation, GUID_NULL, S_OK, NULL);
}
}
@@ -1352,78 +1243,72 @@ HRESULT CMFStreamSource::RequestSample(IUnknown* pToken)
HRESULT CMFStreamSource::InitializeParams()
{
- HRESULT hr = S_OK;
-
- IMFMediaTypeHandler *pMediaTypeHandler = NULL;
- IMFMediaType* pMediaType = NULL;
-
- CHECK_HR(hr = m_pStreamDescriptor->GetMediaTypeHandler(&pMediaTypeHandler));
- CHECK_HR(hr = pMediaTypeHandler->GetCurrentMediaType(&pMediaType));
-
- GUID majorType, subType;
- pMediaType->GetMajorType(&majorType);
- if(majorType == MFMediaType_Video)
- {
- memset(&m_structVideoParams, 0, sizeof(m_structVideoParams));
- CHECK_HR(hr = MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &m_structVideoParams.nWidth, &m_structVideoParams.nHeigh));
- CHECK_HR(hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &subType));
-
- m_guidMajorType = MFMediaType_Video;
- m_guidSubType = subType;
-
- // Guess video size
- UINT32 nBufferSize;
- if(subType == MFVideoFormat_RGB32)
- {
- nBufferSize = (m_structVideoParams.nWidth * m_structVideoParams.nHeigh << 2);
- }
- else if(subType == MFVideoFormat_RGB24)
- {
- nBufferSize = (m_structVideoParams.nWidth * m_structVideoParams.nHeigh << 2);
- }
- else if(subType == MFVideoFormat_NV12 || subType == MFVideoFormat_I420)
- {
- nBufferSize = (m_structVideoParams.nWidth * m_structVideoParams.nHeigh * 3) >> 1;
- }
- else
- {
- TSK_DEBUG_ERROR("Video subType not supported");
- CHECK_HR(hr = E_NOTIMPL);
- }
-
- // Allocate media buffer
- SafeRelease(&m_pMediaBuffer);
- CHECK_HR(hr = MFCreateMemoryBuffer(nBufferSize, &m_pMediaBuffer));
- m_nBufferSize = nBufferSize;
- {
- //FIXME: DeliverSample() stops if no data
- BYTE* pBuffer = NULL;
- CHECK_HR(hr = m_pMediaBuffer->Lock(&pBuffer, NULL, NULL));
- memset(pBuffer, 0, nBufferSize);
- CHECK_HR(hr = m_pMediaBuffer->SetCurrentLength(nBufferSize));
- CHECK_HR(hr = m_pMediaBuffer->Unlock());
- }
-
- // Retrieve video Frame rate
- UINT32 unNumerator, unDenominator;
- CHECK_HR(hr = MFGetAttributeRatio(pMediaType, MF_MT_FRAME_RATE, &unNumerator, &unDenominator));
- m_structVideoParams.nFps = (unNumerator / unDenominator);
-
- // Retrieve sample duration based on framerate
- m_rtCurrentPosition = 0;
- CHECK_HR(hr = MFFrameRateToAverageTimePerFrame(m_structVideoParams.nFps, 1, &m_rtDuration));
- }
- else
- {
- TSK_DEBUG_ERROR("Only video media type is supported");
- CHECK_HR(hr = E_NOTIMPL);
- }
+ HRESULT hr = S_OK;
+
+ IMFMediaTypeHandler *pMediaTypeHandler = NULL;
+ IMFMediaType* pMediaType = NULL;
+
+ CHECK_HR(hr = m_pStreamDescriptor->GetMediaTypeHandler(&pMediaTypeHandler));
+ CHECK_HR(hr = pMediaTypeHandler->GetCurrentMediaType(&pMediaType));
+
+ GUID majorType, subType;
+ pMediaType->GetMajorType(&majorType);
+ if(majorType == MFMediaType_Video) {
+ memset(&m_structVideoParams, 0, sizeof(m_structVideoParams));
+ CHECK_HR(hr = MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &m_structVideoParams.nWidth, &m_structVideoParams.nHeigh));
+ CHECK_HR(hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &subType));
+
+ m_guidMajorType = MFMediaType_Video;
+ m_guidSubType = subType;
+
+ // Guess video size
+ UINT32 nBufferSize;
+ if(subType == MFVideoFormat_RGB32) {
+ nBufferSize = (m_structVideoParams.nWidth * m_structVideoParams.nHeigh << 2);
+ }
+ else if(subType == MFVideoFormat_RGB24) {
+ nBufferSize = (m_structVideoParams.nWidth * m_structVideoParams.nHeigh << 2);
+ }
+ else if(subType == MFVideoFormat_NV12 || subType == MFVideoFormat_I420) {
+ nBufferSize = (m_structVideoParams.nWidth * m_structVideoParams.nHeigh * 3) >> 1;
+ }
+ else {
+ TSK_DEBUG_ERROR("Video subType not supported");
+ CHECK_HR(hr = E_NOTIMPL);
+ }
+
+ // Allocate media buffer
+ SafeRelease(&m_pMediaBuffer);
+ CHECK_HR(hr = MFCreateMemoryBuffer(nBufferSize, &m_pMediaBuffer));
+ m_nBufferSize = nBufferSize;
+ {
+ //FIXME: DeliverSample() stops if no data
+ BYTE* pBuffer = NULL;
+ CHECK_HR(hr = m_pMediaBuffer->Lock(&pBuffer, NULL, NULL));
+ memset(pBuffer, 0, nBufferSize);
+ CHECK_HR(hr = m_pMediaBuffer->SetCurrentLength(nBufferSize));
+ CHECK_HR(hr = m_pMediaBuffer->Unlock());
+ }
+
+ // Retrieve video Frame rate
+ UINT32 unNumerator, unDenominator;
+ CHECK_HR(hr = MFGetAttributeRatio(pMediaType, MF_MT_FRAME_RATE, &unNumerator, &unDenominator));
+ m_structVideoParams.nFps = (unNumerator / unDenominator);
+
+ // Retrieve sample duration based on framerate
+ m_rtCurrentPosition = 0;
+ CHECK_HR(hr = MFFrameRateToAverageTimePerFrame(m_structVideoParams.nFps, 1, &m_rtDuration));
+ }
+ else {
+ TSK_DEBUG_ERROR("Only video media type is supported");
+ CHECK_HR(hr = E_NOTIMPL);
+ }
bail:
- SafeRelease(&pMediaTypeHandler);
- SafeRelease(&pMediaType);
+ SafeRelease(&pMediaTypeHandler);
+ SafeRelease(&pMediaType);
- return hr;
+ return hr;
}
// NOTE: Some of these methods hold the stream's critical section
@@ -1436,29 +1321,27 @@ bail:
HRESULT CMFStreamSource::CreateSample(IMFSample **ppSample)
{
- *ppSample = NULL;
+ *ppSample = NULL;
HRESULT hr = S_OK;
IMFSample *pSample = NULL;
- DWORD nCurrentLength = 0;
-
- CHECK_HR(hr = m_pMediaBuffer->GetCurrentLength(&nCurrentLength));
-
- if(nCurrentLength > 0)
- {
- CHECK_HR(hr = MFCreateSample(&pSample));
- CHECK_HR(hr = pSample->SetSampleTime(m_rtCurrentPosition));
- CHECK_HR(hr = pSample->SetSampleDuration(m_rtDuration));
- m_rtCurrentPosition += m_rtDuration;
- CHECK_HR(hr = pSample->AddBuffer(m_pMediaBuffer));
-
- if((*ppSample = pSample))
- {
- (*ppSample)->AddRef();
- }
- }
-
+ DWORD nCurrentLength = 0;
+
+ CHECK_HR(hr = m_pMediaBuffer->GetCurrentLength(&nCurrentLength));
+
+ if(nCurrentLength > 0) {
+ CHECK_HR(hr = MFCreateSample(&pSample));
+ CHECK_HR(hr = pSample->SetSampleTime(m_rtCurrentPosition));
+ CHECK_HR(hr = pSample->SetSampleDuration(m_rtDuration));
+ m_rtCurrentPosition += m_rtDuration;
+ CHECK_HR(hr = pSample->AddBuffer(m_pMediaBuffer));
+
+ if((*ppSample = pSample)) {
+ (*ppSample)->AddRef();
+ }
+ }
+
bail:
SafeRelease(&pSample);
return hr;
@@ -1472,15 +1355,13 @@ HRESULT CMFStreamSource::DeliverSample(IMFSample *pSample)
{
HRESULT hr = S_OK;
- if(pSample)
- {
- // Send the MEMediaSample event with the new sample.
- hr = QueueEventWithIUnknown(this, MEMediaSample, hr, pSample);
- }
+ if(pSample) {
+ // Send the MEMediaSample event with the new sample.
+ hr = QueueEventWithIUnknown(this, MEMediaSample, hr, pSample);
+ }
// See if we reached the end of the stream.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = CheckEndOfStream(); // This method sends MEEndOfStream if needed.
}
@@ -1506,25 +1387,20 @@ HRESULT CMFStreamSource::DeliverQueuedSamples()
// If we already reached the end of the stream, send the MEEndStream
// event again.
- if (m_EOS)
- {
+ if (m_EOS) {
hr = QueueEvent(MEEndOfStream, GUID_NULL, S_OK, NULL);
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
// Deliver any queued samples.
- while (!m_sampleQueue.IsEmpty())
- {
+ while (!m_sampleQueue.IsEmpty()) {
hr = m_sampleQueue.Dequeue(&pSample);
- if (FAILED(hr))
- {
+ if (FAILED(hr)) {
break;
}
hr = DeliverSample(pSample);
- if (FAILED(hr))
- {
+ if (FAILED(hr)) {
break;
}
@@ -1536,10 +1412,8 @@ HRESULT CMFStreamSource::DeliverQueuedSamples()
// If we reached the end of the stream, send the end-of-presentation event from
// the media source.
- if (SUCCEEDED(hr))
- {
- if (m_EOS)
- {
+ if (SUCCEEDED(hr)) {
+ if (m_EOS) {
hr = m_pSource->QueueEvent(MEEndOfPresentation, GUID_NULL, S_OK, NULL);
}
}
@@ -1578,8 +1452,7 @@ HRESULT CMFStreamSource::Shutdown()
Flush();
// Shut down the event queue.
- if (m_pEventQueue)
- {
+ if (m_pEventQueue) {
m_pEventQueue->Shutdown();
}
@@ -1602,37 +1475,37 @@ HRESULT CMFStreamSource::SetPosition(LONGLONG rtNewPosition)
{
EnterCriticalSection(&m_critSec);
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK;
-/*
- // Check if the requested position is beyond the end of the stream.
- LONGLONG duration = AudioDurationFromBufferSize(m_pRiff->Format(), m_pRiff->Chunk().DataSize());
+ /*
+ // Check if the requested position is beyond the end of the stream.
+ LONGLONG duration = AudioDurationFromBufferSize(m_pRiff->Format(), m_pRiff->Chunk().DataSize());
- if (rtNewPosition > duration)
- {
- LeaveCriticalSection(&m_critSec);
+ if (rtNewPosition > duration)
+ {
+ LeaveCriticalSection(&m_critSec);
- return MF_E_INVALIDREQUEST; // Start position is past the end of the presentation.
- }
+ return MF_E_INVALIDREQUEST; // Start position is past the end of the presentation.
+ }
- if (m_rtCurrentPosition != rtNewPosition)
- {
- LONGLONG offset = BufferSizeFromAudioDuration(m_pRiff->Format(), rtNewPosition);
+ if (m_rtCurrentPosition != rtNewPosition)
+ {
+ LONGLONG offset = BufferSizeFromAudioDuration(m_pRiff->Format(), rtNewPosition);
- // The chunk size is a DWORD. So if our calculations are correct, there is no
- // way that the maximum valid seek position can be larger than a DWORD.
- assert(offset <= MAXDWORD);
+ // The chunk size is a DWORD. So if our calculations are correct, there is no
+ // way that the maximum valid seek position can be larger than a DWORD.
+ assert(offset <= MAXDWORD);
- hr = m_pRiff->MoveToChunkOffset((DWORD)offset);
+ hr = m_pRiff->MoveToChunkOffset((DWORD)offset);
- if (SUCCEEDED(hr))
- {
- m_rtCurrentPosition = rtNewPosition;
- m_discontinuity = TRUE;
- m_EOS = FALSE;
+ if (SUCCEEDED(hr))
+ {
+ m_rtCurrentPosition = rtNewPosition;
+ m_discontinuity = TRUE;
+ m_EOS = FALSE;
+ }
}
- }
-*/
+ */
LeaveCriticalSection(&m_critSec);
return hr;
}
@@ -1640,18 +1513,18 @@ HRESULT CMFStreamSource::SetPosition(LONGLONG rtNewPosition)
HRESULT CMFStreamSource::CheckEndOfStream()
{
HRESULT hr = S_OK;
-/*
- if (m_pRiff->BytesRemainingInChunk() < m_pRiff->Format()->nBlockAlign)
- {
- // The remaining data is smaller than the audio block size. (In theory there shouldn't be
- // partial bits of data at the end, so we should reach an even zero bytes, but the file
- // might not be authored correctly.)
- m_EOS = TRUE;
-
- // Send the end-of-stream event,
- hr = QueueEvent(MEEndOfStream, GUID_NULL, S_OK, NULL);
- }
- */
+ /*
+ if (m_pRiff->BytesRemainingInChunk() < m_pRiff->Format()->nBlockAlign)
+ {
+ // The remaining data is smaller than the audio block size. (In theory there shouldn't be
+ // partial bits of data at the end, so we should reach an even zero bytes, but the file
+ // might not be authored correctly.)
+ m_EOS = TRUE;
+
+ // Send the end-of-stream event,
+ hr = QueueEvent(MEEndOfStream, GUID_NULL, S_OK, NULL);
+ }
+ */
return hr;
}
@@ -1697,8 +1570,7 @@ LONGLONG AudioDurationFromBufferSize(const WAVEFORMATEX *pWav, DWORD cbAudioData
{
assert(pWav != NULL);
- if (pWav->nAvgBytesPerSec == 0)
- {
+ if (pWav->nAvgBytesPerSec == 0) {
return 0;
}
return (LONGLONG)cbAudioDataSize * 10000000 / pWav->nAvgBytesPerSec;
@@ -1711,8 +1583,7 @@ LONGLONG BufferSizeFromAudioDuration(const WAVEFORMATEX *pWav, LONGLONG duration
ULONG ulRemainder = (ULONG)(cbSize % pWav->nBlockAlign);
// Round up to the next block.
- if(ulRemainder)
- {
+ if(ulRemainder) {
cbSize += pWav->nBlockAlign - ulRemainder;
}
diff --git a/plugins/pluginWinMF/internals/mf_custom_src.h b/plugins/pluginWinMF/internals/mf_custom_src.h
index f9194c9..15d8b90 100755
--- a/plugins/pluginWinMF/internals/mf_custom_src.h
+++ b/plugins/pluginWinMF/internals/mf_custom_src.h
@@ -1,20 +1,20 @@
-/*
+/*
* Copyright (C) Microsoft Corporation. All rights reserved.
* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -50,10 +50,10 @@ class CMFSource : public IMFMediaSource
public:
static HRESULT CreateInstance(REFIID iid, void **ppSource);
- static HRESULT CreateInstanceEx(REFIID iid, void **ppSource, IMFMediaType *pMediaType);
+ static HRESULT CreateInstanceEx(REFIID iid, void **ppSource, IMFMediaType *pMediaType);
- // IMFCustomSource
- HRESULT CopyVideoBuffer(UINT32 nWidth, UINT32 nHeight, const void* pBufferPtr, UINT32 nBufferSize);
+ // IMFCustomSource
+ HRESULT CopyVideoBuffer(UINT32 nWidth, UINT32 nHeight, const void* pBufferPtr, UINT32 nBufferSize);
// IUnknown
STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
@@ -80,8 +80,7 @@ public:
private:
- enum State
- {
+ enum State {
STATE_STOPPED,
STATE_PAUSED,
STATE_STARTED
@@ -92,14 +91,11 @@ private:
CMFSource(HRESULT &hr, IMFMediaType *pMediaType);
virtual ~CMFSource();
- HRESULT CheckShutdown() const
- {
- if (m_IsShutdown)
- {
+ HRESULT CheckShutdown() const {
+ if (m_IsShutdown) {
return MF_E_SHUTDOWN;
}
- else
- {
+ else {
return S_OK;
}
}
@@ -110,7 +106,9 @@ private:
HRESULT ValidatePresentationDescriptor(IMFPresentationDescriptor *pPD);
LONGLONG GetCurrentPosition() const;
- State GetState() const { return m_state; }
+ State GetState() const {
+ return m_state;
+ }
IMFMediaEventQueue *m_pEventQueue; // Event generator helper
IMFPresentationDescriptor *m_pPresentationDescriptor; // Default presentation
@@ -122,7 +120,7 @@ private:
BOOL m_IsShutdown; // Flag to indicate if Shutdown() method was called.
State m_state; // Current state (running, stopped, paused)
- IMFMediaType *m_pMediaType; // The supported mediaType
+ IMFMediaType *m_pMediaType; // The supported mediaType
};
@@ -131,22 +129,21 @@ class SampleQueue
protected:
// Nodes in the linked list
- struct Node
- {
+ struct Node {
Node *prev;
Node *next;
IMFSample* item;
- Node() : prev(NULL), next(NULL)
- {
+ Node() : prev(NULL), next(NULL) {
}
- Node(IMFSample* item) : prev(NULL), next(NULL)
- {
+ Node(IMFSample* item) : prev(NULL), next(NULL) {
this->item = item;
}
- IMFSample* Item() const { return item; }
+ IMFSample* Item() const {
+ return item;
+ }
};
@@ -155,27 +152,22 @@ protected:
public:
- SampleQueue()
- {
+ SampleQueue() {
m_anchor.next = &m_anchor;
m_anchor.prev = &m_anchor;
}
- virtual ~SampleQueue()
- {
+ virtual ~SampleQueue() {
Clear();
}
- HRESULT Queue(IMFSample* item)
- {
- if (item == NULL)
- {
+ HRESULT Queue(IMFSample* item) {
+ if (item == NULL) {
return E_POINTER;
}
Node *pNode = new (std::nothrow) Node(item);
- if (pNode == NULL)
- {
+ if (pNode == NULL) {
return E_OUTOFMEMORY;
}
@@ -195,14 +187,11 @@ public:
}
- HRESULT Dequeue(IMFSample* *ppItem)
- {
- if (IsEmpty())
- {
+ HRESULT Dequeue(IMFSample**ppItem) {
+ if (IsEmpty()) {
return E_FAIL;
}
- if (ppItem == NULL)
- {
+ if (ppItem == NULL) {
return E_POINTER;
}
@@ -220,17 +209,16 @@ public:
return S_OK;
}
- BOOL IsEmpty() const { return m_anchor.next == &m_anchor; }
+ BOOL IsEmpty() const {
+ return m_anchor.next == &m_anchor;
+ }
- void Clear()
- {
+ void Clear() {
Node *n = m_anchor.next;
// Delete the nodes
- while (n != &m_anchor)
- {
- if (n->item)
- {
+ while (n != &m_anchor) {
+ if (n->item) {
n->item->Release();
}
@@ -260,8 +248,8 @@ class CMFStreamSource : public IMFMediaStream
public:
- // IMFCustomSource
- HRESULT CopyVideoBuffer(UINT32 nWidth, UINT32 nHeight, const void* pBufferPtr, UINT32 nBufferSize);
+ // IMFCustomSource
+ HRESULT CopyVideoBuffer(UINT32 nWidth, UINT32 nHeight, const void* pBufferPtr, UINT32 nBufferSize);
// IUnknown
STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
@@ -285,26 +273,25 @@ private:
~CMFStreamSource();
- HRESULT CheckShutdown() const
- {
- if (m_IsShutdown)
- {
+ HRESULT CheckShutdown() const {
+ if (m_IsShutdown) {
return MF_E_SHUTDOWN;
}
- else
- {
+ else {
return S_OK;
}
}
- HRESULT InitializeParams();
+ HRESULT InitializeParams();
HRESULT Shutdown();
HRESULT CreateSample(IMFSample **pSample);
HRESULT DeliverSample(IMFSample *pSample);
HRESULT DeliverQueuedSamples();
HRESULT Flush();
- LONGLONG GetCurrentPosition() const { return m_rtCurrentPosition; }
+ LONGLONG GetCurrentPosition() const {
+ return m_rtCurrentPosition;
+ }
HRESULT SetPosition(LONGLONG rtNewPosition);
HRESULT CheckEndOfStream();
@@ -313,7 +300,7 @@ private:
CRITICAL_SECTION m_critSec;
BOOL m_IsShutdown; // Flag to indicate if source's Shutdown() method was called.
LONGLONG m_rtCurrentPosition; // Current position in the stream, in 100-ns units
- UINT64 m_rtDuration; // Sample duration, in 100-ns units
+ UINT64 m_rtDuration; // Sample duration, in 100-ns units
BOOL m_discontinuity; // Is the next sample a discontinuity?
BOOL m_EOS; // Did we reach the end of the stream?
@@ -322,18 +309,17 @@ private:
IMFStreamDescriptor *m_pStreamDescriptor; // Stream descriptor for this stream.
SampleQueue m_sampleQueue; // Queue for samples while paused.
- GUID m_guidMajorType; // major media type (e.g. MFMediaType_Video or MFMediaType_Audio)
- GUID m_guidSubType; // Media subtype (e.g. MFVideoFormat_RGB32 or MFVideoFormat_H264)
- IMFMediaBuffer *m_pMediaBuffer; // Pointer to the data to deliver
- UINT32 m_nBufferSize; // Size of the data to deliver
-
- struct
- {
- UINT32 nWidth;
- UINT32 nHeigh;
- UINT32 nFps;
- }
- m_structVideoParams;
+ GUID m_guidMajorType; // major media type (e.g. MFMediaType_Video or MFMediaType_Audio)
+ GUID m_guidSubType; // Media subtype (e.g. MFVideoFormat_RGB32 or MFVideoFormat_H264)
+ IMFMediaBuffer *m_pMediaBuffer; // Pointer to the data to deliver
+ UINT32 m_nBufferSize; // Size of the data to deliver
+
+ struct {
+ UINT32 nWidth;
+ UINT32 nHeigh;
+ UINT32 nFps;
+ }
+ m_structVideoParams;
};
diff --git a/plugins/pluginWinMF/internals/mf_devices.cxx b/plugins/pluginWinMF/internals/mf_devices.cxx
index 22b862e..49005de 100755
--- a/plugins/pluginWinMF/internals/mf_devices.cxx
+++ b/plugins/pluginWinMF/internals/mf_devices.cxx
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -20,25 +20,25 @@
#include "mf_utils.h"
DeviceList::DeviceList()
-: m_ppDevices(NULL)
-, m_cDevices(0)
+ : m_ppDevices(NULL)
+ , m_cDevices(0)
{
-
+
}
DeviceList::~DeviceList()
{
- Clear();
+ Clear();
}
UINT32 DeviceList::Count()const
{
- return m_cDevices;
+ return m_cDevices;
}
void DeviceList::Clear()
{
- for (UINT32 i = 0; i < m_cDevices; i++) {
+ for (UINT32 i = 0; i < m_cDevices; i++) {
SafeRelease(&m_ppDevices[i]);
}
CoTaskMemFree(m_ppDevices);
@@ -49,7 +49,7 @@ void DeviceList::Clear()
HRESULT DeviceList::EnumerateDevices(const GUID& sourceType)
{
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK;
IMFAttributes *pAttributes = NULL;
Clear();
@@ -60,17 +60,15 @@ HRESULT DeviceList::EnumerateDevices(const GUID& sourceType)
hr = MFCreateAttributes(&pAttributes, 1);
// Ask for source type = video capture devices
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pAttributes->SetGUID(
- MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
- sourceType
- );
+ MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
+ sourceType
+ );
}
// Enumerate devices.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = MFEnumDeviceSources(pAttributes, &m_ppDevices, &m_cDevices);
}
@@ -81,8 +79,7 @@ HRESULT DeviceList::EnumerateDevices(const GUID& sourceType)
HRESULT DeviceList::GetDeviceAtIndex(UINT32 index, IMFActivate **ppActivate)
{
- if (index >= Count())
- {
+ if (index >= Count()) {
return E_INVALIDARG;
}
@@ -94,58 +91,52 @@ HRESULT DeviceList::GetDeviceAtIndex(UINT32 index, IMFActivate **ppActivate)
HRESULT DeviceList::GetDeviceBest(IMFActivate **ppActivate, WCHAR *pszName /*= NULL*/)
{
- UINT32 index = 0;
- if(pszName)
- {
- WCHAR *_pszName = NULL;
- BOOL bFound = FALSE;
- for(UINT32 i = 0; i < Count() && !bFound; ++i)
- {
- if((SUCCEEDED(GetDeviceName(i, &_pszName))))
- {
- if(wcscmp(_pszName, pszName) == 0)
- {
- index = i;
- bFound = TRUE;
- // do not break the loop because we need to free(_pszName)
- }
- }
- if(_pszName)
- {
- CoTaskMemFree(_pszName), _pszName = NULL;
- }
- }
- }
- return GetDeviceAtIndex(index, ppActivate);
+ UINT32 index = 0;
+ if(pszName) {
+ WCHAR *_pszName = NULL;
+ BOOL bFound = FALSE;
+ for(UINT32 i = 0; i < Count() && !bFound; ++i) {
+ if((SUCCEEDED(GetDeviceName(i, &_pszName)))) {
+ if(wcscmp(_pszName, pszName) == 0) {
+ index = i;
+ bFound = TRUE;
+ // do not break the loop because we need to free(_pszName)
+ }
+ }
+ if(_pszName) {
+ CoTaskMemFree(_pszName), _pszName = NULL;
+ }
+ }
+ }
+ return GetDeviceAtIndex(index, ppActivate);
}
// The caller must free the memory for the string by calling CoTaskMemFree
HRESULT DeviceList::GetDeviceName(UINT32 index, WCHAR **ppszName)
{
- if (index >= Count())
- {
+ if (index >= Count()) {
return E_INVALIDARG;
}
HRESULT hr = S_OK;
hr = m_ppDevices[index]->GetAllocatedString(
- MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,
- ppszName,
- NULL
- );
+ MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,
+ ppszName,
+ NULL
+ );
return hr;
}
HRESULT DeviceListAudio::EnumerateDevices()
{
- // call base class function
- return DeviceList::EnumerateDevices(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID);
+ // call base class function
+ return DeviceList::EnumerateDevices(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID);
}
HRESULT DeviceListVideo::EnumerateDevices()
{
- // call base class function
- return DeviceList::EnumerateDevices(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
+ // call base class function
+ return DeviceList::EnumerateDevices(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
}
diff --git a/plugins/pluginWinMF/internals/mf_devices.h b/plugins/pluginWinMF/internals/mf_devices.h
index 03d010f..3a16a29 100755
--- a/plugins/pluginWinMF/internals/mf_devices.h
+++ b/plugins/pluginWinMF/internals/mf_devices.h
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -46,19 +46,19 @@ public:
HRESULT GetDeviceName(UINT32 index, WCHAR **ppszName);
protected:
- HRESULT EnumerateDevices(const GUID& sourceType);
+ HRESULT EnumerateDevices(const GUID& sourceType);
};
class DeviceListAudio : public DeviceList
{
public:
- HRESULT EnumerateDevices();
+ HRESULT EnumerateDevices();
};
class DeviceListVideo : public DeviceList
{
public:
- HRESULT EnumerateDevices();
+ HRESULT EnumerateDevices();
};
#endif /* PLUGIN_WIN_MF_DEVICES_H */
diff --git a/plugins/pluginWinMF/internals/mf_display_watcher.cxx b/plugins/pluginWinMF/internals/mf_display_watcher.cxx
index 62dbc5f..38f3687 100755
--- a/plugins/pluginWinMF/internals/mf_display_watcher.cxx
+++ b/plugins/pluginWinMF/internals/mf_display_watcher.cxx
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -24,137 +24,126 @@
#include <assert.h>
DisplayWatcher::DisplayWatcher(HWND hWnd, IMFMediaSink* pMediaSink, HRESULT &hr)
-: m_pDisplayControl(NULL)
-, m_hWnd(hWnd)
-, m_pWndProc(NULL)
-, m_bStarted(FALSE)
-, m_bFullScreen(FALSE)
+ : m_pDisplayControl(NULL)
+ , m_hWnd(hWnd)
+ , m_pWndProc(NULL)
+ , m_bStarted(FALSE)
+ , m_bFullScreen(FALSE)
{
- IMFGetService *pService = NULL;
+ IMFGetService *pService = NULL;
- CHECK_HR(hr = pMediaSink->QueryInterface(__uuidof(IMFGetService), (void**)&pService));
- CHECK_HR(hr = pService->GetService(MR_VIDEO_RENDER_SERVICE, __uuidof(IMFVideoDisplayControl), (void**)&m_pDisplayControl));
- CHECK_HR(hr = m_pDisplayControl->SetAspectRatioMode(MFVideoARMode_PreservePicture));
+ CHECK_HR(hr = pMediaSink->QueryInterface(__uuidof(IMFGetService), (void**)&pService));
+ CHECK_HR(hr = pService->GetService(MR_VIDEO_RENDER_SERVICE, __uuidof(IMFVideoDisplayControl), (void**)&m_pDisplayControl));
+ CHECK_HR(hr = m_pDisplayControl->SetAspectRatioMode(MFVideoARMode_PreservePicture));
bail:
- SafeRelease(&pService);
+ SafeRelease(&pService);
}
DisplayWatcher::~DisplayWatcher()
{
- Stop();
+ Stop();
- SafeRelease(&m_pDisplayControl);
+ SafeRelease(&m_pDisplayControl);
}
HRESULT DisplayWatcher::Start()
{
- HRESULT hr = S_OK;
- HWND hWnd = m_hWnd; // save()
- CHECK_HR(hr = Stop());
-
- if((m_hWnd = hWnd) && m_pDisplayControl)
- {
- CHECK_HR(hr = m_pDisplayControl->SetVideoWindow(hWnd));
-
- BOOL ret = SetPropA(m_hWnd, "This", this);
- assert(ret);
-
+ HRESULT hr = S_OK;
+ HWND hWnd = m_hWnd; // save()
+ CHECK_HR(hr = Stop());
+
+ if((m_hWnd = hWnd) && m_pDisplayControl) {
+ CHECK_HR(hr = m_pDisplayControl->SetVideoWindow(hWnd));
+
+ BOOL ret = SetPropA(m_hWnd, "This", this);
+ assert(ret);
+
#if _M_X64
- m_pWndProc = (WNDPROC)SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)DisplayWatcher::WndProc);
+ m_pWndProc = (WNDPROC)SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)DisplayWatcher::WndProc);
#else
- m_pWndProc = (WNDPROC)SetWindowLongPtr(m_hWnd, GWL_WNDPROC, (LONG)DisplayWatcher::WndProc);
+ m_pWndProc = (WNDPROC)SetWindowLongPtr(m_hWnd, GWL_WNDPROC, (LONG)DisplayWatcher::WndProc);
#endif
- UpdatePosition(); // black screen if attached later
- }
- m_bStarted = TRUE;
+ UpdatePosition(); // black screen if attached later
+ }
+ m_bStarted = TRUE;
bail:
- return hr;
+ return hr;
}
HRESULT DisplayWatcher::SetFullscreen(BOOL bEnabled)
{
- if(m_pDisplayControl)
- {
- HRESULT hr = m_pDisplayControl->SetFullscreen(bEnabled);
- m_bFullScreen = SUCCEEDED(hr);
- return hr;
- }
-
- return E_FAIL;
+ if(m_pDisplayControl) {
+ HRESULT hr = m_pDisplayControl->SetFullscreen(bEnabled);
+ m_bFullScreen = SUCCEEDED(hr);
+ return hr;
+ }
+
+ return E_FAIL;
}
HRESULT DisplayWatcher::SetHwnd(HWND hWnd)
{
- BOOL bWasStarted = m_bStarted;
- Stop();
- m_hWnd = hWnd;
- if(bWasStarted)
- {
- return Start();
- }
- return S_OK;
+ BOOL bWasStarted = m_bStarted;
+ Stop();
+ m_hWnd = hWnd;
+ if(bWasStarted) {
+ return Start();
+ }
+ return S_OK;
}
HRESULT DisplayWatcher::Stop()
{
- if(m_hWnd && m_pWndProc)
- {
- // Restore
-
+ if(m_hWnd && m_pWndProc) {
+ // Restore
+
#if _M_X64
- SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_pWndProc);
+ SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)m_pWndProc);
#else
- SetWindowLongPtr(m_hWnd, GWL_WNDPROC, (LONG)m_pWndProc);
+ SetWindowLongPtr(m_hWnd, GWL_WNDPROC, (LONG)m_pWndProc);
#endif
- }
- m_hWnd = NULL;
- m_pWndProc = NULL;
- m_bStarted = FALSE;
- return S_OK;
+ }
+ m_hWnd = NULL;
+ m_pWndProc = NULL;
+ m_bStarted = FALSE;
+ return S_OK;
}
void DisplayWatcher::UpdatePosition()
{
- if(m_pDisplayControl && m_hWnd)
- {
- RECT rcDst = { 0, 0, 0, 0 };
- GetClientRect(m_hWnd, &rcDst);
- m_pDisplayControl->SetVideoPosition(NULL, &rcDst);
- }
+ if(m_pDisplayControl && m_hWnd) {
+ RECT rcDst = { 0, 0, 0, 0 };
+ GetClientRect(m_hWnd, &rcDst);
+ m_pDisplayControl->SetVideoPosition(NULL, &rcDst);
+ }
}
LRESULT CALLBACK DisplayWatcher::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- switch(uMsg)
- {
- case WM_CREATE:
- case WM_SIZE:
- case WM_MOVE:
- {
- DisplayWatcher* This = dynamic_cast<DisplayWatcher*>((DisplayWatcher*)GetPropA(hWnd, "This"));
- if(This)
- {
- This->UpdatePosition();
- }
- break;
- }
-
- case WM_CHAR:
- case WM_KEYUP:
- {
- DisplayWatcher* This = dynamic_cast<DisplayWatcher*>((DisplayWatcher*)GetPropA(hWnd, "This"));
- if(This)
- {
- if(This->m_bFullScreen && (wParam == 0x1B || wParam == VK_ESCAPE))
- {
- This->SetFullscreen(FALSE);
- }
- }
-
- break;
- }
- }
-
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
+ switch(uMsg) {
+ case WM_CREATE:
+ case WM_SIZE:
+ case WM_MOVE: {
+ DisplayWatcher* This = dynamic_cast<DisplayWatcher*>((DisplayWatcher*)GetPropA(hWnd, "This"));
+ if(This) {
+ This->UpdatePosition();
+ }
+ break;
+ }
+
+ case WM_CHAR:
+ case WM_KEYUP: {
+ DisplayWatcher* This = dynamic_cast<DisplayWatcher*>((DisplayWatcher*)GetPropA(hWnd, "This"));
+ if(This) {
+ if(This->m_bFullScreen && (wParam == 0x1B || wParam == VK_ESCAPE)) {
+ This->SetFullscreen(FALSE);
+ }
+ }
+
+ break;
+ }
+ }
+
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
} \ No newline at end of file
diff --git a/plugins/pluginWinMF/internals/mf_display_watcher.h b/plugins/pluginWinMF/internals/mf_display_watcher.h
index d41d6a6..127fb35 100755
--- a/plugins/pluginWinMF/internals/mf_display_watcher.h
+++ b/plugins/pluginWinMF/internals/mf_display_watcher.h
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -31,25 +31,25 @@
class DisplayWatcher
{
public:
- DisplayWatcher(HWND hWnd, IMFMediaSink* pMediaSink, HRESULT &hr);
- virtual ~DisplayWatcher();
+ DisplayWatcher(HWND hWnd, IMFMediaSink* pMediaSink, HRESULT &hr);
+ virtual ~DisplayWatcher();
public:
- HRESULT Start();
- HRESULT SetFullscreen(BOOL bEnabled);
- HRESULT SetHwnd(HWND hWnd);
- HRESULT Stop();
+ HRESULT Start();
+ HRESULT SetFullscreen(BOOL bEnabled);
+ HRESULT SetHwnd(HWND hWnd);
+ HRESULT Stop();
private:
- void UpdatePosition();
- static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ void UpdatePosition();
+ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
private:
- IMFVideoDisplayControl *m_pDisplayControl;
- HWND m_hWnd;
- WNDPROC m_pWndProc;
- BOOL m_bStarted;
- BOOL m_bFullScreen;
+ IMFVideoDisplayControl *m_pDisplayControl;
+ HWND m_hWnd;
+ WNDPROC m_pWndProc;
+ BOOL m_bStarted;
+ BOOL m_bFullScreen;
};
#endif /* PLUGIN_WIN_MF_DISPLAY_WATCHER_H */
diff --git a/plugins/pluginWinMF/internals/mf_sample_grabber.cxx b/plugins/pluginWinMF/internals/mf_sample_grabber.cxx
index 87aa6af..8d148a3 100755
--- a/plugins/pluginWinMF/internals/mf_sample_grabber.cxx
+++ b/plugins/pluginWinMF/internals/mf_sample_grabber.cxx
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -28,108 +28,105 @@
// Create a new instance of the object.
HRESULT SampleGrabberCB::CreateInstance(const struct tmedia_producer_s* pcWrappedProducer, SampleGrabberCB **ppCB)
{
- assert(pcWrappedProducer);
+ assert(pcWrappedProducer);
- *ppCB = new (std::nothrow) SampleGrabberCB(pcWrappedProducer);
+ *ppCB = new (std::nothrow) SampleGrabberCB(pcWrappedProducer);
- if (ppCB == NULL)
- {
- return E_OUTOFMEMORY;
- }
- return S_OK;
+ if (ppCB == NULL) {
+ return E_OUTOFMEMORY;
+ }
+ return S_OK;
}
STDMETHODIMP SampleGrabberCB::QueryInterface(REFIID riid, void** ppv)
{
- static const QITAB qit[] =
- {
- QITABENT(SampleGrabberCB, IMFSampleGrabberSinkCallback),
- QITABENT(SampleGrabberCB, IMFClockStateSink),
- { 0 }
- };
- return QISearch(this, qit, riid, ppv);
+ static const QITAB qit[] = {
+ QITABENT(SampleGrabberCB, IMFSampleGrabberSinkCallback),
+ QITABENT(SampleGrabberCB, IMFClockStateSink),
+ { 0 }
+ };
+ return QISearch(this, qit, riid, ppv);
}
STDMETHODIMP_(ULONG) SampleGrabberCB::AddRef()
{
- return InterlockedIncrement(&m_cRef);
+ return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) SampleGrabberCB::Release()
{
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- {
- delete this;
- }
- return cRef;
+ ULONG cRef = InterlockedDecrement(&m_cRef);
+ if (cRef == 0) {
+ delete this;
+ }
+ return cRef;
}
// IMFClockStateSink methods.
-// In these example, the IMFClockStateSink methods do not perform any actions.
+// In these example, the IMFClockStateSink methods do not perform any actions.
// You can use these methods to track the state of the sample grabber sink.
STDMETHODIMP SampleGrabberCB::OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset)
{
- TSK_DEBUG_INFO("SampleGrabberCB::OnClockStart(%lld, %lld)", hnsSystemTime, llClockStartOffset);
- return S_OK;
+ TSK_DEBUG_INFO("SampleGrabberCB::OnClockStart(%lld, %lld)", hnsSystemTime, llClockStartOffset);
+ return S_OK;
}
STDMETHODIMP SampleGrabberCB::OnClockStop(MFTIME hnsSystemTime)
{
- TSK_DEBUG_INFO("SampleGrabberCB::OnClockStop(%lld)", hnsSystemTime);
- return S_OK;
+ TSK_DEBUG_INFO("SampleGrabberCB::OnClockStop(%lld)", hnsSystemTime);
+ return S_OK;
}
STDMETHODIMP SampleGrabberCB::OnClockPause(MFTIME hnsSystemTime)
{
- TSK_DEBUG_INFO("SampleGrabberCB::OnClockPause(%lld)", hnsSystemTime);
- return S_OK;
+ TSK_DEBUG_INFO("SampleGrabberCB::OnClockPause(%lld)", hnsSystemTime);
+ return S_OK;
}
STDMETHODIMP SampleGrabberCB::OnClockRestart(MFTIME hnsSystemTime)
{
- TSK_DEBUG_INFO("SampleGrabberCB::OnClockRestart(%lld)", hnsSystemTime);
- return S_OK;
+ TSK_DEBUG_INFO("SampleGrabberCB::OnClockRestart(%lld)", hnsSystemTime);
+ return S_OK;
}
STDMETHODIMP SampleGrabberCB::OnClockSetRate(MFTIME hnsSystemTime, float flRate)
{
- TSK_DEBUG_INFO("SampleGrabberCB::OnClockSetRate(%lld, %f)", hnsSystemTime, flRate);
- return S_OK;
+ TSK_DEBUG_INFO("SampleGrabberCB::OnClockSetRate(%lld, %f)", hnsSystemTime, flRate);
+ return S_OK;
}
// IMFSampleGrabberSink methods.
STDMETHODIMP SampleGrabberCB::OnSetPresentationClock(IMFPresentationClock* pClock)
{
- TSK_DEBUG_INFO("SampleGrabberCB::OnSetPresentationClock");
- return S_OK;
+ TSK_DEBUG_INFO("SampleGrabberCB::OnSetPresentationClock");
+ return S_OK;
}
STDMETHODIMP SampleGrabberCB::OnProcessSample(
- REFGUID guidMajorMediaType, DWORD dwSampleFlags,
- LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer,
- DWORD dwSampleSize)
+ REFGUID guidMajorMediaType, DWORD dwSampleFlags,
+ LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer,
+ DWORD dwSampleSize)
{
- if (m_pWrappedProducer && TMEDIA_PRODUCER(m_pWrappedProducer)->enc_cb.callback) {
+ if (m_pWrappedProducer && TMEDIA_PRODUCER(m_pWrappedProducer)->enc_cb.callback) {
#if 1
- if (m_bMuted) {
- // Send zeros. Do not skip sending data to avoid NAT issues and session deconnection.
- // Some TelePresence systems disconnect the session when the remote peer stops sending video data.
- memset((void*)pSampleBuffer, 0, dwSampleSize);
- }
+ if (m_bMuted) {
+ // Send zeros. Do not skip sending data to avoid NAT issues and session deconnection.
+ // Some TelePresence systems disconnect the session when the remote peer stops sending video data.
+ memset((void*)pSampleBuffer, 0, dwSampleSize);
+ }
#endif
- TMEDIA_PRODUCER(m_pWrappedProducer)->enc_cb.callback(TMEDIA_PRODUCER(m_pWrappedProducer)->enc_cb.callback_data, pSampleBuffer, dwSampleSize);
- }
+ TMEDIA_PRODUCER(m_pWrappedProducer)->enc_cb.callback(TMEDIA_PRODUCER(m_pWrappedProducer)->enc_cb.callback_data, pSampleBuffer, dwSampleSize);
+ }
- return S_OK;
+ return S_OK;
}
STDMETHODIMP SampleGrabberCB::OnShutdown()
{
- TSK_DEBUG_INFO("SampleGrabberCB::OnShutdown");
- return S_OK;
+ TSK_DEBUG_INFO("SampleGrabberCB::OnShutdown");
+ return S_OK;
} \ No newline at end of file
diff --git a/plugins/pluginWinMF/internals/mf_sample_grabber.h b/plugins/pluginWinMF/internals/mf_sample_grabber.h
index 858f3c1..9ea239d 100755
--- a/plugins/pluginWinMF/internals/mf_sample_grabber.h
+++ b/plugins/pluginWinMF/internals/mf_sample_grabber.h
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -31,9 +31,9 @@
// Sample Grabber callback [Declaration]
// http://msdn.microsoft.com/en-us/library/windows/desktop/hh184779(v=vs.85).aspx
//
-class SampleGrabberCB : public IMFSampleGrabberSinkCallback
+class SampleGrabberCB : public IMFSampleGrabberSinkCallback
{
- bool m_bMuted;
+ bool m_bMuted;
long m_cRef;
const struct tmedia_producer_s* m_pWrappedProducer;
@@ -42,7 +42,9 @@ class SampleGrabberCB : public IMFSampleGrabberSinkCallback
public:
static HRESULT CreateInstance(const struct tmedia_producer_s* pcWrappedProducer, SampleGrabberCB **ppCB);
- void SetMute(bool bMuted) { m_bMuted = bMuted; }
+ void SetMute(bool bMuted) {
+ m_bMuted = bMuted;
+ }
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
@@ -59,8 +61,8 @@ public:
// IMFSampleGrabberSinkCallback methods
STDMETHODIMP OnSetPresentationClock(IMFPresentationClock* pClock);
STDMETHODIMP OnProcessSample(REFGUID guidMajorMediaType, DWORD dwSampleFlags,
- LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer,
- DWORD dwSampleSize);
+ LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer,
+ DWORD dwSampleSize);
STDMETHODIMP OnShutdown();
};
diff --git a/plugins/pluginWinMF/internals/mf_sample_queue.cxx b/plugins/pluginWinMF/internals/mf_sample_queue.cxx
index 05c2bc6..32630b8 100755
--- a/plugins/pluginWinMF/internals/mf_sample_queue.cxx
+++ b/plugins/pluginWinMF/internals/mf_sample_queue.cxx
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -21,39 +21,38 @@
#include <assert.h>
MFSampleQueue::MFSampleQueue()
-: m_nRefCount(1)
-, m_nCount(0)
+ : m_nRefCount(1)
+ , m_nCount(0)
{
- InitializeCriticalSection(&m_critSec);
+ InitializeCriticalSection(&m_critSec);
- m_anchor.next = &m_anchor;
- m_anchor.prev = &m_anchor;
+ m_anchor.next = &m_anchor;
+ m_anchor.prev = &m_anchor;
}
MFSampleQueue::~MFSampleQueue()
{
- assert(m_nRefCount == 0);
+ assert(m_nRefCount == 0);
- Clear();
+ Clear();
- DeleteCriticalSection(&m_critSec);
+ DeleteCriticalSection(&m_critSec);
}
STDMETHODIMP MFSampleQueue::QueryInterface(REFIID iid, void** ppv)
{
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
STDMETHODIMP_(ULONG) MFSampleQueue::AddRef()
{
- return InterlockedIncrement(&m_nRefCount);
+ return InterlockedIncrement(&m_nRefCount);
}
STDMETHODIMP_(ULONG) MFSampleQueue::Release()
{
- ULONG uCount = InterlockedDecrement(&m_nRefCount);
- if (uCount == 0)
- {
+ ULONG uCount = InterlockedDecrement(&m_nRefCount);
+ if (uCount == 0) {
delete this;
}
// For thread safety, return a temporary variable.
@@ -62,20 +61,18 @@ STDMETHODIMP_(ULONG) MFSampleQueue::Release()
HRESULT MFSampleQueue::Queue(IMFSample* item)
{
- if (item == NULL)
- {
+ if (item == NULL) {
return E_POINTER;
}
Node *pNode = new (std::nothrow) Node(item);
- if (pNode == NULL)
- {
+ if (pNode == NULL) {
return E_OUTOFMEMORY;
}
item->AddRef();
- EnterCriticalSection(&m_critSec);
+ EnterCriticalSection(&m_critSec);
Node *pBefore = m_anchor.prev;
@@ -87,25 +84,23 @@ HRESULT MFSampleQueue::Queue(IMFSample* item)
pNode->prev = pBefore;
pNode->next = pAfter;
- m_nCount++;
+ m_nCount++;
- LeaveCriticalSection(&m_critSec);
+ LeaveCriticalSection(&m_critSec);
return S_OK;
}
-HRESULT MFSampleQueue::Dequeue(IMFSample* *ppItem)
+HRESULT MFSampleQueue::Dequeue(IMFSample**ppItem)
{
- if (ppItem == NULL)
- {
+ if (ppItem == NULL) {
return E_POINTER;
}
- EnterCriticalSection(&m_critSec);
+ EnterCriticalSection(&m_critSec);
- if (IsEmpty())
- {
- LeaveCriticalSection(&m_critSec);
+ if (IsEmpty()) {
+ LeaveCriticalSection(&m_critSec);
return E_FAIL;
}
@@ -120,24 +115,22 @@ HRESULT MFSampleQueue::Dequeue(IMFSample* *ppItem)
*ppItem = pNode->item;
delete pNode;
- m_nCount--;
+ m_nCount--;
- LeaveCriticalSection(&m_critSec);
+ LeaveCriticalSection(&m_critSec);
return S_OK;
}
HRESULT MFSampleQueue::Clear()
{
- EnterCriticalSection(&m_critSec);
+ EnterCriticalSection(&m_critSec);
- Node *n = m_anchor.next;
+ Node *n = m_anchor.next;
// Delete the nodes
- while (n != &m_anchor)
- {
- if (n->item)
- {
+ while (n != &m_anchor) {
+ if (n->item) {
n->item->Release();
}
@@ -150,9 +143,9 @@ HRESULT MFSampleQueue::Clear()
m_anchor.next = &m_anchor;
m_anchor.prev = &m_anchor;
- m_nCount = 0;
+ m_nCount = 0;
- LeaveCriticalSection(&m_critSec);
+ LeaveCriticalSection(&m_critSec);
- return S_OK;
+ return S_OK;
}
diff --git a/plugins/pluginWinMF/internals/mf_sample_queue.h b/plugins/pluginWinMF/internals/mf_sample_queue.h
index b42ecde..b110a06 100755
--- a/plugins/pluginWinMF/internals/mf_sample_queue.h
+++ b/plugins/pluginWinMF/internals/mf_sample_queue.h
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -32,49 +32,52 @@ class MFSampleQueue : public IUnknown
protected:
// Nodes in the linked list
- struct Node
- {
+ struct Node {
Node *prev;
Node *next;
IMFSample* item;
- Node() : prev(NULL), next(NULL)
- {
+ Node() : prev(NULL), next(NULL) {
}
- Node(IMFSample* item) : prev(NULL), next(NULL)
- {
+ Node(IMFSample* item) : prev(NULL), next(NULL) {
this->item = item;
}
- IMFSample* Item() const { return item; }
+ IMFSample* Item() const {
+ return item;
+ }
};
protected:
Node m_anchor;
- long m_nCount;
- CRITICAL_SECTION m_critSec;
+ long m_nCount;
+ CRITICAL_SECTION m_critSec;
private:
- long m_nRefCount;
+ long m_nRefCount;
public:
MFSampleQueue();
virtual ~MFSampleQueue();
- // IUnknown
+ // IUnknown
STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
HRESULT Queue(IMFSample* item);
- HRESULT Dequeue(IMFSample* *ppItem);
+ HRESULT Dequeue(IMFSample**ppItem);
HRESULT Clear();
- inline BOOL IsEmpty() const { return m_anchor.next == &m_anchor; }
- inline long Count() { return m_nCount; }
+ inline BOOL IsEmpty() const {
+ return m_anchor.next == &m_anchor;
+ }
+ inline long Count() {
+ return m_nCount;
+ }
};
diff --git a/plugins/pluginWinMF/internals/mf_utils.cxx b/plugins/pluginWinMF/internals/mf_utils.cxx
index d1f326c..bcb63f1 100755
--- a/plugins/pluginWinMF/internals/mf_utils.cxx
+++ b/plugins/pluginWinMF/internals/mf_utils.cxx
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -74,35 +74,34 @@ const TOPOID MFUtils::g_ullTopoIdSource = 333;
const TOPOID MFUtils::g_ullTopoIdVideoProcessor = 444;
// Preferred VideoSubTypes
-static const VideoSubTypeGuidPair PreferredVideoSubTypeGuidPairs[] =
-{
- { tmedia_chroma_yuv420p, MFVideoFormat_I420 },
- { tmedia_chroma_nv12, MFVideoFormat_NV12 },
- { tmedia_chroma_uyvy422, MFVideoFormat_UYVY },
- { tmedia_chroma_yuyv422, MFVideoFormat_YUY2 },
- /* TODO: Add more YUV formats */
- { tmedia_chroma_rgb565le, MFVideoFormat_RGB565 },
- { tmedia_chroma_bgr24, MFVideoFormat_RGB24 },
- { tmedia_chroma_rgb32, MFVideoFormat_RGB32 },
+static const VideoSubTypeGuidPair PreferredVideoSubTypeGuidPairs[] = {
+ { tmedia_chroma_yuv420p, MFVideoFormat_I420 },
+ { tmedia_chroma_nv12, MFVideoFormat_NV12 },
+ { tmedia_chroma_uyvy422, MFVideoFormat_UYVY },
+ { tmedia_chroma_yuyv422, MFVideoFormat_YUY2 },
+ /* TODO: Add more YUV formats */
+ { tmedia_chroma_rgb565le, MFVideoFormat_RGB565 },
+ { tmedia_chroma_bgr24, MFVideoFormat_RGB24 },
+ { tmedia_chroma_rgb32, MFVideoFormat_RGB32 },
};
static const tsk_size_t PreferredVideoSubTypeGuidPairsCount = sizeof(PreferredVideoSubTypeGuidPairs)/sizeof(PreferredVideoSubTypeGuidPairs[0]);
// Video Processor
-DEFINE_GUID(CLSID_VideoProcessorMFT,
- 0x88753b26, 0x5b24, 0x49bd, 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82);
+DEFINE_GUID(CLSID_VideoProcessorMFT,
+ 0x88753b26, 0x5b24, 0x49bd, 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82);
// {4BE8D3C0-0515-4A37-AD55-E4BAE19AF471}
DEFINE_GUID(CLSID_MF_INTEL_H264EncFilter, // Intel Quick Sync Encoder
-0x4be8d3c0, 0x0515, 0x4a37, 0xad, 0x55, 0xe4, 0xba, 0xe1, 0x9a, 0xf4, 0x71);
+ 0x4be8d3c0, 0x0515, 0x4a37, 0xad, 0x55, 0xe4, 0xba, 0xe1, 0x9a, 0xf4, 0x71);
// {0855C9AC-BC6F-4371-8954-671CCD4EC16F}
DEFINE_GUID(CLSID_MF_INTEL_H264DecFilter, // Intel Quick Sync Decoder
-0x0855c9ac, 0xbc6f, 0x4371, 0x89, 0x54, 0x67, 0x1c, 0xcd, 0x4e, 0xc1, 0x6f);
+ 0x0855c9ac, 0xbc6f, 0x4371, 0x89, 0x54, 0x67, 0x1c, 0xcd, 0x4e, 0xc1, 0x6f);
#if WINVER < 0x0602/* From "sdkddkver.h" and defines the SDK version not the host */
// 6ca50344-051a-4ded-9779-a43305165e35
DEFINE_GUID(CLSID_CMSH264EncoderMFT, // MS H.264 encoder
-0x6ca50344, 0x051a, 0x4ded, 0x97, 0x79, 0xa4, 0x33, 0x05, 0x16, 0x5e, 0x35);
+ 0x6ca50344, 0x051a, 0x4ded, 0x97, 0x79, 0xa4, 0x33, 0x05, 0x16, 0x5e, 0x35);
#endif /* WINVER */
#define IsWin7_OrLater(dwMajorVersion, dwMinorVersion) ( (dwMajorVersion > 6) || ( (dwMajorVersion == 6) && (dwMinorVersion >= 1) ) )
@@ -111,249 +110,231 @@ DEFINE_GUID(CLSID_CMSH264EncoderMFT, // MS H.264 encoder
HRESULT MFUtils::Startup()
{
- if(!g_bStarted)
- {
- HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
- if(SUCCEEDED(hr) || hr == 0x80010106) // 0x80010106 when called from managed code (e.g. Boghe) - More info: http://support.microsoft.com/kb/824480
- {
- hr = MFStartup(MF_VERSION);
- }
- g_bStarted = SUCCEEDED(hr);
-
- OSVERSIONINFO osvi;
- ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&osvi);
- g_dwMajorVersion = osvi.dwMajorVersion;
- g_dwMinorVersion = osvi.dwMinorVersion;
-
- return hr;
- }
- return S_OK;
+ if(!g_bStarted) {
+ HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
+ if(SUCCEEDED(hr) || hr == 0x80010106) { // 0x80010106 when called from managed code (e.g. Boghe) - More info: http://support.microsoft.com/kb/824480
+ hr = MFStartup(MF_VERSION);
+ }
+ g_bStarted = SUCCEEDED(hr);
+
+ OSVERSIONINFO osvi;
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osvi);
+ g_dwMajorVersion = osvi.dwMajorVersion;
+ g_dwMinorVersion = osvi.dwMinorVersion;
+
+ return hr;
+ }
+ return S_OK;
}
HRESULT MFUtils::Shutdown()
{
- if(g_bStarted)
- {
- g_bStarted = false;
- return S_OK;
- }
- return S_OK;
+ if(g_bStarted) {
+ g_bStarted = false;
+ return S_OK;
+ }
+ return S_OK;
}
BOOL MFUtils::IsD3D9Supported()
{
- if (MFUtils::g_bD3D9Checked)
- {
- return MFUtils::g_bD3D9Supported;
- }
- MFUtils::g_bD3D9Checked = TRUE;
- HRESULT hr = S_OK;
- IDirect3D9* pD3D = NULL;
- D3DDISPLAYMODE mode = { 0 };
- D3DPRESENT_PARAMETERS pp = {0};
- IDirect3DDevice9* pDevice = NULL;
-
- CHECK_HR(hr = MFUtils::Startup());
-
- if (!(pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
- {
+ if (MFUtils::g_bD3D9Checked) {
+ return MFUtils::g_bD3D9Supported;
+ }
+ MFUtils::g_bD3D9Checked = TRUE;
+ HRESULT hr = S_OK;
+ IDirect3D9* pD3D = NULL;
+ D3DDISPLAYMODE mode = { 0 };
+ D3DPRESENT_PARAMETERS pp = {0};
+ IDirect3DDevice9* pDevice = NULL;
+
+ CHECK_HR(hr = MFUtils::Startup());
+
+ if (!(pD3D = Direct3DCreate9(D3D_SDK_VERSION))) {
CHECK_HR(hr = E_OUTOFMEMORY);
}
hr = pD3D->GetAdapterDisplayMode(
- D3DADAPTER_DEFAULT,
- &mode
- );
- if (FAILED(hr))
- {
- goto bail;
- }
+ D3DADAPTER_DEFAULT,
+ &mode
+ );
+ if (FAILED(hr)) {
+ goto bail;
+ }
hr = pD3D->CheckDeviceType(
- D3DADAPTER_DEFAULT,
- D3DDEVTYPE_HAL,
- mode.Format,
- D3DFMT_X8R8G8B8,
- TRUE // windowed
- );
- if (FAILED(hr))
- {
- goto bail;
- }
+ D3DADAPTER_DEFAULT,
+ D3DDEVTYPE_HAL,
+ mode.Format,
+ D3DFMT_X8R8G8B8,
+ TRUE // windowed
+ );
+ if (FAILED(hr)) {
+ goto bail;
+ }
pp.BackBufferFormat = D3DFMT_X8R8G8B8;
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
- pp.Windowed = TRUE;
- pp.hDeviceWindow = GetDesktopWindow();
+ pp.Windowed = TRUE;
+ pp.hDeviceWindow = GetDesktopWindow();
hr = pD3D->CreateDevice(
- D3DADAPTER_DEFAULT,
- D3DDEVTYPE_HAL,
- pp.hDeviceWindow,
- D3DCREATE_HARDWARE_VERTEXPROCESSING,
- &pp,
- &pDevice
- );
- if (FAILED(hr))
- {
- goto bail;
- }
-
- // Everythings is OK
- MFUtils::g_bD3D9Supported = TRUE;
- TSK_DEBUG_INFO("D3D9 supported");
+ D3DADAPTER_DEFAULT,
+ D3DDEVTYPE_HAL,
+ pp.hDeviceWindow,
+ D3DCREATE_HARDWARE_VERTEXPROCESSING,
+ &pp,
+ &pDevice
+ );
+ if (FAILED(hr)) {
+ goto bail;
+ }
+
+ // Everythings is OK
+ MFUtils::g_bD3D9Supported = TRUE;
+ TSK_DEBUG_INFO("D3D9 supported");
bail:
- if (!MFUtils::g_bD3D9Supported) {
- TSK_DEBUG_WARN("D3D9 not supported");
- }
- SafeRelease(&pDevice);
- SafeRelease(&pD3D);
- return MFUtils::g_bD3D9Supported;
+ if (!MFUtils::g_bD3D9Supported) {
+ TSK_DEBUG_WARN("D3D9 not supported");
+ }
+ SafeRelease(&pDevice);
+ SafeRelease(&pD3D);
+ return MFUtils::g_bD3D9Supported;
}
BOOL MFUtils::IsLowLatencyH264Supported()
{
- if(MFUtils::g_bLowLatencyH264Checked)
- {
- return MFUtils::g_bLowLatencyH264Supported;
- }
+ if(MFUtils::g_bLowLatencyH264Checked) {
+ return MFUtils::g_bLowLatencyH264Supported;
+ }
#if PLUGIN_MF_DISABLE_CODECS
- MFUtils::g_bLowLatencyH264Checked = TRUE;
- MFUtils::g_bLowLatencyH264Supported = FALSE;
+ MFUtils::g_bLowLatencyH264Checked = TRUE;
+ MFUtils::g_bLowLatencyH264Supported = FALSE;
#else
- Startup();
-
- HRESULT hr = S_OK;
- IMFTransform *pEncoderMFT = NULL;
- IMFTransform *pDecoderMFT = NULL;
- MFCodecVideoH264* pEncoderCodec = NULL;
- MFCodecVideoH264* pDecoderCodec = NULL;
-
- static const BOOL IsEncoderYes = TRUE;
-
- // Encoder
- hr = MFUtils::GetBestCodec(IsEncoderYes, MFMediaType_Video, MFVideoFormat_NV12, MFVideoFormat_H264, &pEncoderMFT);
- if(FAILED(hr))
- {
- TSK_DEBUG_INFO("No low latency H.264 encoder");
- goto bail;
- }
-
- // Decoder
- hr = MFUtils::GetBestCodec(!IsEncoderYes, MFMediaType_Video, MFVideoFormat_H264, MFVideoFormat_NV12, &pDecoderMFT);
- if(FAILED(hr))
- {
- TSK_DEBUG_INFO("No low latency H.264 decoder");
- goto bail;
- }
-
- // Make sure both encoder and decoder are working well. Check encoding/decoding 1080p@30 would work.
-
- TSK_DEBUG_INFO("Probing H.264 MFT encoder...");
- pEncoderCodec = MFCodecVideoH264::CreateCodecH264Main(MFCodecType_Encoder, pEncoderMFT);
- if(!pEncoderCodec)
- {
- CHECK_HR(hr = E_FAIL);
- }
- CHECK_HR(hr = pEncoderCodec->Initialize(
- 30, // FPS
- 1920, // WIDTH
- 1080, // HEIGHT
- tmedia_get_video_bandwidth_kbps_2(1920, 1080, 30) * 1024) // BITRATE
- );
- CHECK_HR(pEncoderCodec->IsSetSliceMaxSizeInBytesSupported(MFUtils::g_bLowLatencyH264SupportsMaxSliceSize));
-
- TSK_DEBUG_INFO("Probing H.264 MFT decoder...");
- pDecoderCodec = MFCodecVideoH264::CreateCodecH264Main(MFCodecType_Decoder, pDecoderMFT);
- if(!pDecoderCodec)
- {
- CHECK_HR(hr = E_FAIL);
- }
- CHECK_HR(hr = pDecoderCodec->Initialize(
- 30, // FPS
- 1920, // WIDTH
- 1080 // HEIGHT
- ));
+ Startup();
+
+ HRESULT hr = S_OK;
+ IMFTransform *pEncoderMFT = NULL;
+ IMFTransform *pDecoderMFT = NULL;
+ MFCodecVideoH264* pEncoderCodec = NULL;
+ MFCodecVideoH264* pDecoderCodec = NULL;
+
+ static const BOOL IsEncoderYes = TRUE;
+
+ // Encoder
+ hr = MFUtils::GetBestCodec(IsEncoderYes, MFMediaType_Video, MFVideoFormat_NV12, MFVideoFormat_H264, &pEncoderMFT);
+ if(FAILED(hr)) {
+ TSK_DEBUG_INFO("No low latency H.264 encoder");
+ goto bail;
+ }
+
+ // Decoder
+ hr = MFUtils::GetBestCodec(!IsEncoderYes, MFMediaType_Video, MFVideoFormat_H264, MFVideoFormat_NV12, &pDecoderMFT);
+ if(FAILED(hr)) {
+ TSK_DEBUG_INFO("No low latency H.264 decoder");
+ goto bail;
+ }
+
+ // Make sure both encoder and decoder are working well. Check encoding/decoding 1080p@30 would work.
+
+ TSK_DEBUG_INFO("Probing H.264 MFT encoder...");
+ pEncoderCodec = MFCodecVideoH264::CreateCodecH264Main(MFCodecType_Encoder, pEncoderMFT);
+ if(!pEncoderCodec) {
+ CHECK_HR(hr = E_FAIL);
+ }
+ CHECK_HR(hr = pEncoderCodec->Initialize(
+ 30, // FPS
+ 1920, // WIDTH
+ 1080, // HEIGHT
+ tmedia_get_video_bandwidth_kbps_2(1920, 1080, 30) * 1024) // BITRATE
+ );
+ CHECK_HR(pEncoderCodec->IsSetSliceMaxSizeInBytesSupported(MFUtils::g_bLowLatencyH264SupportsMaxSliceSize));
+
+ TSK_DEBUG_INFO("Probing H.264 MFT decoder...");
+ pDecoderCodec = MFCodecVideoH264::CreateCodecH264Main(MFCodecType_Decoder, pDecoderMFT);
+ if(!pDecoderCodec) {
+ CHECK_HR(hr = E_FAIL);
+ }
+ CHECK_HR(hr = pDecoderCodec->Initialize(
+ 30, // FPS
+ 1920, // WIDTH
+ 1080 // HEIGHT
+ ));
bail:
- MFUtils::g_bLowLatencyH264Checked = TRUE;
- MFUtils::g_bLowLatencyH264Supported = SUCCEEDED(hr) ? TRUE : FALSE;
- SafeRelease(&pEncoderMFT);
- SafeRelease(&pEncoderCodec);
- SafeRelease(&pDecoderMFT);
- SafeRelease(&pDecoderCodec);
+ MFUtils::g_bLowLatencyH264Checked = TRUE;
+ MFUtils::g_bLowLatencyH264Supported = SUCCEEDED(hr) ? TRUE : FALSE;
+ SafeRelease(&pEncoderMFT);
+ SafeRelease(&pEncoderCodec);
+ SafeRelease(&pDecoderMFT);
+ SafeRelease(&pDecoderCodec);
#endif /* PLUGIN_MF_DISABLE_CODECS */
- return MFUtils::g_bLowLatencyH264Supported;
+ return MFUtils::g_bLowLatencyH264Supported;
}
BOOL MFUtils::IsLowLatencyH264SupportsMaxSliceSize()
{
- return MFUtils::IsLowLatencyH264Supported() && MFUtils::g_bLowLatencyH264SupportsMaxSliceSize;
+ return MFUtils::IsLowLatencyH264Supported() && MFUtils::g_bLowLatencyH264SupportsMaxSliceSize;
}
HRESULT MFUtils::IsAsyncMFT(
- IMFTransform *pMFT, // The MFT to check
- BOOL* pbIsAsync // Whether the MFT is Async
- )
+ IMFTransform *pMFT, // The MFT to check
+ BOOL* pbIsAsync // Whether the MFT is Async
+)
{
- if(!pbIsAsync || !pMFT)
- {
- return E_POINTER;
- }
+ if(!pbIsAsync || !pMFT) {
+ return E_POINTER;
+ }
- IMFAttributes *pAttributes = NULL;
- UINT32 nIsAsync = 0;
- HRESULT hr = S_OK;
+ IMFAttributes *pAttributes = NULL;
+ UINT32 nIsAsync = 0;
+ HRESULT hr = S_OK;
hr = pMFT->GetAttributes(&pAttributes);
- if(SUCCEEDED(hr))
- {
- hr = pAttributes->GetUINT32(MF_TRANSFORM_ASYNC, &nIsAsync);
- }
-
- // Never fails: just say not Async
- CHECK_HR(hr = S_OK);
+ if(SUCCEEDED(hr)) {
+ hr = pAttributes->GetUINT32(MF_TRANSFORM_ASYNC, &nIsAsync);
+ }
+
+ // Never fails: just say not Async
+ CHECK_HR(hr = S_OK);
- *pbIsAsync = !!nIsAsync;
+ *pbIsAsync = !!nIsAsync;
bail:
- return hr;
+ return hr;
}
HRESULT MFUtils::UnlockAsyncMFT(
- IMFTransform *pMFT // The MFT to unlock
- )
+ IMFTransform *pMFT // The MFT to unlock
+)
{
- IMFAttributes *pAttributes = NULL;
- UINT32 nValue = 0;
- HRESULT hr = S_OK;
+ IMFAttributes *pAttributes = NULL;
+ UINT32 nValue = 0;
+ HRESULT hr = S_OK;
hr = pMFT->GetAttributes(&pAttributes);
- if(FAILED(hr))
- {
- hr = S_OK;
- goto bail;
- }
-
- hr = pAttributes->GetUINT32(MF_TRANSFORM_ASYNC, &nValue);
- if(FAILED(hr))
- {
- hr = S_OK;
- goto bail;
- }
-
- if(nValue == TRUE)
- {
- CHECK_HR(hr = pAttributes->SetUINT32(MF_TRANSFORM_ASYNC_UNLOCK, TRUE));
- }
-
+ if(FAILED(hr)) {
+ hr = S_OK;
+ goto bail;
+ }
+
+ hr = pAttributes->GetUINT32(MF_TRANSFORM_ASYNC, &nValue);
+ if(FAILED(hr)) {
+ hr = S_OK;
+ goto bail;
+ }
+
+ if(nValue == TRUE) {
+ CHECK_HR(hr = pAttributes->SetUINT32(MF_TRANSFORM_ASYNC_UNLOCK, TRUE));
+ }
+
bail:
- SafeRelease(&pAttributes);
- return hr;
+ SafeRelease(&pAttributes);
+ return hr;
}
//-------------------------------------------------------------------
// CreatePCMAudioType
@@ -367,7 +348,7 @@ HRESULT MFUtils::CreatePCMAudioType(
UINT32 bitsPerSample, // Bits per sample
UINT32 cChannels, // Number of channels
IMFMediaType **ppType // Receives a pointer to the media type.
- )
+)
{
HRESULT hr = S_OK;
@@ -381,48 +362,39 @@ HRESULT MFUtils::CreatePCMAudioType(
hr = MFCreateMediaType(&pType);
// Set attributes on the type.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, cChannels);
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, sampleRate);
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pType->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, blockAlign);
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, bytesPerSecond);
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, bitsPerSample);
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
// Return the type to the caller.
*ppType = pType;
(*ppType)->AddRef();
@@ -440,13 +412,13 @@ HRESULT MFUtils::CreatePCMAudioType(
// format.
//-------------------------------------------------------------------
HRESULT MFUtils::CreateVideoType(
- const GUID* subType, // video subType
- IMFMediaType **ppType, // Receives a pointer to the media type.
- UINT32 unWidth, // Video width (0 to ignore)
- UINT32 unHeight // Video height (0 to ignore)
- )
+ const GUID* subType, // video subType
+ IMFMediaType **ppType, // Receives a pointer to the media type.
+ UINT32 unWidth, // Video width (0 to ignore)
+ UINT32 unHeight // Video height (0 to ignore)
+)
{
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK;
IMFMediaType *pType = NULL;
@@ -456,17 +428,16 @@ HRESULT MFUtils::CreateVideoType(
CHECK_HR(hr = pType->SetGUID(MF_MT_SUBTYPE, *subType));
- CHECK_HR(hr = pType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE)); // UnCompressed
+ CHECK_HR(hr = pType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE)); // UnCompressed
- CHECK_HR(hr = pType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE)); // UnCompressed
+ CHECK_HR(hr = pType->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, TRUE)); // UnCompressed
- CHECK_HR(hr = pType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
+ CHECK_HR(hr = pType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive));
+
+ if(unWidth > 0 && unHeight > 0) {
+ CHECK_HR(hr = MFSetAttributeSize(pType, MF_MT_FRAME_SIZE, unWidth, unHeight));
+ }
- if(unWidth > 0 && unHeight > 0)
- {
- CHECK_HR(hr = MFSetAttributeSize(pType, MF_MT_FRAME_SIZE, unWidth, unHeight));
- }
-
*ppType = pType;
(*ppType)->AddRef();
@@ -481,7 +452,7 @@ bail:
//-------------------------------------------------------------------
HRESULT MFUtils::ValidateVideoFormat(IMFMediaType *pmt)
{
- GUID major_type = GUID_NULL;
+ GUID major_type = GUID_NULL;
GUID subtype = GUID_NULL;
MFVideoInterlaceMode interlace = MFVideoInterlace_Unknown;
UINT32 val = 0;
@@ -492,8 +463,7 @@ HRESULT MFUtils::ValidateVideoFormat(IMFMediaType *pmt)
// Major type must be video.
CHECK_HR(hr = pmt->GetGUID(MF_MT_MAJOR_TYPE, &major_type));
- if (major_type != MFMediaType_Video)
- {
+ if (major_type != MFMediaType_Video) {
CHECK_HR(hr = MF_E_INVALIDMEDIATYPE);
}
@@ -504,24 +474,20 @@ HRESULT MFUtils::ValidateVideoFormat(IMFMediaType *pmt)
#if 0
// Look for the subtype in our list of accepted types.
- for (DWORD i = 0; i < g_NumVideoSubtypes; i++)
- {
- if (subtype == *g_VideoSubtypes[i])
- {
+ for (DWORD i = 0; i < g_NumVideoSubtypes; i++) {
+ if (subtype == *g_VideoSubtypes[i]) {
bFoundMatchingSubtype = TRUE;
break;
}
}
- if (!bFoundMatchingSubtype)
- {
+ if (!bFoundMatchingSubtype) {
CHECK_HR(hr = MF_E_INVALIDMEDIATYPE);
}
#endif
// Video must be progressive frames.
CHECK_HR(hr = pmt->GetUINT32(MF_MT_INTERLACE_MODE, (UINT32*)&interlace));
- if (interlace != MFVideoInterlace_Progressive)
- {
+ if (interlace != MFVideoInterlace_Progressive) {
CHECK_HR(hr = MF_E_INVALIDMEDIATYPE);
}
@@ -533,9 +499,9 @@ HRESULT MFUtils::ConvertVideoTypeToUncompressedType(
IMFMediaType *pType, // Pointer to an encoded video type.
const GUID& subtype, // Uncompressed subtype (eg, RGB-32, AYUV)
IMFMediaType **ppType // Receives a matching uncompressed video type.
- )
+)
{
- IMFMediaType *pTypeUncomp = NULL;
+ IMFMediaType *pTypeUncomp = NULL;
HRESULT hr = S_OK;
GUID majortype = { 0 };
@@ -543,59 +509,51 @@ HRESULT MFUtils::ConvertVideoTypeToUncompressedType(
hr = pType->GetMajorType(&majortype);
- if (majortype != MFMediaType_Video)
- {
+ if (majortype != MFMediaType_Video) {
return MF_E_INVALIDMEDIATYPE;
}
// Create a new media type and copy over all of the items.
// This ensures that extended color information is retained.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = MFCreateMediaType(&pTypeUncomp);
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pType->CopyAllItems(pTypeUncomp);
}
// Set the subtype.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pTypeUncomp->SetGUID(MF_MT_SUBTYPE, subtype);
}
// Uncompressed means all samples are independent.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pTypeUncomp->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
}
// Fix up PAR if not set on the original type.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = MFGetAttributeRatio(
- pTypeUncomp,
- MF_MT_PIXEL_ASPECT_RATIO,
- (UINT32*)&par.Numerator,
- (UINT32*)&par.Denominator
- );
+ pTypeUncomp,
+ MF_MT_PIXEL_ASPECT_RATIO,
+ (UINT32*)&par.Numerator,
+ (UINT32*)&par.Denominator
+ );
// Default to square pixels.
- if (FAILED(hr))
- {
+ if (FAILED(hr)) {
hr = MFSetAttributeRatio(
- pTypeUncomp,
- MF_MT_PIXEL_ASPECT_RATIO,
- 1, 1
- );
+ pTypeUncomp,
+ MF_MT_PIXEL_ASPECT_RATIO,
+ 1, 1
+ );
}
}
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
*ppType = pTypeUncomp;
(*ppType)->AddRef();
}
@@ -605,21 +563,21 @@ HRESULT MFUtils::ConvertVideoTypeToUncompressedType(
}
HRESULT MFUtils::CreateMediaSample(
- DWORD cbData, // Maximum buffer size
- IMFSample **ppSample // Receives the sample
+ DWORD cbData, // Maximum buffer size
+ IMFSample **ppSample // Receives the sample
)
{
- assert(ppSample);
+ assert(ppSample);
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK;
IMFSample *pSample = NULL;
IMFMediaBuffer *pBuffer = NULL;
- CHECK_HR(hr = MFCreateSample(&pSample));
- CHECK_HR(hr = MFCreateMemoryBuffer(cbData, &pBuffer));
+ CHECK_HR(hr = MFCreateSample(&pSample));
+ CHECK_HR(hr = MFCreateMemoryBuffer(cbData, &pBuffer));
CHECK_HR(hr = pSample->AddBuffer(pBuffer));
-
+
*ppSample = pSample;
(*ppSample)->AddRef();
@@ -631,222 +589,198 @@ bail:
// Gets the best encoder and decoder. Up to the caller to release the returned pointer
HRESULT MFUtils::GetBestCodec(
- BOOL bEncoder, // Whether we request an encoder or not (TRUE=encoder, FALSE=decoder)
- const GUID& mediaType, // The MediaType
- const GUID& inputFormat, // The input MediaFormat (e.g. MFVideoFormat_NV12)
- const GUID& outputFormat, // The output MediaFormat (e.g. MFVideoFormat_H264)
- IMFTransform **ppMFT // Receives the decoder/encoder transform
- )
+ BOOL bEncoder, // Whether we request an encoder or not (TRUE=encoder, FALSE=decoder)
+ const GUID& mediaType, // The MediaType
+ const GUID& inputFormat, // The input MediaFormat (e.g. MFVideoFormat_NV12)
+ const GUID& outputFormat, // The output MediaFormat (e.g. MFVideoFormat_H264)
+ IMFTransform **ppMFT // Receives the decoder/encoder transform
+)
{
- assert(ppMFT);
- assert(mediaType == MFMediaType_Video || mediaType == MFMediaType_Audio); // only audio and video codecs are support for now
-
- *ppMFT = NULL;
-
- HRESULT hr = S_OK;
-
- if(outputFormat == MFVideoFormat_H264 || inputFormat == MFVideoFormat_H264)
- {
- if(bEncoder)
- {
- // Force using Intel Quick Sync Encoder
- hr = CoCreateInstance(CLSID_MF_INTEL_H264EncFilter, NULL,
- CLSCTX_INPROC_SERVER, IID_PPV_ARGS(ppMFT));
- if(SUCCEEDED(hr) && *ppMFT)
- {
- TSK_DEBUG_INFO("Using Intel Quick Sync encoder :)");
- return hr;
- }
- TSK_DEBUG_INFO("Not using Intel Quick Sync encoder :(");
- }
- else
- {
+ assert(ppMFT);
+ assert(mediaType == MFMediaType_Video || mediaType == MFMediaType_Audio); // only audio and video codecs are support for now
+
+ *ppMFT = NULL;
+
+ HRESULT hr = S_OK;
+
+ if(outputFormat == MFVideoFormat_H264 || inputFormat == MFVideoFormat_H264) {
+ if(bEncoder) {
+ // Force using Intel Quick Sync Encoder
+ hr = CoCreateInstance(CLSID_MF_INTEL_H264EncFilter, NULL,
+ CLSCTX_INPROC_SERVER, IID_PPV_ARGS(ppMFT));
+ if(SUCCEEDED(hr) && *ppMFT) {
+ TSK_DEBUG_INFO("Using Intel Quick Sync encoder :)");
+ return hr;
+ }
+ TSK_DEBUG_INFO("Not using Intel Quick Sync encoder :(");
+ }
+ else {
#if !PLUGIN_MF_DISABLE_ASYNC_DECODERS // Intel Quick Sync decoder is asynchronous
- // Force using Intel Quick Sync Decoder
- hr = CoCreateInstance(CLSID_MF_INTEL_H264DecFilter, NULL,
- CLSCTX_INPROC_SERVER, IID_PPV_ARGS(ppMFT));
+ // Force using Intel Quick Sync Decoder
+ hr = CoCreateInstance(CLSID_MF_INTEL_H264DecFilter, NULL,
+ CLSCTX_INPROC_SERVER, IID_PPV_ARGS(ppMFT));
#endif
- if(SUCCEEDED(hr) && *ppMFT)
- {
- TSK_DEBUG_INFO("Using Intel Quick Sync decoder :)");
- return hr;
- }
- TSK_DEBUG_INFO("Not using Intel Quick Sync decoder :(");
- }
- }
-
- UINT32 count = 0;
- BOOL bAsync = FALSE;
- GUID guidActivateCLSID = GUID_NULL;
-
- IMFActivate **ppActivate = NULL;
-
- MFT_REGISTER_TYPE_INFO infoInput = { mediaType, inputFormat };
- MFT_REGISTER_TYPE_INFO infoOutput = { mediaType, outputFormat };
-
- UINT32 unFlags = MFT_ENUM_FLAG_HARDWARE |
- MFT_ENUM_FLAG_SYNCMFT |
- MFT_ENUM_FLAG_ASYNCMFT |
- MFT_ENUM_FLAG_LOCALMFT |
- MFT_ENUM_FLAG_TRANSCODE_ONLY | // Otherwise Intel Quick Sync will not be listed
- MFT_ENUM_FLAG_SORTANDFILTER;
-
- hr = MFTEnumEx(
- (mediaType == MFMediaType_Video) ? (bEncoder ? MFT_CATEGORY_VIDEO_ENCODER : MFT_CATEGORY_VIDEO_DECODER) : (bEncoder ? MFT_CATEGORY_AUDIO_ENCODER : MFT_CATEGORY_AUDIO_DECODER),
- unFlags,
- (inputFormat == GUID_NULL) ? NULL : &infoInput, // Input type
- (outputFormat == GUID_NULL) ? NULL : &infoOutput, // Output type
- &ppActivate,
- &count
- );
-
- for(UINT32 i = 0; i < count; ++i)
- {
- SafeRelease(ppMFT);
- hr = ppActivate[i]->GetGUID(MFT_TRANSFORM_CLSID_Attribute, &guidActivateCLSID);
- if(FAILED(hr))
- {
- continue;
- }
-
- if(bEncoder)
- {
- // Encoder
- if(guidActivateCLSID == CLSID_CMSH264EncoderMFT) // MS H.264 encoder ?
- {
- if(PLUGIN_MF_DISABLE_MS_H264_ENCODER)
- {
- // Microsoft H.264 encoder is disabled
- TSK_DEBUG_INFO("MS H.264 encoder is disabled...skipping");
- continue;
- }
- if(!IsWin8_OrLater(g_dwMajorVersion, g_dwMinorVersion))
- {
- // Microsoft H.264 encoder doesn't support low latency on Win7.
- TSK_DEBUG_INFO("MS H.264 encoder doesn't support low delay on (%ld, %ld)...skipping", g_dwMajorVersion, g_dwMinorVersion);
- continue;
- }
- }
- }
- else
- {
- // Decoder
- if(guidActivateCLSID == CLSID_CMSH264DecoderMFT) // MS H.264 decoder ?
- {
- if(!IsWin8_OrLater(g_dwMajorVersion, g_dwMinorVersion))
- {
- // Microsoft H.264 decoder doesn't support low latency on Win7.
- TSK_DEBUG_INFO("MS H.264 decoder doesn't support low delay on (%ld, %ld)...skipping", g_dwMajorVersion, g_dwMinorVersion);
- continue;
- }
- }
- }
-
- hr = ppActivate[i]->ActivateObject(IID_PPV_ARGS(ppMFT));
- if(SUCCEEDED(hr) && *ppMFT) // For now we just get the first one. FIXME: Give HW encoders/decoders higher priority.
- {
- if(bEncoder)
- {
- // Encoder
-
- }
- else
- {
- // Decoder
+ if(SUCCEEDED(hr) && *ppMFT) {
+ TSK_DEBUG_INFO("Using Intel Quick Sync decoder :)");
+ return hr;
+ }
+ TSK_DEBUG_INFO("Not using Intel Quick Sync decoder :(");
+ }
+ }
+
+ UINT32 count = 0;
+ BOOL bAsync = FALSE;
+ GUID guidActivateCLSID = GUID_NULL;
+
+ IMFActivate **ppActivate = NULL;
+
+ MFT_REGISTER_TYPE_INFO infoInput = { mediaType, inputFormat };
+ MFT_REGISTER_TYPE_INFO infoOutput = { mediaType, outputFormat };
+
+ UINT32 unFlags = MFT_ENUM_FLAG_HARDWARE |
+ MFT_ENUM_FLAG_SYNCMFT |
+ MFT_ENUM_FLAG_ASYNCMFT |
+ MFT_ENUM_FLAG_LOCALMFT |
+ MFT_ENUM_FLAG_TRANSCODE_ONLY | // Otherwise Intel Quick Sync will not be listed
+ MFT_ENUM_FLAG_SORTANDFILTER;
+
+ hr = MFTEnumEx(
+ (mediaType == MFMediaType_Video) ? (bEncoder ? MFT_CATEGORY_VIDEO_ENCODER : MFT_CATEGORY_VIDEO_DECODER) : (bEncoder ? MFT_CATEGORY_AUDIO_ENCODER : MFT_CATEGORY_AUDIO_DECODER),
+ unFlags,
+ (inputFormat == GUID_NULL) ? NULL : &infoInput, // Input type
+ (outputFormat == GUID_NULL) ? NULL : &infoOutput, // Output type
+ &ppActivate,
+ &count
+ );
+
+ for(UINT32 i = 0; i < count; ++i) {
+ SafeRelease(ppMFT);
+ hr = ppActivate[i]->GetGUID(MFT_TRANSFORM_CLSID_Attribute, &guidActivateCLSID);
+ if(FAILED(hr)) {
+ continue;
+ }
+
+ if(bEncoder) {
+ // Encoder
+ if(guidActivateCLSID == CLSID_CMSH264EncoderMFT) { // MS H.264 encoder ?
+ if(PLUGIN_MF_DISABLE_MS_H264_ENCODER) {
+ // Microsoft H.264 encoder is disabled
+ TSK_DEBUG_INFO("MS H.264 encoder is disabled...skipping");
+ continue;
+ }
+ if(!IsWin8_OrLater(g_dwMajorVersion, g_dwMinorVersion)) {
+ // Microsoft H.264 encoder doesn't support low latency on Win7.
+ TSK_DEBUG_INFO("MS H.264 encoder doesn't support low delay on (%ld, %ld)...skipping", g_dwMajorVersion, g_dwMinorVersion);
+ continue;
+ }
+ }
+ }
+ else {
+ // Decoder
+ if(guidActivateCLSID == CLSID_CMSH264DecoderMFT) { // MS H.264 decoder ?
+ if(!IsWin8_OrLater(g_dwMajorVersion, g_dwMinorVersion)) {
+ // Microsoft H.264 decoder doesn't support low latency on Win7.
+ TSK_DEBUG_INFO("MS H.264 decoder doesn't support low delay on (%ld, %ld)...skipping", g_dwMajorVersion, g_dwMinorVersion);
+ continue;
+ }
+ }
+ }
+
+ hr = ppActivate[i]->ActivateObject(IID_PPV_ARGS(ppMFT));
+ if(SUCCEEDED(hr) && *ppMFT) { // For now we just get the first one. FIXME: Give HW encoders/decoders higher priority.
+ if(bEncoder) {
+ // Encoder
+
+ }
+ else {
+ // Decoder
#if PLUGIN_MF_DISABLE_ASYNC_DECODERS
- hr = IsAsyncMFT(*ppMFT, &bAsync);
- if(bAsync)
- {
- TSK_DEBUG_INFO("Skipping async decoder because not supported yet");
- continue; // Async decoders not supported yet
- }
+ hr = IsAsyncMFT(*ppMFT, &bAsync);
+ if(bAsync) {
+ TSK_DEBUG_INFO("Skipping async decoder because not supported yet");
+ continue; // Async decoders not supported yet
+ }
#endif
- }
- break;
- }
- }
-
- for (UINT32 i = 0; i < count; i++)
- {
- ppActivate[i]->Release();
- }
- CoTaskMemFree(ppActivate);
-
- return *ppMFT ? S_OK : MF_E_NOT_FOUND;
+ }
+ break;
+ }
+ }
+
+ for (UINT32 i = 0; i < count; i++) {
+ ppActivate[i]->Release();
+ }
+ CoTaskMemFree(ppActivate);
+
+ return *ppMFT ? S_OK : MF_E_NOT_FOUND;
}
HRESULT MFUtils::IsVideoProcessorSupported(BOOL *pbSupported)
{
- HRESULT hr = S_OK;
- IMFTransform *pTransform = NULL;
-
- if(!pbSupported)
- {
- CHECK_HR(hr = E_POINTER);
- }
-
- hr = CoCreateInstance(CLSID_VideoProcessorMFT, NULL,
- CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pTransform));
- *pbSupported = SUCCEEDED(hr);
- if(FAILED(hr))
- {
- hr = S_OK; // not an error
- }
+ HRESULT hr = S_OK;
+ IMFTransform *pTransform = NULL;
+
+ if(!pbSupported) {
+ CHECK_HR(hr = E_POINTER);
+ }
+
+ hr = CoCreateInstance(CLSID_VideoProcessorMFT, NULL,
+ CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pTransform));
+ *pbSupported = SUCCEEDED(hr);
+ if(FAILED(hr)) {
+ hr = S_OK; // not an error
+ }
bail:
- SafeRelease(&pTransform);
- return hr;
+ SafeRelease(&pTransform);
+ return hr;
}
HRESULT MFUtils::GetBestVideoProcessor(
- const GUID& inputFormat, // The input MediaFormat (e.g. MFVideoFormat_I420)
- const GUID& outputFormat, // The output MediaFormat (e.g. MFVideoFormat_NV12)
- IMFTransform **ppProcessor // Receives the video processor
- )
+ const GUID& inputFormat, // The input MediaFormat (e.g. MFVideoFormat_I420)
+ const GUID& outputFormat, // The output MediaFormat (e.g. MFVideoFormat_NV12)
+ IMFTransform **ppProcessor // Receives the video processor
+)
{
- assert(ppProcessor);
-
- *ppProcessor = NULL;
-
- HRESULT hr = S_OK;
- UINT32 count = 0;
-
- IMFActivate **ppActivate = NULL;
-
- MFT_REGISTER_TYPE_INFO infoInput = { MFMediaType_Video, inputFormat };
- MFT_REGISTER_TYPE_INFO infoOutput = { MFMediaType_Video, outputFormat };
-
- UINT32 unFlags = MFT_ENUM_FLAG_HARDWARE |
- MFT_ENUM_FLAG_SYNCMFT |
- MFT_ENUM_FLAG_LOCALMFT |
- MFT_ENUM_FLAG_SORTANDFILTER;
-
- hr = MFTEnumEx(
- MFT_CATEGORY_VIDEO_PROCESSOR,
- unFlags,
- &infoInput, // Input type
- &infoOutput, // Output type
- &ppActivate,
- &count
- );
-
- for(UINT32 i = 0; i < count; ++i)
- {
- hr = ppActivate[i]->ActivateObject(IID_PPV_ARGS(ppProcessor));
- if(SUCCEEDED(hr) && *ppProcessor)
- {
- break;
- }
- SafeRelease(ppProcessor);
- }
-
- for (UINT32 i = 0; i < count; i++)
- {
- ppActivate[i]->Release();
- }
- CoTaskMemFree(ppActivate);
-
- return *ppProcessor ? S_OK : MF_E_NOT_FOUND;
+ assert(ppProcessor);
+
+ *ppProcessor = NULL;
+
+ HRESULT hr = S_OK;
+ UINT32 count = 0;
+
+ IMFActivate **ppActivate = NULL;
+
+ MFT_REGISTER_TYPE_INFO infoInput = { MFMediaType_Video, inputFormat };
+ MFT_REGISTER_TYPE_INFO infoOutput = { MFMediaType_Video, outputFormat };
+
+ UINT32 unFlags = MFT_ENUM_FLAG_HARDWARE |
+ MFT_ENUM_FLAG_SYNCMFT |
+ MFT_ENUM_FLAG_LOCALMFT |
+ MFT_ENUM_FLAG_SORTANDFILTER;
+
+ hr = MFTEnumEx(
+ MFT_CATEGORY_VIDEO_PROCESSOR,
+ unFlags,
+ &infoInput, // Input type
+ &infoOutput, // Output type
+ &ppActivate,
+ &count
+ );
+
+ for(UINT32 i = 0; i < count; ++i) {
+ hr = ppActivate[i]->ActivateObject(IID_PPV_ARGS(ppProcessor));
+ if(SUCCEEDED(hr) && *ppProcessor) {
+ break;
+ }
+ SafeRelease(ppProcessor);
+ }
+
+ for (UINT32 i = 0; i < count; i++) {
+ ppActivate[i]->Release();
+ }
+ CoTaskMemFree(ppActivate);
+
+ return *ppProcessor ? S_OK : MF_E_NOT_FOUND;
}
// Add an transform node to a topology.
@@ -855,26 +789,26 @@ HRESULT MFUtils::AddTransformNode(
IMFTransform *pMFT, // MFT.
DWORD dwId, // Identifier of the stream sink.
IMFTopologyNode **ppNode // Receives the node pointer.
- )
+)
{
- *ppNode = NULL;
+ *ppNode = NULL;
IMFTopologyNode *pNode = NULL;
- HRESULT hr = S_OK;
-
+ HRESULT hr = S_OK;
+
// Create the node.
CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &pNode));
// Set the object pointer.
CHECK_HR(hr = pNode->SetObject(pMFT));
- CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_STREAMID, dwId));
- CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE));
+ CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_STREAMID, dwId));
+ CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE));
// Add the node to the topology.
CHECK_HR(hr = pTopology->AddNode(pNode));
// Return the pointer to the caller.
*ppNode = pNode;
(*ppNode)->AddRef();
-
+
bail:
SafeRelease(&pNode);
return hr;
@@ -882,13 +816,13 @@ bail:
// Sets the IMFStreamSink pointer on an output node.
HRESULT MFUtils::BindOutputNode(
- IMFTopologyNode *pNode // The Node
- )
+ IMFTopologyNode *pNode // The Node
+)
{
- assert(pNode);
+ assert(pNode);
- HRESULT hr = S_OK;
- IUnknown *pNodeObject = NULL;
+ HRESULT hr = S_OK;
+ IUnknown *pNodeObject = NULL;
IMFActivate *pActivate = NULL;
IMFStreamSink *pStream = NULL;
IMFMediaSink *pSink = NULL;
@@ -905,44 +839,38 @@ HRESULT MFUtils::BindOutputNode(
// First, check if it's an activation object.
CHECK_HR(hr = pNodeObject->QueryInterface(IID_PPV_ARGS(&pActivate)));
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
DWORD dwStreamID = 0;
- // The object pointer is an activation object.
-
+ // The object pointer is an activation object.
+
// Try to create the media sink.
hr = pActivate->ActivateObject(IID_PPV_ARGS(&pSink));
// Look up the stream ID. (Default to zero.)
- if (SUCCEEDED(hr))
- {
- dwStreamID = MFGetAttributeUINT32(pNode, MF_TOPONODE_STREAMID, 0);
+ if (SUCCEEDED(hr)) {
+ dwStreamID = MFGetAttributeUINT32(pNode, MF_TOPONODE_STREAMID, 0);
}
// Now try to get or create the stream sink.
// Check if the media sink already has a stream sink with the requested ID.
- if (SUCCEEDED(hr))
- {
+ if (SUCCEEDED(hr)) {
hr = pSink->GetStreamSinkById(dwStreamID, &pStream);
- if (FAILED(hr))
- {
+ if (FAILED(hr)) {
// Try to add a new stream sink.
hr = pSink->AddStreamSink(dwStreamID, NULL, &pStream);
}
}
- // Replace the node's object pointer with the stream sink.
- if (SUCCEEDED(hr))
- {
+ // Replace the node's object pointer with the stream sink.
+ if (SUCCEEDED(hr)) {
hr = pNode->SetObject(pStream);
}
}
- else
- {
+ else {
// Not an activation object. Is it a stream sink?
hr = pNodeObject->QueryInterface(IID_PPV_ARGS(&pStream));
}
@@ -957,54 +885,54 @@ bail:
// Add an output node to a topology.
HRESULT MFUtils::AddOutputNode(
- IMFTopology *pTopology, // Topology.
- IMFActivate *pActivate, // Media sink activation object.
- DWORD dwId, // Identifier of the stream sink.
- IMFTopologyNode **ppNode) // Receives the node pointer
+ IMFTopology *pTopology, // Topology.
+ IMFActivate *pActivate, // Media sink activation object.
+ DWORD dwId, // Identifier of the stream sink.
+ IMFTopologyNode **ppNode) // Receives the node pointer
{
- IMFTopologyNode *pNode = NULL;
+ IMFTopologyNode *pNode = NULL;
- HRESULT hr = S_OK;
- CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode));
- CHECK_HR(hr = pNode->SetObject(pActivate));
- CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_STREAMID, dwId));
- CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE));
- CHECK_HR(hr = pTopology->AddNode(pNode));
+ HRESULT hr = S_OK;
+ CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pNode));
+ CHECK_HR(hr = pNode->SetObject(pActivate));
+ CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_STREAMID, dwId));
+ CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE));
+ CHECK_HR(hr = pTopology->AddNode(pNode));
- // Return the pointer to the caller.
- *ppNode = pNode;
- (*ppNode)->AddRef();
+ // Return the pointer to the caller.
+ *ppNode = pNode;
+ (*ppNode)->AddRef();
bail:
- SafeRelease(&pNode);
- return hr;
+ SafeRelease(&pNode);
+ return hr;
}
// Add a source node to a topology
HRESULT MFUtils::AddSourceNode(
- IMFTopology *pTopology, // Topology.
- IMFMediaSource *pSource, // Media source.
- IMFPresentationDescriptor *pPD, // Presentation descriptor.
- IMFStreamDescriptor *pSD, // Stream descriptor.
- IMFTopologyNode **ppNode // Receives the node pointer.
- )
+ IMFTopology *pTopology, // Topology.
+ IMFMediaSource *pSource, // Media source.
+ IMFPresentationDescriptor *pPD, // Presentation descriptor.
+ IMFStreamDescriptor *pSD, // Stream descriptor.
+ IMFTopologyNode **ppNode // Receives the node pointer.
+)
{
- IMFTopologyNode *pNode = NULL;
+ IMFTopologyNode *pNode = NULL;
- HRESULT hr = S_OK;
- CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &pNode));
- CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource));
- CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPD));
- CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, pSD));
- CHECK_HR(hr = pTopology->AddNode(pNode));
+ HRESULT hr = S_OK;
+ CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &pNode));
+ CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource));
+ CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPD));
+ CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, pSD));
+ CHECK_HR(hr = pTopology->AddNode(pNode));
- // Return the pointer to the caller.
- *ppNode = pNode;
- (*ppNode)->AddRef();
+ // Return the pointer to the caller.
+ *ppNode = pNode;
+ (*ppNode)->AddRef();
bail:
- SafeRelease(&pNode);
- return hr;
+ SafeRelease(&pNode);
+ return hr;
}
// Create the topology
@@ -1013,386 +941,345 @@ bail:
// \-> (SinkPreview)
//
HRESULT MFUtils::CreateTopology(
- IMFMediaSource *pSource, // Media source
- IMFTransform *pTransform, // Transform filter (e.g. encoder or decoder) to insert between the source and Sink. NULL is valid.
- IMFActivate *pSinkActivateMain, // Main sink (e.g. sample grabber or EVR).
- IMFActivate *pSinkActivatePreview, // Preview sink. Optional. Could be NULL.
- IMFMediaType *pIputTypeMain, // Main sink input MediaType
- IMFTopology **ppTopo // Receives the newly created topology
- )
+ IMFMediaSource *pSource, // Media source
+ IMFTransform *pTransform, // Transform filter (e.g. encoder or decoder) to insert between the source and Sink. NULL is valid.
+ IMFActivate *pSinkActivateMain, // Main sink (e.g. sample grabber or EVR).
+ IMFActivate *pSinkActivatePreview, // Preview sink. Optional. Could be NULL.
+ IMFMediaType *pIputTypeMain, // Main sink input MediaType
+ IMFTopology **ppTopo // Receives the newly created topology
+)
{
- IMFTopology *pTopology = NULL;
- IMFPresentationDescriptor *pPD = NULL;
- IMFStreamDescriptor *pSD = NULL;
- IMFMediaTypeHandler *pHandler = NULL;
- IMFTopologyNode *pNodeSource = NULL;
- IMFTopologyNode *pNodeSinkMain = NULL;
- IMFTopologyNode *pNodeSinkPreview = NULL;
- IMFTopologyNode *pNodeTransform = NULL;
- IMFTopologyNode *pNodeTee = NULL;
- IMFMediaType *pMediaType = NULL;
+ IMFTopology *pTopology = NULL;
+ IMFPresentationDescriptor *pPD = NULL;
+ IMFStreamDescriptor *pSD = NULL;
+ IMFMediaTypeHandler *pHandler = NULL;
+ IMFTopologyNode *pNodeSource = NULL;
+ IMFTopologyNode *pNodeSinkMain = NULL;
+ IMFTopologyNode *pNodeSinkPreview = NULL;
+ IMFTopologyNode *pNodeTransform = NULL;
+ IMFTopologyNode *pNodeTee = NULL;
+ IMFMediaType *pMediaType = NULL;
IMFTransform *pVideoProcessor = NULL;
IMFTopologyNode *pNodeVideoProcessor = NULL;
- IMFTransform *pConvFrameRate = NULL;
- IMFTransform *pConvSize = NULL;
- IMFTransform *pConvColor = NULL;
- IMFTopologyNode *pNodeConvFrameRate = NULL;
- IMFTopologyNode *pNodeConvSize = NULL;
- IMFTopologyNode *pNodeConvColor = NULL;
- IMFMediaType *pTransformInputType = NULL;
- IMFMediaType *pSinkMainInputType = NULL;
- const IMFTopologyNode *pcNodeBeforeSinkMain = NULL;
-
- HRESULT hr = S_OK;
- DWORD cStreams = 0;
- BOOL bSourceFound = FALSE;
- BOOL bSupportedSize = FALSE;
- BOOL bSupportedFps = FALSE;
- BOOL bSupportedFormat = FALSE;
- BOOL bVideoProcessorSupported = FALSE;
- GUID inputMajorType, inputSubType;
-
- CHECK_HR(hr = IsVideoProcessorSupported(&bVideoProcessorSupported));
- CHECK_HR(hr = pIputTypeMain->GetMajorType(&inputMajorType));
-
- CHECK_HR(hr = MFCreateTopology(&pTopology));
- CHECK_HR(hr = pSource->CreatePresentationDescriptor(&pPD));
- CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams));
-
- for (DWORD i = 0; i < cStreams; i++)
- {
- BOOL fSelected = FALSE;
- GUID majorType;
-
- CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(i, &fSelected, &pSD));
- CHECK_HR(hr = pSD->GetMediaTypeHandler(&pHandler));
- CHECK_HR(hr = pHandler->GetMajorType(&majorType));
-
- if (majorType == inputMajorType && fSelected)
- {
- CHECK_HR(hr = AddSourceNode(pTopology, pSource, pPD, pSD, &pNodeSource));
- CHECK_HR(hr = pNodeSource->SetTopoNodeID(MFUtils::g_ullTopoIdSource));
- CHECK_HR(hr = AddOutputNode(pTopology, pSinkActivateMain, 0, &pNodeSinkMain));
- CHECK_HR(hr = pNodeSinkMain->SetTopoNodeID(MFUtils::g_ullTopoIdSinkMain));
- CHECK_HR(hr = MFUtils::BindOutputNode(pNodeSinkMain)); // To avoid MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED
-
- //
- // Create preview
- //
-
- if(pSinkActivatePreview)
- {
- CHECK_HR(hr = AddOutputNode(pTopology, pSinkActivatePreview, 0, &pNodeSinkPreview));
- CHECK_HR(hr = pNodeSinkPreview->SetTopoNodeID(MFUtils::g_ullTopoIdSinkPreview));
- CHECK_HR(hr = MFUtils::BindOutputNode(pNodeSinkPreview));
-
- CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &pNodeTee));
- CHECK_HR(hr = pTopology->AddNode(pNodeTee));
- }
-
- //
- // Create converters
- //
-
- if(majorType == MFMediaType_Video)
- {
- // Even when size matches the topology could add a resizer which doesn't keep ratio when resizing while video processor does.
- if(!bVideoProcessorSupported)
- {
- hr = IsSupported(
- pPD,
- i,
- pIputTypeMain,
- &bSupportedSize,
- &bSupportedFps,
- &bSupportedFormat);
- }
-
- CHECK_HR(hr = pIputTypeMain->GetGUID(MF_MT_SUBTYPE, &inputSubType));
-
- if(!bSupportedSize || !bSupportedFps || !bSupportedFormat)
- {
- // Use video processor single MFT or 3 different MFTs
- if(!pVideoProcessor)
- {
- hr = CoCreateInstance(CLSID_VideoProcessorMFT, NULL,
- CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pVideoProcessor));
- }
- if(!pVideoProcessor)
- {
- // Video Resizer DSP(http://msdn.microsoft.com/en-us/library/windows/desktop/ff819491(v=vs.85).aspx) supports I420 only
- if(!bSupportedSize && !pConvSize && inputSubType == MFVideoFormat_I420)
- {
- hr = CoCreateInstance(CLSID_CResizerDMO, NULL,
- CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pConvSize));
- }
- // Frame Rate Converter DSP(http://msdn.microsoft.com/en-us/library/windows/desktop/ff819100(v=vs.85).aspx) supports neither NV12 nor I420
- /*if(!bSupportedFps && !pConvFrameRate)
- {
- hr = CoCreateInstance(CLSID_CFrameRateConvertDmo, NULL,
- CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pConvFrameRate));
- }*/
- // Color Converter DSP (http://msdn.microsoft.com/en-us/library/windows/desktop/ff819079(v=vs.85).aspx) supports both NV12 and I420
- if(!bSupportedFormat && !pConvColor)
- {
- hr = CoCreateInstance(CLSID_CColorConvertDMO, NULL,
- CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pConvColor));
- }
- }
- }
- else
- {
- // MediaType supported
- CHECK_HR(hr = pHandler->SetCurrentMediaType(pIputTypeMain));
- }
-
- if(pVideoProcessor && !pNodeVideoProcessor)
- {
- CHECK_HR(hr = AddTransformNode(pTopology, pVideoProcessor, 0, &pNodeVideoProcessor));
- CHECK_HR(hr = pNodeVideoProcessor->SetTopoNodeID(MFUtils::g_ullTopoIdVideoProcessor));
- }
- if(pConvColor && !pNodeConvColor)
- {
- CHECK_HR(hr = AddTransformNode(pTopology, pConvColor, 0, &pNodeConvColor));
- }
- if(pConvFrameRate && !pNodeConvFrameRate)
- {
- CHECK_HR(hr = AddTransformNode(pTopology, pConvFrameRate, 0, &pNodeConvFrameRate));
- }
- if(pConvSize && !pNodeConvSize)
- {
- CHECK_HR(hr = AddTransformNode(pTopology, pConvSize, 0, &pNodeConvSize));
- }
- } // if(majorType == MFMediaType_Video)
-
-
- //
- // Set media type
- //
-
- if(pTransform)
- {
- CHECK_HR(hr = AddTransformNode(pTopology, pTransform, 0, &pNodeTransform));
- hr = pTransform->GetInputCurrentType(0, &pTransformInputType);
- if(FAILED(hr))
- {
- pTransformInputType = pIputTypeMain;
- pTransformInputType->AddRef();
- hr = S_OK;
- }
- if(pVideoProcessor)
- {
- CHECK_HR(hr = pVideoProcessor->SetOutputType(0, pTransformInputType, 0));
- }
- else
- {
- if(pConvColor)
- {
- /*CHECK_HR*/(hr = pConvColor->SetOutputType(0, pTransformInputType, 0));
- }
- if(pConvFrameRate)
- {
- /*CHECK_HR*/(hr = pConvFrameRate->SetOutputType(0, pTransformInputType, 0));
- }
- if(pConvSize)
- {
- // Transform requires NV12
- //Video Resizer DSP(http://msdn.microsoft.com/en-us/library/windows/desktop/ff819491(v=vs.85).aspx) doesn't support NV12
- //*CHECK_HR*/(hr = pConvSize->SetOutputType(0, pTransformInputType, 0));
- }
- }
- }
- else
- {
- hr = pNodeSinkMain->GetInputPrefType(0, &pSinkMainInputType);
- if(FAILED(hr))
- {
- pSinkMainInputType = pIputTypeMain;
- pSinkMainInputType->AddRef();
- hr = S_OK;
- }
- if(SUCCEEDED(hr))
- {
- if(pVideoProcessor)
- {
- CHECK_HR(hr = pVideoProcessor->SetOutputType(0, pSinkMainInputType, 0));
- }
- else
- {
- //!\ MUST NOT SET OUTPUT TYPE
- if(pConvColor)
- {
- //*CHECK_HR*/(hr = pConvColor->SetOutputType(0, pSinkMainInputType, 0));
- }
- if(pConvFrameRate)
- {
- //*CHECK_HR*/(hr = pConvFrameRate->SetOutputType(0, pSinkMainInputType, 0));
- }
- if(pConvSize)
- {
- //*CHECK_HR*/(hr = pConvSize->SetOutputType(0, pSinkMainInputType, 0));
- }
- }
- }
- }
-
- //
- // Connect
- //
-
- if(pNodeTee)
- {
- // Connect(Source -> Tee)
- CHECK_HR(hr = pNodeSource->ConnectOutput(0, pNodeTee, 0));
-
- // Connect(Tee -> SinkPreview)
- CHECK_HR(hr = pNodeTee->ConnectOutput(1, pNodeSinkPreview, 0));
-
- // Connect(Tee ->(Processors)
- if(pVideoProcessor)
- {
- CHECK_HR(hr = pNodeTee->ConnectOutput(0, pNodeVideoProcessor, 0));
- pcNodeBeforeSinkMain = pNodeVideoProcessor;
- }
- else if(pNodeConvFrameRate || pNodeConvSize || pNodeConvColor)
- {
- CHECK_HR(hr = ConnectConverters(
- pNodeTee,
- 0,
- pNodeConvFrameRate,
- pNodeConvColor,
- pNodeConvSize
- ));
- pcNodeBeforeSinkMain = pNodeConvSize ? pNodeConvSize : (pNodeConvColor ? pNodeConvColor : pNodeConvFrameRate);
- }
- else
- {
- pcNodeBeforeSinkMain = pNodeTee;
- }
- }
- else
- {
- // Connect(Source -> (Processors))
- if(pVideoProcessor)
- {
- CHECK_HR(hr = pNodeSource->ConnectOutput(0, pNodeVideoProcessor, 0));
- pcNodeBeforeSinkMain = pNodeVideoProcessor;
- }
- else if(pNodeConvFrameRate || pNodeConvFrameRate || pNodeConvColor)
- {
- CHECK_HR(hr = ConnectConverters(
- pNodeSource,
- 0,
- pNodeConvFrameRate,
- pNodeConvSize,
- pNodeConvColor
- ));
- pcNodeBeforeSinkMain = pNodeConvSize ? pNodeConvSize : (pNodeConvColor ? pNodeConvColor : pNodeConvFrameRate);
- }
- else
- {
- pcNodeBeforeSinkMain = pNodeSource;
- }
- }
-
-
- if(pNodeTransform)
- {
- // Connect(X->Transform)
- CHECK_HR(hr = ((IMFTopologyNode *)pcNodeBeforeSinkMain)->ConnectOutput(0, pNodeTransform, 0));
- pcNodeBeforeSinkMain = pNodeTransform;
- }
-
- // Connect(X -> SinkMain)
- CHECK_HR(hr = ((IMFTopologyNode *)pcNodeBeforeSinkMain)->ConnectOutput(0, pNodeSinkMain, 0));
-
- bSourceFound = TRUE;
- break;
- }
- else
- {
- CHECK_HR(hr = pPD->DeselectStream(i));
- }
- SafeRelease(&pSD);
- SafeRelease(&pHandler);
- }
-
- *ppTopo = pTopology;
- (*ppTopo)->AddRef();
+ IMFTransform *pConvFrameRate = NULL;
+ IMFTransform *pConvSize = NULL;
+ IMFTransform *pConvColor = NULL;
+ IMFTopologyNode *pNodeConvFrameRate = NULL;
+ IMFTopologyNode *pNodeConvSize = NULL;
+ IMFTopologyNode *pNodeConvColor = NULL;
+ IMFMediaType *pTransformInputType = NULL;
+ IMFMediaType *pSinkMainInputType = NULL;
+ const IMFTopologyNode *pcNodeBeforeSinkMain = NULL;
+
+ HRESULT hr = S_OK;
+ DWORD cStreams = 0;
+ BOOL bSourceFound = FALSE;
+ BOOL bSupportedSize = FALSE;
+ BOOL bSupportedFps = FALSE;
+ BOOL bSupportedFormat = FALSE;
+ BOOL bVideoProcessorSupported = FALSE;
+ GUID inputMajorType, inputSubType;
+
+ CHECK_HR(hr = IsVideoProcessorSupported(&bVideoProcessorSupported));
+ CHECK_HR(hr = pIputTypeMain->GetMajorType(&inputMajorType));
+
+ CHECK_HR(hr = MFCreateTopology(&pTopology));
+ CHECK_HR(hr = pSource->CreatePresentationDescriptor(&pPD));
+ CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams));
+
+ for (DWORD i = 0; i < cStreams; i++) {
+ BOOL fSelected = FALSE;
+ GUID majorType;
+
+ CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(i, &fSelected, &pSD));
+ CHECK_HR(hr = pSD->GetMediaTypeHandler(&pHandler));
+ CHECK_HR(hr = pHandler->GetMajorType(&majorType));
+
+ if (majorType == inputMajorType && fSelected) {
+ CHECK_HR(hr = AddSourceNode(pTopology, pSource, pPD, pSD, &pNodeSource));
+ CHECK_HR(hr = pNodeSource->SetTopoNodeID(MFUtils::g_ullTopoIdSource));
+ CHECK_HR(hr = AddOutputNode(pTopology, pSinkActivateMain, 0, &pNodeSinkMain));
+ CHECK_HR(hr = pNodeSinkMain->SetTopoNodeID(MFUtils::g_ullTopoIdSinkMain));
+ CHECK_HR(hr = MFUtils::BindOutputNode(pNodeSinkMain)); // To avoid MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED
+
+ //
+ // Create preview
+ //
+
+ if(pSinkActivatePreview) {
+ CHECK_HR(hr = AddOutputNode(pTopology, pSinkActivatePreview, 0, &pNodeSinkPreview));
+ CHECK_HR(hr = pNodeSinkPreview->SetTopoNodeID(MFUtils::g_ullTopoIdSinkPreview));
+ CHECK_HR(hr = MFUtils::BindOutputNode(pNodeSinkPreview));
+
+ CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &pNodeTee));
+ CHECK_HR(hr = pTopology->AddNode(pNodeTee));
+ }
+
+ //
+ // Create converters
+ //
+
+ if(majorType == MFMediaType_Video) {
+ // Even when size matches the topology could add a resizer which doesn't keep ratio when resizing while video processor does.
+ if(!bVideoProcessorSupported) {
+ hr = IsSupported(
+ pPD,
+ i,
+ pIputTypeMain,
+ &bSupportedSize,
+ &bSupportedFps,
+ &bSupportedFormat);
+ }
+
+ CHECK_HR(hr = pIputTypeMain->GetGUID(MF_MT_SUBTYPE, &inputSubType));
+
+ if(!bSupportedSize || !bSupportedFps || !bSupportedFormat) {
+ // Use video processor single MFT or 3 different MFTs
+ if(!pVideoProcessor) {
+ hr = CoCreateInstance(CLSID_VideoProcessorMFT, NULL,
+ CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pVideoProcessor));
+ }
+ if(!pVideoProcessor) {
+ // Video Resizer DSP(http://msdn.microsoft.com/en-us/library/windows/desktop/ff819491(v=vs.85).aspx) supports I420 only
+ if(!bSupportedSize && !pConvSize && inputSubType == MFVideoFormat_I420) {
+ hr = CoCreateInstance(CLSID_CResizerDMO, NULL,
+ CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pConvSize));
+ }
+ // Frame Rate Converter DSP(http://msdn.microsoft.com/en-us/library/windows/desktop/ff819100(v=vs.85).aspx) supports neither NV12 nor I420
+ /*if(!bSupportedFps && !pConvFrameRate)
+ {
+ hr = CoCreateInstance(CLSID_CFrameRateConvertDmo, NULL,
+ CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pConvFrameRate));
+ }*/
+ // Color Converter DSP (http://msdn.microsoft.com/en-us/library/windows/desktop/ff819079(v=vs.85).aspx) supports both NV12 and I420
+ if(!bSupportedFormat && !pConvColor) {
+ hr = CoCreateInstance(CLSID_CColorConvertDMO, NULL,
+ CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pConvColor));
+ }
+ }
+ }
+ else {
+ // MediaType supported
+ CHECK_HR(hr = pHandler->SetCurrentMediaType(pIputTypeMain));
+ }
+
+ if(pVideoProcessor && !pNodeVideoProcessor) {
+ CHECK_HR(hr = AddTransformNode(pTopology, pVideoProcessor, 0, &pNodeVideoProcessor));
+ CHECK_HR(hr = pNodeVideoProcessor->SetTopoNodeID(MFUtils::g_ullTopoIdVideoProcessor));
+ }
+ if(pConvColor && !pNodeConvColor) {
+ CHECK_HR(hr = AddTransformNode(pTopology, pConvColor, 0, &pNodeConvColor));
+ }
+ if(pConvFrameRate && !pNodeConvFrameRate) {
+ CHECK_HR(hr = AddTransformNode(pTopology, pConvFrameRate, 0, &pNodeConvFrameRate));
+ }
+ if(pConvSize && !pNodeConvSize) {
+ CHECK_HR(hr = AddTransformNode(pTopology, pConvSize, 0, &pNodeConvSize));
+ }
+ } // if(majorType == MFMediaType_Video)
+
+
+ //
+ // Set media type
+ //
+
+ if(pTransform) {
+ CHECK_HR(hr = AddTransformNode(pTopology, pTransform, 0, &pNodeTransform));
+ hr = pTransform->GetInputCurrentType(0, &pTransformInputType);
+ if(FAILED(hr)) {
+ pTransformInputType = pIputTypeMain;
+ pTransformInputType->AddRef();
+ hr = S_OK;
+ }
+ if(pVideoProcessor) {
+ CHECK_HR(hr = pVideoProcessor->SetOutputType(0, pTransformInputType, 0));
+ }
+ else {
+ if(pConvColor) {
+ /*CHECK_HR*/(hr = pConvColor->SetOutputType(0, pTransformInputType, 0));
+ }
+ if(pConvFrameRate) {
+ /*CHECK_HR*/(hr = pConvFrameRate->SetOutputType(0, pTransformInputType, 0));
+ }
+ if(pConvSize) {
+ // Transform requires NV12
+ //Video Resizer DSP(http://msdn.microsoft.com/en-us/library/windows/desktop/ff819491(v=vs.85).aspx) doesn't support NV12
+ //*CHECK_HR*/(hr = pConvSize->SetOutputType(0, pTransformInputType, 0));
+ }
+ }
+ }
+ else {
+ hr = pNodeSinkMain->GetInputPrefType(0, &pSinkMainInputType);
+ if(FAILED(hr)) {
+ pSinkMainInputType = pIputTypeMain;
+ pSinkMainInputType->AddRef();
+ hr = S_OK;
+ }
+ if(SUCCEEDED(hr)) {
+ if(pVideoProcessor) {
+ CHECK_HR(hr = pVideoProcessor->SetOutputType(0, pSinkMainInputType, 0));
+ }
+ else {
+ //!\ MUST NOT SET OUTPUT TYPE
+ if(pConvColor) {
+ //*CHECK_HR*/(hr = pConvColor->SetOutputType(0, pSinkMainInputType, 0));
+ }
+ if(pConvFrameRate) {
+ //*CHECK_HR*/(hr = pConvFrameRate->SetOutputType(0, pSinkMainInputType, 0));
+ }
+ if(pConvSize) {
+ //*CHECK_HR*/(hr = pConvSize->SetOutputType(0, pSinkMainInputType, 0));
+ }
+ }
+ }
+ }
+
+ //
+ // Connect
+ //
+
+ if(pNodeTee) {
+ // Connect(Source -> Tee)
+ CHECK_HR(hr = pNodeSource->ConnectOutput(0, pNodeTee, 0));
+
+ // Connect(Tee -> SinkPreview)
+ CHECK_HR(hr = pNodeTee->ConnectOutput(1, pNodeSinkPreview, 0));
+
+ // Connect(Tee ->(Processors)
+ if(pVideoProcessor) {
+ CHECK_HR(hr = pNodeTee->ConnectOutput(0, pNodeVideoProcessor, 0));
+ pcNodeBeforeSinkMain = pNodeVideoProcessor;
+ }
+ else if(pNodeConvFrameRate || pNodeConvSize || pNodeConvColor) {
+ CHECK_HR(hr = ConnectConverters(
+ pNodeTee,
+ 0,
+ pNodeConvFrameRate,
+ pNodeConvColor,
+ pNodeConvSize
+ ));
+ pcNodeBeforeSinkMain = pNodeConvSize ? pNodeConvSize : (pNodeConvColor ? pNodeConvColor : pNodeConvFrameRate);
+ }
+ else {
+ pcNodeBeforeSinkMain = pNodeTee;
+ }
+ }
+ else {
+ // Connect(Source -> (Processors))
+ if(pVideoProcessor) {
+ CHECK_HR(hr = pNodeSource->ConnectOutput(0, pNodeVideoProcessor, 0));
+ pcNodeBeforeSinkMain = pNodeVideoProcessor;
+ }
+ else if(pNodeConvFrameRate || pNodeConvFrameRate || pNodeConvColor) {
+ CHECK_HR(hr = ConnectConverters(
+ pNodeSource,
+ 0,
+ pNodeConvFrameRate,
+ pNodeConvSize,
+ pNodeConvColor
+ ));
+ pcNodeBeforeSinkMain = pNodeConvSize ? pNodeConvSize : (pNodeConvColor ? pNodeConvColor : pNodeConvFrameRate);
+ }
+ else {
+ pcNodeBeforeSinkMain = pNodeSource;
+ }
+ }
+
+
+ if(pNodeTransform) {
+ // Connect(X->Transform)
+ CHECK_HR(hr = ((IMFTopologyNode *)pcNodeBeforeSinkMain)->ConnectOutput(0, pNodeTransform, 0));
+ pcNodeBeforeSinkMain = pNodeTransform;
+ }
+
+ // Connect(X -> SinkMain)
+ CHECK_HR(hr = ((IMFTopologyNode *)pcNodeBeforeSinkMain)->ConnectOutput(0, pNodeSinkMain, 0));
+
+ bSourceFound = TRUE;
+ break;
+ }
+ else {
+ CHECK_HR(hr = pPD->DeselectStream(i));
+ }
+ SafeRelease(&pSD);
+ SafeRelease(&pHandler);
+ }
+
+ *ppTopo = pTopology;
+ (*ppTopo)->AddRef();
bail:
- SafeRelease(&pTopology);
- SafeRelease(&pNodeSource);
- SafeRelease(&pNodeSinkMain);
- SafeRelease(&pNodeSinkPreview);
- SafeRelease(&pNodeTransform);
- SafeRelease(&pNodeTee);
- SafeRelease(&pPD);
- SafeRelease(&pSD);
- SafeRelease(&pHandler);
- SafeRelease(&pMediaType);
- SafeRelease(&pTransformInputType);
- SafeRelease(&pSinkMainInputType);
-
- SafeRelease(&pVideoProcessor);
+ SafeRelease(&pTopology);
+ SafeRelease(&pNodeSource);
+ SafeRelease(&pNodeSinkMain);
+ SafeRelease(&pNodeSinkPreview);
+ SafeRelease(&pNodeTransform);
+ SafeRelease(&pNodeTee);
+ SafeRelease(&pPD);
+ SafeRelease(&pSD);
+ SafeRelease(&pHandler);
+ SafeRelease(&pMediaType);
+ SafeRelease(&pTransformInputType);
+ SafeRelease(&pSinkMainInputType);
+
+ SafeRelease(&pVideoProcessor);
SafeRelease(&pNodeVideoProcessor);
- SafeRelease(&pConvFrameRate);
- SafeRelease(&pConvSize);
- SafeRelease(&pConvColor);
- SafeRelease(&pNodeConvFrameRate);
- SafeRelease(&pNodeConvSize);
- SafeRelease(&pNodeConvColor);
-
- if(!bSourceFound)
- {
- TSK_DEBUG_ERROR("No source node found");
- return E_NOT_SET;
- }
-
- return hr;
+ SafeRelease(&pConvFrameRate);
+ SafeRelease(&pConvSize);
+ SafeRelease(&pConvColor);
+ SafeRelease(&pNodeConvFrameRate);
+ SafeRelease(&pNodeConvSize);
+ SafeRelease(&pNodeConvColor);
+
+ if(!bSourceFound) {
+ TSK_DEBUG_ERROR("No source node found");
+ return E_NOT_SET;
+ }
+
+ return hr;
}
// Creates a fully loaded topology from the input partial topology.
HRESULT MFUtils::ResolveTopology(
- IMFTopology *pInputTopo, // A pointer to the IMFTopology interface of the partial topology to be resolved.
- IMFTopology **ppOutputTopo, // Receives a pointer to the IMFTopology interface of the completed topology. The caller must release the interface.
- IMFTopology *pCurrentTopo /*= NULL*/ // A pointer to the IMFTopology interface of the previous full topology. The topology loader can re-use objects from this topology in the new topology. This parameter can be NULL.
- )
+ IMFTopology *pInputTopo, // A pointer to the IMFTopology interface of the partial topology to be resolved.
+ IMFTopology **ppOutputTopo, // Receives a pointer to the IMFTopology interface of the completed topology. The caller must release the interface.
+ IMFTopology *pCurrentTopo /*= NULL*/ // A pointer to the IMFTopology interface of the previous full topology. The topology loader can re-use objects from this topology in the new topology. This parameter can be NULL.
+)
{
- assert(ppOutputTopo && pInputTopo);
-
- HRESULT hr = S_OK;
- IMFTopoLoader* pTopoLoader = NULL;
-
- *ppOutputTopo = NULL;
-
- CHECK_HR(hr = MFCreateTopoLoader(&pTopoLoader));
- CHECK_HR(hr = pTopoLoader->Load(pInputTopo, ppOutputTopo, pCurrentTopo));
-
+ assert(ppOutputTopo && pInputTopo);
+
+ HRESULT hr = S_OK;
+ IMFTopoLoader* pTopoLoader = NULL;
+
+ *ppOutputTopo = NULL;
+
+ CHECK_HR(hr = MFCreateTopoLoader(&pTopoLoader));
+ CHECK_HR(hr = pTopoLoader->Load(pInputTopo, ppOutputTopo, pCurrentTopo));
+
bail:
- SafeRelease(&pTopoLoader);
- return hr;
+ SafeRelease(&pTopoLoader);
+ return hr;
}
HRESULT MFUtils::FindNodeObject(
- IMFTopology *pInputTopo, // The Topology containing the node to find
- TOPOID qwTopoNodeID, //The identifier for the node
- void** ppObject // Receives the Object
- )
+ IMFTopology *pInputTopo, // The Topology containing the node to find
+ TOPOID qwTopoNodeID, //The identifier for the node
+ void** ppObject // Receives the Object
+)
{
- assert(pInputTopo && ppObject);
+ assert(pInputTopo && ppObject);
- *ppObject = NULL;
+ *ppObject = NULL;
- IMFTopologyNode *pNode = NULL;
- HRESULT hr = S_OK;
+ IMFTopologyNode *pNode = NULL;
+ HRESULT hr = S_OK;
- CHECK_HR(hr = pInputTopo->GetNodeByID(qwTopoNodeID, &pNode));
- CHECK_HR(hr = pNode->GetObject((IUnknown**)ppObject));
+ CHECK_HR(hr = pInputTopo->GetNodeByID(qwTopoNodeID, &pNode));
+ CHECK_HR(hr = pNode->GetObject((IUnknown**)ppObject));
bail:
- SafeRelease(&pNode);
- return hr;
+ SafeRelease(&pNode);
+ return hr;
}
// Create an activation object for a renderer, based on the stream media type.
@@ -1402,7 +1289,7 @@ HRESULT MFUtils::CreateMediaSinkActivate(
IMFActivate **ppActivate
)
{
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK;
IMFMediaTypeHandler *pHandler = NULL;
IMFActivate *pActivate = NULL;
@@ -1411,29 +1298,25 @@ HRESULT MFUtils::CreateMediaSinkActivate(
// Get the major media type.
GUID guidMajorType;
CHECK_HR(hr = pHandler->GetMajorType(&guidMajorType));
-
+
// Create an IMFActivate object for the renderer, based on the media type.
- if (MFMediaType_Audio == guidMajorType)
- {
+ if (MFMediaType_Audio == guidMajorType) {
// Create the audio renderer.
CHECK_HR(hr = MFCreateAudioRendererActivate(&pActivate));
}
- else if (MFMediaType_Video == guidMajorType)
- {
+ else if (MFMediaType_Video == guidMajorType) {
// Create the video renderer.
CHECK_HR(hr = MFCreateVideoRendererActivate(hVideoWindow, &pActivate));
}
- else
- {
- // Unknown stream type.
+ else {
+ // Unknown stream type.
hr = E_FAIL;
// Optionally, you could deselect this stream instead of failing.
}
- if (FAILED(hr))
- {
+ if (FAILED(hr)) {
goto bail;
}
-
+
// Return IMFActivate pointer to caller.
*ppActivate = pActivate;
(*ppActivate)->AddRef();
@@ -1447,92 +1330,87 @@ bail:
// Set source output media type
HRESULT MFUtils::SetMediaType(
IMFMediaSource *pSource, // Media source.
- IMFMediaType* pMediaType // Media Type.
- )
+ IMFMediaType* pMediaType // Media Type.
+)
{
- assert(pSource && pMediaType);
-
- IMFPresentationDescriptor *pPD = NULL;
- IMFStreamDescriptor *pSD = NULL;
- IMFMediaTypeHandler *pHandler = NULL;
-
- HRESULT hr = S_OK;
- DWORD cStreams = 0;
- GUID inputMajorType;
-
- CHECK_HR(hr = pSource->CreatePresentationDescriptor(&pPD));
- CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams));
- CHECK_HR(hr = pMediaType->GetMajorType(&inputMajorType));
-
- for (DWORD i = 0; i < cStreams; i++)
- {
- BOOL fSelected = FALSE;
- GUID majorType;
-
- CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(i, &fSelected, &pSD));
- CHECK_HR(hr = pSD->GetMediaTypeHandler(&pHandler));
- CHECK_HR(hr = pHandler->GetMajorType(&majorType));
-
- if (majorType == inputMajorType && fSelected)
- {
- CHECK_HR(hr = pHandler->SetCurrentMediaType(pMediaType));
- }
- else
- {
- CHECK_HR(hr = pPD->DeselectStream(i));
- }
- SafeRelease(&pSD);
- SafeRelease(&pHandler);
- }
+ assert(pSource && pMediaType);
+
+ IMFPresentationDescriptor *pPD = NULL;
+ IMFStreamDescriptor *pSD = NULL;
+ IMFMediaTypeHandler *pHandler = NULL;
+
+ HRESULT hr = S_OK;
+ DWORD cStreams = 0;
+ GUID inputMajorType;
+
+ CHECK_HR(hr = pSource->CreatePresentationDescriptor(&pPD));
+ CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams));
+ CHECK_HR(hr = pMediaType->GetMajorType(&inputMajorType));
+
+ for (DWORD i = 0; i < cStreams; i++) {
+ BOOL fSelected = FALSE;
+ GUID majorType;
+
+ CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(i, &fSelected, &pSD));
+ CHECK_HR(hr = pSD->GetMediaTypeHandler(&pHandler));
+ CHECK_HR(hr = pHandler->GetMajorType(&majorType));
+
+ if (majorType == inputMajorType && fSelected) {
+ CHECK_HR(hr = pHandler->SetCurrentMediaType(pMediaType));
+ }
+ else {
+ CHECK_HR(hr = pPD->DeselectStream(i));
+ }
+ SafeRelease(&pSD);
+ SafeRelease(&pHandler);
+ }
bail:
- SafeRelease(&pPD);
- SafeRelease(&pSD);
- SafeRelease(&pHandler);
+ SafeRelease(&pPD);
+ SafeRelease(&pSD);
+ SafeRelease(&pHandler);
- return hr;
+ return hr;
}
HRESULT MFUtils::SetVideoWindow(
IMFTopology *pTopology, // Topology.
IMFMediaSource *pSource, // Media source.
HWND hVideoWnd // Window for video playback.
- )
+)
{
- HRESULT hr = S_OK;
- IMFStreamDescriptor *pSD = NULL;
- IMFPresentationDescriptor *pPD = NULL;
+ HRESULT hr = S_OK;
+ IMFStreamDescriptor *pSD = NULL;
+ IMFPresentationDescriptor *pPD = NULL;
IMFActivate *pSinkActivate = NULL;
IMFTopologyNode *pSourceNode = NULL;
IMFTopologyNode *pOutputNode = NULL;
- DWORD cStreams = 0, iStream;
-
- CHECK_HR(hr = pSource->CreatePresentationDescriptor(&pPD));
- CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams));
-
- for(iStream = 0; iStream < cStreams; ++iStream)
- {
- BOOL fSelected = FALSE;
-
- CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(iStream, &fSelected, &pSD));
-
- if (fSelected)
- {
- // Create the media sink activation object.
- CHECK_HR(hr = CreateMediaSinkActivate(pSD, hVideoWnd, &pSinkActivate));
- // Add a source node for this stream.
- CHECK_HR(hr = AddSourceNode(pTopology, pSource, pPD, pSD, &pSourceNode));
- // Create the output node for the renderer.
- CHECK_HR(hr = AddOutputNode(pTopology, pSinkActivate, 0, &pOutputNode));
- // Connect the source node to the output node.
- CHECK_HR(hr = pSourceNode->ConnectOutput(0, pOutputNode, 0));
- }
- // else: If not selected, don't add the branch.
- }
+ DWORD cStreams = 0, iStream;
+
+ CHECK_HR(hr = pSource->CreatePresentationDescriptor(&pPD));
+ CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams));
+
+ for(iStream = 0; iStream < cStreams; ++iStream) {
+ BOOL fSelected = FALSE;
+
+ CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(iStream, &fSelected, &pSD));
+
+ if (fSelected) {
+ // Create the media sink activation object.
+ CHECK_HR(hr = CreateMediaSinkActivate(pSD, hVideoWnd, &pSinkActivate));
+ // Add a source node for this stream.
+ CHECK_HR(hr = AddSourceNode(pTopology, pSource, pPD, pSD, &pSourceNode));
+ // Create the output node for the renderer.
+ CHECK_HR(hr = AddOutputNode(pTopology, pSinkActivate, 0, &pOutputNode));
+ // Connect the source node to the output node.
+ CHECK_HR(hr = pSourceNode->ConnectOutput(0, pOutputNode, 0));
+ }
+ // else: If not selected, don't add the branch.
+ }
bail:
- SafeRelease(&pPD);
+ SafeRelease(&pPD);
SafeRelease(&pSD);
SafeRelease(&pSinkActivate);
SafeRelease(&pSourceNode);
@@ -1542,407 +1420,374 @@ bail:
// Run the session
HRESULT MFUtils::RunSession(
- IMFMediaSession *pSession, // Session to run
- IMFTopology *pTopology // The toppology
- )
+ IMFMediaSession *pSession, // Session to run
+ IMFTopology *pTopology // The toppology
+)
{
- assert(pSession && pTopology);
-
- IMFMediaEvent *pEvent = NULL;
-
- PROPVARIANT var;
- PropVariantInit(&var);
-
- MediaEventType met;
- HRESULT hrStatus = S_OK;
- HRESULT hr = S_OK;
- CHECK_HR(hr = pSession->SetTopology(MFSESSION_SETTOPOLOGY_IMMEDIATE, pTopology)); // MFSESSION_SETTOPOLOGY_IMMEDIATE required to update (reload) topology when media type change
- CHECK_HR(hr = pSession->Start(&GUID_NULL, &var));
-
- // Check first event
- hr = pSession->GetEvent(MF_EVENT_FLAG_NO_WAIT, &pEvent);
- if(hr == MF_E_NO_EVENTS_AVAILABLE || hr == MF_E_MULTIPLE_SUBSCRIBERS){ // MF_E_MULTIPLE_SUBSCRIBERS means already listening
- hr = S_OK;
- goto bail;
- }
- if(pEvent) {
- CHECK_HR(hr = pEvent->GetStatus(&hrStatus));
- }
- else {
- hrStatus = hr;
- }
- if (FAILED(hrStatus))
- {
- CHECK_HR(hr = pEvent->GetType(&met));
- TSK_DEBUG_ERROR("Session error: 0x%x (event id: %d)\n", hrStatus, met);
- hr = hrStatus;
- goto bail;
- }
+ assert(pSession && pTopology);
+
+ IMFMediaEvent *pEvent = NULL;
+
+ PROPVARIANT var;
+ PropVariantInit(&var);
+
+ MediaEventType met;
+ HRESULT hrStatus = S_OK;
+ HRESULT hr = S_OK;
+ CHECK_HR(hr = pSession->SetTopology(MFSESSION_SETTOPOLOGY_IMMEDIATE, pTopology)); // MFSESSION_SETTOPOLOGY_IMMEDIATE required to update (reload) topology when media type change
+ CHECK_HR(hr = pSession->Start(&GUID_NULL, &var));
+
+ // Check first event
+ hr = pSession->GetEvent(MF_EVENT_FLAG_NO_WAIT, &pEvent);
+ if(hr == MF_E_NO_EVENTS_AVAILABLE || hr == MF_E_MULTIPLE_SUBSCRIBERS) { // MF_E_MULTIPLE_SUBSCRIBERS means already listening
+ hr = S_OK;
+ goto bail;
+ }
+ if(pEvent) {
+ CHECK_HR(hr = pEvent->GetStatus(&hrStatus));
+ }
+ else {
+ hrStatus = hr;
+ }
+ if (FAILED(hrStatus)) {
+ CHECK_HR(hr = pEvent->GetType(&met));
+ TSK_DEBUG_ERROR("Session error: 0x%x (event id: %d)\n", hrStatus, met);
+ hr = hrStatus;
+ goto bail;
+ }
bail:
- SafeRelease(&pEvent);
- return hr;
+ SafeRelease(&pEvent);
+ return hr;
}
// Stop session
HRESULT MFUtils::ShutdownSession(
- IMFMediaSession *pSession, // The Session
- IMFMediaSource *pSource // Source to shutdown (optional)
- )
+ IMFMediaSession *pSession, // The Session
+ IMFMediaSource *pSource // Source to shutdown (optional)
+)
{
- // MUST be source then session
- if(pSource){
- pSource->Stop();
- pSource->Shutdown();
- }
- if(pSession){
- pSession->Shutdown();
- }
- return S_OK;
+ // MUST be source then session
+ if(pSource) {
+ pSource->Stop();
+ pSource->Shutdown();
+ }
+ if(pSession) {
+ pSession->Shutdown();
+ }
+ return S_OK;
}
// Pause session
HRESULT MFUtils::PauseSession(
- IMFMediaSession *pSession, // The session
- IMFMediaSource *pSource // Source to pause (optional)
- )
+ IMFMediaSession *pSession, // The session
+ IMFMediaSource *pSource // Source to pause (optional)
+)
{
- if(!pSession){
- return E_INVALIDARG;
- }
- if(pSource){
- pSource->Pause();
- }
- return pSession->Pause();
+ if(!pSession) {
+ return E_INVALIDARG;
+ }
+ if(pSource) {
+ pSource->Pause();
+ }
+ return pSession->Pause();
}
// Returns -1 if none is supported
INT MFUtils::GetSupportedSubTypeIndex(
- IMFMediaSource *pSource, // The source
- const GUID& mediaType, // The MediaType
- const VideoSubTypeGuidPair* subTypes, UINT subTypesCount // List of preferred subtypes (in ascending order)
- )
+ IMFMediaSource *pSource, // The source
+ const GUID& mediaType, // The MediaType
+ const VideoSubTypeGuidPair* subTypes, UINT subTypesCount // List of preferred subtypes (in ascending order)
+)
{
- assert(pSource);
-
- IMFPresentationDescriptor *pPD = NULL;
- IMFStreamDescriptor *pSD = NULL;
- IMFMediaTypeHandler *pHandler = NULL;
- IMFMediaType *pMediaType = NULL;
-
- INT nIndex = -1;
- HRESULT hr = S_OK;
- DWORD cStreams = 0, cMediaTypesCount;
- GUID majorType, subType;
- BOOL fSelected;
-
- CHECK_HR(hr = pSource->CreatePresentationDescriptor(&pPD));
- CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams));
-
- for (UINT subTypesIndex = 0; subTypesIndex < subTypesCount && nIndex == -1; ++subTypesIndex)
- {
- for (DWORD cStreamIndex = 0; cStreamIndex < cStreams && nIndex == -1; ++cStreamIndex)
- {
- fSelected = FALSE;
- CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(cStreamIndex, &fSelected, &pSD));
- if(fSelected)
- {
- CHECK_HR(hr = pSD->GetMediaTypeHandler(&pHandler));
- CHECK_HR(hr = pHandler->GetMajorType(&majorType));
- if(majorType == mediaType)
- {
- CHECK_HR(hr = pHandler->GetMediaTypeCount(&cMediaTypesCount));
- for(DWORD cMediaTypesIndex = 0; cMediaTypesIndex < cMediaTypesCount && nIndex == -1; ++cMediaTypesIndex)
- {
- CHECK_HR(hr = pHandler->GetMediaTypeByIndex(cMediaTypesIndex, &pMediaType));
- CHECK_HR(hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &subType));
- if (subTypes[subTypesIndex].fourcc == subType)
- {
- nIndex = subTypesIndex;
- break;
- }
- SafeRelease(&pMediaType);
- }
- }
- }
-
- SafeRelease(&pSD);
- SafeRelease(&pHandler);
- }
- }
+ assert(pSource);
+
+ IMFPresentationDescriptor *pPD = NULL;
+ IMFStreamDescriptor *pSD = NULL;
+ IMFMediaTypeHandler *pHandler = NULL;
+ IMFMediaType *pMediaType = NULL;
+
+ INT nIndex = -1;
+ HRESULT hr = S_OK;
+ DWORD cStreams = 0, cMediaTypesCount;
+ GUID majorType, subType;
+ BOOL fSelected;
+
+ CHECK_HR(hr = pSource->CreatePresentationDescriptor(&pPD));
+ CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams));
+
+ for (UINT subTypesIndex = 0; subTypesIndex < subTypesCount && nIndex == -1; ++subTypesIndex) {
+ for (DWORD cStreamIndex = 0; cStreamIndex < cStreams && nIndex == -1; ++cStreamIndex) {
+ fSelected = FALSE;
+ CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(cStreamIndex, &fSelected, &pSD));
+ if(fSelected) {
+ CHECK_HR(hr = pSD->GetMediaTypeHandler(&pHandler));
+ CHECK_HR(hr = pHandler->GetMajorType(&majorType));
+ if(majorType == mediaType) {
+ CHECK_HR(hr = pHandler->GetMediaTypeCount(&cMediaTypesCount));
+ for(DWORD cMediaTypesIndex = 0; cMediaTypesIndex < cMediaTypesCount && nIndex == -1; ++cMediaTypesIndex) {
+ CHECK_HR(hr = pHandler->GetMediaTypeByIndex(cMediaTypesIndex, &pMediaType));
+ CHECK_HR(hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &subType));
+ if (subTypes[subTypesIndex].fourcc == subType) {
+ nIndex = subTypesIndex;
+ break;
+ }
+ SafeRelease(&pMediaType);
+ }
+ }
+ }
+
+ SafeRelease(&pSD);
+ SafeRelease(&pHandler);
+ }
+ }
bail:
- SafeRelease(&pMediaType);
- SafeRelease(&pPD);
- SafeRelease(&pSD);
- SafeRelease(&pHandler);
+ SafeRelease(&pMediaType);
+ SafeRelease(&pPD);
+ SafeRelease(&pSD);
+ SafeRelease(&pHandler);
- return nIndex;
+ return nIndex;
}
HRESULT MFUtils::IsSupported(
- IMFPresentationDescriptor *pPD,
- DWORD cStreamIndex,
- UINT32 nWidth,
- UINT32 nHeight,
- UINT32 nFps,
- const GUID& guidFormat,
- BOOL* pbSupportedSize,
- BOOL* pbSupportedFps,
- BOOL* pbSupportedFormat
- )
+ IMFPresentationDescriptor *pPD,
+ DWORD cStreamIndex,
+ UINT32 nWidth,
+ UINT32 nHeight,
+ UINT32 nFps,
+ const GUID& guidFormat,
+ BOOL* pbSupportedSize,
+ BOOL* pbSupportedFps,
+ BOOL* pbSupportedFormat
+)
{
- HRESULT hr = S_OK;
-
- BOOL fSelected = FALSE;
- IMFStreamDescriptor *pSD = NULL;
- IMFMediaTypeHandler *pHandler = NULL;
- IMFMediaType *pMediaType = NULL;
- UINT32 _nWidth = 0, _nHeight = 0, numeratorFps = 0, denominatorFps = 0;
- GUID subType;
- DWORD cMediaTypesCount;
-
- if(!pPD || !pbSupportedSize || !pbSupportedFps || !pbSupportedFormat)
- {
- CHECK_HR(hr = E_POINTER);
- }
-
- *pbSupportedSize = FALSE;
- *pbSupportedFps = FALSE;
- *pbSupportedFormat = FALSE;
-
- CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(cStreamIndex, &fSelected, &pSD));
- if(fSelected)
- {
- CHECK_HR(hr = pSD->GetMediaTypeHandler(&pHandler));
- CHECK_HR(hr = pHandler->GetMediaTypeCount(&cMediaTypesCount));
- for(DWORD cMediaTypesIndex = 0; cMediaTypesIndex < cMediaTypesCount; ++cMediaTypesIndex)
- {
- CHECK_HR(hr = pHandler->GetMediaTypeByIndex(cMediaTypesIndex, &pMediaType));
- CHECK_HR(hr = MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &_nWidth, &_nHeight));
- CHECK_HR(hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &subType));
- if(FAILED(hr = MFGetAttributeRatio(pMediaType, MF_MT_FRAME_RATE, &numeratorFps, &denominatorFps)))
- {
- numeratorFps = 30;
- denominatorFps = 1;
- }
-
- // all must match for the same stream
- if(_nWidth == nWidth && _nHeight == nHeight && subType == guidFormat && (numeratorFps/denominatorFps) == nFps)
- {
- *pbSupportedSize = TRUE;
- *pbSupportedFormat = TRUE;
- *pbSupportedFps = TRUE;
- break;
- }
-
- SafeRelease(&pMediaType);
- }
- SafeRelease(&pHandler);
- }
-
+ HRESULT hr = S_OK;
+
+ BOOL fSelected = FALSE;
+ IMFStreamDescriptor *pSD = NULL;
+ IMFMediaTypeHandler *pHandler = NULL;
+ IMFMediaType *pMediaType = NULL;
+ UINT32 _nWidth = 0, _nHeight = 0, numeratorFps = 0, denominatorFps = 0;
+ GUID subType;
+ DWORD cMediaTypesCount;
+
+ if(!pPD || !pbSupportedSize || !pbSupportedFps || !pbSupportedFormat) {
+ CHECK_HR(hr = E_POINTER);
+ }
+
+ *pbSupportedSize = FALSE;
+ *pbSupportedFps = FALSE;
+ *pbSupportedFormat = FALSE;
+
+ CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(cStreamIndex, &fSelected, &pSD));
+ if(fSelected) {
+ CHECK_HR(hr = pSD->GetMediaTypeHandler(&pHandler));
+ CHECK_HR(hr = pHandler->GetMediaTypeCount(&cMediaTypesCount));
+ for(DWORD cMediaTypesIndex = 0; cMediaTypesIndex < cMediaTypesCount; ++cMediaTypesIndex) {
+ CHECK_HR(hr = pHandler->GetMediaTypeByIndex(cMediaTypesIndex, &pMediaType));
+ CHECK_HR(hr = MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &_nWidth, &_nHeight));
+ CHECK_HR(hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &subType));
+ if(FAILED(hr = MFGetAttributeRatio(pMediaType, MF_MT_FRAME_RATE, &numeratorFps, &denominatorFps))) {
+ numeratorFps = 30;
+ denominatorFps = 1;
+ }
+
+ // all must match for the same stream
+ if(_nWidth == nWidth && _nHeight == nHeight && subType == guidFormat && (numeratorFps/denominatorFps) == nFps) {
+ *pbSupportedSize = TRUE;
+ *pbSupportedFormat = TRUE;
+ *pbSupportedFps = TRUE;
+ break;
+ }
+
+ SafeRelease(&pMediaType);
+ }
+ SafeRelease(&pHandler);
+ }
+
bail:
- SafeRelease(&pSD);
- SafeRelease(&pHandler);
- SafeRelease(&pMediaType);
-
- return hr;
+ SafeRelease(&pSD);
+ SafeRelease(&pHandler);
+ SafeRelease(&pMediaType);
+
+ return hr;
}
HRESULT MFUtils::IsSupported(
- IMFPresentationDescriptor *pPD,
- DWORD cStreamIndex,
- IMFMediaType* pMediaType,
- BOOL* pbSupportedSize,
- BOOL* pbSupportedFps,
- BOOL* pbSupportedFormat
- )
+ IMFPresentationDescriptor *pPD,
+ DWORD cStreamIndex,
+ IMFMediaType* pMediaType,
+ BOOL* pbSupportedSize,
+ BOOL* pbSupportedFps,
+ BOOL* pbSupportedFormat
+)
{
- HRESULT hr = S_OK;
-
- UINT32 nWidth = 0, nHeight = 0, nFps = 0, numeratorFps = 30, denominatorFps = 1;
- GUID subType;
-
- if(!pPD || !pMediaType || !pbSupportedSize || !pbSupportedFps || !pbSupportedFormat)
- {
- CHECK_HR(hr = E_POINTER);
- }
-
- CHECK_HR(hr = MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &nWidth, &nHeight));
- CHECK_HR(hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &subType));
- if(FAILED(hr = MFGetAttributeRatio(pMediaType, MF_MT_FRAME_RATE, &numeratorFps, &denominatorFps)))
- {
- numeratorFps = 30;
- denominatorFps = 1;
- }
-
- CHECK_HR(hr = IsSupported(
- pPD,
- cStreamIndex,
- nWidth,
- nHeight,
- (numeratorFps / denominatorFps),
- subType,
- pbSupportedSize,
- pbSupportedFps,
- pbSupportedFormat
- ));
+ HRESULT hr = S_OK;
+
+ UINT32 nWidth = 0, nHeight = 0, nFps = 0, numeratorFps = 30, denominatorFps = 1;
+ GUID subType;
+
+ if(!pPD || !pMediaType || !pbSupportedSize || !pbSupportedFps || !pbSupportedFormat) {
+ CHECK_HR(hr = E_POINTER);
+ }
+
+ CHECK_HR(hr = MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &nWidth, &nHeight));
+ CHECK_HR(hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &subType));
+ if(FAILED(hr = MFGetAttributeRatio(pMediaType, MF_MT_FRAME_RATE, &numeratorFps, &denominatorFps))) {
+ numeratorFps = 30;
+ denominatorFps = 1;
+ }
+
+ CHECK_HR(hr = IsSupported(
+ pPD,
+ cStreamIndex,
+ nWidth,
+ nHeight,
+ (numeratorFps / denominatorFps),
+ subType,
+ pbSupportedSize,
+ pbSupportedFps,
+ pbSupportedFormat
+ ));
bail:
- return hr;
+ return hr;
}
HRESULT MFUtils::IsSupportedByInput(
- IMFPresentationDescriptor *pPD,
- DWORD cStreamIndex,
- IMFTopologyNode *pNode,
- BOOL* pbSupportedSize,
- BOOL* pbSupportedFps,
- BOOL* pbSupportedFormat
- )
+ IMFPresentationDescriptor *pPD,
+ DWORD cStreamIndex,
+ IMFTopologyNode *pNode,
+ BOOL* pbSupportedSize,
+ BOOL* pbSupportedFps,
+ BOOL* pbSupportedFormat
+)
{
- HRESULT hr = S_OK;
-
- IMFMediaType *pMediaType = NULL;
- IUnknown* pObject = NULL;
- IMFActivate *pActivate = NULL;
- IMFMediaSink *pMediaSink = NULL;
- IMFTransform *pTransform = NULL;
- IMFStreamSink *pStreamSink = NULL;
- IMFMediaTypeHandler *pHandler = NULL;
-
- if(!pPD || !pNode || !pbSupportedSize || !pbSupportedFps || !pbSupportedFormat)
- {
- CHECK_HR(hr = E_POINTER);
- }
-
- CHECK_HR(hr = pNode->GetObject(&pObject));
- hr = pObject->QueryInterface(IID_PPV_ARGS(&pActivate));
- if(SUCCEEDED(hr))
- {
- SafeRelease(&pObject);
- hr = pActivate->ActivateObject(IID_IMFMediaSink, (void**)&pObject);
- if(FAILED(hr))
- {
- hr = pActivate->ActivateObject(IID_IMFTransform, (void**)&pObject);
- }
- }
-
- if(!pObject)
- {
- CHECK_HR(hr = E_NOINTERFACE);
- }
-
- hr = pObject->QueryInterface(IID_PPV_ARGS(&pMediaSink));
- if(FAILED(hr))
- {
- hr = pObject->QueryInterface(IID_PPV_ARGS(&pTransform));
- }
-
-
-
- if(pMediaSink)
- {
- CHECK_HR(hr = pMediaSink->GetStreamSinkByIndex(0, &pStreamSink));
- CHECK_HR(hr = pStreamSink->GetMediaTypeHandler(&pHandler));
- CHECK_HR(hr = pHandler->GetCurrentMediaType(&pMediaType));
-
- }
- else if(pTransform)
- {
- CHECK_HR(hr = pTransform->GetInputCurrentType(0, &pMediaType));
- }
- else
- {
- CHECK_HR(hr = pNode->GetInputPrefType(0, &pMediaType));
- }
-
- CHECK_HR(hr = IsSupported(
- pPD,
- cStreamIndex,
- pMediaType,
- pbSupportedSize,
- pbSupportedFps,
- pbSupportedFormat
- ));
+ HRESULT hr = S_OK;
+
+ IMFMediaType *pMediaType = NULL;
+ IUnknown* pObject = NULL;
+ IMFActivate *pActivate = NULL;
+ IMFMediaSink *pMediaSink = NULL;
+ IMFTransform *pTransform = NULL;
+ IMFStreamSink *pStreamSink = NULL;
+ IMFMediaTypeHandler *pHandler = NULL;
+
+ if(!pPD || !pNode || !pbSupportedSize || !pbSupportedFps || !pbSupportedFormat) {
+ CHECK_HR(hr = E_POINTER);
+ }
+
+ CHECK_HR(hr = pNode->GetObject(&pObject));
+ hr = pObject->QueryInterface(IID_PPV_ARGS(&pActivate));
+ if(SUCCEEDED(hr)) {
+ SafeRelease(&pObject);
+ hr = pActivate->ActivateObject(IID_IMFMediaSink, (void**)&pObject);
+ if(FAILED(hr)) {
+ hr = pActivate->ActivateObject(IID_IMFTransform, (void**)&pObject);
+ }
+ }
+
+ if(!pObject) {
+ CHECK_HR(hr = E_NOINTERFACE);
+ }
+
+ hr = pObject->QueryInterface(IID_PPV_ARGS(&pMediaSink));
+ if(FAILED(hr)) {
+ hr = pObject->QueryInterface(IID_PPV_ARGS(&pTransform));
+ }
+
+
+
+ if(pMediaSink) {
+ CHECK_HR(hr = pMediaSink->GetStreamSinkByIndex(0, &pStreamSink));
+ CHECK_HR(hr = pStreamSink->GetMediaTypeHandler(&pHandler));
+ CHECK_HR(hr = pHandler->GetCurrentMediaType(&pMediaType));
+
+ }
+ else if(pTransform) {
+ CHECK_HR(hr = pTransform->GetInputCurrentType(0, &pMediaType));
+ }
+ else {
+ CHECK_HR(hr = pNode->GetInputPrefType(0, &pMediaType));
+ }
+
+ CHECK_HR(hr = IsSupported(
+ pPD,
+ cStreamIndex,
+ pMediaType,
+ pbSupportedSize,
+ pbSupportedFps,
+ pbSupportedFormat
+ ));
bail:
- SafeRelease(&pObject);
- SafeRelease(&pActivate);
- SafeRelease(&pMediaType);
- SafeRelease(&pStreamSink);
- SafeRelease(&pHandler);
- return hr;
+ SafeRelease(&pObject);
+ SafeRelease(&pActivate);
+ SafeRelease(&pMediaType);
+ SafeRelease(&pStreamSink);
+ SafeRelease(&pHandler);
+ return hr;
}
HRESULT MFUtils::ConnectConverters(
- IMFTopologyNode *pNode,
- DWORD dwOutputIndex,
- IMFTopologyNode *pNodeConvFrameRate,
- IMFTopologyNode *pNodeConvColor,
- IMFTopologyNode *pNodeConvSize
- )
+ IMFTopologyNode *pNode,
+ DWORD dwOutputIndex,
+ IMFTopologyNode *pNodeConvFrameRate,
+ IMFTopologyNode *pNodeConvColor,
+ IMFTopologyNode *pNodeConvSize
+)
{
- HRESULT hr = S_OK;
-
- if(!pNode)
- {
- CHECK_HR(hr = E_POINTER);
- }
-
- if(pNodeConvFrameRate)
- {
- CHECK_HR(hr = pNode->ConnectOutput(dwOutputIndex, pNodeConvFrameRate, 0));
- if(pNodeConvSize)
- {
- CHECK_HR(hr = pNodeConvFrameRate->ConnectOutput(0, pNodeConvSize, 0));
- if(pNodeConvColor)
- {
- CHECK_HR(hr = pNodeConvSize->ConnectOutput(0, pNodeConvColor, 0));
- }
- }
- else
- {
- if(pNodeConvColor)
- {
- CHECK_HR(hr = pNodeConvFrameRate->ConnectOutput(0, pNodeConvColor, 0));
- }
- }
- }
- else
- {
- if(pNodeConvSize)
- {
- CHECK_HR(hr = pNode->ConnectOutput(dwOutputIndex, pNodeConvSize, 0));
- if(pNodeConvColor)
- {
- CHECK_HR(hr = pNodeConvSize->ConnectOutput(0, pNodeConvColor, 0));
- }
- }
- else
- {
- if(pNodeConvColor)
- {
- CHECK_HR(hr = pNode->ConnectOutput(dwOutputIndex, pNodeConvColor, 0));
- }
- }
- }
+ HRESULT hr = S_OK;
+
+ if(!pNode) {
+ CHECK_HR(hr = E_POINTER);
+ }
+
+ if(pNodeConvFrameRate) {
+ CHECK_HR(hr = pNode->ConnectOutput(dwOutputIndex, pNodeConvFrameRate, 0));
+ if(pNodeConvSize) {
+ CHECK_HR(hr = pNodeConvFrameRate->ConnectOutput(0, pNodeConvSize, 0));
+ if(pNodeConvColor) {
+ CHECK_HR(hr = pNodeConvSize->ConnectOutput(0, pNodeConvColor, 0));
+ }
+ }
+ else {
+ if(pNodeConvColor) {
+ CHECK_HR(hr = pNodeConvFrameRate->ConnectOutput(0, pNodeConvColor, 0));
+ }
+ }
+ }
+ else {
+ if(pNodeConvSize) {
+ CHECK_HR(hr = pNode->ConnectOutput(dwOutputIndex, pNodeConvSize, 0));
+ if(pNodeConvColor) {
+ CHECK_HR(hr = pNodeConvSize->ConnectOutput(0, pNodeConvColor, 0));
+ }
+ }
+ else {
+ if(pNodeConvColor) {
+ CHECK_HR(hr = pNode->ConnectOutput(dwOutputIndex, pNodeConvColor, 0));
+ }
+ }
+ }
bail:
- return hr;
+ return hr;
}
// This function should be called only if VideoProcessor is not supported
HRESULT MFUtils::GetBestFormat(
- IMFMediaSource *pSource,
- const GUID *pSubType,
- UINT32 nWidth,
- UINT32 nHeight,
- UINT32 nFps,
- UINT32 *pnWidth,
- UINT32 *pnHeight,
- UINT32 *pnFps,
- const VideoSubTypeGuidPair **ppSubTypeGuidPair
- )
+ IMFMediaSource *pSource,
+ const GUID *pSubType,
+ UINT32 nWidth,
+ UINT32 nHeight,
+ UINT32 nFps,
+ UINT32 *pnWidth,
+ UINT32 *pnHeight,
+ UINT32 *pnFps,
+ const VideoSubTypeGuidPair **ppSubTypeGuidPair
+)
{
#define _FindPairByGuid(_guid, _index) { \
@@ -1954,151 +1799,146 @@ HRESULT MFUtils::GetBestFormat(
} \
}
#if 0
- *pnWidth = 640;
- *pnHeight = 480;
- *pnFps = 30;
- return S_OK;
-#else
- HRESULT hr = S_OK;
- IMFPresentationDescriptor *pPD = NULL;
- IMFStreamDescriptor *pSD = NULL;
- IMFMediaTypeHandler *pHandler = NULL;
- IMFMediaType *pMediaType = NULL;
- DWORD cStreams = 0, cMediaTypesCount;
- GUID majorType, subType, _BestSubType;
- BOOL bFound = FALSE, fSelected;
- UINT32 _nWidth, _nHeight, numeratorFps, denominatorFps, _nFps, _nScore, _nBestScore;
- int PreferredVideoSubTypeGuidPairIndex;
- static const UINT32 kSubTypeMismatchPad = _UI32_MAX >> 4;
- static const UINT32 kFpsMismatchPad = _UI32_MAX >> 2;
-
- if (!ppSubTypeGuidPair || !pSubType) {
- CHECK_HR(hr = E_INVALIDARG);
- }
- _FindPairByGuid(*pSubType, PreferredVideoSubTypeGuidPairIndex);
- if (PreferredVideoSubTypeGuidPairIndex == -1) {
- CHECK_HR(hr = E_INVALIDARG);
- }
- *ppSubTypeGuidPair = &PreferredVideoSubTypeGuidPairs[PreferredVideoSubTypeGuidPairIndex];
-
- _nBestScore = _UI32_MAX;
- CHECK_HR(hr = pSource->CreatePresentationDescriptor(&pPD));
- CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams));
-
-
- for (DWORD i = 0; i < cStreams; i++)
- {
- fSelected = FALSE;
-
- CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(i, &fSelected, &pSD));
-
- if (fSelected)
- {
- CHECK_HR(hr = pSD->GetMediaTypeHandler(&pHandler));
-
- CHECK_HR(hr = pHandler->GetMajorType(&majorType));
-
- if(majorType == MFMediaType_Video)
- {
- CHECK_HR(hr = pHandler->GetMediaTypeCount(&cMediaTypesCount));
-
- for(DWORD cMediaTypesIndex = 0; cMediaTypesIndex < cMediaTypesCount; ++cMediaTypesIndex)
- {
- CHECK_HR(hr = pHandler->GetMediaTypeByIndex(cMediaTypesIndex, &pMediaType));
-
- CHECK_HR(hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &subType));
- // if(subType == *pSubType)
- {
- CHECK_HR(hr = MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &_nWidth, &_nHeight));
- CHECK_HR(hr = MFGetAttributeRatio(pMediaType, MF_MT_FRAME_RATE, &numeratorFps, &denominatorFps));
- _nFps = (numeratorFps / denominatorFps);
-
- if (subType == *pSubType) {
- _nScore = 0;
- }
- else {
- _FindPairByGuid(subType, PreferredVideoSubTypeGuidPairIndex);
- if (PreferredVideoSubTypeGuidPairIndex == -1) {
- _nScore = kSubTypeMismatchPad; // Not a must but important: If(!VideoProcess) then CLSID_CColorConvertDMO
- }
- else {
- _nScore = kSubTypeMismatchPad >> (PreferredVideoSubTypeGuidPairsCount - PreferredVideoSubTypeGuidPairIndex);
- }
- }
- _nScore += abs((int)(_nWidth - nWidth)); // Not a must: If(!VideoProcess) then CLSID_CResizerDMO
- _nScore += abs((int)(_nHeight - nHeight)); // Not a must: If(!VideoProcess) then CLSID_CResizerDMO
- _nScore += (_nFps == nFps) ? 0 : kFpsMismatchPad; // Fps is a must because without video processor no alternative exist (CLSID_CFrameRateConvertDmo doesn't support I420)
-
- if (_nScore <= _nBestScore || !bFound)
- {
- *pnWidth = _nWidth;
- *pnHeight = _nHeight;
- *pnFps = _nFps;
- bFound = TRUE;
- _BestSubType = subType;
- _nBestScore = _nScore;
- }
- }
-
- SafeRelease(&pMediaType);
- }
- }
- }
-
- SafeRelease(&pHandler);
- SafeRelease(&pSD);
- }
+ *pnWidth = 640;
+ *pnHeight = 480;
+ *pnFps = 30;
+ return S_OK;
+#else
+ HRESULT hr = S_OK;
+ IMFPresentationDescriptor *pPD = NULL;
+ IMFStreamDescriptor *pSD = NULL;
+ IMFMediaTypeHandler *pHandler = NULL;
+ IMFMediaType *pMediaType = NULL;
+ DWORD cStreams = 0, cMediaTypesCount;
+ GUID majorType, subType, _BestSubType;
+ BOOL bFound = FALSE, fSelected;
+ UINT32 _nWidth, _nHeight, numeratorFps, denominatorFps, _nFps, _nScore, _nBestScore;
+ int PreferredVideoSubTypeGuidPairIndex;
+ static const UINT32 kSubTypeMismatchPad = _UI32_MAX >> 4;
+ static const UINT32 kFpsMismatchPad = _UI32_MAX >> 2;
+
+ if (!ppSubTypeGuidPair || !pSubType) {
+ CHECK_HR(hr = E_INVALIDARG);
+ }
+ _FindPairByGuid(*pSubType, PreferredVideoSubTypeGuidPairIndex);
+ if (PreferredVideoSubTypeGuidPairIndex == -1) {
+ CHECK_HR(hr = E_INVALIDARG);
+ }
+ *ppSubTypeGuidPair = &PreferredVideoSubTypeGuidPairs[PreferredVideoSubTypeGuidPairIndex];
+
+ _nBestScore = _UI32_MAX;
+ CHECK_HR(hr = pSource->CreatePresentationDescriptor(&pPD));
+ CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams));
+
+
+ for (DWORD i = 0; i < cStreams; i++) {
+ fSelected = FALSE;
+
+ CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(i, &fSelected, &pSD));
+
+ if (fSelected) {
+ CHECK_HR(hr = pSD->GetMediaTypeHandler(&pHandler));
+
+ CHECK_HR(hr = pHandler->GetMajorType(&majorType));
+
+ if(majorType == MFMediaType_Video) {
+ CHECK_HR(hr = pHandler->GetMediaTypeCount(&cMediaTypesCount));
+
+ for(DWORD cMediaTypesIndex = 0; cMediaTypesIndex < cMediaTypesCount; ++cMediaTypesIndex) {
+ CHECK_HR(hr = pHandler->GetMediaTypeByIndex(cMediaTypesIndex, &pMediaType));
+
+ CHECK_HR(hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &subType));
+ // if(subType == *pSubType)
+ {
+ CHECK_HR(hr = MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &_nWidth, &_nHeight));
+ CHECK_HR(hr = MFGetAttributeRatio(pMediaType, MF_MT_FRAME_RATE, &numeratorFps, &denominatorFps));
+ _nFps = (numeratorFps / denominatorFps);
+
+ if (subType == *pSubType) {
+ _nScore = 0;
+ }
+ else {
+ _FindPairByGuid(subType, PreferredVideoSubTypeGuidPairIndex);
+ if (PreferredVideoSubTypeGuidPairIndex == -1) {
+ _nScore = kSubTypeMismatchPad; // Not a must but important: If(!VideoProcess) then CLSID_CColorConvertDMO
+ }
+ else {
+ _nScore = kSubTypeMismatchPad >> (PreferredVideoSubTypeGuidPairsCount - PreferredVideoSubTypeGuidPairIndex);
+ }
+ }
+ _nScore += abs((int)(_nWidth - nWidth)); // Not a must: If(!VideoProcess) then CLSID_CResizerDMO
+ _nScore += abs((int)(_nHeight - nHeight)); // Not a must: If(!VideoProcess) then CLSID_CResizerDMO
+ _nScore += (_nFps == nFps) ? 0 : kFpsMismatchPad; // Fps is a must because without video processor no alternative exist (CLSID_CFrameRateConvertDmo doesn't support I420)
+
+ if (_nScore <= _nBestScore || !bFound) {
+ *pnWidth = _nWidth;
+ *pnHeight = _nHeight;
+ *pnFps = _nFps;
+ bFound = TRUE;
+ _BestSubType = subType;
+ _nBestScore = _nScore;
+ }
+ }
+
+ SafeRelease(&pMediaType);
+ }
+ }
+ }
+
+ SafeRelease(&pHandler);
+ SafeRelease(&pSD);
+ }
bail:
- SafeRelease(&pPD);
- SafeRelease(&pSD);
- SafeRelease(&pHandler);
- SafeRelease(&pMediaType);
-
- _FindPairByGuid(_BestSubType, PreferredVideoSubTypeGuidPairIndex);
- if (PreferredVideoSubTypeGuidPairIndex != -1) {
- *ppSubTypeGuidPair = &PreferredVideoSubTypeGuidPairs[PreferredVideoSubTypeGuidPairIndex];
- }
- else /*if (_nBestScore > kSubTypeMismatchPad)*/ {
- *pnWidth = 640;
- *pnHeight = 480;
- *pnFps = 30;
- TSK_DEBUG_WARN("Failed to math subtype...using VGA@30fps");
- }
-
- return SUCCEEDED(hr) ? (bFound ? S_OK : E_NOT_SET): hr;
+ SafeRelease(&pPD);
+ SafeRelease(&pSD);
+ SafeRelease(&pHandler);
+ SafeRelease(&pMediaType);
+
+ _FindPairByGuid(_BestSubType, PreferredVideoSubTypeGuidPairIndex);
+ if (PreferredVideoSubTypeGuidPairIndex != -1) {
+ *ppSubTypeGuidPair = &PreferredVideoSubTypeGuidPairs[PreferredVideoSubTypeGuidPairIndex];
+ }
+ else { /*if (_nBestScore > kSubTypeMismatchPad)*/
+ *pnWidth = 640;
+ *pnHeight = 480;
+ *pnFps = 30;
+ TSK_DEBUG_WARN("Failed to math subtype...using VGA@30fps");
+ }
+
+ return SUCCEEDED(hr) ? (bFound ? S_OK : E_NOT_SET): hr;
#endif
}
HWND MFUtils::GetConsoleHwnd(void)
{
- #define MY_BUFSIZE 1024 // Buffer size for console window titles.
- HWND hwndFound; // This is what is returned to the caller.
- TCHAR pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated
- // WindowTitle.
- TCHAR pszOldWindowTitle[MY_BUFSIZE]; // Contains original
- // WindowTitle.
+#define MY_BUFSIZE 1024 // Buffer size for console window titles.
+ HWND hwndFound; // This is what is returned to the caller.
+ TCHAR pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated
+ // WindowTitle.
+ TCHAR pszOldWindowTitle[MY_BUFSIZE]; // Contains original
+ // WindowTitle.
- // Fetch current window title.
- GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);
+ // Fetch current window title.
+ GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);
- // Format a "unique" NewWindowTitle.
- wsprintf(pszNewWindowTitle,TEXT("%d/%d"),
- GetTickCount(),
- GetCurrentProcessId());
+ // Format a "unique" NewWindowTitle.
+ wsprintf(pszNewWindowTitle,TEXT("%d/%d"),
+ GetTickCount(),
+ GetCurrentProcessId());
- // Change current window title.
- SetConsoleTitle(pszNewWindowTitle);
+ // Change current window title.
+ SetConsoleTitle(pszNewWindowTitle);
- // Ensure window title has been updated.
- Sleep(40);
+ // Ensure window title has been updated.
+ Sleep(40);
- // Look for NewWindowTitle.
- hwndFound=FindWindow(NULL, pszNewWindowTitle);
+ // Look for NewWindowTitle.
+ hwndFound=FindWindow(NULL, pszNewWindowTitle);
- // Restore original window title.
- SetConsoleTitle(pszOldWindowTitle);
+ // Restore original window title.
+ SetConsoleTitle(pszOldWindowTitle);
- return(hwndFound);
+ return(hwndFound);
}
diff --git a/plugins/pluginWinMF/internals/mf_utils.h b/plugins/pluginWinMF/internals/mf_utils.h
index 0819597..1225b3b 100755
--- a/plugins/pluginWinMF/internals/mf_utils.h
+++ b/plugins/pluginWinMF/internals/mf_utils.h
@@ -1,18 +1,18 @@
/* Copyright (C) 2013 Mamadou DIOP
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*/
@@ -35,14 +35,13 @@
(*ppT)->Release(); \
*ppT = NULL; \
} \
-}
+}
#undef CHECK_HR
// In CHECK_HR(x) When (x) is a function it will be executed twice when used in "TSK_DEBUG_ERROR(x)" and "If(x)"
#define CHECK_HR(x) { HRESULT __hr__ = (x); if (FAILED(__hr__)) { TSK_DEBUG_ERROR("Operation Failed (%08x)", __hr__); goto bail; } }
-typedef struct VideoSubTypeGuidPair
-{
+typedef struct VideoSubTypeGuidPair {
enum tmedia_chroma_e chroma;
const GUID& fourcc;
}
@@ -52,209 +51,207 @@ class MFUtils
{
public:
-static HRESULT Startup();
-static HRESULT Shutdown();
+ static HRESULT Startup();
+ static HRESULT Shutdown();
-static BOOL IsD3D9Supported();
-static BOOL IsLowLatencyH264Supported();
-static BOOL IsLowLatencyH264SupportsMaxSliceSize();
+ static BOOL IsD3D9Supported();
+ static BOOL IsLowLatencyH264Supported();
+ static BOOL IsLowLatencyH264SupportsMaxSliceSize();
-static HRESULT IsAsyncMFT(
- IMFTransform *pMFT, // The MFT to check
- BOOL* pbIsAsync // Whether the MFT is Async
- );
-static HRESULT UnlockAsyncMFT(
- IMFTransform *pMFT // The MFT to unlock
- );
+ static HRESULT IsAsyncMFT(
+ IMFTransform *pMFT, // The MFT to check
+ BOOL* pbIsAsync // Whether the MFT is Async
+ );
+ static HRESULT UnlockAsyncMFT(
+ IMFTransform *pMFT // The MFT to unlock
+ );
-static HRESULT CreatePCMAudioType(
- UINT32 sampleRate, // Samples per second
- UINT32 bitsPerSample, // Bits per sample
- UINT32 cChannels, // Number of channels
- IMFMediaType **ppType // Receives a pointer to the media type.
+ static HRESULT CreatePCMAudioType(
+ UINT32 sampleRate, // Samples per second
+ UINT32 bitsPerSample, // Bits per sample
+ UINT32 cChannels, // Number of channels
+ IMFMediaType **ppType // Receives a pointer to the media type.
+ );
+ static HRESULT CreateVideoType(
+ const GUID* subType, // video subType
+ IMFMediaType **ppType, // Receives a pointer to the media type.
+ UINT32 unWidth = 0, // Video width (0 to ignore)
+ UINT32 unHeight = 0 // Video height (0 to ignore)
+ );
+ static HRESULT ConvertVideoTypeToUncompressedType(
+ IMFMediaType *pType, // Pointer to an encoded video type.
+ const GUID& subtype, // Uncompressed subtype (eg, RGB-32, AYUV)
+ IMFMediaType **ppType // Receives a matching uncompressed video type.
+ );
+ static HRESULT CreateMediaSample(
+ DWORD cbData, // Maximum buffer size
+ IMFSample **ppSample // Receives the sample
+ );
+ static HRESULT ValidateVideoFormat(
+ IMFMediaType *pmt
+ );
+ static HRESULT IsVideoProcessorSupported(BOOL *pbSupported);
+ static HRESULT GetBestVideoProcessor(
+ const GUID& inputFormat, // The input MediaFormat (e.g. MFVideoFormat_I420)
+ const GUID& outputFormat, // The output MediaFormat (e.g. MFVideoFormat_NV12)
+ IMFTransform **ppProcessor // Receives the video processor
+ );
+ static HRESULT GetBestCodec(
+ BOOL bEncoder, // Whether we request an encoder or not (TRUE=encoder, FALSE=decoder)
+ const GUID& mediaType, // The MediaType
+ const GUID& inputFormat, // The input MediaFormat (e.g. MFVideoFormat_NV12)
+ const GUID& outputFormat, // The output MediaFormat (e.g. MFVideoFormat_H264)
+ IMFTransform **ppMFT // Receives the decoder/encoder transform
+ );
+ static HRESULT BindOutputNode(
+ IMFTopologyNode *pNode // The Node
+ );
+ static HRESULT AddOutputNode(
+ IMFTopology *pTopology, // Topology.
+ IMFActivate *pActivate, // Media sink activation object.
+ DWORD dwId, // Identifier of the stream sink.
+ IMFTopologyNode **ppNode // Receives the node pointer.
+ );
+ static HRESULT AddTransformNode(
+ IMFTopology *pTopology, // Topology.
+ IMFTransform *pMFT, // MFT.
+ DWORD dwId, // Identifier of the stream sink.
+ IMFTopologyNode **ppNode // Receives the node pointer.
+ );
+ static HRESULT AddSourceNode(
+ IMFTopology *pTopology, // Topology.
+ IMFMediaSource *pSource, // Media source.
+ IMFPresentationDescriptor *pPD, // Presentation descriptor.
+ IMFStreamDescriptor *pSD, // Stream descriptor.
+ IMFTopologyNode **ppNode // Receives the node pointer.
);
-static HRESULT CreateVideoType(
- const GUID* subType, // video subType
- IMFMediaType **ppType, // Receives a pointer to the media type.
- UINT32 unWidth = 0, // Video width (0 to ignore)
- UINT32 unHeight = 0 // Video height (0 to ignore)
- );
-static HRESULT ConvertVideoTypeToUncompressedType(
- IMFMediaType *pType, // Pointer to an encoded video type.
- const GUID& subtype, // Uncompressed subtype (eg, RGB-32, AYUV)
- IMFMediaType **ppType // Receives a matching uncompressed video type.
+ static HRESULT CreateTopology(
+ IMFMediaSource *pSource, // Media source
+ IMFTransform *pTransform, // Transform filter (e.g. encoder or decoder) to insert between the source and Sink. NULL is valid.
+ IMFActivate *pSinkActivateMain, // Main sink (e.g. sample grabber or EVR).
+ IMFActivate *pSinkActivatePreview, // Preview sink. Optional. Could be NULL.
+ IMFMediaType *pIputTypeMain, // Main sink input MediaType
+ IMFTopology **ppTopo // Receives the newly created topology
+ );
+ static HRESULT ResolveTopology(
+ IMFTopology *pInputTopo, // A pointer to the IMFTopology interface of the partial topology to be resolved.
+ IMFTopology **ppOutputTopo, // Receives a pointer to the IMFTopology interface of the completed topology. The caller must release the interface.
+ IMFTopology *pCurrentTopo = NULL // A pointer to the IMFTopology interface of the previous full topology. The topology loader can re-use objects from this topology in the new topology. This parameter can be NULL.
+ );
+ static HRESULT FindNodeObject(
+ IMFTopology *pInputTopo, // The Topology containing the node to find
+ TOPOID qwTopoNodeID, //The identifier for the node
+ void** ppObject // Receives the Object
+ );
+ static HRESULT CreateMediaSinkActivate(
+ IMFStreamDescriptor *pSourceSD, // Pointer to the stream descriptor.
+ HWND hVideoWindow, // Handle to the video clipping window.
+ IMFActivate **ppActivate
+ );
+ static HRESULT SetMediaType(
+ IMFMediaSource *pSource, // Media source.
+ IMFMediaType* pMediaType // Media Type.
+ );
+ static HRESULT SetVideoWindow(
+ IMFTopology *pTopology, // Topology.
+ IMFMediaSource *pSource, // Media source.
+ HWND hVideoWnd // Window for video playback.
+ );
+ static HRESULT RunSession(
+ IMFMediaSession *pSession, // Session to run
+ IMFTopology *pTopology // The toppology
+ );
+ static HRESULT ShutdownSession(
+ IMFMediaSession *pSession, // The Session
+ IMFMediaSource *pSource = NULL // Source to shutdown (optional)
+ );
+ static HRESULT PauseSession(
+ IMFMediaSession *pSession, // The session
+ IMFMediaSource *pSource = NULL// Source to pause (optional)
+ );
+ static INT GetSupportedSubTypeIndex(
+ IMFMediaSource *pSource, // The source
+ const GUID& mediaType, // The MediaType
+ const VideoSubTypeGuidPair* subTypes, UINT subTypesCount // List of preferred subtypes (in ascending order)
+ );
+ static HRESULT IsSupported(
+ IMFPresentationDescriptor *pPD,
+ DWORD cStreamIndex,
+ UINT32 nWidth,
+ UINT32 nHeight,
+ UINT32 nFps,
+ const GUID& guidFormat,
+ BOOL* pbSupportedSize,
+ BOOL* pbSupportedFps,
+ BOOL* pbSupportedFormat
+ );
+ static HRESULT IsSupported(
+ IMFPresentationDescriptor *pPD,
+ DWORD cStreamIndex,
+ IMFMediaType* pMediaType,
+ BOOL* pbSupportedSize,
+ BOOL* pbSupportedFps,
+ BOOL* pbSupportedFormat
+ );
+ static HRESULT IsSupportedByInput(
+ IMFPresentationDescriptor *pPD,
+ DWORD cStreamIndex,
+ IMFTopologyNode *pNode,
+ BOOL* pbSupportedSize,
+ BOOL* pbSupportedFps,
+ BOOL* pbSupportedFormat
+ );
+ static HRESULT ConnectConverters(
+ IMFTopologyNode *pNode,
+ DWORD dwOutputIndex,
+ IMFTopologyNode *pNodeConvFrameRate,
+ IMFTopologyNode *pNodeConvColor,
+ IMFTopologyNode *pNodeConvSize
+ );
+ static HRESULT GetBestFormat(
+ IMFMediaSource *pSource,
+ const GUID *pSubType,
+ UINT32 nWidth,
+ UINT32 nHeight,
+ UINT32 nFps,
+ UINT32 *pnWidth,
+ UINT32 *pnHeight,
+ UINT32 *pnFps,
+ const VideoSubTypeGuidPair **pSubTypeGuidPair
);
-static HRESULT CreateMediaSample(
- DWORD cbData, // Maximum buffer size
- IMFSample **ppSample // Receives the sample
- );
-static HRESULT ValidateVideoFormat(
- IMFMediaType *pmt
- );
-static HRESULT IsVideoProcessorSupported(BOOL *pbSupported);
-static HRESULT GetBestVideoProcessor(
- const GUID& inputFormat, // The input MediaFormat (e.g. MFVideoFormat_I420)
- const GUID& outputFormat, // The output MediaFormat (e.g. MFVideoFormat_NV12)
- IMFTransform **ppProcessor // Receives the video processor
- );
-static HRESULT GetBestCodec(
- BOOL bEncoder, // Whether we request an encoder or not (TRUE=encoder, FALSE=decoder)
- const GUID& mediaType, // The MediaType
- const GUID& inputFormat, // The input MediaFormat (e.g. MFVideoFormat_NV12)
- const GUID& outputFormat, // The output MediaFormat (e.g. MFVideoFormat_H264)
- IMFTransform **ppMFT // Receives the decoder/encoder transform
- );
-static HRESULT BindOutputNode(
- IMFTopologyNode *pNode // The Node
- );
-static HRESULT AddOutputNode(
- IMFTopology *pTopology, // Topology.
- IMFActivate *pActivate, // Media sink activation object.
- DWORD dwId, // Identifier of the stream sink.
- IMFTopologyNode **ppNode // Receives the node pointer.
- );
-static HRESULT AddTransformNode(
- IMFTopology *pTopology, // Topology.
- IMFTransform *pMFT, // MFT.
- DWORD dwId, // Identifier of the stream sink.
- IMFTopologyNode **ppNode // Receives the node pointer.
- );
-static HRESULT AddSourceNode(
- IMFTopology *pTopology, // Topology.
- IMFMediaSource *pSource, // Media source.
- IMFPresentationDescriptor *pPD, // Presentation descriptor.
- IMFStreamDescriptor *pSD, // Stream descriptor.
- IMFTopologyNode **ppNode // Receives the node pointer.
- );
-static HRESULT CreateTopology(
- IMFMediaSource *pSource, // Media source
- IMFTransform *pTransform, // Transform filter (e.g. encoder or decoder) to insert between the source and Sink. NULL is valid.
- IMFActivate *pSinkActivateMain, // Main sink (e.g. sample grabber or EVR).
- IMFActivate *pSinkActivatePreview, // Preview sink. Optional. Could be NULL.
- IMFMediaType *pIputTypeMain, // Main sink input MediaType
- IMFTopology **ppTopo // Receives the newly created topology
- );
-static HRESULT ResolveTopology(
- IMFTopology *pInputTopo, // A pointer to the IMFTopology interface of the partial topology to be resolved.
- IMFTopology **ppOutputTopo, // Receives a pointer to the IMFTopology interface of the completed topology. The caller must release the interface.
- IMFTopology *pCurrentTopo = NULL // A pointer to the IMFTopology interface of the previous full topology. The topology loader can re-use objects from this topology in the new topology. This parameter can be NULL.
- );
-static HRESULT FindNodeObject(
- IMFTopology *pInputTopo, // The Topology containing the node to find
- TOPOID qwTopoNodeID, //The identifier for the node
- void** ppObject // Receives the Object
- );
-static HRESULT CreateMediaSinkActivate(
- IMFStreamDescriptor *pSourceSD, // Pointer to the stream descriptor.
- HWND hVideoWindow, // Handle to the video clipping window.
- IMFActivate **ppActivate
-);
-static HRESULT SetMediaType(
- IMFMediaSource *pSource, // Media source.
- IMFMediaType* pMediaType // Media Type.
- );
-static HRESULT SetVideoWindow(
- IMFTopology *pTopology, // Topology.
- IMFMediaSource *pSource, // Media source.
- HWND hVideoWnd // Window for video playback.
- );
-static HRESULT RunSession(
- IMFMediaSession *pSession, // Session to run
- IMFTopology *pTopology // The toppology
- );
-static HRESULT ShutdownSession(
- IMFMediaSession *pSession, // The Session
- IMFMediaSource *pSource = NULL // Source to shutdown (optional)
- );
-static HRESULT PauseSession(
- IMFMediaSession *pSession, // The session
- IMFMediaSource *pSource = NULL// Source to pause (optional)
- );
-static INT GetSupportedSubTypeIndex(
- IMFMediaSource *pSource, // The source
- const GUID& mediaType, // The MediaType
- const VideoSubTypeGuidPair* subTypes, UINT subTypesCount // List of preferred subtypes (in ascending order)
- );
-static HRESULT IsSupported(
- IMFPresentationDescriptor *pPD,
- DWORD cStreamIndex,
- UINT32 nWidth,
- UINT32 nHeight,
- UINT32 nFps,
- const GUID& guidFormat,
- BOOL* pbSupportedSize,
- BOOL* pbSupportedFps,
- BOOL* pbSupportedFormat
- );
-static HRESULT IsSupported(
- IMFPresentationDescriptor *pPD,
- DWORD cStreamIndex,
- IMFMediaType* pMediaType,
- BOOL* pbSupportedSize,
- BOOL* pbSupportedFps,
- BOOL* pbSupportedFormat
- );
-static HRESULT IsSupportedByInput(
- IMFPresentationDescriptor *pPD,
- DWORD cStreamIndex,
- IMFTopologyNode *pNode,
- BOOL* pbSupportedSize,
- BOOL* pbSupportedFps,
- BOOL* pbSupportedFormat
- );
-static HRESULT ConnectConverters(
- IMFTopologyNode *pNode,
- DWORD dwOutputIndex,
- IMFTopologyNode *pNodeConvFrameRate,
- IMFTopologyNode *pNodeConvColor,
- IMFTopologyNode *pNodeConvSize
- );
-static HRESULT GetBestFormat(
- IMFMediaSource *pSource,
- const GUID *pSubType,
- UINT32 nWidth,
- UINT32 nHeight,
- UINT32 nFps,
- UINT32 *pnWidth,
- UINT32 *pnHeight,
- UINT32 *pnFps,
- const VideoSubTypeGuidPair **pSubTypeGuidPair
- );
-static HWND GetConsoleHwnd(void);
+ static HWND GetConsoleHwnd(void);
-template <class Q>
-static HRESULT GetTopoNodeObject(IMFTopologyNode *pNode, Q **ppObject)
-{
- IUnknown *pUnk = NULL; // zero output
+ template <class Q>
+ static HRESULT GetTopoNodeObject(IMFTopologyNode *pNode, Q **ppObject) {
+ IUnknown *pUnk = NULL; // zero output
- HRESULT hr = pNode->GetObject(&pUnk);
- if (SUCCEEDED(hr))
- {
- pUnk->QueryInterface(IID_PPV_ARGS(ppObject));
- pUnk->Release();
+ HRESULT hr = pNode->GetObject(&pUnk);
+ if (SUCCEEDED(hr)) {
+ pUnk->QueryInterface(IID_PPV_ARGS(ppObject));
+ pUnk->Release();
+ }
+ return hr;
}
- return hr;
-}
private:
- static BOOL g_bStarted;
+ static BOOL g_bStarted;
- static DWORD g_dwMajorVersion;
- static DWORD g_dwMinorVersion;
+ static DWORD g_dwMajorVersion;
+ static DWORD g_dwMinorVersion;
- static BOOL g_bLowLatencyH264Checked;
- static BOOL g_bLowLatencyH264Supported;
- static BOOL g_bLowLatencyH264SupportsMaxSliceSize;
+ static BOOL g_bLowLatencyH264Checked;
+ static BOOL g_bLowLatencyH264Supported;
+ static BOOL g_bLowLatencyH264SupportsMaxSliceSize;
- static BOOL g_bD3D9Checked;
- static BOOL g_bD3D9Supported;
+ static BOOL g_bD3D9Checked;
+ static BOOL g_bD3D9Supported;
public:
- static const TOPOID g_ullTopoIdSinkMain;
- static const TOPOID g_ullTopoIdSinkPreview;
- static const TOPOID g_ullTopoIdSource;
- static const TOPOID g_ullTopoIdVideoProcessor;
+ static const TOPOID g_ullTopoIdSinkMain;
+ static const TOPOID g_ullTopoIdSinkPreview;
+ static const TOPOID g_ullTopoIdSource;
+ static const TOPOID g_ullTopoIdVideoProcessor;
};
#endif /* PLUGIN_WIN_MF_UTILS_H */
OpenPOWER on IntegriCloud