From 40ef322a3422aaeda6ffa2e071f3bf5d9c713969 Mon Sep 17 00:00:00 2001 From: raghu447 Date: Thu, 11 Jun 2020 19:34:21 +0530 Subject: [PATCH] libcamera: Fixed the crash issue when rtkit is enabled. --- spa/plugins/libcamera/libcamera-source.c | 13 +++++++- spa/plugins/libcamera/libcamera-utils.c | 22 ++++++++---- spa/plugins/libcamera/libcamera_wrapper.cpp | 37 ++++++++------------- spa/plugins/libcamera/libcamera_wrapper.h | 6 ++-- 4 files changed, 46 insertions(+), 32 deletions(-) diff --git a/spa/plugins/libcamera/libcamera-source.c b/spa/plugins/libcamera/libcamera-source.c index 5bb233c23..31f8c4af1 100644 --- a/spa/plugins/libcamera/libcamera-source.c +++ b/spa/plugins/libcamera/libcamera-source.c @@ -134,9 +134,11 @@ struct port { struct impl { struct spa_handle handle; struct spa_node node; + bool have_source; struct spa_log *log; struct spa_loop *data_loop; + struct spa_system *system; uint64_t info_all; struct spa_node_info info; @@ -901,7 +903,10 @@ static int impl_clear(struct spa_handle *handle) free(port->dev.camera); port->dev.camera = NULL; } - + if(this->have_source) { + spa_system_close(this->system, port->source.fd); + this->have_source = false; + } return 0; } @@ -935,12 +940,18 @@ impl_init(const struct spa_handle_factory *factory, this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); this->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop); + this->system = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_System); if (this->data_loop == NULL) { spa_log_error(this->log, "a data_loop is needed"); return -EINVAL; } + if (this->system == NULL) { + spa_log_error(this->log, "a system is needed"); + return -EINVAL; + } + this->node.iface = SPA_INTERFACE_INIT( SPA_TYPE_INTERFACE_Node, SPA_VERSION_NODE, diff --git a/spa/plugins/libcamera/libcamera-utils.c b/spa/plugins/libcamera/libcamera-utils.c index f6e191bf8..09fd7357f 100644 --- a/spa/plugins/libcamera/libcamera-utils.c +++ b/spa/plugins/libcamera/libcamera-utils.c @@ -579,10 +579,6 @@ static int mmap_read(struct impl *this) uint32_t bytesused; if(dev->camera) { - if(!libcamera_is_data_available(dev->camera)) { - return -1; - } - pOut = (struct OutBuf *)libcamera_get_ring_buffer_data(dev->camera); if(!pOut) { spa_log_debug(this->log, "Exiting %s as pOut is NULL\n", __FUNCTION__); @@ -672,6 +668,7 @@ static void libcamera_on_fd_events(struct spa_source *source) struct spa_io_buffers *io; struct port *port = &this->out_ports[0]; struct buffer *b; + uint64_t cnt; if (source->rmask & SPA_IO_ERR) { struct port *port = &this->out_ports[0]; @@ -685,6 +682,11 @@ static void libcamera_on_fd_events(struct spa_source *source) spa_log_warn(this->log, "libcamera %p: spurious wakeup %d", this, source->rmask); return; } + + if (spa_system_eventfd_read(this->system, port->source.fd, &cnt) < 0) { + spa_log_error(this->log, "Failed to read on event fd"); + return; + } if (mmap_read(this) < 0) { spa_log_debug(this->log, "%s:: mmap_read failure\n", __FUNCTION__); @@ -911,10 +913,18 @@ static int spa_libcamera_stream_on(struct impl *this) port->source.func = libcamera_on_fd_events; port->source.data = this; - port->source.fd = get_dev_fd(dev); + port->source.fd = spa_system_eventfd_create(this->system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK); port->source.mask = SPA_IO_IN | SPA_IO_ERR; port->source.rmask = 0; - spa_loop_add_source(this->data_loop, &port->source); + if (port->source.fd < 0) { + spa_log_error(this->log, "Failed to create eventfd. Exting %s with -EIO\n", __FUNCTION__); + } else { + spa_loop_add_source(this->data_loop, &port->source); + this->have_source = true; + + libcamera_set_spa_system(dev->camera, this->system); + libcamera_set_eventfd(dev->camera, port->source.fd); + } dev->active = true; diff --git a/spa/plugins/libcamera/libcamera_wrapper.cpp b/spa/plugins/libcamera/libcamera_wrapper.cpp index aed3dccf5..fef4c7a88 100644 --- a/spa/plugins/libcamera/libcamera_wrapper.cpp +++ b/spa/plugins/libcamera/libcamera_wrapper.cpp @@ -42,6 +42,7 @@ #include #include +#include #include #include @@ -121,6 +122,8 @@ extern "C" { struct ring_buf ringbuf_; void *ringbuf_data_[MAX_NUM_BUFFERS] = {}; struct spa_log *log_; + struct spa_system *system_; + int eventfd_ = -1; pthread_mutex_t lock; /* Methods */ @@ -130,8 +133,6 @@ extern "C" { void ring_buffer_init(); void *ring_buffer_read(); void ring_buffer_write(void *p); - void empty_data(); - void fill_data(); bool open(); void close(); int request_capture(); @@ -170,13 +171,8 @@ extern "C" { uint32_t get_stride(); uint32_t ring_buffer_get_read_index(); uint32_t ring_buffer_get_write_index(); - bool is_data_available(); }LibCamera; - bool LibCamera::is_data_available() { - return this->isAvail_; - } - uint32_t LibCamera::get_max_size() { return this->maxSize_; } @@ -297,18 +293,6 @@ extern "C" { return p; } - void LibCamera::empty_data() { - pthread_mutex_lock(&this->lock); - this->isAvail_ = true; - pthread_mutex_unlock(&this->lock); - } - - void LibCamera::fill_data() { - pthread_mutex_lock(&this->lock); - this->isAvail_ = false; - pthread_mutex_unlock(&this->lock); - } - void LibCamera::item_free_fn() { uint32_t ringbuf_read_index; struct OutBuf *pOut = NULL; @@ -604,7 +588,6 @@ extern "C" { } void libcamera_ringbuffer_read_update(LibCamera *camera) { - camera->fill_data(); camera->ring_buffer_update_read_index(); } @@ -634,8 +617,12 @@ extern "C" { camera->log_ = log; } - bool libcamera_is_data_available(LibCamera *camera) { - return camera->is_data_available(); + void libcamera_set_spa_system(LibCamera *camera, struct spa_system *system) { + camera->system_ = system; + } + + void libcamera_set_eventfd(LibCamera *camera, int fd) { + camera->eventfd_ = fd; } spa_video_format libcamera_map_drm_fourcc_format(unsigned int fourcc) { @@ -887,7 +874,11 @@ extern "C" { spa_log_trace(log_, "%s::Pushing buffer %p at index: %d\n", __FUNCTION__, pBuf, ringbuf_write_index); /* Now update the write index of the ring buffer */ this->ring_buffer_update_write_index(); - this->empty_data(); + if(this->system_ && (this->eventfd_ > 0)) { + if (spa_system_eventfd_write(this->system_, this->eventfd_, 1) < 0) { + spa_log_error(log_, "Failed to write on event fd"); + } + } } } diff --git a/spa/plugins/libcamera/libcamera_wrapper.h b/spa/plugins/libcamera/libcamera_wrapper.h index ab78c6ce9..f424b05bb 100644 --- a/spa/plugins/libcamera/libcamera_wrapper.h +++ b/spa/plugins/libcamera/libcamera_wrapper.h @@ -114,14 +114,16 @@ void libcamera_reset_ring_buffer_data(LibCamera *camera); void libcamera_ringbuffer_read_update(LibCamera *camera); -bool libcamera_is_data_available(LibCamera *camera); - void libcamera_consume_data(LibCamera *camera); void libcamera_free_CamData(LibCamera *camera, CamData *p); void libcamera_free_OutBuf(LibCamera *camera, OutBuf *p); +void libcamera_set_spa_system(LibCamera *camera, struct spa_system *system); + +void libcamera_set_eventfd(LibCamera *camera, int fd); + #ifdef __cplusplus } #endif /* extern "C" */