【问题标题】:Draw video frames as bitmaps to MFC Window将视频帧作为位图绘制到 MFC 窗口
【发布时间】:2012-11-17 22:07:05
【问题描述】:

我正在尝试使用 BlackMagic SDK 编写预览应用程序,但播放时出现断断续续的情况。我正在使用 MFC 框架,并将 CWnd 子类化为我的视频预览窗口。

当每一帧视频到达时,我将颜色转换为 RGB,然后调用一个函数来显示 RGB 位图。

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

【问题讨论】:

  • 一次处理一帧会导致视频断断续续,因为它太慢了,即使使用当今的处理器也是如此。您需要使用视频管道。
  • 那么视频需要尽可能接近实时地显示。对视频管道有什么建议吗?
  • 对不起,如果我有建议,我会留下答案。
  • 使用 SetDIBits 是否会使其更快?你确定瓶颈在这里吗?你测量过画一帧需要多长时间吗?如果您所追求的只是大约 24 fps,我会说使用 SetDIBits 应该是可能的——我已经实现了比 5 多年前在计算机上更好的帧速率。但是他们不必进行视频解码,因此我的问题是瓶颈是否真的在这里。
  • OpenCV 有很好的工具来显示视频。

标签: video bitmap mfc


【解决方案1】:

BlackMagic 带有DirectShow 视频源过滤器。使用GraphEditPlus 生成以BlackMagic 滤镜为视频源的渲染代码。 Renderer 过滤器可以链接到您选择的HWND。这应该会提供最佳性能。

我相信你当前的实现会导致更多的RAMCPU 使用,即使你使用Direct2D 来blit 缓冲区。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    • 2017-10-29
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    相关资源
    最近更新 更多