Commit eafed0bb authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

Guard VideoCaptureDeviceAVFoundationFrameReceiver

The class VideoCaptureDeviceAVFoundationFrameReceiver cannot handle
concurrent calls. Make VideoCaptureDeviceAVFoundation guard all access
like VideoCaptureDeviceAVFoundationLegacy does.

Bug: 1135246
Change-Id: I6ae5a810ed2df9af4de0b4412b3dfe906b666b41
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2454426Reviewed-by: default avatarMarkus Handell <handellm@google.com>
Commit-Queue: ccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#814884}
parent 32ea3ebe
...@@ -42,8 +42,11 @@ CAPTURE_EXPORT ...@@ -42,8 +42,11 @@ CAPTURE_EXPORT
// The capture format that best matches the above attributes. // The capture format that best matches the above attributes.
base::scoped_nsobject<AVCaptureDeviceFormat> _bestCaptureFormat; base::scoped_nsobject<AVCaptureDeviceFormat> _bestCaptureFormat;
base::Lock _lock; // Protects concurrent setting and using |frameReceiver_|. // Protects concurrent setting and using |frameReceiver_|. Note that the
media::VideoCaptureDeviceAVFoundationFrameReceiver* _frameReceiver; // weak. // GUARDED_BY decoration below does not have any effect.
base::Lock _lock;
media::VideoCaptureDeviceAVFoundationFrameReceiver* _frameReceiver
GUARDED_BY(_lock); // weak.
base::scoped_nsobject<AVCaptureSession> _captureSession; base::scoped_nsobject<AVCaptureSession> _captureSession;
......
...@@ -553,6 +553,7 @@ AVCaptureDeviceFormat* FindBestCaptureFormat( ...@@ -553,6 +553,7 @@ AVCaptureDeviceFormat* FindBestCaptureFormat(
char* baseAddress = 0; char* baseAddress = 0;
size_t frameSize = 0; size_t frameSize = 0;
media::ExtractBaseAddressAndLength(&baseAddress, &frameSize, sampleBuffer); media::ExtractBaseAddressAndLength(&baseAddress, &frameSize, sampleBuffer);
_lock.AssertAcquired();
_frameReceiver->ReceiveFrame(reinterpret_cast<const uint8_t*>(baseAddress), _frameReceiver->ReceiveFrame(reinterpret_cast<const uint8_t*>(baseAddress),
frameSize, captureFormat, colorSpace, 0, 0, frameSize, captureFormat, colorSpace, 0, 0,
timestamp); timestamp);
...@@ -588,6 +589,7 @@ AVCaptureDeviceFormat* FindBestCaptureFormat( ...@@ -588,6 +589,7 @@ AVCaptureDeviceFormat* FindBestCaptureFormat(
frameSize = CVPixelBufferGetDataSize(pixelBuffer); frameSize = CVPixelBufferGetDataSize(pixelBuffer);
// Only contiguous buffers are supported. // Only contiguous buffers are supported.
CHECK(frameSize); CHECK(frameSize);
_lock.AssertAcquired();
_frameReceiver->ReceiveFrame(reinterpret_cast<const uint8_t*>(baseAddress), _frameReceiver->ReceiveFrame(reinterpret_cast<const uint8_t*>(baseAddress),
frameSize, captureFormat, colorSpace, 0, 0, frameSize, captureFormat, colorSpace, 0, 0,
timestamp); timestamp);
...@@ -608,6 +610,7 @@ AVCaptureDeviceFormat* FindBestCaptureFormat( ...@@ -608,6 +610,7 @@ AVCaptureDeviceFormat* FindBestCaptureFormat(
handle.mach_port.reset(IOSurfaceCreateMachPort(ioSurface)); handle.mach_port.reset(IOSurfaceCreateMachPort(ioSurface));
if (!handle.mach_port) if (!handle.mach_port)
return NO; return NO;
_lock.AssertAcquired();
_frameReceiver->ReceiveExternalGpuMemoryBufferFrame( _frameReceiver->ReceiveExternalGpuMemoryBufferFrame(
std::move(handle), std::move(handle),
std::make_unique<CMSampleBufferScopedAccessPermission>(sampleBuffer), std::make_unique<CMSampleBufferScopedAccessPermission>(sampleBuffer),
...@@ -622,6 +625,13 @@ AVCaptureDeviceFormat* FindBestCaptureFormat( ...@@ -622,6 +625,13 @@ AVCaptureDeviceFormat* FindBestCaptureFormat(
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection*)connection { fromConnection:(AVCaptureConnection*)connection {
VLOG(3) << __func__; 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: // We have certain format expectation for capture output:
// For MJPEG, |sampleBuffer| is expected to always be a CVBlockBuffer. // For MJPEG, |sampleBuffer| is expected to always be a CVBlockBuffer.
// For other formats, |sampleBuffer| may be either CVBlockBuffer or // For other formats, |sampleBuffer| may be either CVBlockBuffer or
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment