다음을 통해 공유


비디오 압축 속성 설정

[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngineMedia Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드에서 DirectShow 대신 MediaPlayer, IMFMediaEngine오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]

비디오 압축 필터는 출력 핀에서 IAMVideoCompression 인터페이스를 지원할 수 있습니다. 이 인터페이스를 사용하여 키 프레임 속도, 키 프레임당 예측된(P) 프레임 수 및 상대 압축 품질과 같은 압축 속성을 설정합니다.

먼저 IBaseFilter::EnumPins 메서드를 호출하여 필터의 출력 핀을 찾고 인터페이스에 대한 핀을 쿼리합니다. 일부 필터는 인터페이스를 전혀 지원하지 않을 수 있습니다. 다른 사용자는 인터페이스를 노출할 수 있지만 모든 압축 속성을 지원하지는 않습니다. 지원되는 속성을 확인하려면 IAMVideoCompression::GetInfo를 호출합니다. 이 메서드는 다음과 같은 여러 정보를 반환합니다.

  • 기능 플래그 집합
  • 설명 문자열 및 버전 번호 문자열
  • 키 프레임 속도, P 프레임 속도 및 품질에 대한 기본값(지원되는 경우)

메서드에는 다음 구문이 있습니다.

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

pszVersionpszDesc 매개 변수는 버전 문자열 및 설명 문자열을 수신하는 와이드 문자 버퍼입니다. cbVersioncbDesc 매개 변수는 필요한 버퍼 크기를 바이트(문자 아님)로 받습니다. lKeyFrame, lPFramedblQuality 매개 변수는 키 프레임 속도, P 프레임 속도 및 품질에 대한 기본값을 받습니다. 품질은 0.0에서 1.0까지의 부동 소수점 숫자로 표현됩니다. lCap 매개 변수는 CompressionCaps 열거형 형식으로 정의된 기능 플래그의 비트 OR을 받습니다.

이러한 매개 변수는 NULL일 수 있으며, 이 경우 메서드는 해당 매개 변수를 무시합니다. 예를 들어 버전 및 설명 문자열에 대한 버퍼를 할당하려면 먼저 첫 번째 및 세 번째 매개 변수에서 NULL 을 사용하여 메서드를 호출합니다. cbVersioncbDesc에 대해 반환된 값을 사용하여 버퍼를 할당한 다음 메서드를 다시 호출합니다.

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

lCap 값은 필터가 지원하는 다른 IAMVideoCompression 메서드를 나타냅니다. 예를 들어 lCap 에 CompressionCaps_CanKeyFrame 플래그가 포함된 경우 IAMVideoCompression::get_KeyFrameRate 호출하여 키 프레임 속도를 얻고 IAMVideoCompression::p ut_KeyFrameRate 를 호출하여 키 프레임 속도를 설정할 수 있습니다. 음수 값은 필터가 IAMVideoCompression::GetInfo에서 가져온 기본값을 사용한다는 것을 나타냅니다. 예를 들면 다음과 같습니다.

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

다음 코드 예제에서는 출력 핀에서 IAMVideoCompression 인터페이스를 찾으려고 시도합니다. 성공하면 압축 속성의 기본값과 실제 값을 검색합니다.

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

참고

ICaptureGraphBuilder2 인터페이스를 사용하여 그래프를 빌드하는 경우 IBaseFilter::EnumPins를 사용하는 대신 ICaptureGraphBuilder2::FindInterface를 호출하여 IAMVideoCompression 인터페이스를 가져올 수 있습니다. FindInterface 메서드는 그래프의 필터 및 핀에서 지정된 인터페이스를 검색하는 도우미 메서드입니다.