123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- // 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 SERVICES_VIDEO_CAPTURE_BROADCASTING_RECEIVER_H_
- #define SERVICES_VIDEO_CAPTURE_BROADCASTING_RECEIVER_H_
- #include <map>
- #include "base/gtest_prod_util.h"
- #include "base/memory/weak_ptr.h"
- #include "base/sequence_checker.h"
- #include "build/build_config.h"
- #include "media/capture/video/video_frame_receiver.h"
- #include "media/capture/video_capture_types.h"
- #include "mojo/public/cpp/bindings/pending_remote.h"
- #include "mojo/public/cpp/bindings/remote.h"
- #include "services/video_capture/public/cpp/video_frame_access_handler.h"
- #include "services/video_capture/public/mojom/video_frame_handler.mojom.h"
- namespace video_capture {
- // Implementation of mojom::VideoFrameHandler that distributes frames to
- // potentially multiple clients.
- class BroadcastingReceiver : public mojom::VideoFrameHandler {
- public:
- class BufferContext {
- public:
- BufferContext(int32_t buffer_id,
- media::mojom::VideoBufferHandlePtr buffer_handle);
- ~BufferContext();
- BufferContext(BufferContext&& other);
- BufferContext& operator=(BufferContext&& other);
- int32_t buffer_context_id() const { return buffer_context_id_; }
- int32_t buffer_id() const { return buffer_id_; }
- void SetFrameAccessHandlerRemote(
- scoped_refptr<VideoFrameAccessHandlerRemote>
- frame_access_handler_remote);
- void IncreaseConsumerCount();
- void DecreaseConsumerCount();
- bool IsStillBeingConsumed() const;
- bool is_retired() const { return is_retired_; }
- void set_retired() { is_retired_ = true; }
- media::mojom::VideoBufferHandlePtr CloneBufferHandle(
- media::VideoCaptureBufferType target_buffer_type);
- private:
- // If the source handle is shared_memory_via_raw_file_descriptor, we first
- // have to unwrap it before we can clone it. Instead of unwrapping, cloning,
- // and than wrapping back each time we need to clone it, we convert it to
- // a regular shared memory and keep it in this form.
- void ConvertRawFileDescriptorToUnsafeShmemRegion();
- int32_t buffer_context_id_;
- int32_t buffer_id_;
- scoped_refptr<VideoFrameAccessHandlerRemote> frame_access_handler_remote_;
- media::mojom::VideoBufferHandlePtr buffer_handle_;
- // Indicates how many consumers are currently relying on
- // |access_permission_|.
- int32_t consumer_hold_count_;
- bool is_retired_;
- };
- BroadcastingReceiver();
- ~BroadcastingReceiver() override;
- // Indicates to the BroadcastingReceiver that we want to restart the source
- // without letting connected clients know about the restart. The
- // BroadcastingReceiver will hide the OnStopped() event sent by the source
- // from the connected clients and instead invoke the given
- // |on_stopped_handler|. It will also not forward the subsequent
- // OnStarted() and possibly OnStartedUsingGpuDecode() events to clients who
- // have already received these events.
- void HideSourceRestartFromClients(base::OnceClosure on_stopped_handler);
- void SetOnStoppedHandler(base::OnceClosure on_stopped_handler);
- // Returns a client_id that can be used for a call to Suspend/Resume/Remove.
- int32_t AddClient(mojo::PendingRemote<mojom::VideoFrameHandler> client,
- media::VideoCaptureBufferType target_buffer_type);
- void SuspendClient(int32_t client_id);
- void ResumeClient(int32_t client_id);
- // Returns ownership of the client back to the caller.
- mojo::Remote<mojom::VideoFrameHandler> RemoveClient(int32_t client_id);
- // video_capture::mojom::VideoFrameHandler:
- void OnNewBuffer(int32_t buffer_id,
- media::mojom::VideoBufferHandlePtr buffer_handle) override;
- void OnFrameAccessHandlerReady(
- mojo::PendingRemote<video_capture::mojom::VideoFrameAccessHandler>
- frame_access_handler_remote) override;
- void OnFrameReadyInBuffer(
- mojom::ReadyFrameInBufferPtr buffer,
- std::vector<mojom::ReadyFrameInBufferPtr> scaled_buffers) override;
- void OnBufferRetired(int32_t buffer_id) override;
- void OnError(media::VideoCaptureError error) override;
- void OnFrameDropped(media::VideoCaptureFrameDropReason reason) override;
- void OnNewCropVersion(uint32_t crop_version) override;
- void OnFrameWithEmptyRegionCapture() override;
- void OnLog(const std::string& message) override;
- void OnStarted() override;
- void OnStartedUsingGpuDecode() override;
- void OnStopped() override;
- private:
- enum class Status {
- kOnStartedHasNotYetBeenCalled,
- kOnStartedHasBeenCalled,
- kOnStartedUsingGpuDecodeHasBeenCalled,
- kDeviceIsRestarting,
- kOnErrorHasBeenCalled,
- kOnStoppedHasBeenCalled
- };
- // Wrapper that suppresses calls to OnStarted() and OnStartedUsingGpuDecode()
- // after they have already been called once. Keeps track of whether or not
- // a client is suspended.
- class ClientContext {
- public:
- ClientContext(mojo::PendingRemote<mojom::VideoFrameHandler> client,
- media::VideoCaptureBufferType target_buffer_type);
- ~ClientContext();
- ClientContext(ClientContext&& other);
- ClientContext& operator=(ClientContext&& other);
- void OnStarted();
- void OnStartedUsingGpuDecode();
- mojo::Remote<mojom::VideoFrameHandler>& client() { return client_; }
- media::VideoCaptureBufferType target_buffer_type() {
- return target_buffer_type_;
- }
- void set_is_suspended(bool suspended) { is_suspended_ = suspended; }
- bool is_suspended() const { return is_suspended_; }
- void set_has_client_frame_access_handler_remote() {
- has_client_frame_access_handler_remote_ = true;
- }
- bool has_client_frame_access_handler_remote() const {
- return has_client_frame_access_handler_remote_;
- }
- private:
- mojo::Remote<mojom::VideoFrameHandler> client_;
- media::VideoCaptureBufferType target_buffer_type_;
- bool is_suspended_;
- bool on_started_has_been_called_;
- bool on_started_using_gpu_decode_has_been_called_;
- bool has_client_frame_access_handler_remote_;
- };
- class ClientVideoFrameAccessHandler;
- void OnClientFinishedConsumingFrame(int32_t buffer_context_id);
- void OnClientDisconnected(int32_t client_id);
- std::vector<BufferContext>::iterator FindUnretiredBufferContextFromBufferId(
- int32_t buffer_id);
- SEQUENCE_CHECKER(sequence_checker_);
- scoped_refptr<VideoFrameAccessHandlerRemote> frame_access_handler_remote_;
- std::map<int32_t /*client_id*/, ClientContext> clients_;
- std::vector<BufferContext> buffer_contexts_;
- Status status_;
- base::OnceClosure on_stopped_handler_;
- // Keeps track of the last VideoCaptureError that arrived via OnError().
- // This is used for relaying the error event to clients that connect after the
- // OnError() call has been received.
- media::VideoCaptureError error_;
- // Keeps track of the id value for the next client to be added. This member is
- // incremented each time a client is added and represents a unique identifier
- // for each client.
- int32_t next_client_id_;
- base::WeakPtrFactory<BroadcastingReceiver> weak_factory_{this};
- };
- } // namespace video_capture
- #endif // SERVICES_VIDEO_CAPTURE_BROADCASTING_RECEIVER_H_
|