diff --git a/src/internal/wcam_linux.cpp b/src/internal/wcam_linux.cpp index 2a26a9e..68e9742 100644 --- a/src/internal/wcam_linux.cpp +++ b/src/internal/wcam_linux.cpp @@ -131,9 +131,8 @@ auto grab_all_infos_impl() -> std::vector return list_webcam_info; } -CaptureImpl::CaptureImpl(DeviceId const& id, Resolution const& resolution) +Bob::Bob(DeviceId const& id, Resolution const& resolution) : _resolution{resolution} - , _thread{&CaptureImpl::thread_job, std::ref(*this)} { fd = open(id.as_string().c_str(), O_RDWR); if (fd == -1) @@ -158,7 +157,8 @@ CaptureImpl::CaptureImpl(DeviceId const& id, Resolution const& resolution) if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) { - perror("Failed to set format"); + // perror("Failed to set format"); + throw CaptureException{Error_WebcamAlreadyUsedInAnotherApplication{}}; // TODO cleaner } struct v4l2_requestbuffers req; @@ -214,11 +214,8 @@ CaptureImpl::CaptureImpl(DeviceId const& id, Resolution const& resolution) } } -CaptureImpl::~CaptureImpl() +Bob::~Bob() { - _wants_to_stop_thread.store(true); - _thread.join(); - enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(fd, VIDIOC_STREAMOFF, &type) == -1) { @@ -237,20 +234,29 @@ CaptureImpl::~CaptureImpl() } } -void CaptureImpl::thread_job(CaptureImpl& This) +CaptureImpl::CaptureImpl(DeviceId const& id, Resolution const& resolution) + : _bob{id, resolution} + , _thread{&CaptureImpl::thread_job, std::ref(*this)} { - using namespace std::chrono_literals; +} - std::this_thread::sleep_for(2000ms); +CaptureImpl::~CaptureImpl() +{ + _wants_to_stop_thread.store(true); + _thread.join(); +} + +void CaptureImpl::thread_job(CaptureImpl& This) +{ while (!This._wants_to_stop_thread.load()) { auto image = image_factory().make_image(); - image->set_data(ImageDataView{This.getFrame(), static_cast(This._resolution.pixels_count() * 3), This._resolution, wcam::FirstRowIs::Bottom}); + image->set_data(ImageDataView{This._bob.getFrame(), static_cast(This._bob._resolution.pixels_count() * 3), This._bob._resolution, wcam::FirstRowIs::Bottom}); This.set_image(std::move(image)); } } -auto CaptureImpl::getFrame() -> uint8_t* +auto Bob::getFrame() -> uint8_t* { struct v4l2_buffer buf; memset(&buf, 0, sizeof(buf)); diff --git a/src/internal/wcam_linux.hpp b/src/internal/wcam_linux.hpp index 53649c8..b10c4ec 100644 --- a/src/internal/wcam_linux.hpp +++ b/src/internal/wcam_linux.hpp @@ -13,24 +13,30 @@ struct Buffer { size_t length; }; +class Bob { +public: + Bob(DeviceId const& id, Resolution const& resolution); + ~Bob(); + auto getFrame() -> uint8_t*; + Resolution _resolution; + +private: + int fd{-1}; + std::vector buffers; +}; + class CaptureImpl : public ICaptureImpl { public: CaptureImpl(DeviceId const& id, Resolution const& resolution); ~CaptureImpl() override; private: - auto getFrame() -> uint8_t*; - void openDevice(DeviceId const& id); - void initDevice(); - void startCapture(); static void thread_job(CaptureImpl&); private: - Resolution _resolution; - int fd{-1}; - std::vector buffers; - std::atomic _wants_to_stop_thread{false}; - std::thread _thread{}; // Must be initialized last, to make sure that everything else is init when the thread starts its job and uses those other things + Bob _bob; + std::atomic _wants_to_stop_thread{false}; + std::thread _thread{}; // Must be initialized last, to make sure that everything else is init when the thread starts its job and uses those other things }; } // namespace wcam::internal