Chromium Code Reviews| 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_ = kPendingConfigChange; | |
|
xhwang
2014/03/05 00:40:46
In DVD, we use kPendingDecoderInit for this status
rileya (GONE FROM CHROMIUM)
2014/03/05 08:08:28
Not that I can see. Removed kPendingConfigChange e
| |
| 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 } | |
|
xhwang
2014/03/05 00:40:46
nit: no need for {}
rileya (GONE FROM CHROMIUM)
2014/03/05 08:08:28
Removed.
| |
| 130 scoped_refptr<AudioBuffer> out = queued_audio_frames_.front(); | |
| 131 queued_audio_frames_.pop_front(); | |
| 132 return out; | |
| 109 } | 133 } |
| 110 | 134 |
| 111 void DecryptingAudioDecoder::Reset(const base::Closure& closure) { | 135 void DecryptingAudioDecoder::Reset(const base::Closure& closure) { |
| 112 DVLOG(2) << "Reset() - state: " << state_; | 136 DVLOG(2) << "Reset() - state: " << state_; |
| 113 DCHECK(task_runner_->BelongsToCurrentThread()); | 137 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 114 DCHECK(state_ == kIdle || | 138 DCHECK(state_ == kIdle || |
| 139 state_ == kPendingDecode || | |
| 115 state_ == kPendingConfigChange || | 140 state_ == kPendingConfigChange || |
| 116 state_ == kPendingDemuxerRead || | |
| 117 state_ == kPendingDecode || | |
| 118 state_ == kWaitingForKey || | 141 state_ == kWaitingForKey || |
| 119 state_ == kDecodeFinished) << state_; | 142 state_ == kDecodeFinished) << state_; |
| 120 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. | 143 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. |
| 121 DCHECK(reset_cb_.is_null()); | 144 DCHECK(reset_cb_.is_null()); |
| 122 | 145 |
| 123 reset_cb_ = BindToCurrentLoop(closure); | 146 reset_cb_ = BindToCurrentLoop(closure); |
| 124 | 147 |
| 125 decryptor_->ResetDecoder(Decryptor::kAudio); | 148 decryptor_->ResetDecoder(Decryptor::kAudio); |
| 126 | 149 |
| 127 // Reset() cannot complete if the read callback is still pending. | 150 // Reset() cannot complete if the read callback is still pending. |
| 128 // Defer the resetting process in this case. The |reset_cb_| will be fired | 151 // Defer the resetting process in this case. The |reset_cb_| will be fired |
| 129 // after the read callback is fired - see DecryptAndDecodeBuffer() and | 152 // after the read callback is fired - see DecryptAndDecodeBuffer() and |
| 130 // DeliverFrame(). | 153 // DeliverFrame(). |
| 131 if (state_ == kPendingConfigChange || | 154 if (state_ == kPendingDecode) { |
| 132 state_ == kPendingDemuxerRead || | 155 DCHECK(!decode_cb_.is_null()); |
| 133 state_ == kPendingDecode) { | |
| 134 DCHECK(!read_cb_.is_null()); | |
| 135 return; | 156 return; |
| 136 } | 157 } |
| 137 | 158 |
| 138 if (state_ == kWaitingForKey) { | 159 if (state_ == kWaitingForKey) { |
| 139 DCHECK(!read_cb_.is_null()); | 160 DCHECK(!decode_cb_.is_null()); |
| 140 pending_buffer_to_decode_ = NULL; | 161 pending_buffer_to_decode_ = NULL; |
| 141 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 162 base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL); |
| 142 } | 163 } |
| 143 | 164 |
| 144 DCHECK(read_cb_.is_null()); | 165 DCHECK(decode_cb_.is_null()); |
| 145 DoReset(); | 166 DoReset(); |
| 146 } | 167 } |
| 147 | 168 |
| 148 void DecryptingAudioDecoder::Stop(const base::Closure& closure) { | 169 void DecryptingAudioDecoder::Stop(const base::Closure& closure) { |
| 149 DVLOG(2) << "Stop() - state: " << state_; | 170 DVLOG(2) << "Stop() - state: " << state_; |
| 150 DCHECK(task_runner_->BelongsToCurrentThread()); | 171 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 151 | 172 |
| 152 // Invalidate all weak pointers so that pending callbacks won't be fired into | 173 // Invalidate all weak pointers so that pending callbacks won't be fired into |
| 153 // this object. | 174 // this object. |
| 154 weak_factory_.InvalidateWeakPtrs(); | 175 weak_factory_.InvalidateWeakPtrs(); |
| 155 | 176 |
| 156 if (decryptor_) { | 177 if (decryptor_) { |
| 157 decryptor_->DeinitializeDecoder(Decryptor::kAudio); | 178 decryptor_->DeinitializeDecoder(Decryptor::kAudio); |
| 158 decryptor_ = NULL; | 179 decryptor_ = NULL; |
| 159 } | 180 } |
| 160 if (!set_decryptor_ready_cb_.is_null()) | 181 if (!set_decryptor_ready_cb_.is_null()) |
| 161 base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB()); | 182 base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB()); |
| 162 pending_buffer_to_decode_ = NULL; | 183 pending_buffer_to_decode_ = NULL; |
| 163 if (!init_cb_.is_null()) | 184 if (!init_cb_.is_null()) |
| 164 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 185 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
| 165 if (!read_cb_.is_null()) | 186 if (!decode_cb_.is_null()) |
| 166 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 187 base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL); |
| 167 if (!reset_cb_.is_null()) | 188 if (!reset_cb_.is_null()) |
| 168 base::ResetAndReturn(&reset_cb_).Run(); | 189 base::ResetAndReturn(&reset_cb_).Run(); |
| 169 | 190 |
| 170 state_ = kStopped; | 191 state_ = kStopped; |
| 171 task_runner_->PostTask(FROM_HERE, closure); | 192 task_runner_->PostTask(FROM_HERE, closure); |
| 172 } | 193 } |
| 173 | 194 |
| 174 int DecryptingAudioDecoder::bits_per_channel() { | 195 int DecryptingAudioDecoder::bits_per_channel() { |
| 175 DCHECK(task_runner_->BelongsToCurrentThread()); | 196 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 176 return bits_per_channel_; | 197 return bits_per_channel_; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 201 | 222 |
| 202 if (!decryptor) { | 223 if (!decryptor) { |
| 203 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 224 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
| 204 // TODO(xhwang): Add kError state. See http://crbug.com/251503 | 225 // TODO(xhwang): Add kError state. See http://crbug.com/251503 |
| 205 state_ = kStopped; | 226 state_ = kStopped; |
| 206 return; | 227 return; |
| 207 } | 228 } |
| 208 | 229 |
| 209 decryptor_ = decryptor; | 230 decryptor_ = decryptor; |
| 210 | 231 |
| 211 const AudioDecoderConfig& input_config = | 232 config_.Initialize(config_.codec(), |
| 212 demuxer_stream_->audio_decoder_config(); | 233 kSampleFormatS16, |
| 213 AudioDecoderConfig config; | 234 config_.channel_layout(), |
| 214 config.Initialize(input_config.codec(), | 235 config_.samples_per_second(), |
| 215 kSampleFormatS16, | 236 config_.extra_data(), |
| 216 input_config.channel_layout(), | 237 config_.extra_data_size(), |
| 217 input_config.samples_per_second(), | 238 config_.is_encrypted(), |
| 218 input_config.extra_data(), | 239 false, |
| 219 input_config.extra_data_size(), | 240 base::TimeDelta(), |
| 220 input_config.is_encrypted(), | 241 base::TimeDelta()); |
| 221 false, | |
| 222 base::TimeDelta(), | |
| 223 base::TimeDelta()); | |
| 224 | 242 |
| 225 state_ = kPendingDecoderInit; | 243 state_ = kPendingDecoderInit; |
| 226 decryptor_->InitializeAudioDecoder( | 244 decryptor_->InitializeAudioDecoder( |
| 227 config, | 245 config_, |
| 228 BindToCurrentLoop(base::Bind( | 246 BindToCurrentLoop(base::Bind( |
| 229 &DecryptingAudioDecoder::FinishInitialization, weak_this_))); | 247 &DecryptingAudioDecoder::FinishInitialization, weak_this_))); |
| 230 } | 248 } |
| 231 | 249 |
| 232 void DecryptingAudioDecoder::FinishInitialization(bool success) { | 250 void DecryptingAudioDecoder::FinishInitialization(bool success) { |
| 233 DVLOG(2) << "FinishInitialization()"; | 251 DVLOG(2) << "FinishInitialization()"; |
| 234 DCHECK(task_runner_->BelongsToCurrentThread()); | 252 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 235 DCHECK_EQ(state_, kPendingDecoderInit) << state_; | 253 DCHECK(state_ == kPendingDecoderInit || state_ == kPendingConfigChange) |
| 254 << state_; | |
| 236 DCHECK(!init_cb_.is_null()); | 255 DCHECK(!init_cb_.is_null()); |
| 237 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. | 256 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. |
| 238 DCHECK(read_cb_.is_null()); // No Read() before initialization finished. | 257 DCHECK(decode_cb_.is_null()); // No Decode() before initialization finished. |
| 239 | 258 |
| 240 if (!success) { | 259 if (!success) { |
| 241 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 260 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
| 242 state_ = kStopped; | 261 state_ = kStopped; |
| 243 return; | 262 return; |
| 244 } | 263 } |
| 245 | 264 |
| 246 // Success! | 265 // Success! |
| 247 UpdateDecoderConfig(); | 266 UpdateDecoderConfig(); |
| 248 | 267 |
| 249 decryptor_->RegisterNewKeyCB( | 268 decryptor_->RegisterNewKeyCB( |
| 250 Decryptor::kAudio, | 269 Decryptor::kAudio, |
| 251 BindToCurrentLoop( | 270 BindToCurrentLoop( |
| 252 base::Bind(&DecryptingAudioDecoder::OnKeyAdded, weak_this_))); | 271 base::Bind(&DecryptingAudioDecoder::OnKeyAdded, weak_this_))); |
| 253 | 272 |
| 254 state_ = kIdle; | 273 state_ = kIdle; |
| 255 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); | 274 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
| 256 } | 275 } |
| 257 | 276 |
| 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() { | 277 void DecryptingAudioDecoder::DecodePendingBuffer() { |
| 355 DCHECK(task_runner_->BelongsToCurrentThread()); | 278 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 356 DCHECK_EQ(state_, kPendingDecode) << state_; | 279 DCHECK_EQ(state_, kPendingDecode) << state_; |
| 357 | 280 |
| 358 int buffer_size = 0; | 281 int buffer_size = 0; |
| 359 if (!pending_buffer_to_decode_->end_of_stream()) { | 282 if (!pending_buffer_to_decode_->end_of_stream()) { |
| 360 buffer_size = pending_buffer_to_decode_->data_size(); | 283 buffer_size = pending_buffer_to_decode_->data_size(); |
| 361 } | 284 } |
| 362 | 285 |
| 363 decryptor_->DecryptAndDecodeAudio( | 286 decryptor_->DecryptAndDecodeAudio( |
| 364 pending_buffer_to_decode_, | 287 pending_buffer_to_decode_, |
| 365 BindToCurrentLoop(base::Bind( | 288 BindToCurrentLoop(base::Bind( |
| 366 &DecryptingAudioDecoder::DeliverFrame, weak_this_, buffer_size))); | 289 &DecryptingAudioDecoder::DeliverFrame, weak_this_, buffer_size))); |
| 367 } | 290 } |
| 368 | 291 |
| 369 void DecryptingAudioDecoder::DeliverFrame( | 292 void DecryptingAudioDecoder::DeliverFrame( |
| 370 int buffer_size, | 293 int buffer_size, |
| 371 Decryptor::Status status, | 294 Decryptor::Status status, |
| 372 const Decryptor::AudioBuffers& frames) { | 295 const Decryptor::AudioBuffers& frames) { |
| 373 DVLOG(3) << "DeliverFrame() - status: " << status; | 296 DVLOG(3) << "DeliverFrame() - status: " << status; |
| 374 DCHECK(task_runner_->BelongsToCurrentThread()); | 297 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 375 DCHECK_EQ(state_, kPendingDecode) << state_; | 298 DCHECK_EQ(state_, kPendingDecode) << state_; |
| 376 DCHECK(!read_cb_.is_null()); | 299 DCHECK(!decode_cb_.is_null()); |
| 377 DCHECK(pending_buffer_to_decode_.get()); | 300 DCHECK(pending_buffer_to_decode_.get()); |
| 378 DCHECK(queued_audio_frames_.empty()); | 301 DCHECK(queued_audio_frames_.empty()); |
| 379 | 302 |
| 380 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_; | 303 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_; |
| 381 key_added_while_decode_pending_ = false; | 304 key_added_while_decode_pending_ = false; |
| 382 | 305 |
| 383 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode = | 306 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode = |
| 384 pending_buffer_to_decode_; | 307 pending_buffer_to_decode_; |
| 385 pending_buffer_to_decode_ = NULL; | 308 pending_buffer_to_decode_ = NULL; |
| 386 | 309 |
| 387 if (!reset_cb_.is_null()) { | 310 if (!reset_cb_.is_null()) { |
| 388 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); | 311 base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL); |
| 389 DoReset(); | 312 DoReset(); |
| 390 return; | 313 return; |
| 391 } | 314 } |
| 392 | 315 |
| 393 DCHECK_EQ(status == Decryptor::kSuccess, !frames.empty()); | 316 DCHECK_EQ(status == Decryptor::kSuccess, !frames.empty()); |
| 394 | 317 |
| 395 if (status == Decryptor::kError) { | 318 if (status == Decryptor::kError) { |
| 396 DVLOG(2) << "DeliverFrame() - kError"; | 319 DVLOG(2) << "DeliverFrame() - kError"; |
| 397 state_ = kDecodeFinished; | 320 state_ = kDecodeFinished; // TODO add kError state |
| 398 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); | 321 base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL); |
| 399 return; | 322 return; |
| 400 } | 323 } |
| 401 | 324 |
| 402 if (status == Decryptor::kNoKey) { | 325 if (status == Decryptor::kNoKey) { |
| 403 DVLOG(2) << "DeliverFrame() - kNoKey"; | 326 DVLOG(2) << "DeliverFrame() - kNoKey"; |
| 404 // Set |pending_buffer_to_decode_| back as we need to try decoding the | 327 // 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. | 328 // pending buffer again when new key is added to the decryptor. |
| 406 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; | 329 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; |
| 407 | 330 |
| 408 if (need_to_try_again_if_nokey_is_returned) { | 331 if (need_to_try_again_if_nokey_is_returned) { |
| 409 // The |state_| is still kPendingDecode. | 332 // The |state_| is still kPendingDecode. |
| 410 DecodePendingBuffer(); | 333 DecodePendingBuffer(); |
| 411 return; | 334 return; |
| 412 } | 335 } |
| 413 | 336 |
| 414 state_ = kWaitingForKey; | 337 state_ = kWaitingForKey; |
| 415 return; | 338 return; |
| 416 } | 339 } |
| 417 | 340 |
| 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) { | 341 if (status == Decryptor::kNeedMoreData) { |
| 426 DVLOG(2) << "DeliverFrame() - kNeedMoreData"; | 342 DVLOG(2) << "DeliverFrame() - kNeedMoreData"; |
| 427 if (scoped_pending_buffer_to_decode->end_of_stream()) { | 343 if (scoped_pending_buffer_to_decode->end_of_stream()) { |
| 428 state_ = kDecodeFinished; | 344 state_ = kDecodeFinished; |
| 429 base::ResetAndReturn(&read_cb_).Run(kOk, AudioBuffer::CreateEOSBuffer()); | 345 base::ResetAndReturn(&decode_cb_) |
| 346 .Run(kOk, AudioBuffer::CreateEOSBuffer()); | |
| 430 return; | 347 return; |
| 431 } | 348 } |
| 432 | 349 |
| 433 state_ = kPendingDemuxerRead; | 350 state_ = kIdle; |
| 434 ReadFromDemuxerStream(); | 351 base::ResetAndReturn(&decode_cb_).Run(kNotEnoughData, NULL); |
| 435 return; | 352 return; |
| 436 } | 353 } |
| 437 | 354 |
| 438 DCHECK_EQ(status, Decryptor::kSuccess); | 355 DCHECK_EQ(status, Decryptor::kSuccess); |
| 439 DCHECK(!frames.empty()); | 356 DCHECK(!frames.empty()); |
| 440 EnqueueFrames(frames); | 357 EnqueueFrames(frames); |
| 441 | 358 |
| 442 state_ = kIdle; | 359 state_ = kIdle; |
| 443 base::ResetAndReturn(&read_cb_).Run(kOk, queued_audio_frames_.front()); | 360 base::ResetAndReturn(&decode_cb_).Run(kOk, queued_audio_frames_.front()); |
| 444 queued_audio_frames_.pop_front(); | 361 queued_audio_frames_.pop_front(); |
| 445 } | 362 } |
| 446 | 363 |
| 447 void DecryptingAudioDecoder::OnKeyAdded() { | 364 void DecryptingAudioDecoder::OnKeyAdded() { |
| 448 DCHECK(task_runner_->BelongsToCurrentThread()); | 365 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 449 | 366 |
| 450 if (state_ == kPendingDecode) { | 367 if (state_ == kPendingDecode) { |
| 451 key_added_while_decode_pending_ = true; | 368 key_added_while_decode_pending_ = true; |
| 452 return; | 369 return; |
| 453 } | 370 } |
| 454 | 371 |
| 455 if (state_ == kWaitingForKey) { | 372 if (state_ == kWaitingForKey) { |
| 456 state_ = kPendingDecode; | 373 state_ = kPendingDecode; |
| 457 DecodePendingBuffer(); | 374 DecodePendingBuffer(); |
| 458 } | 375 } |
| 459 } | 376 } |
| 460 | 377 |
| 461 void DecryptingAudioDecoder::DoReset() { | 378 void DecryptingAudioDecoder::DoReset() { |
| 462 DCHECK(init_cb_.is_null()); | 379 DCHECK(init_cb_.is_null()); |
| 463 DCHECK(read_cb_.is_null()); | 380 DCHECK(decode_cb_.is_null()); |
| 464 timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); | 381 timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); |
| 465 state_ = kIdle; | 382 state_ = kIdle; |
| 466 base::ResetAndReturn(&reset_cb_).Run(); | 383 base::ResetAndReturn(&reset_cb_).Run(); |
| 467 } | 384 } |
| 468 | 385 |
| 469 void DecryptingAudioDecoder::UpdateDecoderConfig() { | 386 void DecryptingAudioDecoder::UpdateDecoderConfig() { |
| 470 const AudioDecoderConfig& config = demuxer_stream_->audio_decoder_config(); | |
| 471 bits_per_channel_ = kSupportedBitsPerChannel; | 387 bits_per_channel_ = kSupportedBitsPerChannel; |
| 472 channel_layout_ = config.channel_layout(); | 388 channel_layout_ = config_.channel_layout(); |
| 473 samples_per_second_ = config.samples_per_second(); | 389 samples_per_second_ = config_.samples_per_second(); |
| 474 timestamp_helper_.reset(new AudioTimestampHelper(samples_per_second_)); | 390 timestamp_helper_.reset(new AudioTimestampHelper(samples_per_second_)); |
| 475 } | 391 } |
| 476 | 392 |
| 477 void DecryptingAudioDecoder::EnqueueFrames( | 393 void DecryptingAudioDecoder::EnqueueFrames( |
| 478 const Decryptor::AudioBuffers& frames) { | 394 const Decryptor::AudioBuffers& frames) { |
| 479 queued_audio_frames_ = frames; | 395 queued_audio_frames_ = frames; |
| 480 | 396 |
| 481 for (Decryptor::AudioBuffers::iterator iter = queued_audio_frames_.begin(); | 397 for (Decryptor::AudioBuffers::iterator iter = queued_audio_frames_.begin(); |
| 482 iter != queued_audio_frames_.end(); | 398 iter != queued_audio_frames_.end(); |
| 483 ++iter) { | 399 ++iter) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 495 } | 411 } |
| 496 | 412 |
| 497 frame->set_timestamp(current_time); | 413 frame->set_timestamp(current_time); |
| 498 frame->set_duration( | 414 frame->set_duration( |
| 499 timestamp_helper_->GetFrameDuration(frame->frame_count())); | 415 timestamp_helper_->GetFrameDuration(frame->frame_count())); |
| 500 timestamp_helper_->AddFrames(frame->frame_count()); | 416 timestamp_helper_->AddFrames(frame->frame_count()); |
| 501 } | 417 } |
| 502 } | 418 } |
| 503 | 419 |
| 504 } // namespace media | 420 } // namespace media |
| OLD | NEW |