123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- // 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 "components/viz/host/client_frame_sink_video_capturer.h"
- #include <utility>
- #include "base/bind.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "media/capture/mojom/video_capture_buffer.mojom.h"
- #include "media/capture/mojom/video_capture_types.mojom.h"
- namespace viz {
- namespace {
- // How long to wait before attempting to re-establish a lost connection.
- constexpr base::TimeDelta kReEstablishConnectionDelay = base::Milliseconds(100);
- } // namespace
- ClientFrameSinkVideoCapturer::ClientFrameSinkVideoCapturer(
- EstablishConnectionCallback callback)
- : establish_connection_callback_(callback) {
- EstablishConnection();
- }
- ClientFrameSinkVideoCapturer::~ClientFrameSinkVideoCapturer() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- }
- void ClientFrameSinkVideoCapturer::SetFormat(media::VideoPixelFormat format) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- format_.emplace(format);
- capturer_remote_->SetFormat(format);
- }
- void ClientFrameSinkVideoCapturer::SetMinCapturePeriod(
- base::TimeDelta min_capture_period) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- min_capture_period_ = min_capture_period;
- capturer_remote_->SetMinCapturePeriod(min_capture_period);
- }
- void ClientFrameSinkVideoCapturer::SetMinSizeChangePeriod(
- base::TimeDelta min_period) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- min_size_change_period_ = min_period;
- capturer_remote_->SetMinSizeChangePeriod(min_period);
- }
- void ClientFrameSinkVideoCapturer::SetResolutionConstraints(
- const gfx::Size& min_size,
- const gfx::Size& max_size,
- bool use_fixed_aspect_ratio) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- resolution_constraints_.emplace(min_size, max_size, use_fixed_aspect_ratio);
- capturer_remote_->SetResolutionConstraints(min_size, max_size,
- use_fixed_aspect_ratio);
- }
- void ClientFrameSinkVideoCapturer::SetAutoThrottlingEnabled(bool enabled) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- auto_throttling_enabled_ = enabled;
- capturer_remote_->SetAutoThrottlingEnabled(enabled);
- }
- void ClientFrameSinkVideoCapturer::ChangeTarget(
- const absl::optional<VideoCaptureTarget>& target) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- ChangeTarget(target, crop_version_);
- }
- void ClientFrameSinkVideoCapturer::ChangeTarget(
- const absl::optional<VideoCaptureTarget>& target,
- uint32_t crop_version) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK_GE(crop_version, crop_version_);
- target_ = target;
- crop_version_ = crop_version;
- capturer_remote_->ChangeTarget(target, crop_version);
- }
- void ClientFrameSinkVideoCapturer::Start(
- mojom::FrameSinkVideoConsumer* consumer,
- mojom::BufferFormatPreference buffer_format_preference) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(consumer);
- is_started_ = true;
- buffer_format_preference_ = buffer_format_preference;
- consumer_ = consumer;
- StartInternal();
- }
- void ClientFrameSinkVideoCapturer::Stop() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- is_started_ = false;
- buffer_format_preference_ = mojom::BufferFormatPreference::kDefault;
- capturer_remote_->Stop();
- }
- void ClientFrameSinkVideoCapturer::StopAndResetConsumer() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- Stop();
- consumer_ = nullptr;
- consumer_receiver_.reset();
- }
- void ClientFrameSinkVideoCapturer::RequestRefreshFrame() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- capturer_remote_->RequestRefreshFrame();
- }
- std::unique_ptr<ClientFrameSinkVideoCapturer::Overlay>
- ClientFrameSinkVideoCapturer::CreateOverlay(int32_t stacking_index) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- // If there is an existing overlay at the same index, drop it.
- auto it = std::find_if(overlays_.begin(), overlays_.end(),
- [&stacking_index](const Overlay* overlay) {
- return overlay->stacking_index() == stacking_index;
- });
- if (it != overlays_.end()) {
- (*it)->DisconnectPermanently();
- overlays_.erase(it);
- }
- auto overlay =
- std::make_unique<Overlay>(weak_factory_.GetWeakPtr(), stacking_index);
- overlays_.push_back(overlay.get());
- if (capturer_remote_)
- overlays_.back()->EstablishConnection(capturer_remote_.get());
- return overlay;
- }
- ClientFrameSinkVideoCapturer::ResolutionConstraints::ResolutionConstraints(
- const gfx::Size& min_size,
- const gfx::Size& max_size,
- bool use_fixed_aspect_ratio)
- : min_size(min_size),
- max_size(max_size),
- use_fixed_aspect_ratio(use_fixed_aspect_ratio) {}
- void ClientFrameSinkVideoCapturer::OnFrameCaptured(
- media::mojom::VideoBufferHandlePtr data,
- media::mojom::VideoFrameInfoPtr info,
- const gfx::Rect& content_rect,
- mojo::PendingRemote<mojom::FrameSinkVideoConsumerFrameCallbacks>
- callbacks) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- consumer_->OnFrameCaptured(std::move(data), std::move(info), content_rect,
- std::move(callbacks));
- }
- void ClientFrameSinkVideoCapturer::OnFrameWithEmptyRegionCapture() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- consumer_->OnFrameWithEmptyRegionCapture();
- }
- void ClientFrameSinkVideoCapturer::OnNewCropVersion(uint32_t crop_version) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- consumer_->OnNewCropVersion(crop_version);
- }
- void ClientFrameSinkVideoCapturer::OnLog(const std::string& message) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- consumer_->OnLog(message);
- }
- void ClientFrameSinkVideoCapturer::OnStopped() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- consumer_->OnStopped();
- }
- void ClientFrameSinkVideoCapturer::EstablishConnection() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- capturer_remote_.reset();
- establish_connection_callback_.Run(
- capturer_remote_.BindNewPipeAndPassReceiver());
- capturer_remote_.set_disconnect_handler(
- base::BindOnce(&ClientFrameSinkVideoCapturer::OnConnectionError,
- base::Unretained(this)));
- if (format_)
- capturer_remote_->SetFormat(*format_);
- if (min_capture_period_)
- capturer_remote_->SetMinCapturePeriod(*min_capture_period_);
- if (min_size_change_period_)
- capturer_remote_->SetMinSizeChangePeriod(*min_size_change_period_);
- if (resolution_constraints_) {
- capturer_remote_->SetResolutionConstraints(
- resolution_constraints_->min_size, resolution_constraints_->max_size,
- resolution_constraints_->use_fixed_aspect_ratio);
- }
- if (auto_throttling_enabled_)
- capturer_remote_->SetAutoThrottlingEnabled(*auto_throttling_enabled_);
- if (target_) {
- capturer_remote_->ChangeTarget(target_.value(), crop_version_);
- }
- for (Overlay* overlay : overlays_)
- overlay->EstablishConnection(capturer_remote_.get());
- if (is_started_)
- StartInternal();
- }
- void ClientFrameSinkVideoCapturer::OnConnectionError() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&ClientFrameSinkVideoCapturer::EstablishConnection,
- weak_factory_.GetWeakPtr()),
- kReEstablishConnectionDelay);
- }
- void ClientFrameSinkVideoCapturer::StartInternal() {
- DCHECK(is_started_);
- if (consumer_receiver_.is_bound())
- consumer_receiver_.reset();
- capturer_remote_->Start(consumer_receiver_.BindNewPipeAndPassRemote(),
- buffer_format_preference_);
- }
- void ClientFrameSinkVideoCapturer::OnOverlayDestroyed(Overlay* overlay) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- const auto it = std::find(overlays_.begin(), overlays_.end(), overlay);
- DCHECK(it != overlays_.end());
- overlays_.erase(it);
- }
- ClientFrameSinkVideoCapturer::Overlay::Overlay(
- base::WeakPtr<ClientFrameSinkVideoCapturer> client_capturer,
- int32_t stacking_index)
- : client_capturer_(client_capturer), stacking_index_(stacking_index) {}
- ClientFrameSinkVideoCapturer::Overlay::~Overlay() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (client_capturer_)
- client_capturer_->OnOverlayDestroyed(this);
- }
- void ClientFrameSinkVideoCapturer::Overlay::SetImageAndBounds(
- const SkBitmap& image,
- const gfx::RectF& bounds) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(!image.isNull());
- if (!client_capturer_)
- return;
- image_ = image;
- bounds_ = bounds;
- overlay_->SetImageAndBounds(image_, bounds_);
- }
- void ClientFrameSinkVideoCapturer::Overlay::SetBounds(
- const gfx::RectF& bounds) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (!client_capturer_)
- return;
- bounds_ = bounds;
- overlay_->SetBounds(bounds_);
- }
- void ClientFrameSinkVideoCapturer::Overlay::DisconnectPermanently() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- client_capturer_.reset();
- overlay_.reset();
- image_.reset();
- }
- void ClientFrameSinkVideoCapturer::Overlay::EstablishConnection(
- mojom::FrameSinkVideoCapturer* capturer) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(client_capturer_);
- overlay_.reset();
- capturer->CreateOverlay(stacking_index_,
- overlay_.BindNewPipeAndPassReceiver());
- // Note: There's no need to add a connection error handler on the remote. If
- // the connection to the service is lost, the ClientFrameSinkVideoCapturer
- // will realize this when the FrameSinkVideoCapturer's binding is lost, and
- // re-establish a connection to both that and this overlay.
- if (!image_.isNull())
- overlay_->SetImageAndBounds(image_, bounds_);
- }
- } // namespace viz
|