Microsoft DirectX 8.1 (C++)

Configuring the VMR for a Static Bitmap Display

This topic applies to Windows XP Home Edition and Windows XP Professional only.

To blend a static bitmap image with the video stream, the application creates the VMR and adds it to the graph, and then calls IVMRFilterConfig::SetNumberOfStreamss. The value passed to this function identifies the number of input pins that the VMR should create. Applications can specify any value between 1 and MAX_MIXER_STREAMS, specifying a value of 1 is valid if the application only intends to display a single video stream at once. Even though the VMR has a single input pin by default, this method must be called in order to force the VMR to load its mixer component.

The bitmap can be specified by either a handle to a GDI Device Context (hDC) or by a DirectDraw Surface interface. If the application wants the image to contain embedded alpha information (also known as per pixel alpha) it must place the image data in a DirectDraw Surface interface. This is because it is not currently possible to place per-pixel alpha information with a GDI Device Context. The DirectDraw surface must be either RGB32 or ARGB32, and should preferably be a system memory surface. It is not necessary for the surface dimensions to be a power of 2.

The VMR allows applications to specify the location and an overall transparency value for the image. The code below shows how to pass image data down to the VMR for subsequent blending:

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;

  BITMAP bm;
  HBITMAP hbmOld;
  HDC hdc = GetDC(hwndApp);
  HDC hdcBmp = CreateCompatibleDC(hdc);
  ReleaseDC(hwndApp, hdc);

  GetObject(hbm, sizeof(bm), &bm);
  hbmOld = (HBITMAP)SelectObject(hdcBmp, hbm);

  VMRALPHABITMAP bmpInfo;
  ZeroMemory(&bmpInfo, sizeof(bmpInfo) );
  bmpInfo.dwFlags = VMRBITMAP_HDC;
  bmpInfo.hdc = hdcBmp;

  // Display all the bitmap in the top
  // left hand corner of the video image.
  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;

  // Transparency value 1.0 is opaque, 0.0 is transparent.
  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;
}

The concepts discussed in this topic are demonstrated in the VMRPlayer Sample sample application.