vendredi 24 juin 2016

cannot readsample from IMFSource in synchronous mode


I am having trouble with a video recording application that I am writing using Microsoft Media Foundation. Specifically, the read/write function (which I put on a loop that lives on it's own thread) doesn't make it pass the call to ReadSample: HRESULT WinCapture::rwFunction(void) { HRESULT hr; DWORD streamIndex, flags; LONGLONG llTimeStamp; IMFSample *pSample = NULL; EnterCriticalSection(&m_critsec); // Read another sample. hr = m_pReader->ReadSample( (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &streamIndex, // actual &flags,//NULL, // flags &llTimeStamp,//NULL, // timestamp &pSample // sample ); if (FAILED(hr)) { goto done; } hr = m_pWriter->WriteSample(0, pSample); goto done; done: return hr; SafeRelease(&pSample); LeaveCriticalSection(&m_critsec); } The value of hr is an exception code: 0xc00d3704 so the code snippet skips the call to WriteSample. It is a lot of steps, but I am fairly certain that I am setting up m_pReader (type IMFSource *) correctly. HRESULT WinCapture::OpenMediaSource(IMFMediaSource *pSource) { HRESULT hr = S_OK; IMFAttributes *pAttributes = NULL; hr = MFCreateAttributes(&pAttributes, 2); // use a callback //if (SUCCEEDED(hr)) //{ // hr = pAttributes->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, this); //} // set the desired format type DWORD dwFormatIndex = (DWORD)formatIdx; IMFPresentationDescriptor *pPD = NULL; IMFStreamDescriptor *pSD = NULL; IMFMediaTypeHandler *pHandler = NULL; IMFMediaType *pType = NULL; // create the source reader if (SUCCEEDED(hr)) { hr = MFCreateSourceReaderFromMediaSource( pSource, pAttributes, &m_pReader ); } // steps to set the selected format type hr = pSource->CreatePresentationDescriptor(&pPD); if (FAILED(hr)) { goto done; } BOOL fSelected; hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD); if (FAILED(hr)) { goto done; } hr = pSD->GetMediaTypeHandler(&pHandler); if (FAILED(hr)) { goto done; } hr = pHandler->GetMediaTypeByIndex(dwFormatIndex, &pType); if (FAILED(hr)) { goto done; } hr = pHandler->SetCurrentMediaType(pType); { goto done; } hr = m_pReader->SetCurrentMediaType( (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, pType ); // set to maximum framerate? hr = pHandler->GetCurrentMediaType(&pType); if (FAILED(hr)) { goto done; } // Get the maximum frame rate for the selected capture format. // Note: To get the minimum frame rate, use the // MF_MT_FRAME_RATE_RANGE_MIN attribute instead. PROPVARIANT var; if (SUCCEEDED(pType->GetItem(MF_MT_FRAME_RATE_RANGE_MAX, &var))) { hr = pType->SetItem(MF_MT_FRAME_RATE, var); PropVariantClear(&var); if (FAILED(hr)) { goto done; } hr = pHandler->SetCurrentMediaType(pType); { goto done; } hr = m_pReader->SetCurrentMediaType( (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, pType ); } goto done; done: SafeRelease(&pPD); SafeRelease(&pSD); SafeRelease(&pHandler); SafeRelease(&pType); SafeRelease(&pAttributes); return hr; } This code is all copied from Microsoft documentation pages and the SDK sample code. The variable formatIdx is 0, I get it from enumerating the camera formats and choosing the first one.

Aucun commentaire:

Enregistrer un commentaire