Definindo propriedades de compactação de vídeo
[O recurso associado a esta página, DirectShow, é um recurso herdado. Foi substituído por MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]
Os filtros de compactação de vídeo podem dar suporte à interface IAMVideoCompression em seus pinos de saída. Use essa interface para definir propriedades de compactação, como a taxa de quadros chave, o número de quadros previstos (P) por quadro-chave e a qualidade de compactação relativa.
Primeiro, chame o método IBaseFilter::EnumPins para localizar o pino de saída do filtro e consulte o pino da interface. Alguns filtros podem não dar suporte à interface. Outros podem expor a interface, mas não dar suporte a todas as propriedades de compactação. Para determinar quais propriedades têm suporte, chame IAMVideoCompression::GetInfo. Esse método retorna várias informações:
- Um conjunto de sinalizadores de funcionalidades
- Uma cadeia de caracteres descritiva e uma cadeia de caracteres de número de versão
- Valores padrão para taxa de quadros chave, taxa de quadros P e qualidade (quando houver suporte)
O método tem a seguinte sintaxe:
hr = pCompress->GetInfo(pszVersion, &cbVersion, pszDesc, &cbDesc,
&lKeyFrame, &lPFrame, &dblQuality, &lCap);
Os parâmetros pszVersion e pszDesc são buffers de caractere largo que recebem a cadeia de caracteres de versão e a cadeia de caracteres de descrição. Os parâmetros cbVersion e cbDesc recebem os tamanhos de buffer necessários em bytes (não caracteres). Os parâmetros lKeyFrame, lPFrame e dblQuality recebem os valores padrão para a taxa de quadros chave, a taxa de quadros P e a qualidade. A qualidade é expressa como um número de ponto flutuante de 0,0 para 1,0. O parâmetro lCap recebe um OR bit a bit dos sinalizadores de funcionalidades, que são definidos pelo tipo enumerado CompressionCaps .
Qualquer um desses parâmetros pode ser NULL; nesse caso, o método ignora esse parâmetro. Por exemplo, para alocar buffers para as cadeias de caracteres de versão e descrição, primeiro chame o método com NULL no primeiro e no terceiro parâmetros. Use os valores retornados para cbVersion e cbDesc para alocar os buffers e, em seguida, chame o método novamente:
int cbVersion, cbDesc; // Size in bytes, not characters!
hr = pCompress->GetInfo(0, &cbVersion, 0, &cbDesc, 0, 0, 0, 0);
if (SUCCEEDED(hr))
{
WCHAR *pszVersion = new WCHAR[cbVersion/2]; // Wide character = 2 bytes
WCHAR *pszDesc = new WCHAR[cbDesc/2];
hr = pCompress->GetInfo(pszVersion, 0, pszDesc, 0, 0, 0, 0, 0);
}
O valor de lCap indica qual dos outros métodos IAMVideoCompression o filtro dá suporte. Por exemplo, se lCap contiver o sinalizador CompressionCaps_CanKeyFrame, você poderá chamar IAMVideoCompression::get_KeyFrameRate para obter a taxa de quadros chave e IAMVideoCompression::p ut_KeyFrameRate para definir a taxa de quadros chave. Um valor negativo indica que o filtro usará o valor padrão, conforme obtido de IAMVideoCompression::GetInfo. Por exemplo:
if (lCap & CompressionCaps_CanKeyFrame)
{
hr = pCompress->get_KeyFrameRate(&lKeyFrame);
if (FAILED(hr) || lKeyFrame < 0)
{
lKeyFrame = lDefaultKeyFrame; // From GetInfo.
}
}
O exemplo de código a seguir tenta localizar a interface IAMVideoCompression no pino de saída. Se for bem-sucedido, ele recuperará os valores padrão e reais para as propriedades de compactação:
HRESULT hr = E_FAIL;
IEnumPins *pEnum = NULL;
IPin *pPin = NULL;
IAMVideoCompression *pCompress = NULL;
// Find the pin that supports IAMVideoCompression (if any).
pFilter->EnumPins(&pEnum);
while (S_OK == pEnum->Next(1, &pPin, NULL))
{
hr = pPin->QueryInterface(IID_IAMVideoCompression, (void**)&pCompress);
pPin->Release();
if (SUCCEEDED(hr)) // Found the interface.
{
break;
}
}
if (SUCCEEDED(hr))
{
long lCap; // Capability flags
long lKeyFrame, lPFrame; // Real values
double m_Quality;
long lKeyFrameDef, lPFrameDef; // Default values
double QualityDef;
// Get default values and capabilities.
hr = pCompress->GetInfo(0, 0, 0, 0, &KeyFrameDef, &lPFrameDef,
&QualityDef, &lCap);
if (SUCCEEDED(hr))
{
// Get actual values where possible.
if (lCap & CompressionCaps_CanKeyFrame)
{
hr = pCompress->get_KeyFrameRate(&lKeyFrame);
if (FAILED(hr) || lKeyFrame < 0)
lKeyFrame = lKeyFrameDef;
}
if (lCap & CompressionCaps_CanBFrame)
{
hr = pCompress->get_PFramesPerKeyFrame(&lPFrame);
if (FAILED(hr) || lPFrame < 0)
lPFrame = lPFrameDef;
}
if (lCap & CompressionCaps_CanQuality)
{
hr = pCompress->get_Quality(&Quality);
if (FAILED(hr) || Quality < 0)
Quality = QualityDef;
}
}
}
Observação
Se você estiver usando a interface ICaptureGraphBuilder2 para criar seu grafo, poderá obter a interface IAMVideoCompression chamando ICaptureGraphBuilder2::FindInterface, em vez de usar IBaseFilter::EnumPins. O método FindInterface é um método auxiliar que pesquisa filtros e pinos no grafo para uma interface especificada.