diff --git a/src/HelperSources/TimeHelper.hpp b/src/HelperSources/TimeHelper.hpp index 75492437..848eee6b 100644 --- a/src/HelperSources/TimeHelper.hpp +++ b/src/HelperSources/TimeHelper.hpp @@ -110,6 +110,12 @@ static std::string min_max_avg_as_string(const MinMaxAvg& minMaxAvg,bool aver } return ss.str(); } +static MinMaxAvg min_max_avg_as_us(const MinMaxAvg& minMaxAvg){ + const uint32_t min=std::chrono::duration_cast(minMaxAvg.min).count(); + const uint32_t max=std::chrono::duration_cast(minMaxAvg.max).count(); + const uint32_t avg=std::chrono::duration_cast(minMaxAvg.avg).count(); + return {min,max,avg}; +} // Use this class to compare many samples of the same kind // Saves the minimum,maximum and average of all the samples diff --git a/src/WBStreamTx.cpp b/src/WBStreamTx.cpp index c118e8ec..434ad1ba 100644 --- a/src/WBStreamTx.cpp +++ b/src/WBStreamTx.cpp @@ -111,6 +111,9 @@ WBStreamTx::Statistics WBStreamTx::get_latest_stats() { ret.n_dropped_frames=m_n_dropped_frames; ret.current_injected_packets_per_second=m_packets_per_second_calculator.get_last_or_recalculate( m_n_injected_packets,std::chrono::seconds(2)); + ret.curr_block_until_tx_min_us=m_curr_block_until_tx_min_max_avg_us.min; + ret.curr_block_until_tx_max_us=m_curr_block_until_tx_min_max_avg_us.max; + ret.curr_block_until_tx_avg_us=m_curr_block_until_tx_min_max_avg_us.avg; return ret; } @@ -120,9 +123,10 @@ void WBStreamTx::loop_process_data() { } static constexpr std::int64_t timeout_usecs=100*1000; if(options.enable_fec){ - std::shared_ptr frame; + std::shared_ptr frame= nullptr; while (m_process_data_thread_run){ if(m_block_queue->wait_dequeue_timed(frame,timeout_usecs)){ + // dequeued frame m_queue_time_calculator.add(std::chrono::steady_clock::now()-frame->enqueue_time_point); if(m_queue_time_calculator.get_delta_since_last_reset()>std::chrono::seconds(1)){ if(options.log_time_spent_in_atomic_queue){ @@ -131,13 +135,14 @@ void WBStreamTx::loop_process_data() { m_queue_time_calculator.reset(); } process_enqueued_block(*frame); - if(options.log_time_blocks_until_tx){ - const auto delta=std::chrono::steady_clock::now()-frame->enqueue_time_point; - m_block_until_tx_time.add(delta); - if(m_block_until_tx_time.get_delta_since_last_reset()>std::chrono::seconds(2)){ + const auto delta=std::chrono::steady_clock::now()-frame->enqueue_time_point; + m_block_until_tx_time.add(delta); + if(m_block_until_tx_time.get_delta_since_last_reset()>std::chrono::seconds(2)){ + if(options.log_time_blocks_until_tx){ m_console->debug("Time until tx {}",m_block_until_tx_time.getAvgReadable()); - m_block_until_tx_time.reset(); } + m_curr_block_until_tx_min_max_avg_us= min_max_avg_as_us(m_block_until_tx_time.getMinMaxAvg()); + m_block_until_tx_time.reset(); } } } diff --git a/src/WBStreamTx.h b/src/WBStreamTx.h index 2dc64f2e..09a3f535 100644 --- a/src/WBStreamTx.h +++ b/src/WBStreamTx.h @@ -86,6 +86,10 @@ class WBStreamTx { // In FEC mode (video), every time a frame is dropped this is increased by the n of fragments in this frame uint64_t n_dropped_packets; int32_t n_dropped_frames; + // only for frame (FEC) mode + uint32_t curr_block_until_tx_min_us; + uint32_t curr_block_until_tx_max_us; + uint32_t curr_block_until_tx_avg_us; }; Statistics get_latest_stats(); // only valid when actually doing FEC @@ -136,6 +140,7 @@ class WBStreamTx { // Time fragments / blocks spend in the non-blocking atomic queue. AvgCalculator m_queue_time_calculator; AvgCalculator m_block_until_tx_time; + MinMaxAvg m_curr_block_until_tx_min_max_avg_us{0,0,0}; // n of packets fed to the instance int64_t m_n_input_packets = 0; // count of bytes we got passed (aka for example, what the video encoder produced - does not include FEC)