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

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

Issue 331863004: Revert 276344 "Add callback in VideoDecoder and AudioDecoder to ..." (Closed) Base URL: svn://svn.chromium.org/chrome/branches/2049/src/
Patch Set: Created 6 years, 6 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 27 matching lines...) Expand all
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 state_(kUninitialized), 41 state_(kUninitialized),
42 set_decryptor_ready_cb_(set_decryptor_ready_cb), 42 set_decryptor_ready_cb_(set_decryptor_ready_cb),
43 decryptor_(NULL), 43 decryptor_(NULL),
44 key_added_while_decode_pending_(false), 44 key_added_while_decode_pending_(false),
45 weak_factory_(this) {} 45 weak_factory_(this) {}
46 46
47 void DecryptingAudioDecoder::Initialize(const AudioDecoderConfig& config, 47 void DecryptingAudioDecoder::Initialize(const AudioDecoderConfig& config,
48 const PipelineStatusCB& status_cb, 48 const PipelineStatusCB& status_cb) {
49 const OutputCB& output_cb) {
50 DVLOG(2) << "Initialize()"; 49 DVLOG(2) << "Initialize()";
51 DCHECK(task_runner_->BelongsToCurrentThread()); 50 DCHECK(task_runner_->BelongsToCurrentThread());
52 DCHECK(decode_cb_.is_null()); 51 DCHECK(decode_cb_.is_null());
53 DCHECK(reset_cb_.is_null()); 52 DCHECK(reset_cb_.is_null());
54 53
55 weak_this_ = weak_factory_.GetWeakPtr(); 54 weak_this_ = weak_factory_.GetWeakPtr();
56 init_cb_ = BindToCurrentLoop(status_cb); 55 init_cb_ = BindToCurrentLoop(status_cb);
57 output_cb_ = BindToCurrentLoop(output_cb);
58 56
59 if (!config.IsValidConfig()) { 57 if (!config.IsValidConfig()) {
60 DLOG(ERROR) << "Invalid audio stream config."; 58 DLOG(ERROR) << "Invalid audio stream config.";
61 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_DECODE); 59 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_DECODE);
62 return; 60 return;
63 } 61 }
64 62
65 // DecryptingAudioDecoder only accepts potentially encrypted stream. 63 // DecryptingAudioDecoder only accepts potentially encrypted stream.
66 if (!config.is_encrypted()) { 64 if (!config.is_encrypted()) {
67 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 65 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
(...skipping 19 matching lines...) Expand all
87 DVLOG(3) << "Decode()"; 85 DVLOG(3) << "Decode()";
88 DCHECK(task_runner_->BelongsToCurrentThread()); 86 DCHECK(task_runner_->BelongsToCurrentThread());
89 DCHECK(state_ == kIdle || state_ == kDecodeFinished) << state_; 87 DCHECK(state_ == kIdle || state_ == kDecodeFinished) << state_;
90 DCHECK(!decode_cb.is_null()); 88 DCHECK(!decode_cb.is_null());
91 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported."; 89 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported.";
92 90
93 decode_cb_ = BindToCurrentLoop(decode_cb); 91 decode_cb_ = BindToCurrentLoop(decode_cb);
94 92
95 // Return empty (end-of-stream) frames if decoding has finished. 93 // Return empty (end-of-stream) frames if decoding has finished.
96 if (state_ == kDecodeFinished) { 94 if (state_ == kDecodeFinished) {
97 output_cb_.Run(AudioBuffer::CreateEOSBuffer()); 95 base::ResetAndReturn(&decode_cb_).Run(kOk, AudioBuffer::CreateEOSBuffer());
98 base::ResetAndReturn(&decode_cb_).Run(kOk); 96 return;
97 }
98
99 if (!queued_audio_frames_.empty()) {
100 DCHECK(!buffer);
101 base::ResetAndReturn(&decode_cb_).Run(kOk, queued_audio_frames_.front());
102 queued_audio_frames_.pop_front();
99 return; 103 return;
100 } 104 }
101 105
102 // Initialize the |next_output_timestamp_| to be the timestamp of the first 106 // Initialize the |next_output_timestamp_| to be the timestamp of the first
103 // non-EOS buffer. 107 // non-EOS buffer.
104 if (timestamp_helper_->base_timestamp() == kNoTimestamp() && 108 if (timestamp_helper_->base_timestamp() == kNoTimestamp() &&
105 !buffer->end_of_stream()) { 109 !buffer->end_of_stream()) {
106 timestamp_helper_->SetBaseTimestamp(buffer->timestamp()); 110 timestamp_helper_->SetBaseTimestamp(buffer->timestamp());
107 } 111 }
108 112
109 pending_buffer_to_decode_ = buffer; 113 pending_buffer_to_decode_ = buffer;
110 state_ = kPendingDecode; 114 state_ = kPendingDecode;
111 DecodePendingBuffer(); 115 DecodePendingBuffer();
112 } 116 }
113 117
118 scoped_refptr<AudioBuffer> DecryptingAudioDecoder::GetDecodeOutput() {
119 if (queued_audio_frames_.empty())
120 return NULL;
121 scoped_refptr<AudioBuffer> out = queued_audio_frames_.front();
122 queued_audio_frames_.pop_front();
123 return out;
124 }
125
114 void DecryptingAudioDecoder::Reset(const base::Closure& closure) { 126 void DecryptingAudioDecoder::Reset(const base::Closure& closure) {
115 DVLOG(2) << "Reset() - state: " << state_; 127 DVLOG(2) << "Reset() - state: " << state_;
116 DCHECK(task_runner_->BelongsToCurrentThread()); 128 DCHECK(task_runner_->BelongsToCurrentThread());
117 DCHECK(state_ == kIdle || 129 DCHECK(state_ == kIdle ||
118 state_ == kPendingDecode || 130 state_ == kPendingDecode ||
119 state_ == kWaitingForKey || 131 state_ == kWaitingForKey ||
120 state_ == kDecodeFinished) << state_; 132 state_ == kDecodeFinished) << state_;
121 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. 133 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization.
122 DCHECK(reset_cb_.is_null()); 134 DCHECK(reset_cb_.is_null());
123 135
124 reset_cb_ = BindToCurrentLoop(closure); 136 reset_cb_ = BindToCurrentLoop(closure);
125 137
126 decryptor_->ResetDecoder(Decryptor::kAudio); 138 decryptor_->ResetDecoder(Decryptor::kAudio);
127 139
128 // Reset() cannot complete if the read callback is still pending. 140 // Reset() cannot complete if the read callback is still pending.
129 // Defer the resetting process in this case. The |reset_cb_| will be fired 141 // Defer the resetting process in this case. The |reset_cb_| will be fired
130 // after the read callback is fired - see DecryptAndDecodeBuffer() and 142 // after the read callback is fired - see DecryptAndDecodeBuffer() and
131 // DeliverFrame(). 143 // DeliverFrame().
132 if (state_ == kPendingDecode) { 144 if (state_ == kPendingDecode) {
133 DCHECK(!decode_cb_.is_null()); 145 DCHECK(!decode_cb_.is_null());
134 return; 146 return;
135 } 147 }
136 148
137 if (state_ == kWaitingForKey) { 149 if (state_ == kWaitingForKey) {
138 DCHECK(!decode_cb_.is_null()); 150 DCHECK(!decode_cb_.is_null());
139 pending_buffer_to_decode_ = NULL; 151 pending_buffer_to_decode_ = NULL;
140 base::ResetAndReturn(&decode_cb_).Run(kAborted); 152 base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL);
141 } 153 }
142 154
143 DCHECK(decode_cb_.is_null()); 155 DCHECK(decode_cb_.is_null());
144 DoReset(); 156 DoReset();
145 } 157 }
146 158
147 void DecryptingAudioDecoder::Stop() { 159 void DecryptingAudioDecoder::Stop() {
148 DVLOG(2) << "Stop() - state: " << state_; 160 DVLOG(2) << "Stop() - state: " << state_;
149 DCHECK(task_runner_->BelongsToCurrentThread()); 161 DCHECK(task_runner_->BelongsToCurrentThread());
150 162
151 // Invalidate all weak pointers so that pending callbacks won't be fired into 163 // Invalidate all weak pointers so that pending callbacks won't be fired into
152 // this object. 164 // this object.
153 weak_factory_.InvalidateWeakPtrs(); 165 weak_factory_.InvalidateWeakPtrs();
154 166
155 if (decryptor_) { 167 if (decryptor_) {
156 decryptor_->DeinitializeDecoder(Decryptor::kAudio); 168 decryptor_->DeinitializeDecoder(Decryptor::kAudio);
157 decryptor_ = NULL; 169 decryptor_ = NULL;
158 } 170 }
159 if (!set_decryptor_ready_cb_.is_null()) 171 if (!set_decryptor_ready_cb_.is_null())
160 base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB()); 172 base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB());
161 pending_buffer_to_decode_ = NULL; 173 pending_buffer_to_decode_ = NULL;
162 if (!init_cb_.is_null()) 174 if (!init_cb_.is_null())
163 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 175 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
164 if (!decode_cb_.is_null()) 176 if (!decode_cb_.is_null())
165 base::ResetAndReturn(&decode_cb_).Run(kAborted); 177 base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL);
166 if (!reset_cb_.is_null()) 178 if (!reset_cb_.is_null())
167 base::ResetAndReturn(&reset_cb_).Run(); 179 base::ResetAndReturn(&reset_cb_).Run();
168 180
169 state_ = kStopped; 181 state_ = kStopped;
170 } 182 }
171 183
172 DecryptingAudioDecoder::~DecryptingAudioDecoder() { 184 DecryptingAudioDecoder::~DecryptingAudioDecoder() {
173 DCHECK(state_ == kUninitialized || state_ == kStopped) << state_; 185 DCHECK(state_ == kUninitialized || state_ == kStopped) << state_;
174 } 186 }
175 187
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 258
247 void DecryptingAudioDecoder::DeliverFrame( 259 void DecryptingAudioDecoder::DeliverFrame(
248 int buffer_size, 260 int buffer_size,
249 Decryptor::Status status, 261 Decryptor::Status status,
250 const Decryptor::AudioBuffers& frames) { 262 const Decryptor::AudioBuffers& frames) {
251 DVLOG(3) << "DeliverFrame() - status: " << status; 263 DVLOG(3) << "DeliverFrame() - status: " << status;
252 DCHECK(task_runner_->BelongsToCurrentThread()); 264 DCHECK(task_runner_->BelongsToCurrentThread());
253 DCHECK_EQ(state_, kPendingDecode) << state_; 265 DCHECK_EQ(state_, kPendingDecode) << state_;
254 DCHECK(!decode_cb_.is_null()); 266 DCHECK(!decode_cb_.is_null());
255 DCHECK(pending_buffer_to_decode_.get()); 267 DCHECK(pending_buffer_to_decode_.get());
268 DCHECK(queued_audio_frames_.empty());
256 269
257 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_; 270 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_;
258 key_added_while_decode_pending_ = false; 271 key_added_while_decode_pending_ = false;
259 272
260 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode = 273 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode =
261 pending_buffer_to_decode_; 274 pending_buffer_to_decode_;
262 pending_buffer_to_decode_ = NULL; 275 pending_buffer_to_decode_ = NULL;
263 276
264 if (!reset_cb_.is_null()) { 277 if (!reset_cb_.is_null()) {
265 base::ResetAndReturn(&decode_cb_).Run(kAborted); 278 base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL);
266 DoReset(); 279 DoReset();
267 return; 280 return;
268 } 281 }
269 282
270 DCHECK_EQ(status == Decryptor::kSuccess, !frames.empty()); 283 DCHECK_EQ(status == Decryptor::kSuccess, !frames.empty());
271 284
272 if (status == Decryptor::kError) { 285 if (status == Decryptor::kError) {
273 DVLOG(2) << "DeliverFrame() - kError"; 286 DVLOG(2) << "DeliverFrame() - kError";
274 state_ = kDecodeFinished; // TODO add kError state 287 state_ = kDecodeFinished; // TODO add kError state
275 base::ResetAndReturn(&decode_cb_).Run(kDecodeError); 288 base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL);
276 return; 289 return;
277 } 290 }
278 291
279 if (status == Decryptor::kNoKey) { 292 if (status == Decryptor::kNoKey) {
280 DVLOG(2) << "DeliverFrame() - kNoKey"; 293 DVLOG(2) << "DeliverFrame() - kNoKey";
281 // Set |pending_buffer_to_decode_| back as we need to try decoding the 294 // Set |pending_buffer_to_decode_| back as we need to try decoding the
282 // pending buffer again when new key is added to the decryptor. 295 // pending buffer again when new key is added to the decryptor.
283 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; 296 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode;
284 297
285 if (need_to_try_again_if_nokey_is_returned) { 298 if (need_to_try_again_if_nokey_is_returned) {
286 // The |state_| is still kPendingDecode. 299 // The |state_| is still kPendingDecode.
287 DecodePendingBuffer(); 300 DecodePendingBuffer();
288 return; 301 return;
289 } 302 }
290 303
291 state_ = kWaitingForKey; 304 state_ = kWaitingForKey;
292 return; 305 return;
293 } 306 }
294 307
295 if (status == Decryptor::kNeedMoreData) { 308 if (status == Decryptor::kNeedMoreData) {
296 DVLOG(2) << "DeliverFrame() - kNeedMoreData"; 309 DVLOG(2) << "DeliverFrame() - kNeedMoreData";
297 if (scoped_pending_buffer_to_decode->end_of_stream()) { 310 if (scoped_pending_buffer_to_decode->end_of_stream()) {
298 state_ = kDecodeFinished; 311 state_ = kDecodeFinished;
299 output_cb_.Run(AudioBuffer::CreateEOSBuffer()); 312 base::ResetAndReturn(&decode_cb_)
300 base::ResetAndReturn(&decode_cb_).Run(kOk); 313 .Run(kOk, AudioBuffer::CreateEOSBuffer());
301 return; 314 return;
302 } 315 }
303 316
304 state_ = kIdle; 317 state_ = kIdle;
305 base::ResetAndReturn(&decode_cb_).Run(kOk); 318 base::ResetAndReturn(&decode_cb_).Run(kNotEnoughData, NULL);
306 return; 319 return;
307 } 320 }
308 321
309 DCHECK_EQ(status, Decryptor::kSuccess); 322 DCHECK_EQ(status, Decryptor::kSuccess);
310 DCHECK(!frames.empty()); 323 DCHECK(!frames.empty());
311 ProcessDecodedFrames(frames); 324 EnqueueFrames(frames);
312 325
313 state_ = kIdle; 326 state_ = kIdle;
314 base::ResetAndReturn(&decode_cb_).Run(kOk); 327 base::ResetAndReturn(&decode_cb_).Run(kOk, queued_audio_frames_.front());
328 queued_audio_frames_.pop_front();
315 } 329 }
316 330
317 void DecryptingAudioDecoder::OnKeyAdded() { 331 void DecryptingAudioDecoder::OnKeyAdded() {
318 DCHECK(task_runner_->BelongsToCurrentThread()); 332 DCHECK(task_runner_->BelongsToCurrentThread());
319 333
320 if (state_ == kPendingDecode) { 334 if (state_ == kPendingDecode) {
321 key_added_while_decode_pending_ = true; 335 key_added_while_decode_pending_ = true;
322 return; 336 return;
323 } 337 }
324 338
325 if (state_ == kWaitingForKey) { 339 if (state_ == kWaitingForKey) {
326 state_ = kPendingDecode; 340 state_ = kPendingDecode;
327 DecodePendingBuffer(); 341 DecodePendingBuffer();
328 } 342 }
329 } 343 }
330 344
331 void DecryptingAudioDecoder::DoReset() { 345 void DecryptingAudioDecoder::DoReset() {
332 DCHECK(init_cb_.is_null()); 346 DCHECK(init_cb_.is_null());
333 DCHECK(decode_cb_.is_null()); 347 DCHECK(decode_cb_.is_null());
334 timestamp_helper_->SetBaseTimestamp(kNoTimestamp()); 348 timestamp_helper_->SetBaseTimestamp(kNoTimestamp());
335 state_ = kIdle; 349 state_ = kIdle;
336 base::ResetAndReturn(&reset_cb_).Run(); 350 base::ResetAndReturn(&reset_cb_).Run();
337 } 351 }
338 352
339 void DecryptingAudioDecoder::ProcessDecodedFrames( 353 void DecryptingAudioDecoder::EnqueueFrames(
340 const Decryptor::AudioBuffers& frames) { 354 const Decryptor::AudioBuffers& frames) {
341 for (Decryptor::AudioBuffers::const_iterator iter = frames.begin(); 355 queued_audio_frames_ = frames;
342 iter != frames.end(); 356
357 for (Decryptor::AudioBuffers::iterator iter = queued_audio_frames_.begin();
358 iter != queued_audio_frames_.end();
343 ++iter) { 359 ++iter) {
344 scoped_refptr<AudioBuffer> frame = *iter; 360 scoped_refptr<AudioBuffer>& frame = *iter;
345 361
346 DCHECK(!frame->end_of_stream()) << "EOS frame returned."; 362 DCHECK(!frame->end_of_stream()) << "EOS frame returned.";
347 DCHECK_GT(frame->frame_count(), 0) << "Empty frame returned."; 363 DCHECK_GT(frame->frame_count(), 0) << "Empty frame returned.";
348 364
349 base::TimeDelta current_time = timestamp_helper_->GetTimestamp(); 365 base::TimeDelta current_time = timestamp_helper_->GetTimestamp();
350 if (IsOutOfSync(current_time, frame->timestamp())) { 366 if (IsOutOfSync(current_time, frame->timestamp())) {
351 DVLOG(1) << "Timestamp returned by the decoder (" 367 DVLOG(1) << "Timestamp returned by the decoder ("
352 << frame->timestamp().InMilliseconds() << " ms)" 368 << frame->timestamp().InMilliseconds() << " ms)"
353 << " does not match the input timestamp and number of samples" 369 << " does not match the input timestamp and number of samples"
354 << " decoded (" << current_time.InMilliseconds() << " ms)."; 370 << " decoded (" << current_time.InMilliseconds() << " ms).";
355 } 371 }
356 372
357 frame->set_timestamp(current_time); 373 frame->set_timestamp(current_time);
358 timestamp_helper_->AddFrames(frame->frame_count()); 374 timestamp_helper_->AddFrames(frame->frame_count());
359
360 output_cb_.Run(frame);
361 } 375 }
362 } 376 }
363 377
364 } // namespace media 378 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/decrypting_audio_decoder.h ('k') | media/filters/decrypting_audio_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698