| 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 |