Condividi tramite


Impostazione delle proprietà di compressione video

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEnginee Cattura audio/video con Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft raccomanda fortemente che il nuovo codice utilizzi MediaPlayer, IMFMediaEngine e Acquisizione audio/video in Media Foundation anziché DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

I filtri di compressione video possono supportare l'interfacciaIAMVideoCompressionsui pin di output. Usare questa interfaccia per impostare le proprietà di compressione, ad esempio la frequenza dei fotogrammi chiave, il numero di fotogrammi stimati (P) per fotogrammi chiave e la qualità di compressione relativa.

Chiamare prima di tutto il metodoIBaseFilter::EnumPinsper trovare il pin di output del filtro ed eseguire una query sul pin per l'interfaccia. Alcuni filtri potrebbero non supportare affatto l'interfaccia. Altri utenti possono esporre l'interfaccia ma non supportano tutte le proprietà di compressione. Per determinare quali proprietà sono supportate, chiamare IAMVideoCompression::GetInfo. Questo metodo restituisce diverse informazioni:

  • Un insieme di bandiere di funzionalità
  • Stringa descrittiva e stringa del numero di versione
  • Valori predefiniti per la frequenza dei fotogrammi chiave, la frequenza dei fotogrammi P e la qualità (se supportato)

Il metodo ha la sintassi seguente:

hr = pCompress->GetInfo(pszVersion, &cbVersion, pszDesc, &cbDesc, 
         &lKeyFrame, &lPFrame, &dblQuality, &lCap);

I parametri pszVersion e pszDesc sono buffer di caratteri a larghezza fissa che ricevono la stringa di versione e la stringa di descrizione. I parametri cbVersion e cbDesc ricevono le dimensioni del buffer necessarie in byte (non caratteri). I parametri lKeyFrame, lPFramee dblQuality ricevono i valori predefiniti per la frequenza dei fotogrammi chiave, la frequenza dei fotogrammi P e la qualità. La qualità viene espressa come numero a virgola mobile da 0,0 a 1,0. Il parametro lCap riceve un OR bit per bit dei flag di funzionalità, definiti dal tipo enumeratoCompressionCaps.

Uno di questi parametri può essere NULL, nel qual caso il metodo ignora tale parametro. Ad esempio, per allocare buffer per le stringhe di versione e descrizione, chiamare prima il metodo con NULL nei primi e nel terzo parametro. Usare i valori restituiti per cbVersion e cbDesc per allocare i buffer e quindi chiamare di nuovo il metodo:

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

Il valore di lCap indica quale degli altri metodi IAMVideoCompression supportati dal filtro. Ad esempio, se lCap contiene il flag CompressionCaps_CanKeyFrame, è possibile chiamare IAMVideoCompression::get_KeyFrameRate per ottenere la frequenza dei fotogrammi chiave e IAMVideoCompression::put_KeyFrameRate per impostare la frequenza dei fotogrammi chiave. Un valore negativo indica che il filtro userà il valore predefinito, come ottenuto da IAMVideoCompression::GetInfo. Per esempio:

if (lCap & CompressionCaps_CanKeyFrame)
{
    hr = pCompress->get_KeyFrameRate(&lKeyFrame);
    if (FAILED(hr) || lKeyFrame < 0)
    {
        lKeyFrame = lDefaultKeyFrame; // From GetInfo.
    }
}

L'esempio di codice seguente tenta di trovare l'interfaccia IAMVideoCompression sul pin di output. Se ha esito positivo, recupera i valori predefiniti e effettivi per le proprietà di compressione:

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;
        }
    }
}

Nota

Se si usa l'interfacciaICaptureGraphBuilder2per compilare il grafico, è possibile ottenere l'interfaccia IAMVideoCompression chiamando ICaptureGraphBuilder2::FindInterface, anziché usare IBaseFilter::EnumPins. Il metodo FindInterface è un metodo helper che cerca filtri e puntini nel grafico per un'interfaccia specificata.