blob: 6ba33faa57acdce8bdcdcb5c6c2c8a74068c8051 [file] [log] [blame]
// Copyright 2018 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.
#include "base/callback.h"
#include "base/component_export.h"
#include "base/containers/flat_map.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "media/capture/mojom/video_capture.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/buffer.h"
namespace media {
class VideoFrame;
class VideoFrameMetadata;
} // 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.
: public media::mojom::VideoCaptureObserver {
VideoCaptureClient(const media::VideoCaptureParams& params,
media::mojom::VideoCaptureHostPtr host);
~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);
// 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::VideoCaptureState state) override;
void OnNewBuffer(int32_t buffer_id,
media::mojom::VideoBufferHandlePtr buffer_handle) override;
void OnBufferReady(int32_t buffer_id,
media::mojom::VideoFrameInfoPtr info) override;
void OnBufferDestroyed(int32_t buffer_id) override;
using BufferFinishedCallback =
base::OnceCallback<void(double consumer_resource_utilization)>;
// Called by the VideoFrame destructor.
static void DidFinishConsumingFrame(const media::VideoFrameMetadata* metadata,
BufferFinishedCallback callback);
// Reports the utilization, unmaps the shared memory, and returns the buffer.
void OnClientBufferFinished(int buffer_id,
base::ReadOnlySharedMemoryMapping mapping,
double consumer_resource_utilization);
const media::VideoCaptureParams params_;
const media::mojom::VideoCaptureHostPtr video_capture_host_;
// Called when capturing failed to start.
base::OnceClosure error_callback_;
mojo::Binding<media::mojom::VideoCaptureObserver> binding_;
// TODO( 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_;
// TODO( Remove the MappingMap after migrating
// media::VideoCaptureDeviceClient to the new shared memory API.
using MappingAndSize = std::pair<mojo::ScopedSharedBufferMapping, uint32_t>;
using MappingMap = base::flat_map<int32_t, MappingAndSize>;
// Stores the mapped buffers and their size. Each buffer is added the first
// time the mapping is done or a larger size is requested.
// |buffer_id| is the key to this map.
MappingMap mapped_buffers_;
base::WeakPtrFactory<VideoCaptureClient> weak_factory_;
} // namespace mirroring