Video 将视频帧绘制为位图到MFC窗口
我正试图使用BlackMagic SDK编写一个预览应用程序,但我得到的是断断续续的播放。我正在使用MFC框架,并为我的视频预览窗口子类化CWnd 当视频的每一帧到达时,我将颜色转换为RGB,然后调用一个函数来显示RGB位图Video 将视频帧绘制为位图到MFC窗口,video,bitmap,mfc,Video,Bitmap,Mfc,我正试图使用BlackMagic SDK编写一个预览应用程序,但我得到的是断断续续的播放。我正在使用MFC框架,并为我的视频预览窗口子类化CWnd 当视频的每一帧到达时,我将颜色转换为RGB,然后调用一个函数来显示RGB位图 void VideoPreview::Display(int width, int height, byte* buffer) { __int64 begin = GetTickCount(); HRESULT hr; CRect
void VideoPreview::Display(int width, int height, byte* buffer)
{
__int64 begin = GetTickCount();
HRESULT hr;
CRect rcRect, statusBarRect;
GetClientRect (rcRect);
BITMAPINFO bmInfo;
ZeroMemory(&bmInfo, sizeof(BITMAPINFO));
bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmInfo.bmiHeader.biBitCount = 32;
bmInfo.bmiHeader.biPlanes = 1;
bmInfo.bmiHeader.biWidth = width;
bmInfo.bmiHeader.biHeight = -height;
dc->SetStretchBltMode(COLORONCOLOR);
int iResult = StretchDIBits(*dc,
rcRect.left, rcRect.top, rcRect.right, rcRect.bottom,
0, 0, width, height,
buffer, &bmInfo, 0, SRCCOPY);
DWORD dwError;
if (iResult == 0 || iResult == GDI_ERROR)
{
dwError = GetLastError();
}
else
fpsCount++;
procTimeCount += GetTickCount() - begin;
}
如何创建更平滑的视频
更新:
我最终选择了Direct2D而不是GDI,并且获得了更好的性能。下面的代码是我现在用于渲染的代码:
// initialization
HRESULT hr = D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
&pD2DFactory
);
// Obtain the size of the drawing area.
RECT rc;
GetClientRect(&rc);
// Create a Direct2D render target
hr = pD2DFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(
this->GetSafeHwnd(),
D2D1::SizeU(
1280, 720
/*rc.right - rc.left,
rc.bottom - rc.top*/)
),
&pRT);
D2D1_BITMAP_PROPERTIES properties;
properties.pixelFormat = D2D1::PixelFormat(
DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE);
properties.dpiX = properties.dpiY = 96;
hr = pRT->CreateBitmap(D2D1::SizeU(1280, 720), properties, &pBitmap);
ASSERT(SUCCEEDED(hr));
// per frame code
// buffer is rgb frame
HRESULT hr;
pRT->BeginDraw();
pBitmap->CopyFromMemory(NULL, buffer, width*4);
pRT->DrawBitmap(pBitmap);
pRT->EndDraw();
BlackMagic附带了
DirectShow
视频源过滤器。使用graphieditplus
以BlackMagic过滤器作为视频源生成渲染代码。渲染器
过滤器可以链接到您选择的HWND
。这将提供最佳性能
我相信您当前的实现将导致更多的
RAM
和CPU
使用,即使您使用Direct2D
对缓冲区进行blit。一次执行一帧将导致视频断断续续,因为即使使用今天的处理器,速度也太慢。您需要使用视频管道。视频需要尽可能接近实时地显示。对视频管道有什么建议吗?对不起,如果我有建议的话,我会留下一个答案。使用SetDIBits会让它更快吗?你确定瓶颈在这里吗?你测量过画一个单帧需要多长时间吗?如果你所追求的是大约24帧每秒,我会说,这应该是可能的与SetDIBits-我已经取得了更好的帧速率比电脑上的5+年前。然而,他们不必做视频解码,因此我的问题是瓶颈是否真的在这里。OpenCV有很好的工具来显示视频。