MFT와 DMO 비교
MFT(Media Foundation 변환)는 DMO(DirectX Media Objects)를 사용하여 처음 도입된 변환 모델의 진화입니다. 이 항목에서는 MFT가 DMO와 다른 기본 방법을 요약합니다. DMO 인터페이스에 이미 익숙하거나 기존 DMO를 MFT로 변환하려는 경우 이 항목을 읽어보세요.
이 항목에는 다음과 같은 섹션이 포함되어 있습니다.
스트림 수
DMO에는 고정된 개수의 스트림이 있지만 MFT는 동적 개수의 스트림을 지원할 수 있습니다. 클라이언트는 입력 스트림을 추가할 수 있으며 MFT는 처리 중에 새 출력 스트림을 추가할 수 있습니다. 그러나 동적 스트림을 지원하려면 MFT가 필요하지 않습니다. MFT는 DMO와 마찬가지로 고정된 개수의 스트림을 가질 수 있습니다.
다음 메서드는 MFT에서 동적 스트림을 지원하는 데 사용됩니다.
- IMFTransform::AddInputStreams
- IMFTransform::D eleteInputStream
- IMFTransform::GetStreamIDs
- IMFTransform::GetStreamLimits
또한 IMFTransform::P rocessOutput 메서드는 출력 스트림을 추가하거나 제거하는 동작을 정의합니다.
DMO에는 고정 스트림이 있으므로 DMO의 스트림은 0부터 시작하는 인덱스 값을 사용하여 식별됩니다. 반면 MFT는 인덱스 값에 반드시 해당하지 않는 스트림 식별자를 사용합니다. MFT의 스트림 수가 변경될 수 있기 때문입니다. 예를 들어 스트림 0이 제거되어 스트림 1이 첫 번째 스트림으로 남을 수 있습니다. 그러나 고정된 개수의 스트림이 있는 MFT는 DMO와 동일한 규칙을 준수하고 스트림 식별자에 인덱스 값을 사용해야 합니다.
형식 협상
MFT는 IMFMediaType 인터페이스를 사용하여 미디어 형식을 설명합니다. 그렇지 않으면 MFT와의 형식 협상은 DMO와 동일한 기본 원칙에서 작동합니다. 다음 표에는 DMO에 대한 형식 협상 메서드 및 MFT에 대한 해당 메서드가 나열되어 있습니다.
스트리밍
DMO와 마찬가지로 MFT는 ProcessInput 및 ProcessOutput 메서드에 대한 호출을 통해 데이터를 처리합니다. 다음은 데이터를 스트리밍할 때 DMO와 MFT 프로세스 간의 주요 차이점입니다.
리소스 할당
MFT에는 DMO와 함께 사용되는 IMediaObject::AllocateStreamingResources 및 IMediaObject::FreeStreamingResources 메서드가 없습니다. 리소스 할당 및 할당을 효율적으로 처리하기 위해 MFT는 IMFTransform::P rocessMessage 메서드의 다음 메시지에 응답할 수 있습니다.
또한 클라이언트는 다음 메시지로 ProcessMessage 를 호출하여 스트림의 시작과 끝을 알릴 수 있습니다.
이 두 메시지에는 정확한 DMO가 없습니다.
데이터 처리
MFT는 미디어 샘플을 사용하여 입력 및 출력 데이터를 저장합니다. 미디어 샘플은 IMFSample 인터페이스를 노출하고 다음 데이터를 포함합니다.
- 타임스탬프를 지정하고 기간을 지정합니다.
- 샘플별 정보를 포함하는 특성입니다. 특성 목록은 샘플 특성을 참조하세요.
- 미디어 버퍼가 0개 이상입니다. 각 미디어 버퍼는 IMFMediaBuffer 인터페이스를 노출합니다.
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는 없습니다.
집계를 지원하기 위해 MFT가 필요하지 않습니다.
MFT는 드레이닝이라는 작업을 지원합니다. 드레이닝의 목적은 MFT에 더 이상 입력 데이터를 제공하지 않고 MF에 남아 있는 모든 데이터를 처리하는 것입니다(예: 스트림의 끝에서). MFT를 드레이닝하려면 MFT_MESSAGE_COMMAND_DRAIN 메시지와 함께 IMFTransform::P rocessMessage를 호출합니다. 자세한 내용은 기본 MFT 처리 모델을 참조하세요.
MFT에는 스트림별 특성을 포함한 특성이 있을 수 있습니다. 다음 메서드를 사용하여 MFT에서 특성을 가져옵니다.
MFT는 이벤트를 처리할 수 있습니다. MFT에 이벤트를 보내려면 IMFTransform::P rocessEvent를 호출합니다. MFT는 ProcessOutput 메서드를 통해 클라이언트에 이벤트를 보낼 수 있습니다. 자세한 내용은 기본 MFT 처리 모델을 참조하세요.
플래그
다음 표에는 다양한 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 rocessInput 은 IMFTransform::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 설명서에 설명되어 있습니다.
관련 항목