Definindo preferências de desinterlace
[O recurso associado a esta página, DirectShow, é um recurso herdado. Ele foi substituído por MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo na Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo no Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]
O VMR (Renderizador de Mixagem de Vídeo) dá suporte à desinterlacização acelerada por hardware, o que melhora a qualidade de renderização para vídeos entrelaçados. Os recursos exatos disponíveis dependem do hardware subjacente. O aplicativo pode consultar os recursos de desinterlacização de hardware e definir preferências de desinterlacing por meio da interface IVMRDeinterlaceControl (VMR-7) ou da interface IVMRDeinterlaceControl9 (VMR-9). A desinterlacização é executada por fluxo.
Há uma diferença importante no comportamento de interlação entre a VMR-7 e a VMR-9. Em sistemas em que o hardware gráfico não dá suporte à desinterlacização avançada, o VMR-7 pode voltar à sobreposição de hardware e instruí-lo a usar um desinterlação de estilo BOB. Nesse caso, embora a VMR esteja relatando 30fps, o vídeo está sendo renderizado a 60 lançamentos por segundo.
Exceto no caso da VMR-7 usando a sobreposição de hardware, a desinterlacização é executada pelo mixer da VMR. O mixer usa a DDI (interface de driver de dispositivo) de desinterlacização de DXVA (Aceleração de Vídeo) do DirectX para executar a desinterlacização. Essa DDI não pode ser chamada por aplicativos e os aplicativos não podem substituir a funcionalidade de desinterlacização da VMR. No entanto, um aplicativo pode selecionar o modo de desinterlacing desejado, conforme descrito nesta seção.
Observação
Esta seção descreve os métodos IVMRDeinterlaceControl9 , mas as versões do VMR-7 são quase idênticas.
Para obter os recursos de desinterlacagem de um fluxo de vídeo, faça o seguinte:
- Preencha uma estrutura VMR9VideoDesc com uma descrição do fluxo de vídeo. Detalhes de como preencher essa estrutura são dados posteriormente.
- Passe a estrutura para o método IVMRDeinterlaceControl9::GetNumberOfDeinterlaceModes . Chame o método duas vezes. A primeira chamada retorna o número de modos de desinterlace aos quais o hardware dá suporte para o formato especificado. Aloque uma matriz de GUIDs desse tamanho e chame o método novamente, passando o endereço da matriz. A segunda chamada preenche a matriz com GUIDs. Cada GUID identifica um modo de desinterlacagem.
- Para obter as capacidades de um modo específico, chame o método IVMRDeinterlaceControl9::GetDeinterlaceModeCaps . Passe a mesma estrutura VMR9VideoDesc , juntamente com um dos GUIDs da matriz. O método preenche uma estrutura VMR9DeinterlaceCaps com os recursos de modo.
O código a seguir mostra essas etapas:
VMR9VideoDesc VideoDesc;
DWORD dwNumModes = 0;
// Fill in the VideoDesc structure (not shown).
hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc,
&dwNumModes, NULL);
if (SUCCEEDED(hr) && (dwNumModes != 0))
{
// Allocate an array for the GUIDs that identify the modes.
GUID *pModes = new GUID[dwNumModes];
if (pModes)
{
// Fill the array.
hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc,
&dwNumModes, pModes);
if (SUCCEEDED(hr))
{
// Loop through each item and get the capabilities.
for (int i = 0; i < dwNumModes; i++)
{
VMR9DeinterlaceCaps Caps;
hr = pDeinterlace->GetDeinterlaceModeCaps(pModes + i,
&VideoDesc, &Caps);
if (SUCCEEDED(hr))
{
// Examine the Caps structure.
}
}
}
delete [] pModes;
}
}
Agora, o aplicativo pode definir o modo de desinterlacagem para o fluxo, usando os seguintes métodos:
- O método SetDeinterlaceMode define o modo preferencial. Use GUID_NULL para desativar o desinterlacamento.
- O método SetDeinterlacePrefs especifica o comportamento se o modo solicitado não estiver disponível.
- O método GetDeinterlaceMode retorna o modo preferencial definido.
- O método GetActualDeinterlaceMode retorna o modo real em uso, que pode ser um modo de fallback, se o modo preferencial não estiver disponível.
As páginas de referência do método fornecem mais informações.
Usando a estrutura VMR9VideoDesc
No procedimento fornecido anteriormente, a primeira etapa é preencher uma estrutura VMR9VideoDesc com uma descrição do fluxo de vídeo. Comece obtendo o tipo de mídia do fluxo de vídeo. Você pode fazer isso chamando IPin::ConnectionMediaType no pin de entrada do filtro VMR. Em seguida, confirme se o fluxo de vídeo está entrelaçado. Somente formatos VIDEOINFOHEADER2 podem ser entrelaçados. Se o tipo de formato for FORMAT_VideoInfo, ele deverá ser um quadro progressivo. Se o tipo de formato for FORMAT_VideoInfo2, marcar o campo dwInterlaceFlags para o sinalizador AMINTERLACE_IsInterlaced. A presença desse sinalizador indica que o vídeo está entrelaçado.
Suponha que a variável pBMI seja um ponteiro para a estrutura BITMAPINFOHEADER no bloco de formato. Defina os seguintes valores na estrutura VMR9VideoDesc :
dwSize: defina esse campo como
sizeof(VMR9VideoDesc)
.dwSampleWidth: defina esse campo como
pBMI->biWidth
.dwSampleHeight: defina esse campo como
abs(pBMI->biHeight)
.SampleFormat: este campo descreve as características de entrelaçamento do tipo de mídia. Verifique o campo dwInterlaceFlags na estrutura VIDEOINFOHEADER2 e defina SampleFormat igual ao sinalizador de VMR9_SampleFormat equivalente. Uma função auxiliar para fazer isso é fornecida abaixo.
InputSampleFreq: esse campo fornece a frequência de entrada, que pode ser calculada a partir do campo AvgTimePerFrame na estrutura VIDEOINFOHEADER2 . No caso geral, defina dwNumerator como 10000000 e defina dwDenominator como AvgTimePerFrame. No entanto, você também pode marcar para algumas taxas de quadros conhecidas:
Tempo médio por quadro Taxa de quadros (fps) Numerador Denominador 166833 59.94 (NTSC) 60000 1001 333667 29.97 (NTSC) 30000 1001 417188 23.97 (NTSC) 24.000 1001 200000 50.00 (PAL) 50 1 400000 25.00 (PAL) 25 1 416667 24.00 (Filme) 24 1 OutputFrameFreq: esse campo fornece a frequência de saída, que pode ser calculada a partir do valor InputSampleFreq e das características de intercalação do fluxo de entrada:
- Defina OutputFrameFreq.dwDenominator igual a InputSampleFreq.dwDenominator.
- Se o vídeo de entrada for intercalado, defina OutputFrameFreq.dwNumerator como 2 x InputSampleFreq.dwNumerator. (Após a desinterlacização, a taxa de quadros é dobrada.) Caso contrário, defina o valor como InputSampleFreq.dwNumerator.
dwFourCC: defina esse campo como
pBMI->biCompression
.
A função auxiliar a seguir converte sinalizadores AMINTERLACE_X em valores de VMR9_SampleFormat :
#define IsInterlaced(x) ((x) & AMINTERLACE_IsInterlaced)
#define IsSingleField(x) ((x) & AMINTERLACE_1FieldPerSample)
#define IsField1First(x) ((x) & AMINTERLACE_Field1First)
VMR9_SampleFormat ConvertInterlaceFlags(DWORD dwInterlaceFlags)
{
if (IsInterlaced(dwInterlaceFlags)) {
if (IsSingleField(dwInterlaceFlags)) {
if (IsField1First(dwInterlaceFlags)) {
return VMR9_SampleFieldSingleEven;
}
else {
return VMR9_SampleFieldSingleOdd;
}
}
else {
if (IsField1First(dwInterlaceFlags)) {
return VMR9_SampleFieldInterleavedEvenFirst;
}
else {
return VMR9_SampleFieldInterleavedOddFirst;
}
}
}
else {
return VMR9_SampleProgressiveFrame; // Not interlaced.
}
}