Skip to content

Commit 823c702

Browse files
PehrsonsWebRTC LUCI CQ
authored andcommitted
In VideoCaptureV4L2 use requested/configured capability
VideoCaptureV4L2 has some members that are set in StartCapture during configuration of the device, but later accessed both on the capture thread and on the api thread (same as StartCapture) in CaptureSettings(), which can be called at any time. This is safe because they are written only on the api thread when the capture thread is not running. However, there is no helper class that separates the read and write modes to allow annotations and static analysis of the thread access of these members. This commit allows annotations to be added by making VideoCaptureV4L2 use: - VideoCaptureImpl::_requestedCapability for storing those members requested through StartCapture(), to allow access on the api thread through CaptureSettings(). - A new member configured_capability_ to replace those members mentioned in the first paragraph above. Writes to it happen only in StartCapture() and StopCapture(), while reads happen exclusively on the capture thread in between. Bug: webrtc:15181 Change-Id: I27e0f578e6ac2a2e6b0e34fbabfe4f743b296321 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/306122 Reviewed-by: Ilya Nikolaevskiy <[email protected]> Commit-Queue: Ilya Nikolaevskiy <[email protected]> Reviewed-by: Per Kjellander <[email protected]> Cr-Commit-Position: refs/heads/main@{#40290}
1 parent 51b8206 commit 823c702

File tree

2 files changed

+29
-39
lines changed

2 files changed

+29
-39
lines changed

modules/video_capture/linux/video_capture_v4l2.cc

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,7 @@ VideoCaptureModuleV4L2::VideoCaptureModuleV4L2()
5454
_deviceId(-1),
5555
_deviceFd(-1),
5656
_buffersAllocatedByDevice(-1),
57-
_currentWidth(-1),
58-
_currentHeight(-1),
59-
_currentFrameRate(-1),
6057
_captureStarted(false),
61-
_captureVideoType(VideoType::kI420),
6258
_pool(NULL) {}
6359

6460
int32_t VideoCaptureModuleV4L2::Init(const char* deviceUniqueIdUTF8) {
@@ -111,15 +107,17 @@ VideoCaptureModuleV4L2::~VideoCaptureModuleV4L2() {
111107
int32_t VideoCaptureModuleV4L2::StartCapture(
112108
const VideoCaptureCapability& capability) {
113109
if (_captureStarted) {
114-
if (capability.width == _currentWidth &&
115-
capability.height == _currentHeight &&
116-
_captureVideoType == capability.videoType) {
110+
if (capability == _requestedCapability) {
117111
return 0;
118112
} else {
119113
StopCapture();
120114
}
121115
}
122116

117+
// Set a baseline of configured parameters. It is updated here during
118+
// configuration, then read from the capture thread.
119+
configured_capability_ = capability;
120+
123121
MutexLock lock(&capture_lock_);
124122
// first open /dev/video device
125123
char device[20];
@@ -189,32 +187,32 @@ int32_t VideoCaptureModuleV4L2::StartCapture(
189187
video_fmt.fmt.pix.pixelformat = fmts[fmtsIdx];
190188

191189
if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
192-
_captureVideoType = VideoType::kYUY2;
190+
configured_capability_.videoType = VideoType::kYUY2;
193191
else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
194-
_captureVideoType = VideoType::kI420;
192+
configured_capability_.videoType = VideoType::kI420;
195193
else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420)
196-
_captureVideoType = VideoType::kYV12;
194+
configured_capability_.videoType = VideoType::kYV12;
197195
else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY)
198-
_captureVideoType = VideoType::kUYVY;
196+
configured_capability_.videoType = VideoType::kUYVY;
199197
else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12)
200-
_captureVideoType = VideoType::kNV12;
198+
configured_capability_.videoType = VideoType::kNV12;
201199
else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24)
202-
_captureVideoType = VideoType::kRGB24;
200+
configured_capability_.videoType = VideoType::kRGB24;
203201
else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
204-
_captureVideoType = VideoType::kBGR24;
202+
configured_capability_.videoType = VideoType::kBGR24;
205203
else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565)
206-
_captureVideoType = VideoType::kRGB565;
204+
configured_capability_.videoType = VideoType::kRGB565;
207205
else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_ABGR32 ||
208206
video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32)
209-
_captureVideoType = VideoType::kARGB;
207+
configured_capability_.videoType = VideoType::kARGB;
210208
else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_ARGB32 ||
211209
video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32)
212-
_captureVideoType = VideoType::kBGRA;
210+
configured_capability_.videoType = VideoType::kBGRA;
213211
else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGBA32)
214-
_captureVideoType = VideoType::kABGR;
212+
configured_capability_.videoType = VideoType::kABGR;
215213
else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG ||
216214
video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG)
217-
_captureVideoType = VideoType::kMJPEG;
215+
configured_capability_.videoType = VideoType::kMJPEG;
218216
else
219217
RTC_DCHECK_NOTREACHED();
220218

@@ -225,8 +223,8 @@ int32_t VideoCaptureModuleV4L2::StartCapture(
225223
}
226224

227225
// initialize current width and height
228-
_currentWidth = video_fmt.fmt.pix.width;
229-
_currentHeight = video_fmt.fmt.pix.height;
226+
configured_capability_.width = video_fmt.fmt.pix.width;
227+
configured_capability_.height = video_fmt.fmt.pix.height;
230228

231229
// Trying to set frame rate, before check driver capability.
232230
bool driver_framerate_support = true;
@@ -248,18 +246,17 @@ int32_t VideoCaptureModuleV4L2::StartCapture(
248246
if (ioctl(_deviceFd, VIDIOC_S_PARM, &streamparms) < 0) {
249247
RTC_LOG(LS_INFO) << "Failed to set the framerate. errno=" << errno;
250248
driver_framerate_support = false;
251-
} else {
252-
_currentFrameRate = capability.maxFPS;
253249
}
254250
}
255251
}
256252
// If driver doesn't support framerate control, need to hardcode.
257253
// Hardcoding the value based on the frame size.
258254
if (!driver_framerate_support) {
259-
if (_currentWidth >= 800 && _captureVideoType != VideoType::kMJPEG) {
260-
_currentFrameRate = 15;
255+
if (configured_capability_.width >= 800 &&
256+
configured_capability_.videoType != VideoType::kMJPEG) {
257+
configured_capability_.maxFPS = 15;
261258
} else {
262-
_currentFrameRate = 30;
259+
configured_capability_.maxFPS = 30;
263260
}
264261
}
265262

@@ -276,6 +273,7 @@ int32_t VideoCaptureModuleV4L2::StartCapture(
276273
return -1;
277274
}
278275

276+
_requestedCapability = capability;
279277
_captureStarted = true;
280278

281279
// start capture thread;
@@ -309,6 +307,8 @@ int32_t VideoCaptureModuleV4L2::StopCapture() {
309307
DeAllocateVideoBuffers();
310308
close(_deviceFd);
311309
_deviceFd = -1;
310+
311+
_requestedCapability = configured_capability_ = VideoCaptureCapability();
312312
}
313313

314314
return 0;
@@ -431,14 +431,10 @@ bool VideoCaptureModuleV4L2::CaptureProcess() {
431431
return true;
432432
}
433433
}
434-
VideoCaptureCapability frameInfo;
435-
frameInfo.width = _currentWidth;
436-
frameInfo.height = _currentHeight;
437-
frameInfo.videoType = _captureVideoType;
438434

439435
// convert to to I420 if needed
440436
IncomingFrame(reinterpret_cast<uint8_t*>(_pool[buf.index].start),
441-
buf.bytesused, frameInfo);
437+
buf.bytesused, configured_capability_);
442438
// enqueue the buffer again
443439
if (ioctl(_deviceFd, VIDIOC_QBUF, &buf) == -1) {
444440
RTC_LOG(LS_INFO) << "Failed to enqueue capture buffer";
@@ -451,10 +447,7 @@ bool VideoCaptureModuleV4L2::CaptureProcess() {
451447

452448
int32_t VideoCaptureModuleV4L2::CaptureSettings(
453449
VideoCaptureCapability& settings) {
454-
settings.width = _currentWidth;
455-
settings.height = _currentHeight;
456-
settings.maxFPS = _currentFrameRate;
457-
settings.videoType = _captureVideoType;
450+
settings = _requestedCapability;
458451

459452
return 0;
460453
}

modules/video_capture/linux/video_capture_v4l2.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,8 @@ class VideoCaptureModuleV4L2 : public VideoCaptureImpl {
4848
int32_t _deviceFd;
4949

5050
int32_t _buffersAllocatedByDevice;
51-
int32_t _currentWidth;
52-
int32_t _currentHeight;
53-
int32_t _currentFrameRate;
51+
VideoCaptureCapability configured_capability_;
5452
bool _captureStarted;
55-
VideoType _captureVideoType;
5653
struct Buffer {
5754
void* start;
5855
size_t length;

0 commit comments

Comments
 (0)