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
|
// 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 OnNewSubCaptureTargetVersion(
uint32_t sub_capture_target_version) override;
void SwitchVideoCaptureHost(
mojo::PendingRemote<media::mojom::VideoCaptureHost> host);
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_
|