Обработчик Canon EDSDK не вызывается на Mac

Я программирую привязку для камеры canon в Qt под Mac OSX и по какой-то причине мои обработчики для sdk не называются. Когда я хочу снимать с камеры, все идет хорошо, но моя фотография не загружается, потому что EdsSetObjectEventHandler не вызывается.

НО по какой-то причине, когда я снимаю на камеру и после этого перезагружаю приложение, загружается одна фотография. Мое мнение, мне нужно использовать их цикл событий, но я не знаю как.

Мое приложение не зависает, только обработчик не вызывается. Я могу сделать много фотографий (но только в кэш камеры).

Вот мой код

Метод инициализации

void CameraControl::initEDS()
{
Q_D(CameraControl);

// Camera init
EdsUInt32 count = 0;
EdsDeviceInfo info;

EdsError err = EdsInitializeSDK();

if(err != EDS_ERR_OK)
qFatal("Error: Could not initialize library!");

EdsCameraListRef cameraList = NULL;

if(EdsGetCameraList(&cameraList) != EDS_ERR_OK)
qFatal("Error: Could not get camera list!");

if(EdsGetChildCount(cameraList, &count) != EDS_ERR_OK)
qFatal("Error: Could not get number of cameras!");

if(EdsGetChildAtIndex(cameraList, 0, &(d->m_camera)) != EDS_ERR_OK)
qFatal("Error: Could not get camera!");

if(EdsGetDeviceInfo(d->m_camera, &info) != EDS_ERR_OK)
qFatal("Error: Could not get camera info!");

EdsRelease(cameraList);

// Register handler - this are not called
if(EdsSetObjectEventHandler(d->m_camera, kEdsObjectEvent_All, handleObjectEvent, (EdsVoid*)this) != EDS_ERR_OK)
{
qFatal("Error: can't setup object handler");
}

if(info.deviceSubType == 0)
d->m_isLegacy = true;
else
d->m_isLegacy = false;

// open session
if(EdsOpenSession(d->m_camera) != EDS_ERR_OK)
qFatal("Can't open session with camera");

sleep(1);

EdsUInt32 saveTo = kEdsSaveTo_Host;
if(EdsSetPropertyData(d->m_camera, kEdsPropID_SaveTo, 0, sizeof(saveTo), &saveTo) != EDS_ERR_OK)
qFatal("Error: can't get property for saveTo");

if(!d->m_isLegacy)
{
EdsCapacity capacity = {0x7FFFFFFF, 0x1000, 1};

if(EdsSetCapacity(d->m_camera, capacity) != EDS_ERR_OK)
qFatal("Error: can't set capacity");
}

// get property camera name
EdsUInt32 dataSize = 0;
EdsDataType dataType = kEdsDataType_Unknown;
EdsChar dataString[EDS_MAX_NAME];

if(EdsGetPropertySize(d->m_camera, kEdsPropID_ProductName, 0, &dataType, &dataSize) != EDS_ERR_OK)
qFatal("Can't get property size");

if(dataType == kEdsDataType_String)
{
qDebug() << "property is string";

if(EdsGetPropertyData(d->m_camera, kEdsPropID_ProductName, 0, dataSize, &dataString) != EDS_ERR_OK)
qFatal("Can't get product name of camera");
}

}

Метод захвата

void CameraControl::capture()
{
Q_D(CameraControl);

EdsError err;
if((err = EdsSendCommand(d->m_camera, kEdsCameraCommand_TakePicture, 0)) != EDS_ERR_OK)
{
QString str = QString("Error: can't shoot with camera - code: %1").arg(QString::number(err, 16));

qDebug() << str;
}
else
qDebug() << "picture taken";
}

Метод обработчика

EdsError EDSCALLBACK handleObjectEvent(EdsUInt32 inEvent, EdsBaseRef inRef, EdsVoid* inContext)
{
EdsError err = EDS_ERR_OK;
CameraControl* control = static_cast<CameraControl*>(inContext);

qDebug() << "object handler called"; // never called

switch(inEvent)
{
case kEdsObjectEvent_DirItemRequestTransfer:
download(inRef, control); // download photo
default:
EdsRelease(inRef);
}

return EDS_ERR_OK;
}

Кто-нибудь знает, почему это происходит? Спасибо за помощь.

0

Решение

РЕДАКТИРОВАТЬ — РАЗРЕШЕНО

Я нашел решение для этого.
Когда вы используете EDSDK, вам нужно запустить цикл событий для конкретной платформы, но проблема в том, что он вам нужен внутри основного потока, потому что все события usb идут туда.
Итак, проблема возникла — вам нужен цикл событий для конкретной платформы, но в том же потоке, в котором вы нуждаетесь (в моей ситуации) цикл событий Qt.

решение

Вам нужно время от времени запускать цикл событий Mac для обработки новых событий.
Итак, я создал processEvents() метод и этот метод имеют CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false) которые обрабатывают все события в очереди.

В конструкторе моего объекта появился новый таймер

Q_D(CameraControl);
d->m_timer.setInterval(500);
d->m_timer.setSingleShot(false);
connect(&d->m_timer, &QTimer::timeout, this, &CameraControl::processEvents);
d->m_timer.start();

Таймер, вызывающий этот метод слота

void CameraControl::processEvents()
{
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
}

Я надеюсь, что это поможет кому-то с той же проблемой.

0

Другие решения


По вопросам рекламы [email protected]