DirectShow DirectShow 의 사용법 Video Mixing Renderer 의 사용법 애플리케이션이 제공하는 비트 맵을 합성 이미지상에 표시한다   [목차열람] [주소복사] [슬롯비우기]
애플리케이션이 제공하는 비트 맵을 합성 이미지상에 표시한다
 
Microsoft DirectX 9.0

애플리케이션이 제공하는 비트 맵을 합성 이미지상에 표시한다

애플리케이션은 VMR 의 "믹서 비트 맵" 기능을 사용해, 알파 블렌드 된 채널 로고, 사용자 인터페이스, 또는 광고의 일부나 전체를 비디오 직사각형내에 표시할 수 있다. 혼합은 그래픽 프로세서에 의해 하드웨어로 실행되기 (위해)때문에, 비디오 스트림의 재생의 퍼포먼스는 거의 영향을 받지 않고, 검출 가능한 플릭커나 예기치 못한 표시는 발생하지 않는다. 애플리케이션은, 표시하는 이미지를 필요에 따라서 몇회에서도 변경할 수 있다. 변경이 화면에 반영되는 것은, DirectShow 필터 그래프가 실행 상태가 되어 있을 때인 점에 주의 해야 한다.

VMR 는 믹서 구성 요소를 사용해 비트 맵을 합성 이미지에 오버레이 한다. VMR-7 의 경우, 비디오 스트림이 1 개 밖에 없을 때에서도, 애플리케이션은 VMR 의 믹서를 로드할 필요가 있다. VMR-9 는 디폴트로 믹서를 로드하기 (위해)때문에, 이러한 처리는 필요없다.

정적 비트 맵 이미지를 비디오 스트림과 블렌드 하려면 , 애플리케이션은 VMR 를 생성 해 그래프에 추가해,IVMRFilterConfig::SetNumberOfStreams 를 호출한다. 이 함수에 건네주는 값은, VMR 가 생성 하는 입력 핀의 수를 나타낸다. 애플리케이션은 1 으로부터 MAX_MIXER_STREAMS 까지의 임의의 값을 지정할 수 있다. 1 개의 비디오 스트림 밖에 표시하지 않는 경우는, 값 1 을 지정해도 유효하다. VMR-7 에는 디폴트로 1 개의 입력 핀이 있지만, 믹서 구성 요소를 강제적으로 로드하기 (위해)때문에, 이 메서드를 호출할 필요가 있다. (VMR-9 는 디폴트로 믹서를 로드해, 4 개의 핀을 셋업 한다. )

비트 맵은 GDI 장치 문맥에의 핸들 (hDC) 또는 DirectDraw 표면 인터페이스에 의해 지정할 수 있다. 애플리케이션이 이미지에 묻어 알파 정보 (픽셀 단위 알파라고도 부른다)를 넣을 필요가 있는 경우, 이미지 데이터는 DirectDraw 표면 인터페이스에 두지 않으면 안 된다. 현재는, GDI 장치 문맥을 사용해 픽셀 단위의 알파 정보를 배치할 수 없기 때문이다. DirectDraw 표면은 RGB32 나 ARGB32 일 필요가 있어, 시스템 메모리 표면인 것이 바람직하다. 표면 넓이가 2 의 거듭제곱일 필요는 없다.

애플리케이션은 VMR 를 사용해, 이미지의 위치와 전체적인 투과값을 지정할 수 있다. 다음 코드는, 혼합이기 때문에, 이미지 데이터를 VMR 에 건네주는 방법을 나타내고 있다.

HRESULT BlendApplicationImage( 
  HWND hwndApp,
  IVMRWindowlessControl* pWc,
  HBITMAP hbm
)
{
    LONG cx, cy;
    HRESULT hr;
    hr = pWc->GetNativeVideoSize(&cx, &cy, NULL, NULL);
    if (FAILED(hr))
        return hr;
    
    HDC hdc = GetDC(hwndApp);
    if (hdc == NULL)
    {
        return E_FAIL;
    }
    
    HDC hdcBmp = CreateCompatibleDC(hdc);
    ReleaseDC(hwndApp, hdc);
    
    if (hdcBmp == NULL)
    {
        return E_FAIL;
    }
    
    BITMAP bm;
    if (0 == GetObject(hbm, sizeof(bm), &bm))
    {
        DeleteDC(hdcBmp);
        return E_FAIL;
    }
    
    HBITMAP hbmOld = (HBITMAP) SelectObject(hdcBmp, hbm);
    if (hbmOld == 0)
    {
        DeleteDC(hdcBmp);
        return E_FAIL;
    }
    
    VMRALPHABITMAP bmpInfo;
    ZeroMemory(&bmpInfo, sizeof(bmpInfo) );
    bmpInfo.dwFlags = VMRBITMAP_HDC;
    bmpInfo.hdc = hdcBmp;
    
    // 비디오 이미지의 맨 왼쪽 위쪽에 비트 맵 전체를 표시한다.
    SetRect(&bmpInfo.rSrc, 0, 0, bm.bmWidth, bm.bmHeight);
    bmpInfo.rDest.left = 0. f;
    bmpInfo.rDest.top = 0. f;
    bmpInfo.rDest.right = (float) bm.bmWidth / (float) cx;
    bmpInfo.rDest.bottom = (float) bm.bmHeight / (float) cy;
    
    // 투과값을 설정한다 (1.0 은 불투명, 0.0 은 투명).
    bmpInfo.fAlpha = 0.2f;
    
    IVMRMixerBitmap* pBmp;
    hr = pWc->QueryInterface(IID_IVMRMixerBitmap, (LPVOID *) &pBmp);
    if (SUCCEEDED(hr)) 
    {
        pBmp->SetAlphaBitmap(&bmpInfo);
        pBmp->Release();
    }
    
    DeleteObject(SelectObject(hdcBmp, hbmOld));
    DeleteDC(hdcBmp);
    return hr;
}

여기서 설명한 내용은,VMRPlayer 샘플 샘플 애플리케이션에 나타나고 있다.

↑TOP