File: remoting_sender.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 (159 lines) | stat: -rw-r--r-- 5,950 bytes parent folder | download | duplicates (6)
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
// Copyright 2018 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_MIRRORING_SERVICE_REMOTING_SENDER_H_
#define COMPONENTS_MIRRORING_SERVICE_REMOTING_SENDER_H_

#include <memory>

#include "base/component_export.h"
#include "base/containers/queue.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "media/cast/sender/frame_sender.h"
#include "media/mojo/mojom/remoting.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"

namespace base {
class TickClock;
}  // namespace base

namespace media {
class DecoderBuffer;
}  // namespace media

namespace media::cast {
class DecoderBufferReader;
}  // namespace media::cast

namespace openscreen::cast {
class Sender;
}  // namespace openscreen::cast

namespace mirroring {

// RTP sender for a single Cast Remoting RTP stream. The client calls Send() to
// instruct the sender to read from a Mojo data pipe and transmit the data using
// a CastTransport.
class COMPONENT_EXPORT(MIRRORING_SERVICE) RemotingSender final
    : public media::mojom::RemotingDataStreamSender,
      public media::cast::FrameSender::Client {
 public:
  // New way of instantiating using an openscreen::cast::Sender. Since the
  // |Sender| instance is destroyed when renegotiation is complete, |this|
  // is also invalid and should be immediately torn down.
  RemotingSender(scoped_refptr<media::cast::CastEnvironment> cast_environment,
                 std::unique_ptr<openscreen::cast::Sender> sender,
                 const media::cast::FrameSenderConfig& config,
                 mojo::ScopedDataPipeConsumerHandle pipe,
                 mojo::PendingReceiver<media::mojom::RemotingDataStreamSender>
                     stream_sender,
                 base::OnceClosure error_callback);

  RemotingSender(const RemotingSender&) = delete;
  RemotingSender& operator=(const RemotingSender&) = delete;

  ~RemotingSender() override;

 private:
  // Ctor that takes a media::cast::FrameSender for unit tests.
  // TODO(issues.chromium.org/329781397): Remove unnecessary wrapper objects in
  // Chrome's implementation of the Cast sender.
  RemotingSender(scoped_refptr<media::cast::CastEnvironment> cast_environment,
                 std::unique_ptr<media::cast::FrameSender> sender,
                 const media::cast::FrameSenderConfig& config,
                 mojo::ScopedDataPipeConsumerHandle pipe,
                 mojo::PendingReceiver<media::mojom::RemotingDataStreamSender>
                     stream_sender,
                 base::OnceClosure error_callback);

  // Friend class for unit tests.
  friend class RemotingSenderTest;

  // Creates SenderEncodedFrames.
  class SenderEncodedFrameFactory;

  // media::mojom::RemotingDataStreamSender implementation.
  void SendFrame(media::mojom::DecoderBufferPtr buffer,
                 SendFrameCallback callback) override;
  void CancelInFlightData() override;

  // FrameSender::Client overrides.
  int GetNumberOfFramesInEncoder() const override;
  base::TimeDelta GetEncoderBacklogDuration() const override;
  void OnFrameCanceled(media::cast::FrameId frame_id) override;

  // Sends out the frame to the receiver over network if |frame_sender_| has
  // available space to handle it.
  void TrySendFrame();

  // Sets |next_frame_| once it has been read from the data pipe.
  void OnFrameRead(scoped_refptr<media::DecoderBuffer> buffer);

  // Called when |stream_sender_| is disconnected.
  void OnRemotingDataStreamError();

  // Clears the current frame and requests a new one be sent.
  void ClearCurrentFrame();

  // Returns true if OnRemotingDataStreamError was called.
  bool HadError() const {
    DCHECK_EQ(!decoder_buffer_reader_, !stream_sender_.is_bound());
    return !decoder_buffer_reader_;
  }

  SEQUENCE_CHECKER(sequence_checker_);

  // The backing frame sender implementation.
  std::unique_ptr<media::cast::FrameSender> frame_sender_;

  raw_ref<const base::TickClock> clock_;

  // Callback that is run to notify when a fatal error occurs.
  base::OnceClosure error_callback_;

  // Reads media::DecoderBuffer instances and passes them to OnFrameRead().
  std::unique_ptr<media::cast::DecoderBufferReader> decoder_buffer_reader_;

  // Mojo receiver for this instance. Implementation at the other end of the
  // message pipe uses the RemotingDataStreamSender remote to control when
  // this RemotingSender consumes from |pipe_|.
  mojo::Receiver<media::mojom::RemotingDataStreamSender> stream_sender_;

  // Whether this is an audio sender (true) or a video sender (false).
  const bool is_audio_;

  // Responsible for creating encoded frames.
  std::unique_ptr<SenderEncodedFrameFactory> frame_factory_;

  // The next frame. Populated by call to OnFrameRead() when reading succeeded.
  scoped_refptr<media::DecoderBuffer> next_frame_;

  // To be called once a frame has been successfully read and this instance is
  // ready to process a new one.
  SendFrameCallback read_complete_cb_;

  // Set to true if the first frame has not yet been sent, or if a
  // CancelInFlightData() operation just completed. This causes TrySendFrame()
  // to mark the next frame as the start of a new sequence.
  bool flow_restart_pending_ = true;

  // Number of EnqueueFrame() calls that have failed since the last successful
  // call.
  int consecutive_enqueue_frame_failure_count_ = 0;

  // The next frame's ID. Before any frames are sent, this will be the ID of
  // the first frame.
  media::cast::FrameId next_frame_id_ = media::cast::FrameId::first();

  // NOTE: Weak pointers must be invalidated before all other member variables.
  base::WeakPtrFactory<RemotingSender> weak_factory_{this};
};

}  // namespace mirroring

#endif  // COMPONENTS_MIRRORING_SERVICE_REMOTING_SENDER_H_