2012-11-29 20 views
8

BlackMagic SDK'yı kullanarak bir önizleme uygulaması yazmaya çalışıyorum ama dalgalı oynatım yapıyorum. MFC framework kullanıyorum ve video önizleme pencerem için CWnd alt sınıfını kullanıyorum.MFC Penceresine bitmapler olarak video karelerini çizin

Videonun her karesi geldiğinde, RGB'ye bir renk dönüşümü yaparım ve ardından RGB bitmapini görüntülemek için bir işlevi çağırıyorum.

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; 
} 

Daha düzgün bir video oluşturmak için ne yapılabilir?

Güncelleme:

Ben Direct2D'yi yerine GDI ile gidiş sona erdi ve çok daha iyi bir performans aldık. Aşağıdaki kod ben render üzere hemen kullanıyorum budur:

// 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(); 
+1

Bir kerede bir çerçeve yapmak, dalgalı videoya yol açacaktır çünkü günümüzün işlemcileriyle bile çok yavaştır. Bir video borusu kullanmalısın. –

+0

Videonun mümkün olduğunca gerçek zamana yakın olarak gösterilmesi gerekiyor. Video borusunda herhangi bir öneriniz var mı? – wshirey

+0

Üzgünüm, bir öneri olsaydı bir cevap bırakmış olurdum. –

cevap

0

BlackMagic DirectShow video kaynağı filtreleri ile gelir. BlackMagic filtresini video kaynağı olarak oluşturma kodu oluşturmak için GraphEditPlus kullanın. Renderer filtresi, bir HWND seçiminize bağlanabilir. Bu en iyi performansı vermelidir.

Geçerli uygulamanızın, arabelleği karıştırmak için Direct2D kullanıyor olsanız bile, daha fazla RAM ve CPU kullanımına neden olacağına inanıyorum.