【发布时间】:2018-06-10 05:23:07
【问题描述】:
有 USB 3.0 HDMI Capture 设备。它使用 YUY2 格式(每像素 2 字节)和 1920x1080 分辨率。
视频捕获输出引脚直接连接到视频渲染输入引脚。 一切都很好。它向我显示 1920x1080 没有任何冻结。 但我需要每秒制作一次屏幕截图。所以这就是我所做的:
void CaptureInterface::ScreenShoot() {
IMemInputPin* p_MemoryInputPin = nullptr;
hr = p_RenderInputPin->QueryInterface(IID_IMemInputPin, (void**)&p_MemoryInputPin);
IMemAllocator* p_MemoryAllocator = nullptr;
hr = p_MemoryInputPin->GetAllocator(&p_MemoryAllocator);
IMediaSample* p_MediaSample = nullptr;
hr = p_MemoryAllocator->GetBuffer(&p_MediaSample, 0, 0, 0);
long buff_size = p_MediaSample->GetSize(); //buff_size = 4147200 Bytes
BYTE* buff = nullptr;
hr = p_MediaSample->GetPointer(&buff);
//BYTE CaptureInterface::ScreenBuff[1920*1080*2]; defined in header
//--------- TOO SLOW (1.5 seconds for 4 MBytes) ----------
std::memcpy(ScreenBuff, buff, buff_size);
//--------------------------------------------
p_MediaSample->Release();
p_MemoryAllocator->Release();
p_MemoryInputPin->Release();
return;
}
使用此缓冲区的任何其他操作也很慢。
但是如果我在其他数据上使用memcpy(我的类中的 2 个数组,例如相同大小 4MB)它非常快。
【问题讨论】:
-
这种内存页的感觉只是捕获设备上的物理缓冲区的链接。在 USB 3.0 线的另一端。并且 memcpy 每次都会在其 USB 连接中复制部分数据,然后将其关闭。
-
如果您尝试在渲染器之前插入 tee 过滤器?然后,您可以尝试从第二个引脚转储视频数据。
-
谢谢大家。我在我的图中枚举了过滤器,并看到 capturepraphbuilder2 自己添加了 2 个过滤器。 Smart Tee 和 AVI 解压器。有些奇怪的是,AVI Decompessor 什么都不做。输入和输出格式相同(yuy2)。但是我找到了它的第一个引脚,获取缓冲区并且它不在显存中,所以我通过预定义的 LUT 表非常快(
标签: c performance memory directshow screen-capture