| 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 | 
|---|