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/frame_sender.h" | 5 #include "media/cast/sender/frame_sender.h" |
6 | 6 |
7 #include "base/trace_event/trace_event.h" | 7 #include "base/trace_event/trace_event.h" |
8 #include "media/cast/sender/sender_encoded_frame.h" | 8 #include "media/cast/sender/sender_encoded_frame.h" |
9 | 9 |
10 namespace media { | 10 namespace media { |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 SendRtcpReport(is_last_aggressive_report); | 253 SendRtcpReport(is_last_aggressive_report); |
254 } | 254 } |
255 | 255 |
256 congestion_control_->SendFrameToTransport( | 256 congestion_control_->SendFrameToTransport( |
257 frame_id, encoded_frame->data.size() * 8, last_send_time_); | 257 frame_id, encoded_frame->data.size() * 8, last_send_time_); |
258 | 258 |
259 if (send_target_playout_delay_) { | 259 if (send_target_playout_delay_) { |
260 encoded_frame->new_playout_delay_ms = | 260 encoded_frame->new_playout_delay_ms = |
261 target_playout_delay_.InMilliseconds(); | 261 target_playout_delay_.InMilliseconds(); |
262 } | 262 } |
| 263 |
| 264 TRACE_EVENT_ASYNC_BEGIN2("cast.stream", |
| 265 is_audio_ ? "Audio Transport" : "Video Transport", |
| 266 frame_id, |
| 267 "timestamp", encoded_frame->reference_time.ToInternalValue(), |
| 268 "rtp_timestamp", encoded_frame->rtp_timestamp); |
263 transport_sender_->InsertFrame(ssrc_, *encoded_frame); | 269 transport_sender_->InsertFrame(ssrc_, *encoded_frame); |
264 } | 270 } |
265 | 271 |
266 void FrameSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { | 272 void FrameSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { |
267 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 273 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
268 | 274 |
269 const bool have_valid_rtt = current_round_trip_time_ > base::TimeDelta(); | 275 const bool have_valid_rtt = current_round_trip_time_ > base::TimeDelta(); |
270 if (have_valid_rtt) { | 276 if (have_valid_rtt) { |
271 congestion_control_->UpdateRtt(current_round_trip_time_); | 277 congestion_control_->UpdateRtt(current_round_trip_time_); |
272 | 278 |
(...skipping 19 matching lines...) Expand all Loading... |
292 if (latest_acked_frame_id_ == cast_feedback.ack_frame_id && | 298 if (latest_acked_frame_id_ == cast_feedback.ack_frame_id && |
293 latest_acked_frame_id_ != last_sent_frame_id_) { | 299 latest_acked_frame_id_ != last_sent_frame_id_) { |
294 duplicate_ack_counter_++; | 300 duplicate_ack_counter_++; |
295 } else { | 301 } else { |
296 duplicate_ack_counter_ = 0; | 302 duplicate_ack_counter_ = 0; |
297 } | 303 } |
298 // TODO(miu): The values "2" and "3" should be derived from configuration. | 304 // TODO(miu): The values "2" and "3" should be derived from configuration. |
299 if (duplicate_ack_counter_ >= 2 && duplicate_ack_counter_ % 3 == 2) { | 305 if (duplicate_ack_counter_ >= 2 && duplicate_ack_counter_ % 3 == 2) { |
300 VLOG(1) << SENDER_SSRC << "Received duplicate ACK for frame " | 306 VLOG(1) << SENDER_SSRC << "Received duplicate ACK for frame " |
301 << latest_acked_frame_id_; | 307 << latest_acked_frame_id_; |
| 308 TRACE_EVENT_INSTANT2( |
| 309 "cast.stream", "Duplicate ACK", TRACE_EVENT_SCOPE_THREAD, |
| 310 "ack_frame_id", cast_feedback.ack_frame_id, |
| 311 "last_sent_frame_id", last_sent_frame_id_); |
302 ResendForKickstart(); | 312 ResendForKickstart(); |
303 } | 313 } |
304 } else { | 314 } else { |
305 // Only count duplicated ACKs if there is no NACK request in between. | 315 // Only count duplicated ACKs if there is no NACK request in between. |
306 // This is to avoid aggresive resend. | 316 // This is to avoid aggresive resend. |
307 duplicate_ack_counter_ = 0; | 317 duplicate_ack_counter_ = 0; |
308 } | 318 } |
309 | 319 |
310 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 320 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); |
311 congestion_control_->AckFrame(cast_feedback.ack_frame_id, now); | 321 congestion_control_->AckFrame(cast_feedback.ack_frame_id, now); |
312 | 322 |
313 cast_environment_->Logging()->InsertFrameEvent( | 323 cast_environment_->Logging()->InsertFrameEvent( |
314 now, | 324 now, |
315 FRAME_ACK_RECEIVED, | 325 FRAME_ACK_RECEIVED, |
316 is_audio_ ? AUDIO_EVENT : VIDEO_EVENT, | 326 is_audio_ ? AUDIO_EVENT : VIDEO_EVENT, |
317 GetRecordedRtpTimestamp(cast_feedback.ack_frame_id), | 327 GetRecordedRtpTimestamp(cast_feedback.ack_frame_id), |
318 cast_feedback.ack_frame_id); | 328 cast_feedback.ack_frame_id); |
| 329 if (!duplicate_ack_counter_) { |
| 330 if (have_valid_rtt) { |
| 331 TRACE_EVENT_ASYNC_END1("cast.stream", |
| 332 is_audio_ ? "Audio Transport" : "Video Transport", |
| 333 cast_feedback.ack_frame_id, |
| 334 "RTT", current_round_trip_time_.ToInternalValue()); |
| 335 } else { |
| 336 TRACE_EVENT_ASYNC_END0("cast.stream", |
| 337 is_audio_ ? "Audio Transport" : "Video Transport", |
| 338 cast_feedback.ack_frame_id); |
| 339 } |
| 340 } |
319 | 341 |
320 const bool is_acked_out_of_order = | 342 const bool is_acked_out_of_order = |
321 static_cast<int32>(cast_feedback.ack_frame_id - | 343 static_cast<int32>(cast_feedback.ack_frame_id - |
322 latest_acked_frame_id_) < 0; | 344 latest_acked_frame_id_) < 0; |
323 VLOG(2) << SENDER_SSRC | 345 VLOG(2) << SENDER_SSRC |
324 << "Received ACK" << (is_acked_out_of_order ? " out-of-order" : "") | 346 << "Received ACK" << (is_acked_out_of_order ? " out-of-order" : "") |
325 << " for frame " << cast_feedback.ack_frame_id; | 347 << " for frame " << cast_feedback.ack_frame_id; |
326 if (!is_acked_out_of_order) { | 348 if (!is_acked_out_of_order) { |
327 // Cancel resends of acked frames. | 349 // Cancel resends of acked frames. |
328 std::vector<uint32> cancel_sending_frames; | 350 std::vector<uint32> cancel_sending_frames; |
329 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) { | 351 while (latest_acked_frame_id_ != cast_feedback.ack_frame_id) { |
330 latest_acked_frame_id_++; | 352 latest_acked_frame_id_++; |
331 cancel_sending_frames.push_back(latest_acked_frame_id_); | 353 cancel_sending_frames.push_back(latest_acked_frame_id_); |
332 } | 354 } |
333 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames); | 355 transport_sender_->CancelSendingFrames(ssrc_, cancel_sending_frames); |
334 latest_acked_frame_id_ = cast_feedback.ack_frame_id; | 356 latest_acked_frame_id_ = cast_feedback.ack_frame_id; |
| 357 } else { |
| 358 TRACE_EVENT_INSTANT2( |
| 359 "cast.stream", "ACK out of order", TRACE_EVENT_SCOPE_THREAD, |
| 360 "ack_frame_id", cast_feedback.ack_frame_id, |
| 361 "latest_acked_frame_id", latest_acked_frame_id_); |
335 } | 362 } |
336 } | 363 } |
337 | 364 |
338 bool FrameSender::ShouldDropNextFrame(base::TimeDelta frame_duration) const { | 365 bool FrameSender::ShouldDropNextFrame(base::TimeDelta frame_duration) const { |
339 // Check that accepting the next frame won't cause more frames to become | 366 // Check that accepting the next frame won't cause more frames to become |
340 // in-flight than the system's design limit. | 367 // in-flight than the system's design limit. |
341 const int count_frames_in_flight = | 368 const int count_frames_in_flight = |
342 GetUnacknowledgedFrameCount() + GetNumberOfFramesInEncoder(); | 369 GetUnacknowledgedFrameCount() + GetNumberOfFramesInEncoder(); |
343 if (count_frames_in_flight >= kMaxUnackedFrames) { | 370 if (count_frames_in_flight >= kMaxUnackedFrames) { |
344 VLOG(1) << SENDER_SSRC << "Dropping: Too many frames would be in-flight."; | 371 VLOG(1) << SENDER_SSRC << "Dropping: Too many frames would be in-flight."; |
(...skipping 28 matching lines...) Expand all Loading... |
373 VLOG(1) << SENDER_SSRC << "Dropping: In-flight duration would be too high."; | 400 VLOG(1) << SENDER_SSRC << "Dropping: In-flight duration would be too high."; |
374 return true; | 401 return true; |
375 } | 402 } |
376 | 403 |
377 // Next frame is accepted. | 404 // Next frame is accepted. |
378 return false; | 405 return false; |
379 } | 406 } |
380 | 407 |
381 } // namespace cast | 408 } // namespace cast |
382 } // namespace media | 409 } // namespace media |
OLD | NEW |