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}