Skip to content

Commit b62a9cb

Browse files
authored
emit error signal in case of driver errors (#34)
1 parent e2ceff4 commit b62a9cb

File tree

3 files changed

+48
-23
lines changed

3 files changed

+48
-23
lines changed

camera.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ static PixelFormat mode_to_pixel_format(sensor_mode_t *mode) {
9797
struct CameraPriv {
9898
const parameters_t *params;
9999
camera_frame_cb frame_cb;
100+
camera_error_cb error_cb;
100101
std::unique_ptr<CameraManager> camera_manager;
101102
std::shared_ptr<Camera> camera;
102103
Stream *video_stream;
@@ -107,6 +108,7 @@ struct CameraPriv {
107108
std::map<FrameBuffer *, uint8_t *> mapped_buffers;
108109
bool ts_initialized;
109110
uint64_t ts_start;
111+
bool in_error;
110112
};
111113

112114
static int get_v4l2_colorspace(std::optional<ColorSpace> const &cs) {
@@ -133,7 +135,11 @@ static void set_hdr(bool hdr) {
133135
}
134136
}
135137

136-
bool camera_create(const parameters_t *params, camera_frame_cb frame_cb, camera_t **cam) {
138+
bool camera_create(
139+
const parameters_t *params,
140+
camera_frame_cb frame_cb,
141+
camera_error_cb error_cb,
142+
camera_t **cam) {
137143
std::unique_ptr<CameraPriv> camp = std::make_unique<CameraPriv>();
138144

139145
set_hdr(params->hdr);
@@ -242,7 +248,6 @@ bool camera_create(const parameters_t *params, camera_frame_cb frame_cb, camera_
242248
// this improves performance by a lot.
243249
// https://forums.raspberrypi.com/viewtopic.php?t=352554
244250
// https://github.com/raspberrypi/rpicam-apps/blob/6de1ab6a899df35f929b2a15c0831780bd8e750e/core/rpicam_app.cpp#L1012
245-
246251
int allocator_fd = create_dma_allocator();
247252
if (allocator_fd < 0) {
248253
set_error("failed to open dma heap allocator");
@@ -288,6 +293,7 @@ bool camera_create(const parameters_t *params, camera_frame_cb frame_cb, camera_
288293

289294
camp->params = params;
290295
camp->frame_cb = frame_cb;
296+
camp->error_cb = error_cb;
291297
*cam = camp.release();
292298

293299
return true;
@@ -302,11 +308,17 @@ static int buffer_size(const std::vector<FrameBuffer::Plane> &planes) {
302308
}
303309

304310
static void on_request_complete(Request *request) {
305-
if (request->status() == Request::RequestCancelled) {
311+
CameraPriv *camp = (CameraPriv *)request->cookie();
312+
313+
if (camp->in_error) {
306314
return;
307315
}
308316

309-
CameraPriv *camp = (CameraPriv *)request->cookie();
317+
if (request->status() == Request::RequestCancelled) {
318+
camp->in_error = true;
319+
camp->error_cb();
320+
return;
321+
}
310322

311323
FrameBuffer *buffer = request->buffers().at(camp->video_stream);
312324

camera.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,18 @@ typedef void (*camera_frame_cb)(
1111
uint64_t size,
1212
uint64_t timestamp);
1313

14+
typedef void (*camera_error_cb)();
15+
1416
#ifdef __cplusplus
1517
extern "C" {
1618
#endif
1719

1820
const char *camera_get_error();
19-
bool camera_create(const parameters_t *params, camera_frame_cb frame_cb, camera_t **cam);
21+
bool camera_create(
22+
const parameters_t *params,
23+
camera_frame_cb frame_cb,
24+
camera_error_cb error_cb,
25+
camera_t **cam);
2026
int camera_get_stride(camera_t *cam);
2127
int camera_get_colorspace(camera_t *cam);
2228
bool camera_start(camera_t *cam);

main.c

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
#include "text.h"
1616
#include "encoder.h"
1717

18-
static int pipe_video_fd;
19-
static pthread_mutex_t pipe_video_mutex;
18+
static int pipe_out_fd;
19+
static pthread_mutex_t pipe_out_mutex;
2020
static text_t *text;
2121
static encoder_t *enc;
2222

@@ -40,9 +40,15 @@ static void on_frame(
4040
}
4141

4242
static void on_encoder_output(const uint8_t *mapped, uint64_t size, uint64_t ts) {
43-
pthread_mutex_lock(&pipe_video_mutex);
44-
pipe_write_buf(pipe_video_fd, mapped, size, ts);
45-
pthread_mutex_unlock(&pipe_video_mutex);
43+
pthread_mutex_lock(&pipe_out_mutex);
44+
pipe_write_buf(pipe_out_fd, mapped, size, ts);
45+
pthread_mutex_unlock(&pipe_out_mutex);
46+
}
47+
48+
static void on_error() {
49+
pthread_mutex_lock(&pipe_out_mutex);
50+
pipe_write_error(pipe_out_fd, "camera driver exited");
51+
pthread_mutex_unlock(&pipe_out_mutex);
4652
}
4753

4854
int main() {
@@ -51,30 +57,31 @@ int main() {
5157
return 0;
5258
}
5359

54-
int pipe_conf_fd = atoi(getenv("PIPE_CONF_FD"));
55-
pipe_video_fd = atoi(getenv("PIPE_VIDEO_FD"));
60+
int pipe_in_fd = atoi(getenv("PIPE_CONF_FD"));
61+
pipe_out_fd = atoi(getenv("PIPE_VIDEO_FD"));
5662

5763
uint8_t *buf;
58-
uint32_t n = pipe_read(pipe_conf_fd, &buf);
64+
uint32_t n = pipe_read(pipe_in_fd, &buf);
5965

6066
parameters_t params;
6167
bool ok = parameters_unserialize(&params, &buf[1], n-1);
6268
free(buf);
6369
if (!ok) {
64-
pipe_write_error(pipe_video_fd, "parameters_unserialize(): %s", parameters_get_error());
70+
pipe_write_error(pipe_out_fd, "parameters_unserialize(): %s", parameters_get_error());
6571
return -1;
6672
}
6773

68-
pthread_mutex_init(&pipe_video_mutex, NULL);
69-
pthread_mutex_lock(&pipe_video_mutex);
74+
pthread_mutex_init(&pipe_out_mutex, NULL);
75+
pthread_mutex_lock(&pipe_out_mutex);
7076

7177
camera_t *cam;
7278
ok = camera_create(
7379
&params,
7480
on_frame,
81+
on_error,
7582
&cam);
7683
if (!ok) {
77-
pipe_write_error(pipe_video_fd, "camera_create(): %s", camera_get_error());
84+
pipe_write_error(pipe_out_fd, "camera_create(): %s", camera_get_error());
7885
return -1;
7986
}
8087

@@ -83,7 +90,7 @@ int main() {
8390
camera_get_stride(cam),
8491
&text);
8592
if (!ok) {
86-
pipe_write_error(pipe_video_fd, "text_create(): %s", text_get_error());
93+
pipe_write_error(pipe_out_fd, "text_create(): %s", text_get_error());
8794
return -1;
8895
}
8996

@@ -94,22 +101,22 @@ int main() {
94101
on_encoder_output,
95102
&enc);
96103
if (!ok) {
97-
pipe_write_error(pipe_video_fd, "encoder_create(): %s", encoder_get_error());
104+
pipe_write_error(pipe_out_fd, "encoder_create(): %s", encoder_get_error());
98105
return -1;
99106
}
100107

101108
ok = camera_start(cam);
102109
if (!ok) {
103-
pipe_write_error(pipe_video_fd, "camera_start(): %s", camera_get_error());
110+
pipe_write_error(pipe_out_fd, "camera_start(): %s", camera_get_error());
104111
return -1;
105112
}
106113

107-
pipe_write_ready(pipe_video_fd);
108-
pthread_mutex_unlock(&pipe_video_mutex);
114+
pipe_write_ready(pipe_out_fd);
115+
pthread_mutex_unlock(&pipe_out_mutex);
109116

110117
while (true) {
111118
uint8_t *buf;
112-
uint32_t n = pipe_read(pipe_conf_fd, &buf);
119+
uint32_t n = pipe_read(pipe_in_fd, &buf);
113120

114121
switch (buf[0]) {
115122
case 'e':

0 commit comments

Comments
 (0)