OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 #include "media/cast/video_sender/video_sender.h" | 5 #include "media/cast/video_sender/video_sender.h" |
6 | 6 |
7 #include <cstring> | 7 #include <cstring> |
8 #include <list> | 8 #include <list> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
44 const VideoSenderConfig& video_config, | 44 const VideoSenderConfig& video_config, |
45 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, | 45 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, |
46 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, | 46 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, |
47 const CastInitializationCallback& cast_initialization_cb, | 47 const CastInitializationCallback& cast_initialization_cb, |
48 transport::CastTransportSender* const transport_sender) | 48 transport::CastTransportSender* const transport_sender) |
49 : rtp_max_delay_(base::TimeDelta::FromMilliseconds( | 49 : rtp_max_delay_(base::TimeDelta::FromMilliseconds( |
50 video_config.rtp_config.max_delay_ms)), | 50 video_config.rtp_config.max_delay_ms)), |
51 max_frame_rate_(video_config.max_frame_rate), | 51 max_frame_rate_(video_config.max_frame_rate), |
52 cast_environment_(cast_environment), | 52 cast_environment_(cast_environment), |
53 transport_sender_(transport_sender), | 53 transport_sender_(transport_sender), |
54 rtp_stats_(kVideoFrequency), | 54 rtp_timestamp_helper_(kVideoFrequency), |
55 rtcp_feedback_(new LocalRtcpVideoSenderFeedback(this)), | 55 rtcp_feedback_(new LocalRtcpVideoSenderFeedback(this)), |
56 last_acked_frame_id_(-1), | 56 last_acked_frame_id_(-1), |
57 last_sent_frame_id_(-1), | 57 last_sent_frame_id_(-1), |
58 frames_in_encoder_(0), | 58 frames_in_encoder_(0), |
59 duplicate_ack_(0), | 59 duplicate_ack_(0), |
60 last_skip_count_(0), | 60 last_skip_count_(0), |
61 current_requested_bitrate_(video_config.start_bitrate), | 61 current_requested_bitrate_(video_config.start_bitrate), |
62 current_bitrate_divider_(1), | 62 current_bitrate_divider_(1), |
63 congestion_control_(cast_environment->Clock(), | 63 congestion_control_(cast_environment->Clock(), |
64 video_config.congestion_control_back_off, | 64 video_config.congestion_control_back_off, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 rtcp_->SetCastReceiverEventHistorySize(kReceiverRtcpEventHistorySize); | 106 rtcp_->SetCastReceiverEventHistorySize(kReceiverRtcpEventHistorySize); |
107 | 107 |
108 // TODO(pwestin): pass cast_initialization_cb to |video_encoder_| | 108 // TODO(pwestin): pass cast_initialization_cb to |video_encoder_| |
109 // and remove this call. | 109 // and remove this call. |
110 cast_environment_->PostTask( | 110 cast_environment_->PostTask( |
111 CastEnvironment::MAIN, | 111 CastEnvironment::MAIN, |
112 FROM_HERE, | 112 FROM_HERE, |
113 base::Bind(cast_initialization_cb, STATUS_VIDEO_INITIALIZED)); | 113 base::Bind(cast_initialization_cb, STATUS_VIDEO_INITIALIZED)); |
114 | 114 |
115 memset(frame_id_to_rtp_timestamp_, 0, sizeof(frame_id_to_rtp_timestamp_)); | 115 memset(frame_id_to_rtp_timestamp_, 0, sizeof(frame_id_to_rtp_timestamp_)); |
116 | |
117 transport_sender_->SubscribeVideoRtpStatsCallback( | |
118 base::Bind(&VideoSender::StoreStatistics, weak_factory_.GetWeakPtr())); | |
119 } | 116 } |
120 | 117 |
121 VideoSender::~VideoSender() { | 118 VideoSender::~VideoSender() { |
122 } | 119 } |
123 | 120 |
124 void VideoSender::InitializeTimers() { | 121 void VideoSender::InitializeTimers() { |
125 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 122 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
126 if (!initialized_) { | 123 if (!initialized_) { |
127 initialized_ = true; | 124 initialized_ = true; |
128 ScheduleNextResendCheck(); | 125 ScheduleNextResendCheck(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc | 182 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc |
186 TRACE_EVENT_INSTANT1( | 183 TRACE_EVENT_INSTANT1( |
187 "cast_perf_test", "VideoFrameEncoded", | 184 "cast_perf_test", "VideoFrameEncoded", |
188 TRACE_EVENT_SCOPE_THREAD, | 185 TRACE_EVENT_SCOPE_THREAD, |
189 "rtp_timestamp", GetVideoRtpTimestamp(capture_time)); | 186 "rtp_timestamp", GetVideoRtpTimestamp(capture_time)); |
190 | 187 |
191 // Only use lowest 8 bits as key. | 188 // Only use lowest 8 bits as key. |
192 frame_id_to_rtp_timestamp_[frame_id & 0xff] = encoded_frame->rtp_timestamp; | 189 frame_id_to_rtp_timestamp_[frame_id & 0xff] = encoded_frame->rtp_timestamp; |
193 | 190 |
194 last_sent_frame_id_ = static_cast<int>(encoded_frame->frame_id); | 191 last_sent_frame_id_ = static_cast<int>(encoded_frame->frame_id); |
192 rtp_timestamp_helper_.StoreLatestTime(capture_time, | |
193 encoded_frame->rtp_timestamp); | |
195 transport_sender_->InsertCodedVideoFrame(encoded_frame.get(), capture_time); | 194 transport_sender_->InsertCodedVideoFrame(encoded_frame.get(), capture_time); |
196 UpdateFramesInFlight(); | 195 UpdateFramesInFlight(); |
197 InitializeTimers(); | 196 InitializeTimers(); |
198 } | 197 } |
199 | 198 |
200 void VideoSender::IncomingRtcpPacket(scoped_ptr<Packet> packet) { | 199 void VideoSender::IncomingRtcpPacket(scoped_ptr<Packet> packet) { |
201 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 200 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
202 rtcp_->IncomingRtcpPacket(&packet->front(), packet->size()); | 201 rtcp_->IncomingRtcpPacket(&packet->front(), packet->size()); |
203 } | 202 } |
204 | 203 |
205 void VideoSender::ScheduleNextRtcpReport() { | 204 void VideoSender::ScheduleNextRtcpReport() { |
206 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 205 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
207 base::TimeDelta time_to_next = rtcp_->TimeToSendNextRtcpReport() - | 206 base::TimeDelta time_to_next = rtcp_->TimeToSendNextRtcpReport() - |
208 cast_environment_->Clock()->NowTicks(); | 207 cast_environment_->Clock()->NowTicks(); |
209 | 208 |
210 time_to_next = std::max( | 209 time_to_next = std::max( |
211 time_to_next, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); | 210 time_to_next, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); |
212 | 211 |
213 cast_environment_->PostDelayedTask( | 212 cast_environment_->PostDelayedTask( |
214 CastEnvironment::MAIN, | 213 CastEnvironment::MAIN, |
215 FROM_HERE, | 214 FROM_HERE, |
216 base::Bind(&VideoSender::SendRtcpReport, weak_factory_.GetWeakPtr()), | 215 base::Bind(&VideoSender::SendRtcpReport, weak_factory_.GetWeakPtr()), |
217 time_to_next); | 216 time_to_next); |
218 } | 217 } |
219 | 218 |
220 void VideoSender::StoreStatistics( | |
221 const transport::RtcpSenderInfo& sender_info, | |
222 base::TimeTicks time_sent, | |
223 uint32 rtp_timestamp) { | |
224 rtp_stats_.Store(sender_info, time_sent, rtp_timestamp); | |
225 } | |
226 | |
227 void VideoSender::SendRtcpReport() { | 219 void VideoSender::SendRtcpReport() { |
228 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 220 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
229 | 221 const base::TimeTicks now = cast_environment_->Clock()->NowTicks(); |
230 rtp_stats_.UpdateInfo(cast_environment_->Clock()->NowTicks()); | 222 uint32 now_as_rtp_timestamp = 0; |
231 rtcp_->SendRtcpFromRtpSender(rtp_stats_.sender_info()); | 223 if (rtp_timestamp_helper_.GetCurrentTimeAsRtpTimestamp( |
miu
2014/05/13 01:11:56
We need to document in code comments why we're rol
Alpha Left Google
2014/05/13 21:45:39
Already documented in rtcp.h.
| |
224 now, &now_as_rtp_timestamp)) { | |
225 rtcp_->SendRtcpFromRtpSender(now, now_as_rtp_timestamp); | |
226 } | |
232 ScheduleNextRtcpReport(); | 227 ScheduleNextRtcpReport(); |
233 } | 228 } |
234 | 229 |
235 void VideoSender::ScheduleNextResendCheck() { | 230 void VideoSender::ScheduleNextResendCheck() { |
236 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 231 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
237 base::TimeDelta time_to_next; | 232 base::TimeDelta time_to_next; |
238 if (last_send_time_.is_null()) { | 233 if (last_send_time_.is_null()) { |
239 time_to_next = rtp_max_delay_; | 234 time_to_next = rtp_max_delay_; |
240 } else { | 235 } else { |
241 time_to_next = last_send_time_ - cast_environment_->Clock()->NowTicks() + | 236 time_to_next = last_send_time_ - cast_environment_->Clock()->NowTicks() + |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
437 void VideoSender::UpdateBitrate(int new_bitrate) { | 432 void VideoSender::UpdateBitrate(int new_bitrate) { |
438 new_bitrate /= current_bitrate_divider_; | 433 new_bitrate /= current_bitrate_divider_; |
439 // Make sure we don't set the bitrate too insanely low. | 434 // Make sure we don't set the bitrate too insanely low. |
440 DCHECK_GT(new_bitrate, 1000); | 435 DCHECK_GT(new_bitrate, 1000); |
441 video_encoder_->SetBitRate(new_bitrate); | 436 video_encoder_->SetBitRate(new_bitrate); |
442 current_requested_bitrate_ = new_bitrate; | 437 current_requested_bitrate_ = new_bitrate; |
443 } | 438 } |
444 | 439 |
445 } // namespace cast | 440 } // namespace cast |
446 } // namespace media | 441 } // namespace media |
OLD | NEW |