DirectShow DirectShow 튜토리얼 AVI 파일의 재압축 비디오 압축 프로퍼티의 설정   [목차열람] [주소복사] [슬롯비우기]
비디오 압축 프로퍼티의 설정
 
Microsoft DirectX 9.0

비디오 압축 프로퍼티의 설정

비디오 압축 필터는, 자신의 출력 핀으로 IAMVideoCompression 인터페이스를 지원 할 수 있다. 이 인터페이스를 사용해, 키 frame rate, 키 프레임마다 예측 (P) 프레임수, 상대적인 압축 품질 등, 압축 프로퍼티를 설정한다.

최초로,IBaseFilter::EnumPins 메서드를 호출해, 필터의 출력 핀을 검색해, 그 핀에 인터페이스의 유무를 문의한다. 필터안에는, 이 인터페이스를 지원 하고 있지 않는 것도 있다. 그 외의 필터도, 인터페이스는 공개하지만, 모든 압축 프로퍼티를 지원 하고 있다고는 할 수 없는 경우가 있다. 지원 되고 있는 프로퍼티를 판단하려면 ,IAMVideoCompression::GetInfo 를 호출한다. 이 메서드는, 다음과 같은 정보를 돌려준다.

이 메서드의 구문은 다음과 같다.

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

pszVersion 파라미터와 pszDesc 파라미터는, 버전 캐릭터 라인과 설명문자열을 받는 와이드 캐릭터 라인 버퍼이다. cbVersion 파라미터와 cbDesc 파라미터는, 필요한 버퍼 사이즈를 바이트수 (문자는 아니고)로 받는다. lKeyFrame,lPFrame,dblQuality 의 각 파라미터는, 키 frame rate, P frame rate, 품질에 대응하는 각 디폴트값을 받는다. 품질은, 0.0 ~ 1.0 의 범위의 부동 소수점수(실수)값으로 나타낸다. lCap 파라미터는,CompressionCaps 열거형으로 정의된, 능력 플래그의 비트마다 OR 의 편성을 받는다.

이러한 파라미터에는 NULL 를 설정해도 상관없지만, 그 경우, 그 파라미터는 무시된다. 예를 들어, 버전 캐릭터 라인과 설명문자열에 버퍼를 할당하려면 최초로, 1 번째의 파라미터와 3 번째의 파라미터에 NULL 를 설정해 이 메서드를 호출한다. cbVersioncbDesc 에 돌려받는 값을 사용해 버퍼를 할당하고 나서, 이 메서드를 다시 호출한다.

int cbVersion, cbDesc; // 문자 단위는 아니고, 바이트 단위의 사이즈!
hr = pCompress->GetInfo(0, &cbVersion, 0, &cbDesc, 0, 0, 0, 0);
if (SUCCEEDED(hr))
{
    WCHAR *pszVersion = new WCHAR[cbVersion/2]; // 와이드 문자 = 2 바이트
    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::put_KeyFrameRate 를 호출해 키 프레임을 설정할 수 있다. 부의 값은, 필터가 IAMVideoCompression::GetInfo 로 취득한 값을 디폴트값으로 사용하는 것을 나타낸다. 다음에 예를 나타낸다.

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

다음 샘플 코드에서는, 출력 핀의 IAMVideoCompression 인터페이스를 검색하려고 한다. 성공하면 압축 프로퍼티에 대한 디폴트값과 실제의 값을 받는다.

HRESULT hr = E_FAIL;
IEnumPins *pEnum = NULL;
IPin *pPin = NULL;
IAMVideoCompression *pCompress = NULL;

// IAMVideoCompression 를 지원 하는 핀을 검색한다 (존재하는 경우).
pFilter->EnumPins(&pEnum);
while (S_OK == pEnum->Next(1, &pPin, NULL))
{
    hr = pPin->QueryInterface(IID_IAMVideoCompression, (void**) &pCompress);
    pPin->Release();
    if (SUCCEEDED(hr)) // 인터페이스가 발견되었다.
    {
        break;
    }
}
if (SUCCEEDED(hr)) 
{
    long lCap;                     // 능력 플래그.
    long lKeyFrame, lPFrame;       // 실제의 값.
    double m_Quality;
    long lKeyFrameDef, lPFrameDef; // 디폴트값.
    double QualityDef;
    
    // 디폴트값과 능력을 얻어온다.
    hr = pCompress->GetInfo(0, 0, 0, 0, &KeyFrameDef, &lPFrameDef,
             &QualityDef, &lCap);
    if (SUCCEEDED(hr))
    {
        // 가능한 경우는 실제의 값을 얻어온다.
        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 메서드는, 그래프내의 필터 및 핀으로 지정된 인터페이스를 검색하는 헬퍼-메서드이다.

↑TOP