| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/filters/decrypting_audio_decoder.h" | 5 #include "media/filters/decrypting_audio_decoder.h" |
| 6 | 6 |
| 7 #include <cstdlib> | 7 #include <cstdlib> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 return std::abs(timestamp_1.InMilliseconds() - timestamp_2.InMilliseconds()) > | 33 return std::abs(timestamp_1.InMilliseconds() - timestamp_2.InMilliseconds()) > |
| 34 kOutOfSyncThresholdInMilliseconds; | 34 kOutOfSyncThresholdInMilliseconds; |
| 35 } | 35 } |
| 36 | 36 |
| 37 DecryptingAudioDecoder::DecryptingAudioDecoder( | 37 DecryptingAudioDecoder::DecryptingAudioDecoder( |
| 38 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 38 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 39 const SetDecryptorReadyCB& set_decryptor_ready_cb) | 39 const SetDecryptorReadyCB& set_decryptor_ready_cb) |
| 40 : task_runner_(task_runner), | 40 : task_runner_(task_runner), |
| 41 weak_factory_(this), | 41 weak_factory_(this), |
| 42 state_(kUninitialized), | 42 state_(kUninitialized), |
| 43 demuxer_stream_(NULL), | |
| 44 set_decryptor_ready_cb_(set_decryptor_ready_cb), | 43 set_decryptor_ready_cb_(set_decryptor_ready_cb), |
| 45 decryptor_(NULL), | 44 decryptor_(NULL), |
| 46 key_added_while_decode_pending_(false), | 45 key_added_while_decode_pending_(false), |
| 47 bits_per_channel_(0), | 46 bits_per_channel_(0), |
| 48 channel_layout_(CHANNEL_LAYOUT_NONE), | 47 channel_layout_(CHANNEL_LAYOUT_NONE), |
| 49 samples_per_second_(0) { | 48 samples_per_second_(0) { |
| 50 } | 49 } |
| 51 | 50 |
| 52 void DecryptingAudioDecoder::Initialize( | 51 void DecryptingAudioDecoder::Initialize(const AudioDecoderConfig& config, |
| 53 DemuxerStream* stream, | 52 const PipelineStatusCB& status_cb) { |
| 54 const PipelineStatusCB& status_cb, | |
| 55 const StatisticsCB& statistics_cb) { | |
| 56 DVLOG(2) << "Initialize()"; | 53 DVLOG(2) << "Initialize()"; |
| 57 DCHECK(task_runner_->BelongsToCurrentThread()); | 54 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 58 DCHECK_EQ(state_, kUninitialized) << state_; | 55 DCHECK(decode_cb_.is_null()); |
| 59 DCHECK(stream); | 56 DCHECK(reset_cb_.is_null()); |
| 60 | 57 |
| 61 weak_this_ = weak_factory_.GetWeakPtr(); | 58 weak_this_ = weak_factory_.GetWeakPtr(); |
| 62 init_cb_ = BindToCurrentLoop(status_cb); | 59 init_cb_ = BindToCurrentLoop(status_cb); |
| 63 | 60 |
| 64 const AudioDecoderConfig& config = stream->audio_decoder_config(); | |
| 65 if (!config.IsValidConfig()) { | 61 if (!config.IsValidConfig()) { |
| 66 DLOG(ERROR) << "Invalid audio stream config."; | 62 DLOG(ERROR) << "Invalid audio stream config."; |
| 67 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_DECODE); | 63 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_DECODE); |
| 68 return; | 64 return; |
| 69 } | 65 } |
| 70 | 66 |
| 71 // DecryptingAudioDecoder only accepts potentially encrypted stream. | 67 // DecryptingAudioDecoder only accepts potentially encrypted stream. |
| 72 if (!config.is_encrypted()) { | 68 if (!config.is_encrypted()) { |
| 73 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 69 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
| 74 return; | 70 return; |
| 75 } | 71 } |
| 76 | 72 |
| 77 DCHECK(!demuxer_stream_); | 73 config_ = config; |
| 78 demuxer_stream_ = stream; | |
| 79 statistics_cb_ = statistics_cb; | |
| 80 | 74 |
| 81 state_ = kDecryptorRequested; | 75 if (state_ == kUninitialized) { |
| 82 set_decryptor_ready_cb_.Run(BindToCurrentLoop( | 76 state_ = kDecryptorRequested; |
| 83 base::Bind(&DecryptingAudioDecoder::SetDecryptor, weak_this_))); | 77 set_decryptor_ready_cb_.Run(BindToCurrentLoop( |
| 78 base::Bind(&DecryptingAudioDecoder::SetDecryptor, weak_this_))); |
| 79 return; |
| 80 } |
| 81 |
| 82 // Reinitialization (i.e. upon a config change) |
| 83 decryptor_->DeinitializeDecoder(Decryptor::kAudio); |
| 84 state_ = kPendingDecoderInit; |
| 85 decryptor_->InitializeAudioDecoder( |
| 86 config, |
| 87 BindToCurrentLoop(base::Bind( |
| 88 &DecryptingAudioDecoder::FinishInitialization, weak_this_))); |
| 84 } | 89 } |
| 85 | 90 |
| 86 void DecryptingAudioDecoder::Read(const ReadCB& read_cb) { | 91 void DecryptingAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, |
| 87 DVLOG(3) << "Read()"; | 92 const DecodeCB& decode_cb) { |
| 93 DVLOG(3) << "Decode()"; |
| 88 DCHECK(task_runner_->BelongsToCurrentThread()); | 94 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 89 DCHECK(state_ == kIdle || state_ == kDecodeFinished) << state_; | 95 DCHECK(state_ == kIdle || state_ == kDecodeFinished) << state_; |
| 90 DCHECK(!read_cb.is_null()); | 96 DCHECK(!decode_cb.is_null()); |
| 91 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported."; | 97 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported."; |
| 92 | 98 |
| 93 read_cb_ = BindToCurrentLoop(read_cb); | 99 decode_cb_ = BindToCurrentLoop(decode_cb); |
| 94 | 100 |
| 95 // Return empty (end-of-stream) frames if decoding has finished. | 101 // Return empty (end-of-stream) frames if decoding has finished. |
| 96 if (state_ == kDecodeFinished) { | 102 if (state_ == kDecodeFinished) { |
| 97 base::ResetAndReturn(&read_cb_).Run(kOk, AudioBuffer::CreateEOSBuffer()); | 103 base::ResetAndReturn(&decode_cb_).Run(kOk, AudioBuffer::CreateEOSBuffer()); |
| 98 return; | 104 return; |
| 99 } | 105 } |
| 100 | 106 |
| 101 if (!queued_audio_frames_.empty()) { | 107 if (!queued_audio_frames_.empty()) { |
| 102 base::ResetAndReturn(&read_cb_).Run(kOk, queued_audio_frames_.front()); | 108 DCHECK(!buffer); |
| 109 base::ResetAndReturn(&decode_cb_).Run(kOk, queued_audio_frames_.front()); |
| 103 queued_audio_frames_.pop_front(); | 110 queued_audio_frames_.pop_front(); |
| 104 return; | 111 return; |
| 105 } | 112 } |
| 106 | 113 |
| 107 state_ = kPendingDemuxerRead; | 114 // Initialize the |next_output_timestamp_| to be the timestamp of the first |
| 108 ReadFromDemuxerStream(); | 115 // non-EOS buffer. |
| 116 if (timestamp_helper_->base_timestamp() == kNoTimestamp() && |
| 117 !buffer->end_of_stream()) { |
| 118 timestamp_helper_->SetBaseTimestamp(buffer->timestamp()); |
| 119 } |
| 120 |
| 121 pending_buffer_to_decode_ = buffer; |
| 122 state_ = kPendingDecode; |
| 123 DecodePendingBuffer(); |
| 124 } |
| 125 |
| 126 scoped_refptr<AudioBuffer> DecryptingAudioDecoder::GetDecodeOutput() { |
| 127 if (queued_audio_frames_.empty()) |
| 128 return NULL; |
| 129 scoped_refptr<AudioBuffer> out = queued_audio_frames_.front(); |
| 130 queued_audio_frames_.pop_front(); |
| 131 return out; |
| 109 } | 132 } |
| 110 | 133 |
| 111 void DecryptingAudioDecoder::Reset(const base::Closure& closure) { | 134 void DecryptingAudioDecoder::Reset(const base::Closure& closure) { |
| 112 DVLOG(2) << "Reset() - state: " << state_; | 135 DVLOG(2) << "Reset() - state: " << state_; |
| 113 DCHECK(task_runner_->BelongsToCurrentThread()); | 136 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 114 DCHECK(state_ == kIdle || | 137 DCHECK(state_ == kIdle || |
| 115 state_ == kPendingConfigChange || | |
| 116 state_ == kPendingDemuxerRead || | |
| 117 state_ == kPendingDecode || | 138 state_ == kPendingDecode || |
| 118 state_ == kWaitingForKey || | 139 state_ == kWaitingForKey || |
| 119 state_ == kDecodeFinished) << state_; | 140 state_ == kDecodeFinished) << state_; |
| 120 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. | 141 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. |
| 121 DCHECK(reset_cb_.is_null()); | 142 DCHECK(reset_cb_.is_null()); |
| 122 | 143 |
| 123 reset_cb_ = BindToCurrentLoop(closure); | 144 reset_cb_ = BindToCurrentLoop(closure); |
| 124 | 145 |
| 125 decryptor_->ResetDecoder(Decryptor::kAudio); | 146 decryptor_->ResetDecoder(Decryptor::kAudio); |
| 126 | 147 |
| 127 // Reset() cannot complete if the read callback is still pending. | 148 // Reset() cannot complete if the read callback is still pending. |
| 128 // Defer the resetting process in this case. The |reset_cb_| will be fired | 149 // Defer the resetting process in this case. The |reset_cb_| will be fired |
| 129 // after the read callback is fired - see DecryptAndDecodeBuffer() and | 150 // after the read callback is fired - see DecryptAndDecodeBuffer() and |
| 130 // DeliverFrame(). | 151 // DeliverFrame(). |
| 131 if (state_ == kPendingConfigChange || | 152 if (state_ == kPendingDecode) { |
| 132 state_ == kPendingDemuxerRead || | 153 DCHECK(!decode_cb_.is_null()); |
| 133 state_ == kPendingDecode) { | |
| 134 DCHECK(!read_cb_.is_null()); | |
| 135 return; | 154 return; |
| 136 } | 155 } |
| 137 | 156 |
| 138 if (state_ == kWaitingForKey) { | 157 if (state_ == kWaitingForKey) { |
| 139 DCHECK(!read_cb_.is_null()); | 158 DCHECK(!decode_cb_.is_null()); |
| 140 pending_buffer_to_decode_ = NULL; | 159 pending_buffer_to_decode_ = NULL; |
| 141 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 160 base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL); |
| 142 } | 161 } |
| 143 | 162 |
| 144 DCHECK(read_cb_.is_null()); | 163 DCHECK(decode_cb_.is_null()); |
| 145 DoReset(); | 164 DoReset(); |
| 146 } | 165 } |
| 147 | 166 |
| 148 void DecryptingAudioDecoder::Stop(const base::Closure& closure) { | 167 void DecryptingAudioDecoder::Stop(const base::Closure& closure) { |
| 149 DVLOG(2) << "Stop() - state: " << state_; | 168 DVLOG(2) << "Stop() - state: " << state_; |
| 150 DCHECK(task_runner_->BelongsToCurrentThread()); | 169 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 151 | 170 |
| 152 // Invalidate all weak pointers so that pending callbacks won't be fired into | 171 // Invalidate all weak pointers so that pending callbacks won't be fired into |
| 153 // this object. | 172 // this object. |
| 154 weak_factory_.InvalidateWeakPtrs(); | 173 weak_factory_.InvalidateWeakPtrs(); |
| 155 | 174 |
| 156 if (decryptor_) { | 175 if (decryptor_) { |
| 157 decryptor_->DeinitializeDecoder(Decryptor::kAudio); | 176 decryptor_->DeinitializeDecoder(Decryptor::kAudio); |
| 158 decryptor_ = NULL; | 177 decryptor_ = NULL; |
| 159 } | 178 } |
| 160 if (!set_decryptor_ready_cb_.is_null()) | 179 if (!set_decryptor_ready_cb_.is_null()) |
| 161 base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB()); | 180 base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB()); |
| 162 pending_buffer_to_decode_ = NULL; | 181 pending_buffer_to_decode_ = NULL; |
| 163 if (!init_cb_.is_null()) | 182 if (!init_cb_.is_null()) |
| 164 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 183 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
| 165 if (!read_cb_.is_null()) | 184 if (!decode_cb_.is_null()) |
| 166 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 185 base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL); |
| 167 if (!reset_cb_.is_null()) | 186 if (!reset_cb_.is_null()) |
| 168 base::ResetAndReturn(&reset_cb_).Run(); | 187 base::ResetAndReturn(&reset_cb_).Run(); |
| 169 | 188 |
| 170 state_ = kStopped; | 189 state_ = kStopped; |
| 171 task_runner_->PostTask(FROM_HERE, closure); | 190 task_runner_->PostTask(FROM_HERE, closure); |
| 172 } | 191 } |
| 173 | 192 |
| 174 int DecryptingAudioDecoder::bits_per_channel() { | 193 int DecryptingAudioDecoder::bits_per_channel() { |
| 175 DCHECK(task_runner_->BelongsToCurrentThread()); | 194 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 176 return bits_per_channel_; | 195 return bits_per_channel_; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 201 | 220 |
| 202 if (!decryptor) { | 221 if (!decryptor) { |
| 203 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 222 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
| 204 // TODO(xhwang): Add kError state. See http://crbug.com/251503 | 223 // TODO(xhwang): Add kError state. See http://crbug.com/251503 |
| 205 state_ = kStopped; | 224 state_ = kStopped; |
| 206 return; | 225 return; |
| 207 } | 226 } |
| 208 | 227 |
| 209 decryptor_ = decryptor; | 228 decryptor_ = decryptor; |
| 210 | 229 |
| 211 const AudioDecoderConfig& input_config = | 230 config_.Initialize(config_.codec(), |
| 212 demuxer_stream_->audio_decoder_config(); | 231 kSampleFormatS16, |
| 213 AudioDecoderConfig config; | 232 config_.channel_layout(), |
| 214 config.Initialize(input_config.codec(), | 233 config_.samples_per_second(), |
| 215 kSampleFormatS16, | 234 config_.extra_data(), |
| 216 input_config.channel_layout(), | 235 config_.extra_data_size(), |
| 217 input_config.samples_per_second(), | 236 config_.is_encrypted(), |
| 218 input_config.extra_data(), | 237 false, |
| 219 input_config.extra_data_size(), | 238 base::TimeDelta(), |
| 220 input_config.is_encrypted(), | 239 base::TimeDelta()); |
| 221 false, | |
| 222 base::TimeDelta(), | |
| 223 base::TimeDelta()); | |
| 224 | 240 |
| 225 state_ = kPendingDecoderInit; | 241 state_ = kPendingDecoderInit; |
| 226 decryptor_->InitializeAudioDecoder( | 242 decryptor_->InitializeAudioDecoder( |
| 227 config, | 243 config_, |
| 228 BindToCurrentLoop(base::Bind( | 244 BindToCurrentLoop(base::Bind( |
| 229 &DecryptingAudioDecoder::FinishInitialization, weak_this_))); | 245 &DecryptingAudioDecoder::FinishInitialization, weak_this_))); |
| 230 } | 246 } |
| 231 | 247 |
| 232 void DecryptingAudioDecoder::FinishInitialization(bool success) { | 248 void DecryptingAudioDecoder::FinishInitialization(bool success) { |
| 233 DVLOG(2) << "FinishInitialization()"; | 249 DVLOG(2) << "FinishInitialization()"; |
| 234 DCHECK(task_runner_->BelongsToCurrentThread()); | 250 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 235 DCHECK_EQ(state_, kPendingDecoderInit) << state_; | 251 DCHECK(state_ == kPendingDecoderInit) |
| 252 << state_; |
| 236 DCHECK(!init_cb_.is_null()); | 253 DCHECK(!init_cb_.is_null()); |
| 237 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. | 254 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. |
| 238 DCHECK(read_cb_.is_null()); // No Read() before initialization finished. | 255 DCHECK(decode_cb_.is_null()); // No Decode() before initialization finished. |
| 239 | 256 |
| 240 if (!success) { | 257 if (!success) { |
| 241 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 258 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
| 242 state_ = kStopped; | 259 state_ = kStopped; |
| 243 return; | 260 return; |
| 244 } | 261 } |
| 245 | 262 |
| 246 // Success! | 263 // Success! |
| 247 UpdateDecoderConfig(); | 264 UpdateDecoderConfig(); |
| 248 | 265 |
| 249 decryptor_->RegisterNewKeyCB( | 266 decryptor_->RegisterNewKeyCB( |
| 250 Decryptor::kAudio, | 267 Decryptor::kAudio, |
| 251 BindToCurrentLoop( | 268 BindToCurrentLoop( |
| 252 base::Bind(&DecryptingAudioDecoder::OnKeyAdded, weak_this_))); | 269 base::Bind(&DecryptingAudioDecoder::OnKeyAdded, weak_this_))); |
| 253 | 270 |
| 254 state_ = kIdle; | 271 state_ = kIdle; |
| 255 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); | 272 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
| 256 } | 273 } |
| 257 | 274 |
| 258 void DecryptingAudioDecoder::FinishConfigChange(bool success) { | |
| 259 DVLOG(2) << "FinishConfigChange()"; | |
| 260 DCHECK(task_runner_->BelongsToCurrentThread()); | |
| 261 DCHECK_EQ(state_, kPendingConfigChange) << state_; | |
| 262 DCHECK(!read_cb_.is_null()); | |
| 263 | |
| 264 if (!success) { | |
| 265 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | |
| 266 state_ = kDecodeFinished; | |
| 267 if (!reset_cb_.is_null()) | |
| 268 base::ResetAndReturn(&reset_cb_).Run(); | |
| 269 return; | |
| 270 } | |
| 271 | |
| 272 // Config change succeeded. | |
| 273 UpdateDecoderConfig(); | |
| 274 | |
| 275 if (!reset_cb_.is_null()) { | |
| 276 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | |
| 277 DoReset(); | |
| 278 return; | |
| 279 } | |
| 280 | |
| 281 state_ = kPendingDemuxerRead; | |
| 282 ReadFromDemuxerStream(); | |
| 283 } | |
| 284 | |
| 285 void DecryptingAudioDecoder::ReadFromDemuxerStream() { | |
| 286 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; | |
| 287 DCHECK(!read_cb_.is_null()); | |
| 288 | |
| 289 demuxer_stream_->Read( | |
| 290 base::Bind(&DecryptingAudioDecoder::DecryptAndDecodeBuffer, weak_this_)); | |
| 291 } | |
| 292 | |
| 293 void DecryptingAudioDecoder::DecryptAndDecodeBuffer( | |
| 294 DemuxerStream::Status status, | |
| 295 const scoped_refptr<DecoderBuffer>& buffer) { | |
| 296 DVLOG(3) << "DecryptAndDecodeBuffer()"; | |
| 297 DCHECK(task_runner_->BelongsToCurrentThread()); | |
| 298 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; | |
| 299 DCHECK(!read_cb_.is_null()); | |
| 300 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; | |
| 301 | |
| 302 if (status == DemuxerStream::kConfigChanged) { | |
| 303 DVLOG(2) << "DecryptAndDecodeBuffer() - kConfigChanged"; | |
| 304 | |
| 305 const AudioDecoderConfig& input_config = | |
| 306 demuxer_stream_->audio_decoder_config(); | |
| 307 AudioDecoderConfig config; | |
| 308 config.Initialize(input_config.codec(), | |
| 309 kSampleFormatS16, | |
| 310 input_config.channel_layout(), | |
| 311 input_config.samples_per_second(), | |
| 312 input_config.extra_data(), | |
| 313 input_config.extra_data_size(), | |
| 314 input_config.is_encrypted(), | |
| 315 false, | |
| 316 base::TimeDelta(), | |
| 317 base::TimeDelta()); | |
| 318 | |
| 319 state_ = kPendingConfigChange; | |
| 320 decryptor_->DeinitializeDecoder(Decryptor::kAudio); | |
| 321 decryptor_->InitializeAudioDecoder( | |
| 322 config, BindToCurrentLoop(base::Bind( | |
| 323 &DecryptingAudioDecoder::FinishConfigChange, weak_this_))); | |
| 324 return; | |
| 325 } | |
| 326 | |
| 327 if (!reset_cb_.is_null()) { | |
| 328 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | |
| 329 DoReset(); | |
| 330 return; | |
| 331 } | |
| 332 | |
| 333 if (status == DemuxerStream::kAborted) { | |
| 334 DVLOG(2) << "DecryptAndDecodeBuffer() - kAborted"; | |
| 335 state_ = kIdle; | |
| 336 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | |
| 337 return; | |
| 338 } | |
| 339 | |
| 340 DCHECK_EQ(status, DemuxerStream::kOk); | |
| 341 | |
| 342 // Initialize the |next_output_timestamp_| to be the timestamp of the first | |
| 343 // non-EOS buffer. | |
| 344 if (timestamp_helper_->base_timestamp() == kNoTimestamp() && | |
| 345 !buffer->end_of_stream()) { | |
| 346 timestamp_helper_->SetBaseTimestamp(buffer->timestamp()); | |
| 347 } | |
| 348 | |
| 349 pending_buffer_to_decode_ = buffer; | |
| 350 state_ = kPendingDecode; | |
| 351 DecodePendingBuffer(); | |
| 352 } | |
| 353 | |
| 354 void DecryptingAudioDecoder::DecodePendingBuffer() { | 275 void DecryptingAudioDecoder::DecodePendingBuffer() { |
| 355 DCHECK(task_runner_->BelongsToCurrentThread()); | 276 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 356 DCHECK_EQ(state_, kPendingDecode) << state_; | 277 DCHECK_EQ(state_, kPendingDecode) << state_; |
| 357 | 278 |
| 358 int buffer_size = 0; | 279 int buffer_size = 0; |
| 359 if (!pending_buffer_to_decode_->end_of_stream()) { | 280 if (!pending_buffer_to_decode_->end_of_stream()) { |
| 360 buffer_size = pending_buffer_to_decode_->data_size(); | 281 buffer_size = pending_buffer_to_decode_->data_size(); |
| 361 } | 282 } |
| 362 | 283 |
| 363 decryptor_->DecryptAndDecodeAudio( | 284 decryptor_->DecryptAndDecodeAudio( |
| 364 pending_buffer_to_decode_, | 285 pending_buffer_to_decode_, |
| 365 BindToCurrentLoop(base::Bind( | 286 BindToCurrentLoop(base::Bind( |
| 366 &DecryptingAudioDecoder::DeliverFrame, weak_this_, buffer_size))); | 287 &DecryptingAudioDecoder::DeliverFrame, weak_this_, buffer_size))); |
| 367 } | 288 } |
| 368 | 289 |
| 369 void DecryptingAudioDecoder::DeliverFrame( | 290 void DecryptingAudioDecoder::DeliverFrame( |
| 370 int buffer_size, | 291 int buffer_size, |
| 371 Decryptor::Status status, | 292 Decryptor::Status status, |
| 372 const Decryptor::AudioBuffers& frames) { | 293 const Decryptor::AudioBuffers& frames) { |
| 373 DVLOG(3) << "DeliverFrame() - status: " << status; | 294 DVLOG(3) << "DeliverFrame() - status: " << status; |
| 374 DCHECK(task_runner_->BelongsToCurrentThread()); | 295 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 375 DCHECK_EQ(state_, kPendingDecode) << state_; | 296 DCHECK_EQ(state_, kPendingDecode) << state_; |
| 376 DCHECK(!read_cb_.is_null()); | 297 DCHECK(!decode_cb_.is_null()); |
| 377 DCHECK(pending_buffer_to_decode_.get()); | 298 DCHECK(pending_buffer_to_decode_.get()); |
| 378 DCHECK(queued_audio_frames_.empty()); | 299 DCHECK(queued_audio_frames_.empty()); |
| 379 | 300 |
| 380 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_; | 301 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_; |
| 381 key_added_while_decode_pending_ = false; | 302 key_added_while_decode_pending_ = false; |
| 382 | 303 |
| 383 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode = | 304 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode = |
| 384 pending_buffer_to_decode_; | 305 pending_buffer_to_decode_; |
| 385 pending_buffer_to_decode_ = NULL; | 306 pending_buffer_to_decode_ = NULL; |
| 386 | 307 |
| 387 if (!reset_cb_.is_null()) { | 308 if (!reset_cb_.is_null()) { |
| 388 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 309 base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL); |
| 389 DoReset(); | 310 DoReset(); |
| 390 return; | 311 return; |
| 391 } | 312 } |
| 392 | 313 |
| 393 DCHECK_EQ(status == Decryptor::kSuccess, !frames.empty()); | 314 DCHECK_EQ(status == Decryptor::kSuccess, !frames.empty()); |
| 394 | 315 |
| 395 if (status == Decryptor::kError) { | 316 if (status == Decryptor::kError) { |
| 396 DVLOG(2) << "DeliverFrame() - kError"; | 317 DVLOG(2) << "DeliverFrame() - kError"; |
| 397 state_ = kDecodeFinished; | 318 state_ = kDecodeFinished; // TODO add kError state |
| 398 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | 319 base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL); |
| 399 return; | 320 return; |
| 400 } | 321 } |
| 401 | 322 |
| 402 if (status == Decryptor::kNoKey) { | 323 if (status == Decryptor::kNoKey) { |
| 403 DVLOG(2) << "DeliverFrame() - kNoKey"; | 324 DVLOG(2) << "DeliverFrame() - kNoKey"; |
| 404 // Set |pending_buffer_to_decode_| back as we need to try decoding the | 325 // Set |pending_buffer_to_decode_| back as we need to try decoding the |
| 405 // pending buffer again when new key is added to the decryptor. | 326 // pending buffer again when new key is added to the decryptor. |
| 406 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; | 327 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; |
| 407 | 328 |
| 408 if (need_to_try_again_if_nokey_is_returned) { | 329 if (need_to_try_again_if_nokey_is_returned) { |
| 409 // The |state_| is still kPendingDecode. | 330 // The |state_| is still kPendingDecode. |
| 410 DecodePendingBuffer(); | 331 DecodePendingBuffer(); |
| 411 return; | 332 return; |
| 412 } | 333 } |
| 413 | 334 |
| 414 state_ = kWaitingForKey; | 335 state_ = kWaitingForKey; |
| 415 return; | 336 return; |
| 416 } | 337 } |
| 417 | 338 |
| 418 // The buffer has been accepted by the decoder, let's report statistics. | |
| 419 if (buffer_size) { | |
| 420 PipelineStatistics statistics; | |
| 421 statistics.audio_bytes_decoded = buffer_size; | |
| 422 statistics_cb_.Run(statistics); | |
| 423 } | |
| 424 | |
| 425 if (status == Decryptor::kNeedMoreData) { | 339 if (status == Decryptor::kNeedMoreData) { |
| 426 DVLOG(2) << "DeliverFrame() - kNeedMoreData"; | 340 DVLOG(2) << "DeliverFrame() - kNeedMoreData"; |
| 427 if (scoped_pending_buffer_to_decode->end_of_stream()) { | 341 if (scoped_pending_buffer_to_decode->end_of_stream()) { |
| 428 state_ = kDecodeFinished; | 342 state_ = kDecodeFinished; |
| 429 base::ResetAndReturn(&read_cb_).Run(kOk, AudioBuffer::CreateEOSBuffer()); | 343 base::ResetAndReturn(&decode_cb_) |
| 344 .Run(kOk, AudioBuffer::CreateEOSBuffer()); |
| 430 return; | 345 return; |
| 431 } | 346 } |
| 432 | 347 |
| 433 state_ = kPendingDemuxerRead; | 348 state_ = kIdle; |
| 434 ReadFromDemuxerStream(); | 349 base::ResetAndReturn(&decode_cb_).Run(kNotEnoughData, NULL); |
| 435 return; | 350 return; |
| 436 } | 351 } |
| 437 | 352 |
| 438 DCHECK_EQ(status, Decryptor::kSuccess); | 353 DCHECK_EQ(status, Decryptor::kSuccess); |
| 439 DCHECK(!frames.empty()); | 354 DCHECK(!frames.empty()); |
| 440 EnqueueFrames(frames); | 355 EnqueueFrames(frames); |
| 441 | 356 |
| 442 state_ = kIdle; | 357 state_ = kIdle; |
| 443 base::ResetAndReturn(&read_cb_).Run(kOk, queued_audio_frames_.front()); | 358 base::ResetAndReturn(&decode_cb_).Run(kOk, queued_audio_frames_.front()); |
| 444 queued_audio_frames_.pop_front(); | 359 queued_audio_frames_.pop_front(); |
| 445 } | 360 } |
| 446 | 361 |
| 447 void DecryptingAudioDecoder::OnKeyAdded() { | 362 void DecryptingAudioDecoder::OnKeyAdded() { |
| 448 DCHECK(task_runner_->BelongsToCurrentThread()); | 363 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 449 | 364 |
| 450 if (state_ == kPendingDecode) { | 365 if (state_ == kPendingDecode) { |
| 451 key_added_while_decode_pending_ = true; | 366 key_added_while_decode_pending_ = true; |
| 452 return; | 367 return; |
| 453 } | 368 } |
| 454 | 369 |
| 455 if (state_ == kWaitingForKey) { | 370 if (state_ == kWaitingForKey) { |
| 456 state_ = kPendingDecode; | 371 state_ = kPendingDecode; |
| 457 DecodePendingBuffer(); | 372 DecodePendingBuffer(); |
| 458 } | 373 } |
| 459 } | 374 } |
| 460 | 375 |
| 461 void DecryptingAudioDecoder::DoReset() { | 376 void DecryptingAudioDecoder::DoReset() { |
| 462 DCHECK(init_cb_.is_null()); | 377 DCHECK(init_cb_.is_null()); |
| 463 DCHECK(read_cb_.is_null()); | 378 DCHECK(decode_cb_.is_null()); |
| 464 timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); | 379 timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); |
| 465 state_ = kIdle; | 380 state_ = kIdle; |
| 466 base::ResetAndReturn(&reset_cb_).Run(); | 381 base::ResetAndReturn(&reset_cb_).Run(); |
| 467 } | 382 } |
| 468 | 383 |
| 469 void DecryptingAudioDecoder::UpdateDecoderConfig() { | 384 void DecryptingAudioDecoder::UpdateDecoderConfig() { |
| 470 const AudioDecoderConfig& config = demuxer_stream_->audio_decoder_config(); | |
| 471 bits_per_channel_ = kSupportedBitsPerChannel; | 385 bits_per_channel_ = kSupportedBitsPerChannel; |
| 472 channel_layout_ = config.channel_layout(); | 386 channel_layout_ = config_.channel_layout(); |
| 473 samples_per_second_ = config.samples_per_second(); | 387 samples_per_second_ = config_.samples_per_second(); |
| 474 timestamp_helper_.reset(new AudioTimestampHelper(samples_per_second_)); | 388 timestamp_helper_.reset(new AudioTimestampHelper(samples_per_second_)); |
| 475 } | 389 } |
| 476 | 390 |
| 477 void DecryptingAudioDecoder::EnqueueFrames( | 391 void DecryptingAudioDecoder::EnqueueFrames( |
| 478 const Decryptor::AudioBuffers& frames) { | 392 const Decryptor::AudioBuffers& frames) { |
| 479 queued_audio_frames_ = frames; | 393 queued_audio_frames_ = frames; |
| 480 | 394 |
| 481 for (Decryptor::AudioBuffers::iterator iter = queued_audio_frames_.begin(); | 395 for (Decryptor::AudioBuffers::iterator iter = queued_audio_frames_.begin(); |
| 482 iter != queued_audio_frames_.end(); | 396 iter != queued_audio_frames_.end(); |
| 483 ++iter) { | 397 ++iter) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 495 } | 409 } |
| 496 | 410 |
| 497 frame->set_timestamp(current_time); | 411 frame->set_timestamp(current_time); |
| 498 frame->set_duration( | 412 frame->set_duration( |
| 499 timestamp_helper_->GetFrameDuration(frame->frame_count())); | 413 timestamp_helper_->GetFrameDuration(frame->frame_count())); |
| 500 timestamp_helper_->AddFrames(frame->frame_count()); | 414 timestamp_helper_->AddFrames(frame->frame_count()); |
| 501 } | 415 } |
| 502 } | 416 } |
| 503 | 417 |
| 504 } // namespace media | 418 } // namespace media |
| OLD | NEW |