| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_MIRRORING_SERVICE_VIDEO_CAPTURE_CLIENT_H_ |
| #define COMPONENTS_MIRRORING_SERVICE_VIDEO_CAPTURE_CLIENT_H_ |
| |
| #include <variant> |
| |
| #include "base/component_export.h" |
| #include "base/containers/flat_map.h" |
| #include "base/functional/callback.h" |
| #include "base/memory/shared_memory_mapping.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/sequence_checker.h" |
| #include "base/time/time.h" |
| #include "media/base/video_frame_converter.h" |
| #include "media/capture/mojom/video_capture.mojom.h" |
| #include "mojo/public/cpp/bindings/pending_remote.h" |
| #include "mojo/public/cpp/bindings/receiver.h" |
| #include "mojo/public/cpp/bindings/remote.h" |
| |
| namespace media { |
| class VideoFrame; |
| class VideoFramePool; |
| struct VideoCaptureFeedback; |
| } // namespace media |
| |
| namespace mirroring { |
| |
| // On Start(), this class connects to |host| through the |
| // media::mojom::VideoCaptureHost interface and requests to launch a video |
| // capture device. After the device is started, the captured video frames are |
| // received through the media::mojom::VideoCaptureObserver interface. |
| class COMPONENT_EXPORT(MIRRORING_SERVICE) VideoCaptureClient |
| : public media::mojom::VideoCaptureObserver { |
| public: |
| VideoCaptureClient(const media::VideoCaptureParams& params, |
| mojo::PendingRemote<media::mojom::VideoCaptureHost> host); |
| |
| VideoCaptureClient(const VideoCaptureClient&) = delete; |
| VideoCaptureClient& operator=(const VideoCaptureClient&) = delete; |
| |
| ~VideoCaptureClient() override; |
| |
| using FrameDeliverCallback = base::RepeatingCallback<void( |
| scoped_refptr<media::VideoFrame> video_frame)>; |
| void Start(FrameDeliverCallback deliver_callback, |
| base::OnceClosure error_callback); |
| |
| void Stop(); |
| |
| // Will stop delivering frames on this call. |
| void Pause(); |
| |
| void Resume(FrameDeliverCallback deliver_callback); |
| |
| // Feedback callback. |
| void ProcessFeedback(const media::VideoCaptureFeedback& feedback); |
| |
| // Requests to receive a refreshed captured video frame. Do nothing if the |
| // capturing device is not started or the capturing is paused. |
| void RequestRefreshFrame(); |
| |
| // media::mojom::VideoCaptureObserver implementations. |
| void OnStateChanged(media::mojom::VideoCaptureResultPtr result) override; |
| void OnNewBuffer(int32_t buffer_id, |
| media::mojom::VideoBufferHandlePtr buffer_handle) override; |
| void OnBufferReady(media::mojom::ReadyBufferPtr buffer) override; |
| void OnBufferDestroyed(int32_t buffer_id) override; |
| void OnFrameDropped(media::VideoCaptureFrameDropReason reason) override; |
| void OnNewCaptureVersion( |
| const media::CaptureVersion& capture_version) override; |
| |
| void SwitchVideoCaptureHost( |
| mojo::PendingRemote<media::mojom::VideoCaptureHost> host); |
| |
| // Reference to the const capture params set on construction. |
| const media::VideoCaptureParams& params() const { return params_; } |
| |
| private: |
| using BufferFinishedCallback = base::OnceCallback<void()>; |
| // Called by the VideoFrame destructor. |
| static void DidFinishConsumingFrame(BufferFinishedCallback callback); |
| |
| // Reports the utilization to release the buffer for potential reuse. |
| using MappingKeepAlive = std::variant<std::monostate, |
| base::WritableSharedMemoryMapping, |
| base::ReadOnlySharedMemoryMapping>; |
| void OnClientBufferFinished(int buffer_id, |
| MappingKeepAlive mapping_keep_alive); |
| |
| const media::VideoCaptureParams params_; |
| mojo::Remote<media::mojom::VideoCaptureHost> video_capture_host_; |
| |
| // Called when capturing failed to start. |
| base::OnceClosure error_callback_; |
| |
| mojo::Receiver<media::mojom::VideoCaptureObserver> receiver_{this}; |
| |
| // TODO(crbug.com/40576409): Store the base::ReadOnlySharedMemoryRegion |
| // instead after migrating the media::VideoCaptureDeviceClient to the new |
| // shared memory API. |
| using ClientBufferMap = |
| base::flat_map<int32_t, media::mojom::VideoBufferHandlePtr>; |
| // Stores the buffer handler on OnBufferCreated(). |buffer_id| is the key. |
| ClientBufferMap client_buffers_; |
| |
| // The reference time for the first frame. Used to calculate the timestamp of |
| // the captured frame if not provided in the frame info. |
| base::TimeTicks first_frame_ref_time_; |
| |
| // The callback to deliver the received frame. |
| FrameDeliverCallback frame_deliver_callback_; |
| |
| // Latest received feedback. |
| media::VideoCaptureFeedback feedback_; |
| |
| // Cast Streaming does not support NV12 frames. When NV12 frames are received, |
| // these structures are used to convert them to I420 on the CPU. |
| // https://crbug.com/1206325 |
| std::unique_ptr<media::VideoFramePool> nv12_to_i420_pool_; |
| media::VideoFrameConverter frame_converter_; |
| |
| // Indicates whether we're in the middle of switching video capture host. |
| bool switching_video_capture_host_ = false; |
| |
| // Represents the timestamp for the last frame sent to be delivered through |
| // `frame_deliver_callback_`. |
| base::TimeDelta last_timestamp_; |
| |
| // When capturing stops, it gets assigned the value of the `last_timestamp_`. |
| // Added to frame timestamps when capturing restarts, since frame |
| // timestamps are expected to always increase. |
| base::TimeDelta accumulated_time_; |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| base::WeakPtrFactory<VideoCaptureClient> weak_factory_{this}; |
| }; |
| |
| } // namespace mirroring |
| |
| #endif // COMPONENTS_MIRRORING_SERVICE_VIDEO_CAPTURE_CLIENT_H_ |