123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- // Copyright 2022 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef ASH_CAPTURE_MODE_FAKE_CAMERA_DEVICE_H_
- #define ASH_CAPTURE_MODE_FAKE_CAMERA_DEVICE_H_
- #include <memory>
- #include "ash/ash_export.h"
- #include "base/containers/flat_map.h"
- #include "base/time/time.h"
- #include "base/timer/timer.h"
- #include "media/capture/video/video_capture_device_info.h"
- #include "media/capture/video_capture_types.h"
- #include "mojo/public/cpp/bindings/pending_remote.h"
- #include "mojo/public/cpp/bindings/receiver_set.h"
- #include "services/video_capture/public/mojom/video_frame_handler.mojom.h"
- #include "services/video_capture/public/mojom/video_source.mojom.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "third_party/skia/include/core/SkBitmap.h"
- namespace ash {
- // A fake implementation of the `VideoSource` mojo API that represents a fake
- // camera in ash_unittests.
- class ASH_EXPORT FakeCameraDevice
- : public video_capture::mojom::VideoSource,
- public video_capture::mojom::VideoFrameAccessHandler {
- public:
- explicit FakeCameraDevice(const media::VideoCaptureDeviceInfo& device_info);
- FakeCameraDevice(const FakeCameraDevice&) = delete;
- FakeCameraDevice& operator=(const FakeCameraDevice&) = delete;
- ~FakeCameraDevice() override;
- // The max size of the `buffer_pool_` which contains the buffers backing the
- // video frames produced by this device.
- static constexpr size_t kMaxBufferCount = 4;
- // Returns the same bitmap used to paint the produced video frames from this
- // camera device for purposes of comparing them with the received frames in
- // tests.
- static SkBitmap GetProducedFrameAsBitmap(const gfx::Size& frame_size);
- const media::VideoCaptureDeviceInfo& device_info() const {
- return device_info_;
- }
- // Binds the given `pending_receiver` to this instance.
- void Bind(mojo::PendingReceiver<video_capture::mojom::VideoSource>
- pending_receiver);
- // Simulates a fatal error on this camera device, by sending an error of type
- // `kCrosHalV3DeviceDelegateMojoConnectionError` to the `VideoFrameHandler`.
- // See https://crbug.com/1316230 for more details.
- void TriggerFatalError();
- // video_capture::mojom::VideoSource:
- void CreatePushSubscription(
- mojo::PendingRemote<video_capture::mojom::VideoFrameHandler> subscriber,
- const media::VideoCaptureParams& requested_settings,
- bool force_reopen_with_new_settings,
- mojo::PendingReceiver<video_capture::mojom::PushVideoStreamSubscription>
- subscription,
- CreatePushSubscriptionCallback callback) override;
- // video_capture::mojom::VideoFrameAccessHandler:
- void OnFinishedConsumingBuffer(int32_t buffer_id) override;
- private:
- class Buffer;
- class Subscription;
- // Creates a new pending remote whose receiver is bound to this instance. The
- // pending remote will be sent to a remote `VideoFrameHandler` so it can
- // notify us when done consuming a buffer.
- mojo::PendingRemote<video_capture::mojom::VideoFrameAccessHandler>
- GetNewAccessHandlerRemote();
- // Handles the case when a subscriber `VideoFrameHandler` gets disconnected
- // from this instance.
- void OnSubscriberDisconnected(Subscription* subscription);
- // Called when the subscription activation changes or the settings used to
- // open this device changes. If this if for a specific `subscription`, it will
- // provided (i.e not null).
- void OnSubscriptionActivationChanged(Subscription* subscription);
- // Returns true if any of the current subscriptions to this device are active,
- // and therefore should be provided with video frames.
- bool IsAnySubscriptionActive() const;
- // Called repeatedly on every tick of `frame_timer_` which depends on the
- // frame desired to open this device.
- void OnNextFrame();
- // Allocates a new buffer (and therefore notifies active subscribers with
- // `OnNewBuffer()`) or reuses an existing one. Either way, the buffer is
- // returned. If all buffers in the `buffer_pool_` are used, and there's no
- // room for another buffer, active-non-suspended subscribers are notfied with
- // `OnFrameDropped()`, and nullptr is returned.
- Buffer* AllocateOrReuseBuffer();
- // Clears all the buffers in `buffer_pool_` and notifies active subscribers
- // with `OnBufferRetired()`.
- void RetireAllBuffers();
- // The device info this camera device has.
- const media::VideoCaptureDeviceInfo device_info_;
- mojo::ReceiverSet<video_capture::mojom::VideoSource>
- video_source_receiver_set_;
- mojo::ReceiverSet<video_capture::mojom::VideoFrameAccessHandler>
- access_handler_receiver_set_;
- // Maps each owned subscription instance by its instance ptr.
- base::flat_map<Subscription*, std::unique_ptr<Subscription>>
- subscriptions_map_;
- // The current settings used to open this device. It's a nullopt until a
- // subscription is created to this device.
- absl::optional<media::VideoCaptureParams> current_settings_;
- // Maps each buffer by its buffer ID.
- base::flat_map</*buffer_id=*/int, std::unique_ptr<Buffer>> buffer_pool_;
- // The time at which this device started producing video frames.
- base::Time start_time_;
- // The timer that invokes `OnNextFrame()` repeatedly depending on the frame
- // rate requested to open this device.
- base::RepeatingTimer frame_timer_;
- };
- } // namespace ash
- #endif // ASH_CAPTURE_MODE_FAKE_CAMERA_DEVICE_H_
|