From b62a9cb2a91f2373fca1cc8e1a35c77b95a81dc8 Mon Sep 17 00:00:00 2001 From: Alessandro Ros Date: Sat, 30 Nov 2024 10:43:53 +0100 Subject: [PATCH] emit error signal in case of driver errors (#34) --- camera.cpp | 20 ++++++++++++++++---- camera.h | 8 +++++++- main.c | 43 +++++++++++++++++++++++++------------------ 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/camera.cpp b/camera.cpp index 4b7ccb9..207c506 100644 --- a/camera.cpp +++ b/camera.cpp @@ -97,6 +97,7 @@ static PixelFormat mode_to_pixel_format(sensor_mode_t *mode) { struct CameraPriv { const parameters_t *params; camera_frame_cb frame_cb; + camera_error_cb error_cb; std::unique_ptr camera_manager; std::shared_ptr camera; Stream *video_stream; @@ -107,6 +108,7 @@ struct CameraPriv { std::map mapped_buffers; bool ts_initialized; uint64_t ts_start; + bool in_error; }; static int get_v4l2_colorspace(std::optional const &cs) { @@ -133,7 +135,11 @@ static void set_hdr(bool hdr) { } } -bool camera_create(const parameters_t *params, camera_frame_cb frame_cb, camera_t **cam) { +bool camera_create( + const parameters_t *params, + camera_frame_cb frame_cb, + camera_error_cb error_cb, + camera_t **cam) { std::unique_ptr camp = std::make_unique(); set_hdr(params->hdr); @@ -242,7 +248,6 @@ bool camera_create(const parameters_t *params, camera_frame_cb frame_cb, camera_ // this improves performance by a lot. // https://forums.raspberrypi.com/viewtopic.php?t=352554 // https://github.com/raspberrypi/rpicam-apps/blob/6de1ab6a899df35f929b2a15c0831780bd8e750e/core/rpicam_app.cpp#L1012 - int allocator_fd = create_dma_allocator(); if (allocator_fd < 0) { 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_ camp->params = params; camp->frame_cb = frame_cb; + camp->error_cb = error_cb; *cam = camp.release(); return true; @@ -302,11 +308,17 @@ static int buffer_size(const std::vector &planes) { } static void on_request_complete(Request *request) { - if (request->status() == Request::RequestCancelled) { + CameraPriv *camp = (CameraPriv *)request->cookie(); + + if (camp->in_error) { return; } - CameraPriv *camp = (CameraPriv *)request->cookie(); + if (request->status() == Request::RequestCancelled) { + camp->in_error = true; + camp->error_cb(); + return; + } FrameBuffer *buffer = request->buffers().at(camp->video_stream); diff --git a/camera.h b/camera.h index e2c70c4..fe3a28c 100644 --- a/camera.h +++ b/camera.h @@ -11,12 +11,18 @@ typedef void (*camera_frame_cb)( uint64_t size, uint64_t timestamp); +typedef void (*camera_error_cb)(); + #ifdef __cplusplus extern "C" { #endif const char *camera_get_error(); -bool camera_create(const parameters_t *params, camera_frame_cb frame_cb, camera_t **cam); +bool camera_create( + const parameters_t *params, + camera_frame_cb frame_cb, + camera_error_cb error_cb, + camera_t **cam); int camera_get_stride(camera_t *cam); int camera_get_colorspace(camera_t *cam); bool camera_start(camera_t *cam); diff --git a/main.c b/main.c index 110879f..53b378a 100644 --- a/main.c +++ b/main.c @@ -15,8 +15,8 @@ #include "text.h" #include "encoder.h" -static int pipe_video_fd; -static pthread_mutex_t pipe_video_mutex; +static int pipe_out_fd; +static pthread_mutex_t pipe_out_mutex; static text_t *text; static encoder_t *enc; @@ -40,9 +40,15 @@ static void on_frame( } static void on_encoder_output(const uint8_t *mapped, uint64_t size, uint64_t ts) { - pthread_mutex_lock(&pipe_video_mutex); - pipe_write_buf(pipe_video_fd, mapped, size, ts); - pthread_mutex_unlock(&pipe_video_mutex); + pthread_mutex_lock(&pipe_out_mutex); + pipe_write_buf(pipe_out_fd, mapped, size, ts); + pthread_mutex_unlock(&pipe_out_mutex); +} + +static void on_error() { + pthread_mutex_lock(&pipe_out_mutex); + pipe_write_error(pipe_out_fd, "camera driver exited"); + pthread_mutex_unlock(&pipe_out_mutex); } int main() { @@ -51,30 +57,31 @@ int main() { return 0; } - int pipe_conf_fd = atoi(getenv("PIPE_CONF_FD")); - pipe_video_fd = atoi(getenv("PIPE_VIDEO_FD")); + int pipe_in_fd = atoi(getenv("PIPE_CONF_FD")); + pipe_out_fd = atoi(getenv("PIPE_VIDEO_FD")); uint8_t *buf; - uint32_t n = pipe_read(pipe_conf_fd, &buf); + uint32_t n = pipe_read(pipe_in_fd, &buf); parameters_t params; bool ok = parameters_unserialize(¶ms, &buf[1], n-1); free(buf); if (!ok) { - pipe_write_error(pipe_video_fd, "parameters_unserialize(): %s", parameters_get_error()); + pipe_write_error(pipe_out_fd, "parameters_unserialize(): %s", parameters_get_error()); return -1; } - pthread_mutex_init(&pipe_video_mutex, NULL); - pthread_mutex_lock(&pipe_video_mutex); + pthread_mutex_init(&pipe_out_mutex, NULL); + pthread_mutex_lock(&pipe_out_mutex); camera_t *cam; ok = camera_create( ¶ms, on_frame, + on_error, &cam); if (!ok) { - pipe_write_error(pipe_video_fd, "camera_create(): %s", camera_get_error()); + pipe_write_error(pipe_out_fd, "camera_create(): %s", camera_get_error()); return -1; } @@ -83,7 +90,7 @@ int main() { camera_get_stride(cam), &text); if (!ok) { - pipe_write_error(pipe_video_fd, "text_create(): %s", text_get_error()); + pipe_write_error(pipe_out_fd, "text_create(): %s", text_get_error()); return -1; } @@ -94,22 +101,22 @@ int main() { on_encoder_output, &enc); if (!ok) { - pipe_write_error(pipe_video_fd, "encoder_create(): %s", encoder_get_error()); + pipe_write_error(pipe_out_fd, "encoder_create(): %s", encoder_get_error()); return -1; } ok = camera_start(cam); if (!ok) { - pipe_write_error(pipe_video_fd, "camera_start(): %s", camera_get_error()); + pipe_write_error(pipe_out_fd, "camera_start(): %s", camera_get_error()); return -1; } - pipe_write_ready(pipe_video_fd); - pthread_mutex_unlock(&pipe_video_mutex); + pipe_write_ready(pipe_out_fd); + pthread_mutex_unlock(&pipe_out_mutex); while (true) { uint8_t *buf; - uint32_t n = pipe_read(pipe_conf_fd, &buf); + uint32_t n = pipe_read(pipe_in_fd, &buf); switch (buf[0]) { case 'e':