sample code - “connect to multi-camera”¶
usage:
set <camera index> <DP name> <param> [1-blocking,0-no blocking]
get <camera index> <DP name>
To exit, please enter 'q'.
This sample code is included in SimpleCli.
1// connect to multi-camera sample
2#include <chrono>
3#include <cinttypes>
4#include <cstdint>
5#include <cstdlib>
6#include <fstream>
7#include <future>
8#include <iostream>
9#include <mutex>
10#include <sstream>
11#include <stdexcept>
12#include <string>
13#include <thread>
14#include <vector>
15
16#if !defined(__APPLE__)
17 #if defined(USE_EXPERIMENTAL_FS) // for jetson
18 #include <experimental/filesystem>
19 namespace fs = std::experimental::filesystem;
20 #else
21 #include <filesystem>
22 namespace fs = std::filesystem;
23 #endif
24#endif
25
26#if defined(__APPLE__) || defined(__linux__)
27 #include <unistd.h>
28#endif
29
30// macro for multibyte character
31#if defined(_WIN32) || defined(_WIN64)
32 using CrString = std::wstring;
33 #define CRSTR(s) L ## s
34 #define CrCout std::wcout
35#else
36 using CrString = std::string;
37 #define CRSTR(s) s
38 #define CrCout std::cout
39#endif
40
41
42#include "CrDeviceProperty.h"
43#include "CameraRemote_SDK.h"
44#include "IDeviceCallback.h"
45#include "CrDebugString.h" // use CrDebugString.cpp
46
47#define PrintError(msg, err) { fprintf(stderr, "Error in %s(%d):" msg ",%s\n", __FUNCTION__, __LINE__, (err ? CrErrorString(err).c_str():"")); }
48#define GotoError(msg, err) { PrintError(msg, err); goto Error; }
49
50CrString _getModelId(const SCRSDK::ICrCameraObjectInfo* objInfo)
51{
52 CrString id;
53 if (CrString(objInfo->GetConnectionTypeName()) == CRSTR("IP")) {
54 id = CrString(objInfo->GetMACAddressChar());
55 } else {
56 id = CrString((CrChar*)objInfo->GetId());
57 }
58 return CrString(objInfo->GetModel()).append(CRSTR(" (")).append(id).append(CRSTR(")"));
59}
60
61std::vector<std::string> _split(std::string inputLine, char delimiter)
62{
63 std::vector<std::string> strArray;
64 if (inputLine.empty()) return strArray;
65
66 std::string tmp;
67 std::stringstream ss{inputLine};
68 while (getline(ss, tmp, delimiter)) {
69 strArray.push_back(tmp);
70 }
71 return strArray;
72}
73
74int64_t _stoll(std::string inputLine)
75{
76 int64_t data = 0;
77 if(inputLine.empty()) throw std::runtime_error("error");
78 try {
79 if (inputLine.compare(0, 2, "0x") == 0 || inputLine.compare(0, 2, "0X") == 0) {
80 data = std::stoull(inputLine.substr(2), nullptr, 16);
81 } else {
82 data = std::stoll(inputLine, nullptr, 10);
83 }
84 } catch(const std::exception& ex) {
85 throw ex;
86 }
87 return data;
88}
89
90class CameraDevice : public SCRSDK::IDeviceCallback
91{
92public:
93 int64_t m_device_handle = 0;
94 bool m_connected = false;
95 CrString m_modelId;
96
97 std::mutex m_eventPromiseMutex;
98 uint32_t m_setDPCode = 0;
99 std::promise<void>* m_eventPromise = nullptr;
100 void setEventPromise(std::promise<void>* dp)
101 {
102 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
103 m_eventPromise = dp;
104 }
105
106 CameraDevice() {};
107 ~CameraDevice() {};
108
109 // override of IDeviceCallback
110
111 void OnConnected(SCRSDK::DeviceConnectionVersioin version)
112 {
113 CrCout << "Connected to " << m_modelId << "\n";
114 m_connected = true;
115 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
116 if(m_eventPromise) {
117 m_eventPromise->set_value();
118 m_eventPromise = nullptr;
119 }
120 }
121
122 void OnError(CrInt32u error)
123 {
124 printf("Connection error:%s\n", CrErrorString(error).c_str());
125 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
126 if(m_eventPromise) {
127 m_eventPromise->set_exception(std::make_exception_ptr(std::runtime_error("error")));
128 m_eventPromise = nullptr;
129 }
130 }
131
132 void OnDisconnected(CrInt32u error)
133 {
134 CrCout << "Disconnected from " << m_modelId << "\n";
135 m_connected = false;
136 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
137 if(m_eventPromise) {
138 m_eventPromise->set_value();
139 m_eventPromise = nullptr;
140 }
141 }
142
143 void OnCompleteDownload(CrChar* filename, CrInt32u type )
144 {
145 CrCout << "OnCompleteDownload:" << filename << "\n";
146 }
147
148 void OnNotifyContentsTransfer(CrInt32u notify, SCRSDK::CrContentHandle contentHandle, CrChar* filename)
149 {
150 std::cout << "OnNotifyContentsTransfer.\n";
151 }
152
153 void OnWarning(CrInt32u warning)
154 {
155 if (warning == SCRSDK::CrWarning_Connect_Reconnecting) {
156 CrCout << "Reconnecting to " << m_modelId << "\n";
157 return;
158 }
159 std::cout << "OnWarning:" << CrErrorString(warning) << "\n";
160 }
161
162 void OnWarningExt(CrInt32u warning, CrInt32 param1, CrInt32 param2, CrInt32 param3) {}
163 void OnLvPropertyChanged() {}
164 void OnLvPropertyChangedCodes(CrInt32u num, CrInt32u* codes) {}
165 void OnPropertyChanged() {}
166 void OnPropertyChangedCodes(CrInt32u num, CrInt32u* codes)
167 {
168 //std::cout << "OnPropertyChangedCodes:\n";
169 for(uint32_t i = 0; i < num; ++i) {
170 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
171 if(m_setDPCode && m_setDPCode == codes[i]) {
172 m_setDPCode = 0;
173 if(m_eventPromise) {
174 m_eventPromise->set_value();
175 m_eventPromise = nullptr;
176 }
177 }
178 }
179 }
180
181 // method
182
183 SCRSDK::CrError _getIdPassword(const SCRSDK::ICrCameraObjectInfo* objInfo, std::string& fingerprint, std::string& userId, std::string& userPassword)
184 {
185 char fpBuff[128] = {0};
186 CrInt32u fpLen = 0;
187 SCRSDK::CrError err = SCRSDK::GetFingerprint((SCRSDK::ICrCameraObjectInfo*)objInfo, fpBuff, &fpLen);
188 if(err) GotoError("", err);
189 fingerprint = std::string(fpBuff, fpLen);
190
191 std::cout << "fingerprint: " << fingerprint.c_str() << "\n";
192 std::cout << "id:"; std::getline(std::cin, userId);
193 std::cout << "password:"; std::getline(std::cin, userPassword);
194 return 0;
195 Error:
196 return err;
197 }
198
199 SCRSDK::CrError connect(const SCRSDK::ICrCameraObjectInfo* objInfo)
200 {
201 SCRSDK::CrError err = SCRSDK::CrError_None;
202 int result = SCRSDK::CrError_Generic_Unknown;
203 std::string fingerprint = "";
204 std::string userId = "";
205 std::string userPassword = "";
206 std::promise<void> eventPromise;
207 std::future<void> eventFuture = eventPromise.get_future();
208
209 m_modelId = _getModelId(objInfo);
210
211 if (objInfo->GetSSHsupport() == SCRSDK::CrSSHsupport_ON) {
212 err = _getIdPassword(objInfo, fingerprint, userId, userPassword); if(err) goto Error;
213 }
214
215 setEventPromise(&eventPromise);
216 err = SCRSDK::Connect((SCRSDK::ICrCameraObjectInfo*)objInfo, this, &m_device_handle,
217 SCRSDK::CrSdkControlMode_Remote,
218 SCRSDK::CrReconnecting_ON,
219 userId.c_str(), userPassword.c_str(), fingerprint.c_str(), (uint32_t)fingerprint.size());
220 if(err) GotoError("", err);
221
222 // std::future_status status = eventFuture.wait_for(std::chrono::milliseconds(3000));
223 // if(status != std::future_status::ready) GotoError("timeout",0);
224 try{
225 eventFuture.get();
226 } catch(const std::exception&) GotoError("", 0);
227 result = 0;
228 Error:
229 return result;
230 }
231
232 SCRSDK::CrError disconnect(void)
233 {
234 if(m_connected) {
235 std::promise<void> eventPromise;
236 std::future<void> eventFuture = eventPromise.get_future();
237 setEventPromise(&eventPromise);
238 SCRSDK::Disconnect(m_device_handle);
239 eventFuture.wait_for(std::chrono::milliseconds(3000));
240 m_connected = false;
241 }
242 if(m_device_handle) {
243 SCRSDK::ReleaseDevice(m_device_handle);
244 m_device_handle = 0;
245 }
246 return SCRSDK::CrError_None;
247 }
248
249 SCRSDK::CrError getDeviceProperty(uint32_t code, SCRSDK::CrDeviceProperty* devProp)
250 {
251 std::int32_t nprop = 0;
252 SCRSDK::CrDeviceProperty* prop_list = nullptr;
253 SCRSDK::CrError err = SCRSDK::GetSelectDeviceProperties(m_device_handle, 1, &code, &prop_list, &nprop);
254 if(err) GotoError("", err);
255 if(prop_list && nprop >= 1) {
256 *devProp = prop_list[0];
257 }
258 Error:
259 if(prop_list) SCRSDK::ReleaseDeviceProperties(m_device_handle, prop_list);
260 return err;
261 }
262
263 SCRSDK::CrError setDeviceProperty(uint32_t code, uint64_t data, bool blocking=true)
264 {
265 int result = SCRSDK::CrError_Generic_Unknown;
266 SCRSDK::CrError err = 0;
267 std::promise<void> eventPromise;
268 std::future<void> eventFuture = eventPromise.get_future();
269 std::future_status status;
270
271 SCRSDK::CrDeviceProperty devProp;
272
273 err = getDeviceProperty(code, &devProp);
274 if(err) GotoError("", err);
275 if (devProp.GetValueType() == SCRSDK::CrDataType_STR) GotoError("STR is not supported", 0);
276 if (blocking && devProp.GetCurrentValue() == data) {
277 std::cout << "skipped\n";
278 return 0;
279 }
280
281 if(blocking) {
282 std::lock_guard<std::mutex> lock(m_eventPromiseMutex);
283 m_setDPCode = code;
284 m_eventPromise = &eventPromise;
285 }
286
287 devProp.SetCurrentValue(data);
288 err = SCRSDK::SetDeviceProperty(m_device_handle, &devProp);
289 if(err) GotoError("", err);
290
291 if(!blocking) return 0;
292
293 status = eventFuture.wait_for(std::chrono::milliseconds(3000));
294 if(status != std::future_status::ready) GotoError("timeout", 0);
295
296 try{
297 eventFuture.get();
298 } catch(const std::exception&) GotoError("", 0);
299 std::cout << "OK\n";
300
301 result = 0;
302 Error:
303 setEventPromise(nullptr);
304 return result;
305 }
306};
307
308int main(void)
309{
310 int result = -1;
311 SCRSDK::CrError err = SCRSDK::CrError_None;
312 SCRSDK::ICrEnumCameraObjectInfo* enumCameraObjectInfo = nullptr;
313 uint32_t count = 0;
314 #define DEVICE_MAX 2
315 CameraDevice devices[DEVICE_MAX];
316 uint32_t device_num = 0;
317 uint32_t i;
318
319 #if defined(__APPLE__)
320 #define MAC_MAX_PATH 255
321 char pathBuf[MAC_MAX_PATH] = {0};
322 if(NULL == getcwd(pathBuf, sizeof(pathBuf) - 1)) return 1;
323 CrString path = pathBuf;
324 #else
325 CrString path = fs::current_path().native();
326 #endif
327
328 bool boolRet = SCRSDK::Init();
329 if(!boolRet) GotoError("", 0);
330
331 // enumeration & select camera
332
333 err = SCRSDK::EnumCameraObjects(&enumCameraObjectInfo, 3/*timeInSec*/);
334 if(err || !enumCameraObjectInfo) GotoError("no camera", err);
335
336 count = enumCameraObjectInfo->GetCount();
337 for (i = 0; i < count; i++) {
338 auto* info = enumCameraObjectInfo->GetCameraObjectInfo(i);
339 CrCout << '[' << i << "] " << _getModelId(info) << "\n";
340 }
341
342 device_num = count;
343 if(device_num > DEVICE_MAX) device_num = DEVICE_MAX;
344 for(i = 0; i < device_num; i++) {
345 uint32_t index;
346 std::string inputLine;
347 printf("select camera%d:", i); std::getline(std::cin, inputLine);
348 try { index = stoi(inputLine); } catch(const std::exception&) { GotoError("", 0); }
349 if(index < 0 || index >= count) GotoError("", 0);
350
351 // connect
352 err = devices[i].connect(enumCameraObjectInfo->GetCameraObjectInfo(index));
353 if(err) goto Error;
354
355 // set work directory
356 err = SCRSDK::SetSaveInfo(devices[i].m_device_handle, const_cast<CrChar*>(path.data()), const_cast<CrChar*>(CRSTR("DSC")), -1/*startNo*/);
357 if(err) GotoError("", err);
358 }
359
360 CrCout << "path=" << path.data() << "\n";
361
362 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
363
364 std::cout << "usage:\n";
365 std::cout << " set <camera index> <DP name> <param> [1-blocking,0-no blocking]\n";
366 std::cout << " get <camera index> <DP name>\n";
367 std::cout << "To exit, please enter 'q'.\n";
368
369 while(1) {
370 uint32_t deviceId = 0;
371 int32_t code;
372 std::string inputLine;
373 std::getline(std::cin, inputLine);
374 std::vector<std::string> args = _split(inputLine, ' ');
375
376 if(args.size() == 0) continue;
377
378 if(args[0] == "q" || args[0] == "Q") break;
379
380 if(args.size() < 3) continue;
381
382 try{ deviceId = (int)_stoll(args[1]); } catch(const std::exception&) {continue;}
383 if(deviceId >= device_num) continue;
384
385 code = CrDevicePropertyCode(args[2]);
386 if(code < 0) continue;
387
388 if(args[0] == "get") {
389 SCRSDK::CrDeviceProperty devProp;
390 err = devices[deviceId].getDeviceProperty(code, &devProp);
391 if(err) continue;
392
393 if(devProp.GetValueType() != SCRSDK::CrDataType_STR) {
394 printf("0x%" PRIx64 "(%" PRId64 ")\n", devProp.GetCurrentValue(), devProp.GetCurrentValue()); // macro for %lld
395 }
396 } else if(args[0] == "set" && args.size() >= 4) {
397 int64_t data = 0;
398 bool blocking = true;
399
400 try{ data = _stoll(args[3]); } catch(const std::exception&) {continue;}
401 if(args.size() >= 5)
402 try{ blocking = _stoll(args[4]); } catch(const std::exception&) {continue;}
403
404 err = devices[deviceId].setDeviceProperty(code, data, blocking);
405 if(err) continue;
406 } else {
407 std::cout << "unknown command\n";
408 }
409 }
410
411 result = 0;
412Error:
413 if(enumCameraObjectInfo) enumCameraObjectInfo->Release();
414 for(i = 0; i < device_num; i++)
415 devices[i].disconnect();
416 SCRSDK::Release();
417
418 return result;
419}