File: fake_camera_device.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (150 lines) | stat: -rw-r--r-- 5,875 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright 2022 The Chromium Authors
// 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 <optional>

#include "ash/ash_export.h"
#include "base/containers/flat_map.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "media/capture/mojom/video_effects_manager.mojom.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 "services/video_effects/public/cpp/buildflags.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;

#if BUILDFLAG(ENABLE_VIDEO_EFFECTS)
  void RegisterVideoEffectsProcessor(
      mojo::PendingRemote<video_effects::mojom::VideoEffectsProcessor> remote)
      override;

  void RegisterReadonlyVideoEffectsManager(
      mojo::PendingRemote<media::mojom::ReadonlyVideoEffectsManager> remote)
      override;
#endif

  // 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.
  std::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_