| 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/audio_receiver/audio_receiver.h" | 5 #include "media/cast/audio_receiver/audio_receiver.h" | 
| 6 | 6 | 
|  | 7 #include <algorithm> | 
|  | 8 | 
| 7 #include "base/bind.h" | 9 #include "base/bind.h" | 
| 8 #include "base/logging.h" | 10 #include "base/logging.h" | 
| 9 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" | 
| 10 #include "media/cast/audio_receiver/audio_decoder.h" | 12 #include "media/cast/audio_receiver/audio_decoder.h" | 
| 11 #include "media/cast/transport/cast_transport_defines.h" | 13 #include "media/cast/transport/cast_transport_defines.h" | 
| 12 | 14 | 
| 13 namespace { | 15 namespace { | 
|  | 16 const int kMinSchedulingDelayMs = 1; | 
|  | 17 // TODO(miu): This should go in AudioReceiverConfig. | 
| 14 const int kTypicalAudioFrameDurationMs = 10; | 18 const int kTypicalAudioFrameDurationMs = 10; | 
| 15 const int kMinSchedulingDelayMs = 1; |  | 
| 16 }  // namespace | 19 }  // namespace | 
| 17 | 20 | 
| 18 namespace media { | 21 namespace media { | 
| 19 namespace cast { | 22 namespace cast { | 
| 20 | 23 | 
| 21 AudioReceiver::AudioReceiver(scoped_refptr<CastEnvironment> cast_environment, | 24 AudioReceiver::AudioReceiver(scoped_refptr<CastEnvironment> cast_environment, | 
| 22                              const AudioReceiverConfig& audio_config, | 25                              const AudioReceiverConfig& audio_config, | 
| 23                              transport::PacedPacketSender* const packet_sender) | 26                              transport::PacedPacketSender* const packet_sender) | 
| 24     : RtpReceiver(cast_environment->Clock(), &audio_config, NULL), | 27     : RtpReceiver(cast_environment->Clock(), &audio_config, NULL), | 
| 25       cast_environment_(cast_environment), | 28       cast_environment_(cast_environment), | 
| 26       event_subscriber_(kReceiverRtcpEventHistorySize, | 29       event_subscriber_(kReceiverRtcpEventHistorySize, | 
| 27                         ReceiverRtcpEventSubscriber::kAudioEventSubscriber), | 30                         ReceiverRtcpEventSubscriber::kAudioEventSubscriber), | 
| 28       codec_(audio_config.codec), | 31       codec_(audio_config.codec), | 
| 29       frequency_(audio_config.frequency), | 32       frequency_(audio_config.frequency), | 
|  | 33       target_delay_delta_( | 
|  | 34           base::TimeDelta::FromMilliseconds(audio_config.rtp_max_delay_ms)), | 
| 30       framer_(cast_environment->Clock(), | 35       framer_(cast_environment->Clock(), | 
| 31              this, | 36               this, | 
| 32              audio_config.incoming_ssrc, | 37               audio_config.incoming_ssrc, | 
| 33              true, | 38               true, | 
| 34              0), | 39               audio_config.rtp_max_delay_ms / kTypicalAudioFrameDurationMs), | 
| 35       rtcp_(cast_environment, | 40       rtcp_(cast_environment, | 
| 36             NULL, | 41             NULL, | 
| 37             NULL, | 42             NULL, | 
| 38             packet_sender, | 43             packet_sender, | 
| 39             GetStatistics(), | 44             GetStatistics(), | 
| 40             audio_config.rtcp_mode, | 45             audio_config.rtcp_mode, | 
| 41             base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval), | 46             base::TimeDelta::FromMilliseconds(audio_config.rtcp_interval), | 
| 42             audio_config.feedback_ssrc, | 47             audio_config.feedback_ssrc, | 
| 43             audio_config.incoming_ssrc, | 48             audio_config.incoming_ssrc, | 
| 44             audio_config.rtcp_c_name), | 49             audio_config.rtcp_c_name), | 
| 45       is_waiting_for_consecutive_frame_(false), | 50       is_waiting_for_consecutive_frame_(false), | 
| 46       weak_factory_(this) { | 51       weak_factory_(this) { | 
| 47   target_delay_delta_ = |  | 
| 48       base::TimeDelta::FromMilliseconds(audio_config.rtp_max_delay_ms); |  | 
| 49   if (!audio_config.use_external_decoder) | 52   if (!audio_config.use_external_decoder) | 
| 50     audio_decoder_.reset(new AudioDecoder(cast_environment, audio_config)); | 53     audio_decoder_.reset(new AudioDecoder(cast_environment, audio_config)); | 
| 51   decryptor_.Initialize(audio_config.aes_key, audio_config.aes_iv_mask); | 54   decryptor_.Initialize(audio_config.aes_key, audio_config.aes_iv_mask); | 
| 52   rtcp_.SetTargetDelay(target_delay_delta_); | 55   rtcp_.SetTargetDelay(target_delay_delta_); | 
| 53   cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber_); | 56   cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber_); | 
| 54   memset(frame_id_to_rtp_timestamp_, 0, sizeof(frame_id_to_rtp_timestamp_)); | 57   memset(frame_id_to_rtp_timestamp_, 0, sizeof(frame_id_to_rtp_timestamp_)); | 
| 55 } | 58 } | 
| 56 | 59 | 
| 57 AudioReceiver::~AudioReceiver() { | 60 AudioReceiver::~AudioReceiver() { | 
| 58   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 61   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 74   ScheduleNextRtcpReport(); | 77   ScheduleNextRtcpReport(); | 
| 75   ScheduleNextCastMessage(); | 78   ScheduleNextCastMessage(); | 
| 76 } | 79 } | 
| 77 | 80 | 
| 78 void AudioReceiver::OnReceivedPayloadData(const uint8* payload_data, | 81 void AudioReceiver::OnReceivedPayloadData(const uint8* payload_data, | 
| 79                                           size_t payload_size, | 82                                           size_t payload_size, | 
| 80                                           const RtpCastHeader& rtp_header) { | 83                                           const RtpCastHeader& rtp_header) { | 
| 81   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 84   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 
| 82   base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 85   base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 
| 83 | 86 | 
| 84   frame_id_to_rtp_timestamp_[rtp_header.frame_id & 0xff] = |  | 
| 85       rtp_header.webrtc.header.timestamp; |  | 
| 86   cast_environment_->Logging()->InsertPacketEvent( |  | 
| 87       now, kAudioPacketReceived, rtp_header.webrtc.header.timestamp, |  | 
| 88       rtp_header.frame_id, rtp_header.packet_id, rtp_header.max_packet_id, |  | 
| 89       payload_size); |  | 
| 90 |  | 
| 91   // TODO(pwestin): update this as video to refresh over time. | 87   // TODO(pwestin): update this as video to refresh over time. | 
| 92   if (time_first_incoming_packet_.is_null()) { | 88   if (time_first_incoming_packet_.is_null()) { | 
| 93     InitializeTimers(); | 89     InitializeTimers(); | 
| 94     first_incoming_rtp_timestamp_ = rtp_header.webrtc.header.timestamp; | 90     first_incoming_rtp_timestamp_ = rtp_header.webrtc.header.timestamp; | 
| 95     time_first_incoming_packet_ = now; | 91     time_first_incoming_packet_ = now; | 
| 96   } | 92   } | 
| 97 | 93 | 
|  | 94   frame_id_to_rtp_timestamp_[rtp_header.frame_id & 0xff] = | 
|  | 95       rtp_header.webrtc.header.timestamp; | 
|  | 96   cast_environment_->Logging()->InsertPacketEvent( | 
|  | 97       now, kAudioPacketReceived, rtp_header.webrtc.header.timestamp, | 
|  | 98       rtp_header.frame_id, rtp_header.packet_id, rtp_header.max_packet_id, | 
|  | 99       payload_size); | 
|  | 100 | 
| 98   bool duplicate = false; | 101   bool duplicate = false; | 
| 99   const bool complete = | 102   const bool complete = | 
| 100       framer_.InsertPacket(payload_data, payload_size, rtp_header, &duplicate); | 103       framer_.InsertPacket(payload_data, payload_size, rtp_header, &duplicate); | 
| 101   if (duplicate) { | 104   if (duplicate) { | 
| 102     cast_environment_->Logging()->InsertPacketEvent( | 105     cast_environment_->Logging()->InsertPacketEvent( | 
| 103         now, kDuplicateAudioPacketReceived, rtp_header.webrtc.header.timestamp, | 106         now, | 
| 104         rtp_header.frame_id, rtp_header.packet_id, rtp_header.max_packet_id, | 107         kDuplicateAudioPacketReceived, | 
|  | 108         rtp_header.webrtc.header.timestamp, | 
|  | 109         rtp_header.frame_id, | 
|  | 110         rtp_header.packet_id, | 
|  | 111         rtp_header.max_packet_id, | 
| 105         payload_size); | 112         payload_size); | 
| 106     // Duplicate packets are ignored. | 113     // Duplicate packets are ignored. | 
| 107     return; | 114     return; | 
| 108   } | 115   } | 
| 109   if (!complete) | 116   if (!complete) | 
| 110     return; | 117     return; | 
| 111 | 118 | 
| 112   EmitAvailableEncodedFrames(); | 119   EmitAvailableEncodedFrames(); | 
| 113 } | 120 } | 
| 114 | 121 | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 190     } | 197     } | 
| 191 | 198 | 
| 192     // If |framer_| has a frame ready that is out of sequence, examine the | 199     // If |framer_| has a frame ready that is out of sequence, examine the | 
| 193     // playout time to determine whether it's acceptable to continue, thereby | 200     // playout time to determine whether it's acceptable to continue, thereby | 
| 194     // skipping one or more frames.  Skip if the missing frame wouldn't complete | 201     // skipping one or more frames.  Skip if the missing frame wouldn't complete | 
| 195     // playing before the start of playback of the available frame. | 202     // playing before the start of playback of the available frame. | 
| 196     const base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 203     const base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 
| 197     const base::TimeTicks playout_time = | 204     const base::TimeTicks playout_time = | 
| 198         GetPlayoutTime(now, encoded_frame->rtp_timestamp); | 205         GetPlayoutTime(now, encoded_frame->rtp_timestamp); | 
| 199     if (!is_consecutively_next_frame) { | 206     if (!is_consecutively_next_frame) { | 
|  | 207       // TODO(miu): Also account for expected decode time here? | 
| 200       const base::TimeTicks earliest_possible_end_time_of_missing_frame = | 208       const base::TimeTicks earliest_possible_end_time_of_missing_frame = | 
| 201           now + base::TimeDelta::FromMilliseconds(kTypicalAudioFrameDurationMs); | 209           now + base::TimeDelta::FromMilliseconds(kTypicalAudioFrameDurationMs); | 
| 202       if (earliest_possible_end_time_of_missing_frame < playout_time) { | 210       if (earliest_possible_end_time_of_missing_frame < playout_time) { | 
| 203         VLOG(1) << "Wait for next consecutive frame instead of skipping."; | 211         VLOG(1) << "Wait for next consecutive frame instead of skipping."; | 
| 204         if (!is_waiting_for_consecutive_frame_) { | 212         if (!is_waiting_for_consecutive_frame_) { | 
| 205           is_waiting_for_consecutive_frame_ = true; | 213           is_waiting_for_consecutive_frame_ = true; | 
| 206           cast_environment_->PostDelayedTask( | 214           cast_environment_->PostDelayedTask( | 
| 207               CastEnvironment::MAIN, | 215               CastEnvironment::MAIN, | 
| 208               FROM_HERE, | 216               FROM_HERE, | 
| 209               base::Bind(&AudioReceiver::EmitAvailableEncodedFramesAfterWaiting, | 217               base::Bind(&AudioReceiver::EmitAvailableEncodedFramesAfterWaiting, | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 242 | 250 | 
| 243 void AudioReceiver::EmitAvailableEncodedFramesAfterWaiting() { | 251 void AudioReceiver::EmitAvailableEncodedFramesAfterWaiting() { | 
| 244   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 252   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 
| 245   DCHECK(is_waiting_for_consecutive_frame_); | 253   DCHECK(is_waiting_for_consecutive_frame_); | 
| 246   is_waiting_for_consecutive_frame_ = false; | 254   is_waiting_for_consecutive_frame_ = false; | 
| 247   EmitAvailableEncodedFrames(); | 255   EmitAvailableEncodedFrames(); | 
| 248 } | 256 } | 
| 249 | 257 | 
| 250 void AudioReceiver::IncomingPacket(scoped_ptr<Packet> packet) { | 258 void AudioReceiver::IncomingPacket(scoped_ptr<Packet> packet) { | 
| 251   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 259   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 
| 252   bool rtcp_packet = Rtcp::IsRtcpPacket(&packet->front(), packet->size()); | 260   if (Rtcp::IsRtcpPacket(&packet->front(), packet->size())) { | 
| 253   if (!rtcp_packet) { | 261     rtcp_.IncomingRtcpPacket(&packet->front(), packet->size()); | 
|  | 262   } else { | 
| 254     ReceivedPacket(&packet->front(), packet->size()); | 263     ReceivedPacket(&packet->front(), packet->size()); | 
| 255   } else { |  | 
| 256     rtcp_.IncomingRtcpPacket(&packet->front(), packet->size()); |  | 
| 257   } | 264   } | 
| 258 } | 265 } | 
| 259 | 266 | 
| 260 void AudioReceiver::SetTargetDelay(base::TimeDelta target_delay) { | 267 void AudioReceiver::SetTargetDelay(base::TimeDelta target_delay) { | 
| 261   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 268   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 
| 262   target_delay_delta_ = target_delay; | 269   target_delay_delta_ = target_delay; | 
| 263   rtcp_.SetTargetDelay(target_delay_delta_); | 270   rtcp_.SetTargetDelay(target_delay_delta_); | 
| 264 } | 271 } | 
| 265 | 272 | 
| 266 void AudioReceiver::CastFeedback(const RtcpCastMessage& cast_message) { | 273 void AudioReceiver::CastFeedback(const RtcpCastMessage& cast_message) { | 
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 336 | 343 | 
| 337 void AudioReceiver::ScheduleNextRtcpReport() { | 344 void AudioReceiver::ScheduleNextRtcpReport() { | 
| 338   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 345   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 
| 339   base::TimeDelta time_to_send = rtcp_.TimeToSendNextRtcpReport() - | 346   base::TimeDelta time_to_send = rtcp_.TimeToSendNextRtcpReport() - | 
| 340                                  cast_environment_->Clock()->NowTicks(); | 347                                  cast_environment_->Clock()->NowTicks(); | 
| 341 | 348 | 
| 342   time_to_send = std::max( | 349   time_to_send = std::max( | 
| 343       time_to_send, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); | 350       time_to_send, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); | 
| 344 | 351 | 
| 345   cast_environment_->PostDelayedTask( | 352   cast_environment_->PostDelayedTask( | 
| 346       CastEnvironment::MAIN, FROM_HERE, | 353       CastEnvironment::MAIN, | 
|  | 354       FROM_HERE, | 
| 347       base::Bind(&AudioReceiver::SendNextRtcpReport, | 355       base::Bind(&AudioReceiver::SendNextRtcpReport, | 
| 348                  weak_factory_.GetWeakPtr()), | 356                  weak_factory_.GetWeakPtr()), | 
| 349       time_to_send); | 357       time_to_send); | 
| 350 } | 358 } | 
| 351 | 359 | 
| 352 void AudioReceiver::SendNextRtcpReport() { | 360 void AudioReceiver::SendNextRtcpReport() { | 
| 353   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 361   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 
| 354   // TODO(pwestin): add logging. | 362   // TODO(pwestin): add logging. | 
| 355   rtcp_.SendRtcpFromRtpReceiver(NULL, NULL); | 363   rtcp_.SendRtcpFromRtpReceiver(NULL, NULL); | 
| 356   ScheduleNextRtcpReport(); | 364   ScheduleNextRtcpReport(); | 
| 357 } | 365 } | 
| 358 | 366 | 
| 359 // Cast messages should be sent within a maximum interval. Schedule a call | 367 // Cast messages should be sent within a maximum interval. Schedule a call | 
| 360 // if not triggered elsewhere, e.g. by the cast message_builder. | 368 // if not triggered elsewhere, e.g. by the cast message_builder. | 
| 361 void AudioReceiver::ScheduleNextCastMessage() { | 369 void AudioReceiver::ScheduleNextCastMessage() { | 
| 362   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 370   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 
| 363   base::TimeTicks send_time; | 371   base::TimeTicks send_time; | 
| 364   framer_.TimeToSendNextCastMessage(&send_time); | 372   framer_.TimeToSendNextCastMessage(&send_time); | 
| 365   base::TimeDelta time_to_send = | 373   base::TimeDelta time_to_send = | 
| 366       send_time - cast_environment_->Clock()->NowTicks(); | 374       send_time - cast_environment_->Clock()->NowTicks(); | 
| 367   time_to_send = std::max( | 375   time_to_send = std::max( | 
| 368       time_to_send, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); | 376       time_to_send, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); | 
| 369   cast_environment_->PostDelayedTask( | 377   cast_environment_->PostDelayedTask( | 
| 370       CastEnvironment::MAIN, FROM_HERE, | 378       CastEnvironment::MAIN, | 
|  | 379       FROM_HERE, | 
| 371       base::Bind(&AudioReceiver::SendNextCastMessage, | 380       base::Bind(&AudioReceiver::SendNextCastMessage, | 
| 372                  weak_factory_.GetWeakPtr()), | 381                  weak_factory_.GetWeakPtr()), | 
| 373       time_to_send); | 382       time_to_send); | 
| 374 } | 383 } | 
| 375 | 384 | 
| 376 void AudioReceiver::SendNextCastMessage() { | 385 void AudioReceiver::SendNextCastMessage() { | 
| 377   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 386   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 
| 378   // Will only send a message if it is time. | 387   framer_.SendCastMessage();  // Will only send a message if it is time. | 
| 379   framer_.SendCastMessage(); |  | 
| 380   ScheduleNextCastMessage(); | 388   ScheduleNextCastMessage(); | 
| 381 } | 389 } | 
| 382 | 390 | 
| 383 }  // namespace cast | 391 }  // namespace cast | 
| 384 }  // namespace media | 392 }  // namespace media | 
| OLD | NEW | 
|---|