Remove implicit conversions from scoped_refptr to T* in media/
[chromium-blink-merge.git] / media / cast / receiver / cast_receiver_impl.cc
blob6c588b73fe6f69ea31befbc6504e94896239528a
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
3 // found in the LICENSE file.
5 #include "media/cast/receiver/cast_receiver_impl.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/debug/trace_event.h"
11 #include "base/logging.h"
12 #include "base/message_loop/message_loop.h"
13 #include "media/cast/receiver/audio_decoder.h"
14 #include "media/cast/receiver/video_decoder.h"
16 namespace media {
17 namespace cast {
19 scoped_ptr<CastReceiver> CastReceiver::Create(
20 scoped_refptr<CastEnvironment> cast_environment,
21 const FrameReceiverConfig& audio_config,
22 const FrameReceiverConfig& video_config,
23 PacketSender* const packet_sender) {
24 return scoped_ptr<CastReceiver>(new CastReceiverImpl(
25 cast_environment, audio_config, video_config, packet_sender));
28 CastReceiverImpl::CastReceiverImpl(
29 scoped_refptr<CastEnvironment> cast_environment,
30 const FrameReceiverConfig& audio_config,
31 const FrameReceiverConfig& video_config,
32 PacketSender* const packet_sender)
33 : cast_environment_(cast_environment),
34 pacer_(cast_environment->Clock(),
35 cast_environment->Logging(),
36 packet_sender,
37 cast_environment->GetTaskRunner(CastEnvironment::MAIN)),
38 audio_receiver_(cast_environment, audio_config, AUDIO_EVENT, &pacer_),
39 video_receiver_(cast_environment, video_config, VIDEO_EVENT, &pacer_),
40 ssrc_of_audio_sender_(audio_config.incoming_ssrc),
41 ssrc_of_video_sender_(video_config.incoming_ssrc),
42 num_audio_channels_(audio_config.channels),
43 audio_sampling_rate_(audio_config.frequency),
44 audio_codec_(audio_config.codec),
45 video_codec_(video_config.codec) {}
47 CastReceiverImpl::~CastReceiverImpl() {}
49 void CastReceiverImpl::DispatchReceivedPacket(scoped_ptr<Packet> packet) {
50 const uint8_t* const data = &packet->front();
51 const size_t length = packet->size();
53 uint32 ssrc_of_sender;
54 if (Rtcp::IsRtcpPacket(data, length)) {
55 ssrc_of_sender = Rtcp::GetSsrcOfSender(data, length);
56 } else if (!FrameReceiver::ParseSenderSsrc(data, length, &ssrc_of_sender)) {
57 VLOG(1) << "Invalid RTP packet.";
58 return;
61 base::WeakPtr<FrameReceiver> target;
62 if (ssrc_of_sender == ssrc_of_video_sender_) {
63 target = video_receiver_.AsWeakPtr();
64 } else if (ssrc_of_sender == ssrc_of_audio_sender_) {
65 target = audio_receiver_.AsWeakPtr();
66 } else {
67 VLOG(1) << "Dropping packet with a non matching sender SSRC: "
68 << ssrc_of_sender;
69 return;
71 cast_environment_->PostTask(
72 CastEnvironment::MAIN,
73 FROM_HERE,
74 base::Bind(base::IgnoreResult(&FrameReceiver::ProcessPacket),
75 target,
76 base::Passed(&packet)));
79 PacketReceiverCallback CastReceiverImpl::packet_receiver() {
80 return base::Bind(&CastReceiverImpl::DispatchReceivedPacket,
81 // TODO(miu): This code structure is dangerous, since the
82 // callback could be stored and then invoked after
83 // destruction of |this|.
84 base::Unretained(this));
87 void CastReceiverImpl::RequestDecodedAudioFrame(
88 const AudioFrameDecodedCallback& callback) {
89 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
90 DCHECK(!callback.is_null());
91 audio_receiver_.RequestEncodedFrame(base::Bind(
92 &CastReceiverImpl::DecodeEncodedAudioFrame,
93 // Note: Use of Unretained is safe since this Closure is guaranteed to be
94 // invoked or discarded by |audio_receiver_| before destruction of |this|.
95 base::Unretained(this),
96 callback));
99 void CastReceiverImpl::RequestEncodedAudioFrame(
100 const ReceiveEncodedFrameCallback& callback) {
101 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
102 audio_receiver_.RequestEncodedFrame(callback);
105 void CastReceiverImpl::RequestDecodedVideoFrame(
106 const VideoFrameDecodedCallback& callback) {
107 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
108 DCHECK(!callback.is_null());
109 video_receiver_.RequestEncodedFrame(base::Bind(
110 &CastReceiverImpl::DecodeEncodedVideoFrame,
111 // Note: Use of Unretained is safe since this Closure is guaranteed to be
112 // invoked or discarded by |video_receiver_| before destruction of |this|.
113 base::Unretained(this),
114 callback));
117 void CastReceiverImpl::RequestEncodedVideoFrame(
118 const ReceiveEncodedFrameCallback& callback) {
119 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
120 video_receiver_.RequestEncodedFrame(callback);
123 void CastReceiverImpl::DecodeEncodedAudioFrame(
124 const AudioFrameDecodedCallback& callback,
125 scoped_ptr<EncodedFrame> encoded_frame) {
126 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
127 if (!encoded_frame) {
128 callback.Run(make_scoped_ptr<AudioBus>(NULL), base::TimeTicks(), false);
129 return;
132 if (!audio_decoder_) {
133 audio_decoder_.reset(new AudioDecoder(cast_environment_,
134 num_audio_channels_,
135 audio_sampling_rate_,
136 audio_codec_));
138 const uint32 frame_id = encoded_frame->frame_id;
139 const uint32 rtp_timestamp = encoded_frame->rtp_timestamp;
140 const base::TimeTicks playout_time = encoded_frame->reference_time;
141 audio_decoder_->DecodeFrame(
142 encoded_frame.Pass(),
143 base::Bind(&CastReceiverImpl::EmitDecodedAudioFrame,
144 cast_environment_,
145 callback,
146 frame_id,
147 rtp_timestamp,
148 playout_time));
151 void CastReceiverImpl::DecodeEncodedVideoFrame(
152 const VideoFrameDecodedCallback& callback,
153 scoped_ptr<EncodedFrame> encoded_frame) {
154 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
155 if (!encoded_frame) {
156 callback.Run(
157 make_scoped_refptr<VideoFrame>(NULL), base::TimeTicks(), false);
158 return;
161 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc
162 TRACE_EVENT_INSTANT2(
163 "cast_perf_test", "PullEncodedVideoFrame",
164 TRACE_EVENT_SCOPE_THREAD,
165 "rtp_timestamp", encoded_frame->rtp_timestamp,
166 "render_time", encoded_frame->reference_time.ToInternalValue());
168 if (!video_decoder_)
169 video_decoder_.reset(new VideoDecoder(cast_environment_, video_codec_));
170 const uint32 frame_id = encoded_frame->frame_id;
171 const uint32 rtp_timestamp = encoded_frame->rtp_timestamp;
172 const base::TimeTicks playout_time = encoded_frame->reference_time;
173 video_decoder_->DecodeFrame(
174 encoded_frame.Pass(),
175 base::Bind(&CastReceiverImpl::EmitDecodedVideoFrame,
176 cast_environment_,
177 callback,
178 frame_id,
179 rtp_timestamp,
180 playout_time));
183 // static
184 void CastReceiverImpl::EmitDecodedAudioFrame(
185 const scoped_refptr<CastEnvironment>& cast_environment,
186 const AudioFrameDecodedCallback& callback,
187 uint32 frame_id,
188 uint32 rtp_timestamp,
189 const base::TimeTicks& playout_time,
190 scoped_ptr<AudioBus> audio_bus,
191 bool is_continuous) {
192 DCHECK(cast_environment->CurrentlyOn(CastEnvironment::MAIN));
193 if (audio_bus.get()) {
194 const base::TimeTicks now = cast_environment->Clock()->NowTicks();
195 cast_environment->Logging()->InsertFrameEvent(
196 now, FRAME_DECODED, AUDIO_EVENT, rtp_timestamp, frame_id);
197 cast_environment->Logging()->InsertFrameEventWithDelay(
198 now, FRAME_PLAYOUT, AUDIO_EVENT, rtp_timestamp, frame_id,
199 playout_time - now);
201 callback.Run(audio_bus.Pass(), playout_time, is_continuous);
204 // static
205 void CastReceiverImpl::EmitDecodedVideoFrame(
206 const scoped_refptr<CastEnvironment>& cast_environment,
207 const VideoFrameDecodedCallback& callback,
208 uint32 frame_id,
209 uint32 rtp_timestamp,
210 const base::TimeTicks& playout_time,
211 const scoped_refptr<VideoFrame>& video_frame,
212 bool is_continuous) {
213 DCHECK(cast_environment->CurrentlyOn(CastEnvironment::MAIN));
214 if (video_frame.get()) {
215 const base::TimeTicks now = cast_environment->Clock()->NowTicks();
216 cast_environment->Logging()->InsertFrameEvent(
217 now, FRAME_DECODED, VIDEO_EVENT, rtp_timestamp, frame_id);
218 cast_environment->Logging()->InsertFrameEventWithDelay(
219 now, FRAME_PLAYOUT, VIDEO_EVENT, rtp_timestamp, frame_id,
220 playout_time - now);
222 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc
223 TRACE_EVENT_INSTANT1(
224 "cast_perf_test", "FrameDecoded",
225 TRACE_EVENT_SCOPE_THREAD,
226 "rtp_timestamp", rtp_timestamp);
228 callback.Run(video_frame, playout_time, is_continuous);
231 } // namespace cast
232 } // namespace media