DirectShow DirectShow 의 사용법 Video Mixing Renderer 의 사용법 비인터레이스의 설정 [목차열람] [주소복사] [슬롯비우기] |
Microsoft DirectX 9.0 |
Video Mixing Renderer (VMR)는 하드웨어에 의해 액셀러레이트 되는 비인터레이스를 지원 한다. 이 기능은, 인터레이스 된 비디오의 렌더링 품질을 개선한다. 실제로 이용할 수 있는 기능의 자세한 것은, 기본으로 되는 하드웨어에 따라서 다르다. 애플리케이션은 IVMRDeinterlaceControl 인터페이스 (VMR-7) 또는 IVMRDeinterlaceControl9 인터페이스 (VMR-9)를 개입시켜, 하드웨어의 비인터레이스 기능을 문의해 비인터레이스를 설정할 수 있다. 비인터레이스는 스트림 단위로 실행된다.
주 : 여기에서는 IVMRDeinterlaceControl9 의 메서드에 대해 설명하지만, VMR-7 의 경우도 거의 같다.
비디오 스트림의 비인터레이스 기능을 얻어오려면, 다음의 작업을 실시한다.
다음 코드에 이러한 순서를 나타낸다.
VMR9VideoDesc VideoDesc;
DWORD dwNumModes = 0;
// VideoDesc 구조체에 데이터를 넣는다 (생략).
hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc,
&dwNumModes, NULL);
if (SUCCEEDED(hr) && (dwNumModes != 0))
{
// 모드를 식별하는 GUID 의 배열을 할당한다.
GUID *pModes = new GUID[dwNumModes];
if (pModes)
{
// 배열에 데이터를 넣는다.
hr = pDeinterlace->GetNumberOfDeinterlaceModes(&VideoDesc,
&dwNumModes, pModes);
if (SUCCEEDED(hr))
{
// 각 아이템을 루프 해, 기능을 얻어온다.
for (int i = 0; i < dwNumModes; i++)
{
VMR9DeinterlaceCaps Caps;
hr = pDeinterlace->GetDeinterlaceModeCaps(pModes + i,
&VideoDesc, &Caps);
if (SUCCEEDED(hr))
{
// Caps 구조체를 조사한다.
}
}
}
delete [] pModes;
}
}
애플리케이션은, 다음의 메서드를 사용해 스트림의 비인터레이스 모드를 설정할 수 있게 되었다.
메서드의 레퍼런스 페이지에는, 한층 더 자세한 설명이 게재되고 있다.
VMR9VideoDesc 구조체의 사용법
전에 설명한 순서로, 최초로 VMR9VideoDesc 구조체에 비디오 스트림의 설명을 저장 했다. 처음에, 비디오 스트림의 미디어 타입을 얻어온다. 거기에는, VMR 필터의 입력 핀의 IPin::ConnectionMediaType 를 호출한다. 다음에, 비디오 스트림이 인터레이스 되고 있는지를 확인한다. VIDEOINFOHEADER2 포맷만 인터레이스 할 수 있다. 포맷 타입이 FORMAT_VideoInfo 인 경우는, 반드시 프로그래시브 프레임이다. 포맷 타입이 FORMAT_VideoInfo2 인 경우는,dwInterlaceFlags 필드에서 AMINTERLACE_IsInterlaced 플래그의 유무를 조사한다. 이 플래그가 있는 경우, 비디오는 인터레이스화 되고 있다.
변수 pBMI 가 포맷 블록의 BITMAPINFOHEADER 구조체의 포인터이라고 상정한다. VMR9VideoDesc 구조체에 다음의 값을 설정한다.
sizeof(VMR9VideoDesc)
로 설정한다. pBMI->biWidth
로 설정한다. abs(pBMI->biHeight)
로 설정한다. 프레임 근처의 평균 시간 | frame rate (fps) | 분자 | 분모 |
166833 | 59.94 (NTSC) | 60000 | 1001 |
333667 | 29.97 (NTSC) | 30000 | 1001 |
417188 | 23.97 (NTSC) | 24000 | 1001 |
200000 | 50.00 (PAL) | 50 | 1 |
400000 | 25.00 (PAL) | 25 | 1 |
416667 | 24.00 (필름) | 24 | 1 |
다음의 헬퍼-함수는 AMINTERLACE_X 플래그를 VMR9_SampleFormat 값으로 변환한다.
#define IsInterlaced(x) ((x) & AMINTERLACE_IsInterlaced)
#define IsSingleField(x) ((x) & AMINTERLACE_1FieldPerSample)
#define IsField1First(x) ((x) & AMINTERLACE_Field1First)
VMR9_SampleFormat ConvertInterlaceFlags(DWORD dwInterlaceFlags)
{
if (IsInterlaced(dwInterlaceFlags)) {
if (IsSingleField(dwInterlaceFlags)) {
if (IsField1First(dwInterlaceFlags)) {
return VMR9_SampleFieldSingleEven;
}
else {
return VMR9_SampleFieldSingleOdd;
}
}
else {
if (IsField1First(dwInterlaceFlags)) {
return VMR9_SampleFieldInterleavedEvenFirst;
}
else {
return VMR9_SampleFieldInterleavedOddFirst;
}
}
}
else {
return VMR9_SampleProgressiveFrame; // 인터레이스되지 않다.
}
}