NVIDIA DeepStream SDK API Reference

8.0 Release
measure_fps_probe.hpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: LicenseRef-NvidiaProprietary
4  *
5  * NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
6  * property and proprietary rights in and to this material, related
7  * documentation and any modifications thereto. Any use, reproduction,
8  * disclosure or distribution of this material and related documentation
9  * without an express license agreement from NVIDIA CORPORATION or
10  * its affiliates is strictly prohibited.
11  */
12 
13 #include <algorithm>
14 #include <fstream>
15 #include <iomanip>
16 #include <iostream>
17 #include <utility>
18 #include <chrono>
19 #include <mutex>
20 #include <set>
21 #include <string>
22 #include <unordered_map>
23 #include <thread>
24 #include <condition_variable>
25 
26 #include "buffer_probe.hpp"
27 
28 using namespace std;
29 
30 namespace deepstream {
31 
33 
35 {
36 public:
37  static const int HEADER_PRINT_INTERVAL = 10;
38  std::unordered_map<unsigned int, std::chrono::microseconds> accumulated_time;
39  std::unordered_map<unsigned int, uint64_t> buf_count_lifetime;
41  std::mutex count_mutex;
44  std::set<unsigned int> pad_idxs;
45  std::unordered_map<unsigned int, std::chrono::steady_clock::time_point>
46  first_frame_time, last_frame_time;
47  std::unordered_map<unsigned int, uint64_t> buf_count;
48 
49  std::thread scheduler_;
50  std::condition_variable cv_;
52  std::size_t last_pad_idx_count;
53 
54 
56  scheduler_ = std::thread([&](){
57  do {
58  std::unique_lock<std::mutex> lock(this->count_mutex);
59  this->measure_and_print_unlocked();
60  this->cv_.wait_for(lock, std::chrono::seconds(5));
61  } while (!this->pause_measurment);
62  });
63  last_pad_idx_count = 0;
64  last_header_print_interval = 0;
65  num_surfaces_per_frame = 1;
66  pause_measurment = false;
67  }
68 
69  virtual ~FPSCounter() {
70  {
71  std::unique_lock<std::mutex> lock(this->count_mutex);
72  pause_measurment = true;
73  cv_.notify_one();
74  }
75  scheduler_.join();
76  }
77 
79  time_point current = std::chrono::steady_clock::now();
80  auto current_buf_count = std::move(buf_count);
81  // Print the header after every HEADER_PRINT_INTERVAL or if a source
82  // was dynamically added and pad_idxs size grew
83  if (this->last_header_print_interval == 0 ||
84  this->last_pad_idx_count != this->pad_idxs.size()) {
85  // this->print_header_unlocked();
86  this->last_header_print_interval = 0;
87  }
88  this->last_header_print_interval =
89  (this->last_header_print_interval + 1) % HEADER_PRINT_INTERVAL;
90  std::ostringstream ostr;
91  ostr << "**FPS: " << std::fixed << std::setprecision(2);
92  for (auto pad_idx : this->pad_idxs) {
93  uint64_t current_buf_count_source = 0;
94  // Insert does not update a value if the key already exists
95  accumulated_time.insert({pad_idx, std::chrono::microseconds(0)});
96  time_point first_frame_time = current;
97  time_point end_time = current;
98  bool source_is_eos = false;
99  if (this->first_frame_time.find(pad_idx) != this->first_frame_time.end())
100  first_frame_time = this->first_frame_time[pad_idx];
101  auto last_frame_time = this->last_frame_time.find(pad_idx);
102  if (last_frame_time != this->last_frame_time.end()) {
103  // If the eos was reached, change the end to the time EOS received instead
104  // of the interval end.
105  end_time = last_frame_time->second;
106  source_is_eos = true;
107  }
108  if (current_buf_count.find(pad_idx) != current_buf_count.end()) {
109  current_buf_count_source = current_buf_count[pad_idx];
110  this->buf_count_lifetime[pad_idx] += current_buf_count_source;
111  }
112  // If the source reached EOS before the current measurement interval, do
113  // not print current values. However, if the EOS was reached in the current
114  // interval, print whatever was measured.
115  if (source_is_eos && end_time < this->last_measurement_time)
116  {
117  ostr << "--.--";
118  }
119  else
120  {
121  time_point start =
122  std::max(first_frame_time, this->last_measurement_time);
123  double interval = std::chrono::duration_cast<std::chrono::microseconds>(
124  end_time - start)
125  .count();
126  ostr << (1000000 * current_buf_count_source / interval);
127  }
128  double lifetime = std::chrono::duration_cast<std::chrono::microseconds>(
129  end_time - first_frame_time)
130  .count() +
131  accumulated_time[pad_idx].count();
132  ostr << " (" << (1000000 * this->buf_count_lifetime[pad_idx] / lifetime)
133  << ")\t";
134  }
135 
136  ostr << "\n";
137 
138  if (ostr.str() != "**FPS: \n")
139  std::cout << ostr.str() << std::flush;
140  this->last_measurement_time = current;
141  this->last_pad_idx_count = this->pad_idxs.size();
142 }
143 
144  virtual probeReturn handleData(BufferProbe& probe, const BatchMetadata& data) {
145  time_point current = std::chrono::steady_clock::now();
146  std::lock_guard<std::mutex> lock(count_mutex);
147  if (pause_measurment) return probeReturn::Probe_Ok;
148  auto cnt = 0;
149  pad_idxs.clear();
150  data.iterate([&](const FrameMetadata& frame_meta) {
151  if (cnt++ % num_surfaces_per_frame == 0) {
152  auto pad_idx = frame_meta.padIndex();
153  pad_idxs.insert(pad_idx);
154  // Insert does not update a value if the key already exists
155  first_frame_time.insert({pad_idx, current});
156  buf_count[pad_idx]++;
157  }
158  });
159  return probeReturn::Probe_Ok;
160  }
161 
162 };
163 
164 }
buffer_probe.hpp
deepstream::FPSCounter::buf_count_lifetime
std::unordered_map< unsigned int, uint64_t > buf_count_lifetime
Definition: measure_fps_probe.hpp:39
deepstream::FPSCounter::FPSCounter
FPSCounter()
Definition: measure_fps_probe.hpp:55
deepstream::FPSCounter::last_header_print_interval
int last_header_print_interval
Definition: measure_fps_probe.hpp:51
deepstream::BufferProbe
Represent a custom object for the purpose of probing output buffers.
Definition: buffer_probe.hpp:58
deepstream::FPSCounter::~FPSCounter
virtual ~FPSCounter()
Definition: measure_fps_probe.hpp:69
deepstream::BufferProbe::IBatchMetadataObserver
Readonly interface for handling batch metadata.
Definition: buffer_probe.hpp:103
deepstream::FPSCounter::handleData
virtual probeReturn handleData(BufferProbe &probe, const BatchMetadata &data)
Definition: measure_fps_probe.hpp:144
deepstream::BatchMetadata::iterate
unsigned int iterate(const std::function< void(const FrameMetadata &)> &func) const
Iterate the frame metadata within it.
deepstream::FPSCounter::last_pad_idx_count
std::size_t last_pad_idx_count
Definition: measure_fps_probe.hpp:52
deepstream::FPSCounter::count_mutex
std::mutex count_mutex
Definition: measure_fps_probe.hpp:41
deepstream::FPSCounter::last_frame_time
std::unordered_map< unsigned int, std::chrono::steady_clock::time_point > last_frame_time
Definition: measure_fps_probe.hpp:46
deepstream::FPSCounter::accumulated_time
std::unordered_map< unsigned int, std::chrono::microseconds > accumulated_time
Definition: measure_fps_probe.hpp:38
deepstream::probeReturn
probeReturn
Return values from user implemented probe interfaces.
Definition: buffer_probe.hpp:42
deepstream::FPSCounter::num_surfaces_per_frame
int num_surfaces_per_frame
Definition: measure_fps_probe.hpp:43
deepstream::time_point
std::chrono::steady_clock::time_point time_point
Definition: measure_fps_probe.hpp:32
deepstream::FPSCounter::scheduler_
std::thread scheduler_
Definition: measure_fps_probe.hpp:49
deepstream
Definition: buffer.hpp:33
deepstream::FrameMetadata::padIndex
unsigned int padIndex() const
Index of the pad from which the frame is generated.
deepstream::BatchMetadata
Holds information about a formed batch containingframes from different sources.
Definition: metadata.hpp:652
deepstream::FPSCounter::last_measurement_time
std::chrono::steady_clock::time_point last_measurement_time
Definition: measure_fps_probe.hpp:40
deepstream::FPSCounter::pad_idxs
std::set< unsigned int > pad_idxs
Definition: measure_fps_probe.hpp:44
deepstream::FPSCounter::pause_measurment
bool pause_measurment
Definition: measure_fps_probe.hpp:42
deepstream::FPSCounter::buf_count
std::unordered_map< unsigned int, uint64_t > buf_count
Definition: measure_fps_probe.hpp:47
deepstream::FPSCounter
Definition: measure_fps_probe.hpp:34
deepstream::FPSCounter::cv_
std::condition_variable cv_
Definition: measure_fps_probe.hpp:50
deepstream::FPSCounter::measure_and_print_unlocked
void measure_and_print_unlocked()
Definition: measure_fps_probe.hpp:78
deepstream::FrameMetadata
Holds information for a single frame.
Definition: metadata.hpp:417