미디어 싱크
미디어 싱크 미디어 데이터를 수신하는 파이프라인 개체입니다. 미디어 싱크는 하나 이상의 미디어 스트림에 대한 대상입니다. 미디어 싱크는 다음 두 가지 일반적인 범주로 분류됩니다.
렌더러 재생용 데이터를 제공하는 미디어 싱크입니다. 향상된 비디오 렌더러(EVR)는 비디오 프레임을 표시하고 오디오 렌더러는 사운드 카드 또는 기타 오디오 장치를 통해 오디오 스트림을 재생합니다.
보관 싱크 파일 또는 다른 스토리지에 데이터를 쓰는 미디어 싱크입니다.
둘 사이의 주요 차이점은 보관 싱크가 고정 재생 속도로 데이터를 사용하지 않는다는 것입니다. 대신 가능한 한 빨리 수신하는 데이터를 씁니다.
미디어 싱크는 IMFMediaSink 인터페이스를 노출합니다. 각 미디어 싱크에는 하나 이상의 스트림 싱크가. 각 스트림 싱크는 하나의 스트림에서 데이터를 받습니다. 스트림 싱크는 IMFStreamSink 인터페이스를 노출합니다. 일반적으로 애플리케이션은 미디어 싱크를 직접 만들지 않습니다. 대신 애플리케이션은 하나 이상의 활성화 개체를 만듭니다. 이 개체는 미디어 세션에서 싱크를 만드는 데 사용합니다. 싱크의 다른 모든 작업은 미디어 세션에서 처리되며 애플리케이션은 미디어 싱크 또는 스트림 싱크에서 메서드를 호출하지 않습니다. 활성화 개체에 대한 자세한 내용은 활성화 개체참조하세요.
사용자 지정 미디어 싱크를 작성하거나 미디어 세션 없이 미디어 싱크를 직접 사용하려는 경우 이 항목의 나머지 부분을 읽어야 합니다.
스트림 싱크
미디어 싱크에는 고정된 개수의 스트림 싱크가 있거나 스트림 싱크 추가 및 제거를 지원할 수 있습니다. 고정된 수의 스트림 싱크가 있는 경우 IMFMediaSink::GetCharacteristics 메서드는 MEDIASINK_FIXED_STREAMS 플래그를 반환합니다. 그렇지 않으면 스트림 싱크를 추가하고 제거할 수 있습니다. 새 스트림 싱크를 추가하려면 IMFMediaSink::AddStreamSink호출합니다. 스트림 싱크를 제거하려면 IMFMediaSink::RemoveStreamSink호출합니다. MEDIASINK_FIXED_STREAMS 플래그는 미디어 싱크가 이러한 두 가지 메서드를 지원하지 않음을 나타냅니다. (예를 들어 싱크를 만들 때 초기화 매개 변수를 설정하여 스트림 수를 구성하는 다른 방법을 지원할 수 있습니다.) 스트림 싱크 목록이 정렬됩니다. 인덱스 값으로 열거하려면 IMFMediaSink::GetStreamSinkByIndex 메서드를 호출합니다.
스트림 싱크에는 식별자도 있습니다. 스트림 식별자는 미디어 싱크 내에서 고유하지만 연속될 필요는 없습니다. 미디어 싱크에 따라 스트림 식별자는 콘텐츠와 관련된 의미를 가질 수 있습니다. 예를 들어 보관 싱크는 스트림 식별자를 파일 헤더에 쓸 수 있습니다. 그렇지 않으면 임의입니다. 식별자를 통해 스트림 싱크를 얻으려면 IMFMediaSink::GetStreamSinkById호출합니다.
프레젠테이션 시계
미디어 싱크에서 샘플을 사용하는 속도는 프레젠테이션 클록의해 제어됩니다. 미디어 세션은 프레젠테이션 시계를 선택하고 미디어 싱크의 IMFMediaSink::SetPresentationClock 메서드를 호출하여 미디어 싱크에서 설정합니다. 스트리밍을 시작하려면 먼저 미디어 싱크에서 프레젠테이션 시계를 설정해야 합니다. 모든 미디어 싱크를 실행하려면 프레젠테이션 시계가 필요합니다. 미디어 싱크는 다음 두 가지 용도로 프레젠테이션 시계를 사용합니다.
스트리밍이 시작되거나 중지될 때 알림을 받으려면 미디어 싱크는 모든 미디어 싱크가 구현해야 하는 IMFClockStateSink 인터페이스를 통해 이러한 알림을 받습니다.
샘플을 렌더링해야 하는 시기를 결정합니다. 미디어 싱크가 새 샘플을 받으면 샘플에서 타임스탬프를 가져오고 해당 프레젠테이션 시간에 샘플을 렌더링하려고 시도합니다.
프레젠테이션 시계는 프레젠테이션 시간 원본다른 개체에서 해당 시계 시간을 파생합니다. 프레젠테이션 시간 원본은 IMFPresentationTimeSource 인터페이스를 노출합니다. 일부 미디어 싱크는 정확한 시계에 액세스할 수 있으므로 이 인터페이스를 노출합니다. 즉, 미디어 싱크는 자체 시계에서 제공하는 시간에 대해 샘플을 예약할 수 있습니다. 그러나 미디어 싱크는 이를 사례로 간주할 수 없습니다. 프레젠테이션 시계가 미디어 싱크 자체에 의해 구동되는지 또는 다른 시계에 의해 구동되는지에 관계없이 항상 프레젠테이션 시계의 시간을 사용해야 합니다.
미디어 싱크가 자체 클록이 아닌 다른 클록과 속도를 일치시킬 수 없는 경우 GetCharacteristics 메서드는 MEDIASINK_CANNOT_MATCH_CLOCK 플래그를 반환합니다. 이 플래그가 있고 프레젠테이션 시계가 다른 프레젠테이션 시간 원본을 사용하는 경우 미디어 싱크의 성능이 저조할 수 있습니다. 예를 들어 재생 중에 결함이 발생할 수 있습니다.
속도 없는 싱크는 샘플의 타임스탬프를 무시하고 각 샘플이 도착하는 즉시 데이터를 사용하는 미디어 싱크입니다. 속도 없는 미디어 싱크는 GetCharacteristics 메서드에서 MEDIASINK_RATELESS 플래그를 반환합니다. 일반적으로 이 플래그는 보관 싱크에 적용됩니다. 파이프라인의 모든 미디어 싱크가 속도 없는 경우 미디어 세션에서는 특별한 속도 없는 프레젠테이션 시계를 사용합니다. 이 클록은 싱크에서 샘플을 사용하는 만큼 빠르게 실행됩니다.
스트림 형식
미디어 싱크가 샘플을 수신하려면 먼저 클라이언트가 스트림 싱크에서 미디어 형식을 설정해야 합니다. 미디어 형식을 설정하려면 스트림 싱크의 IMFStreamSink::GetMediaTypeHandler 메서드를 호출합니다. 이 메서드는 IMFMediaTypeHandler 인터페이스에 대한 포인터를 반환합니다. 이 인터페이스를 사용하여 기본 설정 미디어 형식 목록을 가져와 현재 미디어 형식을 가져와 미디어 형식을 설정합니다.
기본 설정 미디어 형식 목록을 얻으려면 IMFMediaTypeHandler::GetMediaTypeByIndex호출합니다. 기본 설정 형식은 클라이언트에 대한 힌트로 사용해야 합니다. 목록이 불완전하거나 부분 미디어 형식을 포함할 수 있습니다. 부분 미디어 형식은 유효한 형식을 설명하는 데 필요한 모든 특성이 없는 형식입니다. 예를 들어 부분 비디오 형식은 색 공간과 비트 깊이를 지정할 수 있지만 이미지 너비나 높이는 지정할 수 없습니다. 부분 오디오 유형은 압축 형식과 샘플 속도를 지정할 수 있지만 오디오 채널 수는 지정할 수 없습니다.
스트림 싱크의 현재 미디어 형식을 얻으려면 IMFMediaTypeHandler::GetCurrentMediaType호출합니다. 스트림 싱크를 처음 만들 때 기본 미디어 형식이 이미 설정되었거나 클라이언트에서 미디어 형식을 설정할 때까지 미디어 형식이 없을 수 있습니다.
미디어 유형을 설정하려면 IMFMediaTypeHandler::SetCurrentMediaType호출합니다. 일부 스트림 싱크는 설정된 후 형식 변경을 지원하지 않을 수 있습니다. 따라서 미디어 형식을 설정하기 전에 테스트하는 것이 유용합니다. 미디어 싱크가 미디어 형식을 허용할지 여부를 테스트하려면(형식을 설정하지 않고) IMFMediaTypeHandler::IsMediaTypeSupported호출합니다.
데이터 흐름
미디어 싱크는 끌어오기 모델사용합니다. 즉, 스트림 싱크는 필요할 때 데이터를 요청합니다. 클라이언트는 오류가 발생하지 않도록 적시에 응답해야 합니다.
일부 미디어 싱크는 사전 등록지원합니다. 미리 등록은 프레젠테이션 시계가 시작되기 전에 미디어 싱크에 데이터를 제공하는 프로세스입니다. 미디어 싱크가 사전 등록을 지원하는 경우 미디어 싱크는 IMFMediaSinkPreroll 인터페이스를 노출하고 GetCharacteristics 메서드는 MEDIASINK_CAN_PREROLL 플래그를 반환합니다. 미리 등록하면 프레젠테이션 시계가 시작될 때 미디어 싱크가 첫 번째 샘플을 표시할 준비가 됩니다. 재생 중에 결함이나 간격을 방지할 수 있으므로 미디어 싱크에서 지원하는 경우 클라이언트가 항상 미리 등록하는 것이 좋습니다.
미디어 싱크로의 데이터 흐름은 다음과 같이 작동합니다.
- 클라이언트는 미디어 형식 및 프레젠테이션 시계를 설정합니다. 미디어 싱크는 프레젠테이션 클록에 자신을 등록하여 클록 상태 변경에 대한 알림을 받습니다.
- 필요에 따라 IMFMediaSinkPreroll에 대한 클라이언트 쿼리는. 미디어 싱크가 이 인터페이스를 노출하는 경우 클라이언트는 IMFMediaSinkPreroll::NotifyPreroll호출합니다. 그렇지 않으면 클라이언트가 5단계로 건너뜁니다.
- 각 스트림 싱크는 하나 이상의 MEStreamSinkRequestSample 이벤트를 보냅니다. 이러한 각 이벤트에 대한 응답으로 클라이언트는 해당 스트림에 대한 다음 데이터 샘플을 가져오고 IMFStreamSink::P rocessSample호출합니다.
- 각 스트림 싱크가 충분한 사전 등록 데이터를 수신하면 MEStreamSinkPrerolled 이벤트를 보냅니다.
- 클라이언트는 IMFPresentationClock::Start 호출하여 프레젠테이션 시계를 시작합니다.
- 프레젠테이션 시계는 IMFClockStateSink::OnClockStart호출하여 시계가 시작되고 있음을 미디어 싱크에 알깁니다.
- 더 많은 데이터를 가져오기 위해 각 스트림 싱크는 MEStreamSinkRequestSample 이벤트를 보냅니다. 이러한 각 이벤트에 대한 응답으로 클라이언트는 다음 샘플을 가져오고 ProcessSample호출합니다. 이 단계는 프레젠테이션이 끝날 때까지 반복됩니다.
대부분의 미디어 싱크는 샘플을 비동기적으로 처리하므로 스트림 싱크는 한 번에 둘 이상의 샘플 요청을 보낼 수 있습니다.
스트리밍하는 동안 클라이언트는 언제든지 IMFStreamSink::P laceMarker 호출하고 IMFStreamSink::Flush수 있습니다. 표식은 다음 섹션에서 설명합니다. 플러시하면 스트림 싱크가 큐에 대기되었지만 아직 렌더링되지 않은 샘플을 삭제합니다.
마커
표식은 클라이언트가 스트림의 특정 지점을 나타내는 방법을 제공합니다. 표식은 다음 정보로 구성됩니다.
- MFSTREAMSINK_MARKER_TYPE 열거형의 멤버로 정의된 표식 형식입니다.
- 표식과 연결된 데이터입니다. 데이터의 의미는 표식 형식에 따라 달라집니다. 일부 표식 형식에는 데이터가 없습니다.
- 클라이언트 고유의 용도에 대한 선택적 데이터입니다.
마커를 배치하기 위해 클라이언트는 IMFStreamSink::P laceMarker호출합니다. 스트림 싱크는 PlaceMarker 호출 전에 받은 샘플 처리를 완료한 다음 MEStreamSinkMarker 이벤트를 보냅니다.
대부분의 미디어 싱크는 보류 중인 샘플 큐를 유지하며 비동기적으로 처리됩니다. 마커 이벤트는 샘플 처리로 직렬화되어야 하므로 미디어 싱크는 마커를 동일한 큐에 배치해야 합니다. 예를 들어 클라이언트가 다음 메서드 호출을 수행한다고 가정합니다.
- ProcessSample(샘플 #1)
- ProcessSample(샘플 #2)
- PlaceMarker(표식 #1)
- ProcessSample(샘플 #3)
- PlaceMarker(표식 #2)
이 예제에서 스트림 싱크는 샘플 #2를 처리한 후 마커 #1에 대한 MEStreamSinkMarker 이벤트와 샘플 #3을 처리한 후 표식 #2에 대한 이벤트를 보내야 합니다.
클라이언트가 스트림 싱크를 플러시하는 경우 스트림 싱크는 큐에 있던 마커를 즉시 처리합니다. 이러한 이벤트에 E_ABORT 상태 코드를 설정합니다.
일부 표식에는 미디어 싱크와 관련된 정보가 포함됩니다.
- MFSTREAMSINK_MARKER_TICK: 스트림에 간격이 있음을 나타냅니다. 다음 샘플은 불연속성입니다.
- MFSTREAMSINK_MARKER_ENDOFSEGMENT: 세그먼트의 끝 또는 스트림의 끝을 나타냅니다. 다음 샘플(있는 경우)은 불연속성일 수 있습니다.
- MFSTREAMSINK_MARKER_EVENT: 이벤트를 포함합니다. 미디어 싱크의 이벤트 유형 및 구현에 따라 미디어 싱크에서 이벤트를 처리하거나 무시할 수 있습니다.
상태 변경 내용
미디어 싱크는 미디어 싱크의 IMFClockStateSink 인터페이스를 통해 프레젠테이션 시계의 상태 변경 내용을 알 수 있습니다. 클라이언트가 프레젠테이션 시계를 설정하면 미디어 싱크가 IMFPresentationClock::AddClockStateSink 호출하여 시계의 알림에 등록합니다. 다음 표에서는 클록 상태 변경에 대한 응답으로 미디어 싱크가 동작하는 방법을 요약합니다.
클록 상태 변경 | 샘플 처리 | 표식 처리 |
---|---|---|
OnClockStart | 타임스탬프를 클록 시작 시간과 같거나 이후인 프로세스 샘플입니다. | 마커가 처리되기 전에 받은 모든 샘플이 처리되면 MEStreamSinkMarker 이벤트를 보냅니다. |
OnClockPause | 미디어 싱크는 일시 중지된 동안 ProcessSample실패할 수 있습니다. 미디어 싱크가 일시 중지된 동안 샘플을 수락하는 경우 클록이 다시 시작될 때까지 큐에 대기해야 합니다. 일시 중지된 동안에는 대기 중인 샘플을 처리하지 마세요. |
큐에 대기 중인 샘플이 있는 경우 동일한 큐에 마커를 배치합니다. 시계가 다시 시작될 때 표식 이벤트를 보냅니다. 그렇지 않으면 마커 이벤트를 즉시 보냅니다. |
OnClockRestart | 일시 중지된 동안 큐에 대기된 샘플을 처리한 다음 OnClockStart동일하게 처리합니다. | 큐에 대기 중인 마커에 대한 MEStreamSinkMarker 이벤트를 보낸 다음(샘플 처리로 직렬화) OnClockStart동일하게 처리합니다. |
OnClockStop | 큐에 대기된 모든 샘플을 삭제합니다. ProcessSample 대한 추가 호출은 실패할 수 있습니다. | 큐에 대기된 마커 이벤트를 보냅니다. PlaceMarker대한 후속 호출에서 마커 이벤트를 즉시 보냅니다. |
또한 스트림 싱크는 상태 전환을 완료했을 때 다음 이벤트를 보내야 합니다.
- OnClockStart, OnClockRestart: MEStreamSinkStarted 이벤트
- OnClockPause: MEStreamSinkPaused 이벤트
- OnClockStop: MEStreamSinkStopped 이벤트
마무리
일부 미디어 싱크는 마지막 샘플이 전달된 후 추가 처리 단계가 필요합니다. 일반적으로 이 요구 사항은 파일에 헤더 또는 인덱스를 작성해야 하는 보관 싱크에 적용됩니다. 미디어 싱크에 최종 처리가 필요한 경우 IMFFinalizableMediaSink 인터페이스를 노출합니다.
클라이언트가 마지막 샘플을 전달한 후 클라이언트는 이 인터페이스에 대해 쿼리합니다. 미디어 싱크가 인터페이스를 지원하는 경우 클라이언트는 IMFFinalizableMediaSink::BeginFinalize 호출하여 최종 처리를 비동기적으로 수행합니다. 이 메서드는 비동기 콜백 메서드설명된 표준 Media Foundation 비동기 모델을 따릅니다. 미디어 싱크는 클라이언트가 BeginFinalize호출한다고 가정할 수 있습니다. beginFinalize 호출하지 않으면 잘못 작성된 파일이 발생할 수 있습니다.
종료
클라이언트가 미디어 싱크를 사용하여 완료되면 클라이언트는 IMFMediaSink::Shutdown호출합니다. 이 메서드 내에서 미디어 싱크는 순환 참조 수를 중단해야 합니다. 일반적으로 미디어 싱크와 스트림 싱크 간에 순환 참조가 있습니다.
이벤트 큐 도우미 개체를 사용하여 IMFMediaEventGenerator구현하는 경우 이벤트 큐에서 IMFMediaEventQueue::Shutdown 호출합니다. 이 메서드는 이벤트 큐를 종료하고 현재 이벤트를 기다리고 있는 호출자에게 신호를 전송합니다.
종료 후 미디어 싱크의 모든 메서드는 IUnknown 메서드를 제외하고 MF_E_SHUTDOWN 반환합니다.
미디어 싱크 인터페이스
다음 표에서는 미디어 싱크가 QueryInterface통해 노출할 수 있는 표준 인터페이스를 나열합니다. 미디어 싱크는 사용자 지정 인터페이스를 노출할 수도 있습니다.
인터페이스 | 묘사 |
---|---|
IMFMediaSink | 미디어 싱크의 기본 인터페이스입니다. (필수) |
IMFClockStateSink | 프레젠테이션 클록 상태가 변경되면 미디어 싱크에 알리는 데 사용됩니다. (필수) |
IMFFinalizableMediaSink | 미디어 싱크가 최종 처리 단계를 수행해야 하는지를 구현합니다. (선택 사항) |
IMFGetService | 미디어 싱크가 서비스 인터페이스를 노출하는지를 구현합니다. (선택 사항) |
IMFMediaEventGenerator | 미디어 싱크에서 이벤트를 보내는 경우 구현합니다. (선택 사항) |
IMFMediaSinkPreroll | 미디어 싱크가 사전 등록을 지원하는지 구현합니다. (선택 사항) |
IMFPresentationTimeSource | 미디어 싱크가 프레젠테이션 시계에 대한 시간 원본을 제공할 수 있는지를 구현합니다. (선택 사항) |
IMFQualityAdvise | 미디어 싱크가 재생 품질을 조정할 수 있는지를 구현합니다. (선택 사항) |
필요에 따라 미디어 싱크는 다음 인터페이스를 서비스로 구현할 수 있습니다.
서비스 인터페이스 | 묘사 |
---|---|
IMFRateSupport | 지원되는 재생 속도의 범위를 보고합니다. |
서비스 인터페이스 및 IMFGetService대한 자세한 내용은 서비스 인터페이스참조하세요.
스트림 싱크 인터페이스
스트림 싱크는 QueryInterface통해 다음 인터페이스를 노출해야 합니다.
인터페이스 | 묘사 |
---|---|
IMFStreamSink | 스트림 싱크의 기본 인터페이스입니다. (필수) |
IMFMediaEventGenerator | 이벤트를 큐에 대기합니다. IMFStreamSink 인터페이스는 이 인터페이스를 상속합니다. (필수) |
현재 스트림 싱크에 대해 정의된 서비스 인터페이스는 없습니다.
싱크 이벤트 스트림
다음 표에서는 제네릭 스트림 싱크에 대해 정의된 이벤트를 나열합니다. 스트림 싱크는 여기에 나열되지 않은 사용자 지정 이벤트를 보낼 수도 있습니다.
이벤트 | 묘사 |
---|---|
MEStreamSinkFormatChanged | 스트림 싱크의 미디어 형식이 더 이상 유효하지 않습니다. (선택 사항) |
MEStreamSinkMarker | 표식이 처리되었습니다. (필수) |
meStreamSinkPaused | 스트림 싱크가 일시 중지되었습니다. (필수) |
meStreamSinkPrerolled | 사전 등록이 완료되었습니다. (선택 사항) |
MEStreamSinkRateChanged | 스트림 싱크의 재생 속도가 변경되었습니다. (선택 사항) |
MEStreamSinkRequestSample | 새 샘플이 요청됩니다. (필수) |
MEStreamSinkScrubSampleComplete | 스크럽 요청이 완료되었습니다. (선택 사항) |
meStreamSinkStarted | 스트림 싱크가 시작되었습니다. (필수) |
MEStreamSinkStopped | 스트림 싱크가 중지되었습니다. (필수) |
현재 미디어 싱크에 대한 범용 이벤트는 정의되지 않습니다. 일부 미디어 싱크는 사용자 지정 이벤트를 보낼 수 있습니다.
관련 항목