Merge to M87: Guard VideoCaptureDeviceAVFoundationFrameReceiver
The class VideoCaptureDeviceAVFoundationFrameReceiver cannot handle
concurrent calls. Make VideoCaptureDeviceAVFoundation guard all access
like VideoCaptureDeviceAVFoundationLegacy does.
[email protected]
(cherry picked from commit eafed0bb7242b0dd0cbc6e9b25807329fb81950a)
Bug: 1135246
Change-Id: I6ae5a810ed2df9af4de0b4412b3dfe906b666b41
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2454426
Reviewed-by: Markus Handell <[email protected]>
Commit-Queue: ccameron <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#814884}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2479702
Reviewed-by: ccameron <[email protected]>
Commit-Queue: Markus Handell <[email protected]>
Cr-Commit-Position: refs/branch-heads/4280@{#463}
Cr-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
diff --git a/media/capture/video/mac/video_capture_device_avfoundation_mac.h b/media/capture/video/mac/video_capture_device_avfoundation_mac.h
index d152e19..a4e4315 100644
--- a/media/capture/video/mac/video_capture_device_avfoundation_mac.h
+++ b/media/capture/video/mac/video_capture_device_avfoundation_mac.h
@@ -42,8 +42,11 @@
// The capture format that best matches the above attributes.
base::scoped_nsobject<AVCaptureDeviceFormat> _bestCaptureFormat;
- base::Lock _lock; // Protects concurrent setting and using |frameReceiver_|.
- media::VideoCaptureDeviceAVFoundationFrameReceiver* _frameReceiver; // weak.
+ // Protects concurrent setting and using |frameReceiver_|. Note that the
+ // GUARDED_BY decoration below does not have any effect.
+ base::Lock _lock;
+ media::VideoCaptureDeviceAVFoundationFrameReceiver* _frameReceiver
+ GUARDED_BY(_lock); // weak.
base::scoped_nsobject<AVCaptureSession> _captureSession;
diff --git a/media/capture/video/mac/video_capture_device_avfoundation_mac.mm b/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
index 5ebc7073..d54d34b 100644
--- a/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
+++ b/media/capture/video/mac/video_capture_device_avfoundation_mac.mm
@@ -553,6 +553,7 @@
char* baseAddress = 0;
size_t frameSize = 0;
media::ExtractBaseAddressAndLength(&baseAddress, &frameSize, sampleBuffer);
+ _lock.AssertAcquired();
_frameReceiver->ReceiveFrame(reinterpret_cast<const uint8_t*>(baseAddress),
frameSize, captureFormat, colorSpace, 0, 0,
timestamp);
@@ -588,6 +589,7 @@
frameSize = CVPixelBufferGetDataSize(pixelBuffer);
// Only contiguous buffers are supported.
CHECK(frameSize);
+ _lock.AssertAcquired();
_frameReceiver->ReceiveFrame(reinterpret_cast<const uint8_t*>(baseAddress),
frameSize, captureFormat, colorSpace, 0, 0,
timestamp);
@@ -608,6 +610,7 @@
handle.mach_port.reset(IOSurfaceCreateMachPort(ioSurface));
if (!handle.mach_port)
return NO;
+ _lock.AssertAcquired();
_frameReceiver->ReceiveExternalGpuMemoryBufferFrame(
std::move(handle),
std::make_unique<CMSampleBufferScopedAccessPermission>(sampleBuffer),
@@ -622,6 +625,13 @@
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection*)connection {
VLOG(3) << __func__;
+
+ // Concurrent calls into |_frameReceiver| are not supported, so take |_lock|
+ // before any of the subsequent paths.
+ base::AutoLock lock(_lock);
+ if (!_frameReceiver)
+ return;
+
// We have certain format expectation for capture output:
// For MJPEG, |sampleBuffer| is expected to always be a CVBlockBuffer.
// For other formats, |sampleBuffer| may be either CVBlockBuffer or