c++ - 将 Visual C++ Media Foundation Capture 应用程序转换为 C++ Builder

标签 c++ video-capture ms-media-foundation

我正在尝试将 Microsoft“CaptureEngine 视频捕获示例”代码从 Visual C++ 转换为 Embarcadero C++ Builder。

https://code.msdn.microsoft.com/windowsdesktop/Media-Foundation-Capture-78504c83

代码在 Visual C++ 中运行良好,但我需要包含在 C++ Builder 应用程序中。我的代码基本上可以正常工作,但有几个问题需要帮助。

我可以选择视频源、预览视频源,甚至可以开始捕捉到文件。然而,视频捕获文件仅包含在视频长度内重复的一帧,即使音频已正确录制。

我想知道这是否是由于事件处理不当造成的。 来自媒体基础捕获引擎的事件使用 Windows 消息传递传递到主线程,然后调用媒体引擎事件处理程序。但是我注意到事件处理程序停止录制并停止预览使用等待结果

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++ Builder 事件处理程序触发的,它是等待事件处理的同一主线程的一部分,所以我在尝试停止视频录制时得到了线程锁。如果我注释掉该行,我不会锁定,但我也不会获得有效的录制视频文件。

我不确定 Visual C++ 如何将事件与 Capture 引擎代码分开,关于我如何为 C++ Builder 执行此操作有什么建议吗?

最佳答案

捕获引擎事件回调在工作线程上调用,它不是“同一主线程的一部分”。

// 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);

这实质上改变了应用程序的行为。控制线程停止预览并阻塞,直到工作线程发送一个通知来设置我上面引用的事件。从那里控制线程从等待操作中唤醒并继续预览停止。

如果这不是您在应用程序中看到的,我建议您在回调函数的第一行设置一个断点,以确保您收到通知。如果收到,您可以单步执行代码并确保到达事件设置行。如果您没有收到,则说明有其他事情正在阻塞,您将不得不解决这个问题,例如,通过中断和检查应用程序的线程状态。

关于c++ - 将 Visual C++ Media Foundation Capture 应用程序转换为 C++ Builder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57318936/

相关文章:

video-capture - 使用 Microsoft Media Foundation 和 Desktop Duplication API 创建视频

c++ - MF 不播放来 self 的来源的视频

c++ - 多线程 C++ 点火过程中 std::basicstring 的运行时段错误

c++ - 如何在 BlackBerry 10 中将日期格式转换为字符串

c++ - 创建一个二维 vector 数组

c++ - 媒体基础 H264 解码器无法正常工作

c++ - 更正实时 IMFMediaSource 时间戳

c++ - 可以 boost::interprocess 条件变量虚假唤醒吗?

linux - Linux 下的 VGA 采集卡

c++ - OpenCV Videocapture 抓取和检索