summaryrefslogtreecommitdiff
path: root/chromium/media/capture/video/chromeos/stream_buffer_manager.h
blob: 7927e32f5d16cdf7792308ec7df466f6709077a9 (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
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_CAPTURE_VIDEO_CHROMEOS_STREAM_BUFFER_MANAGER_H_
#define MEDIA_CAPTURE_VIDEO_CHROMEOS_STREAM_BUFFER_MANAGER_H_

#include <cstring>
#include <initializer_list>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <unordered_map>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/containers/queue.h"
#include "base/memory/weak_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "media/capture/video/chromeos/camera_device_context.h"
#include "media/capture/video/chromeos/camera_device_delegate.h"
#include "media/capture/video/chromeos/mojom/camera3.mojom.h"
#include "media/capture/video_capture_types.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace gfx {

class GpuMemoryBuffer;

}  // namespace gfx

namespace gpu {

class GpuMemoryBufferImpl;
class GpuMemoryBufferSupport;

}  // namespace gpu

namespace media {

class CameraBufferFactory;

struct BufferInfo;

// StreamBufferManager is responsible for managing the buffers of the
// stream.  StreamBufferManager allocates buffers according to the given
// stream configuration.
class CAPTURE_EXPORT StreamBufferManager final {
 public:
  using Buffer = VideoCaptureDevice::Client::Buffer;

  StreamBufferManager() = delete;

  StreamBufferManager(
      CameraDeviceContext* device_context,
      bool video_capture_use_gmb,
      std::unique_ptr<CameraBufferFactory> camera_buffer_factory);

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

  ~StreamBufferManager();

  void ReserveBuffer(StreamType stream_type);

  gfx::GpuMemoryBuffer* GetGpuMemoryBufferById(StreamType stream_type,
                                               uint64_t buffer_ipc_id);

  // Acquires the VCD client buffer specified by |stream_type| and
  // |buffer_ipc_id|, with optional rotation applied.  |rotation| is the
  // clockwise degrees that the source frame would be rotated to, and the valid
  // values are 0, 90, 180, and 270.  Returns the VideoCaptureFormat of the
  // returned buffer in |format|.
  //
  // TODO(crbug.com/990682): Remove the |rotation| arg when we disable the
  // camera frame rotation for good.
  absl::optional<Buffer> AcquireBufferForClientById(StreamType stream_type,
                                                    uint64_t buffer_ipc_id,
                                                    VideoCaptureFormat* format);

  VideoCaptureFormat GetStreamCaptureFormat(StreamType stream_type);

  // Checks if all streams are available. For output stream, it is available if
  // it has free buffers. For input stream, it is always available.
  bool HasFreeBuffers(const std::set<StreamType>& stream_types);

  // Checks if the target stream types have been configured or not.
  bool HasStreamsConfigured(std::initializer_list<StreamType> stream_types);

  // Sets up the stream context and allocate buffers according to the
  // configuration specified in |stream|.
  void SetUpStreamsAndBuffers(
      base::flat_map<ClientType, VideoCaptureParams> capture_params,
      const cros::mojom::CameraMetadataPtr& static_metadata,
      std::vector<cros::mojom::Camera3StreamPtr> streams);

  cros::mojom::Camera3StreamPtr GetStreamConfiguration(StreamType stream_type);

  // Requests buffer for specific stream type. If the |buffer_id| is provided,
  // it will use |buffer_id| as buffer id rather than using id from free
  // buffers.
  absl::optional<BufferInfo> RequestBufferForCaptureRequest(
      StreamType stream_type,
      absl::optional<uint64_t> buffer_ipc_id);

  // Releases buffer by marking it as free buffer.
  void ReleaseBufferFromCaptureResult(StreamType stream_type,
                                      uint64_t buffer_ipc_id);

  gfx::Size GetBufferDimension(StreamType stream_type);

  bool IsReprocessSupported();

  bool IsRecordingSupported();

  std::unique_ptr<gpu::GpuMemoryBufferImpl> CreateGpuMemoryBuffer(
      gfx::GpuMemoryBufferHandle handle,
      const VideoCaptureFormat& format,
      gfx::BufferUsage buffer_usage);

 private:
  friend class RequestManagerTest;

  // BufferPair holding up to two types of handles of a stream buffer.
  struct BufferPair {
    BufferPair(std::unique_ptr<gfx::GpuMemoryBuffer> gmb,
               absl::optional<Buffer> vcd_buffer);
    BufferPair(BufferPair&& other);
    ~BufferPair();
    // The GpuMemoryBuffer interface of the stream buffer.
    //   - When the VCD runs SharedMemory-based VideoCapture buffer, |gmb| is
    //     allocated by StreamBufferManager locally.
    //   - When the VCD runs GpuMemoryBuffer-based VideoCapture buffer, |gmb| is
    //     constructed from |vcd_buffer| below.
    std::unique_ptr<gfx::GpuMemoryBuffer> gmb;
    // The VCD buffer reserved from the VCD buffer pool.  This is only set when
    // the VCD runs GpuMemoryBuffer-based VideoCapture buffer.
    absl::optional<Buffer> vcd_buffer;
  };

  struct StreamContext {
    StreamContext();
    ~StreamContext();
    // The actual pixel format used in the capture request.
    VideoCaptureFormat capture_format;
    // The camera HAL stream.
    cros::mojom::Camera3StreamPtr stream;
    // The dimension of the buffer layout.
    gfx::Size buffer_dimension;
    // The usage of the buffer.
    gfx::BufferUsage buffer_usage;
    // The allocated buffer pairs.
    std::map<int, BufferPair> buffers;
    // The free buffers of this stream.  The queue stores keys into the
    // |buffers| map.
    std::queue<int> free_buffers;
  };

  static uint64_t GetBufferIpcId(StreamType stream_type, int key);

  static int GetBufferKey(uint64_t buffer_ipc_id);

  bool CanReserveBufferFromPool(StreamType stream_type);
  void ReserveBufferFromFactory(StreamType stream_type);
  void ReserveBufferFromPool(StreamType stream_type);
  // Destroy current streams and unmap mapped buffers.
  void DestroyCurrentStreamsAndBuffers();

  // The context for the set of active streams.
  std::unordered_map<StreamType, std::unique_ptr<StreamContext>>
      stream_context_;

  CameraDeviceContext* device_context_;

  bool video_capture_use_gmb_;

  std::unique_ptr<gpu::GpuMemoryBufferSupport> gmb_support_;

  std::unique_ptr<CameraBufferFactory> camera_buffer_factory_;

  base::WeakPtrFactory<StreamBufferManager> weak_ptr_factory_{this};
};

}  // namespace media

#endif  // MEDIA_CAPTURE_VIDEO_CHROMEOS_STREAM_BUFFER_MANAGER_H_