Compartilhar via


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.