77#include < opencv2/core/mat.hpp>
88#include < opencv2/highgui.hpp>
99#include < opencv2/opencv.hpp>
10+ #include < stdexcept>
1011#include < utility>
1112#include < vector>
1213#include < string>
1314
1415#include " depthai/capabilities/ImgFrameCapability.hpp"
1516#include " depthai/common/CameraBoardSocket.hpp"
1617#include " depthai/common/CameraExposureOffset.hpp"
18+ #include " depthai/common/M8FsyncRoles.hpp"
1719#include " depthai/depthai.hpp"
1820#include " depthai/pipeline/MessageQueue.hpp"
1921#include " depthai/pipeline/Node.hpp"
@@ -58,7 +60,8 @@ int main(int argc, char** argv) {
5860 }
5961
6062 std::vector<std::shared_ptr<dai::MessageQueue>> queues;
61- std::vector<dai::Pipeline> pipelines;
63+ std::vector<dai::Pipeline> master_pipelines;
64+ std::vector<dai::Pipeline> slave_pipelines;
6265 std::vector<std::string> device_ids;
6366
6467 for (auto deviceInfo : DEVICE_INFOS)
@@ -76,12 +79,36 @@ int main(int argc, char** argv) {
7679 auto cam = pipeline.create <dai::node::Camera>()->build (socket, std::nullopt , TARGET_FPS);
7780 auto out_q = cam->requestOutput (std::make_pair (640 , 480 ), dai::ImgFrame::Type::NV12, dai::ImgResizeMode::STRETCH)->createOutputQueue ();
7881
79- pipeline.start ();
80- pipelines.push_back (pipeline);
82+ auto role = device->getM8FsyncRole ();
83+
84+ if (role == dai::M8FsyncRole::MASTER_WITH_OUTPUT) {
85+ master_pipelines.push_back (pipeline);
86+ } else if (role == dai::M8FsyncRole::SLAVE) {
87+ slave_pipelines.push_back (pipeline);
88+ } else {
89+ throw std::runtime_error (" Don't know how to handle role " + dai::toString (role));
90+ }
91+
8192 queues.push_back (out_q);
8293 device_ids.push_back (deviceInfo.getXLinkDeviceDesc ().name );
8394 }
8495
96+ if (master_pipelines.size () > 1 ) {
97+ throw std::runtime_error (" Multiple masters detected!" );
98+ }
99+ if (master_pipelines.size () == 0 ) {
100+ throw std::runtime_error (" No master detected!" );
101+ }
102+ if (slave_pipelines.size () < 1 ) {
103+ throw std::runtime_error (" No slaves detected!" );
104+ }
105+ for (auto p : master_pipelines) {
106+ p.start ();
107+ }
108+ for (auto p : slave_pipelines) {
109+ p.start ();
110+ }
111+
85112 std::map<int , std::shared_ptr<dai::ImgFrame>> latest_frames;
86113 std::vector<bool > receivedFrames;
87114 std::vector<FPSCounter> fpsCounters (queues.size ());
@@ -90,8 +117,6 @@ int main(int argc, char** argv) {
90117 receivedFrames.push_back (false );
91118 }
92119
93- int counter = 0 ;
94-
95120 while (true ) {
96121 for (int i = 0 ; i < queues.size (); i++) {
97122 auto q = queues[i];
@@ -111,59 +136,51 @@ int main(int argc, char** argv) {
111136 auto f = pair.second ;
112137 ts_values.push_back (f->getTimestamp (dai::CameraExposureOffset::END));
113138 }
114-
115- if (counter % 100000 == 0 ) {
116- auto diff = *std::max_element (ts_values.begin (), ts_values.end ()) - *std::min_element (ts_values.begin (), ts_values.end ());
117- std::cout << 1e-6 * float (std::chrono::duration_cast<std::chrono::microseconds>(diff).count ()) << std::endl;
118- }
119-
120- if (true ) {
121- // std::vector<cv::Mat> imgs;
122- cv::Mat imgs;
123- for (int i = 0 ; i < queues.size (); i++) {
124- auto msg = latest_frames[i];
125- auto fps = fpsCounters[i].getFps ();
126- auto frame = msg->getCvFrame ();
127-
128- cv::putText (frame,
129- device_ids[i] + " | Timestamp: " + std::to_string (ts_values[i].time_since_epoch ().count ()) + " | FPS: " + std::to_string (fps).substr (0 , 5 ),
130- {20 , 40 },
131- cv::FONT_HERSHEY_SIMPLEX,
132- 0.6 ,
133- {255 , 0 , 50 },
134- 2 ,
135- cv::LINE_AA);
136-
137- if (i == 0 ) {
138- imgs = frame;
139- } else {
140- cv::hconcat (frame, imgs, imgs);
141- }
142- }
143-
144- std::string sync_status = " out of sync" ;
145- if (abs (std::chrono::duration_cast<std::chrono::microseconds>(
146- *std::max_element (ts_values.begin (), ts_values.end ()) -
147- *std::min_element (ts_values.begin (), ts_values.end ())
148- ).count ()) < 1e3 ) {
149- sync_status = " in sync" ;
150- }
151- auto delta = *std::max_element (ts_values.begin (), ts_values.end ()) - *std::min_element (ts_values.begin (), ts_values.end ());
152- cv::Scalar color = (sync_status == " in sync" ) ? cv::Scalar (0 , 255 , 0 ) : cv::Scalar (0 , 0 , 255 );
153-
154- cv::putText (imgs,
155- sync_status + " | delta = " + std::to_string (1e-3 * float (std::chrono::duration_cast<std::chrono::microseconds>(delta).count ())).substr (0 , 5 ) + " ms" ,
156- {20 , 80 },
139+
140+ cv::Mat imgs;
141+ for (int i = 0 ; i < queues.size (); i++) {
142+ auto msg = latest_frames[i];
143+ auto fps = fpsCounters[i].getFps ();
144+ auto frame = msg->getCvFrame ();
145+
146+ cv::putText (frame,
147+ device_ids[i] + " | Timestamp: " + std::to_string (ts_values[i].time_since_epoch ().count ()) + " | FPS: " + std::to_string (fps).substr (0 , 5 ),
148+ {20 , 40 },
157149 cv::FONT_HERSHEY_SIMPLEX,
158- 0.7 ,
159- color ,
150+ 0.6 ,
151+ { 255 , 0 , 50 } ,
160152 2 ,
161153 cv::LINE_AA);
162154
163- cv::imshow (" synced_view" , imgs);
155+ if (i == 0 ) {
156+ imgs = frame;
157+ } else {
158+ cv::hconcat (frame, imgs, imgs);
159+ }
160+ }
164161
165- latest_frames.clear ();
162+ std::string sync_status = " out of sync" ;
163+ if (abs (std::chrono::duration_cast<std::chrono::microseconds>(
164+ *std::max_element (ts_values.begin (), ts_values.end ()) -
165+ *std::min_element (ts_values.begin (), ts_values.end ())
166+ ).count ()) < 1e3 ) {
167+ sync_status = " in sync" ;
166168 }
169+ auto delta = *std::max_element (ts_values.begin (), ts_values.end ()) - *std::min_element (ts_values.begin (), ts_values.end ());
170+ cv::Scalar color = (sync_status == " in sync" ) ? cv::Scalar (0 , 255 , 0 ) : cv::Scalar (0 , 0 , 255 );
171+
172+ cv::putText (imgs,
173+ sync_status + " | delta = " + std::to_string (1e-3 * float (std::chrono::duration_cast<std::chrono::microseconds>(delta).count ())).substr (0 , 5 ) + " ms" ,
174+ {20 , 80 },
175+ cv::FONT_HERSHEY_SIMPLEX,
176+ 0.7 ,
177+ color,
178+ 2 ,
179+ cv::LINE_AA);
180+
181+ cv::imshow (" synced_view" , imgs);
182+
183+ latest_frames.clear ();
167184 }
168185
169186 if (cv::waitKey (1 ) == ' q' ) {
0 commit comments