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

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

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

Powered by Google App Engine
This is Rietveld 408576698