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