Im working on an openframeworks extension for Microsoft Media Foundation. My program executes fine in Debug builds but freezes upon the enterCriticalSection call in Release builds.
I don't get any build errors whatsoever. Upon setup of the ofApp in a release build it just hangs in the console forever.
The line Pass 2b is never written to the console.
HRESULT ofxMMF::SetSourceReader(IMFActivate * device) {
HRESULT hr = S_OK;
IMFMediaSource * source = NULL;
IMFAttributes * attributes = NULL;
std::cout << "Pass 2a" << std::endl;
EnterCriticalSection(&criticalSection);
std::cout << "Pass 2b" << std::endl;
hr = device -> ActivateObject(__uuidof(IMFMediaSource), (void **)&source);
//get symbolic link for the device
if (SUCCEEDED(hr))
hr = device ->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &wSymbolicLink, &cchSymbolicLink);
//Allocate attributes
if (SUCCEEDED(hr))
hr = MFCreateAttributes(&attributes, 2);
//get attributes
if (SUCCEEDED(hr))
hr = attributes -> SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, TRUE);
// Set the callback pointer.
if (SUCCEEDED(hr))
hr = attributes -> SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, this);
//Create the source reader
if (SUCCEEDED(hr))
hr = MFCreateSourceReaderFromMediaSource(source, attributes, &sourceReader);
EnumerateCaptureFormats(source);
bool foundCorrectMediaType = false;
// Try to find a suitable output type.
if (SUCCEEDED(hr)) {
HRESULT nativeTypeErrorCode = S_OK;
DWORD count = 0;
UINT32 streamIndex = 0;
//2688 x 1512
UINT32 requiredWidth = reqW;
UINT32 requiredheight = reqH;
while (nativeTypeErrorCode == S_OK) {
IMFMediaType * nativeType = NULL;
nativeTypeErrorCode = sourceReader->GetNativeMediaType(streamIndex, count, &nativeType);
if (nativeTypeErrorCode != S_OK) continue;
GUID nativeGuid = { 0 };
hr = nativeType->GetGUID(MF_MT_SUBTYPE, &nativeGuid);
if (FAILED(hr)) return hr;
UINT32 cwidth, cheight;
hr = MFGetAttributeSize(nativeType, MF_MT_FRAME_SIZE, &cwidth, &cheight);
if (FAILED(hr)) return hr;
UINT32 yuv_video_matrix = 0;
yuv_video_matrix = MFGetAttributeUINT32(nativeType, MF_MT_YUV_MATRIX, yuv_video_matrix);
UINT32 sample_size = 0;
sample_size = MFGetAttributeUINT32(nativeType, MF_MT_SAMPLE_SIZE, sample_size);
UINT32 curstride = 0;
curstride = MFGetAttributeUINT32(nativeType, MF_MT_DEFAULT_STRIDE, curstride);
GUID subtype = GUID_NULL;
LONG tempStride = 0;
nativeType->GetGUID(MF_MT_SUBTYPE, &subtype);
MFGetStrideForBitmapInfoHeader(subtype.Data1, cwidth, &tempStride);
WCHAR * pGuidValName;
hr = GetGUIDName(nativeGuid, &pGuidValName);
std::cout << count << ": " << ConvertWCharToString(pGuidValName) << "\t" << cwidth << " x " << cheight << " : yuv_decode: " << yuv_video_matrix << " : sample size: " << sample_size << ": stride: " << curstride << ": tmpstride: " << tempStride << std::endl;
if (nativeGuid == MFVideoFormat_NV12 && cwidth == requiredWidth && cheight == requiredheight) {
// found native config, set it
hr = IsMediaTypeSupported(nativeType);
if (FAILED(hr)) {
std::cout << "Media type is not supported" << std::endl;
//return hr;
}
hr = sourceReader->SetCurrentMediaType(streamIndex, NULL, nativeType);
if (FAILED(hr)) {
std::cout << "Failed to set Media type" << std::endl;
//return hr;
}
MFGetAttributeSize(nativeType, MF_MT_FRAME_SIZE, &width, &height);
foundCorrectMediaType = true;
break;
}
count++;
}
}
if (!foundCorrectMediaType) {
hr = E_FAIL;
std::cout << "Cant find appropriate mediatype,exiting" << std::endl;
}
if (SUCCEEDED(hr)) {
// Ask for the first sample.
hr = sourceReader -> ReadSample((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, NULL, NULL, NULL);
}
if (FAILED(hr)) {
if (source) {
source -> Shutdown();
}
//Close();
}
if (source) {
source -> Release();
source = NULL;
}
if (attributes) {
attributes -> Release();
attributes = NULL;
}
LeaveCriticalSection(&criticalSection);
return hr;
}
Any thoughts?
I looked into the linker, at the moment im using
#pragma comment(lib, "Mfplat.lib")
#pragma comment(lib, "Mf.lib")
#pragma comment(lib, "Mfreadwrite.lib")
#pragma comment(lib, "mfuuid.lib")
#pragma comment(lib, "shlwapi.lib")
to include libraries, i would have expected a linker error if this was not appropriate in Release.
This is a bit stupid, and also to me unexpected behavior. I forgot InitializeCriticalSection(&criticalSection);
In my class constructor.
Apparently debug configuration handles this, release doesn't.