Partilhar via


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 mixagem de vídeo.

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

Visão geral

O hardware gráfico pode usar a unidade de processamento gráfico (GPU) 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çamento e telecine inverso
  • Misturando subfluxos de vídeo na imagem de vídeo principal
  • Ajuste de cor (ProcAmp) e filtragem de imagem
  • Dimensionamento de imagem
  • Conversão de espaço de cor
  • Mistura 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. Algumas etapas mostradas aqui, como filtragem de ruído e detalhes, podem não ser suportadas pelo driver.

Diagrama mostrando as etapas 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 de imagem principal. O fluxo de vídeo principal 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 principal. 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 principal e, geralmente, não devem ser mostradas por si mesmas. As imagens de subfluxo podem conter dados alfa por pixel e são sempre quadros progressivos. O dispositivo de processamento de vídeo alfa-mistura as imagens de subfluxo com o quadro desentrelaçado atual do fluxo de vídeo principal.

No restante deste tópico, o termo imagem é usado para os dados de entrada para 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 contém apenas quadros progressivos, sem quadros entrelaçados. (Alguns conteúdos de vídeo contêm uma mistura 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 autor da chamada deve fornecer estas imagens ao condutor na sequência correta, conforme descrito mais adiante nesta secçã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.

Criando 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 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 principal. Use esta descrição para obter uma lista dos dispositivos de processamento de vídeo que suportam o 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 suportados pelo dispositivo. Os formatos são retornados como uma lista de D3DFORMAT valores. Se você planeja misturar subfluxos, obtenha também uma lista dos formatos de subfluxo suportados.
  4. Consulte as capacidades 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 preferido e ver se ele é bem-sucedido. É provável que um formato comum como D3DFMT_X8R8G8B8 seja bem-sucedido.

O restante desta seção descreve essas etapas em detalhes.

Obtenha 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));

n alguns casos, um objeto cria o dispositivo Direct3D e, em seguida, partilha-o com outros objetos através do Gestor 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 de 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 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 para este exemplo é retirado do DXVA2_VideoProc SDK exemplo.

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 do dispositivo retornados por esse método.

Enumerar formatos Render-Target

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 D3DFORMAT valores. 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 motorista.

A lista de formatos disponíveis para os subfluxos pode variar dependendo do formato de renderização-destino e do formato de entrada. Para obter a lista de formatos de subfluxo, passe o GUID do dispositivo, a estrutura do 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 de D3DFORMAT . Os formatos típicos de substream 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 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
        );

Processo de vídeo Blit

A principal operação 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. Este 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 cor 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.
  • pBltParams aponta para uma estrutura DXVA2_VideoProcessBltParams que especifica os parâmetros para o blit.
  • pSamples é o endereço de uma matriz de estruturas DXVA2_VideoSample . Estas estruturas contêm as amostras de entrada para o blit.
  • 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 principal.
  • 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 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 é 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 principal. 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 principal, 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 principal 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
    800000 800000 1000000
    1200000 1200000 1400000

     

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

  • TargetRect define uma região retangular dentro da superfície de destino. O blit gravará a saída para esta 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. A colocação de fluxos individuais dentro desse retângulo é controlada através do parâmetro pSamples de IDirectXVideoProcessor::VideoProcessBlt.

  • BackgroundColor dá a cor do fundo sempre que 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 em caixa de correio são exibidas com a cor de fundo. A cor de fundo aplica-se apenas dentro do retângulo de destino (TargetRect). Quaisquer 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 Extended Color Information.

Outros parâmetros são descritos na página de referência para a 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 um exemplo de entrada e um ponteiro para a superfície Direct3D que contém o exemplo. 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 mais adiante, 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 a 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 principal, este membro descreve o entrelaçamento 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 Início e Fim 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, porque 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 para VideoProcessBlt no momento adequado.

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 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 mescla 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 escala diferente. Na verdade, o dimensionamento pode ser necessário para produzir a proporção correta no quadro de saída. O driver não leva em conta a proporção de pixels da fonte, portanto, se a imagem de origem usa pixels não quadrados, cabe ao aplicativo calcular o retângulo de destino correto.

Os formatos de subfluxo preferidos 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 da paleta serão armazenadas no atributo MF_MT_PALETTE .) Para formatos não paletizados, limpe essa matriz para zero.

Composição da Imagem

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

  • O retângulo de destino (TargetRect) define a região dentro da superfície de destino onde a saída aparecerá. A imagem de saída é cortada para este 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 de destino 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.

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 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 mesclar toda a imagem composta com a cor do plano 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 a 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 de 720 × 480 e deve ser exibido em uma proporção de 16:9. A superfície de destino é de 640 × 480 pixels (proporção 4:3). Para obter a 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 destino.

diagrama mostrando letterboxing.

O diagrama anterior mostra os seguintes retângulos:

  • Retângulo alvo: { 0, 0, 640, 480 }

  • Vídeo principal:

    • Retângulo da fonte: { 0, 0, 720, 480 }
    • Retângulo de destino: { 0, 60, 640, 420 }

O motorista desentrelaçará o vídeo, reduzirá o quadro desentrelaçado para 640 × 360 e colocará o quadro no retângulo de destino. O retângulo alvo é maior do que o retângulo de destino, então o motorista usará a cor de fundo para preencher as barras horizontais acima e abaixo do quadro. A cor de fundo é especificada na estrutura DXVA2_VideoProcessBltParams .

Exemplo 2: Esticando imagens de subfluxo

As imagens de subfluxo podem ir além da imagem de vídeo principal. No vídeo em DVD, por exemplo, o fluxo de vídeo principal pode ter uma 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 destina-se a ser mostrado em uma proporção de 16:9. Para atingir essa proporção, a imagem de subfluxo é esticada horizontalmente. Os retângulos de origem e destino são mostrados no diagrama a seguir.

Diagrama mostrando o alongamento da imagem do subfluxo.

O diagrama anterior mostra os seguintes retângulos:

  • Retângulo alvo: { 0, 0, 854, 480 }

  • Vídeo principal:

    • Retângulo da fonte: { 0, 0, 720, 480 }
    • Retângulo de destino: { 0, 107, 474, 480 }
  • Subfluxo:

    • Retângulo da fonte: { 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 onde ambas as imagens aparecem, elas são misturadas alfa. Onde a imagem do subfluxo se estende além do vídeo principal, o subfluxo é alfa misturado com a cor do plano de fundo. Esta mistura 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 de destino onde nenhum vídeo aparece são desenhadas usando a cor do plano de fundo — preto neste exemplo. Os retângulos de origem e 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 alvo: { 0, 0, 150, 85 }
  • Vídeo principal:
    • 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 de destino menor que a superfície de destino

Este exemplo mostra um caso em que o retângulo de destino é menor do 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 alvo: { 0, 0, 150, 85 }
  • Vídeo principal:
    • 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 de destino não são modificados, portanto, a cor do plano de fundo aparece apenas dentro do retângulo de destino. A área pontilhada indica porções 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 que seja menor do que a imagem de origem, o driver irá blit apenas essa 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, por isso o vídeo não é esticado. Os retângulos de origem e 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 alvo: { 0, 0, 720, 576 }
  • Vídeo principal:
    • Tamanho da superfície da fonte: { 0, 0, 720, 480 }
    • Retângulo da fonte: { 360, 240, 720, 480 }
    • Retângulo de destino: { 0, 0, 360, 240 }
  • Subfluxo:
    • Tamanho da superfície da fonte: { 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 da superfície são as mesmas do exemplo anterior, mas os retângulos de origem e destino não. Mais uma vez, o vídeo é cortado, mas não esticado. Os retângulos de origem e destino são mostrados no diagrama a seguir.

diagrama mostrando retângulos de destino cruzados.

O diagrama anterior mostra os seguintes retângulos:

  • Retângulo alvo: { 0, 0, 720, 576 }
  • Vídeo principal:
    • Tamanho da superfície da fonte: { 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 da fonte: { 0, 0, 640, 576 }
    • Retângulo da fonte: { 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 é esticado e cortado. Uma região de 180 × 120 de cada riacho é esticada 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 alvo: { 0, 0, 720, 480 }
  • Vídeo principal:
    • Tamanho da superfície da fonte: { 0, 0, 360, 240 }
    • Retângulo da fonte: { 180, 120, 360, 240 }
    • Retângulo de destino: { 0, 0, 360, 240 }
  • Subfluxo:
    • Tamanho da superfície da fonte: { 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 por imagens de subfluxo em ordem Z. As amostras devem ser colocadas na matriz na seguinte ordem:

  • As amostras para o 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 Z, 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 principal 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 Início e Fim da estrutura DXVA2_VideoSample dão 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 que se seguem podem ajudar a clarificar estes 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 são zero). O desentrelaçamento de 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
pAmostras[0] Imagem entrelaçada. T

 

O valor de tempo T é assumido como sendo 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
pAmostras[0] Imagem entrelaçada T 0
pAmostras[1] Subfluxo 0 1
pAmostras[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 subfluxo 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
pAmostras[0] Imagem entrelaçada (referência) T −1 Não aplicável
pAmostras[1] Imagem entrelaçada T 0
pAmostras[2] Imagem entrelaçada (referência) T +1 Não aplicável
pAmostras[3] Subfluxo 0 1
pAmostras[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 muda para conteúdo progressivo, usando o mesmo modo de desentrelaçamento, o aplicativo deve fornecer o mesmo número de amostras, conforme mostrado na tabela a seguir.

Índice Tipo de superfície Localização temporal Ordem-Z
pAmostras[0] Imagem progressiva (referência) T −1 Não aplicável
pAmostras[1] Quadro progressivo T 0
pAmostras[2] Imagem progressiva (referência) T +1 Não aplicável
pAmostras[3] Subfluxo 0 1
pAmostras[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 precisa de uma amostra de referência para frente e uma 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
pAmostras[0] Desconhecido 0
pAmostras[1] Desconhecido 0
pAmostras[2] Imagem entrelaçada (referência) T +1

 

Índice Tipo de superfície Localização temporal
pAmostras[0] Desconhecido 0
pAmostras[1] Imagem entrelaçada T
pAmostras[2] Imagem entrelaçada (referência) T +1

 

Índice Tipo de superfície Localização temporal
pAmostras[0] Imagem entrelaçada T −1
pAmostras[1] Imagem entrelaçada T
pAmostras[2] Imagem entrelaçada (referência) T +1

 

Aceleração de vídeo DirectX 2.0

DXVA2_VideoProc Amostra