Compartilhar via


Processamento de vídeo DXVA

O processamento de vídeo DXVA encapsula as funções do hardware gráfico dedicado ao processamento de imagens de vídeo descompactadas. Os serviços de processamento de vídeo incluem desinterlação e combinação de vídeo.

Este tópico contém as seguintes seções:

Visão geral

O hardware gráfico pode usar a GPU (unidade de processamento de elementos gráficos) 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:

  • Telecine desinterlacing e inverso
  • Misturando substreams de vídeo na imagem principal do vídeo
  • Ajuste de cor (ProcAmp) e filtragem de imagem
  • Dimensionamento de imagem
  • Conversão de espaço em cores
  • Mistura alfa

O diagrama a seguir mostra os estágios no pipeline de processamento de vídeo. O diagrama não deve 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 executadas 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 ter suporte do driver.

diagrama mostrando os estágios do processamento de vídeo dxva.

A entrada para o pipeline de processamento de vídeo sempre inclui um fluxo de vídeo primário , que contém os dados principais da imagem. O fluxo de vídeo primário determina a taxa de quadros para o 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. 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 substreams de vídeo. Um substream contém dados auxiliares de imagem, como legendas fechadas ou subpicturas de DVD. Essas imagens são exibidas no fluxo de vídeo principal e geralmente não devem ser mostradas por si mesmas. As imagens de substream podem conter dados alfa por pixel e são sempre quadros progressivos. O dispositivo de processamento de vídeo alfa combina as imagens de substream com o quadro desinterlaceado atual do fluxo de vídeo primário.

No restante deste tópico, a imagem do termo é usada 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 desinterlaceado.

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 seguintes GUIDs são predefinidos:

  • DXVA2_VideoProcBobDevice. Este dispositivo executa a desinterlação bob.
  • DXVA2_VideoProcProgressiveDevice. Esse dispositivo será 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 desinterlacização é necessária para os quadros entrelaçados.)

Cada driver gráfico que dá suporte ao 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 proprietário de desinterlacing que produz uma saída de melhor qualidade do que a desinterlacagem bob. Alguns algoritmos de desinterlação podem exigir imagens de referência para frente ou para trás do fluxo primário. Nesse caso, 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á uma breve estrutura de tópicos das etapas, que são explicadas com mais detalhes no restante desta seção:

  1. Obtenha um ponteiro para a interface IDirectXVideoProcessorService .
  2. 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 dão suporte ao formato de vídeo. Os dispositivos são identificados pelo GUID.
  3. Para um dispositivo específico, obtenha uma lista de formatos de destino de renderização compatíveis com o dispositivo. Os formatos são retornados como uma lista de valores D3DFORMAT . Se você planeja misturar substreams, obtenha uma lista dos formatos de substream com suporte também.
  4. Consulte os recursos de cada dispositivo.
  5. Crie o dispositivo 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 preferencial e ver se ele é bem-sucedido. Um formato comum, como D3DFMT_X8R8G8B8, provavelmente terá êxito.

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:

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 seguinte código:

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, uma 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 consiste inteiramente em 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 deste exemplo é obtido do exemplo 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 formatos de Render-Target

Para obter a lista de formatos de destino de renderização compatíveis com o dispositivo, passe o GUID do dispositivo e a estrutura de DXVA2_VideoDesc para o método IDirectXVideoProcessorService::GetVideoProcessorRenderTargets , conforme mostrado no seguinte código:

    // 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, em que 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 substreams pode variar dependendo do formato de destino de renderização e do formato de entrada. Para obter a lista de formatos de substream, 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;
    }

Esse método retorna outra matriz de valores D3DFORMAT . Os formatos de substream típicos são AYUV e AI44.

Consultar os recursos 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 de 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 substreams 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
        );

Processo de vídeo Blit

A operação principal de processamento de vídeo é o blit de processamento de vídeo. (Um blit é qualquer operação que combina dois ou mais bitmaps em um único bitmap. Um blit de processamento de vídeo combina imagens de entrada para criar um quadro de saída.) Para executar um blit de processamento de vídeo, chame IDirectXVideoProcessor::VideoProcessBlt. Esse método passa um conjunto de exemplos 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 desinterlacing, conversão de espaço em cores e mistura de substream. 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.
  • pBltParams aponta para uma estrutura de DXVA2_VideoProcessBltParams que especifica os parâmetros para o blit.
  • pSamples é o endereço de uma matriz de estruturas DXVA2_VideoSample . Essas estruturas contêm os exemplos de entrada para o blit.
  • NumSamples fornece o tamanho da matriz pSamples .
  • O parâmetro Reservado é reservado e deve ser definido como NULL.

Na matriz pSamples , o chamador deve fornecer os seguintes exemplos de entrada:

  • A imagem atual do fluxo de vídeo primário.
  • Imagens de referência para frente e para trás, se necessário pelo algoritmo de desinterlacing.
  • Zero ou mais imagens substream, até um máximo de 15 substreams.

O driver espera que essa matriz esteja em uma ordem específica, conforme descrito na ordem de exemplo de entrada.

Parâmetros Blit

A estrutura DXVA2_VideoProcessBltParams contém parâmetros gerais para o blit. Os parâmetros mais importantes são armazenados nos seguintes membros da estrutura:

  • TargetFrame é a hora da apresentação do quadro de saída. Para conteúdo progressivo, essa hora deve ser igual à hora de início do quadro atual do fluxo de vídeo primário. Essa hora é especificada no membro Inicial da estrutura de DXVA2_VideoSample para esse exemplo de entrada.

    Para conteúdo entrelaçado, um quadro com dois campos intercalados produz dois quadros de saída desinterlaceados. No primeiro quadro de saída, a hora da 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 data/hora 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 1000000
    1200000 1200000 1400000

     

    Se o conteúdo entrelaçado consiste em campos únicos em vez de campos intercalados, os tempos de saída sempre correspondem aos tempos de entrada, como com o conteúdo progressivo.

  • TargetRect define uma região retangular dentro da superfície de destino. O blit 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 de destino define o retângulo delimitador para todos os fluxos de vídeo de entrada. O posicionamento de fluxos individuais dentro desse retângulo é controlado por meio do parâmetro pSamples de IDirectXVideoProcessor::VideoProcessBlt.

  • BackgroundColor fornece a cor da tela de fundo onde não aparece nenhuma imagem de vídeo. Por exemplo, quando uma imagem de vídeo 16 x 9 é exibida em uma área 4 x 3 (caixa de correio), as regiões em caixa de correio são exibidas com a cor da tela de fundo. A cor da tela de fundo se aplica somente no retângulo de destino (TargetRect). Os pixels fora do TargetRect não são modificados.

  • DestFormat descreve o espaço de cores para o vídeo de saída, por exemplo, se ITU-R cor BT.709 ou BT.601 é usada. Essas informações podem afetar a forma como a imagem é exibida. Para obter mais informações, consulte Informações de Cor Estendidas.

Outros parâmetros são descritos na página de referência da estrutura de DXVA2_VideoProcessBltParams .

Exemplos de entrada

O parâmetro pSamples de IDirectXVideoProcessor::VideoProcessBlt aponta para uma matriz de estruturas de DXVA2_VideoSample . Cada uma dessas estruturas contém informações sobre um exemplo de entrada e um ponteiro para a superfície Direct3D que contém o exemplo. Cada exemplo é um dos 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 desinterlacing.
  • Uma imagem de substream.

A ordem exata na qual os exemplos devem aparecer na matriz é descrita posteriormente, na seção Ordem de Exemplo de Entrada.

Até 15 imagens de substream podem ser fornecidas, embora a maioria dos aplicativos de vídeo precise apenas de um substream, no máximo. O número de substreams pode ser alterado com cada chamada para VideoProcessBlt. As imagens de substream 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 a interlacagem do vídeo de entrada. Para obter mais informações, consulte DXVA2_SampleFormat enumeração.

Para o fluxo de vídeo primário, os membros Start e End da estrutura DXVA2_VideoSample fornecem os horários de início e término da amostra de entrada. Para imagens de substream, defina esses valores como zero, pois o tempo de apresentação é sempre calculado do fluxo primário. O aplicativo é responsável por acompanhar quando cada imagem de substream 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-a como um valor menor 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 em que o quadro de vídeo será exibido.

O driver corta pixels do retângulo de origem para o retângulo de destino. Os dois retângulos podem ter tamanhos ou proporções 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 pixel da origem, portanto, se a imagem de origem usa pixels não quadrados, cabe ao aplicativo calcular o retângulo de destino correto.

Os formatos de substream preferenciais são AYUV e AI44. Este último é um formato paletizado com 16 cores. As entradas de 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 palletizados, desmarque essa matriz como zero.

Composição de imagem

Cada operação blit é definida pelos três retângulos a seguir:

  • O retângulo de destino (TargetRect) define a região dentro da superfície de destino em que a saída será exibida. A imagem de saída é recortada nesse 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 é exibida.

Os retângulos de destino e 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.

diagrama mostrando retângulos de origem, destino e destino

O dispositivo de processamento de vídeo alfa combina as imagens de entrada, usando qualquer uma das seguintes fontes de dados alfa:

  • Dados alfa por pixel de substreams.
  • 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 Alfa 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: Caixa de correio

Este exemplo mostra como fazer a caixa de correio da imagem de origem definindo o retângulo de destino como menor que o retângulo de destino. O fluxo de vídeo principal neste exemplo é uma imagem 720 × 480 e deve ser exibido em uma taxa de proporção de 16:9. A superfície de destino é 640 × 480 pixels (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 substream. O diagrama a seguir mostra os retângulos de origem e de destino.

diagrama mostrando o letterboxing.

O diagrama anterior mostra os seguintes retângulos:

  • Retângulo de destino: { 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 desinterlaceará o vídeo, reduzirá o quadro desinterlaceado para 640 × 360 e cortará o quadro no retângulo de destino. O retângulo de destino é maior 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: Alongamento de imagens substream

As imagens de substream podem se estender além da imagem de vídeo principal. 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 substream é 16:9. Neste exemplo, ambos os fluxos de vídeo têm as mesmas dimensões de origem (720 × 480), mas o substream destina-se a ser mostrado em uma taxa de proporção de 16:9. Para obter essa taxa de proporção, a imagem de substream é ampliada horizontalmente. Os retângulos de origem e de destino são mostrados no diagrama a seguir.

diagrama mostrando o alongamento da imagem de substream.

O diagrama anterior mostra os seguintes retângulos:

  • Retângulo de destino: { 0, 0, 854, 480 }

  • Vídeo primário:

    • Retângulo de origem: { 0, 0, 720, 480 }
    • Retângulo de destino: { 0, 107, 474, 480 }
  • Substream:

    • 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 misturadas alfa. Onde a imagem de substream se estende além do vídeo primário, o substream é combinado alfa com a cor da tela de fundo. Essa mistura alfa explica as cores alteradas no lado direito do diagrama.

Exemplo 3: alturas de fluxo incompatíveis

No exemplo anterior, o substream e o fluxo primário têm a mesma altura. Os fluxos também podem ter alturas incompatíveis, conforme mostrado neste exemplo. As áreas dentro do retângulo de destino em que nenhum vídeo é exibido 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.

diagrama mostrando alturas de fluxo incompatíveis,

O diagrama anterior mostra os seguintes retângulos:

  • Retângulo de destino: { 0, 0, 150, 85 }
  • Vídeo primário:
    • Retângulo de origem: { 0, 0, 150, 50 }
    • Retângulo de destino: { 0, 17, 150, 67 }
  • Substream:
    • Retângulo de origem: { 0, 0, 100, 85 }
    • Retângulo de destino: { 25, 0, 125, 85 }

Exemplo 4: Retângulo de destino menor que a superfície de destino

Este exemplo mostra um caso em que o retângulo de destino é menor que a superfície de destino.

diagrama mostrando um blit para um retângulo de destino.

O diagrama anterior mostra os seguintes retângulos:

  • Superfície de destino: { 0, 0, 300, 200 }
  • Retângulo de destino: { 0, 0, 150, 85 }
  • Vídeo primário:
    • Retângulo de origem: { 0, 0, 150, 50 }
    • Retângulo de destino: { 0, 17, 150, 67 }
  • Substream:
    • Retângulo de origem: { 0, 0, 100, 85 }
    • Retângulo de destino: { 25, 0, 125, 85 }

Pixels fora do retângulo de destino não são modificados, portanto, a cor da tela de fundo aparece somente dentro do retângulo de destino. A área pontilhada indica partes da superfície de destino que não são afetadas pelo blit.

Exemplo 5: Retângulos de origem

Se você especificar um retângulo de origem menor que a imagem de origem, o driver será cortado apenas nessa 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 substream (indicado por marcas de hash no diagrama). Os retângulos de destino têm os mesmos tamanhos que os retângulos de origem, portanto, o vídeo não é estendido. Os retângulos de origem e de destino são mostrados no diagrama a seguir.

diagrama mostrando um blit de dois retângulos de origem.

O diagrama anterior mostra os seguintes retângulos:

  • Retângulo de destino: { 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 }
  • Substream:
    • 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: Interseção de retângulos de destino

Este exemplo é semelhante ao anterior, mas os retângulos de destino se cruzam. As dimensões de 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 estendido. Os retângulos de origem e de destino são mostrados no diagrama a seguir.

diagrama mostrando retângulos de destino interseccionais.

O diagrama anterior mostra os seguintes retângulos:

  • Retângulo de destino: { 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 }
  • Substream:
    • 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: Vídeo de alongamento e corte

Neste exemplo, o vídeo é estendido, bem como cortado. Uma região de 180 × 120 de cada fluxo é estendida para cobrir uma área de 360 × 240 no retângulo de destino.

diagrama mostrando alongamento e corte.

O diagrama anterior mostra os seguintes retângulos:

  • Retângulo de destino: { 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 }
  • Substream:
    • 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 de exemplo de entrada

O parâmetro pSamples do método VideoProcessBlt é um ponteiro para uma matriz de exemplos de entrada. Os exemplos do fluxo de vídeo primário aparecem primeiro, seguidos por imagens de substream na ordem Z. Os exemplos devem ser colocados na matriz na seguinte ordem:

  • Os exemplos do fluxo de vídeo primário aparecem primeiro na matriz, em ordem temporal. Dependendo do modo de desinterlace, o driver pode exigir um ou mais exemplos 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 esses exemplos de referência mesmo que o conteúdo do vídeo seja progressivo e não exija desinterlação. (Isso pode ocorrer quando quadros progressivos são dados a um dispositivo de desinterlação, por exemplo, quando a origem contém uma combinação de quadros entrelaçados e progressivos.)
  • Após os exemplos do fluxo de vídeo primário, a matriz pode conter até 15 amostras de substream, organizadas em ordem Z, de baixo para cima. Os substreams são sempre progressivos e não exigem 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 substreams pode ser alterado.

O membro SampleFormat.SampleFormat da estrutura DXVA2_VideoSample indica o tipo de imagem. Para imagens de substream, 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 exemplos de referência para frente e para trás, o número total de amostras poderá 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 os exemplos ausentes como tendo o tipo DXVA2_SampleUnknown.

Os membros Start e End da estrutura DXVA2_VideoSample fornecem a localização temporal de cada exemplo. Esses valores são usados apenas para exemplos do fluxo de vídeo primário. Para imagens de substream, 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á substreams e o algoritmo de desinterlacing não requer exemplos de referência (NumForwardRefSamples e NumBackwardRefSamples são zero). A desinterlação de Bob é um exemplo de tal 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

 

Supõe-se que o valor de hora T seja a hora de início do quadro de vídeo atual.

Exemplo 2

Neste exemplo, o aplicativo mistura dois substreams com o fluxo primário. O algoritmo de desinterlação não requer exemplos de referência. A tabela a seguir mostra como esses exemplos são organizados na matriz pSamples .

Índice Tipo de superfície Localização temporal Ordem Z
pSamples[0] Imagem entrelaçada T 0
pSamples[1] Substream 0 1
pSamples[2] Substream 0 2

 

Exemplo 3

Agora suponha que o algoritmo de desinterlacing exija um exemplo de referência para trás e um exemplo de referência para frente. Além disso, duas imagens de substream são fornecidas, para um total de cinco superfícies. A ordenação 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] Substream 0 1
pSamples[4] Substream 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 a seguir.

Se o fluxo de vídeo mudar para conteúdo progressivo, usando o mesmo modo de desinterlacagem, o aplicativo deverá fornecer o mesmo número de exemplos, 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] Substream 0 1
pSamples[4] Substream 0 2

 

Exemplo 4

No início de uma sequência de vídeo, os exemplos de referência para frente e para trás podem não estar disponíveis. Quando isso acontece, as entradas para os exemplos ausentes são incluídas na matriz pSamples , com o tipo de exemplo DXVA2_SampleUnknown.

Supondo que o modo de desinterlacagem precise de uma amostra de referência para frente e uma referência para trás, as três primeiras chamadas para VideoProcessBlt teriam 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

 

de Aceleração de Vídeo do DirectX 2.0

Exemplo de DXVA2_VideoProc