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> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 GetEncodedAudioFrame(base::Bind( | 107 GetEncodedAudioFrame(base::Bind( |
108 &AudioReceiver::DecodeEncodedAudioFrame, | 108 &AudioReceiver::DecodeEncodedAudioFrame, |
109 // Note: Use of Unretained is safe since this Closure is guaranteed to be | 109 // Note: Use of Unretained is safe since this Closure is guaranteed to be |
110 // invoked before destruction of |this|. | 110 // invoked before destruction of |this|. |
111 base::Unretained(this), | 111 base::Unretained(this), |
112 callback)); | 112 callback)); |
113 } | 113 } |
114 | 114 |
115 void AudioReceiver::DecodeEncodedAudioFrame( | 115 void AudioReceiver::DecodeEncodedAudioFrame( |
116 const AudioFrameDecodedCallback& callback, | 116 const AudioFrameDecodedCallback& callback, |
117 scoped_ptr<transport::EncodedAudioFrame> encoded_frame, | 117 scoped_ptr<transport::EncodedFrame> encoded_frame) { |
118 const base::TimeTicks& playout_time) { | |
119 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 118 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
120 if (!encoded_frame) { | 119 if (!encoded_frame) { |
121 callback.Run(make_scoped_ptr<AudioBus>(NULL), playout_time, false); | 120 callback.Run(make_scoped_ptr<AudioBus>(NULL), base::TimeTicks(), false); |
122 return; | 121 return; |
123 } | 122 } |
124 const uint32 frame_id = encoded_frame->frame_id; | 123 const uint32 frame_id = encoded_frame->frame_id; |
125 const uint32 rtp_timestamp = encoded_frame->rtp_timestamp; | 124 const uint32 rtp_timestamp = encoded_frame->rtp_timestamp; |
| 125 const base::TimeTicks playout_time = encoded_frame->reference_time; |
126 audio_decoder_->DecodeFrame(encoded_frame.Pass(), | 126 audio_decoder_->DecodeFrame(encoded_frame.Pass(), |
127 base::Bind(&AudioReceiver::EmitRawAudioFrame, | 127 base::Bind(&AudioReceiver::EmitRawAudioFrame, |
128 cast_environment_, | 128 cast_environment_, |
129 callback, | 129 callback, |
130 frame_id, | 130 frame_id, |
131 rtp_timestamp, | 131 rtp_timestamp, |
132 playout_time)); | 132 playout_time)); |
133 } | 133 } |
134 | 134 |
135 // static | 135 // static |
(...skipping 10 matching lines...) Expand all Loading... |
146 const base::TimeTicks now = cast_environment->Clock()->NowTicks(); | 146 const base::TimeTicks now = cast_environment->Clock()->NowTicks(); |
147 cast_environment->Logging()->InsertFrameEvent( | 147 cast_environment->Logging()->InsertFrameEvent( |
148 now, FRAME_DECODED, AUDIO_EVENT, rtp_timestamp, frame_id); | 148 now, FRAME_DECODED, AUDIO_EVENT, rtp_timestamp, frame_id); |
149 cast_environment->Logging()->InsertFrameEventWithDelay( | 149 cast_environment->Logging()->InsertFrameEventWithDelay( |
150 now, FRAME_PLAYOUT, AUDIO_EVENT, rtp_timestamp, frame_id, | 150 now, FRAME_PLAYOUT, AUDIO_EVENT, rtp_timestamp, frame_id, |
151 playout_time - now); | 151 playout_time - now); |
152 } | 152 } |
153 callback.Run(audio_bus.Pass(), playout_time, is_continuous); | 153 callback.Run(audio_bus.Pass(), playout_time, is_continuous); |
154 } | 154 } |
155 | 155 |
156 void AudioReceiver::GetEncodedAudioFrame( | 156 void AudioReceiver::GetEncodedAudioFrame(const FrameEncodedCallback& callback) { |
157 const AudioFrameEncodedCallback& callback) { | |
158 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 157 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
159 frame_request_queue_.push_back(callback); | 158 frame_request_queue_.push_back(callback); |
160 EmitAvailableEncodedFrames(); | 159 EmitAvailableEncodedFrames(); |
161 } | 160 } |
162 | 161 |
163 void AudioReceiver::EmitAvailableEncodedFrames() { | 162 void AudioReceiver::EmitAvailableEncodedFrames() { |
164 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 163 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
165 | 164 |
166 while (!frame_request_queue_.empty()) { | 165 while (!frame_request_queue_.empty()) { |
167 // Attempt to peek at the next completed frame from the |framer_|. | 166 // Attempt to peek at the next completed frame from the |framer_|. |
168 // TODO(miu): We should only be peeking at the metadata, and not copying the | 167 // TODO(miu): We should only be peeking at the metadata, and not copying the |
169 // payload yet! Or, at least, peek using a StringPiece instead of a copy. | 168 // payload yet! Or, at least, peek using a StringPiece instead of a copy. |
170 scoped_ptr<transport::EncodedAudioFrame> encoded_frame( | 169 scoped_ptr<transport::EncodedFrame> encoded_frame( |
171 new transport::EncodedAudioFrame()); | 170 new transport::EncodedFrame()); |
172 bool is_consecutively_next_frame = false; | 171 bool is_consecutively_next_frame = false; |
173 if (!framer_.GetEncodedAudioFrame(encoded_frame.get(), | 172 if (!framer_.GetEncodedAudioFrame(encoded_frame.get(), |
174 &is_consecutively_next_frame)) { | 173 &is_consecutively_next_frame)) { |
175 VLOG(1) << "Wait for more audio packets to produce a completed frame."; | 174 VLOG(1) << "Wait for more audio packets to produce a completed frame."; |
176 return; // OnReceivedPayloadData() will invoke this method in the future. | 175 return; // OnReceivedPayloadData() will invoke this method in the future. |
177 } | 176 } |
178 | 177 |
179 // If |framer_| has a frame ready that is out of sequence, examine the | 178 // If |framer_| has a frame ready that is out of sequence, examine the |
180 // playout time to determine whether it's acceptable to continue, thereby | 179 // playout time to determine whether it's acceptable to continue, thereby |
181 // skipping one or more frames. Skip if the missing frame wouldn't complete | 180 // skipping one or more frames. Skip if the missing frame wouldn't complete |
(...skipping 27 matching lines...) Expand all Loading... |
209 encoded_frame->data, | 208 encoded_frame->data, |
210 &decrypted_audio_data)) { | 209 &decrypted_audio_data)) { |
211 // Decryption failed. Give up on this frame, releasing it from the | 210 // Decryption failed. Give up on this frame, releasing it from the |
212 // jitter buffer. | 211 // jitter buffer. |
213 framer_.ReleaseFrame(encoded_frame->frame_id); | 212 framer_.ReleaseFrame(encoded_frame->frame_id); |
214 continue; | 213 continue; |
215 } | 214 } |
216 encoded_frame->data.swap(decrypted_audio_data); | 215 encoded_frame->data.swap(decrypted_audio_data); |
217 } | 216 } |
218 | 217 |
219 // At this point, we have a decrypted EncodedAudioFrame ready to be emitted. | 218 // At this point, we have a decrypted EncodedFrame ready to be emitted. |
220 encoded_frame->codec = codec_; | 219 encoded_frame->reference_time = playout_time; |
221 framer_.ReleaseFrame(encoded_frame->frame_id); | 220 framer_.ReleaseFrame(encoded_frame->frame_id); |
222 cast_environment_->PostTask(CastEnvironment::MAIN, | 221 cast_environment_->PostTask(CastEnvironment::MAIN, |
223 FROM_HERE, | 222 FROM_HERE, |
224 base::Bind(frame_request_queue_.front(), | 223 base::Bind(frame_request_queue_.front(), |
225 base::Passed(&encoded_frame), | 224 base::Passed(&encoded_frame))); |
226 playout_time)); | |
227 frame_request_queue_.pop_front(); | 225 frame_request_queue_.pop_front(); |
228 } | 226 } |
229 } | 227 } |
230 | 228 |
231 void AudioReceiver::EmitAvailableEncodedFramesAfterWaiting() { | 229 void AudioReceiver::EmitAvailableEncodedFramesAfterWaiting() { |
232 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 230 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
233 DCHECK(is_waiting_for_consecutive_frame_); | 231 DCHECK(is_waiting_for_consecutive_frame_); |
234 is_waiting_for_consecutive_frame_ = false; | 232 is_waiting_for_consecutive_frame_ = false; |
235 EmitAvailableEncodedFrames(); | 233 EmitAvailableEncodedFrames(); |
236 } | 234 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 } | 362 } |
365 | 363 |
366 void AudioReceiver::SendNextCastMessage() { | 364 void AudioReceiver::SendNextCastMessage() { |
367 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 365 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
368 framer_.SendCastMessage(); // Will only send a message if it is time. | 366 framer_.SendCastMessage(); // Will only send a message if it is time. |
369 ScheduleNextCastMessage(); | 367 ScheduleNextCastMessage(); |
370 } | 368 } |
371 | 369 |
372 } // namespace cast | 370 } // namespace cast |
373 } // namespace media | 371 } // namespace media |
OLD | NEW |