5단계. 이미지 변환
[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngine 및 Media Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드에서 DirectShow 대신 MediaPlayer, IMFMediaEngine 및 오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]
변환 필터 작성 자습서의 5단계입니다.
업스트림 필터는 변환 필터의 입력 핀에서 IMemInputPin::Receive 메서드를 호출하여 미디어 샘플을 변환 필터에 제공합니다. 데이터를 처리하기 위해 변환 필터는 순수 가상인 Transform 메서드를 호출합니다. CTransformFilter 및 CTransInPlaceFilter 클래스는 이 메서드의 두 가지 버전을 사용합니다.
- CTransformFilter::Transform 은 입력 샘플에 대한 포인터와 출력 샘플에 대한 포인터를 사용합니다. 필터가 메서드를 호출하기 전에 입력 샘플의 샘플 속성을 타임스탬프를 포함한 출력 샘플로 복사합니다.
- CTransInPlaceFilter::Transform 은 입력 샘플에 대한 포인터를 사용합니다. 필터는 현재 위치에 있는 데이터를 수정합니다.
Transform 메서드가 S_OK 반환하는 경우 필터는 샘플 다운스트림을 제공합니다. 프레임을 건너뛰려면 S_FALSE 반환합니다. 스트리밍 오류가 있는 경우 오류 코드를 반환합니다.
다음 예제에서는 RLE 인코더가 이 메서드를 구현하는 방법을 보여줍니다. 사용자 고유의 구현은 필터의 수행에 따라 상당히 다를 수 있습니다.
HRESULT CRleFilter::Transform(IMediaSample *pSource, IMediaSample *pDest)
{
// Get pointers to the underlying buffers.
BYTE *pBufferIn, *pBufferOut;
hr = pSource->GetPointer(&pBufferIn);
if (FAILED(hr))
{
return hr;
}
hr = pDest->GetPointer(&pBufferOut);
if (FAILED(hr))
{
return hr;
}
// Process the data.
DWORD cbDest = EncodeFrame(pBufferIn, pBufferOut);
KASSERT((long)cbDest <= pDest->GetSize());
pDest->SetActualDataLength(cbDest);
pDest->SetSyncPoint(TRUE);
return S_OK;
}
이 예제에서는 EncodeFrame이 RLE 인코딩을 구현하는 프라이빗 메서드라고 가정합니다. 인코딩 알고리즘 자체는 여기에 설명되어 있지 않습니다. 자세한 내용은 플랫폼 SDK 설명서의 "비트맵 압축" 항목을 참조하세요.
먼저 IMediaSample::GetPointer 를 호출하여 기본 버퍼의 주소를 검색합니다. 프라이빗 EncoderFrame 메서드에 전달합니다. 그런 다음 IMediaSample::SetActualDataLength 를 호출하여 인코딩된 데이터의 길이를 지정합니다. 다운스트림 필터에는 버퍼를 제대로 관리할 수 있도록 이 정보가 필요합니다. 마지막으로 메서드는 IMediaSample::SetSyncPoint 를 호출하여 키 프레임 플래그를 TRUE로 설정합니다. 런 길이 인코딩은 델타 프레임을 사용하지 않으므로 모든 프레임은 키 프레임입니다. 델타 프레임의 경우 값을 FALSE로 설정합니다.
고려해야 할 다른 문제는 다음과 같습니다.
타임스탬프를 선택합니다. CTransformFilter 클래스는 Transform 메서드를 호출하기 전에 출력 샘플을 타임스탬프합니다. 타임스탬프를 수정하지 않고 입력 샘플에서 타임스탬프를 복사합니다. 필터에서 타임스탬프를 변경해야 하는 경우 출력 샘플에서 IMediaSample::SetTime 을 호출합니다.
변경 내용의 서식을 지정합니다. 업스트림 필터는 미디어 형식을 샘플에 연결하여 스트림 중간 형식을 변경할 수 있습니다. 이렇게 하기 전에 필터의 입력 핀에서 IPin::QueryAccept 를 호출합니다. CTransformFilter 클래스에서 CheckInputType을 호출한 다음 CheckTransform을 호출합니다. 다운스트림 필터는 동일한 메커니즘을 사용하여 미디어 형식을 변경할 수도 있습니다. 사용자 고유의 필터에는 watch 두 가지가 있습니다.
- QueryAccept가 잘못된 동의를 반환하지 않는지 확인합니다.
- 필터가 형식 변경을 수락하는 경우 IMediaSample::GetMediaType을 호출하여 Transform 메서드 내에서 검사. 해당 메서드가 S_OK 반환하는 경우 필터는 형식 변경에 응답해야 합니다.
자세한 내용은 동적 형식 변경을 참조하세요.
스레드. CTransformFilter와 CTransInPlaceFilter 모두에서 변환 필터는 Receive 메서드 내에서 동기적으로 출력 샘플을 제공합니다. 필터는 데이터를 처리하는 작업자 스레드를 만들지 않습니다. 일반적으로 변환 필터가 작업자 스레드를 만들 이유가 없습니다.
관련 항목