cam: Use libevent to implement event loop
To prepare for removal of the EventDispatcher from the libcamera public API, switch to libevent to handle the event loop. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
This commit is contained in:
parent
a27057fc50
commit
7d35c771c0
5 changed files with 55 additions and 26 deletions
|
@ -78,6 +78,9 @@ for documentation: [optional]
|
||||||
for gstreamer: [optional]
|
for gstreamer: [optional]
|
||||||
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
|
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
|
||||||
|
|
||||||
|
for cam: [optional]
|
||||||
|
libevent-dev
|
||||||
|
|
||||||
for qcam: [optional]
|
for qcam: [optional]
|
||||||
qtbase5-dev libqt5core5a libqt5gui5 libqt5widgets5 qttools5-dev-tools libtiff-dev
|
qtbase5-dev libqt5core5a libqt5gui5 libqt5widgets5 qttools5-dev-tools libtiff-dev
|
||||||
|
|
||||||
|
|
|
@ -5,19 +5,34 @@
|
||||||
* event_loop.cpp - cam - Event loop
|
* event_loop.cpp - cam - Event loop
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libcamera/event_dispatcher.h>
|
|
||||||
|
|
||||||
#include "event_loop.h"
|
#include "event_loop.h"
|
||||||
|
|
||||||
using namespace libcamera;
|
#include <assert.h>
|
||||||
|
#include <event2/event.h>
|
||||||
|
#include <event2/thread.h>
|
||||||
|
|
||||||
EventLoop::EventLoop(EventDispatcher *dispatcher)
|
EventLoop *EventLoop::instance_ = nullptr;
|
||||||
: dispatcher_(dispatcher)
|
|
||||||
|
EventLoop::EventLoop()
|
||||||
{
|
{
|
||||||
|
assert(!instance_);
|
||||||
|
|
||||||
|
evthread_use_pthreads();
|
||||||
|
event_ = event_base_new();
|
||||||
|
instance_ = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventLoop::~EventLoop()
|
EventLoop::~EventLoop()
|
||||||
{
|
{
|
||||||
|
instance_ = nullptr;
|
||||||
|
|
||||||
|
event_base_free(event_);
|
||||||
|
libevent_global_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
EventLoop *EventLoop::instance()
|
||||||
|
{
|
||||||
|
return instance_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EventLoop::exec()
|
int EventLoop::exec()
|
||||||
|
@ -26,7 +41,7 @@ int EventLoop::exec()
|
||||||
exit_.store(false, std::memory_order_release);
|
exit_.store(false, std::memory_order_release);
|
||||||
|
|
||||||
while (!exit_.load(std::memory_order_acquire))
|
while (!exit_.load(std::memory_order_acquire))
|
||||||
dispatcher_->processEvents();
|
event_base_loop(event_, EVLOOP_NO_EXIT_ON_EMPTY);
|
||||||
|
|
||||||
return exitCode_;
|
return exitCode_;
|
||||||
}
|
}
|
||||||
|
@ -35,5 +50,10 @@ void EventLoop::exit(int code)
|
||||||
{
|
{
|
||||||
exitCode_ = code;
|
exitCode_ = code;
|
||||||
exit_.store(true, std::memory_order_release);
|
exit_.store(true, std::memory_order_release);
|
||||||
dispatcher_->interrupt();
|
interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLoop::interrupt()
|
||||||
|
{
|
||||||
|
event_base_loopbreak(event_);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,26 +9,27 @@
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
#include <libcamera/event_notifier.h>
|
struct event_base;
|
||||||
|
|
||||||
namespace libcamera {
|
|
||||||
class EventDispatcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
class EventLoop
|
class EventLoop
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EventLoop(libcamera::EventDispatcher *dispatcher);
|
EventLoop();
|
||||||
~EventLoop();
|
~EventLoop();
|
||||||
|
|
||||||
|
static EventLoop *instance();
|
||||||
|
|
||||||
int exec();
|
int exec();
|
||||||
void exit(int code = 0);
|
void exit(int code = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
libcamera::EventDispatcher *dispatcher_;
|
static EventLoop *instance_;
|
||||||
|
|
||||||
|
struct event_base *event_;
|
||||||
std::atomic<bool> exit_;
|
std::atomic<bool> exit_;
|
||||||
int exitCode_;
|
int exitCode_;
|
||||||
|
|
||||||
|
void interrupt();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __CAM_EVENT_LOOP_H__ */
|
#endif /* __CAM_EVENT_LOOP_H__ */
|
||||||
|
|
|
@ -52,7 +52,7 @@ private:
|
||||||
CameraManager *cm_;
|
CameraManager *cm_;
|
||||||
std::shared_ptr<Camera> camera_;
|
std::shared_ptr<Camera> camera_;
|
||||||
std::unique_ptr<libcamera::CameraConfiguration> config_;
|
std::unique_ptr<libcamera::CameraConfiguration> config_;
|
||||||
EventLoop *loop_;
|
EventLoop loop_;
|
||||||
|
|
||||||
bool strictFormats_;
|
bool strictFormats_;
|
||||||
};
|
};
|
||||||
|
@ -60,7 +60,7 @@ private:
|
||||||
CamApp *CamApp::app_ = nullptr;
|
CamApp *CamApp::app_ = nullptr;
|
||||||
|
|
||||||
CamApp::CamApp()
|
CamApp::CamApp()
|
||||||
: cm_(nullptr), camera_(nullptr), config_(nullptr), loop_(nullptr),
|
: cm_(nullptr), camera_(nullptr), config_(nullptr),
|
||||||
strictFormats_(false)
|
strictFormats_(false)
|
||||||
{
|
{
|
||||||
CamApp::app_ = this;
|
CamApp::app_ = this;
|
||||||
|
@ -134,16 +134,11 @@ int CamApp::init(int argc, char **argv)
|
||||||
std::cout << "Monitoring new hotplug and unplug events" << std::endl;
|
std::cout << "Monitoring new hotplug and unplug events" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
loop_ = new EventLoop(cm_->eventDispatcher());
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CamApp::cleanup()
|
void CamApp::cleanup()
|
||||||
{
|
{
|
||||||
delete loop_;
|
|
||||||
loop_ = nullptr;
|
|
||||||
|
|
||||||
if (camera_) {
|
if (camera_) {
|
||||||
camera_->release();
|
camera_->release();
|
||||||
camera_.reset();
|
camera_.reset();
|
||||||
|
@ -166,8 +161,7 @@ int CamApp::exec()
|
||||||
|
|
||||||
void CamApp::quit()
|
void CamApp::quit()
|
||||||
{
|
{
|
||||||
if (loop_)
|
loop_.exit();
|
||||||
loop_->exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CamApp::parseOptions(int argc, char *argv[])
|
int CamApp::parseOptions(int argc, char *argv[])
|
||||||
|
@ -366,13 +360,13 @@ int CamApp::run()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options_.isSet(OptCapture)) {
|
if (options_.isSet(OptCapture)) {
|
||||||
Capture capture(camera_, config_.get(), loop_);
|
Capture capture(camera_, config_.get(), &loop_);
|
||||||
return capture.run(options_);
|
return capture.run(options_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options_.isSet(OptMonitor)) {
|
if (options_.isSet(OptMonitor)) {
|
||||||
std::cout << "Press Ctrl-C to interrupt" << std::endl;
|
std::cout << "Press Ctrl-C to interrupt" << std::endl;
|
||||||
ret = loop_->exec();
|
ret = loop_.exec();
|
||||||
if (ret)
|
if (ret)
|
||||||
std::cout << "Failed to run monitor loop" << std::endl;
|
std::cout << "Failed to run monitor loop" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
libevent = dependency('libevent_pthreads', required : false)
|
||||||
|
|
||||||
|
if not libevent.found()
|
||||||
|
warning('libevent_pthreads not found, \'cam\' application will not be compiled')
|
||||||
|
subdir_done()
|
||||||
|
endif
|
||||||
|
|
||||||
cam_sources = files([
|
cam_sources = files([
|
||||||
'buffer_writer.cpp',
|
'buffer_writer.cpp',
|
||||||
'capture.cpp',
|
'capture.cpp',
|
||||||
|
@ -10,5 +17,9 @@ cam_sources = files([
|
||||||
])
|
])
|
||||||
|
|
||||||
cam = executable('cam', cam_sources,
|
cam = executable('cam', cam_sources,
|
||||||
dependencies : [ libatomic, libcamera_dep ],
|
dependencies : [
|
||||||
|
libatomic,
|
||||||
|
libcamera_dep,
|
||||||
|
libevent,
|
||||||
|
],
|
||||||
install : true)
|
install : true)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue