OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_MEDIA_CAST_REMOTING_SENDER_H_ | 5 #ifndef CHROME_BROWSER_MEDIA_CAST_REMOTING_SENDER_H_ |
6 #define CHROME_BROWSER_MEDIA_CAST_REMOTING_SENDER_H_ | 6 #define CHROME_BROWSER_MEDIA_CAST_REMOTING_SENDER_H_ |
7 | 7 |
8 #include "base/callback_forward.h" | 8 #include "base/callback_forward.h" |
9 #include "base/memory/weak_ptr.h" | 9 #include "base/memory/weak_ptr.h" |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
11 #include "media/cast/cast_config.h" | 11 #include "media/cast/cast_config.h" |
12 #include "media/cast/cast_environment.h" | 12 #include "media/cast/cast_environment.h" |
13 #include "media/cast/net/cast_transport.h" | 13 #include "media/cast/net/cast_transport.h" |
14 #include "media/cast/net/rtcp/rtcp_defines.h" | 14 #include "media/cast/net/rtcp/rtcp_defines.h" |
15 #include "media/mojo/interfaces/remoting.mojom.h" | |
16 #include "mojo/public/cpp/bindings/binding.h" | |
15 | 17 |
16 namespace cast { | 18 namespace cast { |
17 | 19 |
18 // RTP sender for a single Cast Remoting RTP stream. The client calls Send() to | 20 // RTP sender for a single Cast Remoting RTP stream. The client calls Send() to |
19 // instruct the sender to transmit the data using a CastTransport. | 21 // instruct the sender to read from a Mojo data pipe and transmit the data using |
22 // a CastTransport. This entire class executes on the IO BrowserThread. | |
20 // | 23 // |
21 // This class is instantiated and owned by CastTransportHostFilter in response | 24 // This class is instantiated and owned by CastTransportHostFilter in response |
22 // to IPC messages from an extension process to create RTP streams for the media | 25 // to IPC messages from an extension process to create RTP streams for the media |
23 // remoting use case. CastTransportHostFilter is also responsible for destroying | 26 // remoting use case. CastTransportHostFilter is also responsible for destroying |
24 // the instance in response to later IPCs. | 27 // the instance in response to later IPCs. |
25 // | 28 // |
26 // TODO(miu): Mojo service bindings/implementation to read from data pipes will | 29 // The Media Router provider extension controls the entire set-up process: |
27 // be added in a soon-upcoming change. | 30 // First, it uses the cast.streaming APIs to create remoting API streams (which |
28 | 31 // instantiates one or more CastRemotingSenders). Then, it sends a message via |
29 class CastRemotingSender { | 32 // Media Router to a CastRemotingConnector to indicate the bitstream transport |
33 // is ready. Finally, CastRemotingConnector calls FindAndBind() to look-up the | |
34 // CastRemotingSender instances and establish the Mojo bindings and data flows. | |
35 class CastRemotingSender : public media::mojom::RemotingDataStreamSender { | |
30 public: | 36 public: |
31 // |transport| is expected to outlive this class. | 37 // |transport| is expected to outlive this class. |
32 explicit CastRemotingSender( | 38 CastRemotingSender( |
33 scoped_refptr<media::cast::CastEnvironment> cast_environment, | 39 scoped_refptr<media::cast::CastEnvironment> cast_environment, |
34 media::cast::CastTransport* transport, | 40 media::cast::CastTransport* transport, |
35 const media::cast::CastTransportRtpConfig& config); | 41 const media::cast::CastTransportRtpConfig& config); |
36 ~CastRemotingSender(); | 42 ~CastRemotingSender() final; |
43 | |
44 // Look-up a CastRemotingSender instance by its |rtp_stream_id| and then bind | |
45 // to the given |request|. The client of the RemotingDataStreamSender will | |
46 // then instruct this CastRemotingSender when to read from the data |pipe| and | |
47 // send the data to the Cast Receiver. If the bind fails, or an error occurs | |
48 // reading from the data pipe during later operation, the |error_callback| is | |
49 // run. | |
50 // | |
51 // Threading note: This function is thread-safe, but its internal | |
52 // implementation runs on the IO BrowserThread. If |error_callback| is run, it | |
53 // will execute on the thread that called this function. | |
54 static void FindAndBind(int32_t rtp_stream_id, | |
55 mojo::ScopedDataPipeConsumerHandle pipe, | |
56 media::mojom::RemotingDataStreamSenderRequest request, | |
57 const base::Closure& error_callback); | |
37 | 58 |
38 private: | 59 private: |
39 // Friend class for unit tests. | 60 // Friend class for unit tests. |
40 friend class CastRemotingSenderTest; | 61 friend class CastRemotingSenderTest; |
41 | 62 |
42 class RemotingRtcpClient; | 63 class RemotingRtcpClient; |
43 | 64 |
44 // Called to send the serialized frame data. | 65 // media::mojom::RemotingDataStreamSender implementation. |
45 void SendFrame(); | 66 void ConsumeDataChunk(uint32_t offset, uint32_t size, |
46 | 67 uint32_t total_payload_size) final; |
47 // Called to cancel all the in flight frames when seeking happens. | 68 void SendFrame() final; |
48 void CancelFramesInFlight(); | 69 void CancelInFlightData() final; |
49 | 70 |
50 // These are called to deliver RTCP feedback from the receiver. | 71 // These are called to deliver RTCP feedback from the receiver. |
51 void OnReceivedCastMessage(const media::cast::RtcpCastMessage& cast_feedback); | 72 void OnReceivedCastMessage(const media::cast::RtcpCastMessage& cast_feedback); |
52 void OnReceivedRtt(base::TimeDelta round_trip_time); | 73 void OnReceivedRtt(base::TimeDelta round_trip_time); |
53 | 74 |
54 // Returns the number of frames that were sent but not yet acknowledged. This | 75 // Returns the number of frames that were sent to the CastTransport, but not |
55 // does not account for frames acknowledged out-of-order, and is always a high | 76 // yet acknowledged. This is always a high watermark estimate, as frames may |
56 // watermark estimate. | 77 // have been acknowledged out-of-order. Also, this does not account for any |
78 // frames queued-up in input pipeline (i.e., in the Mojo data pipe, nor in | |
79 // |next_frame_data_|). | |
57 int NumberOfFramesInFlight() const; | 80 int NumberOfFramesInFlight() const; |
58 | 81 |
59 // Schedule and execute periodic checks for re-sending packets. If no | 82 // Schedule and execute periodic checks for re-sending packets. If no |
60 // acknowledgements have been received for "too long," CastRemotingSender will | 83 // acknowledgements have been received for "too long," CastRemotingSender will |
61 // speculatively re-send certain packets of an unacked frame to kick-start | 84 // speculatively re-send certain packets of an unacked frame to kick-start |
62 // re-transmission. This is a last resort tactic to prevent the session from | 85 // re-transmission. This is a last resort tactic to prevent the session from |
63 // getting stuck after a long outage. | 86 // getting stuck after a long outage. |
64 void ScheduleNextResendCheck(); | 87 void ScheduleNextResendCheck(); |
65 void ResendCheck(); | 88 void ResendCheck(); |
66 void ResendForKickstart(); | 89 void ResendForKickstart(); |
67 | 90 |
68 void RecordLatestFrameTimestamps(media::cast::FrameId frame_id, | 91 void RecordLatestFrameTimestamps(media::cast::FrameId frame_id, |
69 media::cast::RtpTimeTicks rtp_timestamp); | 92 media::cast::RtpTimeTicks rtp_timestamp); |
70 media::cast::RtpTimeTicks GetRecordedRtpTimestamp( | 93 media::cast::RtpTimeTicks GetRecordedRtpTimestamp( |
71 media::cast::FrameId frame_id) const; | 94 media::cast::FrameId frame_id) const; |
72 | 95 |
73 // Unique identifier for the RTP stream and this CastRemotingSender. | 96 // Unique identifier for the RTP stream and this CastRemotingSender. |
74 const int32_t remoting_stream_id_; | 97 const int32_t rtp_stream_id_; |
75 | 98 |
76 const scoped_refptr<media::cast::CastEnvironment> cast_environment_; | 99 const scoped_refptr<media::cast::CastEnvironment> cast_environment_; |
77 | 100 |
78 // Sends encoded frames over the configured transport (e.g., UDP). It outlives | 101 // Sends encoded frames over the configured transport (e.g., UDP). It outlives |
79 // this class. | 102 // this class. |
80 media::cast::CastTransport* const transport_; | 103 media::cast::CastTransport* const transport_; |
81 | 104 |
82 const uint32_t ssrc_; | 105 const uint32_t ssrc_; |
83 | 106 |
84 const bool is_audio_; | 107 const bool is_audio_; |
85 | 108 |
109 // Callback that is run to notify when a fatal error occurs. | |
110 base::Closure error_callback_; | |
111 | |
112 // Mojo data pipe from which to consume data. | |
113 mojo::ScopedDataPipeConsumerHandle pipe_; | |
114 | |
115 // Mojo binding for this instance. Implementation at the other end of the | |
116 // message pipe uses the RemotingDataStreamSender interface to control when | |
117 // this CastRemotingSender consumes from |pipe_|. | |
118 mojo::Binding<RemotingDataStreamSender> binding_; | |
119 | |
86 // This is the maximum delay that the sender should get ack from receiver. | 120 // This is the maximum delay that the sender should get ack from receiver. |
87 // Otherwise, sender will call ResendForKickstart(). | 121 // Otherwise, sender will call ResendForKickstart(). |
88 base::TimeDelta max_ack_delay_; | 122 base::TimeDelta max_ack_delay_; |
89 | 123 |
90 // This is "null" until the first frame is sent. Thereafter, this tracks the | 124 // This is "null" until the first frame is sent. Thereafter, this tracks the |
91 // last time any frame was sent or re-sent. | 125 // last time any frame was sent or re-sent. |
92 base::TimeTicks last_send_time_; | 126 base::TimeTicks last_send_time_; |
93 | 127 |
94 // The ID of the last frame sent. This member is invalid until | 128 // The ID of the last frame sent. This member is invalid until |
95 // |!last_send_time_.is_null()|. | 129 // |!last_send_time_.is_null()|. |
96 media::cast::FrameId last_sent_frame_id_; | 130 media::cast::FrameId last_sent_frame_id_; |
97 | 131 |
98 // The ID of the latest (not necessarily the last) frame that has been | 132 // The ID of the latest (not necessarily the last) frame that has been |
99 // acknowledged. This member is invalid until |!last_send_time_.is_null()|. | 133 // acknowledged. This member is invalid until |!last_send_time_.is_null()|. |
100 media::cast::FrameId latest_acked_frame_id_; | 134 media::cast::FrameId latest_acked_frame_id_; |
101 | 135 |
102 // Counts the number of duplicate ACK that are being received. When this | 136 // Counts the number of duplicate ACK that are being received. When this |
103 // number reaches a threshold, the sender will take this as a sign that the | 137 // number reaches a threshold, the sender will take this as a sign that the |
104 // receiver hasn't yet received the first packet of the next frame. In this | 138 // receiver hasn't yet received the first packet of the next frame. In this |
105 // case, CastRemotingSender will trigger a re-send of the next frame. | 139 // case, CastRemotingSender will trigger a re-send of the next frame. |
106 int duplicate_ack_counter_; | 140 int duplicate_ack_counter_; |
107 | 141 |
108 // The most recently measured round trip time. | 142 // The most recently measured round trip time. |
109 base::TimeDelta current_round_trip_time_; | 143 base::TimeDelta current_round_trip_time_; |
110 | 144 |
111 // The next frame's payload data. Populated by one or more calls to | 145 // The next frame's payload data. Populated by one or more calls to |
112 // ConsumeDataChunk(). | 146 // ConsumeDataChunk(). |
113 // TODO(miu): To be implemented in soon upcoming change. | |
114 std::string next_frame_data_; | 147 std::string next_frame_data_; |
115 | 148 |
116 // Ring buffer to keep track of recent frame RTP timestamps. This should | 149 // Ring buffer to keep track of recent frame RTP timestamps. This should |
117 // only be accessed through the Record/GetXX() methods. The index into this | 150 // only be accessed through the Record/GetXX() methods. The index into this |
118 // ring buffer is the lower 8 bits of the FrameId. | 151 // ring buffer is the lower 8 bits of the FrameId. |
119 media::cast::RtpTimeTicks frame_rtp_timestamps_[256]; | 152 media::cast::RtpTimeTicks frame_rtp_timestamps_[256]; |
120 | 153 |
121 // This flag indicates whether CancelFramesInFlight() was called. | 154 // Current flow control state. |
122 bool last_frame_was_canceled_; | 155 enum { |
156 RESTARTING, // Starting new, or restarting after CancelInFlightData(). | |
xjz
2016/09/15 18:01:49
nit: How about just STARTING? Actually this status
miu
2016/09/16 16:39:28
Done.
| |
157 CONSUMING, // Reading from Mojo data pipes. | |
158 CONSUME_PAUSED, // Too many frames in-flight; paused Mojo input. | |
159 } flow_control_state_; | |
123 | 160 |
124 // NOTE: Weak pointers must be invalidated before all other member variables. | 161 // NOTE: Weak pointers must be invalidated before all other member variables. |
125 base::WeakPtrFactory<CastRemotingSender> weak_factory_; | 162 base::WeakPtrFactory<CastRemotingSender> weak_factory_; |
126 | 163 |
127 DISALLOW_COPY_AND_ASSIGN(CastRemotingSender); | 164 DISALLOW_COPY_AND_ASSIGN(CastRemotingSender); |
128 }; | 165 }; |
129 | 166 |
130 } // namespace cast | 167 } // namespace cast |
131 | 168 |
132 #endif // CHROME_BROWSER_MEDIA_CAST_REMOTING_SENDER_H_ | 169 #endif // CHROME_BROWSER_MEDIA_CAST_REMOTING_SENDER_H_ |
OLD | NEW |