디코더가 IAMVideoAccelerator를 사용하는 방법

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

IAMVideoAccelerator 인터페이스를 사용하면 VA(DirectX 비디오 가속)를 비롯한 일반 비디오 가속 작업을 수행할 수 있습니다. 비 DirectX VA 가속의 경우 디코더 및 비디오 드라이버는 모두 공통 프로토콜을 준수해야 합니다.

이 섹션에서는 이 인터페이스를 사용할 때 디코더가 따라야 하는 작업의 일반적인 순서를 설명합니다. DirectX VA 기반 디코더와 관련된 자세한 내용은 DirectX 비디오 가속을 IAMVideoAccelerator에 매핑에서 찾을 수 있습니다.

참고

이 인터페이스는 Windows 2000 이상에서 사용할 수 있습니다.

 

IAMVideoAccelerator 인터페이스는 오버레이 믹서 또는 VMR(비디오 믹싱 렌더러)의 입력 핀에 노출됩니다. IAMVideoAcceleratorNotify 인터페이스는 디코더의 출력 핀에 노출됩니다. 필터 핀을 연결하기 위한 이벤트 시퀀스는 다음과 같습니다.

  1. 필터 그래프 관리자는 디코더 필터의 출력 핀에서 IPin::Connect 를 호출합니다. AM_MEDIA_TYPE 선택적 매개 변수입니다.

    • AM_MEDIA_TYPE 미디어 유형을 설명하는 데이터 구조입니다. 여기에는 majortype GUID(이 경우 MEDIATYPE_Video), 하위 형식 GUID(이 경우 비디오 가속기 GUID여야 합니다) 및 기타 다양한 항목이 포함됩니다. 이러한 항목 중 하나는 MPEG1VIDEOINFO, VIDEOINFOHEADER, MPEG2VIDEOINFO 또는 VIDEOINFOHEADER2 구조체에서 압축되지 않은 비디오 사진의 너비와 높이를 포함하여 미디어에 대한 정보를 포함하는 형식 형식 GUID입니다.
    • AM_MEDIA_TYPE 구조체가 있는 경우 디코더가 지정된 미디어 형식을 사용하여 작동하도록 지시합니다. 이 형식은 "완전히 지정됨" 또는 "부분적으로 지정"될 수 있습니다. "완전히 지정된" 경우 디코더는 일반적으로 단순히 해당 미디어 형식으로 작동하려고 시도합니다. "부분적으로 지정된" 경우 "부분적으로 지정된" 미디어 형식과 일치하는 방식으로 연결하는 데 사용할 수 있는 "완전히 지정된" 호환되는 작업 모드를 찾으려고 시도합니다.
    • 연결에 사용할 "완전히 지정된" 미디어 형식을 찾으려는 일반적인 방법은 출력 핀이 지원하는 모든 "완전히 지정된" 미디어 형식 목록을 통해 실행하여 "부분적으로 지정된" 미디어 형식과 호환되고 성공할 때까지 각 미디어 형식과 연결을 시도하는 것입니다. IPin::Connect 호출에 AM_MEDIA_TYPE 포함되지 않지만 출력 핀이 모든 미디어 형식을 검사 경우 프로세스는 일반적으로 유사합니다.
  2. 디코더가 다운스트림 입력 핀에서 특정 AM_MEDIA_TYPE(비디오 가속기 GUID 포함)를 지원하는지 여부를 검사 하려는 경우 해당 핀의 IPin::QueryAccept(비디오 가속기 GUID를 AM_MEDIA_TYPE 하위 형식으로 사용)를 호출하거나 아래 항목 5에 설명된 대로 해당 핀에 연결을 시도할 수 있습니다.

  3. 디코더가 다운스트림 입력 핀이 지원하는 비디오 가속기 GUID를 모르고 다운스트림 입력 핀의 IPin::QueryAccept를 호출하여 특정 후보 비디오 가속기 GUID만 제안하지 않으려는 경우 디코더는 IAMVideoAccelerator::GetVideoAcceleratorGUIDs 를 호출하여 핀이 지원하는 비디오 가속기 GUID 목록을 가져올 수 있습니다.

  4. 일부 특정 비디오 가속기 GUID의 경우 디코더는 다운스트림 입력 핀의 IAMVideoAccelerator::GetUncompFormatsSupported 를 호출하여 특정 비디오 가속기 GUID를 렌더링하는 데 사용할 수 있는 DDPIXELFORMAT 픽셀 형식 목록을 가져올 수 있습니다. 반환된 목록은 기본 설정 순서가 감소하는 것으로 간주되어야 합니다(즉, 가장 선호하는 형식이 먼저 나열됨).

  5. 디코더는 다운스트림 입력 핀의 IPin::ReceiveConnection을 호출하여 적절한 비디오 가속기 GUID가 있는 AM_MEDIA_TYPE 미디어 형식의 하위 형식으로 전달합니다. 이렇게 하면 압축되지 않은 출력 표면( AM_MEDIA_TYPE 찾은 너비 및 높이를 사용하여 할당되고, 아래에 설명된 호출에서 찾을 수 있는 할당할 표면 수, 비디오 가속기에서 사용할 수 있고 비디오 가속기 GUID 자체와 같이 해당 용도에 사용하려는 기타 정보)를 포함하여 작업에 대한 연결이 설정됩니다. 다운스트림 입력 핀이 비디오 가속기 GUID 또는 연결의 다른 측면을 거부하는 경우 IPin::ReceiveConnection 이 실패할 수 있습니다. IPin::ReceiveConnection이 실패하면 반환된 HRESULT에 표시되며 디코더는 AM_MEDIA_TYPE 구조의 새 비디오 가속기 GUID를 사용하여 다시 호출을 시도할 수 있습니다.

    • [!Note]

      이는 디코더가 다운스트림 입력 핀에서 지원하는 항목을 결정하는 또 다른 방법(그리고 가장 확실한 방법)입니다. 단순히 IPin::ReceiveConnection 을 호출하고 연결을 시도한 다음 연결 시도가 성공했는지 확인합니다.

       

    • IPin::ReceiveConnection 중에 렌더러는 디코더의 IAMVideoAcceleratorNotify::GetUncompSurfacesInfo를 호출하여 할당할 압축되지 않은 표면 수를 파악하기 위해 비디오 가속기 GUID 및 AMVAUncompBufferInfo 구조를 전달합니다. 디코더는 특정 형식에 할당할 최소 및 최대 표면 수와 할당할 표면의 픽셀 형식을 설명하는 DDPIXELFORMAT 구조체를 포함하는 구조를 채우고 반환합니다.

    • [!Note]

      비디오 가속기 GUID 이외의 IAMVideoAcceleratorNotify::GetUncompSurfacesInfo 호출에서 디코더에 실제로 전달되는 것은 없습니다.

       

  6. 렌더러는 디코더의 IAMVideoAcceleratorNotify::SetUncompSurfacesInfo를 호출하여 디코더에 할당된 압축되지 않은 표면의 실제 수를 디코더에 전달합니다.

  7. 렌더러는 디코더의 IAMVideoAcceleratorNotify::GetCreateVideoAcceleratorData 를 호출하여 비디오 가속기를 초기화하는 데 필요한 데이터를 가져옵니다.

  8. 디코더는 IAMVideoAccelerator::GetCompBufferInfo를 호출하여 비디오 가속기 GUID, AMVAUncompDataInfo 구조 및 압축 버퍼 형식의 수를 전달하여 비디오 가속기 GUID에서 사용하는 압축된 데이터 버퍼의 각 형식에 해당하는 AMVACompBufferInfo 데이터 구조 집합을 반환합니다.

    • AMVAUncompDataInfo 구조체에는 압축되지 않은 디코딩된 데이터의 너비와 높이(픽셀)와 압축되지 않은 그림의 DDPIXELFORMAT이 포함됩니다.
    • 반환된 AMVACompBufferInfo 데이터 구조는 각각 다음을 포함합니다.
      • 특정 형식에 필요한 압축 버퍼 수입니다.

      • 만들 표면의 너비와 높이(실제 의미가 있거나 없을 수 있는 필드)입니다.

        참고

        압축된 버퍼에 대한 DirectDraw 표면 할당 작업은 현재 이러한 표면의 너비 또는 높이가 2^15보다 크거나 같을 수 있도록 제공하지 않지만, 이 제한을 위반하는 경우 표면 할당 호출이 지나치게 실패하지 않을 수 있습니다. 따라서 드라이버는 이러한 극단적인 크기를 방지하기 위해 압축된 버퍼 메모리에 대한 요청을 구조화할 수 있습니다. 예를 들어 width="1" 및 height="65536"을 사용하여 버퍼를 요청하는 대신 드라이버는 width="1024" 및 height="64"의 버퍼를 요청해야 합니다.

         

      • 표면에서 사용할 총 바이트 수입니다.

      • 압축된 데이터를 저장할 표면을 만드는 기능을 설명하는 DirectDrawSurface 개체를 정의하는 DDSCAPS2 형식의 구조체입니다.

      • 압축된 데이터를 저장하는 표면을 만드는 데 사용되는 픽셀 형식(실제 의미가 있거나 없을 수 있는 필드)을 설명하는 DDPIXELFORMAT입니다.

참고

디코더의 IAMVideoAcceleratorNotify 인터페이스 메서드 중 일부에 대한 렌더러의 호출은 렌더러의 IPin::ReceiveConnection에 대한 디코더 호출 내에서 발생할 수 있습니다(일반적으로 발생). 특히 다음 사항에 적용됩니다.

 

참고

동적 형식 변경을 지원하기 위해 디코더는 필터가 연결되고 실행되는 동안 위의 IPin::ReceiveConnection 및 기타 메서드를 호출할 수도 있습니다. 이 기능은 동적 형식 변경을 지원하기 위해 제공됩니다(H.263, 부속서 P, 센스는 아니지만 모든 데이터 세트가 처음부터 다시 시작되고 참조 그림 정보가 손실되므로).

 

다음은 초기화 후 작업 중에 IAMVideoAccelerator 사용에 대한 설명입니다.

  1. 압축되지 않은 각 표면에 대해 디코더는 IAMVideoAccelerator::BeginFrame 을 호출하여 출력 그림을 만들기 위한 처리를 시작합니다. 이렇게 하면 디코더가 AMVABeginFrameInfo 구조를 보냅니다.

    • AMVABeginFrameInfo 구조에는 대상 버퍼에 대한 인덱스, 다운스트림으로 보낼 일부 데이터에 대한 포인터 및 액셀러레이터가 디코더가 읽을 일부 데이터를 넣을 수 있는 위치에 대한 포인터가 포함됩니다.

    • 참고 1: 가속기는 다운스트림으로 전환하기 전에 렌더러에서 변환하므로 대상 버퍼 인덱스가 실제로 수신되지 않습니다.

    • 참고 2: IAMVideoAccelerator::BeginFrameIAMVideoAccelerator::EndFrame 호출 간에 두 번 이상 호출할 수 있습니다.

    • 참고 3: 인터페이스 작업 내에서 비트스트림의 모든 개별 그림을 처리하기 위해 IAMVideoAccelerator::BeginFrameIAMVideoAccelerator::EndFrame 을 호출해야 한다는 가정은 없습니다.

      인터페이스에 관한 한 IAMVideoAccelerator::BeginFrame 이 수행하는 일은 렌더러 내에서 인덱스와 압축되지 않은 표면 간의 연결을 만드는 것입니다. 또한 디바이스 드라이버에서 특정 함수를 호출하는 방법을 제공합니다(디코더와 디바이스 드라이버 간에 임의 데이터를 주고 받는 방법을 지원함).

      (그러나 DirectX VA 작업에는 아래에 설명된 요구 사항이 있습니다. IAMVideoAccelerator::BeginFrameIAMVideoAccelerator::EndFrame 은 비트스트림의 모든 개별 그림을 처리하기 위해 호출해야 합니다.)

  2. 압축되지 않은 데이터를 가속기로 보내기 위해 디코더는 다음을 호출합니다.

    • IAMVideoAccelerator::QueryRenderStatus - 버퍼가 읽기 또는 쓰기에 안전한지 여부를 결정합니다.
    • IAMVideoAccelerator::GetBuffer 를 사용하여 지정된 버퍼에 대한 액세스를 잠그고 가져옵니다(이전에 이 버퍼를 호출하여 해당 액세스를 가져오지 않은 경우). GetBuffer 를 사용하여 IAMVideoAccelerator::BeginFrame 이 호출된 마지막 압축되지 않은 출력 그림의 내용 복사본을 가져올 수도 있습니다. 이 경우 대상 버퍼 인덱스에 대해 IAMVideoAccelerator::EndFrame 이 호출되지 않았습니다. DDI가 요청된 버퍼에 대한 DDERR_WASSTILLDRAWING 렌더링 상태 반환하는 경우 절전 모드 루프는 이 조건이 지워질 때까지 GetBuffer 내에서 작동합니다. GetBuffer를 호출하려면 디코더에 IAMVideoAccelerator::GetCompBufferInfo를 호출하여 가져온 AMVACompBufferInfo 데이터 구조의 일부 정보가 필요합니다.
    • IAMVideoAccelerator::ExecuteAMVABUFFERINFO 데이터 구조 배열에 표시된 대로 압축된 버퍼 집합의 데이터를 처리해야 함을 나타냅니다. 함수 코드 dwFunction은 이 호출에서 드라이버에 전달됩니다. lpPrivateInputData 포인터는 다운스트림을 보내기 위해 일부 데이터에도 전달되며, lpPrivateOutputData 포인터는 다운스트림 프로세스에서 디코더가 읽을 일부 데이터를 넣을 수 있는 위치로 전달됩니다.
    • IAMVideoAccelerator::ReleaseBuffer 는 디코더가 현재 지정된 버퍼 사용을 완료했으며 더 이상 버퍼에 대한 잠긴 액세스 권한이 필요하지 않음을 나타냅니다. (디코더가 버퍼를 계속 사용하려는 경우 지금은 IAMVideoAccelerator::ReleaseBuffer를 호출할 수 없으므로 실제로 버퍼를 더 이상 사용하지 않을 때까지 IAMVideoAccelerator::GetBuffer를 호출할 필요가 없습니다.) QueryRenderStatus가 버퍼를 쓰기에 안전하다고 표시할 때까지 Execute가 호출된 후에는 디코더가 버퍼에 기록되지 않아야 합니다.
  3. 대상 버퍼에 대한 출력 처리를 완료하기 위해 디코더는 IAMVideoAccelerator::EndFrame을 호출합니다. 이 호출을 사용하여 일부 임의 데이터 다운스트림을 전달할 수 있으며, 이는 기본적으로 이 호출의 결과로 발생하는 모든 것입니다. 이 호출에서는 대상 버퍼 인덱스가 전송되지 않으므로 전달된 임의의 데이터에 이 표시가 포함되지 않는 한 가속기에서 완료된 대상 버퍼를 정확하게 나타낼 수 없습니다.

  4. 프레임을 표시하기 위해 디코더는 표시할 프레임의 인덱스를 사용하여 IAMVideoAccelerator::D isplayFrame을 호출하고, 시작 및 중지 타임스탬프와 관련 플래그(예: AM_SAMPLE2_PROPERTIES 구조체의 dwTypeSpecificFlagsVIDEOINFOHEADER2 구조체의 dwInterlaceFlags)를 포함하는 IMediaSample 구조체를 호출합니다. 디코더는 DisplayFrame을 호출하기 전에 프레임의 콘텐츠에 영향을 주는 모든 압축 해제 작업이 완료되었는지 확인해야 합니다.

  5. 마지막으로 디코더는 모든 처리가 완료되면 IAMVideoAccelerator::EndFrame 을 호출하여 나머지 시작된 모든 출력 프레임의 완료를 나타내고, 릴리스되지 않은 각 버퍼에 대해 IAMVideoAccelerator::ReleaseBuffer 를 호출하여 잠긴 버퍼를 모두 해제해야 합니다.

디코더 인터페이스 및 사양