Adding more Jitter data points
This commit is contained in:
Родитель
811ccd6a32
Коммит
e6428da53d
|
@ -104,7 +104,7 @@ namespace ctsTraffic {
|
|||
void PrintException(const std::exception& e) NOEXCEPT
|
||||
{
|
||||
}
|
||||
void PrintJitterUpdate(long long _sequence_number, long long _sender_qpc, long long _sender_qpf, long long _recevier_qpc, long long _receiver_qpf) NOEXCEPT
|
||||
void PrintJitterUpdate(const JitterFrameEntry& current_frame, const JitterFrameEntry& previous_frame, const JitterFrameEntry& first_frame) NOEXCEPT
|
||||
{
|
||||
}
|
||||
void PrintErrorInfo(_In_z_ _Printf_format_string_ LPCWSTR _text, ...) NOEXCEPT
|
||||
|
|
|
@ -104,7 +104,7 @@ namespace ctsTraffic {
|
|||
void PrintException(const std::exception& e) NOEXCEPT
|
||||
{
|
||||
}
|
||||
void PrintJitterUpdate(long long _sequence_number, long long _sender_qpc, long long _sender_qpf, long long _recevier_qpc, long long _receiver_qpf) NOEXCEPT
|
||||
void PrintJitterUpdate(const JitterFrameEntry& current_frame, const JitterFrameEntry& previous_frame, const JitterFrameEntry& first_frame) NOEXCEPT
|
||||
{
|
||||
}
|
||||
void PrintErrorInfo(_In_z_ _Printf_format_string_ LPCWSTR _text, ...) NOEXCEPT
|
||||
|
|
|
@ -2446,7 +2446,7 @@ namespace ctsTraffic {
|
|||
}
|
||||
|
||||
if (s_JitterLogger && s_JitterLogger->IsCsvFormat()) {
|
||||
s_JitterLogger->LogMessage(L"SequenceNumber,SenderQpc,SenderQpf,ReceiverQpc,ReceiverQpf\r\n");
|
||||
s_JitterLogger->LogMessage(L"SequenceNumber,SenderQpc,SenderQpf,ReceiverQpc,ReceiverQpf,PriorReceiveDelta,EstReceivedDgramInFlight\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2723,10 +2723,24 @@ namespace ctsTraffic {
|
|||
}
|
||||
}
|
||||
|
||||
void PrintJitterUpdate(long long _sequence_number, long long _sender_qpc, long long _sender_qpf, long long _recevier_qpc, long long _receiver_qpf) NOEXCEPT
|
||||
void PrintJitterUpdate(const JitterFrameEntry& current_frame, const JitterFrameEntry& previous_frame, const JitterFrameEntry& first_frame) NOEXCEPT
|
||||
{
|
||||
if (!s_ShutdownCalled) {
|
||||
if (s_JitterLogger) {
|
||||
long ms_since_prior_receive = 0;
|
||||
// calculate time since the prior receive
|
||||
if (previous_frame.receiver_qpc != 0) {
|
||||
ms_since_prior_receive = static_cast<long>(((current_frame.receiver_qpc * 1000LL) / current_frame.receiver_qpf) - ((previous_frame.receiver_qpc * 1000LL) / previous_frame.receiver_qpf));
|
||||
}
|
||||
|
||||
// estimating time in flight for this frame by determining how much time since the first send was just 'waiting' to send this frame
|
||||
// and subtracing that from how much time since the first receive - since time between receives should at least be time between sends
|
||||
long ms_estimated_time_in_flight = 0;
|
||||
if (first_frame.receiver_qpc != 0) {
|
||||
long ms_since_first_receive = static_cast<long>(((current_frame.receiver_qpc * 1000LL) / current_frame.receiver_qpf) - ((first_frame.receiver_qpc * 1000LL) / first_frame.receiver_qpf));
|
||||
long ms_since_first_send = static_cast<long>(((current_frame.sender_qpc * 1000LL) / current_frame.sender_qpf) - ((first_frame.sender_qpc * 1000LL) / first_frame.sender_qpf));
|
||||
ms_estimated_time_in_flight = ms_since_first_receive - ms_since_first_send;
|
||||
}
|
||||
// long long ~= up to 20 characters long, plus 5 for commas & CR
|
||||
static const size_t formatted_text_length = (20 * 5) + 5;
|
||||
wchar_t formatted_text[formatted_text_length];
|
||||
|
@ -2735,12 +2749,12 @@ namespace ctsTraffic {
|
|||
formatted_text,
|
||||
formatted_text_length,
|
||||
_TRUNCATE,
|
||||
L"%lld,%lld,%lld,%lld,%lld\r\n",
|
||||
_sequence_number, _sender_qpc, _sender_qpf, _recevier_qpc, _receiver_qpf);
|
||||
L"%lld,%lld,%lld,%lld,%lld,%ld,%ld\r\n",
|
||||
current_frame.sequence_number, current_frame.sender_qpc, current_frame.sender_qpf, current_frame.receiver_qpc, current_frame.receiver_qpf, ms_since_prior_receive, ms_estimated_time_in_flight);
|
||||
ctl::ctFatalCondition(
|
||||
-1 == converted,
|
||||
L"_snwprintf_s failed to convert Jitter information: %lld, %lld, %lld, %lld, %lld",
|
||||
_sequence_number, _sender_qpc, _sender_qpf, _recevier_qpc, _receiver_qpf);
|
||||
L"_snwprintf_s failed to convert Jitter information: %lld, %lld, %lld, %lld, %lld, %ld, %ld",
|
||||
current_frame.sequence_number, current_frame.sender_qpc, current_frame.sender_qpf, current_frame.receiver_qpc, current_frame.receiver_qpf, ms_since_prior_receive, ms_estimated_time_in_flight);
|
||||
s_JitterLogger->LogMessage(formatted_text);
|
||||
}
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -102,48 +102,48 @@ namespace ctsTraffic {
|
|||
|
||||
/// OR
|
||||
inline
|
||||
OptionType operator| (OptionType& _lhs, OptionType _rhs)
|
||||
OptionType operator| (OptionType& lhs, OptionType rhs)
|
||||
{
|
||||
return OptionType(static_cast<unsigned long>(_lhs) | static_cast<unsigned long>(_rhs));
|
||||
return OptionType(static_cast<unsigned long>(lhs) | static_cast<unsigned long>(rhs));
|
||||
}
|
||||
inline
|
||||
OptionType& operator|= (OptionType& _lhs, OptionType _rhs)
|
||||
OptionType& operator|= (OptionType& lhs, OptionType rhs)
|
||||
{
|
||||
_lhs = _lhs | _rhs;
|
||||
return _lhs;
|
||||
lhs = lhs | rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/// AND
|
||||
inline
|
||||
OptionType operator& (OptionType _lhs, OptionType _rhs)
|
||||
OptionType operator& (OptionType lhs, OptionType rhs)
|
||||
{
|
||||
return OptionType(static_cast<unsigned long>(_lhs) & static_cast<unsigned long>(_rhs));
|
||||
return OptionType(static_cast<unsigned long>(lhs) & static_cast<unsigned long>(rhs));
|
||||
}
|
||||
inline
|
||||
OptionType& operator&= (OptionType& _lhs, OptionType _rhs)
|
||||
OptionType& operator&= (OptionType& lhs, OptionType rhs)
|
||||
{
|
||||
_lhs = _lhs & _rhs;
|
||||
return _lhs;
|
||||
lhs = lhs & rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/// XOR
|
||||
inline
|
||||
OptionType operator^ (OptionType _lhs, OptionType _rhs)
|
||||
OptionType operator^ (OptionType lhs, OptionType rhs)
|
||||
{
|
||||
return OptionType(static_cast<unsigned long>(_lhs) ^ static_cast<unsigned long>(_rhs));
|
||||
return OptionType(static_cast<unsigned long>(lhs) ^ static_cast<unsigned long>(rhs));
|
||||
}
|
||||
inline
|
||||
OptionType& operator^= (OptionType& _lhs, OptionType _rhs)
|
||||
OptionType& operator^= (OptionType& lhs, OptionType rhs)
|
||||
{
|
||||
_lhs = _lhs ^ _rhs;
|
||||
return _lhs;
|
||||
lhs = lhs ^ rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
/// NOT
|
||||
inline
|
||||
OptionType operator~ (OptionType _lhs)
|
||||
OptionType operator~ (OptionType lhs)
|
||||
{
|
||||
return OptionType(~static_cast<unsigned long>(_lhs));
|
||||
return OptionType(~static_cast<unsigned long>(lhs));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -166,9 +166,19 @@ namespace ctsTraffic {
|
|||
void PrintSettings();
|
||||
|
||||
void PrintLegend() NOEXCEPT;
|
||||
|
||||
struct JitterFrameEntry {
|
||||
long long sequence_number = 0LL;
|
||||
long long sender_qpc = 0LL;
|
||||
long long sender_qpf = 0LL;
|
||||
long long receiver_qpc = 0LL;
|
||||
long long receiver_qpf = 0LL;
|
||||
unsigned long received = 0UL;
|
||||
};
|
||||
void PrintJitterUpdate(const JitterFrameEntry& current_frame, const JitterFrameEntry& previous_frame, const JitterFrameEntry& first_frame) NOEXCEPT;
|
||||
|
||||
void PrintStatusUpdate() NOEXCEPT;
|
||||
void PrintJitterUpdate(long long _sequence_number, long long _sender_qpc, long long _sender_qpf, long long _recevier_qpc, long long _receiver_qpf) NOEXCEPT;
|
||||
void __cdecl PrintSummary(_In_z_ _Printf_format_string_ LPCWSTR _text, ...) NOEXCEPT;
|
||||
void __cdecl PrintSummary(_In_z_ _Printf_format_string_ LPCWSTR text, ...) NOEXCEPT;
|
||||
|
||||
// Putting PrintDebugInfo as a macro to avoid running any code for debug printing if not necessary
|
||||
#define PrintDebugInfo(fmt, ...) \
|
||||
|
@ -182,19 +192,19 @@ namespace ctsTraffic {
|
|||
} \
|
||||
}
|
||||
|
||||
void PrintErrorIfFailed(_In_ LPCWSTR _what, unsigned long _why) NOEXCEPT;
|
||||
void __cdecl PrintErrorInfo(_In_z_ _Printf_format_string_ LPCWSTR _text, ...) NOEXCEPT;
|
||||
void PrintErrorIfFailed(_In_ LPCWSTR what, unsigned long why) NOEXCEPT;
|
||||
void __cdecl PrintErrorInfo(_In_z_ _Printf_format_string_ LPCWSTR text, ...) NOEXCEPT;
|
||||
// Override will always print to console regardless of settings (important if can't even start)
|
||||
void __cdecl PrintErrorInfoOverride(_In_z_ _Printf_format_string_ LPCWSTR _text, ...) NOEXCEPT;
|
||||
void __cdecl PrintErrorInfoOverride(_In_z_ _Printf_format_string_ LPCWSTR text, ...) NOEXCEPT;
|
||||
|
||||
void PrintException(const std::exception& e) NOEXCEPT;
|
||||
// Override will always print to console regardless of settings (important if can't even start)
|
||||
void PrintExceptionOverride(const std::exception& e) NOEXCEPT;
|
||||
|
||||
void PrintNewConnection(const ctl::ctSockaddr& _local_addr, const ctl::ctSockaddr& _remote_addr) NOEXCEPT;
|
||||
void PrintConnectionResults(const ctl::ctSockaddr& _local_addr, const ctl::ctSockaddr& _remote_addr, unsigned long _error, const ctsTcpStatistics& _stats) NOEXCEPT;
|
||||
void PrintConnectionResults(const ctl::ctSockaddr& _local_addr, const ctl::ctSockaddr& _remote_addr, unsigned long _error, const ctsUdpStatistics& _stats) NOEXCEPT;
|
||||
void PrintConnectionResults(const ctl::ctSockaddr& _local_addr, const ctl::ctSockaddr& _remote_addr, unsigned long _error) NOEXCEPT;
|
||||
void PrintNewConnection(const ctl::ctSockaddr& local_addr, const ctl::ctSockaddr& remote_addr) NOEXCEPT;
|
||||
void PrintConnectionResults(const ctl::ctSockaddr& local_addr, const ctl::ctSockaddr& remote_addr, unsigned long error, const ctsTcpStatistics& stats) NOEXCEPT;
|
||||
void PrintConnectionResults(const ctl::ctSockaddr& local_addr, const ctl::ctSockaddr& remote_addr, unsigned long error, const ctsUdpStatistics& stats) NOEXCEPT;
|
||||
void PrintConnectionResults(const ctl::ctSockaddr& local_addr, const ctl::ctSockaddr& remote_addr, unsigned long error) NOEXCEPT;
|
||||
|
||||
// Get* functions
|
||||
ctsSignedLongLong GetTcpBytesPerSecond() NOEXCEPT;
|
||||
|
@ -208,8 +218,8 @@ namespace ctsTraffic {
|
|||
bool IsListening() NOEXCEPT;
|
||||
|
||||
// Set* functions
|
||||
int SetPreBindOptions(SOCKET _s, const ctl::ctSockaddr& _local_address);
|
||||
int SetPreConnectOptions(SOCKET _s);
|
||||
int SetPreBindOptions(SOCKET s, const ctl::ctSockaddr& local_address);
|
||||
int SetPreConnectOptions(SOCKET s);
|
||||
|
||||
// for the MediaStream pattern
|
||||
struct MediaStreamSettings {
|
||||
|
|
|
@ -594,15 +594,6 @@ namespace ctsTraffic {
|
|||
ctsIOPatternProtocolError completed_task(const ctsIOTask& _task, unsigned long _current_transfer) NOEXCEPT override;
|
||||
|
||||
private:
|
||||
struct FrameEntry {
|
||||
long long sequence_number = 0LL;
|
||||
long long sender_qpc = 0LL;
|
||||
long long sender_qpf = 0LL;
|
||||
long long receiver_qpc = 0LL;
|
||||
long long receiver_qpf = 0LL;
|
||||
unsigned long received = 0UL;
|
||||
};
|
||||
|
||||
// private member variables
|
||||
PTP_TIMER renderer_timer;
|
||||
PTP_TIMER start_timer;
|
||||
|
@ -625,14 +616,18 @@ namespace ctsTraffic {
|
|||
|
||||
// member variables that require the base lock
|
||||
_Requires_lock_held_(cs)
|
||||
std::vector<FrameEntry> frame_entries;
|
||||
std::vector<ctsConfig::JitterFrameEntry> frame_entries;
|
||||
|
||||
_Requires_lock_held_(cs)
|
||||
std::vector<FrameEntry>::iterator head_entry;
|
||||
std::vector<ctsConfig::JitterFrameEntry>::iterator head_entry;
|
||||
|
||||
// tracking for jitter information
|
||||
ctsConfig::JitterFrameEntry first_frame;
|
||||
ctsConfig::JitterFrameEntry previous_frame;
|
||||
|
||||
// member functions - all require the base lock
|
||||
_Requires_lock_held_(cs)
|
||||
std::vector<FrameEntry>::iterator find_sequence_number(long long _seq_number) NOEXCEPT;
|
||||
std::vector<ctsConfig::JitterFrameEntry>::iterator find_sequence_number(long long _seq_number) NOEXCEPT;
|
||||
|
||||
_Requires_lock_held_(cs)
|
||||
bool received_buffered_frames() NOEXCEPT;
|
||||
|
|
|
@ -303,7 +303,7 @@ namespace ctsTraffic {
|
|||
/// If the sequence number was not found, will return end(frame_entries)
|
||||
///
|
||||
_Requires_lock_held_(cs)
|
||||
vector<ctsIOPatternMediaStreamClient::FrameEntry>::iterator ctsIOPatternMediaStreamClient::find_sequence_number(long long _seq_number) NOEXCEPT
|
||||
vector<ctsConfig::JitterFrameEntry>::iterator ctsIOPatternMediaStreamClient::find_sequence_number(long long _seq_number) NOEXCEPT
|
||||
{
|
||||
ctsSignedLongLong head_sequence_number = this->head_entry->sequence_number;
|
||||
ctsSignedLongLong tail_sequence_number = head_sequence_number + this->frame_entries.size() - 1;
|
||||
|
@ -397,12 +397,14 @@ namespace ctsTraffic {
|
|||
static_cast<long long>(this->head_entry->sequence_number));
|
||||
|
||||
// Directly write this status update if jitter is enabled
|
||||
ctsConfig::PrintJitterUpdate(
|
||||
this->head_entry->sequence_number,
|
||||
this->head_entry->sender_qpc,
|
||||
this->head_entry->sender_qpf,
|
||||
this->head_entry->receiver_qpc,
|
||||
this->head_entry->receiver_qpf);
|
||||
ctsConfig::PrintJitterUpdate(*this->head_entry, this->previous_frame, this->first_frame);
|
||||
|
||||
// if this is the first frame, capture it
|
||||
if (this->first_frame.receiver_qpc == 0) {
|
||||
this->first_frame = *this->head_entry;
|
||||
}
|
||||
// always keep the most recently received frame for jitter
|
||||
this->previous_frame = *this->head_entry;
|
||||
|
||||
} else {
|
||||
ctsConfig::Settings->UdpStatusDetails.dropped_frames.increment();
|
||||
|
@ -411,6 +413,10 @@ namespace ctsTraffic {
|
|||
PrintDebugInfo(
|
||||
L"\t\tctsIOPatternMediaStreamClient **dropped** frame %lld\n",
|
||||
static_cast<long long>(this->head_entry->sequence_number));
|
||||
|
||||
// write and empty row
|
||||
ctsConfig::PrintJitterUpdate(ctsConfig::JitterFrameEntry(), ctsConfig::JitterFrameEntry(), ctsConfig::JitterFrameEntry());
|
||||
|
||||
}
|
||||
|
||||
// update the current sequence number so it's now the "end" sequence number of the queue (the new max value)
|
||||
|
|
Загрузка…
Ссылка в новой задаче