| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/sender/video_sender.h" | 5 #include "media/cast/sender/video_sender.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 rtp_timestamp, | 119 rtp_timestamp, |
| 120 kFrameIdUnknown); | 120 kFrameIdUnknown); |
| 121 | 121 |
| 122 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc | 122 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc |
| 123 TRACE_EVENT_INSTANT2( | 123 TRACE_EVENT_INSTANT2( |
| 124 "cast_perf_test", "InsertRawVideoFrame", | 124 "cast_perf_test", "InsertRawVideoFrame", |
| 125 TRACE_EVENT_SCOPE_THREAD, | 125 TRACE_EVENT_SCOPE_THREAD, |
| 126 "timestamp", capture_time.ToInternalValue(), | 126 "timestamp", capture_time.ToInternalValue(), |
| 127 "rtp_timestamp", rtp_timestamp); | 127 "rtp_timestamp", rtp_timestamp); |
| 128 | 128 |
| 129 if (AreTooManyFramesInFlight()) { | 129 if (ShouldDropNextFrame(capture_time)) { |
| 130 VLOG(1) << "Dropping frame due to too many frames currently in-flight."; | 130 VLOG(1) << "Dropping frame due to too many frames currently in-flight."; |
| 131 return; | 131 return; |
| 132 } | 132 } |
| 133 | 133 |
| 134 uint32 bitrate = fixed_bitrate_; | 134 uint32 bitrate = fixed_bitrate_; |
| 135 if (!bitrate) { | 135 if (!bitrate) { |
| 136 bitrate = congestion_control_.GetBitrate( | 136 bitrate = congestion_control_.GetBitrate( |
| 137 capture_time + target_playout_delay_, target_playout_delay_); | 137 capture_time + target_playout_delay_, target_playout_delay_); |
| 138 DCHECK(bitrate); | 138 DCHECK(bitrate); |
| 139 video_encoder_->SetBitRate(bitrate); | 139 video_encoder_->SetBitRate(bitrate); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 167 const uint32 frame_id = encoded_frame->frame_id; | 167 const uint32 frame_id = encoded_frame->frame_id; |
| 168 | 168 |
| 169 const bool is_first_frame_to_be_sent = last_send_time_.is_null(); | 169 const bool is_first_frame_to_be_sent = last_send_time_.is_null(); |
| 170 last_send_time_ = cast_environment_->Clock()->NowTicks(); | 170 last_send_time_ = cast_environment_->Clock()->NowTicks(); |
| 171 last_sent_frame_id_ = frame_id; | 171 last_sent_frame_id_ = frame_id; |
| 172 // If this is the first frame about to be sent, fake the value of | 172 // If this is the first frame about to be sent, fake the value of |
| 173 // |latest_acked_frame_id_| to indicate the receiver starts out all caught up. | 173 // |latest_acked_frame_id_| to indicate the receiver starts out all caught up. |
| 174 // Also, schedule the periodic frame re-send checks. | 174 // Also, schedule the periodic frame re-send checks. |
| 175 if (is_first_frame_to_be_sent) { | 175 if (is_first_frame_to_be_sent) { |
| 176 latest_acked_frame_id_ = frame_id - 1; | 176 latest_acked_frame_id_ = frame_id - 1; |
| 177 frame_id_to_rtp_timestamp_[latest_acked_frame_id_ & 0xff] = |
| 178 encoded_frame->rtp_timestamp; |
| 177 ScheduleNextResendCheck(); | 179 ScheduleNextResendCheck(); |
| 178 } | 180 } |
| 179 | 181 |
| 180 VLOG_IF(1, encoded_frame->dependency == EncodedFrame::KEY) | 182 VLOG_IF(1, encoded_frame->dependency == EncodedFrame::KEY) |
| 181 << "Send encoded key frame; frame_id: " << frame_id; | 183 << "Send encoded key frame; frame_id: " << frame_id; |
| 182 | 184 |
| 183 cast_environment_->Logging()->InsertEncodedFrameEvent( | 185 cast_environment_->Logging()->InsertEncodedFrameEvent( |
| 184 last_send_time_, FRAME_ENCODED, VIDEO_EVENT, encoded_frame->rtp_timestamp, | 186 last_send_time_, FRAME_ENCODED, VIDEO_EVENT, encoded_frame->rtp_timestamp, |
| 185 frame_id, static_cast<int>(encoded_frame->data.size()), | 187 frame_id, static_cast<int>(encoded_frame->data.size()), |
| 186 encoded_frame->dependency == EncodedFrame::KEY, | 188 encoded_frame->dependency == EncodedFrame::KEY, |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 std::vector<uint32> cancel_sending_frames; | 333 std::vector<uint32> cancel_sending_frames; |
| 332 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) { | 334 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) { |
| 333 latest_acked_frame_id_++; | 335 latest_acked_frame_id_++; |
| 334 cancel_sending_frames.push_back(latest_acked_frame_id_); | 336 cancel_sending_frames.push_back(latest_acked_frame_id_); |
| 335 } | 337 } |
| 336 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames); | 338 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames); |
| 337 latest_acked_frame_id_ = cast_feedback.ack_frame_id; | 339 latest_acked_frame_id_ = cast_feedback.ack_frame_id; |
| 338 } | 340 } |
| 339 } | 341 } |
| 340 | 342 |
| 341 bool VideoSender::AreTooManyFramesInFlight() const { | 343 bool VideoSender::ShouldDropNextFrame(base::TimeTicks capture_time) const { |
| 342 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 344 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 343 int frames_in_flight = frames_in_encoder_; | 345 int frames_in_flight = 0; |
| 346 int32 rtp_duration_in_flight = 0; |
| 344 if (!last_send_time_.is_null()) { | 347 if (!last_send_time_.is_null()) { |
| 345 frames_in_flight += | 348 frames_in_flight = |
| 346 static_cast<int32>(last_sent_frame_id_ - latest_acked_frame_id_); | 349 static_cast<int32>(last_sent_frame_id_ - latest_acked_frame_id_); |
| 350 uint32 estimated_rtp_timestamp; |
| 351 if (frames_in_flight > 0 && |
| 352 rtp_timestamp_helper_.EstimateRtpTimestamp(capture_time, |
| 353 &estimated_rtp_timestamp)) { |
| 354 const uint32 oldest_unacked_frame_id = latest_acked_frame_id_ + 1; |
| 355 rtp_duration_in_flight = static_cast<int32>( |
| 356 estimated_rtp_timestamp - |
| 357 frame_id_to_rtp_timestamp_[oldest_unacked_frame_id & 0xff]); |
| 358 } |
| 347 } | 359 } |
| 360 frames_in_flight += frames_in_encoder_; |
| 348 VLOG(2) << frames_in_flight | 361 VLOG(2) << frames_in_flight |
| 349 << " frames in flight; last sent: " << last_sent_frame_id_ | 362 << " frames in flight; last sent: " << last_sent_frame_id_ |
| 350 << " latest acked: " << latest_acked_frame_id_ | 363 << "; latest acked: " << latest_acked_frame_id_ |
| 351 << " frames in encoder: " << frames_in_encoder_; | 364 << "; frames in encoder: " << frames_in_encoder_ |
| 352 return frames_in_flight >= max_unacked_frames_; | 365 << "; duration in flight: " |
| 366 << (max_unacked_rtp_delta_ > 0 ? |
| 367 100 * rtp_duration_in_flight / max_unacked_rtp_delta_ : |
| 368 kint32max) << "%"; |
| 369 return frames_in_flight >= max_unacked_frames_ || |
| 370 rtp_duration_in_flight >= max_unacked_rtp_delta_; |
| 353 } | 371 } |
| 354 | 372 |
| 355 void VideoSender::ResendForKickstart() { | 373 void VideoSender::ResendForKickstart() { |
| 356 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 374 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 357 DCHECK(!last_send_time_.is_null()); | 375 DCHECK(!last_send_time_.is_null()); |
| 358 VLOG(1) << "Resending last packet of frame " << last_sent_frame_id_ | 376 VLOG(1) << "Resending last packet of frame " << last_sent_frame_id_ |
| 359 << " to kick-start."; | 377 << " to kick-start."; |
| 360 last_send_time_ = cast_environment_->Clock()->NowTicks(); | 378 last_send_time_ = cast_environment_->Clock()->NowTicks(); |
| 361 transport_sender_->ResendFrameForKickstart(ssrc_, last_sent_frame_id_); | 379 transport_sender_->ResendFrameForKickstart(ssrc_, last_sent_frame_id_); |
| 362 } | 380 } |
| 363 | 381 |
| 364 } // namespace cast | 382 } // namespace cast |
| 365 } // namespace media | 383 } // namespace media |
| OLD | NEW |