Compartilhar via


Exibir um bitmap fornecido pelo aplicativo na imagem composta

[O recurso associado a esta página, DirectShow, é um recurso herdado. Foi substituído por MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]

Os aplicativos podem usar o modo de combinação da VMR para exibir logotipos de canal combinado alfa, uma interface do usuário ou anúncios parcial ou completamente dentro do retângulo de vídeo. Como a mesclagem é executada em hardware pelo processador de elementos gráficos, há um impacto mínimo no desempenho de reprodução do Fluxo de Vídeo e não há nenhum artefato detectável de cintilação ou tearing. Os aplicativos podem alterar a imagem exibida com a frequência que desejarem. Deve-se observar que as alterações só são refletidas na tela quando o grafo de filtro do DirectShow está no estado em execução.

A VMR usa seu componente de mixer para sobrepor o bitmap na imagem composta. Com a VMR-7, o aplicativo deve forçar a VMR a carregar seu mixer, mesmo que haja apenas um único fluxo de vídeo. Isso não é necessário com a VMR-9, pois ela carrega seu mixer por padrão.

Para combinar uma imagem de bitmap estático com o fluxo de vídeo, o aplicativo cria a VMR e a adiciona ao grafo e, em seguida, chama IVMRFilterConfig::SetNumberOfStreams. O valor passado para essa função identifica o número de pinos de entrada que a VMR deve criar. Os aplicativos podem especificar qualquer valor entre 1 e MAX_MIXER_STREAMS; especificar um valor de 1 será válido se o aplicativo pretende exibir apenas um único fluxo de vídeo. Embora a VMR-7 tenha um único pino de entrada por padrão, esse método deve ser chamado para forçá-lo a carregar seu componente de mixer. (A VMR-9 carrega seu mixer e configura quatro pinos por padrão.)

Para definir o bitmap, use a interface IVMRMixerBitmap na interface VMR-7 ou IVMRMixerBitmap9 na VMR-9.

O bitmap pode ser especificado por um identificador para um hDC (Contexto de Dispositivo GDI) ou por uma interface do DirectDraw Surface. Se o aplicativo quiser que a imagem contenha informações alfa inseridas (também conhecidas como por pixel alfa), ele deverá colocar os dados da imagem em uma interface do DirectDraw Surface. Isso ocorre porque atualmente não é possível colocar informações alfa por pixel com um contexto de dispositivo GDI. A superfície DirectDraw deve ser RGB32 ou ARGB32 e, preferencialmente, deve ser uma superfície de memória do sistema. Não é necessário que as dimensões da superfície sejam uma potência de 2.

A VMR permite que os aplicativos especifiquem o local e um valor de transparência geral para a imagem. O código a seguir mostra como passar dados de imagem para a VMR para a combinação subsequente:

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;
    
    // Show the entire bitmap in the top-left 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;
    
    // Set the 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;
}

Os conceitos discutidos neste tópico são demonstrados no aplicativo de exemplo VMRPlayer Sample .

Criando animações simples com a imagem de bitmap

Para criar um logotipo de bitmap animado simples, coloque todos os "quadros" de bitmap em uma única imagem, conforme mostrado na ilustração a seguir.

faixa de imagens da vmr

Quando você definir o bitmap inicialmente usando IVMRMixerBitmap::SetAlphaBitmap, se o bitmap estiver em um HDC, defina o campo rSrc da estrutura VMRALPHABITMAP para especificar o tamanho de todo o bitmap dentro do HDC. Os membros superior e esquerdo da estrutura são definidos como 0 e os membros direito e inferior são a largura e a altura do bitmap. Se o bitmap estiver em uma superfície DirectDraw, o tamanho da superfície será conhecido, portanto, não será necessário especificar rSrc nesse método.

Quando você chamar IVMRMixerBitmap::UpdateAlphaBitmapParameters, use o membro rSrc para bitmaps HDC e DirectDraw, para especificar o quadro ou retângulo específico dentro da imagem que você deseja exibir e defina o sinalizador VMRBITMAP_SRCRECT no membro dwFlags .

Usando o modo de combinação de VMR