| // 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_SERVICE_MEDIA_REMOTER_H_ |
| #define COMPONENTS_MIRRORING_SERVICE_MEDIA_REMOTER_H_ |
| |
| #include "base/component_export.h" |
| #include "base/macros.h" |
| #include "media/cast/cast_config.h" |
| #include "media/mojo/interfaces/remoting.mojom.h" |
| #include "mojo/public/cpp/bindings/binding.h" |
| |
| namespace media { |
| namespace cast { |
| class CastEnvironment; |
| class CastTransport; |
| } // namespace cast |
| } // namespace media |
| |
| namespace mirroring { |
| |
| class MessageDispatcher; |
| struct ReceiverResponse; |
| class RemotingSender; |
| |
| // MediaRemoter remotes media content directly to a Cast Receiver. When |
| // MediaRemoter is started, it connects itself with a source tab in browser |
| // through the Mirroring Service mojo interface and allows the browser to access |
| // this MediaRemoter to start/stop individual remoting sessions, which are |
| // caused by user actions (i.e., when they somehow indicate a desire to |
| // enter/leave an immersive video-watching mode). |
| // |
| // When a remoting session is started, MediaRemoter will first request that tab |
| // mirroring be switched into content remoting mode. If granted, it will notify |
| // the browser that this has succeeded. At this point, two-way RPC binary |
| // messaging begins, and the MediaRemoter simply forwards messages between the |
| // browser and the Cast Receiver. The audio/video data streams are delivered |
| // from the media renderer to the Mirroring Service through mojo datapipes, and |
| // are then sent out to Cast Receiver through Cast Streaming. |
| class COMPONENT_EXPORT(MIRRORING_SERVICE) MediaRemoter final |
| : public media::mojom::Remoter { |
| public: |
| class Client { |
| public: |
| virtual ~Client() {} |
| |
| // Connects the |remoter| with a source tab. |
| virtual void ConnectToRemotingSource( |
| media::mojom::RemoterPtr remoter, |
| media::mojom::RemotingSourceRequest source_request) = 0; |
| |
| // Requests to start remoting. StartRpcMessaging() / OnRemotingStartFailed() |
| // will be called when starting succeeds / fails. |
| virtual void RequestRemotingStreaming() = 0; |
| |
| // Requests to resume mirroring. |
| virtual void RestartMirroringStreaming() = 0; |
| }; |
| |
| MediaRemoter(Client* client, |
| const media::mojom::RemotingSinkMetadata& sink_metadata, |
| MessageDispatcher* message_dispatcher); |
| |
| ~MediaRemoter() override; |
| |
| // Callback from |message_dispatcher_| for received RPC messages. |
| void OnMessageFromSink(const ReceiverResponse& response); |
| |
| // Called when OFFER/ANSWER exchange for a remoting session succeeds. |
| void StartRpcMessaging( |
| scoped_refptr<media::cast::CastEnvironment> cast_environment, |
| media::cast::CastTransport* transport, |
| const media::cast::FrameSenderConfig& audio_config, |
| const media::cast::FrameSenderConfig& video_config); |
| |
| // Called when a mirroring session is successfully resumed. |
| void OnMirroringResumed(); |
| |
| // Error occurred either during the start of remoting or in the middle of |
| // remoting. In either case, this call fallbacks to mirroring, and prevents |
| // further starting of media remoting during this mirroring session. |
| void OnRemotingFailed(); |
| |
| // media::mojom::Remoter implememtation. Stops the current remoting session. |
| // This could be called either by the RemotingSource or the Session. |
| void Stop(media::mojom::RemotingStopReason reason) override; |
| |
| private: |
| // media::mojom::Remoter implememtation. |
| void Start() override; |
| void StartDataStreams( |
| mojo::ScopedDataPipeConsumerHandle audio_pipe, |
| mojo::ScopedDataPipeConsumerHandle video_pipe, |
| media::mojom::RemotingDataStreamSenderRequest audio_sender_request, |
| media::mojom::RemotingDataStreamSenderRequest video_sender_request) |
| override; |
| void SendMessageToSink(const std::vector<uint8_t>& message) override; |
| void EstimateTransmissionCapacity( |
| media::mojom::Remoter::EstimateTransmissionCapacityCallback callback) |
| override; |
| |
| // Called by RemotingSender when error occurred. Will stop this remoting |
| // session and fallback to mirroring. |
| void OnRemotingDataStreamError(); |
| |
| Client* const client_; // Outlives this class. |
| const media::mojom::RemotingSinkMetadata sink_metadata_; |
| MessageDispatcher* const message_dispatcher_; // Outlives this class. |
| mojo::Binding<media::mojom::Remoter> binding_; |
| media::mojom::RemotingSourcePtr remoting_source_; |
| scoped_refptr<media::cast::CastEnvironment> cast_environment_; |
| std::unique_ptr<RemotingSender> audio_sender_; |
| std::unique_ptr<RemotingSender> video_sender_; |
| media::cast::CastTransport* transport_; // Outlives this class; |
| media::cast::FrameSenderConfig audio_config_; |
| media::cast::FrameSenderConfig video_config_; |
| |
| // State transition diagram: |
| // |
| // .-----------> MIRRORING |
| // | | |
| // | V |
| // | STARTING_REMOTING |
| // | | |
| // | V |
| // | .-----------------------------. |
| // | | | | |
| // | | V V |
| // | | REMOTING_STARTED ----> REMOTING_DISABLED |
| // | | | |
| // | V V |
| // .--STOPPING_REMOTING |
| enum { |
| MIRRORING, // In mirroring. |
| STARTING_REMOTING, // Starting a remoting session. |
| REMOTING_STARTED, // Remoting started successfully. |
| REMOTING_DISABLED, // Remoting was disabled (because of error). |
| STOPPING_REMOTING, // Stopping the remoting session. |
| } state_; |
| |
| base::WeakPtrFactory<MediaRemoter> weak_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MediaRemoter); |
| }; |
| |
| } // namespace mirroring |
| |
| #endif // COMPONENTS_MIRRORING_SERVICE_MEDIA_REMOTER_H_ |