Processamento de vídeo DXVA
O processamento de vídeo DXVA encapsula as funções do hardware gráfico que são dedicadas ao processamento de imagens de vídeo não compactadas. Os serviços de processamento de vídeo incluem desentrelaçamento e mistura de vídeo.
Este tópico contém as seguintes seções:
- Visão geral
- Criar um dispositivo de processamento de vídeo
- Transferência de bits do processo de vídeo
- Composição da imagem
- Ordem de amostra de entrada
- Tópicos relacionados
Visão geral
O hardware gráfico pode usar a GPU (unidade de processamento gráfico) para processar imagens de vídeo não compactadas. Um dispositivo de processamento de vídeo é um componente de software que encapsula essas funções. Os aplicativos podem usar um dispositivo de processamento de vídeo para executar funções como:
- Desentrelaçar e telecine inverso
- Misturando subfluxos de vídeo na imagem de vídeo principal
- Ajuste de cor (ProcAmp) e filtragem de imagem
- Colocação em escala da imagem
- Conversão de espaço de cores
- combinação alfa
O diagrama a seguir mostra os estágios no pipeline de processamento de vídeo. O diagrama não se destina a mostrar uma implementação real. Por exemplo, o driver gráfico pode combinar vários estágios em uma única operação. Todas essas operações podem ser realizadas em uma única chamada para o dispositivo de processamento de vídeo. Alguns estágios mostrados aqui, como filtragem de ruído e detalhes, podem não ser suportados pelo driver.
A entrada para o pipeline de processamento de vídeo sempre inclui um fluxo de vídeo primário, que contém os dados da imagem principal. O fluxo de vídeo primário determina a taxa de quadros do vídeo de saída. Cada quadro do vídeo de saída é calculado em relação aos dados de entrada do fluxo de vídeo primário. Os pixels no fluxo primário são sempre opacos, sem dados alfa por pixel. O fluxo de vídeo primário pode ser progressivo ou entrelaçado.
Opcionalmente, o pipeline de processamento de vídeo pode receber até 15 subfluxos de vídeo. Um subfluxo contém dados de imagem auxiliares, como legendas ocultas ou subimagens de DVD. Essas imagens são exibidas sobre o fluxo de vídeo primário e geralmente não devem ser mostradas sozinhas. As imagens de subfluxo podem conter dados alfa por pixel e são sempre quadros progressivos. O dispositivo de processamento de vídeo combina com alfa as imagens de subfluxo com o quadro desentrelaçado atual do fluxo de vídeo primário.
No restante deste tópico, o termo imagem é usado para os dados de entrada em um dispositivo de processamento de vídeo. Uma imagem pode consistir em um quadro progressivo, um único campo ou dois campos intercalados. A saída é sempre um quadro desentrelaçado.
Um driver de vídeo pode implementar mais de um dispositivo de processamento de vídeo, para fornecer diferentes conjuntos de recursos de processamento de vídeo. Os dispositivos são identificados pelo GUID. Os GUIDs a seguir são predefinidos:
- DXVA2_VideoProcBobDevice. Este dispositivo realiza o desentrelaçamento bob.
- DXVA2_VideoProcProgressiveDevice. Este dispositivo é usado se o vídeo contiver apenas quadros progressivos, sem quadros entrelaçados. (Algum conteúdo de vídeo contém uma combinação de quadros progressivos e entrelaçados. O dispositivo progressivo não pode ser usado para esse tipo de conteúdo de vídeo "misto", porque uma etapa de desentrelaçamento é necessária para os quadros entrelaçados.)
Cada driver gráfico que suporta processamento de vídeo DXVA deve implementar pelo menos esses dois dispositivos. O driver gráfico também pode fornecer outros dispositivos, que são identificados por GUIDs específicos do driver. Por exemplo, um driver pode implementar um algoritmo de desentrelaçamento proprietário que produz uma saída de melhor qualidade do que o desentrelaçamento bob. Alguns algoritmos de desentrelaçamento podem exigir imagens de referência para frente ou para trás do fluxo primário. Em caso afirmativo, o chamador deve fornecer essas imagens ao driver na sequência correta, conforme descrito posteriormente nesta seção.
Um dispositivo de software de referência também é fornecido. O dispositivo de software é otimizado para qualidade em vez de velocidade, e pode não ser adequado para processamento de vídeo em tempo real. O dispositivo de software de referência usa o valor GUID DXVA2_VideoProcSoftwareDevice.
Criar um dispositivo de processamento de vídeo
Antes de usar o processamento de vídeo DXVA, o aplicativo deve criar um dispositivo de processamento de vídeo. Aqui está um breve esboço das etapas, que são explicadas em mais detalhes no restante desta seção:
- Obtenha um ponteiro para a interface IDirectXVideoProcessorService.
- Crie uma descrição do formato de vídeo para o fluxo de vídeo primário. Use esta descrição para obter uma lista dos dispositivos de processamento de vídeo que oferecem suporte ao formato de vídeo. Os dispositivos são identificados pelo GUID.
- Para um dispositivo específico, obtenha uma lista de formatos de destino de renderização suportados pelo dispositivo. Os formatos são retornados como uma lista de valores D3DFORMAT. Se você planeja misturar subfluxos, obtenha também uma lista dos formatos de subfluxo suportados.
- Consulte os recursos de cada dispositivo.
- Criar os dispositivos de processamento de vídeo.
Às vezes, você pode omitir algumas dessas etapas. Por exemplo, em vez de obter a lista de formatos de destino de renderização, você pode simplesmente tentar criar o dispositivo de processamento de vídeo com seu formato preferido e ver se ele é bem-sucedido. Um formato comum, como D3DFMT_X8R8G8B8, provavelmente terá sucesso.
O restante desta seção descreve essas etapas em detalhes.
Obter o ponteiro IDirectXVideoProcessorService
A interface IDirectXVideoProcessorService é obtida do dispositivo Direct3D. Há duas maneiras de obter um ponteiro para essa interface:
- A partir de um dispositivo Direct3D.
- A partir do Gerenciador de dispositivos Direct3D.
Se você tiver um ponteiro para um dispositivo Direct3D, poderá obter um ponteiro IDirectXVideoProcessorService chamando a função DXVA2CreateVideoService. Passe um ponteiro para a interface IDirect3DDevice9 do dispositivo e especifique IID_IDirectXVideoProcessorService para o parâmetro riid, conforme mostrado no código a seguir:
// Create the DXVA-2 Video Processor service.
hr = DXVA2CreateVideoService(g_pD3DD9, IID_PPV_ARGS(&g_pDXVAVPS));
Em alguns casos, um objeto cria o dispositivo Direct3D e o compartilha com outros objetos por meio do Gerenciador de Dispositivos Direct3D. Nessa situação, você pode chamar IDirect3DDeviceManager9::GetVideoService no gerenciador de dispositivos para obter o ponteiro IDirectXVideoProcessorService, conforme mostrado no código a seguir:
HRESULT GetVideoProcessorService(
IDirect3DDeviceManager9 *pDeviceManager,
IDirectXVideoProcessorService **ppVPService
)
{
*ppVPService = NULL;
HANDLE hDevice;
HRESULT hr = pDeviceManager->OpenDeviceHandle(&hDevice);
if (SUCCEEDED(hr))
{
// Get the video processor service
HRESULT hr2 = pDeviceManager->GetVideoService(
hDevice,
IID_PPV_ARGS(ppVPService)
);
// Close the device handle.
hr = pDeviceManager->CloseDeviceHandle(hDevice);
if (FAILED(hr2))
{
hr = hr2;
}
}
if (FAILED(hr))
{
SafeRelease(ppVPService);
}
return hr;
}
Enumerar os dispositivos de processamento de vídeo
Para obter uma lista de dispositivos de processamento de vídeo, preencha uma estrutura DXVA2_VideoDesc com o formato do fluxo de vídeo primário e passe essa estrutura para o método IDirectXVideoProcessorService::GetVideoProcessorDeviceGuids. O método retorna uma matriz de GUIDs, um para cada dispositivo de processamento de vídeo que pode ser usado com esse formato de vídeo.
Considere um aplicativo que renderiza um fluxo de vídeo no formato YUY2, usando a definição BT.709 de cor YUV, com uma taxa de quadros de 29,97 quadros por segundo. Suponha que o conteúdo do vídeo consista inteiramente de quadros progressivos. O fragmento de código a seguir mostra como preencher a descrição do formato e obter os GUIDs do dispositivo:
// Initialize the video descriptor.
g_VideoDesc.SampleWidth = VIDEO_MAIN_WIDTH;
g_VideoDesc.SampleHeight = VIDEO_MAIN_HEIGHT;
g_VideoDesc.SampleFormat.VideoChromaSubsampling = DXVA2_VideoChromaSubsampling_MPEG2;
g_VideoDesc.SampleFormat.NominalRange = DXVA2_NominalRange_16_235;
g_VideoDesc.SampleFormat.VideoTransferMatrix = EX_COLOR_INFO[g_ExColorInfo][0];
g_VideoDesc.SampleFormat.VideoLighting = DXVA2_VideoLighting_dim;
g_VideoDesc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_BT709;
g_VideoDesc.SampleFormat.VideoTransferFunction = DXVA2_VideoTransFunc_709;
g_VideoDesc.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
g_VideoDesc.Format = VIDEO_MAIN_FORMAT;
g_VideoDesc.InputSampleFreq.Numerator = VIDEO_FPS;
g_VideoDesc.InputSampleFreq.Denominator = 1;
g_VideoDesc.OutputFrameFreq.Numerator = VIDEO_FPS;
g_VideoDesc.OutputFrameFreq.Denominator = 1;
// Query the video processor GUID.
UINT count;
GUID* guids = NULL;
hr = g_pDXVAVPS->GetVideoProcessorDeviceGuids(&g_VideoDesc, &count, &guids);
O código para esta amostra é retirado da amostra do SDK DXVA2_VideoProc.
A matriz pGuids neste exemplo é alocada pelo método GetVideoProcessorDeviceGuids, portanto, o aplicativo deve liberar a matriz chamando CoTaskMemFree. As etapas restantes podem ser executadas usando qualquer um dos GUIDs de dispositivo retornados por esse método.
Enumerar os formatos de destino de renderização
Para obter a lista de formatos de destino de renderização suportados pelo dispositivo, passe o GUID do dispositivo e a estrutura DXVA2_VideoDesc para o método IDirectXVideoProcessorService::GetVideoProcessorRenderTargets, conforme mostrado no código a seguir:
// Query the supported render-target formats.
UINT i, count;
D3DFORMAT* formats = NULL;
HRESULT hr = g_pDXVAVPS->GetVideoProcessorRenderTargets(
guid, &g_VideoDesc, &count, &formats);
if (FAILED(hr))
{
DBGMSG((L"GetVideoProcessorRenderTargets failed: 0x%x.\n", hr));
return FALSE;
}
for (i = 0; i < count; i++)
{
if (formats[i] == VIDEO_RENDER_TARGET_FORMAT)
{
break;
}
}
CoTaskMemFree(formats);
if (i >= count)
{
DBGMSG((L"The device does not support the render-target format.\n"));
return FALSE;
}
O método retorna uma matriz de valores D3DFORMAT. Neste exemplo, onde o tipo de entrada é YUY2, uma lista típica de formatos pode ser D3DFMT_X8R8G8B8 (RGB de 32 bits) e D3DMFT_YUY2 (o formato de entrada). No entanto, a lista exata dependerá do driver.
A lista de formatos disponíveis para os subfluxos pode variar dependendo do formato de destino de renderização e do formato de entrada. Para obter a lista de formatos de subfluxo, passe o GUID do dispositivo, a estrutura de formato e o formato de destino de renderização para o método IDirectXVideoProcessorService::GetVideoProcessorSubStreamFormats, conforme mostrado no código a seguir:
// Query the supported substream formats.
formats = NULL;
hr = g_pDXVAVPS->GetVideoProcessorSubStreamFormats(
guid, &g_VideoDesc, VIDEO_RENDER_TARGET_FORMAT, &count, &formats);
if (FAILED(hr))
{
DBGMSG((L"GetVideoProcessorSubStreamFormats failed: 0x%x.\n", hr));
return FALSE;
}
for (i = 0; i < count; i++)
{
if (formats[i] == VIDEO_SUB_FORMAT)
{
break;
}
}
CoTaskMemFree(formats);
if (i >= count)
{
DBGMSG((L"The device does not support the substream format.\n"));
return FALSE;
}
O método retorna uma matriz de valores D3DFORMAT. Os formatos típicos de subfluxo são AYUV e AI44.
Consultar as funcionalidades do dispositivo
Para obter os recursos de um dispositivo específico, passe o GUID do dispositivo, a estrutura de formato e um formato de destino de renderização para o método IDirectXVideoProcessorService::GetVideoProcessorCaps. O método preenche uma estrutura DXVA2_VideoProcessorCaps com os recursos do dispositivo.
// Query video processor capabilities.
hr = g_pDXVAVPS->GetVideoProcessorCaps(
guid, &g_VideoDesc, VIDEO_RENDER_TARGET_FORMAT, &g_VPCaps);
if (FAILED(hr))
{
DBGMSG((L"GetVideoProcessorCaps failed: 0x%x.\n", hr));
return FALSE;
}
Criar o dispositivo
Para criar o dispositivo de processamento de vídeo, chame IDirectXVideoProcessorService::CreateVideoProcessor. A entrada para esse método é o GUID do dispositivo, a descrição do formato, o formato de destino de renderização e o número máximo de subfluxos que você planeja misturar. O método retorna um ponteiro para a interface IDirectXVideoProcessor, que representa o dispositivo de processamento de vídeo.
// Finally create a video processor device.
hr = g_pDXVAVPS->CreateVideoProcessor(
guid,
&g_VideoDesc,
VIDEO_RENDER_TARGET_FORMAT,
SUB_STREAM_COUNT,
&g_pDXVAVPD
);
Transferência de bits do processo de vídeo
A principal operação de processamento de vídeo é a transferência de bits do processamento de vídeo. (Uma transferência de bits é qualquer operação que combina dois ou mais bitmaps em um único bitmap. Uma transferência de bits de processamento de vídeo combina imagens de entrada para criar um quadro de saída.) Para executar uma transferência de bits de processamento de vídeo, chame IDirectXVideoProcessor::VideoProcessBlt. Esse método passa um conjunto de amostras de vídeo para o dispositivo de processamento de vídeo. Em resposta, o dispositivo de processamento de vídeo processa as imagens de entrada e gera um quadro de saída. O processamento pode incluir desentrelaçamento, conversão de espaço de cores e mistura de subfluxo. A saída é gravada em uma superfície de destino fornecida pelo chamador.
O método VideoProcessBlt usa os seguintes parâmetros:
- O pRT aponta para uma superfície de destino de renderização IDirect3DSurface9 que receberá o quadro de vídeo processado.
- O pBltParams aponta para uma estrutura DXVA2_VideoProcessBltParams que especifica os parâmetros para a transferência de bits.
- O pSamples é o endereço de uma matriz de estruturas DXVA2_VideoSample. Essas estruturas contêm as amostras de entrada para a transferência de bits.
- O NumSamples fornece o tamanho da matriz pSamples.
- O parâmetro Reserved é reservado e deve ser definido como NULL.
Na matriz pSamples, o chamador deve fornecer as seguintes amostras de entrada:
- A imagem atual do fluxo de vídeo primário.
- Imagens de referência para frente e para trás, se exigido pelo algoritmo de desentrelaçamento.
- Zero ou mais imagens de subfluxo, até um máximo de 15 subfluxos.
O driver espera que essa matriz esteja em uma ordem específica, conforme descrito em Ordem de amostra de entrada.
Parâmetros de transferência de bits
A estrutura DXVA2_VideoProcessBltParams contém parâmetros gerais para a transferência de bits. Os parâmetros mais importantes são armazenados nos seguintes membros da estrutura:
O TargetFrame é o tempo de apresentação do quadro de saída. Para conteúdo progressivo, esse tempo deve ser igual à hora de início do quadro atual do fluxo de vídeo primário. Esse tempo é especificado no membro Start da estrutura DXVA2_VideoSample para essa amostra de entrada.
Para conteúdo entrelaçado, um quadro com dois campos intercalados produz dois quadros de saída desentrelaçados. No primeiro quadro de saída, o tempo de apresentação deve ser igual à hora de início da imagem atual no fluxo de vídeo primário, assim como o conteúdo progressivo. No segundo quadro de saída, a hora de início deve ser igual ao ponto médio entre a hora de início da imagem atual no fluxo de vídeo primário e a hora de início da próxima imagem no fluxo. Por exemplo, se o vídeo de entrada for de 25 quadros por segundo (50 campos por segundo), os quadros de saída terão os carimbos de data/hora mostrados na tabela a seguir. Os carimbos de tempo são mostrados em unidades de 100 nanossegundos.
Imagem de entrada TargetFrame (1) TargetFrame (2) 0 0 200000 400000 0 600000 800.000 800.000 1.000.000 1200000 1200000 1400000 Se o conteúdo entrelaçado consistir em campos únicos em vez de campos intercalados, os tempos de saída sempre corresponderão aos tempos de entrada, como acontece com o conteúdo progressivo.
TargetRect define uma região retangular dentro da superfície de destino. A transferência de bits gravará a saída nessa região. Especificamente, cada pixel dentro do TargetRect será modificado e nenhum pixel fora do TargetRect será modificado. O retângulo alvo define o retângulo delimitador para todos os fluxos de vídeo de entrada. O posicionamento de fluxos individuais dentro desse retângulo é controlado através do parâmetro pSamples de IDirectXVideoProcessor::VideoProcessBlt.
BackgroundColor fornece a cor da tela de fundo onde nenhuma imagem de vídeo aparece. Por exemplo, quando uma imagem de vídeo 16 x 9 é exibida dentro de uma área 4 x 3 (letterboxing), as regiões de letterbox são exibidas com a cor da tela de fundo. A cor da tela de fundo se aplica somente dentro do retângulo alvo (TargetRect). Qualquer pixel fora do TargetRect não será modificado.
DestFormat descreve o espaço de cores para o vídeo de saída. Por exemplo, se a cor ITU-R BT.709 ou BT.601 é usada. Essas informações podem afetar como a imagem é exibida. Para obter mais informações, consulte Informações de cor estendida.
Outros parâmetros são descritos na página de referência da estrutura DXVA2_VideoProcessBltParams.
Amostras de entrada
O parâmetro pSamples de IDirectXVideoProcessor::VideoProcessBlt aponta para uma matriz de estruturas DXVA2_VideoSample. Cada uma dessas estruturas contém informações sobre uma amostra de entrada e um ponteiro para a superfície do Direct3D que contém a amostra. Cada amostra é uma das seguintes:
- A imagem atual do fluxo primário.
- Uma imagem de referência para frente ou para trás do fluxo primário, usada para desentrelaçamento.
- Uma imagem de subfluxo.
A ordem exata em que as amostras devem aparecer na matriz é descrita posteriormente, na seção Ordem da amostra de entrada.
Até 15 imagens de subfluxo podem ser fornecidas, embora a maioria dos aplicativos de vídeo precise de apenas um subfluxo, no máximo. O número de subfluxos pode mudar com cada chamada para VideoProcessBlt. As imagens de subfluxo são indicadas definindo o membro SampleFormat.SampleFormat da estrutura DXVA2_VideoSample igual a DXVA2_SampleSubStream. Para o fluxo de vídeo primário, esse membro descreve o entrelaçamento do vídeo de entrada. Para obter mais informações, consulte a enumeração DXVA2_SampleFormat.
Para o fluxo de vídeo primário, os membros Start e End da estrutura DXVA2_VideoSample fornecem as horas de início e término da amostra de entrada. Para imagens de subfluxo, defina esses valores como zero, pois o tempo de apresentação é sempre calculado a partir do fluxo primário. O aplicativo é responsável por rastrear quando cada imagem de subfluxo deve ser apresentada e enviá-la ao VideoProcessBlt no momento apropriado.
Dois retângulos definem como o vídeo de origem é posicionado para cada fluxo:
- O membro SrcRect da estrutura DXVA2_VideoSample especifica o retângulo de origem, uma região retangular da imagem de origem que aparecerá no quadro de saída composto. Para cortar a imagem, defina-o com um valor menor do que o tamanho do quadro. Caso contrário, defina-o igual ao tamanho do quadro.
- O membro DstRect da mesma estrutura especifica o retângulo de destino, uma região retangular da superfície de destino onde o quadro de vídeo aparecerá.
O driver transfere bits de pixels do retângulo de origem para o retângulo de destino. Os dois retângulos podem ter tamanhos ou taxas de proporção diferentes. O driver dimensionará a imagem conforme necessário. Além disso, cada fluxo de entrada pode usar um fator de dimensionamento diferente. Na verdade, o dimensionamento pode ser necessário para produzir a taxa de proporção correta no quadro de saída. O driver não leva em conta a taxa de proporção de pixels da origem, portanto, se a imagem de origem usar pixels não quadrados, cabe ao aplicativo calcular o retângulo de destino correto.
Os formatos preferidos de subfluxo são AYUV e AI44. Este último é um formato paletizado com 16 cores. As entradas da paleta são especificadas no membro Pal da estrutura DXVA2_VideoSample. (Se o formato de vídeo de origem for originalmente expresso como um tipo de mídia do Media Foundation, as entradas de paleta serão armazenadas no atributo MF_MT_PALETTE.) Para formatos não paletizados, coloque essa matriz como zero.
Composição da imagem
Cada operação de transferência de bits é definida pelos seguintes três retângulos:
- O retângulo alvo (TargetRect) define a região dentro da superfície de destino onde a saída aparecerá. A imagem de saída é recortada para esse retângulo.
- O retângulo de destino para cada fluxo (DstRect) define onde o fluxo de entrada aparece na imagem composta.
- O retângulo de origem para cada fluxo (SrcRect) define qual parte da imagem de origem aparece.
Os retângulos alvo e de destino são especificados em relação à superfície de destino. O retângulo de origem é especificado em relação à imagem de origem. Todos os retângulos são especificados em pixels.
O dispositivo de processamento de vídeo combina com alfa as imagens de entrada, usando qualquer uma das seguintes fontes de dados alfa:
- Dados alfa por pixel de subfluxos.
- Um valor alfa planar para cada fluxo de vídeo, especificado no membro PlanarAlpha da estrutura DXVA2_VideoSample.
- O valor alfa planar da imagem composta, especificado no membro Alpha da estrutura DXVA2_VideoProcessBltParams. Esse valor é usado para misturar toda a imagem composta com a cor da tela de fundo.
Esta seção fornece uma série de exemplos que mostram como o dispositivo de processamento de vídeo cria a imagem de saída.
Exemplo 1: letterboxing
Este exemplo mostra como fazer letterbox na imagem de origem, definindo o retângulo de destino como menor que o retângulo alvo. O fluxo de vídeo primário neste exemplo é uma imagem de 720 × 480 e deve ser exibido em uma taxa de proporção de 16:9. A superfície de destino é de 640 × 480 pixels (taxa de proporção 4:3). Para obter a taxa de proporção correta, o retângulo de destino deve ser 640 × 360. Para simplificar, este exemplo não inclui um subfluxo. O diagrama a seguir mostra os retângulos de origem e de destino.
O diagrama anterior mostra os seguintes retângulos:
Retângulo alvo: { 0, 0, 640, 480 }
Vídeo primário:
- Retângulo de origem: { 0, 0, 720, 480 }
- Retângulo de destino: { 0, 60, 640, 420 }
O driver desentrelaçará o vídeo, reduzirá o quadro desentrelaçado para 640 × 360 e fará a transferência de bits no retângulo de destino. O retângulo alvo é maior do que o retângulo de destino, portanto, o driver usará a cor da tela de fundo para preencher as barras horizontais acima e abaixo do quadro. A cor da tela de fundo é especificada na estrutura DXVA2_VideoProcessBltParams.
Exemplo 2: esticar imagens de subfluxo
As imagens de subfluxo podem se estender além da imagem de vídeo primário. No vídeo de DVD, por exemplo, o fluxo de vídeo primário pode ter uma taxa de proporção de 4:3, enquanto o subfluxo é de 16:9. Neste exemplo, ambos os fluxos de vídeo têm as mesmas dimensões de origem (720 × 480), mas o subfluxo deve ser mostrado em uma taxa de proporção de 16:9. Para atingir essa taxa de proporção, a imagem de subfluxo é esticada horizontalmente. Os retângulos de origem e de destino são mostrados no diagrama a seguir.
O diagrama anterior mostra os seguintes retângulos:
Retângulo alvo: { 0, 0, 854, 480 }
Vídeo primário:
- Retângulo de origem: { 0, 0, 720, 480 }
- Retângulo de destino: { 0, 107, 474, 480 }
Subfluxo:
- Retângulo de origem: { 0, 0, 720, 480 }
- Retângulo de destino: { 0, 0, 854, 480 }
Esses valores preservam a altura da imagem e dimensionam ambas as imagens horizontalmente. Nas regiões em que ambas as imagens aparecem, elas são combinadas com alfa. Onde a imagem do subfluxo se estende além do vídeo principal, o subfluxo é combinado com alfa com a cor da tela de fundo. Essa combinação com alfa explica as cores alteradas no lado direito do diagrama.
Exemplo 3: alturas de fluxo incompatíveis
No exemplo anterior, o subfluxo e o fluxo primário têm a mesma altura. Os fluxos também podem ter alturas incompatíveis, como mostrado neste exemplo. As áreas dentro do retângulo alvo em que nenhum vídeo aparece são desenhadas usando a cor da tela de fundo; preto neste exemplo. Os retângulos de origem e de destino são mostrados no diagrama a seguir.
O diagrama anterior mostra os seguintes retângulos:
- Retângulo alvo: { 0, 0, 150, 85 }
- Vídeo primário:
- Retângulo de origem: { 0, 0, 150, 50 }
- Retângulo de destino: { 0, 17, 150, 67 }
- Subfluxo:
- Retângulo de origem: { 0, 0, 100, 85 }
- Retângulo de destino: { 25, 0, 125, 85 }
Exemplo 4: retângulo alvo menor que a superfície de destino
Este exemplo mostra um caso em que o retângulo alvo é menor que a superfície de destino.
O diagrama anterior mostra os seguintes retângulos:
- Superfície de destino: { 0, 0, 300, 200 }
- Retângulo alvo: { 0, 0, 150, 85 }
- Vídeo primário:
- Retângulo de origem: { 0, 0, 150, 50 }
- Retângulo de destino: { 0, 17, 150, 67 }
- Subfluxo:
- Retângulo de origem: { 0, 0, 100, 85 }
- Retângulo de destino: { 25, 0, 125, 85 }
Os pixels fora do retângulo alvo não são modificados, portanto, a cor da tela de fundo aparece apenas dentro do retângulo de destino. A área pontilhada indica partes da superfície de destino que não são afetadas pela transferência de bits.
Exemplo 5: retângulos de origem
Se você especificar um retângulo de origem menor que a imagem de origem, o driver irá transferir os bits apenas dessa parte da imagem. Neste exemplo, os retângulos de origem especificam o quadrante inferior direito do fluxo de vídeo primário e o quadrante inferior esquerdo do subfluxo (indicado por marcas de hash no diagrama). Os retângulos de destino são dos mesmos tamanhos que os retângulos de origem, portanto, o vídeo não é esticado. Os retângulos de origem e de destino são mostrados no diagrama a seguir.
O diagrama anterior mostra os seguintes retângulos:
- Retângulo alvo: { 0, 0, 720, 576 }
- Vídeo primário:
- Tamanho da superfície de origem: { 0, 0, 720, 480 }
- Retângulo de origem: { 360, 240, 720, 480 }
- Retângulo de destino: { 0, 0, 360, 240 }
- Subfluxo:
- Tamanho da superfície de origem: { 0, 0, 640, 576 }
- Retângulo de origem: { 0, 288, 320, 576 }
- Retângulo de destino: { 400, 0, 720, 288 }
Exemplo 6: retângulos de destino com interseção
Este exemplo é semelhante ao anterior, mas os retângulos de destino se cruzam. As dimensões da superfície são as mesmas do exemplo anterior, mas os retângulos de origem e destino não são. Novamente, o vídeo é cortado, mas não esticado. Os retângulos de origem e de destino são mostrados no diagrama a seguir.
O diagrama anterior mostra os seguintes retângulos:
- Retângulo alvo: { 0, 0, 720, 576 }
- Vídeo primário:
- Tamanho da superfície de origem: { 0, 0, 720, 480 }
- Retângulo de origem: { 260, 92, 720, 480 }
- Retângulo de destino: { 0, 0, 460, 388 }
- Subfluxo:
- Tamanho da superfície de origem: { 0, 0, 640, 576 }
- Retângulo de origem: { 0, 0, 460, 388 }
- Retângulo de destino: { 260, 188, 720, 576 }
Exemplo 7: alongar e cortar vídeo
Neste exemplo, o vídeo é esticado e cortado. Uma região de 180 × 120 de cada fluxo é esticada para cobrir uma área de 360 × 240 no retângulo de destino.
O diagrama anterior mostra os seguintes retângulos:
- Retângulo alvo: { 0, 0, 720, 480 }
- Vídeo primário:
- Tamanho da superfície de origem: { 0, 0, 360, 240 }
- Retângulo de origem: { 180, 120, 360, 240 }
- Retângulo de destino: { 0, 0, 360, 240 }
- Subfluxo:
- Tamanho da superfície de origem: { 0, 0, 360, 240 }
- Retângulo de origem: { 0, 0, 180, 120 }
- Retângulo de destino: { 360, 240, 720, 480 }
Ordem da amostra de entrada
O parâmetro pSamples do método VideoProcessBlt é um ponteiro para uma matriz de amostras de entrada. As amostras do fluxo de vídeo primário aparecem primeiro, seguidas pelas imagens de subfluxo em ordem de empilhamento. As amostras devem ser colocadas na matriz na seguinte ordem:
- As amostras do fluxo de vídeo primário aparecem primeiro na matriz, em ordem temporal. Dependendo do modo de desentrelaçamento, o driver pode exigir uma ou mais amostras de referência do fluxo de vídeo primário. Os membros NumForwardRefSamples e NumBackwardRefSamples da estrutura DXVA2_VideoProcessorCaps especificam quantas amostras de referência para frente e para trás são necessárias. O chamador deve fornecer essas amostras de referência, mesmo que o conteúdo do vídeo seja progressivo e não exija desentrelaçamento. (Isso pode ocorrer quando quadros progressivos são dados a um dispositivo de desentrelaçamento, por exemplo, quando a fonte contém uma mistura de quadros entrelaçados e progressivos.)
- Após as amostras para o fluxo de vídeo primário, a matriz pode conter até 15 amostras de subfluxo, organizadas em ordem de empilhamento, de baixo para cima. Os subfluxos são sempre progressivos e não requerem imagens de referência.
A qualquer momento, o fluxo de vídeo primário pode alternar entre conteúdo entrelaçado e progressivo, e o número de subfluxos pode mudar.
O membro SampleFormat.SampleFormat da estrutura DXVA2_VideoSample indica o tipo de imagem. Para imagens de subfluxo, defina esse valor como DXVA2_SampleSubStream. Para imagens progressivas, o valor é DXVA2_SampleProgressiveFrame. Para imagens entrelaçadas, o valor depende do layout do campo.
Se o driver exigir amostras de referência para frente e para trás, o número total de amostras pode não estar disponível no início da sequência de vídeo. Nesse caso, inclua entradas para eles na matriz pSamples, mas marque as amostras ausentes como tendo o tipo DXVA2_SampleUnknown.
Os membros Start e End da estrutura DXVA2_VideoSample fornecem a localização temporal de cada amostra. Esses valores são usados apenas para amostras do fluxo de vídeo primário. Para imagens de subfluxo, defina ambos os membros como zero.
Os exemplos a seguir podem ajudar a esclarecer esses requisitos.
Exemplo 1
O caso mais simples ocorre quando não há subfluxos e o algoritmo de desentrelaçamento não requer amostras de referência (NumForwardRefSamples e NumBackwardRefSamples ambos são zero). O desentrelaçamento bob é um exemplo desse algoritmo. Nesse caso, a matriz pSamples deve conter uma única superfície de entrada, conforme mostrado na tabela a seguir.
Índice | Tipo de superfície | Localização temporal |
---|---|---|
pSamples[0] | Imagem entrelaçada. | T |
O valor de tempo T é presumido como a hora de início do quadro de vídeo atual.
Exemplo 2
Neste exemplo, o aplicativo mistura dois subfluxos com o fluxo primário. O algoritmo de desentrelaçamento não requer amostras de referência. A tabela a seguir mostra como essas amostras são organizadas na matriz pSamples.
Índice | Tipo de superfície | Localização temporal | Ordem z |
---|---|---|---|
pSamples[0] | Imagem entrelaçada | T | 0 |
pSamples[1] | Subfluxo | 0 | 1 |
pSamples[2] | Subfluxo | 0 | 2 |
Exemplo 3
Agora suponha que o algoritmo de desentrelaçamento requer uma amostra de referência para trás e uma amostra de referência para frente. Além disso, duas imagens de substream são fornecidas, para um total de cinco superfícies. A ordem correta é mostrada na tabela a seguir.
Índice | Tipo de superfície | Localização temporal | Ordem z |
---|---|---|---|
pSamples[0] | Imagem entrelaçada (referência) | T −1 | Não aplicável |
pSamples[1] | Imagem entrelaçada | T | 0 |
pSamples[2] | Imagem entrelaçada (referência) | T +1 | Não aplicável |
pSamples[3] | Subfluxo | 0 | 1 |
pSamples[4] | Subfluxo | 0 | 2 |
A hora T –1 é a hora de início do quadro antes do quadro atual, e T +1 é a hora de início do quadro seguinte.
Se o fluxo de vídeo alternar para conteúdo progressivo, usando o mesmo modo de desentrelaçamento, o aplicativo deverá fornecer o mesmo número de amostras, conforme mostrado na tabela a seguir.
Índice | Tipo de superfície | Localização temporal | Ordem z |
---|---|---|---|
pSamples[0] | Imagem progressiva (referência) | T −1 | Não aplicável |
pSamples[1] | Imagem progressiva | T | 0 |
pSamples[2] | Imagem progressiva (referência) | T +1 | Não aplicável |
pSamples[3] | Subfluxo | 0 | 1 |
pSamples[4] | Subfluxo | 0 | 2 |
Exemplo 4
No início de uma sequência de vídeo, amostras de referência para frente e para trás podem não estar disponíveis. Quando isso acontece, as entradas para as amostras ausentes são incluídas na matriz pSamples, com o tipo de amostra DXVA2_SampleUnknown.
Supondo que o modo de desentrelaçamento precise de uma amostra de referência para frente e outra para trás, as três primeiras chamadas para VideoProcessBlt têm as sequências de entradas mostradas nas três tabelas a seguir.
Índice | Tipo de superfície | Localização temporal |
---|---|---|
pSamples[0] | Desconhecido | 0 |
pSamples[1] | Desconhecido | 0 |
pSamples[2] | Imagem entrelaçada (referência) | T +1 |
Índice | Tipo de superfície | Localização temporal |
---|---|---|
pSamples[0] | Desconhecido | 0 |
pSamples[1] | Imagem entrelaçada | T |
pSamples[2] | Imagem entrelaçada (referência) | T +1 |
Índice | Tipo de superfície | Localização temporal |
---|---|---|
pSamples[0] | Imagem entrelaçada | T −1 |
pSamples[1] | Imagem entrelaçada | T |
pSamples[2] | Imagem entrelaçada (referência) | T +1 |
Tópicos relacionados