Video capture V4L2: fix wrong usage of capture race checker

This RaceChecker is intended to be used on API thread only when we are
not capturing, however, since StartCapture() can be called while already
capturing, we have to avoid using it to guard members that do not meet
this expectations. Use API checker for _captureStarted instead and move
the capture race checker down where we can be sure that capturing is not
happening.

Bug: webrtc:15181
Change-Id: I52f74b893f2c36c3ce0facd053b003fa497101b0
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338040
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Jan Grulich <grulja@gmail.com>
Cr-Commit-Position: refs/heads/main@{#41714}
This commit is contained in:
Jan Grulich 2024-02-11 11:26:01 +01:00 committed by WebRTC LUCI CQ
parent 541f202354
commit 52fec7d3e9
2 changed files with 16 additions and 6 deletions

View File

@ -112,7 +112,6 @@ VideoCaptureModuleV4L2::~VideoCaptureModuleV4L2() {
int32_t VideoCaptureModuleV4L2::StartCapture(
const VideoCaptureCapability& capability) {
RTC_DCHECK_RUN_ON(&api_checker_);
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
if (_captureStarted) {
if (capability == _requestedCapability) {
@ -122,6 +121,13 @@ int32_t VideoCaptureModuleV4L2::StartCapture(
}
}
// We don't want members above to be guarded by capture_checker_ as
// it's meant to be for members that are accessed on the API thread
// only when we are not capturing. The code above can be called many
// times while sharing instance of VideoCaptureV4L2 between websites
// and therefore it would not follow the requirements of this checker.
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
// Set a baseline of configured parameters. It is updated here during
// configuration, then read from the capture thread.
configured_capability_ = capability;
@ -283,6 +289,7 @@ int32_t VideoCaptureModuleV4L2::StartCapture(
_requestedCapability = capability;
_captureStarted = true;
_streaming = true;
// start capture thread;
if (_captureThread.empty()) {
@ -310,10 +317,12 @@ int32_t VideoCaptureModuleV4L2::StopCapture() {
_captureThread.Finalize();
}
_captureStarted = false;
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
MutexLock lock(&capture_lock_);
if (_captureStarted) {
_captureStarted = false;
if (_streaming) {
_streaming = false;
DeAllocateVideoBuffers();
close(_deviceFd);
@ -397,7 +406,7 @@ bool VideoCaptureModuleV4L2::DeAllocateVideoBuffers() {
}
bool VideoCaptureModuleV4L2::CaptureStarted() {
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
RTC_DCHECK_RUN_ON(&api_checker_);
return _captureStarted;
}
@ -434,7 +443,7 @@ bool VideoCaptureModuleV4L2::CaptureProcess() {
return true;
}
if (_captureStarted) {
if (_streaming) {
struct v4l2_buffer buf;
memset(&buf, 0, sizeof(struct v4l2_buffer));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

View File

@ -50,7 +50,8 @@ class VideoCaptureModuleV4L2 : public VideoCaptureImpl {
int32_t _buffersAllocatedByDevice RTC_GUARDED_BY(capture_lock_);
VideoCaptureCapability configured_capability_
RTC_GUARDED_BY(capture_checker_);
bool _captureStarted RTC_GUARDED_BY(capture_checker_);
bool _streaming RTC_GUARDED_BY(capture_checker_);
bool _captureStarted RTC_GUARDED_BY(api_checker_);
struct Buffer {
void* start;
size_t length;