Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: media/filters/decrypting_audio_decoder.cc

Issue 11787012: Encrypted Media: Add config change support in DecryptingAudioDecoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 72
73 void DecryptingAudioDecoder::Reset(const base::Closure& closure) { 73 void DecryptingAudioDecoder::Reset(const base::Closure& closure) {
74 if (!message_loop_->BelongsToCurrentThread()) { 74 if (!message_loop_->BelongsToCurrentThread()) {
75 message_loop_->PostTask(FROM_HERE, base::Bind( 75 message_loop_->PostTask(FROM_HERE, base::Bind(
76 &DecryptingAudioDecoder::Reset, this, closure)); 76 &DecryptingAudioDecoder::Reset, this, closure));
77 return; 77 return;
78 } 78 }
79 79
80 DVLOG(2) << "Reset() - state: " << state_; 80 DVLOG(2) << "Reset() - state: " << state_;
81 DCHECK(state_ == kIdle || 81 DCHECK(state_ == kIdle ||
82 state_ == kPendingConfigChange ||
82 state_ == kPendingDemuxerRead || 83 state_ == kPendingDemuxerRead ||
83 state_ == kPendingDecode || 84 state_ == kPendingDecode ||
84 state_ == kWaitingForKey || 85 state_ == kWaitingForKey ||
85 state_ == kDecodeFinished) << state_; 86 state_ == kDecodeFinished) << state_;
86 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. 87 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization.
87 DCHECK(reset_cb_.is_null()); 88 DCHECK(reset_cb_.is_null());
88 89
89 reset_cb_ = closure; 90 reset_cb_ = closure;
90 91
91 decryptor_->ResetDecoder(Decryptor::kAudio); 92 decryptor_->ResetDecoder(Decryptor::kAudio);
92 93
93 // Reset() cannot complete if the read callback is still pending. 94 // Reset() cannot complete if the read callback is still pending.
94 // Defer the resetting process in this case. The |reset_cb_| will be fired 95 // Defer the resetting process in this case. The |reset_cb_| will be fired
95 // after the read callback is fired - see DoDecryptAndDecodeBuffer() and 96 // after the read callback is fired - see DoDecryptAndDecodeBuffer() and
96 // DoDeliverFrame(). 97 // DoDeliverFrame().
97 if (state_ == kPendingDemuxerRead || state_ == kPendingDecode) { 98 if (state_ == kPendingConfigChange ||
99 state_ == kPendingDemuxerRead ||
100 state_ == kPendingDecode) {
98 DCHECK(!read_cb_.is_null()); 101 DCHECK(!read_cb_.is_null());
99 return; 102 return;
100 } 103 }
101 104
102 if (state_ == kWaitingForKey) { 105 if (state_ == kWaitingForKey) {
103 DCHECK(!read_cb_.is_null()); 106 DCHECK(!read_cb_.is_null());
104 pending_buffer_to_decode_ = NULL; 107 pending_buffer_to_decode_ = NULL;
105 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); 108 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
106 } 109 }
107 110
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 bytes_per_sample_ = ChannelLayoutToChannelCount(channel_layout_) * 202 bytes_per_sample_ = ChannelLayoutToChannelCount(channel_layout_) *
200 bits_per_channel_ / kBitsPerByte; 203 bits_per_channel_ / kBitsPerByte;
201 204
202 decryptor_->RegisterNewKeyCB( 205 decryptor_->RegisterNewKeyCB(
203 Decryptor::kAudio, BIND_TO_LOOP(&DecryptingAudioDecoder::OnKeyAdded)); 206 Decryptor::kAudio, BIND_TO_LOOP(&DecryptingAudioDecoder::OnKeyAdded));
204 207
205 state_ = kIdle; 208 state_ = kIdle;
206 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 209 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
207 } 210 }
208 211
212 void DecryptingAudioDecoder::FinishConfigChange(bool success) {
213 DVLOG(2) << "FinishConfigChange()";
214 DCHECK(message_loop_->BelongsToCurrentThread());
215 DCHECK_EQ(state_, kPendingConfigChange) << state_;
216 DCHECK(!read_cb_.is_null());
217
218 if (!success) {
219 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
220 state_ = kDecodeFinished;
221 if (!reset_cb_.is_null())
222 base::ResetAndReturn(&reset_cb_).Run();
223 return;
224 }
225
226 // Config change succeeded.
227 if (!reset_cb_.is_null()) {
228 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
229 DoReset();
230 return;
231 }
232
233 state_ = kPendingDemuxerRead;
234 ReadFromDemuxerStream();
235 }
236
209 void DecryptingAudioDecoder::DoRead(const ReadCB& read_cb) { 237 void DecryptingAudioDecoder::DoRead(const ReadCB& read_cb) {
210 DVLOG(3) << "DoRead()"; 238 DVLOG(3) << "DoRead()";
211 DCHECK(message_loop_->BelongsToCurrentThread()); 239 DCHECK(message_loop_->BelongsToCurrentThread());
212 DCHECK(state_ == kIdle || state_ == kDecodeFinished) << state_; 240 DCHECK(state_ == kIdle || state_ == kDecodeFinished) << state_;
213 DCHECK(!read_cb.is_null()); 241 DCHECK(!read_cb.is_null());
214 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported."; 242 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported.";
215 243
216 // Return empty (end-of-stream) frames if decoding has finished. 244 // Return empty (end-of-stream) frames if decoding has finished.
217 if (state_ == kDecodeFinished) { 245 if (state_ == kDecodeFinished) {
218 read_cb.Run(kOk, scoped_refptr<Buffer>(new DataBuffer(0))); 246 read_cb.Run(kOk, scoped_refptr<Buffer>(new DataBuffer(0)));
(...skipping 28 matching lines...) Expand all
247 &DecryptingAudioDecoder::DoDecryptAndDecodeBuffer, this, 275 &DecryptingAudioDecoder::DoDecryptAndDecodeBuffer, this,
248 status, buffer)); 276 status, buffer));
249 return; 277 return;
250 } 278 }
251 279
252 DVLOG(3) << "DoDecryptAndDecodeBuffer()"; 280 DVLOG(3) << "DoDecryptAndDecodeBuffer()";
253 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; 281 DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
254 DCHECK(!read_cb_.is_null()); 282 DCHECK(!read_cb_.is_null());
255 DCHECK_EQ(buffer != NULL, status == DemuxerStream::kOk) << status; 283 DCHECK_EQ(buffer != NULL, status == DemuxerStream::kOk) << status;
256 284
285 if (status == DemuxerStream::kConfigChanged) {
286 DVLOG(2) << "DoDecryptAndDecodeBuffer() - kConfigChanged";
287
288 scoped_ptr<AudioDecoderConfig> scoped_config(new AudioDecoderConfig());
289 scoped_config->CopyFrom(demuxer_stream_->audio_decoder_config());
290
291 state_ = kPendingConfigChange;
292 decryptor_->DeinitializeDecoder(Decryptor::kAudio);
293 decryptor_->InitializeAudioDecoder(
acolwell GONE FROM CHROMIUM 2013/01/05 01:25:30 same comment for this method as in the other CL. :
xhwang 2013/01/05 04:09:24 :) will think about it more and probably do it in
294 scoped_config.Pass(), BindToCurrentLoop(base::Bind(
295 &DecryptingAudioDecoder::FinishConfigChange, this)));
296 return;
297 }
298
257 if (!reset_cb_.is_null()) { 299 if (!reset_cb_.is_null()) {
258 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); 300 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
259 DoReset(); 301 DoReset();
260 return; 302 return;
261 } 303 }
262 304
263 if (status == DemuxerStream::kAborted) { 305 if (status == DemuxerStream::kAborted) {
264 DVLOG(2) << "DoDecryptAndDecodeBuffer() - kAborted"; 306 DVLOG(2) << "DoDecryptAndDecodeBuffer() - kAborted";
265 state_ = kIdle; 307 state_ = kIdle;
266 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL); 308 base::ResetAndReturn(&read_cb_).Run(kAborted, NULL);
267 return; 309 return;
268 } 310 }
269 311
270 if (status == DemuxerStream::kConfigChanged) {
271 // TODO(xhwang): Add config change support.
272 // The |state_| is chosen to be kDecodeFinished here to be consistent with
273 // the implementation of FFmpegVideoDecoder.
274 DVLOG(2) << "DoDecryptAndDecodeBuffer() - kConfigChanged";
275 state_ = kDecodeFinished;
276 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
277 return;
278 }
279
280 DCHECK_EQ(status, DemuxerStream::kOk); 312 DCHECK_EQ(status, DemuxerStream::kOk);
281 313
282 // Initialize the |next_output_timestamp_| to be the timestamp of the first 314 // Initialize the |next_output_timestamp_| to be the timestamp of the first
283 // non-EOS buffer. 315 // non-EOS buffer.
284 if (output_timestamp_base_ == kNoTimestamp() && !buffer->IsEndOfStream()) { 316 if (output_timestamp_base_ == kNoTimestamp() && !buffer->IsEndOfStream()) {
285 DCHECK_EQ(total_samples_decoded_, 0); 317 DCHECK_EQ(total_samples_decoded_, 0);
286 output_timestamp_base_ = buffer->GetTimestamp(); 318 output_timestamp_base_ = buffer->GetTimestamp();
287 } 319 }
288 320
289 pending_buffer_to_decode_ = buffer; 321 pending_buffer_to_decode_ = buffer;
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 484
453 base::TimeDelta DecryptingAudioDecoder::NumberOfSamplesToDuration( 485 base::TimeDelta DecryptingAudioDecoder::NumberOfSamplesToDuration(
454 int number_of_samples) const { 486 int number_of_samples) const {
455 DCHECK(samples_per_second_); 487 DCHECK(samples_per_second_);
456 return base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond * 488 return base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond *
457 number_of_samples / 489 number_of_samples /
458 samples_per_second_); 490 samples_per_second_);
459 } 491 }
460 492
461 } // namespace media 493 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698