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