2015-09-17 6 views
7

Я разработал серверное и клиентское приложение для потоковой передачи видеокадров с одного конца на другой с использованием RTSP. Теперь, чтобы собрать статистику, которая поможет мне улучшить мои приложения, мне нужно измерить прошедшее время между отправкой фрейма и получением кадра.Измерение истекшего времени по сети

На данный момент я использую следующую формулу:

Client_Receive_Timestamp - Server_Send_Timestamp = Elapsed_Time 

Проблема

Мне кажется, что время, прошедшее около 100-200ms слишком высоко. Я думаю, причина в том, что часы сервера и клиентские часы не синхронизированы и имеют разницу примерно в 100-200 мс.

Вопрос

Как я могу точно измерить время, прошедшее между двумя апаратов?

В статье Accurately measuring elapsed time between machines предлагается рассчитать задержку в оба конца. Однако я не могу использовать это решение, так как клиент не запрашивает фреймы. Он просто получает кадры через RTSP.

+0

Не могли бы вы пояснить, почему вы можете» t рассчитать задержку в оба конца? Вы вынуждены использовать поток RTSP в качестве единственного сетевого подключения? Если нет, вы можете использовать простые пинги по другому сетевому соединению, чтобы оценить время прохождения туда-обратно. –

+0

Используйте третью машину и подтвердите свои сомнения. – lsalamon

+0

@ LukasBoersma Моя цель - измерить, сколько времени требуется для доставки кадра, а не для определения того, сколько времени потребуется для отправки и получения одного пакета. – chrisp

ответ

4

Мне нужно измерить прошедшее время между отправкой кадра и получением кадра.

Для этого не нужны точные временные метки. Вы можете усреднить ожидаемую задержку.

Если A посылает пакет (или кадр), чтобы B, B реагирует немедленно (*):

(SENDTIME) ---> B ---> а (receivedTime)

, то вы можете рассчитать задержку легко:

latency = (receivedTime - sendTime)/2 

Это предполагает, конечно, что латентность является симметричным. Вы можете найти более сложные алгоритмы, если вы исследуете фразы «алгоритм оценки латентности сети».

Имея расчетную задержку вы можете разницу конечно время оценки (но это не представляется необходимым):

(SENDTIME) ---> B (receivedTimeB) - (receivedTimeB) -> A

timeDelta = sendTime + latency - receivedTimeB 

Обратите внимание, что даже если вы в среднем много результатов, этот алгоритм, вероятно, кабальный. Это просто опубликовано как простой пример общей идеи.


(*) Тот факт, что это не происходит на самом деле сразу же вызывает ошибку, конечно. Это зависит от того, насколько загружена машина B.

+0

Проблема в том, что я не могу просто ответить одним пакетом. Мне нужно будет ответить, отправив весь кадр обратно на сервер, потому что для переноса всего кадра (= нескольких пакетов) требуется больше времени. – chrisp

+1

@ Крис. Пакет «ping» здесь не имеет значения. Если вы можете сразу ответить B, не имеет значения, что вы отправляете.Вы можете делать точно такие же вычисления с использованием фреймов. Таким образом, вы можете выполнять измерения онлайн, передавая данные. Или, если вам нужно это сделать до начала передачи, вы можете использовать N пакетов различного размера и оценить, как быстро увеличивается латентность с размером пакета. Это позволит оценить латентность произвольного размера кадра. – BartoszKP

+0

Звучит неплохо. Однако решение, упомянутое в комментариях ниже вопроса, кажется более простым в реализации. – chrisp

5

Предполагая

, то вы можете просто вычтите «отправленную временную метку» из «полученной метки времени», чтобы получить продолжительность задержки. observed error будет меньше суммы обеих ошибок часов. Если временные шкалы достаточно малы (возможно, что-то меньше часа), вы можете разумно игнорировать эффекты slew.

Если ntpd еще не работает на обеих машинах, и если у вас есть необходимые разрешения, то вы можете

$ sudo ntpdate -v pool.ntp.org 

форсировать синхронизацию с пулом общедоступных серверов времени.

Затем вы можете использовать C++ 11 high_resolution_clock вычислить продолжительность:

/* hrc.cc */ 
#include <chrono> 
#include <iostream> 

int main(int,char**){ 
    using std::chrono::high_resolution_clock; 
    // send something                              
    high_resolution_clock::time_point start = high_resolution_clock::now(); 
    std::cout << "time this" << std::endl ; 
    // receive something                             
    high_resolution_clock::time_point stop = high_resolution_clock::now(); 
    std::cout 
    << "duration == " 
    << std::chrono::duration_cast<std::chrono::nanoseconds>(stop-start).count() 
    << "ns" 
    << std::endl 
    ; 
    return 0; 
} 

Вот что предыдущий пример выглядит на моей системе:

$ make hrc && ./hrc 
c++  hrc.cc -o hrc 
time this 
duration == 32010ns 
Смежные вопросы