client_frame_sink_video_capturer.cc 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/viz/host/client_frame_sink_video_capturer.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/threading/thread_task_runner_handle.h"
  8. #include "media/capture/mojom/video_capture_buffer.mojom.h"
  9. #include "media/capture/mojom/video_capture_types.mojom.h"
  10. namespace viz {
  11. namespace {
  12. // How long to wait before attempting to re-establish a lost connection.
  13. constexpr base::TimeDelta kReEstablishConnectionDelay = base::Milliseconds(100);
  14. } // namespace
  15. ClientFrameSinkVideoCapturer::ClientFrameSinkVideoCapturer(
  16. EstablishConnectionCallback callback)
  17. : establish_connection_callback_(callback) {
  18. EstablishConnection();
  19. }
  20. ClientFrameSinkVideoCapturer::~ClientFrameSinkVideoCapturer() {
  21. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  22. }
  23. void ClientFrameSinkVideoCapturer::SetFormat(media::VideoPixelFormat format) {
  24. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  25. format_.emplace(format);
  26. capturer_remote_->SetFormat(format);
  27. }
  28. void ClientFrameSinkVideoCapturer::SetMinCapturePeriod(
  29. base::TimeDelta min_capture_period) {
  30. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  31. min_capture_period_ = min_capture_period;
  32. capturer_remote_->SetMinCapturePeriod(min_capture_period);
  33. }
  34. void ClientFrameSinkVideoCapturer::SetMinSizeChangePeriod(
  35. base::TimeDelta min_period) {
  36. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  37. min_size_change_period_ = min_period;
  38. capturer_remote_->SetMinSizeChangePeriod(min_period);
  39. }
  40. void ClientFrameSinkVideoCapturer::SetResolutionConstraints(
  41. const gfx::Size& min_size,
  42. const gfx::Size& max_size,
  43. bool use_fixed_aspect_ratio) {
  44. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  45. resolution_constraints_.emplace(min_size, max_size, use_fixed_aspect_ratio);
  46. capturer_remote_->SetResolutionConstraints(min_size, max_size,
  47. use_fixed_aspect_ratio);
  48. }
  49. void ClientFrameSinkVideoCapturer::SetAutoThrottlingEnabled(bool enabled) {
  50. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  51. auto_throttling_enabled_ = enabled;
  52. capturer_remote_->SetAutoThrottlingEnabled(enabled);
  53. }
  54. void ClientFrameSinkVideoCapturer::ChangeTarget(
  55. const absl::optional<VideoCaptureTarget>& target) {
  56. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  57. ChangeTarget(target, crop_version_);
  58. }
  59. void ClientFrameSinkVideoCapturer::ChangeTarget(
  60. const absl::optional<VideoCaptureTarget>& target,
  61. uint32_t crop_version) {
  62. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  63. DCHECK_GE(crop_version, crop_version_);
  64. target_ = target;
  65. crop_version_ = crop_version;
  66. capturer_remote_->ChangeTarget(target, crop_version);
  67. }
  68. void ClientFrameSinkVideoCapturer::Start(
  69. mojom::FrameSinkVideoConsumer* consumer,
  70. mojom::BufferFormatPreference buffer_format_preference) {
  71. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  72. DCHECK(consumer);
  73. is_started_ = true;
  74. buffer_format_preference_ = buffer_format_preference;
  75. consumer_ = consumer;
  76. StartInternal();
  77. }
  78. void ClientFrameSinkVideoCapturer::Stop() {
  79. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  80. is_started_ = false;
  81. buffer_format_preference_ = mojom::BufferFormatPreference::kDefault;
  82. capturer_remote_->Stop();
  83. }
  84. void ClientFrameSinkVideoCapturer::StopAndResetConsumer() {
  85. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  86. Stop();
  87. consumer_ = nullptr;
  88. consumer_receiver_.reset();
  89. }
  90. void ClientFrameSinkVideoCapturer::RequestRefreshFrame() {
  91. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  92. capturer_remote_->RequestRefreshFrame();
  93. }
  94. std::unique_ptr<ClientFrameSinkVideoCapturer::Overlay>
  95. ClientFrameSinkVideoCapturer::CreateOverlay(int32_t stacking_index) {
  96. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  97. // If there is an existing overlay at the same index, drop it.
  98. auto it = std::find_if(overlays_.begin(), overlays_.end(),
  99. [&stacking_index](const Overlay* overlay) {
  100. return overlay->stacking_index() == stacking_index;
  101. });
  102. if (it != overlays_.end()) {
  103. (*it)->DisconnectPermanently();
  104. overlays_.erase(it);
  105. }
  106. auto overlay =
  107. std::make_unique<Overlay>(weak_factory_.GetWeakPtr(), stacking_index);
  108. overlays_.push_back(overlay.get());
  109. if (capturer_remote_)
  110. overlays_.back()->EstablishConnection(capturer_remote_.get());
  111. return overlay;
  112. }
  113. ClientFrameSinkVideoCapturer::ResolutionConstraints::ResolutionConstraints(
  114. const gfx::Size& min_size,
  115. const gfx::Size& max_size,
  116. bool use_fixed_aspect_ratio)
  117. : min_size(min_size),
  118. max_size(max_size),
  119. use_fixed_aspect_ratio(use_fixed_aspect_ratio) {}
  120. void ClientFrameSinkVideoCapturer::OnFrameCaptured(
  121. media::mojom::VideoBufferHandlePtr data,
  122. media::mojom::VideoFrameInfoPtr info,
  123. const gfx::Rect& content_rect,
  124. mojo::PendingRemote<mojom::FrameSinkVideoConsumerFrameCallbacks>
  125. callbacks) {
  126. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  127. consumer_->OnFrameCaptured(std::move(data), std::move(info), content_rect,
  128. std::move(callbacks));
  129. }
  130. void ClientFrameSinkVideoCapturer::OnFrameWithEmptyRegionCapture() {
  131. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  132. consumer_->OnFrameWithEmptyRegionCapture();
  133. }
  134. void ClientFrameSinkVideoCapturer::OnNewCropVersion(uint32_t crop_version) {
  135. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  136. consumer_->OnNewCropVersion(crop_version);
  137. }
  138. void ClientFrameSinkVideoCapturer::OnLog(const std::string& message) {
  139. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  140. consumer_->OnLog(message);
  141. }
  142. void ClientFrameSinkVideoCapturer::OnStopped() {
  143. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  144. consumer_->OnStopped();
  145. }
  146. void ClientFrameSinkVideoCapturer::EstablishConnection() {
  147. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  148. capturer_remote_.reset();
  149. establish_connection_callback_.Run(
  150. capturer_remote_.BindNewPipeAndPassReceiver());
  151. capturer_remote_.set_disconnect_handler(
  152. base::BindOnce(&ClientFrameSinkVideoCapturer::OnConnectionError,
  153. base::Unretained(this)));
  154. if (format_)
  155. capturer_remote_->SetFormat(*format_);
  156. if (min_capture_period_)
  157. capturer_remote_->SetMinCapturePeriod(*min_capture_period_);
  158. if (min_size_change_period_)
  159. capturer_remote_->SetMinSizeChangePeriod(*min_size_change_period_);
  160. if (resolution_constraints_) {
  161. capturer_remote_->SetResolutionConstraints(
  162. resolution_constraints_->min_size, resolution_constraints_->max_size,
  163. resolution_constraints_->use_fixed_aspect_ratio);
  164. }
  165. if (auto_throttling_enabled_)
  166. capturer_remote_->SetAutoThrottlingEnabled(*auto_throttling_enabled_);
  167. if (target_) {
  168. capturer_remote_->ChangeTarget(target_.value(), crop_version_);
  169. }
  170. for (Overlay* overlay : overlays_)
  171. overlay->EstablishConnection(capturer_remote_.get());
  172. if (is_started_)
  173. StartInternal();
  174. }
  175. void ClientFrameSinkVideoCapturer::OnConnectionError() {
  176. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  177. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
  178. FROM_HERE,
  179. base::BindOnce(&ClientFrameSinkVideoCapturer::EstablishConnection,
  180. weak_factory_.GetWeakPtr()),
  181. kReEstablishConnectionDelay);
  182. }
  183. void ClientFrameSinkVideoCapturer::StartInternal() {
  184. DCHECK(is_started_);
  185. if (consumer_receiver_.is_bound())
  186. consumer_receiver_.reset();
  187. capturer_remote_->Start(consumer_receiver_.BindNewPipeAndPassRemote(),
  188. buffer_format_preference_);
  189. }
  190. void ClientFrameSinkVideoCapturer::OnOverlayDestroyed(Overlay* overlay) {
  191. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  192. const auto it = std::find(overlays_.begin(), overlays_.end(), overlay);
  193. DCHECK(it != overlays_.end());
  194. overlays_.erase(it);
  195. }
  196. ClientFrameSinkVideoCapturer::Overlay::Overlay(
  197. base::WeakPtr<ClientFrameSinkVideoCapturer> client_capturer,
  198. int32_t stacking_index)
  199. : client_capturer_(client_capturer), stacking_index_(stacking_index) {}
  200. ClientFrameSinkVideoCapturer::Overlay::~Overlay() {
  201. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  202. if (client_capturer_)
  203. client_capturer_->OnOverlayDestroyed(this);
  204. }
  205. void ClientFrameSinkVideoCapturer::Overlay::SetImageAndBounds(
  206. const SkBitmap& image,
  207. const gfx::RectF& bounds) {
  208. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  209. DCHECK(!image.isNull());
  210. if (!client_capturer_)
  211. return;
  212. image_ = image;
  213. bounds_ = bounds;
  214. overlay_->SetImageAndBounds(image_, bounds_);
  215. }
  216. void ClientFrameSinkVideoCapturer::Overlay::SetBounds(
  217. const gfx::RectF& bounds) {
  218. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  219. if (!client_capturer_)
  220. return;
  221. bounds_ = bounds;
  222. overlay_->SetBounds(bounds_);
  223. }
  224. void ClientFrameSinkVideoCapturer::Overlay::DisconnectPermanently() {
  225. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  226. client_capturer_.reset();
  227. overlay_.reset();
  228. image_.reset();
  229. }
  230. void ClientFrameSinkVideoCapturer::Overlay::EstablishConnection(
  231. mojom::FrameSinkVideoCapturer* capturer) {
  232. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  233. DCHECK(client_capturer_);
  234. overlay_.reset();
  235. capturer->CreateOverlay(stacking_index_,
  236. overlay_.BindNewPipeAndPassReceiver());
  237. // Note: There's no need to add a connection error handler on the remote. If
  238. // the connection to the service is lost, the ClientFrameSinkVideoCapturer
  239. // will realize this when the FrameSinkVideoCapturer's binding is lost, and
  240. // re-establish a connection to both that and this overlay.
  241. if (!image_.isNull())
  242. overlay_->SetImageAndBounds(image_, bounds_);
  243. }
  244. } // namespace viz