비디오 압축 속성 설정
[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngine 및 Media 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);
pszVersion 및 pszDesc 매개 변수는 버전 문자열 및 설명 문자열을 수신하는 와이드 문자 버퍼입니다. cbVersion 및 cbDesc 매개 변수는 필요한 버퍼 크기를 바이트(문자 아님)로 받습니다. lKeyFrame, lPFrame 및 dblQuality 매개 변수는 키 프레임 속도, P 프레임 속도 및 품질에 대한 기본값을 받습니다. 품질은 0.0에서 1.0까지의 부동 소수점 숫자로 표현됩니다. lCap 매개 변수는 CompressionCaps 열거형 형식으로 정의된 기능 플래그의 비트 OR을 받습니다.
이러한 매개 변수는 NULL일 수 있으며, 이 경우 메서드는 해당 매개 변수를 무시합니다. 예를 들어 버전 및 설명 문자열에 대한 버퍼를 할당하려면 먼저 첫 번째 및 세 번째 매개 변수에서 NULL 을 사용하여 메서드를 호출합니다. cbVersion 및 cbDesc에 대해 반환된 값을 사용하여 버퍼를 할당한 다음 메서드를 다시 호출합니다.
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 메서드는 그래프의 필터 및 핀에서 지정된 인터페이스를 검색하는 도우미 메서드입니다.