Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: media/cast/audio_receiver/audio_receiver.cc

Issue 225023010: [Cast] Refactor/clean-up VideoReceiver to match AudioReceiver as closely as possible. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « media/cast/audio_receiver/audio_receiver.h ('k') | media/cast/audio_receiver/audio_receiver_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698