summaryrefslogtreecommitdiff
path: root/chromium/media/capture/video/fuchsia/video_capture_device_fuchsia.h
blob: 5998b5b111ee413e1c7e6643652f5f7a0a41e66e (plain)
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
// Copyright 2020 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 MEDIA_CAPTURE_VIDEO_FUCHSIA_VIDEO_CAPTURE_DEVICE_FUCHSIA_H_
#define MEDIA_CAPTURE_VIDEO_FUCHSIA_VIDEO_CAPTURE_DEVICE_FUCHSIA_H_

#include <fuchsia/camera3/cpp/fidl.h>

#include <memory>

#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "media/capture/video/video_capture_device.h"
#include "media/fuchsia/common/sysmem_client.h"
#include "media/fuchsia/common/vmo_buffer.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace media {

class CAPTURE_EXPORT VideoCaptureDeviceFuchsia final
    : public VideoCaptureDevice {
 public:
  // Returns pixel format to which video frames in the specified sysmem pixel
  // |format| will be converted. PIXEL_FORMAT_UNKNOWN is returned for
  // unsupported formats.
  static VideoPixelFormat GetConvertedPixelFormat(
      fuchsia::sysmem::PixelFormatType format);

  static bool IsSupportedPixelFormat(fuchsia::sysmem::PixelFormatType format);

  explicit VideoCaptureDeviceFuchsia(
      fidl::InterfaceHandle<fuchsia::camera3::Device> device);
  ~VideoCaptureDeviceFuchsia() override;

  VideoCaptureDeviceFuchsia(const VideoCaptureDeviceFuchsia&) = delete;
  VideoCaptureDeviceFuchsia& operator=(const VideoCaptureDeviceFuchsia&) =
      delete;

  // VideoCaptureDevice implementation.
  void AllocateAndStart(const VideoCaptureParams& params,
                        std::unique_ptr<Client> client) override;
  void StopAndDeAllocate() override;

 private:
  // Disconnects the |stream_| and resets related state.
  void DisconnectStream();

  // Reports the specified |error| to the client.
  void OnError(base::Location location,
               VideoCaptureError error,
               const std::string& reason);

  // Error handlers for the |device_| and |stream_|.
  void OnDeviceError(zx_status_t status);
  void OnStreamError(zx_status_t status);

  // Watches for resolution updates and updates |frame_size_| accordingly.
  void WatchResolution();

  // Callback for WatchResolution().
  void OnWatchResolutionResult(fuchsia::math::Size frame_size);

  // Watches for orientation updates and updates |orientation_| accordingly.
  void WatchOrientation();

  // Callback for WatchOrientation().
  void OnWatchOrientationResult(fuchsia::camera3::Orientation orientation);

  // Watches for sysmem buffer collection updates from the camera.
  void WatchBufferCollection();

  // Initializes buffer collection using the specified token. Initialization is
  // asynchronous. |buffer_reader_| will be set once the initialization is
  // complete. Old buffer collection are dropped synchronously (whether they
  // have finished initialization or not).
  void InitializeBufferCollection(
      fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>
          token_handle);

  // Callback for SysmemCollectionClient::AcquireBuffers().
  void OnBuffersAcquired(
      std::vector<VmoBuffer> buffers,
      const fuchsia::sysmem::SingleBufferSettings& buffer_settings);

  // Calls Stream::GetNextFrame() in a loop to receive incoming frames.
  void ReceiveNextFrame();

  // Processes new frames received by ReceiveNextFrame() and passes it to the
  // |client_|.
  void ProcessNewFrame(fuchsia::camera3::FrameInfo frame_info);

  fuchsia::camera3::DevicePtr device_;
  fuchsia::camera3::StreamPtr stream_;

  std::unique_ptr<Client> client_;

  SysmemAllocatorClient sysmem_allocator_;
  std::unique_ptr<SysmemCollectionClient> buffer_collection_;
  std::vector<VmoBuffer> buffers_;
  fuchsia::sysmem::ImageFormatConstraints buffers_format_;

  absl::optional<gfx::Size> frame_size_;
  fuchsia::camera3::Orientation orientation_ =
      fuchsia::camera3::Orientation::UP;

  base::TimeTicks start_time_;

  bool started_ = false;

  size_t frames_received_ = 0;

  THREAD_CHECKER(thread_checker_);
};

}  // namespace media

#endif  // MEDIA_CAPTURE_VIDEO_FUCHSIA_VIDEO_CAPTURE_DEVICE_FUCHSIA_H_