File: cast_streaming_session.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (241 lines) | stat: -rw-r--r-- 10,691 bytes parent folder | download | duplicates (3)
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_