실시간 스트림

실시간 타임스탬프

MediaPipe 계산기 그래프는 동영상 또는 오디오 스트림을 처리하는 데 자주 사용됩니다. 사용할 수 있습니다. MediaPipe 프레임워크에는 연속적인 패킷에는 단조 증가하는 타임스탬프가 할당됩니다. 작성자: 계산법, 실시간 계산기 및 그래프는 기록 시간 또는 각 프레임의 프레젠테이션 시간을 타임스탬프로, 각 타임스탬프는 다음을 나타냅니다. Jan/1/1970:00:00:00 이후의 마이크로초입니다. 이를 통해 다양한 전역적으로 일관된 순서로 처리할 수 있습니다.

실시간 예약

일반적으로 각 계산기는 해당 필드에 대한 모든 입력 패킷이 사용할 수 있게 됩니다. 일반적으로 계산기가 이전 프레임 처리를 완료하고 각 계산기는 입력이 현재 프레임 처리를 완료했음을 의미합니다. MediaPipe 스케줄러 는 조건이 충족되는 즉시 각 계산기를 호출합니다. 자세한 내용은 동기화를 참조하세요.

타임스탬프 경계

계산기는 주어진 타임스탬프에 대한 출력 패킷을 생성하지 않는 경우, 대신 '타임스탬프 경계'를 출력할 수 있습니다. 이는 수신 대기 중인 패킷이 생성됩니다. 이 표시는 다운스트림을 허용하는 해당 시간기록에서 실행되는 패킷이 도착하지 않았더라도 해당 타임스탬프의 특정 스트림을 시작합니다 이는 실시간 입찰의 양방향 응용 프로그램에서 그래프를 확인할 수 있으며, 각 계산기는 최대한 빨리 처리를 시작하세요

다음과 같은 그래프를 살펴보세요.

node {
   calculator: "A"
   input_stream: "alpha_in"
   output_stream: "alpha"
}
node {
   calculator: "B"
   input_stream: "alpha"
   input_stream: "foo"
   output_stream: "beta"
}

타임스탬프 T에 노드 A이(가) 출력 스트림에서 패킷을 보내지 않았다고 가정해 보겠습니다. alpha입니다. 노드 B이(가) T 타임스탬프에 foo의 패킷을 가져오고 T 타임스탬프에 있는 alpha의 패킷입니다. AB에 타임스탬프 경계를 전송하지 않는 경우 alpha 업데이트를 하면 B는 패킷이 alpha에 도착할 때까지 계속 대기합니다. 그동안 foo의 패킷 큐에는 T, T+1, 등등.

계산기는 스트림에 패킷을 출력하기 위해 API 함수를 사용합니다. CalculatorContext::OutputsOutputStream::Add 대신에 타임스탬프가 스트림에 적용되었다면 계산기는 API 함수와 CalculatorContext::OutputsCalculatorContext::SetNextTimestampBound 이 지정된 경계가 패킷의 다음 패킷에 대해 허용되는 가장 낮은 타임스탬프입니다. 지정할 수 있습니다. 패킷이 출력되지 않으면 계산기는 일반적으로 다음과 같이 하세요.

cc->Outputs().Tag("output_frame").SetNextTimestampBound(
  cc->InputTimestamp().NextAllowedInStream());

Timestamp::NextAllowedInStream 함수는 연속 타임스탬프를 반환합니다. 예를 들면 Timestamp(1).NextAllowedInStream() == Timestamp(2)입니다.

타임스탬프 경계 전파

실시간 그래프에 사용할 계산기는 출력을 정의해야 함 다운스트림을 허용하기 위해 입력 타임스탬프 경계를 기반으로 하는 타임스탬프 경계 계산기를 빨리 예약해야 했습니다. 일반적인 패턴은 입력 패킷과 동일한 타임스탬프로 출력 패킷을 보냅니다. 이 경우 모든 Calculator::Process 호출에서 패킷을 출력하는 것으로 충분합니다. 출력 타임스탬프 경계를 정의합니다.

하지만 계산기는 단조 증가하는 출력을 선택하기만 하면 타임스탬프 따라서 특정 계산기는 타임스탬프 경계를 계산해야 합니다. 명시적으로 초기화합니다. MediaPipe는 적절한 타임스탬프를 계산할 수 있는 여러 도구를 제공합니다. 결합되어야 합니다.

1. 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();

2. TimestampOffset()는 해당 타임 스탬프를 자동으로 복사하도록 지정할 수 있습니다. 입력 스트림에서 출력 스트림으로 결합된 타임스탬프입니다.

cc->SetTimestampOffset(0);

이 설정은 타임스탬프 경계를 자동으로 전파하는 이점이 있습니다. 타임스탬프 경계만 도착하고 계산기::프로세스가 호출되지 않는 경우에도 마찬가지입니다.

3. 호출을 위해 ProcessTimestampBounds()가 지정될 수 있습니다. 새로운 각 '정산된 타임스탬프'에 대해 Calculator::Process이며, 여기서 '정산된 타임스탬프'는 timestamp 는 현재 타임스탬프 경계 아래에 있는 새로운 최고 타임스탬프입니다. ProcessTimestampBounds()가 없으면 Calculator::Process는 다음 경우에만 호출됩니다. 수신 패킷을 보내는 데 사용됩니다.

cc->SetProcessTimestampBounds(true);

이 설정을 사용하면 계산기에서 타임스탬프 경계를 직접 계산할 수 있습니다. 및 전파에 사용될 수 있습니다. Kubernetes는 TimestampOffset()의 효과를 복제할 수 있지만 추가 요인을 고려하는 타임스탬프 경계를 계산합니다.

예를 들어 SetTimestampOffset(0)를 복제하기 위해 계산기는 다음을 수행하세요.

absl::Status Open(CalculatorContext* cc) {
  cc->SetProcessTimestampBounds(true);
}

absl::Status Process(CalculatorContext* cc) {
  cc->Outputs.Tag("OUT").SetNextTimestampBound(
      cc->InputTimestamp().NextAllowedInStream());
}

계산기 예약::열기 및 계산기::닫기

Calculator::Open는 필요한 모든 입력 사이드 패킷이 있습니다. 입력 사이드 패킷은 인클로징 애플리케이션 또는 "사이드 패킷 계산기" 찾을 수 있습니다. 사이드 패킷은 API의 CalculatorGraph::Initialize를 사용하여 그래프 외부에서 CalculatorGraph::StartRun입니다. 사이드 패킷은 네트워크 내부의 계산기를 통해 CalculatorGraphConfig::OutputSidePacketsOutputSidePacket::Set입니다.

계산기::Close는 모든 입력 스트림이 다음과 같이 Done가 되면 호출됩니다. 종료 중이거나 타임스탬프 경계 Timestamp::Done에 도달했습니다.

참고: 그래프가 대기 중인 계산기 실행을 모두 마치고 다음과 같이 되면 Done가 되기 전에 일부 스트림이 Done이 되면 MediaPipe가 모든 계산기가Calculator::Close 있습니다.

TimestampOffset를 사용하면 Calculator::Close에 몇 가지 영향을 미칩니다. 가 SetTimestampOffset(0)를 지정하는 계산기는 설계 시 모든 입력 스트림이 있을 때 출력 스트림이 Timestamp::Done에 도달함 Timestamp::Done에 도달하여 더 이상 출력이 불가능합니다. 이렇게 하면 이 계산기가 보내는 동안 패킷을 방출하지 못합니다. Calculator::Close 계산기가 계산을 수행하는 동안 요약 패킷을 생성해야 하는 경우 Calculator::Close, Calculator::Process는 타임스탬프 경계를 지정해야 합니다. 하나 이상의 타임스탬프 (예: Timestamp::Max)를 사용할 수 있는 상태로 유지됨 Calculator::Close 즉, 이러한 계산기는 일반적으로 SetTimestampOffset(0)이며 대신 타임스탬프 경계를 명시적으로 지정해야 합니다. (SetNextTimestampBounds() 사용)