2 years ago
#47387
Andy
Why do IMFSourceReader::ReadSample block when I change the the camera output format?
I have the following Windows C++ code that I have adapted from: https://alax.info/trac/public/browser/trunk/Utilities/MediaFoundation/VideoCaptureSynchronous/VideoCaptureSynchronous.cpp
More info about the original code: https://alax.info/blog/1835 Thanks to Roman R!
#include <winsdkver.h>
#include <sdkddkver.h>
#include <stdio.h>
#include <tchar.h>
#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
#include <atlbase.h>
#include <atlcom.h>
#pragma comment(lib, "mfplat.lib")
#pragma comment(lib, "mf.lib")
#pragma comment(lib, "mfreadwrite.lib")
#define __C ATLENSURE_SUCCEEDED
#define __D ATLENSURE_THROW
static UINT32 g_nIndex = 1;
int main()
{
__C(MFStartup(MF_VERSION));
{
CComPtr<IMFMediaSource> pMediaSource;
{
CComPtr<IMFAttributes> pAttributes;
__C(MFCreateAttributes(&pAttributes, 1));
__C(pAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID));
CComHeapPtr<IMFActivate*> ppActivates;
UINT32 nActivateCount = 0;
__C(MFEnumDeviceSources(pAttributes, &ppActivates, &nActivateCount));
__D(g_nIndex < nActivateCount, E_INVALIDARG);
const CComPtr<IMFActivate> pActivate = ppActivates[g_nIndex];
for (UINT32 nIndex = 0; nIndex < nActivateCount; nIndex++)
reinterpret_cast<CComPtr<IMFActivate>&>(ppActivates[nIndex]).Release();
__C(pActivate->ActivateObject(__uuidof(IMFMediaSource), (VOID**)&pMediaSource));
CComHeapPtr<WCHAR> pszFriendlyName;
__C(pActivate->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &pszFriendlyName, NULL));
_tprintf(_T("Friendly Name: %ls\n"), (LPCWSTR)pszFriendlyName);
}
CComPtr<IMFSourceReader> pSourceReader;
__C(MFCreateSourceReaderFromMediaSource(pMediaSource, NULL, &pSourceReader));
// Start My code
CComPtr<IMFMediaType> mediaType;
int index = 4;
__C(pSourceReader->GetNativeMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, index, &mediaType)); // returns MF_E_NO_MORE_TYPES if index is too large
__C(pSourceReader->SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, mediaType));
// End my code
LONGLONG nBaseTime = 0;
for (; ; )
{
DWORD nStreamIndex;
DWORD nStreamFlags;
LONGLONG nTime;
CComPtr<IMFSample> pSample;
__C(pSourceReader->ReadSample(MF_SOURCE_READER_ANY_STREAM, 0, &nStreamIndex, &nStreamFlags, &nTime, &pSample));
nTime -= nBaseTime;
_tprintf(_T("nStreamIndex %d, nStreamFlags 0x%X, nTime %.3f, pSample 0x%p\n"), nStreamIndex, nStreamFlags, nTime / 1E7, (IMFSample*)pSample);
if (nStreamIndex == 0 && (nStreamFlags & MF_SOURCE_READERF_STREAMTICK))
{
ATLASSERT(!pSample);
nBaseTime = nTime;
continue;
}
}
}
__C(MFShutdown());
return 0;
}
My changes are within the Start my code/End my code block. Without my changes the code runs fine. With my changes however I only get one NULL sample from ReadSample() and after that it blocks in ReadSample(). The output is:
Friendly Name: M034-WDR
nStreamIndex 0, nStreamFlags 0x100, nTime 65175.109, pSample 0x0000000000000000
I have listed the IMFMediaTypes supported by the camera with some other code and found that it had 8 different native formats out of which I preferred number 4.
How can I select this format and get this code to run?
I tried changing to
ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM,..)
but that did not help.
c++
windows
ms-media-foundation
0 Answers
Your Answer