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.
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 .
Tópicos relacionados