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