diff options
Diffstat (limited to 'third_party/libwebrtc/modules/video_capture/linux/video_capture_v4l2.cc')
-rw-r--r-- | third_party/libwebrtc/modules/video_capture/linux/video_capture_v4l2.cc | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/third_party/libwebrtc/modules/video_capture/linux/video_capture_v4l2.cc b/third_party/libwebrtc/modules/video_capture/linux/video_capture_v4l2.cc index 08d23f7f58..b6e7e79a2a 100644 --- a/third_party/libwebrtc/modules/video_capture/linux/video_capture_v4l2.cc +++ b/third_party/libwebrtc/modules/video_capture/linux/video_capture_v4l2.cc @@ -62,6 +62,7 @@ VideoCaptureModuleV4L2::VideoCaptureModuleV4L2() _deviceId(-1), _deviceFd(-1), _buffersAllocatedByDevice(-1), + _streaming(false), _captureStarted(false), _pool(NULL) {} @@ -110,6 +111,7 @@ int32_t VideoCaptureModuleV4L2::Init(const char* deviceUniqueIdUTF8) { VideoCaptureModuleV4L2::~VideoCaptureModuleV4L2() { RTC_DCHECK_RUN_ON(&api_checker_); + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); StopCapture(); if (_deviceFd != -1) @@ -128,6 +130,14 @@ 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; @@ -289,18 +299,23 @@ int32_t VideoCaptureModuleV4L2::StartCapture( _requestedCapability = capability; _captureStarted = true; + _streaming = true; // start capture thread; - if (_captureThread.empty()) { - quit_ = false; - _captureThread = rtc::PlatformThread::SpawnJoinable( - [self = scoped_refptr(this)] { - while (self->CaptureProcess()) { - } - }, - "CaptureThread", - rtc::ThreadAttributes().SetPriority(rtc::ThreadPriority::kHigh)); + if (!_captureThread.empty()) { + return 0; + } + + quit_ = false; } + + _captureThread = rtc::PlatformThread::SpawnJoinable( + [self = scoped_refptr(this)] { + while (self->CaptureProcess()) { + } + }, + "CaptureThread", + rtc::ThreadAttributes().SetPriority(rtc::ThreadPriority::kHigh)); return 0; } @@ -316,9 +331,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); @@ -333,6 +351,7 @@ int32_t VideoCaptureModuleV4L2::StopCapture() { // critical section protected by the caller bool VideoCaptureModuleV4L2::AllocateVideoBuffers() { + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); struct v4l2_requestbuffers rbuffer; memset(&rbuffer, 0, sizeof(v4l2_requestbuffers)); @@ -383,6 +402,7 @@ bool VideoCaptureModuleV4L2::AllocateVideoBuffers() { } bool VideoCaptureModuleV4L2::DeAllocateVideoBuffers() { + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); // unmap buffers for (int i = 0; i < _buffersAllocatedByDevice; i++) munmap(_pool[i].start, _pool[i].length); @@ -400,10 +420,12 @@ bool VideoCaptureModuleV4L2::DeAllocateVideoBuffers() { } bool VideoCaptureModuleV4L2::CaptureStarted() { + RTC_DCHECK_RUN_ON(&api_checker_); return _captureStarted; } bool VideoCaptureModuleV4L2::CaptureProcess() { + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); int retVal = 0; struct pollfd rSet; @@ -432,7 +454,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; |