2012-08-05 3 views

답변

1

Windows GDI 호출로이 작업을 수행 할 수있었습니다. 내가 만든 MFT에는 RGB32 입/출력 유형이있어서 비트 맵 객체로 /으로부터 복사 할 수 있습니다. 텍스트로 오버레이하려는 프레임의 일부를 복사하여 만든 Windows 비트 맵에 복사 한 다음 텍스트를 그린 다음 IMFMediaBuffer에 다시 복사합니다.

#define BREAK_ON_FAIL(val) { if (FAILED(hr = (val))) { break; } } 

HRESULT AddOverlay(IMFSample* pSample) 
{ 
    HRESULT hr = S_OK; 
    IMFMediaBuffer * pBuffer; 
    HDC hDC, hMemDC; 
    HBITMAP hBitmap, hOldBitmap; 

    do 
    { 
     BYTE * pBufferData; 
     UINT32 nWidth, nHeight; 
     BITMAPV5HEADER bi; 
     BYTE * pBitmapData; 
     UINT32 nXOffset, nYOffset; 
     RECT OverlayRect; 
     OverlayRect.left = 0; 
     OverlayRect.top = 0; 
     OverlayRect.right = 400; 
     OverlayRect.bottom = 32; 
     DWORD nOverlayWidth = OverlayRect.right - OverlayRect.left; 
     DWORD nOverlayHeight = OverlayRect.bottom - OverlayRect.top; 
     LONG lFrameStride; 

     // Get the frame dimensions and stride 
     MFGetAttributeSize(m_pInputType, MF_MT_FRAME_SIZE, &nWidth, &nHeight); 
     m_pInputType->GetUINT32(MF_MT_DEFAULT_STRIDE, (UINT32*)&lFrameStride)) 

     // Setup offset for the overlay area into the video frame 
     nXOffset = (nWidth - nOverlayWidth)/2; 
     nYOffset = nOverlayHeight-1; 

     // Set up the bitmap header 
     ZeroMemory(&bi, sizeof(BITMAPV5HEADER)); 
     bi.bV5Size   = sizeof(BITMAPV5HEADER); 
     bi.bV5Width   = nOverlayWidth; 
     // If the stride is negative, the bitmap is bottom-up, which is designated by a negative height 
     bi.bV5Height  = (lFrameStride > 0) ? nOverlayHeight : -(LONG)nOverlayHeight; 
     bi.bV5Planes  = 1; 
     bi.bV5BitCount  = 32; 
     bi.bV5Compression = BI_RGB; 
     // The following mask specification specifies a supported 32 BPP 
     // alpha format for Windows XP. 
     bi.bV5RedMask  = 0x00FF0000; 
     bi.bV5GreenMask  = 0x0000FF00; 
     bi.bV5BlueMask  = 0x000000FF; 
     bi.bV5AlphaMask  = 0xFF000000; 

     // Create a DIB section with an alpha channel, along with 
     // a memory device context 
     hDC = GetDC(NULL); 
     hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&pBitmapData, NULL, 0); 
     hMemDC = CreateCompatibleDC(hDC); 
     ReleaseDC(NULL, hDC); 

     // Lock the media buffer for our use 
     BREAK_ON_FAIL(pSample->GetBufferByIndex(0, &pBuffer)); 
     BREAK_ON_FAIL(pBuffer->Lock(&pBufferData, NULL, NULL)); 

     // Copy the video frame to the bitmap (to support transparency) 
     MFCopyImage(pBitmapData, nOverlayWidth*sizeof(RGBQUAD), 
      pBufferData + nYOffset*abs(lFrameStride) + nXOffset*sizeof(RGBQUAD), lFrameStride, 
      nOverlayWidth*sizeof(RGBQUAD), nOverlayHeight); 

     // Draw on the bitmap 
     hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); 
     //FillRect(hMemDC, &OverlayRect, WHITE_BRUSH); 
     SetTextColor(hMemDC, RGB(255,0,0)); 
     SetBkMode(hMemDC, TRANSPARENT); 
     DrawText(hMemDC, _T("Hello World!"), 12, &OverlayRect, DT_CENTER); 
     SelectObject(hMemDC, hOldBitmap); 

     // Copy the bitmap to the buffer 
     MFCopyImage(pBufferData + nYOffset*abs(lFrameStride) + nXOffset*sizeof(RGBQUAD), lFrameStride, 
      pBitmapData, nOverlayWidth*sizeof(RGBQUAD), 
      nOverlayWidth*sizeof(RGBQUAD), nOverlayHeight); 

     BREAK_ON_FAIL(pBuffer->Unlock()); 

    } while(false); 

    DeleteDC(hMemDC); 
    DeleteObject(hBitmap); 
    SafeRelease(&pBuffer); 

    return hr; 
} 

참고 :

여기 내 코드입니다