broadcasting_receiver.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. #ifndef SERVICES_VIDEO_CAPTURE_BROADCASTING_RECEIVER_H_
  5. #define SERVICES_VIDEO_CAPTURE_BROADCASTING_RECEIVER_H_
  6. #include <map>
  7. #include "base/gtest_prod_util.h"
  8. #include "base/memory/weak_ptr.h"
  9. #include "base/sequence_checker.h"
  10. #include "build/build_config.h"
  11. #include "media/capture/video/video_frame_receiver.h"
  12. #include "media/capture/video_capture_types.h"
  13. #include "mojo/public/cpp/bindings/pending_remote.h"
  14. #include "mojo/public/cpp/bindings/remote.h"
  15. #include "services/video_capture/public/cpp/video_frame_access_handler.h"
  16. #include "services/video_capture/public/mojom/video_frame_handler.mojom.h"
  17. namespace video_capture {
  18. // Implementation of mojom::VideoFrameHandler that distributes frames to
  19. // potentially multiple clients.
  20. class BroadcastingReceiver : public mojom::VideoFrameHandler {
  21. public:
  22. class BufferContext {
  23. public:
  24. BufferContext(int32_t buffer_id,
  25. media::mojom::VideoBufferHandlePtr buffer_handle);
  26. ~BufferContext();
  27. BufferContext(BufferContext&& other);
  28. BufferContext& operator=(BufferContext&& other);
  29. int32_t buffer_context_id() const { return buffer_context_id_; }
  30. int32_t buffer_id() const { return buffer_id_; }
  31. void SetFrameAccessHandlerRemote(
  32. scoped_refptr<VideoFrameAccessHandlerRemote>
  33. frame_access_handler_remote);
  34. void IncreaseConsumerCount();
  35. void DecreaseConsumerCount();
  36. bool IsStillBeingConsumed() const;
  37. bool is_retired() const { return is_retired_; }
  38. void set_retired() { is_retired_ = true; }
  39. media::mojom::VideoBufferHandlePtr CloneBufferHandle(
  40. media::VideoCaptureBufferType target_buffer_type);
  41. private:
  42. // If the source handle is shared_memory_via_raw_file_descriptor, we first
  43. // have to unwrap it before we can clone it. Instead of unwrapping, cloning,
  44. // and than wrapping back each time we need to clone it, we convert it to
  45. // a regular shared memory and keep it in this form.
  46. void ConvertRawFileDescriptorToUnsafeShmemRegion();
  47. int32_t buffer_context_id_;
  48. int32_t buffer_id_;
  49. scoped_refptr<VideoFrameAccessHandlerRemote> frame_access_handler_remote_;
  50. media::mojom::VideoBufferHandlePtr buffer_handle_;
  51. // Indicates how many consumers are currently relying on
  52. // |access_permission_|.
  53. int32_t consumer_hold_count_;
  54. bool is_retired_;
  55. };
  56. BroadcastingReceiver();
  57. ~BroadcastingReceiver() override;
  58. // Indicates to the BroadcastingReceiver that we want to restart the source
  59. // without letting connected clients know about the restart. The
  60. // BroadcastingReceiver will hide the OnStopped() event sent by the source
  61. // from the connected clients and instead invoke the given
  62. // |on_stopped_handler|. It will also not forward the subsequent
  63. // OnStarted() and possibly OnStartedUsingGpuDecode() events to clients who
  64. // have already received these events.
  65. void HideSourceRestartFromClients(base::OnceClosure on_stopped_handler);
  66. void SetOnStoppedHandler(base::OnceClosure on_stopped_handler);
  67. // Returns a client_id that can be used for a call to Suspend/Resume/Remove.
  68. int32_t AddClient(mojo::PendingRemote<mojom::VideoFrameHandler> client,
  69. media::VideoCaptureBufferType target_buffer_type);
  70. void SuspendClient(int32_t client_id);
  71. void ResumeClient(int32_t client_id);
  72. // Returns ownership of the client back to the caller.
  73. mojo::Remote<mojom::VideoFrameHandler> RemoveClient(int32_t client_id);
  74. // video_capture::mojom::VideoFrameHandler:
  75. void OnNewBuffer(int32_t buffer_id,
  76. media::mojom::VideoBufferHandlePtr buffer_handle) override;
  77. void OnFrameAccessHandlerReady(
  78. mojo::PendingRemote<video_capture::mojom::VideoFrameAccessHandler>
  79. frame_access_handler_remote) override;
  80. void OnFrameReadyInBuffer(
  81. mojom::ReadyFrameInBufferPtr buffer,
  82. std::vector<mojom::ReadyFrameInBufferPtr> scaled_buffers) override;
  83. void OnBufferRetired(int32_t buffer_id) override;
  84. void OnError(media::VideoCaptureError error) override;
  85. void OnFrameDropped(media::VideoCaptureFrameDropReason reason) override;
  86. void OnNewCropVersion(uint32_t crop_version) override;
  87. void OnFrameWithEmptyRegionCapture() override;
  88. void OnLog(const std::string& message) override;
  89. void OnStarted() override;
  90. void OnStartedUsingGpuDecode() override;
  91. void OnStopped() override;
  92. private:
  93. enum class Status {
  94. kOnStartedHasNotYetBeenCalled,
  95. kOnStartedHasBeenCalled,
  96. kOnStartedUsingGpuDecodeHasBeenCalled,
  97. kDeviceIsRestarting,
  98. kOnErrorHasBeenCalled,
  99. kOnStoppedHasBeenCalled
  100. };
  101. // Wrapper that suppresses calls to OnStarted() and OnStartedUsingGpuDecode()
  102. // after they have already been called once. Keeps track of whether or not
  103. // a client is suspended.
  104. class ClientContext {
  105. public:
  106. ClientContext(mojo::PendingRemote<mojom::VideoFrameHandler> client,
  107. media::VideoCaptureBufferType target_buffer_type);
  108. ~ClientContext();
  109. ClientContext(ClientContext&& other);
  110. ClientContext& operator=(ClientContext&& other);
  111. void OnStarted();
  112. void OnStartedUsingGpuDecode();
  113. mojo::Remote<mojom::VideoFrameHandler>& client() { return client_; }
  114. media::VideoCaptureBufferType target_buffer_type() {
  115. return target_buffer_type_;
  116. }
  117. void set_is_suspended(bool suspended) { is_suspended_ = suspended; }
  118. bool is_suspended() const { return is_suspended_; }
  119. void set_has_client_frame_access_handler_remote() {
  120. has_client_frame_access_handler_remote_ = true;
  121. }
  122. bool has_client_frame_access_handler_remote() const {
  123. return has_client_frame_access_handler_remote_;
  124. }
  125. private:
  126. mojo::Remote<mojom::VideoFrameHandler> client_;
  127. media::VideoCaptureBufferType target_buffer_type_;
  128. bool is_suspended_;
  129. bool on_started_has_been_called_;
  130. bool on_started_using_gpu_decode_has_been_called_;
  131. bool has_client_frame_access_handler_remote_;
  132. };
  133. class ClientVideoFrameAccessHandler;
  134. void OnClientFinishedConsumingFrame(int32_t buffer_context_id);
  135. void OnClientDisconnected(int32_t client_id);
  136. std::vector<BufferContext>::iterator FindUnretiredBufferContextFromBufferId(
  137. int32_t buffer_id);
  138. SEQUENCE_CHECKER(sequence_checker_);
  139. scoped_refptr<VideoFrameAccessHandlerRemote> frame_access_handler_remote_;
  140. std::map<int32_t /*client_id*/, ClientContext> clients_;
  141. std::vector<BufferContext> buffer_contexts_;
  142. Status status_;
  143. base::OnceClosure on_stopped_handler_;
  144. // Keeps track of the last VideoCaptureError that arrived via OnError().
  145. // This is used for relaying the error event to clients that connect after the
  146. // OnError() call has been received.
  147. media::VideoCaptureError error_;
  148. // Keeps track of the id value for the next client to be added. This member is
  149. // incremented each time a client is added and represents a unique identifier
  150. // for each client.
  151. int32_t next_client_id_;
  152. base::WeakPtrFactory<BroadcastingReceiver> weak_factory_{this};
  153. };
  154. } // namespace video_capture
  155. #endif // SERVICES_VIDEO_CAPTURE_BROADCASTING_RECEIVER_H_