将视觉C 媒体基础捕获应用程序转换为C 构建器
Converting Visual C++ Media Foundation Capture application to C++ Builder
我正在尝试将Microsoft" CaptureEngine视频捕获示例"从Visual C 转换为Embarcadero C 构建器。
https://code.msdn.microsoft.com/windowsdesktop/media-foundation-capture-78504c83
该代码可以通过Visual C 运行良好,但是我需要在C 构建器应用程序中包含。我基本上有代码工作,但是有几个问题我需要帮助。
我可以选择视频源,预览视频源,甚至开始捕获要文件。但是,视频捕获文件仅包含视频长度重复的一个帧,即使音频已正确记录。
我想知道这是否是由于事件无法正确处理。媒体基础捕获引擎的事件使用Windows消息传递给主线程,然后将Windows Mess传递调用媒体引擎事件处理程序。但是,我注意到事件处理程序可以停止录制并停止预览,以便等待结果
void WaitForResult()
{
WaitForSingleObject(m_hEvent, INFINITE);
}
HRESULT CaptureManager::StopPreview()
{
HRESULT hr = S_OK;
if (m_pEngine == NULL)
{
return MF_E_NOT_INITIALIZED;
}
if (!m_bPreviewing)
{
return S_OK;
}
hr = m_pEngine->StopPreview();
if (FAILED(hr))
{
goto done;
}
WaitForResult();
if (m_fPowerRequestSet && m_hpwrRequest != INVALID_HANDLE_VALUE)
{
PowerClearRequest(m_hpwrRequest, PowerRequestExecutionRequired);
m_fPowerRequestSet = false;
}
done:
return hr;
}
问题是,此M_HEVENT是从C 构建器事件处理程序触发的,该事件处理程序是同一主线程的一部分,该主题正在等待该事件的处理,因此在试图停止视频录制时,我会得到线程锁定。如果我发表评论,我不会锁定,但也没有有效的录制视频文件。
我不确定视觉C 如何将事件与捕获引擎代码区分开,关于我如何为C 构建器做到这一点的建议?
捕获引擎事件回调在工作线程上调用,它不是"同一主线程的一部分"。
// Callback method to receive events from the capture engine.
STDMETHODIMP CaptureManager::CaptureEngineCB::OnEvent( _In_ IMFMediaEvent* pEvent)
{
...
if (guidType == MF_CAPTURE_ENGINE_PREVIEW_STOPPED)
{
m_pManager->OnPreviewStopped(hrStatus);
SetEvent(m_pManager->m_hEvent);
这实质上改变了应用程序的行为。控制线程停止预览并阻止,直到Worker Thread发出通知,该通知设置了我上面引用的事件。从那里控制线程从等待操作醒来,并继续停止预览。
如果这不是您在应用程序中看到的内容,我建议您在第一行回调功能上设置一个断点,以确保您收到通知。如果您收到,则可以制定代码并确保到达事件设置行。如果您没有收到,其他事情正在阻止,您必须弄清楚,例如,通过闯入并检查应用程序的线程状态。
我找到了问题的原因。捕获引擎示例中的单个例程绝对是在其自己的线程中。问题在于,它然后将消息发布到主应用程序线程,而不是将其本身处理。这意味着主线在静音上等待时被冷冻。
// Callback method to receive events from the capture engine.
STDMETHODIMP CaptureManager::CaptureEngineCB::OnEvent( _In_ IMFMediaEvent* pEvent)
{
// Post a message to the application window, so the event is handled
// on the application's main thread.
if (m_fSleeping && m_pManager != NULL)
{
// We're about to fall asleep, that means we've just asked the CE to stop the preview
// and record. We need to handle it here since our message pump may be gone.
GUID guidType;
HRESULT hrStatus;
HRESULT hr = pEvent->GetStatus(&hrStatus);
if (FAILED(hr))
{
hrStatus = hr;
}
hr = pEvent->GetExtendedType(&guidType);
if (SUCCEEDED(hr))
{
if (guidType == MF_CAPTURE_ENGINE_PREVIEW_STOPPED)
{
m_pManager->OnPreviewStopped(hrStatus);
SetEvent(m_pManager->m_hEvent);
}
else if (guidType == MF_CAPTURE_ENGINE_RECORD_STOPPED)
{
m_pManager->OnRecordStopped(hrStatus);
SetEvent(m_pManager->m_hEvent);
}
else
{
// This is an event we don't know about, we don't really care and there's
// no clean way to report the error so just set the event and fall through.
SetEvent(m_pManager->m_hEvent);
}
}
return S_OK;
}
else
{
pEvent->AddRef(); // The application will release the pointer when it handles the message.
PostMessage(m_hwnd, WM_APP_CAPTURE_EVENT, (WPARAM)pEvent, 0L);
}
return S_OK;
}
- C++实用程序::转换在静态链接库中不起作用
- 在 OpenGL 中转换应用顺序让我感到困惑
- 如何将我的小程序转换为用于项目的函数?
- 将通用Windows应用程序转换为VisualStudio 2019上的常规应用程序
- C++应用程序通知 C# 应用程序
- 如何将我的程序转换为.dll文件并使用rundll32.exe在cmd中运行它?
- 将 C 程序转换为具有大量字符* 和无符号字符转换错误的C++
- 将视觉C 媒体基础捕获应用程序转换为C 构建器
- 更改 C++ 应用程序的应用程序窗口图标
- Qt 创建器中的实用程序::转换::to_string_t中的链接错误
- 面向对象设计-将C应用程序转换为C++
- 可视化如何将项目 win32 控制台应用程序转换为C++ Windows 窗体
- 将控制台应用程序转换为GUI
- 用驱动程序将win16下的应用程序转换为win32
- Visual studio 2015.c++控制台应用程序转换在安装项目与所有dll
- 将示例应用程序转换为DLL
- 传递List和numpy.从c++应用程序转换成python函数
- 将c++ /Win32控制台应用程序转换为DLL后崩溃
- 将一个完整的应用程序转换为DLL
- c++如何将x64位应用程序转换为x86