1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_MIRRORING_BROWSER_CAST_REMOTING_SENDER_H_
6 #define COMPONENTS_MIRRORING_BROWSER_CAST_REMOTING_SENDER_H_
7 
8 #include "base/callback_forward.h"
9 #include "base/containers/queue.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/time/time.h"
12 #include "media/cast/cast_config.h"
13 #include "media/cast/net/cast_transport.h"
14 #include "media/cast/net/rtcp/rtcp_defines.h"
15 #include "media/mojo/mojom/remoting.mojom.h"
16 #include "mojo/public/cpp/bindings/pending_receiver.h"
17 #include "mojo/public/cpp/bindings/receiver.h"
18 
19 namespace media {
20 class MojoDataPipeReader;
21 }  // namespace media
22 
23 namespace mirroring {
24 
25 // The callback that is used to send frame events to renderer process for
26 // logging purpose.
27 using FrameEventCallback =
28     base::RepeatingCallback<void(const std::vector<media::cast::FrameEvent>&)>;
29 
30 // RTP sender for a single Cast Remoting RTP stream. The client calls Send() to
31 // instruct the sender to read from a Mojo data pipe and transmit the data using
32 // a CastTransport. This entire class executes on the IO BrowserThread.
33 //
34 // This class is instantiated and owned by CastTransportHostFilter in response
35 // to IPC messages from an extension process to create RTP streams for the media
36 // remoting use case. CastTransportHostFilter is also responsible for destroying
37 // the instance in response to later IPCs.
38 //
39 // The Media Router provider extension controls the entire set-up process:
40 // First, it uses the cast.streaming APIs to create remoting API streams (which
41 // instantiates one or more CastRemotingSenders). Then, it sends a message via
42 // Media Router to a CastRemotingConnector to indicate the bitstream transport
43 // is ready. Finally, CastRemotingConnector calls FindAndBind() to look-up the
44 // CastRemotingSender instances and establish the Mojo bindings and data flows.
45 class CastRemotingSender : public media::mojom::RemotingDataStreamSender {
46  public:
47   // |transport| is expected to outlive this class.
48   // |logging_flush_interval| must be greater than |base::TimeDelta()| if |cb|
49   // is not null.
50   CastRemotingSender(media::cast::CastTransport* transport,
51                      const media::cast::CastTransportRtpConfig& config,
52                      base::TimeDelta logging_flush_interval,
53                      const FrameEventCallback& cb);
54   ~CastRemotingSender() final;
55 
56   // Look-up a CastRemotingSender instance by its |rtp_stream_id| and then bind
57   // to the given |stream_sender|. The client of the RemotingDataStreamSender
58   // will then instruct this CastRemotingSender when to read from the data
59   // |pipe| and send the data to the Cast Receiver. If the bind fails, or an
60   // error occurs reading from the data pipe during later operation, the
61   // |error_callback| is run.
62   //
63   // Threading note: This function is thread-safe, but its internal
64   // implementation runs on the IO BrowserThread. If |error_callback| is run, it
65   // will execute on the thread that called this function.
66   static void FindAndBind(
67       int32_t rtp_stream_id,
68       mojo::ScopedDataPipeConsumerHandle pipe,
69       mojo::PendingReceiver<media::mojom::RemotingDataStreamSender>
70           stream_sender,
71       base::OnceClosure error_callback);
72 
73  private:
74   // Friend class for unit tests.
75   friend class CastRemotingSenderTest;
76 
77   class RemotingRtcpClient;
78 
79   // media::mojom::RemotingDataStreamSender implementation. SendFrame() will
80   // push callbacks onto the back of the input queue, and these may or may not
81   // be processed at a later time. It depends on whether the data pipe has data
82   // available or the CastTransport can accept more frames. CancelInFlightData()
83   // is processed immediately, and will cause all pending operations to discard
84   // data when they are processed later.
85   void SendFrame(uint32_t frame_size) final;
86   void CancelInFlightData() final;
87 
88   // Attempt to run next pending input task, popping the head of the input queue
89   // as each task succeeds.
90   void ProcessNextInputTask();
91 
92   // These are called via callbacks run from the input queue.
93   // Consumes a frame of |size| from the associated Mojo data pipe.
94   void ReadFrame(uint32_t size);
95   // Sends out the frame to the receiver over network.
96   void TrySendFrame();
97 
98   // Called when a frame is completely read/discarded from the data pipe.
99   void OnFrameRead(bool success);
100 
101   // Called when an input task completes.
102   void OnInputTaskComplete();
103 
104   // These are called to deliver RTCP feedback from the receiver.
105   void OnReceivedCastMessage(const media::cast::RtcpCastMessage& cast_feedback);
106   void OnReceivedRtt(base::TimeDelta round_trip_time);
107 
108   // Returns the number of frames that were sent to the CastTransport, but not
109   // yet acknowledged. This is always a high watermark estimate, as frames may
110   // have been acknowledged out-of-order. Also, this does not account for any
111   // frames queued-up in input pipeline (i.e., in the Mojo data pipe, nor in
112   // |next_frame_data_|).
113   int NumberOfFramesInFlight() const;
114 
115   // Schedule and execute periodic checks for re-sending packets.  If no
116   // acknowledgements have been received for "too long," CastRemotingSender will
117   // speculatively re-send certain packets of an unacked frame to kick-start
118   // re-transmission.  This is a last resort tactic to prevent the session from
119   // getting stuck after a long outage.
120   void ScheduleNextResendCheck();
121   void ResendCheck();
122   void ResendForKickstart();
123 
124   void RecordLatestFrameTimestamps(media::cast::FrameId frame_id,
125                                    media::cast::RtpTimeTicks rtp_timestamp);
126   media::cast::RtpTimeTicks GetRecordedRtpTimestamp(
127       media::cast::FrameId frame_id) const;
128 
129   // If |frame_event_cb_| is not null, this calls |frame_event_cb_| to
130   // periodically send the frame events to renderer process for logging.
131   void SendFrameEvents();
132 
133   // Schedule and execute periodic sending of RTCP report to prevent keepalive
134   // timeouts on receiver side during media pause.
135   void ScheduleNextRtcpReport();
136   void SendRtcpReport();
137 
138   void OnPipeError();
139 
140   // Unique identifier for the RTP stream and this CastRemotingSender.
141   const int32_t rtp_stream_id_;
142 
143   // Sends encoded frames over the configured transport (e.g., UDP). It outlives
144   // this class.
145   media::cast::CastTransport* const transport_;
146 
147   const uint32_t ssrc_;
148 
149   const bool is_audio_;
150 
151   // The interval to send frame events to renderer process for logging. When
152   // |frame_event_cb_| is not null, this must be greater than base::TimeDelta().
153   const base::TimeDelta logging_flush_interval_;
154 
155   // The callback to send frame events to renderer process for logging.
156   const FrameEventCallback frame_event_cb_;
157 
158   const base::TickClock* clock_;
159 
160   // Callback that is run to notify when a fatal error occurs.
161   base::OnceClosure error_callback_;
162 
163   std::unique_ptr<media::MojoDataPipeReader> data_pipe_reader_;
164 
165   // Mojo receiver for this instance. Implementation at the other end of the
166   // message pipe uses the RemotingDataStreamSender remote to control when
167   // this CastRemotingSender consumes from |pipe_|.
168   mojo::Receiver<RemotingDataStreamSender> receiver_{this};
169 
170   // This is the maximum delay that the sender should get ack from receiver.
171   // Otherwise, sender will call ResendForKickstart().
172   base::TimeDelta max_ack_delay_;
173 
174   // This is "null" until the first frame is sent.  Thereafter, this tracks the
175   // last time any frame was sent or re-sent.
176   base::TimeTicks last_send_time_;
177 
178   // The ID of the last frame sent.  This member is invalid until
179   // |!last_send_time_.is_null()|.
180   media::cast::FrameId last_sent_frame_id_;
181 
182   // The ID of the latest (not necessarily the last) frame that has been
183   // acknowledged.  This member is invalid until |!last_send_time_.is_null()|.
184   media::cast::FrameId latest_acked_frame_id_;
185 
186   // Counts the number of duplicate ACK that are being received.  When this
187   // number reaches a threshold, the sender will take this as a sign that the
188   // receiver hasn't yet received the first packet of the next frame.  In this
189   // case, CastRemotingSender will trigger a re-send of the next frame.
190   int duplicate_ack_counter_;
191 
192   // The most recently measured round trip time.
193   base::TimeDelta current_round_trip_time_;
194 
195   // The next frame's payload data. Populated by call to OnFrameRead() when
196   // reading succeeded.
197   std::string next_frame_data_;
198 
199   // Ring buffer to keep track of recent frame RTP timestamps. This should
200   // only be accessed through the Record/GetXX() methods. The index into this
201   // ring buffer is the lower 8 bits of the FrameId.
202   media::cast::RtpTimeTicks frame_rtp_timestamps_[256];
203 
204   // Queue of pending input operations. |input_queue_discards_remaining_|
205   // indicates the number of operations where data should be discarded (due to
206   // CancelInFlightData()).
207   base::queue<base::RepeatingClosure> input_queue_;
208   size_t input_queue_discards_remaining_;
209 
210   // Indicates whether the |data_pipe_reader_| is processing a reading request.
211   bool is_reading_;
212 
213   // Set to true if the first frame has not yet been sent, or if a
214   // CancelInFlightData() operation just completed. This causes TrySendFrame()
215   // to mark the next frame as the start of a new sequence.
216   bool flow_restart_pending_;
217 
218   // FrameEvents pending delivery via |frame_event_cb_|. No event is added if
219   // |frame_event_cb_| is null.
220   std::vector<media::cast::FrameEvent> recent_frame_events_;
221 
222   // NOTE: Weak pointers must be invalidated before all other member variables.
223   base::WeakPtrFactory<CastRemotingSender> weak_factory_{this};
224 
225   DISALLOW_COPY_AND_ASSIGN(CastRemotingSender);
226 };
227 
228 }  // namespace mirroring
229 
230 #endif  // COMPONENTS_MIRRORING_BROWSER_CAST_REMOTING_SENDER_H_
231