16 #include <semaphore.h> 21 signal(SIGTERM, [](
int signum) {
std::cout <<
"SIGTERM: " << getpid() << std::endl;
exit(1);});
28 for (
auto&&
dev : ctx.query_devices())
40 std::cout <<
"pipe starting: " << serial_number << std::endl;
44 std::cout <<
"pipe started: " << serial_number << std::endl;
46 double max_milli_between_frames(3000);
49 bool is_running(
true);
51 while (is_running && crnt_time-last_frame_time < max_milli_between_frames)
54 if (
pipe.poll_for_frames(&fs))
59 sem_getvalue(sem2, &sem_value);
60 is_running = (sem_value == 0);
66 void multiple_stream(
std::string serial_number, sem_t* sem,
bool do_query)
68 size_t max_iterations(10);
70 std::stringstream sem_name;
71 sem_name <<
"sem_" << serial_number <<
"_" << 0;
72 bool is_running(
true);
76 sem_unlink(sem_name.str().c_str());
77 sem_t *sem2 = sem_open(sem_name.str().c_str(), O_CREAT|O_EXCL, S_IRWXU, 0);
82 std::cout <<
"Start streaming: " << serial_number <<
" : (" <<
counter+1 <<
"/" << max_iterations <<
")" << std::endl;
83 stream(serial_number, sem2, do_query);
88 std::this_thread::sleep_for(std::chrono::seconds(5));
90 pid_t
w = waitpid(pid, &status, WNOHANG);
91 bool child_alive(w == 0);
98 while (child_alive && (crnt_time - start_time < 2000))
100 std::this_thread::sleep_for(std::chrono::milliseconds(500));
101 pid_t w = waitpid(pid, &status, WNOHANG);
102 child_alive = (w == 0);
107 std::cout <<
"Failed to start streaming: " << serial_number << std::endl;
108 int res = kill(pid,SIGTERM);
109 pid_t w = waitpid(pid, &status, 0);
112 std::this_thread::sleep_for(std::chrono::milliseconds(100));
116 std::cout <<
"Frames did not arrive: " << serial_number << std::endl;
120 sem_getvalue(sem, &sem_value);
121 is_running = (sem_value == 0);
125 sem_unlink(sem_name.str().c_str());
130 TEST_CASE(
"multicam_streaming",
"[live][multicam]")
136 std::vector<std::string> serials_numbers;
143 WARN(
"Device " << serial <<
" with usb_type " <<
usb_type <<
" is skipped.");
146 serials_numbers.push_back(serial);
148 REQUIRE(serials_numbers.size() >= 2);
149 std::vector<pid_t> pids;
153 std::vector<sem_t*> sems;
154 for (
size_t idx = 0;
idx < serials_numbers.size();
idx++)
156 std::stringstream sem_name;
157 sem_name <<
"sem_" <<
idx;
158 sem_unlink(sem_name.str().c_str());
159 sems.push_back(sem_open(sem_name.str().c_str(), O_CREAT|O_EXCL, S_IRWXU, 0));
164 multiple_stream(serials_numbers[idx], sems[idx], do_query);
168 std::this_thread::sleep_for(std::chrono::milliseconds(100));
175 pid_t pid = wait(&status0);
176 std::cout <<
"status0 = " << status0 << std::endl;
177 for (
auto sem : sems)
181 for (
auto pid : pids)
184 pid_t w = waitpid(pid, &status, WNOHANG);
185 std::cout <<
"status: " << pid <<
" : " << status << std::endl;
186 bool child_alive(w == 0);
190 while (child_alive && (crnt_time - start_time < 6000))
192 std::cout <<
"waiting for: " << pid << std::endl;
193 std::this_thread::sleep_for(std::chrono::milliseconds(500));
194 pid_t w = waitpid(pid, &status, WNOHANG);
195 child_alive = (w == 0);
200 std::cout <<
"kill: " << pid << std::endl;
201 int res = kill(pid,SIGTERM);
202 pid_t w = waitpid(pid, &status, 0);
203 std::cout <<
"status: " << status <<
", " << w << std::endl;
230 const double msec_to_sec = 0.001;
231 const int frames_for_fps_measure(profile.
fps() * 1);
233 std::vector<global_time_test_meta_data> frames_additional_data;
235 std::condition_variable
cv;
247 double crnt_time(internal::get_time());
250 start_time = crnt_time;
254 if ((frames_additional_data.size() >= frames_for_fps_measure))
259 if (frames_additional_data.size() < frames_for_fps_measure)
269 std::unique_lock<std::mutex>
lock(m);
270 frames_additional_data.push_back(
data);
274 CAPTURE(frames_for_fps_measure);
276 std::unique_lock<std::mutex>
lock(
m);
277 cv.wait_for(lock, std::chrono::seconds(10), [&] {
return ((frames_additional_data.size() >= frames_for_fps_measure)); });
278 CAPTURE(frames_additional_data.size());
286 auto seconds = (end - start_time)*msec_to_sec;
294 if (frames_additional_data.size())
296 std::stringstream
name;
297 name <<
"test_results_" << iter <<
"_" << enable_gts <<
".txt";
298 std::ofstream fout(name.str());
300 for (
auto data : frames_additional_data)
307 auto actual_fps = (double)frames_additional_data.size() / (double)seconds;
309 max_diff_system_global_time = 0;
310 for (
int i = 1;
i < frames_additional_data.size();
i++)
323 double crnt_diff(system_ts_diff - ts_diff);
324 max_diff_system_global_time = std::max(max_diff_system_global_time, crnt_diff);
339 std::vector<sensor> list;
343 const int frames_before_start_measure = 10;
344 const double msec_to_sec = 0.001;
345 const int num_of_profiles_for_each_subdevice = 2;
346 const float max_diff_between_real_and_metadata_fps = 1.0f;
350 for (
auto && subdevice : list) {
353 std::vector<rs2::stream_profile> modes;
365 for (
auto && subdevice : list) {
368 std::vector<rs2::stream_profile> modes;
390 double max_diff_system_global_time;
391 std::vector<double> all_results_gts_on;
392 std::vector<double> all_results_gts_off;
393 const int num_of_runs(30);
394 for (
int i = 0;
i < num_of_runs;
i++)
397 all_results_gts_on.push_back(max_diff_system_global_time);
398 std::cout <<
"Ran iteration " <<
i <<
"/" << num_of_runs <<
" - gts-ON: max_diff_system_global_time=" << max_diff_system_global_time << std::endl;
401 all_results_gts_off.push_back(max_diff_system_global_time);
402 std::cout <<
"Ran iteration " <<
i <<
"/" << num_of_runs <<
" - gts-OFF: max_diff_system_global_time=" << max_diff_system_global_time << std::endl;
404 std::nth_element(all_results_gts_on.begin(), all_results_gts_on.begin() + all_results_gts_on.size() / 2, all_results_gts_on.end());
405 double median_diff_gts_on = all_results_gts_on[all_results_gts_on.size() / 2];
406 std::nth_element(all_results_gts_off.begin(), all_results_gts_off.begin() + all_results_gts_off.size() / 2, all_results_gts_off.end());
407 double median_diff_gts_off = all_results_gts_off[all_results_gts_off.size() / 2];
411 REQUIRE(median_diff_gts_on > 0.5*median_diff_gts_off);
412 REQUIRE(median_diff_gts_on < 2.0*median_diff_gts_off);
422 std::shared_ptr<std::condition_variable>
cv = std::make_shared<std::condition_variable>();
423 std::shared_ptr<std::mutex>
m = std::make_shared<std::mutex>();
424 std::shared_ptr<std::map<rs2_stream, int>> streams_frames = std::make_shared<std::map<rs2_stream, int>>();
426 std::shared_ptr<std::function<void(rs2::frame fref)>>
func;
428 std::vector<rs2::stream_profile> modes;
431 auto streaming =
false;
444 func = std::make_shared< std::function<void(frame fref)>>([
m, streams_frames,
cv](
frame fref)
mutable 446 std::unique_lock<std::mutex>
lock(*m);
447 auto stream = fref.get_profile().stream_type();
448 if (streams_frames->find(
stream) == streams_frames->end())
449 (*streams_frames)[
stream] = 0;
451 (*streams_frames)[
stream]++;
464 std::unique_lock<std::mutex>
lock(*m);
465 cv->wait_for(lock, std::chrono::seconds(30), [&]
467 for (
auto f : (*streams_frames))
469 if (
f.second > num_of_frames)
485 return streams_frames;
495 std::vector<rs2::device> list;
499 auto dev = std::make_shared<device>(list.front());
500 auto sensors = dev->query_sensors();
503 for (
sensor& elem : sensors)
513 std::shared_ptr<std::map<rs2_stream, int>> streams_frames =
count_streams_frames(ctx, d_sensor, 10);
514 std::cout <<
"streams_frames.size: " << streams_frames->size() << std::endl;
515 for (
auto stream_num : (*streams_frames))
517 std::cout <<
"For stream " << stream_num.first <<
" got " << stream_num.second <<
" frames." << std::endl;
520 REQUIRE(streams_frames->size() == 1);
static const textual_icon lock
TEST_CASE("global-time-start","[live]")
GLuint const GLchar * name
std::vector< sensor > query_all_sensors() const
Generate a flat list of all available sensors from all RealSense devices.
const char * rs2_timestamp_domain_to_string(rs2_timestamp_domain info)
std::shared_ptr< std::map< rs2_stream, int > > count_streams_frames(const context &ctx, const sensor &sub, int num_of_frames)
stream_profile get_profile() const
device_list query_devices() const
GLdouble GLdouble GLdouble w
GLsizei const GLchar *const * string
void enable_device(const std::string &serial)
status
Defines return codes that SDK interfaces use. Negative values indicate errors, a zero value indicates...
static const textual_icon usb_type
void disable_all_streams()
double get_timestamp() const
static std::condition_variable cv
#define SECTION_FROM_TEST_NAME
rs2_format
A stream's format identifies how binary data is encoded within a frame.
void enable_stream(rs2_stream stream_type, int stream_index, int width, int height, rs2_format format=RS2_FORMAT_ANY, int framerate=0)
rs2_stream
Streams are different types of data provided by RealSense devices.
static const textual_icon exit
bool make_context(const char *id, rs2::context *ctx, std::string min_api_version="0.0.0")
void run_sensor(rs2::sensor subdevice, rs2::stream_profile profile, bool enable_gts, int iter, double &max_diff_system_global_time)
rs2_format format() const
rs2_timestamp_domain timestamp_domain
rs2_timestamp_domain get_frame_timestamp_domain() const
void open(const stream_profile &profile) const
REQUIRE_NOTHROW(rs2_log(RS2_LOG_SEVERITY_INFO,"Log message using rs2_log()", nullptr))
void disable_sensitive_options_for(rs2::sensor &sen)
unsigned long long get_frame_number() const
std::vector< stream_profile > get_stream_profiles() const
rs2_stream stream_type() const
void set_option(rs2_option option, float value) const
void start(T callback) const
CHECK_FALSE(inverse(inverse(p))==p)
rs2_timestamp_domain
Specifies the clock in relation to which the frame timestamp was measured.