MFT와 DMO 비교

MFT(Media Foundation 변환)는 DMO(DirectX Media Objects)를 사용하여 처음 도입된 변환 모델의 진화입니다. 이 항목에서는 MFT가 DMO와 다른 기본 방법을 요약합니다. DMO 인터페이스에 이미 익숙하거나 기존 DMO를 MFT로 변환하려는 경우 이 항목을 읽어보세요.

이 항목에는 다음과 같은 섹션이 포함되어 있습니다.

스트림 수

DMO에는 고정된 개수의 스트림이 있지만 MFT는 동적 개수의 스트림을 지원할 수 있습니다. 클라이언트는 입력 스트림을 추가할 수 있으며 MFT는 처리 중에 새 출력 스트림을 추가할 수 있습니다. 그러나 동적 스트림을 지원하려면 MFT가 필요하지 않습니다. MFT는 DMO와 마찬가지로 고정된 개수의 스트림을 가질 수 있습니다.

다음 메서드는 MFT에서 동적 스트림을 지원하는 데 사용됩니다.

또한 IMFTransform::P rocessOutput 메서드는 출력 스트림을 추가하거나 제거하는 동작을 정의합니다.

DMO에는 고정 스트림이 있으므로 DMO의 스트림은 0부터 시작하는 인덱스 값을 사용하여 식별됩니다. 반면 MFT는 인덱스 값에 반드시 해당하지 않는 스트림 식별자를 사용합니다. MFT의 스트림 수가 변경될 수 있기 때문입니다. 예를 들어 스트림 0이 제거되어 스트림 1이 첫 번째 스트림으로 남을 수 있습니다. 그러나 고정된 개수의 스트림이 있는 MFT는 DMO와 동일한 규칙을 준수하고 스트림 식별자에 인덱스 값을 사용해야 합니다.

형식 협상

MFT는 IMFMediaType 인터페이스를 사용하여 미디어 형식을 설명합니다. 그렇지 않으면 MFT와의 형식 협상은 DMO와 동일한 기본 원칙에서 작동합니다. 다음 표에는 DMO에 대한 형식 협상 메서드 및 MFT에 대한 해당 메서드가 나열되어 있습니다.

DMO 메서드 MFT 메서드
IMediaObject::GetInputCurrentType IMFTransform::GetInputCurrentType
IMediaObject::GetInputMaxLatency IMFTransform::GetInputStreamInfo
IMediaObject::GetInputSizeInfo IMFTransform::GetInputStreamInfo
IMediaObject::GetInputType IMFTransform::GetInputAvailableType
IMediaObject::GetOutputCurrentType IMFTransform::GetOutputCurrentType
IMediaObject::GetOutputSizeInfo IMFTransform::GetOutputStreamInfo
IMediaObject::GetOutputType IMFTransform::GetOutputAvailableType

 

스트리밍

DMO와 마찬가지로 MFT는 ProcessInputProcessOutput 메서드에 대한 호출을 통해 데이터를 처리합니다. 다음은 데이터를 스트리밍할 때 DMO와 MFT 프로세스 간의 주요 차이점입니다.

리소스 할당

MFT에는 DMO와 함께 사용되는 IMediaObject::AllocateStreamingResourcesIMediaObject::FreeStreamingResources 메서드가 없습니다. 리소스 할당 및 할당을 효율적으로 처리하기 위해 MFT는 IMFTransform::P rocessMessage 메서드의 다음 메시지에 응답할 수 있습니다.

또한 클라이언트는 다음 메시지로 ProcessMessage 를 호출하여 스트림의 시작과 끝을 알릴 수 있습니다.

이 두 메시지에는 정확한 DMO가 없습니다.

데이터 처리

MFT는 미디어 샘플을 사용하여 입력 및 출력 데이터를 저장합니다. 미디어 샘플은 IMFSample 인터페이스를 노출하고 다음 데이터를 포함합니다.

IMFMediaBuffer 인터페이스는 DMO IMediaBuffer 인터페이스와 유사합니다. 기본 메모리 버퍼에 액세스하려면 IMFMediaBuffer::Lock을 호출합니다. 이 메서드는 DMO용 IMediaBuffer::GetBufferAndLength 와 거의 동일합니다.

압축되지 않은 비디오 데이터의 경우 미디어 버퍼가 IMF2DBuffer 인터페이스를 지원할 수도 있습니다. 압축되지 않은 비디오(입력 또는 출력)를 처리하는 MFT는 버퍼가 노출되는 경우 IMF2DBuffer 인터페이스를 사용하도록 준비해야 합니다. 자세한 내용은 압축되지 않은 비디오 버퍼를 참조하세요.

Media Foundation은 IMFMediaBuffer의 몇 가지 표준 구현을 제공하므로 일반적으로 고유한 구현을 작성할 필요가 없습니다. Media Foundation 버퍼에서 DMO 버퍼를 만들려면 MFCreateLegacyMediaBufferOnMFMediaBuffer를 호출합니다.

플러싱

MFT에는 Flush 메서드가 없습니다. MFT를 플러시하려면 MFT_MESSAGE_COMMAND_FLUSH 메시지를 사용하여IMFTransform::P rocessMessage를 호출합니다.

스트림 불연속성

MFT에는 불연속성 메서드가 없습니다. 스트림에서 불연속성을 알리려면 입력 샘플에서 MFSampleExtension_Discontinuity 특성을 설정합니다.

기타 차이점

다음은 MFT와 DMO 간의 몇 가지 사소한 차이점입니다.

플래그

다음 표에는 다양한 DMO 플래그와 해당 MFT에 해당하는 항목이 나열되어 있습니다. DMO 플래그가 MFT 플래그에 직접 매핑할 때마다 두 플래그 모두 동일한 숫자 값을 갖습니다. 그러나 일부 DMO 플래그에는 정확한 MFT 등가 항목이 없으며 그 반대의 경우도 마찬가지입니다.

ProcessInput 플래그

DMO: _DMO_INPUT_DATA_BUFFER_FLAGS 열거형입니다.

MFT: 동등한 열거형이 없습니다.

DMO 플래그 MFT 플래그
DMO_INPUT_DATA_BUFFERF_SYNCPOINT 동등한 플래그가 없습니다. 대신 샘플에서 MFSampleExtension_CleanPoint 특성을 설정합니다.
DMO_INPUT_DATA_BUFFERF_TIME 동등한 플래그가 없습니다. 대신 샘플에서 IMFSample::SetSampleTime 을 호출합니다.
DMO_INPUT_DATA_BUFFERF_TIMELENGTH 동등한 플래그가 없습니다. 대신 샘플에서 IMFSample::SetSampleDuration 을 호출합니다.

 

ProcessOutput 플래그

DMO: _DMO_PROCESS_OUTPUT_FLAGS 열거형입니다.

MFT: _MFT_PROCESS_OUTPUT_FLAGS 열거형입니다.

DMO 플래그 MFT 플래그
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER

 

DMO: _DMO_OUTPUT_DATA_BUFFER_FLAGS 열거형입니다.

MFT: _MFT_OUTPUT_DATA_BUFFER_FLAGS 열거형입니다.

DMO 플래그 MFT 플래그
DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT 동등한 플래그가 없습니다. 대신 샘플에서 MFSampleExtension_CleanPoint 특성에 대한 검사.
DMO_OUTPUT_DATA_BUFFERF_TIME 동등한 플래그가 없습니다. 대신 샘플에서 IMFSample::GetSampleTime 을 호출합니다.
DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH 동등한 플래그가 없습니다. 대신 샘플에서 IMFSample::GetSampleDuration 을 호출합니다.
DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
동등한 플래그가 없습니다. MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
동등한 플래그가 없습니다. MFT_OUTPUT_DATA_BUFFER_STREAM_END
동등한 플래그가 없습니다. MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE

 

GetInputStatus 플래그

DMO: _DMO_INPUT_STATUS_FLAGS 열거형입니다.

MFT: _MFT_INPUT_STATUS_FLAGS 열거형입니다.

DMO 플래그 MFT 플래그
DMO_INPUT_STATUSF_ACCEPT_DATA MFT_INPUT_STATUS_ACCEPT_DATA

 

GetOutputStatus 플래그

DMO: 동등한 열거형이 없습니다.

MFT: _MFT_OUTPUT_STATUS_FLAGS 열거형입니다.

DMO 플래그 MFT 플래그
동등한 플래그가 없습니다. MFT_OUTPUT_STATUS_SAMPLE_READY

 

GetInputStreamInfo 플래그

DMO: _DMO_INPUT_STREAM_INFO_FLAGS 열거형입니다.

MFT: _MFT_INPUT_STREAM_INFO_FLAGS 열거형입니다.

DMO 플래그 MFT 플래그
DMO_INPUT_STREAMF_WHOLE_SAMPLES MFT_INPUT_STREAM_WHOLE_SAMPLES
DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
DMO_INPUT_STREAMF_HOLDS_BUFFERS MFT_INPUT_STREAM_HOLDS_BUFFERS
동등한 플래그가 없습니다. MFT_INPUT_STREAM_DOES_NOT_ADDREF
동등한 플래그가 없습니다. MFT_INPUT_STREAM_REMOVABLE
동등한 플래그가 없습니다. MFT_INPUT_STREAM_OPTIONAL

 

GetOutputStreamInfo 플래그

DMO: _DMO_OUTPUT_STREAM_INFO_FLAGS 열거형입니다.

MFT: _MFT_OUTPUT_STREAM_INFO_FLAGS 열거형입니다.

DMO 플래그 MFT 플래그
DMO_OUTPUT_STREAMF_WHOLE_SAMPLES MFT_OUTPUT_STREAM_WHOLE_SAMPLES
DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
DMO_OUTPUT_STREAMF_DISCARDABLE MFT_OUTPUT_STREAM_DISCARDABLE
DMO_OUTPUT_STREAMF_OPTIONAL MFT_OUTPUT_STREAM_OPTIONAL
동등한 플래그가 없습니다. MFT_OUTPUT_STREAM_PROVIDES_SAMPLES
동등한 플래그가 없습니다. MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
동등한 플래그가 없습니다. MFT_OUTPUT_STREAM_LAZY_READ
동등한 플래그가 없습니다. MFT_OUTPUT_STREAM_REMOVABLE

 

SetInputType/SetOutputType 플래그

DMO: _DMO_SET_TYPE_FLAGS 열거형입니다.

MFT: _MFT_SET_TYPE_FLAGS 열거형입니다.

DMO 플래그 MFT 플래그
DMO_SET_TYPEF_TEST_ONLY MFT_SET_TYPE_TEST_ONLY
DMO_SET_TYPEF_CLEAR 동등한 플래그가 없습니다. 대신 미디어 형식을 NULL 로 설정하여 미디어 형식을 지웁

 

오류 코드

다음 표에서는 DMO 오류 코드를 MFT 오류 코드에 매핑하는 방법을 보여 줍니다. 하이브리드 MFT/DMO 개체는 IMediaObject 메서드의 DMO 오류 코드와 IMFTransform 메서드의 MFT 오류 코드를 반환해야 합니다. DMO 오류 코드는 헤더 파일 MediaErr.h에 정의되어 있습니다. MFT 오류 코드는 헤더 파일 mferror.h에 정의되어 있습니다.

DMO 오류 코드 MFT 오류 코드
DMO_E_INVALIDTYPE MF_E_INVALIDTYPE
DMO_E_INVALIDSTREAMINDEX MF_E_INVALIDSTREAMNUMBER
DMO_E_NOTACCEPTING MF_E_NOTACCEPTING
DMO_E_NO_MORE_ITEMS MF_E_NO_MORE_TYPES
DMO_E_TYPE_NOT_ACCEPTED MF_E_INVALIDMEDIATYPE
DMO_E_TYPE_NOT_SET MF_E_TRANSFORM_TYPE_NOT_SET

 

하이브리드 DMO/MFT 개체 만들기

IMFTransform 인터페이스는 DMO(DirectX Media Objects)의 기본 인터페이스인 IMediaObject를 기반으로 합니다. 두 인터페이스를 모두 노출하는 개체를 만들 수 있습니다. 그러나 인터페이스에 동일한 이름을 공유하는 몇 가지 메서드가 있기 때문에 이로 인해 명명 충돌이 발생할 수 있습니다. 다음 두 가지 방법 중 하나로 이 문제를 해결할 수 있습니다.

해결 방법 1: MFT 함수를 포함하는 .cpp 파일의 맨 위에 다음 줄을 포함합니다.

#define MFT_UNIQUE_METHOD_NAMES

이렇게 하면 대부분의 메서드 이름이 "MFT" 접두사로 지정되도록 IMFTransform 인터페이스의 선언이 변경됩니다. 따라서 IMFTransform::P rocessInputIMFTransform::MFTProcessInput이 되고 IMediaObject::P rocessInput 은 원래 이름을 유지합니다. 이 기술은 기존 DMO를 하이브리드 DMO/MFT로 변환하는 경우에 가장 유용합니다. DMO 메서드를 변경하지 않고 새 MFT 메서드를 추가할 수 있습니다.

해결 방법 2: C++ 구문을 사용하여 둘 이상의 인터페이스에서 상속된 이름을 구분합니다. 예를 들어 다음과 같이 ProcessInput 의 MFT 버전을 선언합니다.

CMyHybridObject::IMFTransform::ProcessInput(...)

다음과 같이 ProcessInput의 DMO 버전을 선언합니다.

CMyHybridObject::IMediaObject::ProcessInput(...)

개체 내에서 메서드를 내부 호출하는 경우 이 구문을 사용할 수 있지만 이렇게 하면 메서드의 가상 상태 재정의됩니다. 개체 내부에서 호출하는 더 좋은 방법은 다음과 같습니다.

hr = ((IMediaObject*)this)->ProcessInput(...)

이렇게 하면 CMyHybridObject 에서 다른 클래스를 파생하고 CMyHybridObject::IMediaObject::P rocessInput 메서드를 재정의하면 올바른 가상 메서드가 호출됩니다. DMO 인터페이스는 DirectShow SDK 설명서에 설명되어 있습니다.

Media Foundation 변환