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}