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

Side by Side Diff: media/cast/receiver/frame_receiver.cc

Issue 387933005: Cast: Refactor RTCP handling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix test Created 6 years, 5 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
« no previous file with comments | « media/cast/receiver/frame_receiver.h ('k') | media/cast/sender/audio_sender.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/receiver/frame_receiver.h" 5 #include "media/cast/receiver/frame_receiver.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/big_endian.h" 9 #include "base/big_endian.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
13 #include "media/cast/cast_environment.h" 13 #include "media/cast/cast_environment.h"
14 #include "media/cast/net/rtcp/rtcp_receiver.h"
14 15
15 namespace { 16 namespace {
16 const int kMinSchedulingDelayMs = 1; 17 const int kMinSchedulingDelayMs = 1;
17 } // namespace 18 } // namespace
18 19
19 namespace media { 20 namespace media {
20 namespace cast { 21 namespace cast {
21 22
22 FrameReceiver::FrameReceiver( 23 FrameReceiver::FrameReceiver(
23 const scoped_refptr<CastEnvironment>& cast_environment, 24 const scoped_refptr<CastEnvironment>& cast_environment,
24 const FrameReceiverConfig& config, 25 const FrameReceiverConfig& config,
25 EventMediaType event_media_type, 26 EventMediaType event_media_type,
26 PacedPacketSender* const packet_sender) 27 PacedPacketSender* const packet_sender)
27 : cast_environment_(cast_environment), 28 : cast_environment_(cast_environment),
28 packet_parser_(config.incoming_ssrc, config.rtp_payload_type), 29 packet_parser_(config.incoming_ssrc, config.rtp_payload_type),
29 stats_(cast_environment->Clock()), 30 stats_(cast_environment->Clock()),
30 event_media_type_(event_media_type), 31 event_media_type_(event_media_type),
31 event_subscriber_(kReceiverRtcpEventHistorySize, event_media_type), 32 event_subscriber_(kReceiverRtcpEventHistorySize, event_media_type),
32 rtp_timebase_(config.frequency), 33 rtp_timebase_(config.frequency),
33 target_playout_delay_( 34 target_playout_delay_(
34 base::TimeDelta::FromMilliseconds(config.rtp_max_delay_ms)), 35 base::TimeDelta::FromMilliseconds(config.rtp_max_delay_ms)),
35 expected_frame_duration_( 36 expected_frame_duration_(
36 base::TimeDelta::FromSeconds(1) / config.max_frame_rate), 37 base::TimeDelta::FromSeconds(1) / config.max_frame_rate),
37 reports_are_scheduled_(false), 38 reports_are_scheduled_(false),
38 framer_(cast_environment->Clock(), 39 framer_(cast_environment->Clock(),
39 this, 40 this,
40 config.incoming_ssrc, 41 config.incoming_ssrc,
41 true, 42 true,
42 config.rtp_max_delay_ms * config.max_frame_rate / 1000), 43 config.rtp_max_delay_ms * config.max_frame_rate / 1000),
43 rtcp_(cast_environment_, 44 rtcp_(RtcpCastMessageCallback(),
44 NULL, 45 RtcpRttCallback(),
45 NULL, 46 RtcpLogMessageCallback(),
47 cast_environment_->Clock(),
46 packet_sender, 48 packet_sender,
47 &stats_,
48 config.rtcp_mode,
49 base::TimeDelta::FromMilliseconds(config.rtcp_interval),
50 config.feedback_ssrc, 49 config.feedback_ssrc,
51 config.incoming_ssrc, 50 config.incoming_ssrc,
52 config.rtcp_c_name, 51 config.rtcp_c_name),
53 event_media_type),
54 is_waiting_for_consecutive_frame_(false), 52 is_waiting_for_consecutive_frame_(false),
55 lip_sync_drift_(ClockDriftSmoother::GetDefaultTimeConstant()), 53 lip_sync_drift_(ClockDriftSmoother::GetDefaultTimeConstant()),
54 rtcp_interval_(base::TimeDelta::FromMilliseconds(config.rtcp_interval)),
56 weak_factory_(this) { 55 weak_factory_(this) {
57 DCHECK_GT(config.rtp_max_delay_ms, 0); 56 DCHECK_GT(config.rtp_max_delay_ms, 0);
58 DCHECK_GT(config.max_frame_rate, 0); 57 DCHECK_GT(config.max_frame_rate, 0);
59 decryptor_.Initialize(config.aes_key, config.aes_iv_mask); 58 decryptor_.Initialize(config.aes_key, config.aes_iv_mask);
60 rtcp_.SetTargetDelay(target_playout_delay_);
61 cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber_); 59 cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber_);
62 memset(frame_id_to_rtp_timestamp_, 0, sizeof(frame_id_to_rtp_timestamp_)); 60 memset(frame_id_to_rtp_timestamp_, 0, sizeof(frame_id_to_rtp_timestamp_));
63 } 61 }
64 62
65 FrameReceiver::~FrameReceiver() { 63 FrameReceiver::~FrameReceiver() {
66 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 64 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
67 cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber_); 65 cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber_);
68 } 66 }
69 67
70 void FrameReceiver::RequestEncodedFrame( 68 void FrameReceiver::RequestEncodedFrame(
71 const ReceiveEncodedFrameCallback& callback) { 69 const ReceiveEncodedFrameCallback& callback) {
72 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 70 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
73 frame_request_queue_.push_back(callback); 71 frame_request_queue_.push_back(callback);
74 EmitAvailableEncodedFrames(); 72 EmitAvailableEncodedFrames();
75 } 73 }
76 74
77 bool FrameReceiver::ProcessPacket(scoped_ptr<Packet> packet) { 75 bool FrameReceiver::ProcessPacket(scoped_ptr<Packet> packet) {
78 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 76 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
79 77
80 if (Rtcp::IsRtcpPacket(&packet->front(), packet->size())) { 78 if (RtcpReceiver::IsRtcpPacket(&packet->front(), packet->size())) {
81 rtcp_.IncomingRtcpPacket(&packet->front(), packet->size()); 79 rtcp_.IncomingRtcpPacket(&packet->front(), packet->size());
82 } else { 80 } else {
83 RtpCastHeader rtp_header; 81 RtpCastHeader rtp_header;
84 const uint8* payload_data; 82 const uint8* payload_data;
85 size_t payload_size; 83 size_t payload_size;
86 if (!packet_parser_.ParsePacket(&packet->front(), 84 if (!packet_parser_.ParsePacket(&packet->front(),
87 packet->size(), 85 packet->size(),
88 &rtp_header, 86 &rtp_header,
89 &payload_data, 87 &payload_data,
90 &payload_size)) { 88 &payload_size)) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 // more frames to satisfy enqueued requests. 167 // more frames to satisfy enqueued requests.
170 if (complete) 168 if (complete)
171 EmitAvailableEncodedFrames(); 169 EmitAvailableEncodedFrames();
172 } 170 }
173 171
174 void FrameReceiver::CastFeedback(const RtcpCastMessage& cast_message) { 172 void FrameReceiver::CastFeedback(const RtcpCastMessage& cast_message) {
175 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 173 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
176 174
177 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 175 base::TimeTicks now = cast_environment_->Clock()->NowTicks();
178 RtpTimestamp rtp_timestamp = 176 RtpTimestamp rtp_timestamp =
179 frame_id_to_rtp_timestamp_[cast_message.ack_frame_id_ & 0xff]; 177 frame_id_to_rtp_timestamp_[cast_message.ack_frame_id & 0xff];
180 cast_environment_->Logging()->InsertFrameEvent( 178 cast_environment_->Logging()->InsertFrameEvent(
181 now, FRAME_ACK_SENT, event_media_type_, 179 now, FRAME_ACK_SENT, event_media_type_,
182 rtp_timestamp, cast_message.ack_frame_id_); 180 rtp_timestamp, cast_message.ack_frame_id);
183 181
184 ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events; 182 ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
185 event_subscriber_.GetRtcpEventsAndReset(&rtcp_events); 183 event_subscriber_.GetRtcpEventsAndReset(&rtcp_events);
186 rtcp_.SendRtcpFromRtpReceiver(&cast_message, &rtcp_events); 184 rtcp_.SendRtcpFromRtpReceiver(&cast_message, target_playout_delay_,
185 &rtcp_events, NULL);
187 } 186 }
188 187
189 void FrameReceiver::EmitAvailableEncodedFrames() { 188 void FrameReceiver::EmitAvailableEncodedFrames() {
190 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 189 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
191 190
192 while (!frame_request_queue_.empty()) { 191 while (!frame_request_queue_.empty()) {
193 // Attempt to peek at the next completed frame from the |framer_|. 192 // Attempt to peek at the next completed frame from the |framer_|.
194 // TODO(miu): We should only be peeking at the metadata, and not copying the 193 // TODO(miu): We should only be peeking at the metadata, and not copying the
195 // payload yet! Or, at least, peek using a StringPiece instead of a copy. 194 // payload yet! Or, at least, peek using a StringPiece instead of a copy.
196 scoped_ptr<EncodedFrame> encoded_frame( 195 scoped_ptr<EncodedFrame> encoded_frame(
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 } 294 }
296 295
297 void FrameReceiver::SendNextCastMessage() { 296 void FrameReceiver::SendNextCastMessage() {
298 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 297 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
299 framer_.SendCastMessage(); // Will only send a message if it is time. 298 framer_.SendCastMessage(); // Will only send a message if it is time.
300 ScheduleNextCastMessage(); 299 ScheduleNextCastMessage();
301 } 300 }
302 301
303 void FrameReceiver::ScheduleNextRtcpReport() { 302 void FrameReceiver::ScheduleNextRtcpReport() {
304 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 303 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
305 base::TimeDelta time_to_next = rtcp_.TimeToSendNextRtcpReport() - 304 base::TimeDelta time_to_next = rtcp_interval_;
306 cast_environment_->Clock()->NowTicks();
307
308 time_to_next = std::max( 305 time_to_next = std::max(
309 time_to_next, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs)); 306 time_to_next, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs));
310 307
311 cast_environment_->PostDelayedTask( 308 cast_environment_->PostDelayedTask(
312 CastEnvironment::MAIN, 309 CastEnvironment::MAIN,
313 FROM_HERE, 310 FROM_HERE,
314 base::Bind(&FrameReceiver::SendNextRtcpReport, 311 base::Bind(&FrameReceiver::SendNextRtcpReport,
315 weak_factory_.GetWeakPtr()), 312 weak_factory_.GetWeakPtr()),
316 time_to_next); 313 time_to_next);
317 } 314 }
318 315
319 void FrameReceiver::SendNextRtcpReport() { 316 void FrameReceiver::SendNextRtcpReport() {
320 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 317 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
321 rtcp_.SendRtcpFromRtpReceiver(NULL, NULL); 318 rtcp_.SendRtcpFromRtpReceiver(NULL, base::TimeDelta(), NULL, &stats_);
322 ScheduleNextRtcpReport(); 319 ScheduleNextRtcpReport();
323 } 320 }
324 321
325 } // namespace cast 322 } // namespace cast
326 } // namespace media 323 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/receiver/frame_receiver.h ('k') | media/cast/sender/audio_sender.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698