CVE-2026-91730
Overview
Background
- `VideoCaptureDevice::InvalidateBuffers`
- a newly added (non-pure) virtual method on the base capture-device interface whose job is to signal that the device’s currently allocated frame buffers must be dropped rather than kept alive for reuse.
- `VideoCaptureDevice::Client`
- the per-device bridge object (declared in
video_capture_device_client.h) that owns the connection to the shared-memoryVideoCaptureBufferPool; each device forwardsInvalidateBuffers()toclient_->InvalidateBuffers(), which reaches the pool implementation landed in the sibling CL 1/6. - Buffer pool invalidation
- marking pooled shared-memory buffers as invalid so they are not silently reused for a new capture while a consumer may still hold or map the old handle, i.e. the cleanup step that prevents stale-buffer reuse.
- GetUserMedia
- the Web API path that grants a renderer camera access and streams captured frames to it through these pooled buffers, so any device that fails to invalidate leaves the renderer’s buffer view uncleaned.
Root Cause Analysis
The InvalidateBuffers capability was introduced across a six-CL series: CL 1/6 implemented the actual invalidation in the shared-memory buffer pool, and media::VideoCaptureDevice exposed a virtual InvalidateBuffers() entry point. The defect is that most concrete VideoCaptureDevice subclasses did not override the method, so on the code path that is supposed to reclaim buffers the call resolved to the base (no-op) implementation and never reached the pool for those device types — an incomplete-cleanup logic error rather than a missing bounds check.
As a result, buffers that were meant to be invalidated stayed live in the pool and could be recycled or remain mapped while a consumer still referenced the old content, violating the invariant that an invalidation request must propagate all the way from device to pool. This CL (3/6) fixes it by implementing InvalidateBuffers() in every device (Android, Apple, ChromeOS, Fuchsia, Linux/V4L2, WebRTC, DeckLink, file, fake, mock) so each one forwards to client_->InvalidateBuffers() and, through it, to the pool. Because the method is not yet pure virtual, the partial landing still tolerated gaps, but the follow-up CL noted in the message will mark it pure to guarantee no implementation is missed.
InvalidateBuffers) was wired into the pool and the base interface but not into the concrete device implementations, so the invalidation silently became a no-op for real capture devices; the fix restores the end-to-end path by having every device forward the call to its Client and thus to the buffer pool.Attack Path
- Start a capture stream
A renderer obtains camera access via GetUserMedia, causing a concrete
VideoCaptureDevice(e.g.VideoCaptureDeviceLinux,VideoCaptureDeviceApple,VideoCaptureDeviceAndroid) to allocate shared-memory frame buffers from the pool and share them with the consumer. - Trigger the invalidation event
An event that is supposed to reclaim buffers occurs (per the CL series, buffer invalidation on the pool side); the framework invokes
VideoCaptureDevice::InvalidateBuffers()expecting the buffers to be dropped. (inferred — the specific trigger lives in sibling CL 1/6, not in this diff.) - Invalidation is dropped
Before the fix the device had no override, so the call hit the base no-op and never reached
client_->InvalidateBuffers()or the pool; the buffers were not invalidated (incomplete cleanup). - Stale buffer persists / is reused The un-invalidated shared-memory buffer remains valid and can be recycled for new content or stay mapped by the consumer, allowing access to buffer contents that should have been cleaned up. (inferred — the diff shows only the missing forwarding, not a concrete disclosure or corruption sink.)
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifmedia/capture/video/android/video_capture_device_android.cc |
modified | |
ifmedia/capture/video/apple/video_capture_device_apple.mm |
modified | |
ifmedia/capture/video/chromeos/video_capture_device_chromeos_delegate.cc |
modified | |
ifmedia/capture/video/fake_video_capture_device.cc |
modified | |
ifmedia/capture/video/fuchsia/video_capture_device_fuchsia.cc |
modified |
Files Changed
media/capture/video/mock_device_factory.ccmedia/capture/video/linux/v4l2_capture_delegate_gpu_helper_unittest.ccmedia/capture/video/fake_video_capture_device.ccmedia/capture/video/linux/video_capture_device_webrtc.hmedia/capture/video/linux/v4l2_capture_delegate_unittest.ccmedia/capture/video/linux/v4l2_capture_delegate.ccmedia/capture/video/linux/video_capture_device_linux.ccmedia/capture/video/apple/video_capture_device_apple.mmmedia/capture/video/fake_video_capture_device_factory.ccmedia/capture/video/chromeos/camera_device_context.hmedia/capture/video/mock_device.ccmedia/capture/video/mac/video_capture_device_decklink_mac.hmedia/capture/video/chromeos/video_capture_device_chromeos_halv3.hmedia/capture/video/file_video_capture_device.hmedia/capture/video/video_capture_device_client.hmedia/capture/video/chromeos/video_capture_device_chromeos_delegate.ccmedia/capture/video/fuchsia/video_capture_device_fuchsia.hmedia/capture/video/win/video_capture_device_mf_win.hmedia/capture/video/chromeos/camera_device_context.ccmedia/capture/video/chromeos/mock_video_capture_client.hmedia/capture/video/chromeos/video_capture_device_chromeos_halv3.ccmedia/capture/video/android/video_capture_device_android.ccmedia/capture/video/fuchsia/video_capture_device_fuchsia.ccmedia/capture/video/video_capture_device.hmedia/capture/video/mock_device.hmedia/capture/video/fake_video_capture_device.hmedia/capture/video/linux/video_capture_device_linux.hmedia/capture/video/win/video_capture_device_win.hmedia/capture/video/linux/v4l2_capture_delegate.hmedia/capture/video/win/video_capture_device_mf_win.ccmedia/capture/video/mac/video_capture_device_decklink_mac.mmmedia/capture/video/linux/video_capture_device_webrtc.ccmedia/capture/video/android/video_capture_device_android.hmedia/capture/video/win/video_capture_device_win.ccmedia/capture/video/win/video_capture_device_mf_win_unittest.ccmedia/capture/video/video_capture_device_client.ccmedia/capture/video/mock_video_capture_device_client.hmedia/capture/video/fuchsia/video_capture_device_fuchsia_test.ccmedia/capture/video/apple/video_capture_device_apple.hmedia/capture/video/file_video_capture_device.ccmedia/capture/video/chromeos/video_capture_device_chromeos_delegate.h
Audit Directions
- Non-pure virtual interface pointsAudit any newly added virtual method that is intentionally left non-pure “to allow partial landing”; every concrete subclass that silently inherits a no-op is a candidate for the same incomplete-cleanup gap until the method is made pure virtual.
- Cleanup/teardown fan-outReview lifecycle operations (stop, reconfigure, context-loss, invalidate) that must reach a shared resource (buffer pools, GPU handles, shared memory) through a chain of device/delegate/context objects, and confirm every hop in the chain forwards the call rather than dropping it.
- Shared-memory buffer reuseLook for
VideoCaptureBufferPooland cross-process buffer handoffs where a buffer can be recycled while a consumer still holds it, and verify an invalidation or reference-drop step actually executes before reuse for all device backends.
Patch
From 581a1e54096ae8f868a6eb78fd5d228f912711af Mon Sep 17 00:00:00 2001 From: Ilya Nikolaevskiy <[email protected]> Date: Wed, 19 Aug 2026 04:42:16 -0700 Subject: [PATCH] Implement InvalidateBuffers for video capture (cl 3/6) This CL implements InvalidateBuffers for all video capture devices in media/capture and exposes it in virtual method of media::VideoCaptureDevice, but it isn't pure virtual yet to allow partial landing. All devices delegate the call to VideoCaptureDevice::Client, which forwards it to the pool, which already has the feature implemented in cl 1/6. Future CL will mark it pure virtual to ensure that no interface implementation was missed. Bug: 543640868 Change-Id: I58e4dd5c72acb8ed461f7aaeadb671cd32ed2160 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8257270 Reviewed-by: Guido Urdaneta <[email protected]> Commit-Queue: Ilya Nikolaevskiy <[email protected]> Cr-Commit-Position: refs/heads/main@{#1682195} --- diff --git a/media/capture/video/android/video_capture_device_android.cc b/media/capture/video/android/video_capture_device_android.cc index 9b2c8823f7..95e8570 100644 --- a/media/capture/video/android/video_capture_device_android.cc +++ b/media/capture/video/android/video_capture_device_android.cc @@ -1091,3 +1091,10 @@ } // namespace media DEFINE_JNI(VideoCapture) + +void VideoCaptureDeviceAndroid::InvalidateBuffers() { + base::AutoLock lock(lock_); + if (client_) { + client_->InvalidateBuffers(); + } +} diff --git a/media/capture/video/android/video_capture_device_android.h b/media/capture/video/android/video_capture_device_android.h index e67415f..fee2452 100644 --- a/media/capture/video/android/video_capture_device_android.h +++ b/media/capture/video/android/video_capture_device_android.h @@ -117,6 +117,7 @@ void SetPhotoOptions(mojom::PhotoSettingsPtr settings, SetPhotoOptionsCallback callback) override; void TakePhoto(TakePhotoCallback callback) override; + void InvalidateBuffers() override; // VideoCaptureGpuContextLostObserver implementation. void OnContextLost() override; diff --git a/media/capture/video/apple/video_capture_device_apple.h b/media/capture/video/apple/video_capture_device_apple.h index aeec941..6b89e02 100644 --- a/media/capture/video/apple/video_capture_device_apple.h +++ b/media/capture/video/apple/video_capture_device_apple.h @@ -63,6 +63,7 @@ std::unique_ptr<VideoCaptureDevice::Client> client) override; void StopAndDeAllocate() override; void TakePhoto(TakePhotoCallback callback) override; + void InvalidateBuffers() override; void GetPhotoState(GetPhotoStateCallback callback) override; void SetPhotoOptions(mojom::PhotoSettingsPtr settings, SetPhotoOptionsCallback callback) override; diff --git a/media/capture/video/apple/video_capture_device_apple.mm b/media/capture/video/apple/video_capture_device_apple.mm index 806b1480..062dcb0 100644 --- a/media/capture/video/apple/video_capture_device_apple.mm +++ b/media/capture/video/apple/video_capture_device_apple.mm @@ -402,4 +402,11 @@ return metadata; } +void VideoCaptureDeviceApple::InvalidateBuffers() { + DCHECK(task_runner_->BelongsToCurrentThread()); + if (client_) { + client_->InvalidateBuffers(); + } +} + } // namespace media diff --git a/media/capture/video/chromeos/camera_device_context.cc b/media/capture/video/chromeos/camera_device_context.cc index b68c6bd..dd36ee4f 100644 --- a/media/capture/video/chromeos/camera_device_context.cc +++ b/media/capture/video/chromeos/camera_device_context.cc @@ -199,4 +199,11 @@ } } +void CameraDeviceContext::InvalidateBuffers(ClientType client_type) { + base::AutoLock lock(client_lock_); + if (clients_.count(client_type)) { + clients_[client_type]->InvalidateBuffers(); + } +} + } // namespace media diff --git a/media/capture/video/chromeos/camera_device_context.h b/media/capture/video/chromeos/camera_device_context.h index 5cc9f65..d1629697 100644 --- a/media/capture/video/chromeos/camera_device_context.h +++ b/media/capture/video/chromeos/camera_device_context.h @@ -113,6 +113,7 @@ bool AddClient(ClientType client_type, std::unique_ptr<VideoCaptureDevice::Client> client); void RemoveClient(ClientType client_type); + void InvalidateBuffers(ClientType client_type); void SetState(State state); State GetState(); diff --git a/media/capture/video/chromeos/mock_video_capture_client.h b/media/capture/video/chromeos/mock_video_capture_client.h index 61e6cff6..ea3863e 100644 --- a/media/capture/video/chromeos/mock_video_capture_client.h +++ b/media/capture/video/chromeos/mock_video_capture_client.h @@ -28,6 +28,7 @@ MOCK_METHOD1(OnFrameDropped, void(media::VideoCaptureFrameDropReason reason)); MOCK_CONST_METHOD0(GetBufferPoolUtilization, double(void)); MOCK_METHOD0(OnStarted, void(void)); + MOCK_METHOD0(InvalidateBuffers, void()); explicit MockVideoCaptureClient(); diff --git a/media/capture/video/chromeos/video_capture_device_chromeos_delegate.cc b/media/capture/video/chromeos/video_capture_device_chromeos_delegate.cc index d21e20e..c17f2955 100644 --- a/media/capture/video/chromeos/video_capture_device_chromeos_delegate.cc +++ b/media/capture/video/chromeos/video_capture_device_chromeos_delegate.cc @@ -343,4 +343,12 @@ } } +void VideoCaptureDeviceChromeOSDelegate::InvalidateBuffers( + ClientType client_type) { + DCHECK(capture_task_runner_->BelongsToCurrentThread()); + if (device_context_) { + device_context_->InvalidateBuffers(client_type); + } +} + } // namespace media diff --git a/media/capture/video/chromeos/video_capture_device_chromeos_delegate.h b/media/capture/video/chromeos/video_capture_device_chromeos_delegate.h index 3834033..7723165 100644 --- a/media/capture/video/chromeos/video_capture_device_chromeos_delegate.h +++ b/media/capture/video/chromeos/video_capture_device_chromeos_delegate.h @@ -49,6 +49,7 @@ std::unique_ptr<VideoCaptureDevice::Client> client, ClientType client_type); void StopAndDeAllocate(ClientType client_type); + void InvalidateBuffers(ClientType client_type); void TakePhoto(VideoCaptureDevice::TakePhotoCallback callback); void GetPhotoState(VideoCaptureDevice::GetPhotoStateCallback callback); void SetPhotoOptions(mojom::PhotoSettingsPtr settings, diff --git a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc index 3ebafb4..0111d20 100644 --- a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc +++ b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.cc @@ -52,4 +52,8 @@ vcd_delegate_->SetPhotoOptions(std::move(settings), std::move(callback)); } +void VideoCaptureDeviceChromeOSHalv3::InvalidateBuffers() { + vcd_delegate_->InvalidateBuffers(client_type_); +} + } // namespace media diff --git a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h index cca2b4f3..ede2ee6 100644 --- a/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h +++ b/media/capture/video/chromeos/video_capture_device_chromeos_halv3.h @@ -37,6 +37,7 @@ void AllocateAndStart(const VideoCaptureParams& params, std::unique_ptr<Client> client) final; void StopAndDeAllocate() final; + void InvalidateBuffers() final; void TakePhoto(TakePhotoCallback callback) final; void GetPhotoState(GetPhotoStateCallback callback) final; void SetPhotoOptions(mojom::PhotoSettingsPtr settings, diff --git a/media/capture/video/fake_video_capture_device.cc b/media/capture/video/fake_video_capture_device.cc index fd0975a..8258d516 100644 --- a/media/capture/video/fake_video_capture_device.cc +++ b/media/capture/video/fake_video_capture_device.cc @@ -216,6 +216,11 @@ } virtual void PaintAndDeliverNextFrame(base::TimeDelta timestamp_to_paint) = 0; + void InvalidateBuffers() { + CHECK(client_); + client_->InvalidateBuffers(); + } + protected: base::TimeDelta CalculateTimeSinceFirstInvocation(base::TimeTicks now) { if (first_ref_time_.is_null()) @@ -987,6 +992,12 @@ /*capture_begin_timestamp=*/std::nullopt, /*metadata=*/std::nullopt); } +void FakeVideoCaptureDevice::InvalidateBuffers() { + if (frame_deliverer_) { + frame_deliverer_->InvalidateBuffers(); + } +} + void FakeVideoCaptureDevice::BeepAndScheduleNextCapture( base::TimeTicks expected_execution_time) { DCHECK(thread_checker_.CalledOnValidThread()); diff --git a/media/capture/video/fake_video_capture_device.h b/media/capture/video/fake_video_capture_device.h index b729fd1..85b052f 100644 --- a/media/capture/video/fake_video_capture_device.h +++ b/media/capture/video/fake_video_capture_device.h @@ -83,6 +83,7 @@ void SetPhotoOptions(mojom::PhotoSettingsPtr settings, SetPhotoOptionsCallback callback) override; void TakePhoto(TakePhotoCallback callback) override; + void InvalidateBuffers() override; private: void BeepAndScheduleNextCapture(base::TimeTicks expected_execution_time); diff --git a/media/capture/video/fake_video_capture_device_factory.cc b/media/capture/video/fake_video_capture_device_factory.cc index 86fe926..920c9d3 100644 --- a/media/capture/video/fake_video_capture_device_factory.cc +++ b/media/capture/video/fake_video_capture_device_factory.cc @@ -97,6 +97,7 @@ void SetPhotoOptions(media::mojom::PhotoSettingsPtr settings, SetPhotoOptionsCallback callback) override {} void TakePhoto(TakePhotoCallback callback) override {} + void InvalidateBuffers() override {} }; } // anonymous namespace diff --git a/media/capture/video/file_video_capture_device.cc b/media/capture/video/file_video_capture_device.cc index e5867be..10ad1ce 100644 --- a/media/capture/video/file_video_capture_device.cc +++ b/media/capture/video/file_video_capture_device.cc @@ -764,4 +764,8 @@ next_frame_time_ - current_time); } +void FileVideoCaptureDevice::InvalidateBuffers() { + client_->InvalidateBuffers(); +} + } // namespace media diff --git a/media/capture/video/file_video_capture_device.h b/media/capture/video/file_video_capture_device.h index ec822f5b..8e8a9f6 100644 --- a/media/capture/video/file_video_capture_device.h +++ b/media/capture/video/file_video_capture_device.h @@ -54,6 +54,7 @@ const VideoCaptureParams& params, std::unique_ptr<VideoCaptureDevice::Client> client) override; void StopAndDeAllocate() override; + void InvalidateBuffers() override; void GetPhotoState(GetPhotoStateCallback callback) override; void SetPhotoOptions(mojom::PhotoSettingsPtr settings, SetPhotoOptionsCallback callback) override; diff --git a/media/capture/video/fuchsia/video_capture_device_fuchsia.cc b/media/capture/video/fuchsia/video_capture_device_fuchsia.cc index 8d0e039..0750df3 100644 --- a/media/capture/video/fuchsia/video_capture_device_fuchsia.cc +++ b/media/capture/video/fuchsia/video_capture_device_fuchsia.cc @@ -471,4 +471,10 @@ // Frame buffer is returned to the device by dropping the |frame_info|. } +void VideoCaptureDeviceFuchsia::InvalidateBuffers() { + if (client_) { + client_->InvalidateBuffers(); + } +} + } // namespace media diff --git a/media/capture/video/fuchsia/video_capture_device_fuchsia.h b/media/capture/video/fuchsia/video_capture_device_fuchsia.h index d0a2d09..9693777 100644 --- a/media/capture/video/fuchsia/video_capture_device_fuchsia.h +++ b/media/capture/video/fuchsia/video_capture_device_fuchsia.h @@ -43,6 +43,7 @@ void AllocateAndStart(const VideoCaptureParams& params, std::unique_ptr<Client> client) override; void StopAndDeAllocate() override; + void InvalidateBuffers() override; private: // Disconnects the |stream_| and resets related state. diff --git a/media/capture/video/linux/v4l2_capture_delegate.cc b/media/capture/video/linux/v4l2_capture_delegate.cc index 3cb4c5d00..103b9ad1 100644 --- a/media/capture/video/linux/v4l2_capture_delegate.cc +++ b/media/capture/video/linux/v4l2_capture_delegate.cc @@ -1446,4 +1446,8 @@ return true; } +void V4L2CaptureDelegate::InvalidateBuffers() { + client_->InvalidateBuffers(); +} + } // namespace media diff --git a/media/capture/video/linux/v4l2_capture_delegate.h b/media/capture/video/linux/v4l2_capture_delegate.h index 828cfc1..c4f5a01 100644 --- a/media/capture/video/linux/v4l2_capture_delegate.h +++ b/media/capture/video/linux/v4l2_capture_delegate.h @@ -71,6 +71,7 @@ float frame_rate, std::unique_ptr<VideoCaptureDevice::Client> client); void StopAndDeAllocate(); + void InvalidateBuffers(); void TakePhoto(VideoCaptureDevice::TakePhotoCallback callback); diff --git a/media/capture/video/linux/video_capture_device_linux.cc b/media/capture/video/linux/video_capture_device_linux.cc index e3c13fe..ec49c07 100644 --- a/media/capture/video/linux/video_capture_device_linux.cc +++ b/media/capture/video/linux/video_capture_device_linux.cc @@ -154,4 +154,12 @@ waiter->Signal(); } +void VideoCaptureDeviceLinux::InvalidateBuffers() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(capture_impl_); + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&V4L2CaptureDelegate::InvalidateBuffers, + capture_impl_->GetWeakPtr())); +} + } // namespace media diff --git a/media/capture/video/linux/video_capture_device_linux.h b/media/capture/video/linux/video_capture_device_linux.h index 9a352d1..5916184 100644 --- a/media/capture/video/linux/video_capture_device_linux.h +++ b/media/capture/video/linux/video_capture_device_linux.h @@ -49,6 +49,7 @@ void AllocateAndStart(const VideoCaptureParams& params, std::unique_ptr<Client> client) override; void StopAndDeAllocate() override; + void InvalidateBuffers() override; void TakePhoto(TakePhotoCallback callback) override; void GetPhotoState(GetPhotoStateCallback callback) override; void SetPhotoOptions(mojom::PhotoSettingsPtr settings, diff --git a/media/capture/video/linux/video_capture_device_webrtc.cc b/media/capture/video/linux/video_capture_device_webrtc.cc index 7f1af53..006e1b0 100644 --- a/media/capture/video/linux/video_capture_device_webrtc.cc +++ b/media/capture/video/linux/video_capture_device_webrtc.cc @@ -162,3 +162,9 @@ } } // namespace media + +namespace media { +void VideoCaptureDeviceWebRtc::InvalidateBuffers() { + client_->InvalidateBuffers(); +} +} // namespace media diff --git a/media/capture/video/linux/video_capture_device_webrtc.h b/media/capture/video/linux/video_capture_device_webrtc.h index 035b2e3..4aabe48 100644 --- a/media/capture/video/linux/video_capture_device_webrtc.h +++ b/media/capture/video/linux/video_capture_device_webrtc.h @@ -46,6 +46,7 @@ void GetPhotoState(GetPhotoStateCallback callback) override; void SetPhotoOptions(mojom::PhotoSettingsPtr settings, SetPhotoOptionsCallback callback) override; + void InvalidateBuffers() override; int32_t OnRawFrame(uint8_t* video_frame, size_t video_frame_length, diff --git a/media/capture/video/mac/video_capture_device_decklink_mac.h b/media/capture/video/mac/video_capture_device_decklink_mac.h index 8f7b14f0..449debe 100644 --- a/media/capture/video/mac/video_capture_device_decklink_mac.h +++ b/media/capture/video/mac/video_capture_device_decklink_mac.h @@ -78,6 +78,7 @@ const VideoCaptureParams& params, std::unique_ptr<VideoCaptureDevice::Client> client) override; void StopAndDeAllocate() override; + void InvalidateBuffers() override; // Protects concurrent setting and using of |client_|. base::Lock lock_; diff --git a/media/capture/video/mac/video_capture_device_decklink_mac.mm b/media/capture/video/mac/video_capture_device_decklink_mac.mm index 2c0764d..35487648 100644 --- a/media/capture/video/mac/video_capture_device_decklink_mac.mm +++ b/media/capture/video/mac/video_capture_device_decklink_mac.mm @@ -510,4 +510,9 @@ decklink_capture_delegate_->StopAndDeAllocate(); } +void VideoCaptureDeviceDeckLinkMac::InvalidateBuffers() { + base::AutoLock lock(lock_); + client_->InvalidateBuffers(); +} + } // namespace media diff --git a/media/capture/video/mock_device.cc b/media/capture/video/mock_device.cc index b1e36d1..d9c6f3b 100644 --- a/media/capture/video/mock_device.cc +++ b/media/capture/video/mock_device.cc @@ -61,3 +61,10 @@ } } // namespace media + +namespace media { +void MockDevice::InvalidateBuffers() { + client_->InvalidateBuffers(); +} + +} // namespace media diff --git a/media/capture/video/mock_device.h b/media/capture/video/mock_device.h index c813964..c43fabd 100644 --- a/media/capture/video/mock_device.h +++ b/media/capture/video/mock_device.h @@ -43,6 +43,7 @@ void SetPhotoOptions(media::mojom::PhotoSettingsPtr settings, SetPhotoOptionsCallback callback) override; ... (file diff truncated)
Regression Test / PoC
diff --git a/media/capture/video/fuchsia/video_capture_device_fuchsia_test.cc b/media/capture/video/fuchsia/video_capture_device_fuchsia_test.cc
index a48f6f6..7299af6e29 100644
--- a/media/capture/video/fuchsia/video_capture_device_fuchsia_test.cc
+++ b/media/capture/video/fuchsia/video_capture_device_fuchsia_test.cc
@@ -107,6 +107,7 @@
private:
// VideoCaptureDevice::Client implementation.
void OnCaptureConfigurationChanged() override {}
+ void InvalidateBuffers() final {}
void OnStarted() final {
EXPECT_FALSE(started_);
diff --git a/media/capture/video/linux/v4l2_capture_delegate_gpu_helper_unittest.cc b/media/capture/video/linux/v4l2_capture_delegate_gpu_helper_unittest.cc
index 422fb78..3125fa6c 100644
--- a/media/capture/video/linux/v4l2_capture_delegate_gpu_helper_unittest.cc
+++ b/media/capture/video/linux/v4l2_capture_delegate_gpu_helper_unittest.cc
@@ -96,6 +96,7 @@
const std::string&));
MOCK_METHOD1(OnFrameDropped, void(VideoCaptureFrameDropReason));
+ MOCK_METHOD0(InvalidateBuffers, void());
double GetBufferPoolUtilization() const override { return 0.0; }
diff --git a/media/capture/video/linux/v4l2_capture_delegate_unittest.cc b/media/capture/video/linux/v4l2_capture_delegate_unittest.cc
index 9f33db8e..1aa6cff 100644
--- a/media/capture/video/linux/v4l2_capture_delegate_unittest.cc
+++ b/media/capture/video/linux/v4l2_capture_delegate_unittest.cc
@@ -309,6 +309,7 @@
const std::string&));
MOCK_METHOD1(OnFrameDropped, void(VideoCaptureFrameDropReason));
+ MOCK_METHOD0(InvalidateBuffers, void());
double GetBufferPoolUtilization() const override { return 0.0; }
diff --git a/media/capture/video/win/video_capture_device_mf_win_unittest.cc b/media/capture/video/win/video_capture_device_mf_win_unittest.cc
index a7e5e0e..f73251b 100644
--- a/media/capture/video/win/video_capture_device_mf_win_unittest.cc
+++ b/media/capture/video/win/video_capture_device_mf_win_unittest.cc
@@ -136,6 +136,7 @@
double GetBufferPoolUtilization() const override { return 0.0; }
MOCK_METHOD0(OnStarted, void());
+ MOCK_METHOD0(InvalidateBuffers, void());
};
class MockImageCaptureClient