summaryrefslogtreecommitdiffstats
path: root/plugins/pluginWinMF/internals/mf_utils.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pluginWinMF/internals/mf_utils.cxx')
-rwxr-xr-xplugins/pluginWinMF/internals/mf_utils.cxx2792
1 files changed, 1316 insertions, 1476 deletions
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);
}
OpenPOWER on IntegriCloud