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

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

Powered by Google App Engine
This is Rietveld 408576698