디코더에 의한 IAMVideoAccelerator 의 사용법
디코더에 의한 IAMVideoAccelerator 의 사용법
IAMVideoAccelerator 인터페이스를 사용하면 DirectX 비디오 가속화 (VA)를 포함한 범용 비디오 가속화 처리가 가능하게 된다. DirectX VA 이외의 가속화의 경우, 디코더와 비디오 드라이버는 양쪽 모두, 공통 프로토콜에 따르지 않으면 안 된다.
여기에서는, 이 인터페이스를 사용하기에 즈음해, 디코더가 따르지 않으면 안 되는, 조작의 일반적인 순서에 대해 설명한다. DirectX VA 베이스의 디코더에 고유의 정보에 대해서는, 「IAMVideoAccelerator 에의 DirectX 비디오 가속화의 맵핑」을 참조할것.
주 : 이 인터페이스는, Microsoft Windows® 2000 이후에 이용 가능하다.
IAMVideoAccelerator 인터페이스는,오버레이 믹서 또는 Video Mixing Renderer (VMR)의 입력 핀으로 공개되고 있다. IAMVideoAcceleratorNotify 인터페이스는, 비디오 디코더의 출력 핀으로 공개되고 있다. 필터 핀 접속의 이벤트는 다음의 순서로 발생한다.
- 필터 그래프 매니저가 디코더의 출력 핀의 IPin::Connect 를 호출한다. AM_MEDIA_TYPE 는 옵션 파라미터이다.
- AM_MEDIA_TYPE 는, 미디어 타입을 기술하는 데이터 구조체이다. 이 구조체에는, 메이저 타입 GUID (이 경우는 MEDIATYPE_Video), 서브 타입 GUID (이 경우는 비디오 가속기 GUID), 그 외 다양한 것이 포함된다. 그 1 개는, 이 경우는 비압축 비디오 픽쳐의 폭과 높이를 포함한, 미디어에 대한 정보를 저장 한 포맷 타입 GUID 이다 (많은 경우 MPEG1VIDEOINFO ,VIDEOINFOHEADER ,MPEG2VIDEOINFO , 또는 VIDEOINFOHEADER2 구조체).
- AM_MEDIA_TYPE 구조체가 존재하는 경우는, 디코더에, 지정된 미디어 타입을 사용해 동작하도록(듯이) 지시한다. 이 지정은,"완전 지정" 의 경우와 "부분 지정" 의 경우가 있다. "완전 지정" 의 경우, 디코더는 보통, 그 미디어 타입을 사용해 동작하려고 한다. "부분 지정" 의 경우는,"부분 지정" 미디어 타입과 모순되지 않는 방법에서의 접속에 사용할 수 있는 "완전 지정" 호환 동작 모드를 찾아내려고 한다.
- 접속에 사용하는 "완전 지정" 미디어 타입을 찾을 때는, 보통,"부분 지정" 미디어 타입과 호환성이 있는, 출력 핀이 지원 하고 있는 모든 "완전 지정" 미디어 타입을 조사해, 접속이 성공할 때까지 1 개씩 시험한다고 하는 방법을 사용한다. IPin::Connect 호출에 AM_MEDIA_TYPE 가 포함되지 않고, 그러나 모든 미디어 타입을 체크할 필요가 있는 출력 핀이 있는 경우는, 같은 처리를 한다.
- 디코더측에서, 특정의 AM_MEDIA_TYPE (비디오 가속기 GUID 를 포함한다)가 다운 스트림 입력 핀에 의해 지원 되고 있는지를 조사할 필요가 있는 경우, 그 핀의 IPin::QueryAccept (AM_MEDIA_TYPE 의 서브 타입으로서 비디오 가속기 GUID 를 지정)를 호출하는지, 또는 후술의 항목 5 로 해설하도록(듯이), 그 핀에 접속을 시도하는 것에 의해 조사할 수가 있다.
- 디코더측에서, 다운 스트림 입력 핀이 어느 비디오 가속기 GUID 를 지원 하고 있는지를 인식하고 있지 않고, 또 다운 스트림 입력 핀의 IPin::QueryAccept 를 호출해 특정의 몇개의 비디오 가속기 GUID 만을 지명하는 것을 피하고 싶은 경우, 디코더는,IAMVideoAccelerator::GetVideoAcceleratorGUIDs 를 호출해, 그 핀이 지원 하고 있는 비디오 가속기 GUID 의 일람을 취득할 수 있다.
- 몇개의 특정의 비디오 가속기 GUID 에 대해서는, 디코더는 다운 스트림 입력 핀의 IAMVideoAccelerator::GetUncompFormatsSupported 를 호출해, 특정의 비디오 가속기 GUID 의 렌더링에 사용할 수 있는 DDPIXELFORMAT 픽셀 포맷의 일람을 취득할 수 있다. 돌려받는 일람은, 추천의 정도가 높은 것으로부터 순서에 리스트 되고 있는 (가장 추천 되는 포맷이 최초로 기재된다) 것이라고 생각해도 좋다.
- 디코더는 다운 스트림 입력 핀의 IPin::ReceiveConnection 를 호출한다. 그 때, 미디어 타입의 서브 타입으로서 적절한 비디오 가속기 GUID 를 지정한 AM_MEDIA_TYPE 를 건네준다. 이것에 의해, 비압축 출력 표면의 생성을 포함해 동작에 필요한 접속이 설정된다. 이 표면의 할당에는, AM_MEDIA_TYPE 에 있는 폭과 높이나, 후술 하는 호출에 의해 발견한 할당하는 표면의 수나, 그 외의 비디오 가속기가 보관 유지하고 있어 표면 생성 목적으로 사용하고 싶은 정보 (비디오 가속기 GUID 자체등)를 사용한다. 다운 스트림 입력 핀이, 비디오 가속기 GUID, 또는 그 외의 접속에 관한 어떠한 요소를 거부했을 경우는,IPin::ReceiveConnection 가 실패하는 일이 있다. IPin::ReceiveConnection 가 실패했을 경우는, 돌려받는 HRESULT 로 그것을 알 수 있다. 디코더는, AM_MEDIA_TYPE 구조체에 있는 다른 비디오 가속기 GUID 를 사용하는 등 해, 호출을 재시행할 수 있다.
주 : IPin::ReceiveConnection 를 호출해 접속을 시행해, 접속이 성공했는지 어떠했는지를 체크 하면 말하는 것은, 다운 스트림 입력 핀이 지원 하고 있는 미디어 타입을 디코더측에서 조사하는 이제 1 개의 방법이며, 가장 확실한 방법이기도 하다.
- 렌더러는 디코더의 IAMVideoAcceleratorNotify::SetUncompSurfacesInfo 를 호출한다. 그 때 디코더에, 실제로 할당된 비압축 표면의 수를 건네준다.
- 렌더러는, 비디오 가속기의 초기화에 필요한 데이터를 얻어온다 모아 두어 디코더의 IAMVideoAcceleratorNotify::GetCreateVideoAcceleratorData 를 호출한다.
- 디코더는, 일련의 AMVACompBufferInfo 데이터 구조체 (비디오 가속기 GUID 에 사용되는 압축 데이터 버퍼의 각 타입 마다 1 개가 대응한다)를 얻어온다 모아 두어IAMVideoAccelerator::GetCompBufferInfo 를 호출한다. 그 때, 비디오 가속기 GUID, AMVAUncompDataInfo 구조체, 압축 버퍼 타입의 수를 건네준다.
- AMVAUncompDataInfo 구조체에는, 디코드된 비압축 데이터의 폭과 높이를 픽셀로 나타낸 값과 비압축 픽쳐의 DDPIXELFORMAT 가 들어간다.
- 돌려받는 AMVACompBufferInfo 데이터 구조체에는 각각 다음의 항목이 들어간다.
특정의 타입에 필요한 압축 버퍼의 수.
생성 하는 표면의 폭과 높이 (실제의 의미를 가지는 경우와 가지지 않는 경우가 있다).
주 : DirectDraw 의 압축 버퍼의 표면 할당 처리는, 현재로서는 이러한 표면의 폭 또는 높이가 215 이상이 되는 것을 상정하고 있지 않다. 다만 표면 할당의 호출로 이 제한으로 위반해도 분명한 실패는 되지 않는다. 이 때문에 드라이버는, 그러한 극단적인 사이즈를 피하도록(듯이), 압축 버퍼 메모리에의 요구를 구성하는 것이 좋다. 예를 들어, 폭이 "1" 으로 높이가 "65536" 의 버퍼보다, 폭이 "1024" 로 높이가 "64" 의 버퍼를 요구하는 것이 좋다.
표면에 의해 사용되는 바이트의 합계수.
DirectDrawSurface 개체를 정의해, 압축 데이터를 저장 하는 표면의 생성 기능을 기술한 DDSCAPS2 타입의 구조체.
압축 데이터를 저장 하는 표면의 생성에 사용하는 픽셀 포맷을 기술한 DDPIXELFORMAT (실제의 의미를 가지는 경우와 가지지 않는 경우가 있다).
주 : 몇개의 디코더의 IAMVideoAcceleratorNotify 인터페이스 메서드에의 렌더러의 호출은, 렌더러의 IPin::ReceiveConnection 에의 디코더의 호출내에서 행해질 수 있고, 보통 그처럼 발생한다. 이것은 특히 다음의 경우에 들어맞는다.
주 : 동적 포맷 변경을 지원 하기 위한(해), 필터가 접속되고 실행되고 있는 동안, 디코더는 위의 메서드에 의해 IPin::ReceiveConnection 및 그 외의 메서드를 호출할 수가 있다. 이 기능은 동적 포맷 변경을 지원 하기 위해서 준비되어 있지만, 다만 모든 데이터 세트가 최초부터 한번 더 시작 되어 모든 참조 픽쳐 정보가 없어지는 H. 263, Annex P 의 동적 포맷 변경은 대상이 되지 않는다.
초기화 후의 처리중의 IAMVideoAccelerator 의 사용에 대해 다음에 해설한다.
- 디코더는, 출력 픽쳐의 생성 처리를 시작 하기 위한(해), 각 비압축 표면에 대해서 IAMVideoAccelerator::BeginFrame 를 호출한다. 그 때,AMVABeginFrameInfo 구조체를 송신한다.
- AMVABeginFrameInfo 구조체에는, 목적지 버퍼의 인덱스, 다운 스트림에 송신하는 데이터의 포인터, 디코더가 읽어내기 위해서(때문에) 가속기가 데이터를 배치할 수 있는 장소를 나타내는 포인터가 포함된다.
- 주 1 : 가속기는 실제로는 목적지 버퍼의 인덱스를 받지 않고, 인덱스는 다운 스트림에 가기 전에 렌더러에 의해 변환된다.
- 주 2 : IAMVideoAccelerator::BeginFrame 는,IAMVideoAccelerator::EndFrame . 에의 호출동안에 몇 번이라도 호출할 수가 있다.
- 주 3 : 인터페이스 처리 중(안)에서는, 비트 스트림내의 각각의 픽쳐를 처리하기 위해서,IAMVideoAccelerator::BeginFrame 및 IAMVideoAccelerator::EndFrame 를 호출할 필요가 있다고 하는 전제는 없다.
인터페이스에 관해서 IAMVideoAccelerator::BeginFrame 가 실행하는 것은, 렌더러내에서, 인덱스와 비압축 표면와의 사이에 관련짓고를 생성 하는 것이다. 장치 드라이버내에서 특정의 함수를 호출하는 수단도 제공한다 (임의의 데이터를 디코더와 장치 드라이버의 사이에 교환하는 수단의 지원을 포함한다).
그러나, DirectX VA 조작에는, 비트 스트림의 각 픽쳐의 처리에서는 IAMVideoAccelerator::BeginFrame 와 IAMVideoAccelerator::EndFrame 호출이 필요하다고 하는 요건이 있다. 이것에 대해서는 이하로 설명한다.
- 비압축 데이터를 가속기에 송신하기 위해서, 디코더는 다음의 메서드를 호출한다.
- IAMVideoAccelerator::QueryRenderStatus . 버퍼가 읽기나 쓰기의 대상으로 해 안전한가 어떤가를 조사하기 (위해)때문에.
- IAMVideoAccelerator::GetBuffer . 지정된 버퍼에의 액세스를 잠금 및 얻어온다 싶은 (액세스를 얻어오기 위해 이 메서드를 앞에 두고 호출하지 않은 경우). 이 메서드의 사용법으로서IAMVideoAccelerator::BeginFrame 의 호출 대상이 된 마지막 비압축 출력 픽쳐의 내용의 복사를 얻어온다의 것에 사용할 수 있는 특별한 방법도 있다. 다만 그 목적지 버퍼 인덱스에 대해서 IAMVideoAccelerator::EndFrame 가 불려 가지 않은 것이 조건이 된다. DDI 가 요구된 버퍼에 대해서 DDERR_WASSTILLDRAWING 의 렌더링 상태를 돌려주는 경우, 이 상태가 클리어 될 때까지 GetBuffer 내에서 sleeve 루프가 처리된다. GetBuffer 를 호출하기 위해서(때문에), 디코더는 AMVACompBufferInfo 데이터 구조체로부터의 몇개의 정보를 필요로 한다. 이 구조체는,IAMVideoAccelerator::GetCompBufferInfo 를 호출하는 것으로 취득할 수 있다.
- IAMVideoAccelerator::Execute . AMVABUFFERINFO 데이터 구조체의 배열로 지시받은 일련의 압축 버퍼에 포함되는 데이터를 처리하는 것이 좋은 일을 나타낸다. 이 호출에서는, 함수 코드 dwFunction 가 드라이버에게 건네진다. 또, 다운 스트림에 송신하는 데이터에의 lpPrivateInputData 포인터, 디코더가 읽어내기 위해서(때문에) 다운 스트림 처리가 데이터를 배치할 수 있는 장소를 가리키는 lpPrivateOutputData 포인터도 건네받는다.
- IAMVideoAccelerator::ReleaseBuffer . 디코더가, 지정된 버퍼의 사용을 완료했기 때문에, 당면은 버퍼에의 잠금 된 액세스가 필요없게 된 것을 나타낸다. 디코더가 계속해 버퍼를 사용하고 싶은 경우는, 버퍼를 그 이상 사용하지 않다고는 잘라 할 때까지 IAMVideoAccelerator::ReleaseBuffer 를 호출하지 않고 두면,IAMVideoAccelerator::GetBuffer 를 호출하는 필요성을 회피할 수 있다. 디코더는,Execute 가 불려 간 후는,QueryRenderStatus 로 버퍼에 쓰기를 해도 문제 없으면 나타날 때까지는 버퍼에 쓰기를 하지 않는 것.
- 디코더는, 목적지 버퍼의 출력 처리를 완료하기 위해서,IAMVideoAccelerator::EndFrame 를 호출한다. 이 호출 시에 임의의 데이터를 다운 스트림에 건네줄 수가 있다 (이 호출의 결과 실행되는 것은, 기본적으로는 이만큼이다). 이 호출에서는 목적지 버퍼의 인덱스는 송신하지 않기 때문에, 여기서 건네주는 임의의 데이터내에서 가리키지 않는 이상 어느 목적지 버퍼가 완료했는지를 가속기에 정확하게 전할 수 없다.
- 디코더는, 프레임을 표시하기 위해서, 표시하는 프레임의 인덱스와 시작 및 종료의 타임 스탬프를 포함한 IMediaSample 구조체와dwTypeSpecificFlags (AM_SAMPLE2_PROPERTIES 구조체)나 dwInterlaceFlags (VIDEOINFOHEADER2 구조체)등의 관련 플래그와 함께,IAMVideoAccelerator::DisplayFrame 를 호출한다. 디코더는,DisplayFrame 를 호출하기 전에, 프레임의 내용에 영향을 주는 압축 해제 조작이 모두 완료했는지 어떠했는지를 확인할 필요가 있다.
- 마지막으로, 디코더는, 모든 처리가 완료했을 때에,IAMVideoAccelerator::EndFrame 를 호출해, 시작 된 나머지의 출력 프레임이 모두 완료한 것을 나타내, 미릴리즈의 각 버퍼에 대해서 IAMVideoAccelerator::ReleaseBuffer 를 호출해, 잠금 된 버퍼를 모두 릴리즈 할 필요가 있다.