프레젠테이션 시계

프레젠테이션 시계는 프레젠테이션의 클록 시간을 생성하는 개체입니다. 프레젠테이션 시계에서 보고한 시간을 프레젠테이션 시간이라고 합니다. 프레젠테이션의 모든 스트림은 프레젠테이션 시간과 동기화됩니다. 프레젠테이션 시계는 다음 인터페이스를 노출합니다.

인터페이스 Description
IMFPresentationClock 프레젠테이션 클록을 사용하기 위한 기본 인터페이스입니다.
IMFRateControl 클록 속도를 제어합니다.
IMFTimer 타이머 콜백을 제공합니다.
IMFShutdown 프레젠테이션 시계를 종료합니다.

 

미디어 싱크는 프레젠테이션 시간을 사용하여 샘플을 렌더링할 시기를 예약합니다. 미디어 싱크가 새 샘플을 받을 때마다 샘플에서 타임스탬프를 가져오고 표시된 시간에 또는 가능한 한 가까운 시간에 샘플을 렌더링합니다. 토폴로지의 모든 미디어 싱크는 동일한 프레젠테이션 시계를 공유하므로 여러 스트림(예: 오디오 및 비디오)이 동기화됩니다. 미디어 원본 및 변환은 샘플을 배달할 시기를 예약하지 않으므로 프레젠테이션 시계를 사용하지 않습니다. 대신 파이프라인이 새 샘플을 요청할 때마다 샘플을 생성합니다.

재생에 미디어 세션을 사용하는 경우 미디어 세션은 프레젠테이션 시계를 만들고, 시간 원본을 선택하고, 미디어 싱크에 알리는 모든 세부 정보를 처리합니다. 애플리케이션은 재생 중에 프레젠테이션 시계를 사용하여 현재 프레젠테이션 시간을 가져올 수 있지만, 그렇지 않으면 프레젠테이션 시계에서 메서드를 호출하지 않습니다.

클록 시간 및 클록 상태

프레젠테이션 시계에서 최신 시계 시간을 얻으려면 IMFPresentationClock::GetTime을 호출합니다. 클록 시간은 항상 100나노초 단위이므로 1초는 10,000,000(10^7) 틱입니다. 이는 10MHz의 주파수에 해당합니다.

프레젠테이션 시계에는 실행 중, 일시 중지 및 중지됨의 세 가지 상태가 있습니다.

  • 클록을 실행하려면 IMFPresentationClock::Start를 호출합니다. Start 메서드는 클록의 시작 시간을 지정합니다. 클록이 실행되는 동안 클록 시간은 시작 시간부터 현재 클록 속도로 증가합니다.
  • 시계를 일시 중지하려면 IMFPresentationClock::P ause를 호출합니다. 클록이 일시 중지된 동안에는 클록 시간이 진행되지 않으며 GetTime은 시계가 일시 중지된 시간을 반환합니다.
  • 시계를 중지하려면 IMFPresentationClock::Stop을 호출합니다. 클록이 중지되면 클록 시간이 진행되지 않고 GetTime이 0을 반환합니다.

기본적으로 클록은 1.0의 속도로 진행되며, 이는 100나노초당 1틱을 의미합니다. 클록이 진행되는 속도를 변경하려면 IMFRateControl 인터페이스에 대한 프레젠테이션 시계를 쿼리하고 IMFRateControl::SetRate를 호출합니다.

개체는 프레젠테이션 시계에서 상태 변경(속도 변경 포함)에 대한 알림을 받을 수 있습니다. 알림을 받으려면 IMFClockStateSink 인터페이스를 구현하고 프레젠테이션 시계에서 IMFPresentationClock::AddClockStateSink 를 호출합니다. 종료하기 전에 IMFPresentationClock::RemoveClockStateSink 를 호출하여 개체의 등록을 취소합니다. 미디어 싱크는 이 메커니즘을 사용하여 시계에서 알림을 받습니다.

프레젠테이션 시간

미디어 싱크는 샘플이 올바른 시간에 렌더링되거나 가능한 한 올바른 시간에 가깝게 렌더링되도록 각 샘플을 예약하려고 합니다. 다음 정의가 적용됩니다.

  • 프레젠테이션 시간. 샘플을 렌더링해야 하는 시간입니다. 시간은 100나노초 단위로 제공됩니다.
  • 미디어 시간. 콘텐츠 시작 시간을 기준으로 합니다. 예를 들어 비디오 파일의 길이가 10초인 경우 파일의 중간 지점은 미디어 시간이 5초입니다.
  • 타임스탬프를 선택합니다. 미디어 샘플에 표시된 시간입니다. 타임스탬프를 얻으려면 IMFSample::GetSampleTime을 호출합니다. 미디어 원본이 샘플을 생성할 때 타임스탬프를 미디어 시간과 동일하게 설정합니다. 미디어 세션은 타임스탬프를 프레젠테이션 시간으로 변환합니다.

기본적으로 미디어 시간과 프레젠테이션 시간은 동일합니다. 예를 들어 비디오 프레임이 원본 파일에 5초 표시되면 미디어 시간과 프레젠테이션 시간은 모두 5초입니다. Sequencer 원본을 사용하는 경우 타이밍 모델이 다소 복잡하여 세그먼트 간 원활한 전환을 가능하게 합니다. 시퀀서 원본의 타이밍 모델에 대한 자세한 내용은 시퀀스 프레젠테이션 시간을 참조하세요.

미디어 원본은 항상 타임스탬프를 미디어 시간과 동일하게 설정합니다. 프레젠테이션 시간이 미디어 시간과 일치하지 않으면 미디어 세션은 미디어 샘플의 타임스탬프를 변환합니다. 싱크가 샘플을 받을 때까지 샘플의 타임스탬프는 프레젠테이션 시간으로 변환됩니다. 싱크는 프레젠테이션 시계의 현재 시간에 대해 샘플을 예약합니다. (빈도 없는 싱크는 프레젠테이션 시계를 무시하기 때문에 예외입니다.)

애플리케이션이 새 위치를 찾는 경우 미디어 세션은 지정된 검색 시간에 프레젠테이션 시계를 다시 시작합니다. 예를 들어 애플리케이션이 파일에서 5초 위치를 찾는 경우 미디어 세션은 5초에 시계를 시작합니다. 검색 시간이 키 프레임 경계에 속하지 않는 경우 미디어 원본은 약간 이전 타임스탬프를 사용하여 샘플을 제공할 수 있습니다. 디코더가 모든 프레임을 디코딩할 수 있도록 이 작업이 필요합니다. 미디어 세션은 요청된 검색 시간과 일치하도록 미디어 싱크에 도달하기 전에 샘플을 삭제하거나 트리밍합니다. 예를 들어 검색 시간이 5초인 경우 첫 번째 오디오 샘플은 4.5초에서 시작될 수 있습니다. 미디어 세션은 첫 번째 디코딩된 오디오 샘플에서 처음 0.5초를 잘라냅니다.

프레젠테이션 시계 만들기

프레젠테이션 시계를 만들려면 MFCreatePresentationClock을 호출합니다. 시계를 종료하려면 IMFShutdown 인터페이스를 쿼리하고 IMFShutdown::Shutdown을 호출합니다. MFCreatePresentationClock의 호출자는 Shutdown을 호출합니다. 대부분의 경우 애플리케이션이 아닌 미디어 세션입니다.

프레젠테이션 시간 원본

이름에도 불구하고 프레젠테이션 시계는 실제로 클록을 구현하지 않습니다. 대신 프레젠테이션 시간 원본이라는 다른 개체에서 시계 시간을 가져옵니다. 시간 원본은 정확한 클록 틱을 생성하고 IMFPresentationTimeSource 인터페이스를 노출하는 모든 개체일 수 있습니다. 다음 그림에서 이 프로세스를 나타냅니다.

프레젠테이션 시계와 프레젠테이션 시간 원본 간의 관계를 보여 주는 다이어그램

프레젠테이션 시계가 처음 만들어지면 시간 원본이 없습니다. 시간 원본을 설정하려면 시간 원본의 IMFPresentationTimeSource 인터페이스에 대한 포인터를 사용하여 IMFPresentationClock::SetTimeSource를 호출합니다. 시간 원본은 프레젠테이션 시계(실행, 일시 중지 및 중지)와 동일한 상태를 지원하며 IMFClockStateSink 인터페이스를 구현해야 합니다. 프레젠테이션 시계는 이 인터페이스를 사용하여 상태를 변경할 시기를 시간 원본에 알립니다. 이러한 방식으로 시간 원본은 클록 틱을 제공하지만 프레젠테이션 클록은 클록의 상태 변경을 시작합니다.

일부 미디어 싱크는 정확한 시계에 액세스할 수 있으므로 IMFPresentationTimeSource 인터페이스를 노출합니다. 특히 오디오 렌더러는 사운드 카드 주파수를 시계로 사용할 수 있습니다. 오디오 재생에서는 오디오 렌더러가 시간 원본 역할을 하여 비디오가 오디오 재생 속도와 동기화되도록 하는 것이 유용합니다. 이는 일반적으로 오디오를 외부 클록과 일치시키려는 것보다 더 나은 결과를 생성합니다.

또한 Media Foundation은 시스템 시계에 따라 프레젠테이션 시간 원본을 제공합니다. 이 개체를 만들려면 MFCreateSystemTimeSource를 호출합니다. 시간 원본을 제공하는 미디어 싱크가 없는 경우 시스템 시간 원본을 사용할 수 있습니다.

일반적으로 미디어 싱크는 프레젠테이션 시계에서 사용하는 시간 원본에 관계없이 제공된 프레젠테이션 시계를 사용해야 합니다. 이 규칙은 미디어 싱크가 IMFPresentationTimeSource를 구현하는 경우에도 적용됩니다. 프레젠테이션 시계에서 다른 시간 원본을 사용하는 경우 미디어 싱크는 자체 내부 시계가 아닌 해당 시간 원본을 따라야 합니다.

미디어 싱크가 프레젠테이션 시계를 따르지 않는 두 가지 상황이 있습니다.

  • 일부 미디어 싱크는 속도가 없습니다. 미디어 싱크가 속도가 빠를 경우 프레젠테이션 시계에 따라 예약하지 않고 가능한 한 빨리 샘플을 사용합니다. 일반적으로 속도 없는 싱크는 파일에 데이터를 기록하므로 가능한 한 빨리 작업을 완료하는 것이 좋습니다. 속도 없는 싱크는 IMFMediaSink::GetCharacteristics 메서드에서 MEDIASINK_RATELESS 플래그를 반환합니다. 토폴로지의 모든 싱크가 속도 없는 경우 미디어 세션은 가능한 한 빨리 파이프라인을 통해 데이터를 푸시합니다.

  • 일부 미디어 싱크는 자체 이외의 시간 원본과 속도를 일치시킬 수 없습니다. 이 경우 싱크는 GetCharacteristics 메서드에서 MEDIASINK_CANNOT_MATCH_CLOCK 플래그를 반환합니다. 파이프라인은 여전히 다른 시간 원본을 사용할 수 있지만 결과는 최적이 아닌 것입니다. 싱크가 뒤처지고 재생 중에 결함이 발생할 수 있습니다.

Media Foundation Platform API