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 |