gpt4 book ai didi

c++ - 使用 EVR 直接使用 Media Foundation 显示相机设备捕获的帧

转载 作者:太空宇宙 更新时间:2023-11-04 13:20:13 24 4
gpt4 key购买 nike

我正在尝试编写一个小应用程序,将相机设备捕获的视频帧直接显示到窗口上。我正在使用“Source Reader”+“Sink Writer”架构而不是“Media Session”,因为我必须直接处理那些捕获的样本。我已经成功创建了 Source Reader,但是当我尝试创建 EVR 来显示帧时,我遇到了一些问题...以下是我的代码:

HRESULT CCapture::CreatePreviewEVR(HWND hWindow)
{
// m_pPreviewSink, m_pPreviewStream, m_pPresentationClock, and m_pPresentationTimeSource
// are all defined as Class members
HRESULT hr = S_OK;
DWORD sinkCharacteristics = NULL;
IMFActivate *pPreviewSinkActive = NULL;
IMFClockStateSink *pClockStateSink = NULL;
hr = MFCreateVideoRendererActivate(hWindow, &pPreviewSinkActive);
if(SUCCEEDED(hr))
{
hr = pPreviewSinkActive->ActivateObject(IID_PPV_ARGS(&m_pPreviewSink));
}
if(SUCCEEDED(hr))
{
hr = m_pPreviewSink->GetCharacteristics(&sinkCharacteristics); // sinkCharacteristics is 0x18
}
if(SUCCEEDED(hr))
{
hr = m_pPreviewSink->GetStreamSinkByIndex(0, &m_pPreviewStream);
}
if(SUCCEEDED(hr))
{
hr = MFCreatePresentationClock(&m_pPresentationClock);
}
if(SUCCEEDED(hr))
{
hr = MFCreateSystemTimeSource(&m_pPresentationTimeSource);
}
if(SUCCEEDED(hr))
{
hr = m_pPresentationTimeSource->QueryInterface(__uuidof(IMFClockStateSink),(void**)&pClockStateSink);
}
if(SUCCEEDED(hr))
{
hr = m_pPresentationClock->SetTimeSource(m_pPresentationTimeSource);
}
if(SUCCEEDED(hr))
{
hr = m_pPresentationClock->AddClockStateSink(pClockStateSink);
}
if(SUCCEEDED(hr))
{
hr = m_pPreviewSink->SetPresentationClock(m_pPresentationClock);
}
return hr;
}

HRESULT CCapture::ConfigurePreviewEVR()
{
// This function is implemented trying to do EVR Media Type Negotiation
DWORD mediaTypeCount = 0;
HRESULT hr =S_OK;
IMFMediaType *pSourceReaderType = NULL;
IMFMediaType *pSourceReaderTypeValid = NULL;
IMFMediaType *pPreviewSinkMediaType = NULL;
IMFMediaTypeHandler *pPreviewSinkMediaTypeHandler = NULL;
hr = m_pReader->GetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, &pSourceReaderType);
if(SUCCEEDED(hr))
{
hr = MFCreateMediaType(&pPreviewSinkMediaType);
}
if(SUCCEEDED(hr))
{
hr = pPreviewSinkMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
}
if(SUCCEEDED(hr))
{
hr = pPreviewSinkMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
}
if(SUCCEEDED(hr))
{
hr = pPreviewSinkMediaType->SetUINT32(MF_MT_AVG_BITRATE, 14000000);
}
if(SUCCEEDED(hr))
{
hr = CopyAttribute(pSourceReaderType, pPreviewSinkMediaType, MF_MT_FRAME_SIZE);
}
if(SUCCEEDED(hr))
{
hr = CopyAttribute(pSourceReaderType, pPreviewSinkMediaType, MF_MT_FRAME_RATE);
}
if(SUCCEEDED(hr))
{
hr = CopyAttribute(pSourceReaderType, pPreviewSinkMediaType, MF_MT_PIXEL_ASPECT_RATIO);
}
if(SUCCEEDED(hr))
{
hr = CopyAttribute(pSourceReaderType, pPreviewSinkMediaType, MF_MT_INTERLACE_MODE);
}
if(SUCCEEDED(hr))
{
hr = m_pPreviewStream->GetMediaTypeHandler(&pPreviewSinkMediaTypeHandler);
}
if(SUCCEEDED(hr))
{
hr = pPreviewSinkMediaTypeHandler->GetMediaTypeCount(&mediaTypeCount); // derived mediaTypeCount is 0
}
if(SUCCEEDED(hr))
{
hr = pPreviewSinkMediaTypeHandler->IsMediaTypeSupported(pSourceReaderType, &pSourceReaderTypeValid); // Failed to get supported Media Type
}
if(SUCCEEDED(hr))
{
hr = pPreviewSinkMediaTypeHandler->SetCurrentMediaType(pSourceReaderTypeValid); // This function still fails if I use pSourceReaderType directly
}
if(SUCCEEDED(hr))
{
SafeRelease(&pSourceReaderType);
SafeRelease(&pPreviewSinkMediaType);
SafeRelease(&pPreviewSinkMediaTypeHandler);
}
return hr;
}

CopyAttribute函数来自MFCaptureToFile Sample Code,可以正常使用。由于变量“sinkCharacteristics”给出的是 0x18,看来我应该能够向 mediasink 添加一个具有我希望使用的媒体类型的新流;但是我尝试了 AddStreamSink 函数,但它直接返回了错误。“CCapture”类继承自 IMFSourceReaderCallBack,如果我的理解是正确的,我应该在 OnReadSample 回调函数中使用 m_pPreviewStream->ProcessSample(pSample)。如果有人可以提供帮助,非常感谢!最好的问候

最佳答案

这看起来很困惑。

当您希望 EVR 显示来自多个来源的帧时,您必须使用 AddStreamSink。

阅读您的帖子时,您只想显示来自相机(单一来源)的帧。

因此您不需要使用 AddStreamSink。

并且您从 AddStreamSink 收到错误,因为在将流添加到 EVR 时使用的媒体类型存在一些限制(这取决于您的 GPU 特性)。

关于c++ - 使用 EVR 直接使用 Media Foundation 显示相机设备捕获的帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35652090/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com