6f9b9a36c0c6ca48d3c42724ccb2a2013d7d75a2
[platform/framework/web/chromium-efl.git] / media / capture / video / video_capture_device.h
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // VideoCaptureDevice is the abstract base class for realizing video capture
6 // device support in Chromium. It provides the interface for OS dependent
7 // implementations.
8 // The class is created and functions are invoked on a thread owned by
9 // VideoCaptureManager. Capturing is done on other threads, depending on the OS
10 // specific implementation.
11
12 #ifndef MEDIA_CAPTURE_VIDEO_VIDEO_CAPTURE_DEVICE_H_
13 #define MEDIA_CAPTURE_VIDEO_VIDEO_CAPTURE_DEVICE_H_
14
15 #include <stddef.h>
16 #include <stdint.h>
17
18 #include <memory>
19 #include <string>
20
21 #include "base/files/file.h"
22 #include "base/functional/callback.h"
23 #include "base/memory/unsafe_shared_memory_region.h"
24 #include "base/task/single_thread_task_runner.h"
25 #include "base/time/time.h"
26 #include "base/token.h"
27 #include "build/build_config.h"
28 #include "media/base/video_frame.h"
29 #include "media/capture/capture_export.h"
30 #include "media/capture/mojom/image_capture.mojom.h"
31 #include "media/capture/mojom/video_capture_types.mojom.h"
32 #include "media/capture/video/video_capture_buffer_handle.h"
33 #include "media/capture/video/video_capture_device_descriptor.h"
34 #include "media/capture/video/video_capture_feedback.h"
35 #include "media/capture/video_capture_types.h"
36 #include "ui/gfx/gpu_memory_buffer.h"
37
38 #if BUILDFLAG(IS_WIN)
39 #include <mfobjects.h>
40 #include <wrl/client.h>
41 #endif
42
43 namespace base {
44 class Location;
45 }  // namespace base
46
47 namespace media {
48
49 class CAPTURE_EXPORT VideoFrameConsumerFeedbackObserver {
50  public:
51   virtual ~VideoFrameConsumerFeedbackObserver() {}
52
53   // During processing of a video frame, consumers may report back their
54   // utilization level to the source device. The device may use this information
55   // to adjust the rate of data it pushes out. Values are interpreted as
56   // follows:
57   // Less than 0.0 is meaningless and should be ignored.  1.0 indicates a
58   // maximum sustainable utilization.  Greater than 1.0 indicates the consumer
59   // is likely to stall or drop frames if the data volume is not reduced.
60   //
61   // Example: In a system that encodes and transmits video frames over the
62   // network, this value can be used to indicate whether sufficient CPU
63   // is available for encoding and/or sufficient bandwidth is available for
64   // transmission over the network.  The maximum of the two utilization
65   // measurements would be used as feedback.
66   virtual void OnUtilizationReport(media::VideoCaptureFeedback feedback) {}
67 };
68
69 struct CAPTURE_EXPORT CapturedExternalVideoBuffer {
70   CapturedExternalVideoBuffer(gfx::GpuMemoryBufferHandle handle,
71                               VideoCaptureFormat format,
72                               gfx::ColorSpace color_space);
73
74 #if BUILDFLAG(IS_WIN)
75   CapturedExternalVideoBuffer(Microsoft::WRL::ComPtr<IMFMediaBuffer> imf_buffer,
76                               gfx::GpuMemoryBufferHandle handle,
77                               VideoCaptureFormat format,
78                               gfx::ColorSpace color_space);
79 #endif
80
81   CapturedExternalVideoBuffer(CapturedExternalVideoBuffer&& other);
82   CapturedExternalVideoBuffer& operator=(CapturedExternalVideoBuffer&& other);
83
84   CapturedExternalVideoBuffer(const CapturedExternalVideoBuffer&) = delete;
85   CapturedExternalVideoBuffer& operator=(const CapturedExternalVideoBuffer&) =
86       delete;
87
88   ~CapturedExternalVideoBuffer();
89
90 #if BUILDFLAG(IS_WIN)
91   Microsoft::WRL::ComPtr<IMFMediaBuffer> imf_buffer;
92 #endif
93   gfx::GpuMemoryBufferHandle handle;
94   VideoCaptureFormat format;
95   gfx::ColorSpace color_space;
96 };
97
98 class CAPTURE_EXPORT VideoCaptureDevice
99     : public VideoFrameConsumerFeedbackObserver {
100  public:
101
102   // Interface defining the methods that clients of VideoCapture must have. It
103   // is actually two-in-one: clients may implement OnIncomingCapturedData() or
104   // ReserveOutputBuffer() + OnIncomingCapturedVideoFrame(), or all of them.
105   // All methods may be called as soon as AllocateAndStart() of the
106   // corresponding VideoCaptureDevice is invoked. The methods for buffer
107   // reservation and frame delivery may be called from arbitrary threads but
108   // are guaranteed to be called non-concurrently. The status reporting methods
109   // (OnStarted, OnLog, OnError) may be called concurrently.
110   class CAPTURE_EXPORT Client {
111    public:
112     // Struct bundling several parameters being passed between a
113     // VideoCaptureDevice and its VideoCaptureDevice::Client.
114     struct CAPTURE_EXPORT Buffer {
115      public:
116       // Destructor-only interface for encapsulating scoped access permission to
117       // a Buffer.
118       class CAPTURE_EXPORT ScopedAccessPermission {
119        public:
120         virtual ~ScopedAccessPermission() {}
121       };
122
123       class CAPTURE_EXPORT HandleProvider {
124        public:
125         virtual ~HandleProvider() {}
126
127         // Duplicate as an writable (unsafe) shared memory region.
128         virtual base::UnsafeSharedMemoryRegion DuplicateAsUnsafeRegion() = 0;
129
130         // Access a |VideoCaptureBufferHandle| for local, writable memory.
131         virtual std::unique_ptr<VideoCaptureBufferHandle>
132         GetHandleForInProcessAccess() = 0;
133
134         // Clone a |GpuMemoryBufferHandle| for IPC.
135         virtual gfx::GpuMemoryBufferHandle GetGpuMemoryBufferHandle() = 0;
136       };
137
138       Buffer();
139       Buffer(int buffer_id,
140              int frame_feedback_id,
141              std::unique_ptr<HandleProvider> handle_provider,
142              std::unique_ptr<ScopedAccessPermission> access_permission);
143       ~Buffer();
144       Buffer(Buffer&& other);
145       Buffer& operator=(Buffer&& other);
146
147       int id;
148       int frame_feedback_id;
149       std::unique_ptr<HandleProvider> handle_provider;
150       std::unique_ptr<ScopedAccessPermission> access_permission;
151
152       // Some buffer types may be preemptively mapped in the capturer if
153       // requested by the consumer.
154       // This is used to notify the client that a shared memory region
155       // associated with the buffer is valid.
156       bool is_premapped = false;
157     };
158
159     // Result code for calls to ReserveOutputBuffer()
160     enum class ReserveResult {
161       kSucceeded,
162       kMaxBufferCountExceeded,
163       kAllocationFailed
164     };
165
166     virtual ~Client() {}
167
168     // The configuration of the VideoCaptureDevice has changed.
169     virtual void OnCaptureConfigurationChanged() = 0;
170
171     // Captured a new video frame, data for which is pointed to by |data|.
172     //
173     // The format of the frame is described by |frame_format|, and is assumed to
174     // be tightly packed. This method will try to reserve an output buffer and
175     // copy from |data| into the output buffer. If no output buffer is
176     // available, the frame will be silently dropped. |reference_time| is
177     // system clock time when we detect the capture happens, it is used for
178     // Audio/Video sync, not an exact presentation time for playout, because it
179     // could contain noise. |timestamp| measures the ideal time span between the
180     // first frame in the stream and the current frame; however, the time source
181     // is determined by the platform's device driver and is often not the system
182     // clock, or even has a drift with respect to system clock.
183     // |frame_feedback_id| is an identifier that allows clients to refer back to
184     // this particular frame when reporting consumer feedback via
185     // OnConsumerReportingUtilization(). This identifier is needed because
186     // frames are consumed asynchronously and multiple frames can be "in flight"
187     // at the same time.
188     virtual void OnIncomingCapturedData(const uint8_t* data,
189                                         int length,
190                                         const VideoCaptureFormat& frame_format,
191                                         const gfx::ColorSpace& color_space,
192                                         int clockwise_rotation,
193                                         bool flip_y,
194                                         base::TimeTicks reference_time,
195                                         base::TimeDelta timestamp,
196                                         int frame_feedback_id) = 0;
197     // Convenience wrapper that passes in 0 as |frame_feedback_id|.
198     void OnIncomingCapturedData(const uint8_t* data,
199                                 int length,
200                                 const VideoCaptureFormat& frame_format,
201                                 const gfx::ColorSpace& color_space,
202                                 int clockwise_rotation,
203                                 bool flip_y,
204                                 base::TimeTicks reference_time,
205                                 base::TimeDelta timestamp);
206
207     // Captured a new video frame, data for which is stored in the
208     // GpuMemoryBuffer pointed to by |buffer|.  The format of the frame is
209     // described by |frame_format|.  Since the memory buffer pointed to by
210     // |buffer| may be allocated with some size/address alignment requirement,
211     // this method takes into consideration the size and offset of each plane in
212     // |buffer| when creating the content of the output buffer.
213     // |clockwise_rotation|, |reference_time|, |timestamp|, and
214     // |frame_feedback_id| serve the same purposes as in OnIncomingCapturedData.
215     virtual void OnIncomingCapturedGfxBuffer(
216         gfx::GpuMemoryBuffer* buffer,
217         const VideoCaptureFormat& frame_format,
218         int clockwise_rotation,
219         base::TimeTicks reference_time,
220         base::TimeDelta timestamp,
221         int frame_feedback_id) = 0;
222     // Convenience wrapper that passes in 0 as |frame_feedback_id|.
223     void OnIncomingCapturedGfxBuffer(gfx::GpuMemoryBuffer* buffer,
224                                      const VideoCaptureFormat& frame_format,
225                                      int clockwise_rotation,
226                                      base::TimeTicks reference_time,
227                                      base::TimeDelta timestamp);
228
229     // Captured a new video frame. The data for this frame is in
230     // |buffer.handle|, which is owned by the platform-specific capture device.
231     // It is the responsibility of the implementation to prevent the buffer in
232     // |buffer.handle| from being reused by the external capturer. In practice,
233     // this is used only on macOS, the external capturer maintains a
234     // CVPixelBufferPool, and gfx::ScopedInUseIOSurface is used to prevent reuse
235     // of buffers until all consumers have consumed them. |visible_rect|
236     // specifies the region in the memory pointed to by |buffer.handle| that
237     // contains the captured content.
238     virtual void OnIncomingCapturedExternalBuffer(
239         CapturedExternalVideoBuffer buffer,
240         base::TimeTicks reference_time,
241         base::TimeDelta timestamp,
242         const gfx::Rect& visible_rect) = 0;
243
244     // Reserve an output buffer into which contents can be captured directly.
245     // The returned |buffer| will always be allocated with a memory size
246     // suitable for holding a packed video frame with pixels of |format| format,
247     // of |dimensions| frame dimensions. It is permissible for |dimensions| to
248     // be zero; in which case the returned Buffer does not guarantee memory
249     // backing, but functions as a reservation for external input for the
250     // purposes of buffer throttling.
251     //
252     // The buffer stays reserved for use by the caller as long as it
253     // holds on to the contained |buffer_read_write_permission|.
254     [[nodiscard]] virtual ReserveResult ReserveOutputBuffer(
255         const gfx::Size& dimensions,
256         VideoPixelFormat format,
257         int frame_feedback_id,
258         Buffer* buffer) = 0;
259
260     // Provides VCD::Client with a populated Buffer containing the content of
261     // the next video frame. The |buffer| must originate from an earlier call to
262     // ReserveOutputBuffer().
263     // See OnIncomingCapturedData for details of |reference_time| and
264     // |timestamp|.
265     virtual void OnIncomingCapturedBuffer(Buffer buffer,
266                                           const VideoCaptureFormat& format,
267                                           base::TimeTicks reference_time,
268                                           base::TimeDelta timestamp) = 0;
269
270     // Extended version of OnIncomingCapturedBuffer() allowing clients to
271     // pass a custom |visible_rect| and |additional_metadata|.
272     virtual void OnIncomingCapturedBufferExt(
273         Buffer buffer,
274         const VideoCaptureFormat& format,
275         const gfx::ColorSpace& color_space,
276         base::TimeTicks reference_time,
277         base::TimeDelta timestamp,
278         gfx::Rect visible_rect,
279         const VideoFrameMetadata& additional_metadata) = 0;
280
281     // An error has occurred that cannot be handled and VideoCaptureDevice must
282     // be StopAndDeAllocate()-ed. |reason| is a text description of the error.
283     virtual void OnError(VideoCaptureError error,
284                          const base::Location& from_here,
285                          const std::string& reason) = 0;
286
287     virtual void OnFrameDropped(VideoCaptureFrameDropReason reason) = 0;
288
289     // VideoCaptureDevice requests the |message| to be logged.
290     virtual void OnLog(const std::string& message) {}
291
292     // Returns the current buffer pool utilization, in the range 0.0 (no buffers
293     // are in use by producers or consumers) to 1.0 (all buffers are in use).
294     virtual double GetBufferPoolUtilization() const = 0;
295
296     // VideoCaptureDevice reports it's successfully started.
297     virtual void OnStarted() = 0;
298   };
299
300   ~VideoCaptureDevice() override;
301
302   // Prepares the video capturer for use. StopAndDeAllocate() must be called
303   // before the object is deleted.
304   virtual void AllocateAndStart(const VideoCaptureParams& params,
305                                 std::unique_ptr<Client> client) = 0;
306
307   // In cases where the video capturer self-pauses (e.g., a screen capturer
308   // where the screen's content has not changed in a while), consumers may call
309   // this to request a "refresh frame" be delivered to the Client.  This is used
310   // in a number of circumstances, such as:
311   //
312   //   1. An additional consumer of video frames is starting up and requires a
313   //      first frame (as opposed to not receiving a frame for an indeterminate
314   //      amount of time).
315   //   2. A few repeats of the same frame would allow a lossy video encoder to
316   //      improve the video quality of unchanging content.
317   //
318   // The default implementation is a no-op. VideoCaptureDevice implementations
319   // are not required to honor this request, especially if they do not
320   // self-pause and/or if honoring the request would cause them to exceed their
321   // configured maximum frame rate. Any VideoCaptureDevice that does self-pause,
322   // however, should provide an implementation of this method that makes
323   // reasonable attempts to honor these requests.
324   //
325   // Note: This should only be called after AllocateAndStart() and before
326   // StopAndDeAllocate(). Otherwise, its behavior is undefined.
327   virtual void RequestRefreshFrame() {}
328
329   // Optionally suspends frame delivery. The VideoCaptureDevice may or may not
330   // honor this request. Thus, the caller cannot assume frame delivery will
331   // actually stop. Even if frame delivery is suspended, this might not take
332   // effect immediately.
333   //
334   // The purpose of this is to quickly place the device into a state where it's
335   // resource utilization is minimized while there are no frame consumers; and
336   // then quickly resume once a frame consumer is present.
337   //
338   // Note: This should only be called after AllocateAndStart() and before
339   // StopAndDeAllocate(). Otherwise, its behavior is undefined.
340   virtual void MaybeSuspend() {}
341
342   // Resumes frame delivery, if it was suspended. If frame delivery was not
343   // suspended, this is a no-op, and frame delivery will continue.
344   //
345   // Note: This should only be called after AllocateAndStart() and before
346   // StopAndDeAllocate(). Otherwise, its behavior is undefined.
347   virtual void Resume() {}
348
349   // Start/stop cropping.
350   //
351   // Non-empty |crop_id| sets (or changes) the crop-target.
352   // Empty |crop_id| reverts the capture to its original, uncropped state.
353   //
354   // |sub_capture_target_version| must be incremented by at least one for each
355   // call. By including it in frame's metadata, Viz informs Blink what was the
356   // latest invocation of cropTo() before a given frame was produced.
357   //
358   // The callback reports success/failure. It is called on an unspecified
359   // thread, it's the caller's responsibility to wrap it (i.e. via BindPostTask)
360   // as needed.
361   virtual void Crop(
362       const base::Token& crop_id,
363       uint32_t sub_capture_target_version,
364       base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
365           callback);
366
367   // Deallocates the video capturer, possibly asynchronously.
368   //
369   // This call requires the device to do the following things, eventually: put
370   // hardware into a state where other applications could use it, free the
371   // memory associated with capture, and delete the |client| pointer passed into
372   // AllocateAndStart.
373   //
374   // If deallocation is done asynchronously, then the device implementation must
375   // ensure that a subsequent AllocateAndStart() operation targeting the same ID
376   // would be sequenced through the same task runner, so that deallocation
377   // happens first.
378   virtual void StopAndDeAllocate() = 0;
379
380   // Retrieve the photo capabilities and settings of the device (e.g. zoom
381   // levels etc). On success, invokes |callback|. On failure, drops callback
382   // without invoking it.
383   using GetPhotoStateCallback = base::OnceCallback<void(mojom::PhotoStatePtr)>;
384   virtual void GetPhotoState(GetPhotoStateCallback callback);
385
386   // On success, invokes |callback| with value |true|. On failure, drops
387   // callback without invoking it.
388   using SetPhotoOptionsCallback = base::OnceCallback<void(bool)>;
389   virtual void SetPhotoOptions(mojom::PhotoSettingsPtr settings,
390                                SetPhotoOptionsCallback callback);
391
392   // Asynchronously takes a photo, possibly reconfiguring the capture objects
393   // and/or interrupting the capture flow. Runs |callback|, if the photo was
394   // successfully taken. On failure, drops callback without invoking it.
395   // Note that |callback| may be runned on a thread different than the thread
396   // where TakePhoto() was called.
397   using TakePhotoCallback = base::OnceCallback<void(mojom::BlobPtr blob)>;
398   virtual void TakePhoto(TakePhotoCallback callback);
399
400   // Gets the power line frequency, either from the params if specified by the
401   // user or from the current system time zone.
402   static PowerLineFrequency GetPowerLineFrequency(
403       const VideoCaptureParams& params);
404
405  private:
406   // Gets the power line frequency from the current system time zone if this is
407   // defined, otherwise returns 0.
408   static PowerLineFrequency GetPowerLineFrequencyForLocation();
409 };
410
411 VideoCaptureFrameDropReason ConvertReservationFailureToFrameDropReason(
412     VideoCaptureDevice::Client::ReserveResult reserve_result);
413
414 }  // namespace media
415
416 #endif  // MEDIA_CAPTURE_VIDEO_VIDEO_CAPTURE_DEVICE_H_