Skip to content

Commit

Permalink
♻️ [Linux] Only start the thread when the Capture is setup
Browse files Browse the repository at this point in the history
  • Loading branch information
JulesFouchy committed Oct 6, 2024
1 parent 1c9bde0 commit 8ebe179
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 21 deletions.
30 changes: 18 additions & 12 deletions src/internal/wcam_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,8 @@ auto grab_all_infos_impl() -> std::vector<Info>
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)
Expand All @@ -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;
Expand Down Expand Up @@ -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)
{
Expand All @@ -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<RGB24>{This.getFrame(), static_cast<size_t>(This._resolution.pixels_count() * 3), This._resolution, wcam::FirstRowIs::Bottom});
image->set_data(ImageDataView<RGB24>{This._bob.getFrame(), static_cast<size_t>(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));
Expand Down
24 changes: 15 additions & 9 deletions src/internal/wcam_linux.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Buffer> 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<Buffer> buffers;
std::atomic<bool> _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<bool> _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
Expand Down

0 comments on commit 8ebe179

Please sign in to comment.