Skip to content

Commit eee1039

Browse files
PehrsonsWebRTC LUCI CQ
authored andcommitted
In VideoCaptureImpl and subclasses add thread and lock annotations
This annotates all unannotated members in VideoCaptureImpl and its subclasses with either of: - api_checker_: access on the api thread only - capture_checker_: access in callbacks/on the capture thread while capture is active, on the api thread otherwise - a Mutex if it is already protected by it Bug: webrtc:15181 Change-Id: I5084e7752a4716c29b85a9b403a88696f66d811f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/305647 Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Per Kjellander <perkj@webrtc.org> Cr-Commit-Position: refs/heads/main@{#40335}
1 parent 656817c commit eee1039

9 files changed

Lines changed: 120 additions & 40 deletions

modules/video_capture/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@ rtc_library("video_capture_module") {
2929

3030
deps = [
3131
"../../api:scoped_refptr",
32+
"../../api:sequence_checker",
3233
"../../api/video:video_frame",
3334
"../../api/video:video_rtp_headers",
3435
"../../common_video",
3536
"../../media:rtc_media_base",
3637
"../../rtc_base:event_tracer",
3738
"../../rtc_base:logging",
3839
"../../rtc_base:macromagic",
40+
"../../rtc_base:race_checker",
3941
"../../rtc_base:refcount",
4042
"../../rtc_base:stringutils",
4143
"../../rtc_base:timeutils",

modules/video_capture/linux/video_capture_pipewire.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,15 @@ VideoCaptureModulePipeWire::VideoCaptureModulePipeWire(
5151
: VideoCaptureImpl(), session_(options->pipewire_session()) {}
5252

5353
VideoCaptureModulePipeWire::~VideoCaptureModulePipeWire() {
54+
RTC_DCHECK_RUN_ON(&api_checker_);
55+
5456
StopCapture();
5557
}
5658

5759
int32_t VideoCaptureModulePipeWire::Init(const char* deviceUniqueId) {
60+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
61+
RTC_DCHECK_RUN_ON(&api_checker_);
62+
5863
absl::optional<int> id;
5964
id = rtc::StringToNumber<int>(deviceUniqueId);
6065
if (id == absl::nullopt)
@@ -113,6 +118,9 @@ static spa_pod* BuildFormat(spa_pod_builder* builder,
113118

114119
int32_t VideoCaptureModulePipeWire::StartCapture(
115120
const VideoCaptureCapability& capability) {
121+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
122+
RTC_DCHECK_RUN_ON(&api_checker_);
123+
116124
uint8_t buffer[1024] = {};
117125

118126
RTC_LOG(LS_VERBOSE) << "Creating new PipeWire stream for node " << node_id_;
@@ -166,6 +174,9 @@ int32_t VideoCaptureModulePipeWire::StartCapture(
166174
}
167175

168176
int32_t VideoCaptureModulePipeWire::StopCapture() {
177+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
178+
RTC_DCHECK_RUN_ON(&api_checker_);
179+
169180
PipeWireThreadLoopLock thread_loop_lock(session_->pw_main_loop_);
170181
if (stream_) {
171182
pw_stream_destroy(stream_);
@@ -177,13 +188,16 @@ int32_t VideoCaptureModulePipeWire::StopCapture() {
177188
}
178189

179190
bool VideoCaptureModulePipeWire::CaptureStarted() {
191+
RTC_DCHECK_RUN_ON(&api_checker_);
180192
MutexLock lock(&api_lock_);
181193

182194
return started_;
183195
}
184196

185197
int32_t VideoCaptureModulePipeWire::CaptureSettings(
186198
VideoCaptureCapability& settings) {
199+
RTC_DCHECK_RUN_ON(&api_checker_);
200+
187201
settings = _requestedCapability;
188202

189203
return 0;
@@ -196,12 +210,15 @@ void VideoCaptureModulePipeWire::OnStreamParamChanged(
196210
VideoCaptureModulePipeWire* that =
197211
static_cast<VideoCaptureModulePipeWire*>(data);
198212
RTC_DCHECK(that);
213+
RTC_CHECK_RUNS_SERIALIZED(&that->capture_checker_);
199214

200215
if (format && id == SPA_PARAM_Format)
201216
that->OnFormatChanged(format);
202217
}
203218

204219
void VideoCaptureModulePipeWire::OnFormatChanged(const struct spa_pod* format) {
220+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
221+
205222
uint32_t media_type, media_subtype;
206223

207224
if (spa_format_parse(format, &media_type, &media_subtype) < 0) {
@@ -295,6 +312,7 @@ void VideoCaptureModulePipeWire::OnStreamStateChanged(
295312
VideoCaptureModulePipeWire* that =
296313
static_cast<VideoCaptureModulePipeWire*>(data);
297314
RTC_DCHECK(that);
315+
RTC_CHECK_RUNS_SERIALIZED(&that->capture_checker_);
298316

299317
MutexLock lock(&that->api_lock_);
300318
switch (state) {
@@ -319,10 +337,13 @@ void VideoCaptureModulePipeWire::OnStreamProcess(void* data) {
319337
VideoCaptureModulePipeWire* that =
320338
static_cast<VideoCaptureModulePipeWire*>(data);
321339
RTC_DCHECK(that);
340+
RTC_CHECK_RUNS_SERIALIZED(&that->capture_checker_);
322341
that->ProcessBuffers();
323342
}
324343

325344
void VideoCaptureModulePipeWire::ProcessBuffers() {
345+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
346+
326347
while (pw_buffer* buffer = pw_stream_dequeue_buffer(stream_)) {
327348
struct spa_meta_header* h;
328349
h = static_cast<struct spa_meta_header*>(

modules/video_capture/linux/video_capture_pipewire.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@ class VideoCaptureModulePipeWire : public VideoCaptureImpl {
4343
void OnFormatChanged(const struct spa_pod* format);
4444
void ProcessBuffers();
4545

46-
rtc::scoped_refptr<PipeWireSession> session_;
47-
int node_id_;
48-
VideoCaptureCapability configured_capability_;
46+
const rtc::scoped_refptr<PipeWireSession> session_
47+
RTC_GUARDED_BY(capture_checker_);
48+
int node_id_ RTC_GUARDED_BY(capture_checker_);
49+
VideoCaptureCapability configured_capability_
50+
RTC_GUARDED_BY(capture_checker_);
4951
bool started_ RTC_GUARDED_BY(api_lock_);
5052

51-
struct pw_stream* stream_;
52-
struct spa_hook stream_listener_;
53+
struct pw_stream* stream_ RTC_GUARDED_BY(capture_checker_);
54+
struct spa_hook stream_listener_ RTC_GUARDED_BY(capture_checker_);
5355
};
5456
} // namespace videocapturemodule
5557
} // namespace webrtc

modules/video_capture/linux/video_capture_v4l2.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ VideoCaptureModuleV4L2::VideoCaptureModuleV4L2()
5858
_pool(NULL) {}
5959

6060
int32_t VideoCaptureModuleV4L2::Init(const char* deviceUniqueIdUTF8) {
61+
RTC_DCHECK_RUN_ON(&api_checker_);
62+
6163
int len = strlen((const char*)deviceUniqueIdUTF8);
6264
_deviceUniqueId = new (std::nothrow) char[len + 1];
6365
if (_deviceUniqueId) {
@@ -99,13 +101,19 @@ int32_t VideoCaptureModuleV4L2::Init(const char* deviceUniqueIdUTF8) {
99101
}
100102

101103
VideoCaptureModuleV4L2::~VideoCaptureModuleV4L2() {
104+
RTC_DCHECK_RUN_ON(&api_checker_);
105+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
106+
102107
StopCapture();
103108
if (_deviceFd != -1)
104109
close(_deviceFd);
105110
}
106111

107112
int32_t VideoCaptureModuleV4L2::StartCapture(
108113
const VideoCaptureCapability& capability) {
114+
RTC_DCHECK_RUN_ON(&api_checker_);
115+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
116+
109117
if (_captureStarted) {
110118
if (capability == _requestedCapability) {
111119
return 0;
@@ -291,6 +299,8 @@ int32_t VideoCaptureModuleV4L2::StartCapture(
291299
}
292300

293301
int32_t VideoCaptureModuleV4L2::StopCapture() {
302+
RTC_DCHECK_RUN_ON(&api_checker_);
303+
294304
if (!_captureThread.empty()) {
295305
{
296306
MutexLock lock(&capture_lock_);
@@ -300,6 +310,7 @@ int32_t VideoCaptureModuleV4L2::StopCapture() {
300310
_captureThread.Finalize();
301311
}
302312

313+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
303314
MutexLock lock(&capture_lock_);
304315
if (_captureStarted) {
305316
_captureStarted = false;
@@ -317,6 +328,7 @@ int32_t VideoCaptureModuleV4L2::StopCapture() {
317328
// critical section protected by the caller
318329

319330
bool VideoCaptureModuleV4L2::AllocateVideoBuffers() {
331+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
320332
struct v4l2_requestbuffers rbuffer;
321333
memset(&rbuffer, 0, sizeof(v4l2_requestbuffers));
322334

@@ -367,6 +379,7 @@ bool VideoCaptureModuleV4L2::AllocateVideoBuffers() {
367379
}
368380

369381
bool VideoCaptureModuleV4L2::DeAllocateVideoBuffers() {
382+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
370383
// unmap buffers
371384
for (int i = 0; i < _buffersAllocatedByDevice; i++)
372385
munmap(_pool[i].start, _pool[i].length);
@@ -384,10 +397,13 @@ bool VideoCaptureModuleV4L2::DeAllocateVideoBuffers() {
384397
}
385398

386399
bool VideoCaptureModuleV4L2::CaptureStarted() {
400+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
387401
return _captureStarted;
388402
}
389403

390404
bool VideoCaptureModuleV4L2::CaptureProcess() {
405+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
406+
391407
int retVal = 0;
392408
fd_set rSet;
393409
struct timeval timeout;
@@ -447,6 +463,7 @@ bool VideoCaptureModuleV4L2::CaptureProcess() {
447463

448464
int32_t VideoCaptureModuleV4L2::CaptureSettings(
449465
VideoCaptureCapability& settings) {
466+
RTC_DCHECK_RUN_ON(&api_checker_);
450467
settings = _requestedCapability;
451468

452469
return 0;

modules/video_capture/linux/video_capture_v4l2.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,24 @@ class VideoCaptureModuleV4L2 : public VideoCaptureImpl {
3838

3939
static void CaptureThread(void*);
4040
bool CaptureProcess();
41-
bool AllocateVideoBuffers();
42-
bool DeAllocateVideoBuffers();
41+
bool AllocateVideoBuffers() RTC_EXCLUSIVE_LOCKS_REQUIRED(capture_lock_);
42+
bool DeAllocateVideoBuffers() RTC_EXCLUSIVE_LOCKS_REQUIRED(capture_lock_);
4343

44-
rtc::PlatformThread _captureThread;
45-
Mutex capture_lock_;
44+
rtc::PlatformThread _captureThread RTC_GUARDED_BY(api_checker_);
45+
Mutex capture_lock_ RTC_ACQUIRED_BEFORE(api_lock_);
4646
bool quit_ RTC_GUARDED_BY(capture_lock_);
47-
int32_t _deviceId;
48-
int32_t _deviceFd;
47+
int32_t _deviceId RTC_GUARDED_BY(api_checker_);
48+
int32_t _deviceFd RTC_GUARDED_BY(capture_checker_);
4949

50-
int32_t _buffersAllocatedByDevice;
51-
VideoCaptureCapability configured_capability_;
52-
bool _captureStarted;
50+
int32_t _buffersAllocatedByDevice RTC_GUARDED_BY(capture_lock_);
51+
VideoCaptureCapability configured_capability_
52+
RTC_GUARDED_BY(capture_checker_);
53+
bool _captureStarted RTC_GUARDED_BY(capture_checker_);
5354
struct Buffer {
5455
void* start;
5556
size_t length;
5657
};
57-
Buffer* _pool;
58+
Buffer* _pool RTC_GUARDED_BY(capture_lock_);
5859
};
5960
} // namespace videocapturemodule
6061
} // namespace webrtc

modules/video_capture/video_capture_impl.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace webrtc {
2626
namespace videocapturemodule {
2727

2828
const char* VideoCaptureImpl::CurrentDeviceName() const {
29+
RTC_DCHECK_RUN_ON(&api_checker_);
2930
return _deviceUniqueId;
3031
}
3132

@@ -89,6 +90,7 @@ VideoCaptureImpl::VideoCaptureImpl()
8990
}
9091

9192
VideoCaptureImpl::~VideoCaptureImpl() {
93+
RTC_DCHECK_RUN_ON(&api_checker_);
9294
DeRegisterCaptureDataCallback();
9395
if (_deviceUniqueId)
9496
delete[] _deviceUniqueId;
@@ -114,6 +116,8 @@ void VideoCaptureImpl::DeRegisterCaptureDataCallback() {
114116
_rawDataCallBack = NULL;
115117
}
116118
int32_t VideoCaptureImpl::DeliverCapturedFrame(VideoFrame& captureFrame) {
119+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
120+
117121
UpdateFrameCount(); // frame count used for local frame rate callback.
118122

119123
if (_dataCallBack) {
@@ -127,6 +131,8 @@ void VideoCaptureImpl::DeliverRawFrame(uint8_t* videoFrame,
127131
size_t videoFrameLength,
128132
const VideoCaptureCapability& frameInfo,
129133
int64_t captureTime) {
134+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
135+
130136
UpdateFrameCount();
131137
_rawDataCallBack->OnRawFrame(videoFrame, videoFrameLength, frameInfo,
132138
_rotateFrame, captureTime);
@@ -136,6 +142,7 @@ int32_t VideoCaptureImpl::IncomingFrame(uint8_t* videoFrame,
136142
size_t videoFrameLength,
137143
const VideoCaptureCapability& frameInfo,
138144
int64_t captureTime /*=0*/) {
145+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
139146
MutexLock lock(&api_lock_);
140147

141148
const int32_t width = frameInfo.width;
@@ -229,6 +236,7 @@ int32_t VideoCaptureImpl::IncomingFrame(uint8_t* videoFrame,
229236

230237
int32_t VideoCaptureImpl::StartCapture(
231238
const VideoCaptureCapability& capability) {
239+
RTC_DCHECK_RUN_ON(&api_checker_);
232240
_requestedCapability = capability;
233241
return -1;
234242
}
@@ -264,6 +272,8 @@ bool VideoCaptureImpl::GetApplyRotation() {
264272
}
265273

266274
void VideoCaptureImpl::UpdateFrameCount() {
275+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
276+
267277
if (_incomingFrameTimesNanos[0] / rtc::kNumNanosecsPerMicrosec == 0) {
268278
// first no shift
269279
} else {
@@ -276,6 +286,8 @@ void VideoCaptureImpl::UpdateFrameCount() {
276286
}
277287

278288
uint32_t VideoCaptureImpl::CalculateFrameRate(int64_t now_ns) {
289+
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
290+
279291
int32_t num = 0;
280292
int32_t nrOfFrames = 0;
281293
for (num = 1; num < (kFrameRateCountHistorySize - 1); ++num) {

modules/video_capture/video_capture_impl.h

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
#include <stdint.h>
2020

2121
#include "api/scoped_refptr.h"
22+
#include "api/sequence_checker.h"
2223
#include "api/video/video_frame.h"
2324
#include "api/video/video_rotation.h"
2425
#include "api/video/video_sink_interface.h"
2526
#include "modules/video_capture/video_capture.h"
2627
#include "modules/video_capture/video_capture_config.h"
2728
#include "modules/video_capture/video_capture_defines.h"
29+
#include "rtc_base/race_checker.h"
2830
#include "rtc_base/synchronization/mutex.h"
2931
#include "rtc_base/system/rtc_export.h"
3032

@@ -86,36 +88,45 @@ class RTC_EXPORT VideoCaptureImpl : public VideoCaptureModule {
8688
VideoCaptureImpl();
8789
~VideoCaptureImpl() override;
8890

89-
char* _deviceUniqueId; // current Device unique name;
91+
// Calls to the public API must happen on a single thread.
92+
SequenceChecker api_checker_;
93+
// RaceChecker for members that can be accessed on the API thread while
94+
// capture is not happening, and on a callback thread otherwise.
95+
rtc::RaceChecker capture_checker_;
96+
// current Device unique name;
97+
char* _deviceUniqueId RTC_GUARDED_BY(api_checker_);
9098
Mutex api_lock_;
91-
VideoCaptureCapability _requestedCapability; // Should be set by platform
92-
// dependent code in
93-
// StartCapture.
99+
// Should be set by platform dependent code in StartCapture.
100+
VideoCaptureCapability _requestedCapability RTC_GUARDED_BY(api_checker_);
101+
94102
private:
95103
void UpdateFrameCount();
96104
uint32_t CalculateFrameRate(int64_t now_ns);
97-
int32_t DeliverCapturedFrame(VideoFrame& captureFrame);
105+
int32_t DeliverCapturedFrame(VideoFrame& captureFrame)
106+
RTC_EXCLUSIVE_LOCKS_REQUIRED(api_lock_);
98107
void DeliverRawFrame(uint8_t* videoFrame,
99108
size_t videoFrameLength,
100109
const VideoCaptureCapability& frameInfo,
101-
int64_t captureTime);
110+
int64_t captureTime)
111+
RTC_EXCLUSIVE_LOCKS_REQUIRED(api_lock_);
102112

103113
// last time the module process function was called.
104-
int64_t _lastProcessTimeNanos;
114+
int64_t _lastProcessTimeNanos RTC_GUARDED_BY(capture_checker_);
105115
// last time the frame rate callback function was called.
106-
int64_t _lastFrameRateCallbackTimeNanos;
116+
int64_t _lastFrameRateCallbackTimeNanos RTC_GUARDED_BY(capture_checker_);
107117

108-
rtc::VideoSinkInterface<VideoFrame>* _dataCallBack;
109-
RawVideoSinkInterface* _rawDataCallBack;
118+
rtc::VideoSinkInterface<VideoFrame>* _dataCallBack RTC_GUARDED_BY(api_lock_);
119+
RawVideoSinkInterface* _rawDataCallBack RTC_GUARDED_BY(api_lock_);
110120

111-
int64_t _lastProcessFrameTimeNanos;
121+
int64_t _lastProcessFrameTimeNanos RTC_GUARDED_BY(capture_checker_);
112122
// timestamp for local captured frames
113-
int64_t _incomingFrameTimesNanos[kFrameRateCountHistorySize];
114-
VideoRotation _rotateFrame; // Set if the frame should be rotated by the
115-
// capture module.
123+
int64_t _incomingFrameTimesNanos[kFrameRateCountHistorySize] RTC_GUARDED_BY(
124+
capture_checker_);
125+
// Set if the frame should be rotated by the capture module.
126+
VideoRotation _rotateFrame RTC_GUARDED_BY(api_lock_);
116127

117128
// Indicate whether rotation should be applied before delivered externally.
118-
bool apply_rotation_;
129+
bool apply_rotation_ RTC_GUARDED_BY(api_lock_);
119130
};
120131
} // namespace videocapturemodule
121132
} // namespace webrtc

0 commit comments

Comments
 (0)