1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_CAST_STREAMING_BROWSER_CAST_STREAMING_SESSION_H_
#define COMPONENTS_CAST_STREAMING_BROWSER_CAST_STREAMING_SESSION_H_
#include <memory>
#include <optional>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/timer/timer.h"
#include "components/cast_streaming/browser/control/playback_command_dispatcher.h"
#include "components/cast_streaming/browser/control/remoting/remoting_session_client.h"
#include "components/cast_streaming/browser/control/renderer_controller_config.h"
#include "components/cast_streaming/browser/frame/demuxer_stream_data_provider.h"
#include "components/cast_streaming/browser/public/receiver_config.h"
#include "components/cast_streaming/browser/public/receiver_session.h"
#include "components/openscreen_platform/network_util.h"
#include "components/openscreen_platform/task_runner.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/video_decoder_config.h"
#include "media/mojo/mojom/media_types.mojom.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "third_party/openscreen/src/cast/streaming/public/receiver.h"
#include "third_party/openscreen/src/cast/streaming/public/receiver_constraints.h"
#include "third_party/openscreen/src/cast/streaming/public/receiver_session.h"
namespace cast_streaming {
class StreamConsumer;
class CastMessagePortConverter;
// Entry point for the Cast Streaming Receiver implementation. Used to start a
// Cast Streaming Session for a provided MessagePort server.
class CastStreamingSession {
public:
class Client {
public:
// Called when the Cast Streaming Session has been successfully initialized.
// It is guaranteed that at least one of |audio_stream_info| or
// |video_stream_info| will be set.
virtual void OnSessionInitialization(
StreamingInitializationInfo initialization_info,
std::optional<mojo::ScopedDataPipeConsumerHandle> audio_pipe_consumer,
std::optional<mojo::ScopedDataPipeConsumerHandle>
video_pipe_consumer) = 0;
// Called on every new audio buffer after OnSessionInitialization(). The
// frame data must be accessed via the |data_pipe| property in StreamInfo.
virtual void OnAudioBufferReceived(
media::mojom::DecoderBufferPtr buffer) = 0;
// Called on every new video buffer after OnSessionInitialization(). The
// frame data must be accessed via the |data_pipe| property in StreamInfo.
virtual void OnVideoBufferReceived(
media::mojom::DecoderBufferPtr buffer) = 0;
// Called when a session is being renegotiated but has not yet completed
// configuration.
virtual void OnSessionReinitializationPending() = 0;
// Called on receiver session reinitialization. It is guaranteed that at
// least one of |audio_stream_info| or |video_stream_info| will be set.
virtual void OnSessionReinitialization(
StreamingInitializationInfo initialization_info,
std::optional<mojo::ScopedDataPipeConsumerHandle> audio_pipe_consumer,
std::optional<mojo::ScopedDataPipeConsumerHandle>
video_pipe_consumer) = 0;
// Called when the Cast Streaming Session has ended.
virtual void OnSessionEnded() = 0;
protected:
virtual ~Client();
};
CastStreamingSession();
~CastStreamingSession();
CastStreamingSession(const CastStreamingSession&) = delete;
CastStreamingSession& operator=(const CastStreamingSession&) = delete;
// Starts the Cast Streaming Session. This can only be called once during the
// lifespan of this object. |client| must not be null and must outlive this
// object.
// * On success, OnSessionInitialization() will be called and
// OnAudioFrameReceived() and/or OnVideoFrameReceived() will be called on
// every subsequent Frame.
// * On failure, OnSessionEnded() will be called.
// * When a new offer is sent by the Cast Streaming Sender,
// OnSessionReinitialization() will be called.
//
// |av_constraints| specifies the supported media codecs and limitations
// surrounding this support.
void Start(Client* client,
std::optional<RendererControllerConfig> renderer_controls,
ReceiverConfig av_constraints,
ReceiverSession::MessagePortProvider message_port_provider,
scoped_refptr<base::SequencedTaskRunner> task_runner);
// Stops the Cast Streaming Session. This can only be called once during the
// lifespan of this object and only after a call to Start().
void Stop();
bool is_running() const { return !!receiver_session_; }
// Return a callback that may be used to request a buffer of the specified
// type, to be returned asynchronously through the client API. May only be
// called following a call to Start() and prior to a call to Stop().
AudioDemuxerStreamDataProvider::RequestBufferCB GetAudioBufferRequester();
VideoDemuxerStreamDataProvider::RequestBufferCB GetVideoBufferRequester();
// Returns a callback to be used for pre-loading a single frame and then
// potentially using it to begin playback of the stream.
using PreloadBufferCB =
base::OnceCallback<void(media::mojom::DecoderBufferPtr)>;
PreloadBufferCB GetAudioBufferPreloader();
PreloadBufferCB GetVideoBufferPreloader();
private:
// Owns the Open Screen ReceiverSession. The Streaming Session is tied to the
// lifespan of this object.
class ReceiverSessionClient final
: public openscreen::cast::ReceiverSession::Client,
public remoting::RemotingSessionClient::Dispatcher {
public:
ReceiverSessionClient(
CastStreamingSession::Client* client,
std::optional<RendererControllerConfig> renderer_controls,
ReceiverConfig av_constraints,
ReceiverSession::MessagePortProvider message_port_provider,
scoped_refptr<base::SequencedTaskRunner> task_runner);
~ReceiverSessionClient() override;
ReceiverSessionClient(const ReceiverSessionClient&) = delete;
ReceiverSessionClient& operator=(const ReceiverSessionClient&) = delete;
// Requests a new buffer of the specified type, which will be provided
// Return a callback that may be used to request a buffer of the specified
// type, to be returned asynchronously through the |client_|.
void GetAudioBuffer(base::OnceClosure no_frames_available_cb);
void GetVideoBuffer(base::OnceClosure no_frames_available_cb);
// Stores the first frame of a DemuxerStream session, and then may use the
// frame to begin playback fo teh streaming session, depending on its
// configuration.
void PreloadAudioBuffer(media::mojom::DecoderBufferPtr buffer);
void PreloadVideoBuffer(media::mojom::DecoderBufferPtr buffer);
// Returns a WeakPtr associated with this instance;
base::WeakPtr<ReceiverSessionClient> GetWeakPtr();
private:
bool ongoing_session_has_audio() const { return !!audio_consumer_; }
bool ongoing_session_has_video() const { return !!video_consumer_; }
void OnInitializationTimeout();
// Initializes the audio or video consumer, returning the data pipe to
// be used to pass DecoderBuffer data to the Renderer process on success.
std::optional<mojo::ScopedDataPipeConsumerHandle> InitializeAudioConsumer(
const StreamingInitializationInfo& initialization_info);
std::optional<mojo::ScopedDataPipeConsumerHandle> InitializeVideoConsumer(
const StreamingInitializationInfo& initialization_info);
// Called upon completion of a Flush call initiated by this class.
void OnFlushComplete();
// Called when a RPC_FLUSH_UNTIL call is received from the remoting sender.
void OnFlushUntil(uint32_t audio_count, uint32_t video_count);
// remoting::PlaybackCommandDispatcher::Client implementation.
void StartStreamingSession(
StreamingInitializationInfo initialization_info) override;
// openscreen::cast::ReceiverSession::Client implementation.
void OnNegotiated(const openscreen::cast::ReceiverSession* session,
openscreen::cast::ReceiverSession::ConfiguredReceivers
receivers) override;
void OnRemotingNegotiated(
const openscreen::cast::ReceiverSession* session,
openscreen::cast::ReceiverSession::RemotingNegotiation negotiation)
override;
void OnReceiversDestroying(const openscreen::cast::ReceiverSession* session,
ReceiversDestroyingReason reason) override;
void OnError(const openscreen::cast::ReceiverSession* session,
const openscreen::Error& error) override;
void OnDataTimeout();
void OnCastChannelClosed();
// Ends the session by informing the client and setting the client to null
// (to prevent accessing the client later, at which point it may have
// already been destructed).
void EndSession();
openscreen_platform::TaskRunner task_runner_;
openscreen::cast::Environment environment_;
std::unique_ptr<CastMessagePortConverter> cast_message_port_converter_;
std::unique_ptr<openscreen::cast::ReceiverSession> receiver_session_;
base::OneShotTimer init_timeout_timer_;
// Handles remoting messages.
std::unique_ptr<PlaybackCommandDispatcher> playback_command_dispatcher_;
// Timer to trigger connection closure if no data is received for 15
// seconds.
base::OneShotTimer data_timeout_timer_;
bool is_flush_pending_ = false;
// Populated with the most recent call to StartStreamingSession() if there
// is an ongoing call to Flush() at the time of its calling. In this case,
// this callback will be called upon completion of the Flush() call as part
// of OnFlushComplete().
base::OnceCallback<void()> start_session_cb_;
bool is_initialized_ = false;
raw_ptr<CastStreamingSession::Client> client_;
std::unique_ptr<StreamConsumer> audio_consumer_;
std::unique_ptr<StreamConsumer> video_consumer_;
// The currently pre-loaded audio or video buffer, if any exists.
std::optional<media::mojom::DecoderBufferPtr> preloaded_audio_buffer_ =
std::nullopt;
std::optional<media::mojom::DecoderBufferPtr> preloaded_video_buffer_ =
std::nullopt;
base::WeakPtrFactory<ReceiverSessionClient> weak_factory_;
};
std::unique_ptr<ReceiverSessionClient> receiver_session_;
};
} // namespace cast_streaming
#endif // COMPONENTS_CAST_STREAMING_BROWSER_CAST_STREAMING_SESSION_H_
|