Skip to content

Commit 7612089

Browse files
committed
fix: Camera USB stack crash after second capture
Fixes the bug by calling gp_camera_wait_for_event until timeout.
1 parent df8f251 commit 7612089

4 files changed

Lines changed: 74 additions & 8 deletions

File tree

Photobox/GPhoto2/Source/GPhoto2Camera.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ exec::task<void> GPhoto2Camera::asyncCaptureLoop()
7777
Q_EMIT imageCaptured(image.value());
7878
}
7979
return image.has_value();
80+
}) //
81+
| stdexec::continues_on(scheduler_->getWorkScheduler()) //
82+
| stdexec::then([this, &context](auto hasValue) {
83+
return GPhoto2::readUntilTimeout(*context);
8084
}) //
8185
| exec::repeat_effect_until(); // todo: this now retries forever to capture a image.
8286
// maybe retry_n times and emit an error?

Photobox/GPhoto2/Source/GPhoto2Integration.cpp

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
// SPDX-License-Identifier: GPL-3.0-or-later
44

55
#include "GPhoto2Integration.hpp"
6+
67
#include <QImage>
8+
#include <fstream>
79
#include <Pbox/Logger.hpp>
810
#include "GPhoto2Context.hpp"
911

@@ -109,17 +111,49 @@ std::optional<QImage> captureImage(Context &context)
109111
gp_camera_capture(context.camera.get(), GP_CAPTURE_IMAGE, &camera_file_path, context.context.get());
110112
if (ret_val < GP_OK)
111113
{
112-
LOG_ERROR(logger_gphoto2(), "could invoke gphoto2 capture");
114+
LOG_ERROR(logger_gphoto2(), "could not invoke gphoto2 capture: {}", ret_val);
113115
return std::nullopt;
114116
}
115-
gp_camera_file_get(context.camera.get(),
116-
camera_file_path.folder,
117-
camera_file_path.name,
118-
GP_FILE_TYPE_NORMAL,
119-
file.get(),
120-
context.context.get());
117+
LOG_INFO(logger_gphoto2(), "captured image to {}", camera_file_path.name);
118+
119+
const auto file_get_ret_val = gp_camera_file_get(context.camera.get(),
120+
camera_file_path.folder,
121+
camera_file_path.name,
122+
GP_FILE_TYPE_NORMAL,
123+
file.get(),
124+
context.context.get());
125+
if (file_get_ret_val < GP_OK)
126+
{
127+
LOG_ERROR(logger_gphoto2(), "could not get file: {}", file_get_ret_val);
128+
}
121129

122-
return readImageFromFile(file.get());
130+
auto image = readImageFromFile(file.get());
131+
132+
return image;
133+
}
134+
bool readUntilTimeout(Context &context)
135+
{
136+
while (true)
137+
{
138+
CameraEventType evtype;
139+
void *data = nullptr;
140+
141+
const int ret = gp_camera_wait_for_event(context.camera.get(), 100, &evtype, &data, context.context.get());
142+
143+
if (ret < GP_OK)
144+
{
145+
LOG_ERROR(logger_gphoto2(), "could not wait for event: {}", ret);
146+
break;
147+
}
148+
149+
if (evtype == GP_EVENT_TIMEOUT)
150+
{
151+
LOG_DEBUG(logger_gphoto2(), "got timeout event");
152+
return true;
153+
}
154+
}
155+
156+
return false;
123157
}
124158

125159
namespace

Photobox/GPhoto2/Source/GPhoto2Integration.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,6 @@ bool autodetectAndConnectCamera(Context &context);
1515
std::optional<QImage> capturePreviewImage(Context &context);
1616

1717
std::optional<QImage> captureImage(Context &context);
18+
19+
bool readUntilTimeout(Context &context);
1820
} // namespace Pbox::GPhoto2

photobox.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "hochzeit-xyz",
3+
"capture_dir": "./output",
4+
"fonts": [
5+
],
6+
"camera_led": {
7+
"uri": "http://192.168.178.99"
8+
},
9+
"initial_countdown": 2,
10+
"remote_triggers": [
11+
12+
],
13+
"sessions": [
14+
{
15+
"name": "SingleCaptureSession",
16+
"type": "SingleCapture",
17+
"print": false,
18+
"triggers": [
19+
"Display"
20+
],
21+
"collage": null
22+
}
23+
]
24+
}
25+
26+
}

0 commit comments

Comments
 (0)