Real-time Streams
Real-time timestmaps
Mediapipe calculator 그래프는 interactive 어플리케이션을 위한 비디오 또는 오디오 프레임의 스트림을 처리하는 데 자주 사용됩니다. Mediapipe 프레임워크는 연속적 패킷에 단조롭게 증가하는 타임스탬프를 할당하기만 하면 됩니다. 관례에 따라 실시간 Calculator와 그래프는 기록 시간 또는 각 프레임의 표시 시간을 타임스탬프로 사용하며, 각 타임스탬프는 1월 1일 이후 마이크로초를 나타냅니다.
Real-time shceduling
일반적으로 각 Calculator는 주어진 타임스탬프에 대한 모든 입력 패킷을 사용할 수 있게 되는 즉시 실행됩니다. 일반적으로 이것은 Calculator가 이전 프레임 처리를 완료하고 입력을 생성하는 각 Calculator가 현재 프레임 처리를 완료했을 때 발생합니다. Mediapipe 스케쥴러는 이러한 조건이 충족되는 즉시 각 Calculator를 호출합니다.
Timestamp bounds
Calculator가 주어진 타임스탬프에 대해 출력 패킷을 생성하지 않으면 대신 해당 타임스탬프에 대해 패킷이 새성되지 않음을 나타내는 Timestamp bounds를 출력할 수 있습니다. 이 표시는 해당 타임스탬프의 특정 스트림에 대해 패킷이 도착하지 않은 경우에도 다운스트림 Calculator가 해당 타임스탬프에서 실행되도록 하는데 필요합니다. 이는 각 계산기가 가능한 한 빨리 처리를 시작하는 것이 중요한 interactive 어플리케이션의 실시간 그래프에 특히 중요합니다.
그래프가 다음을 따름을 생각하십시오.
node {
calculator : "A"
input_stream : "alpha_in"
output_stream : "alpha"
}
node {
calculator : "B"
input_stream : "alpha"
input_stream : "foo"
output_stream : "beta"
}
가정 : 타임스탬프 T
에서 노드 A
는 출력 스틀미 알파로 패킷을 보내지 않습니다. 노드 B
는 타임스탬프 T
에서 foo
패킷을 받고 타임스탬프 T
에서 알파 패킷을 기다리고 있습니다. A
가 B
에게 알파에 대한 타임스탬프 바운드 업데이트를 보내지 않으면 B
는 패킷이 알파로 도착할 때까지 계속 기다립니다. 한편, foo
패킷 큐는 T
, T+1
등에서 패킷을 누적합니다.
스트림에서 패킷을 출력하기 위해 Calcualtor는 API 함수 CalculatorContext::Outputs
및 OutputStream::Add
를 사용합니다. 대신 스트림에 바인딩된 타임스탬프를 출력하기 위해 Calculator는 API 함수 CalculatorContext::Outputs
및 CalcualtorContext::SetNextTimestmapBound
를 사용할 수 있습니다. 지정된 경계는 지정된 출력 스트림 다음 패킷에 대해 허용되는 가장 낮은 타임스탬프입니다. 패킷이 출력되지 않으면 Calcualtor는 일반적으로 다음과 같은 작업을 수행합니다.
cc->Outputs().Tag("output_frame").SetNextTimestampBound(
cc->InputTimestamp().NextAllowedInStream());
Timestamp::NextAllowedInStream
함수는 연속적인 타임스탬프를 반환합니다. ex) Timestamp(1).NextAllowedInStream() == Timestamp(2)
Propagating timestamp bound
실시간 그래프에 사용되는 Calculator는 다운스트림 Calculator를 즉시 예약할 수 있도록 입력 타임스탬프 경계를 기반으로 출력 타임스탬프 경게를 정의해야 합니다. 일반적 패턴은 Calculator가 입력 패킷과 동일한 타임스탬프를 가진 패킷을 출력하는 것입니다. 이 경우 Calcualtor::Process
를 호출할 때마다 패킷을 출력하는 것만으로도 출력 타임스탬프 경계를 정의하기에 충분합니다.
그러나 Calculator는 출력 타임스탬프에 대해 이 일반적 패턴을 따를 필요가 없으며 단조롭게 증가하는 출력 타임스탬프를 선택하기만 하면 됩니다. 결과적으로 특정 Calculator는 타임스탬프 경계를 명시적으로 계산해야 합니다. MediaPipe는 각 계산기에 대한 적절한 타임스탬프 경계를 계산하기 위한 여러 도구를 제공합니다.
- SetNextTimestampBound() 는 출력 스트림에 대해 타임스탬프 경계
t+1
을 지정하는 데 사용할 수 있습니다.
cc->Outputs.Tag("OUT").SetNextTimestampBound(t.NextAllowedInStream());
또는 타임스탬프가 t
인 빈 패킷을 생성해 타임스탬프 경계 t+1
을 지정할 수 있습니다.
cc->Outputs.Tag("OUT").Add(Packet(), t);
입력 스트림의 타임스탬프 경계는 패킷 또는 입력 스트림 빈 패킷으로 표시됩니다.
Timestamp bound = cc->Inputs().Tag("IN").Value().Timestamp();
- TimestampOffset() 입력 스트림에서 출력 스트림으로 바인딩된 타임스탬프를 자동으로 복사하기 위해 지정할 수 있습니다.
cc->SetTimestampOffset(0);
- ProcessTimestampBounds() 는 각각 새로운 정착된 타임스탬프 (현재 타임스탬프 경계 아래 새로운 최고 타임스태믚)에 대해
Calculator::Process
를 호출하기 위해 지정할 수 있습니다. ProcessTimestampBoudns() 가 없으면Calculator::Process
는 하나 이상의 도착 패킷으로만 호출됩니다.
cc->SetProcessTimestampBounds(true);
이 설정을 사용하면 입력 타임스탬프만 업데이트된 경우에도 Calculator가 자체 타임스탬프 경계 계산 및 전파를 수행할 수 있습니다. TimestampOffset()
의 효과를 복제하는 데 사용할 수 있지만 추가 요소를 고려하는 타임스탬프 경계를 계산하는 데 사용할 수도 있습니다.
예를 들어, SetTimestampOffset(0)
을 복제하기 위해 Calculator는 다음을 수행할 수 있습니다.
absl::Status Open(CalculatorContext* cc) {
cc->SetProcessTimestampBounds(true);
}
absl::Status Process(CalculatorContext* cc) {
cc->Outputs.Tag("OUT").SetNextTimestampBound(
cc->InputTimestamp().NextAllowedInStream());
}
Scheduling of Calculator::Open and Calculator::Close
Calculator::Open
은 필요한 모든 사이드 패킷이 생성되면 호출됩니다. 입력 사이드 패킷은 인클로징 어플리케이션 또는 그래프 내부의 사이드 패킷 Calculator 에서 제공할 수 있습니다.
API의 CalculatorGraph::Initialize
및 CalculatorGraph::StartRun
을 사용해 그래프 외부에서 사이드 패킷을 지정할 수 있습니다.CalculatorGraphConfig::OutputSidePackets
및 OutputSidePacket::Set
을 사용해 그래프 내 Calculator에서 사이드 패킷을 지정할 수 있습니다.
CalculatorGraph::Close
는 모든 입력 스트림이 닫히거나 타임스탬프 바운드 Timestamp::Done
에 도달하여 Done
이 되면 호출됩니다.
참고 : 그래프가 보류 중인 모든 Calculator 실행을 완료하고 완료되면 일부 스트림이 완료되기 전에 MediaPipe가 Calculator::Close
에 대한 나머지 호출을 호출해 모든 Calculator가 최종 출력을 생성할 수 있도록 합니다.
TimestampOffset
을 사용하면 Calculator::Close
에 몇 가지 의미가 생깁니다. SetTimestampOffset(0)
을 지정하는 Calculator는 모든 입력 스트림이 Timestamp::Done
에 도달했을 때 모든 출력 스트림이 TimeStamp::Done
에 도달했음을 신호로 표시하므로 더 이상의 출력이 불가능합니다. 이렇게 하면 이러한 Calculator가 Calculator::Close
동안 패킷을 내보내는 것을 방지할 수 있습니다. Calculator가 Calculator::Close
중에 요약 패킷을 생성해야 하는 경우 Calculator::Process
는 Calculator::Close
중에 최소한 하나의 타임스탬프를 사용할 수 있도록 타임스탬프 경계를 지정해야 합니다. 즉, 이러한 Calculator는 일반적으로 SetTimestampOffset(0)
에 의존할 수 없으며 대신 SetNextTimestampBounds()
를 사용해 명시적으로 타임스탬프 경계를 지정해야 합니다.
'AI > Mediapipe' 카테고리의 다른 글
Mediapipe Framework Concepts - Synchronization (0) | 2021.12.06 |
---|---|
Mediapipe Framework Concepts - Packets (0) | 2021.12.06 |
Mediapipe Framework Concepts - Graphs (0) | 2021.12.06 |
Mediapipe Framework Concepts - Calculators (0) | 2021.12.06 |