blob: 20fd5f1d7f130bde10a429c5f781b51c46d72442 [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.
#ifndef COMPONENTS_MIRRORING_BROWSER_SINGLE_CLIENT_VIDEO_CAPTURE_HOST_H_
#define COMPONENTS_MIRRORING_BROWSER_SINGLE_CLIENT_VIDEO_CAPTURE_HOST_H_
#include <memory>
#include <string>
#include <utility>
#include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "content/public/browser/video_capture_device_launcher.h"
#include "media/capture/mojom/video_capture.mojom.h"
#include "media/capture/video/video_frame_receiver.h"
using media::VideoCaptureParams;
using media::VideoCaptureDevice;
namespace mirroring {
// Implements a subset of mojom::VideoCaptureHost to proxy between a
// content::LaunchedVideoCaptureDevice and a single client. On Start(), uses the
// provided DeviceLauncherCreateCallback to launch a video capture device that
// outputs frames to |this|. The frames are received through the
// VideoFrameReceiver interface and are forwarded to |observer| through the
// mojom::VideoCaptureObserver interface.
// Instances of this class must be operated from the same thread that is reqired
// by the DeviceLauncherCreateCallback.
class SingleClientVideoCaptureHost final
: public media::mojom::VideoCaptureHost,
public media::VideoFrameReceiver {
public:
using DeviceLauncherCreateCallback = base::RepeatingCallback<
std::unique_ptr<content::VideoCaptureDeviceLauncher>()>;
SingleClientVideoCaptureHost(const std::string& device_id,
content::MediaStreamType type,
DeviceLauncherCreateCallback callback);
~SingleClientVideoCaptureHost() override;
// media::mojom::VideoCaptureHost implementations
// |device_id| and |session_id| are ignored since there will be only one
// device and one client.
void Start(int32_t device_id,
int32_t session_id,
const VideoCaptureParams& params,
media::mojom::VideoCaptureObserverPtr observer) override;
void Stop(int32_t device_id) override;
void Pause(int32_t device_id) override;
void Resume(int32_t device_id,
int32_t session_id,
const VideoCaptureParams& params) override;
void RequestRefreshFrame(int32_t device_id) override;
void ReleaseBuffer(int32_t device_id,
int32_t buffer_id,
double consumer_resource_utilization) override;
void GetDeviceSupportedFormats(
int32_t device_id,
int32_t session_id,
GetDeviceSupportedFormatsCallback callback) override;
void GetDeviceFormatsInUse(int32_t device_id,
int32_t session_id,
GetDeviceFormatsInUseCallback callback) override;
// media::VideoFrameReceiver implementations
using Buffer = VideoCaptureDevice::Client::Buffer;
void OnNewBuffer(int buffer_id,
media::mojom::VideoBufferHandlePtr buffer_handle) override;
void OnFrameReadyInBuffer(
int buffer_id,
int frame_feedback_id,
std::unique_ptr<
VideoCaptureDevice::Client::Buffer::ScopedAccessPermission>
buffer_read_permission,
media::mojom::VideoFrameInfoPtr frame_info) override;
void OnBufferRetired(int buffer_id) override;
void OnError() override;
void OnLog(const std::string& message) override;
void OnStarted() override;
void OnStartedUsingGpuDecode() override;
void OnDeviceLaunched(
std::unique_ptr<content::LaunchedVideoCaptureDevice> device);
void OnDeviceLaunchFailed();
void OnDeviceLaunchAborted();
private:
// Reports the |consumer_resource_utilization| and removes the buffer context.
void OnFinishedConsumingBuffer(int buffer_context_id,
double consumer_resource_utilization);
const std::string device_id_;
const content::MediaStreamType type_;
const DeviceLauncherCreateCallback device_launcher_callback_;
media::mojom::VideoCaptureObserverPtr observer_;
std::unique_ptr<content::LaunchedVideoCaptureDevice> launched_device_;
// Unique ID assigned for the next buffer provided by OnNewBufferHandle().
int next_buffer_context_id_ = 0;
// Records the assigned buffer_context_id for buffers that are not retired.
// The |buffer_id| provided by OnNewBufferHandle() is used as the key.
base::flat_map<int, int> id_map_;
// Tracks the the retired buffers that are still held by |observer_|.
base::flat_set<int> retired_buffers_;
// Records the |frame_feedback_id| and |buffer_read_permission| provided by
// OnFrameReadyInBuffer(). The key is the assigned buffer context id. Each
// entry is removed after the |observer_| finishes consuming the buffer by
// calling ReleaseBuffer(). When Stop() is called, all the buffers are cleared
// immediately.
using BufferContext = std::pair<
int,
std::unique_ptr<
VideoCaptureDevice::Client::Buffer::ScopedAccessPermission>>;
base::flat_map<int, BufferContext> buffer_context_map_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<SingleClientVideoCaptureHost> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SingleClientVideoCaptureHost);
};
} // namespace mirroring
#endif // COMPONENTS_MIRRORING_BROWSER_SINGLE_CLIENT_VIDEO_CAPTURE_HOST_H_