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

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

Issue 339653003: No EOS frame in {Audio|Video}Decoder::OutputCB. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/decoder_stream.h" 5 #include "media/filters/decoder_stream.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/location.h" 10 #include "base/location.h"
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, 82 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected,
83 weak_factory_.GetWeakPtr()), 83 weak_factory_.GetWeakPtr()),
84 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, 84 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
85 weak_factory_.GetWeakPtr())); 85 weak_factory_.GetWeakPtr()));
86 } 86 }
87 87
88 template <DemuxerStream::Type StreamType> 88 template <DemuxerStream::Type StreamType>
89 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { 89 void DecoderStream<StreamType>::Read(const ReadCB& read_cb) {
90 FUNCTION_DVLOG(2); 90 FUNCTION_DVLOG(2);
91 DCHECK(task_runner_->BelongsToCurrentThread()); 91 DCHECK(task_runner_->BelongsToCurrentThread());
92 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 92 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING &&
93 state_ == STATE_ERROR || state_ == STATE_REINITIALIZING_DECODER || 93 state_ != STATE_STOPPED) << state_;
94 state_ == STATE_PENDING_DEMUXER_READ)
95 << state_;
96 // No two reads in the flight at any time. 94 // No two reads in the flight at any time.
97 DCHECK(read_cb_.is_null()); 95 DCHECK(read_cb_.is_null());
98 // No read during resetting or stopping process. 96 // No read during resetting or stopping process.
99 DCHECK(reset_cb_.is_null()); 97 DCHECK(reset_cb_.is_null());
100 DCHECK(stop_cb_.is_null()); 98 DCHECK(stop_cb_.is_null());
101 99
102 read_cb_ = read_cb; 100 if (state_ == STATE_ERROR) {
101 task_runner_->PostTask(
102 FROM_HERE, base::Bind(read_cb, DECODE_ERROR, scoped_refptr<Output>()));
103 return;
104 }
103 105
104 if (state_ == STATE_ERROR) { 106 if (state_ == STATE_END_OF_STREAM && ready_outputs_.empty()) {
105 task_runner_->PostTask(FROM_HERE, 107 task_runner_->PostTask(
106 base::Bind(base::ResetAndReturn(&read_cb_), 108 FROM_HERE, base::Bind(read_cb, OK, StreamTraits::CreateEOSOutput()));
107 DECODE_ERROR,
108 scoped_refptr<Output>()));
109 return; 109 return;
110 } 110 }
111 111
112 if (!ready_outputs_.empty()) { 112 if (!ready_outputs_.empty()) {
113 task_runner_->PostTask(FROM_HERE, base::Bind( 113 task_runner_->PostTask(FROM_HERE,
114 base::ResetAndReturn(&read_cb_), OK, ready_outputs_.front())); 114 base::Bind(read_cb, OK, ready_outputs_.front()));
115 ready_outputs_.pop_front(); 115 ready_outputs_.pop_front();
116 } else {
117 read_cb_ = read_cb;
116 } 118 }
117 119
118 if (state_ == STATE_NORMAL && CanDecodeMore()) 120 if (state_ == STATE_NORMAL && CanDecodeMore())
119 ReadFromDemuxerStream(); 121 ReadFromDemuxerStream();
120 } 122 }
121 123
122 template <DemuxerStream::Type StreamType> 124 template <DemuxerStream::Type StreamType>
123 void DecoderStream<StreamType>::Reset(const base::Closure& closure) { 125 void DecoderStream<StreamType>::Reset(const base::Closure& closure) {
124 FUNCTION_DVLOG(2); 126 FUNCTION_DVLOG(2);
125 DCHECK(task_runner_->BelongsToCurrentThread()); 127 DCHECK(task_runner_->BelongsToCurrentThread());
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 if (!reset_cb_.is_null()) 332 if (!reset_cb_.is_null())
331 return; 333 return;
332 334
333 switch (status) { 335 switch (status) {
334 case Decoder::kDecodeError: 336 case Decoder::kDecodeError:
335 case Decoder::kDecryptError: 337 case Decoder::kDecryptError:
336 state_ = STATE_ERROR; 338 state_ = STATE_ERROR;
337 ready_outputs_.clear(); 339 ready_outputs_.clear();
338 if (!read_cb_.is_null()) 340 if (!read_cb_.is_null())
339 SatisfyRead(DECODE_ERROR, NULL); 341 SatisfyRead(DECODE_ERROR, NULL);
340 break; 342 return;
341 343
342 case Decoder::kAborted: 344 case Decoder::kAborted:
343 // Decoder can return kAborted only when Reset is pending. 345 // Decoder can return kAborted only when Reset is pending.
344 NOTREACHED(); 346 NOTREACHED();
345 break; 347 return;
346 348
347 case Decoder::kOk: 349 case Decoder::kOk:
348 // Any successful decode counts! 350 // Any successful decode counts!
349 if (buffer_size > 0) { 351 if (buffer_size > 0)
350 StreamTraits::ReportStatistics(statistics_cb_, buffer_size); 352 StreamTraits::ReportStatistics(statistics_cb_, buffer_size);
353
354 if (state_ == STATE_NORMAL) {
355 if (end_of_stream) {
356 state_ = STATE_END_OF_STREAM;
357 if (ready_outputs_.empty() && !read_cb_.is_null())
358 SatisfyRead(OK, StreamTraits::CreateEOSOutput());
359 return;
360 }
361
362 if (CanDecodeMore())
363 ReadFromDemuxerStream();
364 return;
351 } 365 }
352 366
353 if (state_ == STATE_NORMAL) { 367 if (state_ == STATE_FLUSHING_DECODER && !pending_decode_requests_)
354 if (CanDecodeMore() && !end_of_stream) 368 ReinitializeDecoder();
355 ReadFromDemuxerStream(); 369 return;
356 } else if (state_ == STATE_FLUSHING_DECODER) {
357 if (!pending_decode_requests_)
358 ReinitializeDecoder();
359 }
360 break;
361 } 370 }
362 } 371 }
363 372
364 template <DemuxerStream::Type StreamType> 373 template <DemuxerStream::Type StreamType>
365 void DecoderStream<StreamType>::OnDecodeOutputReady( 374 void DecoderStream<StreamType>::OnDecodeOutputReady(
366 const scoped_refptr<Output>& output) { 375 const scoped_refptr<Output>& output) {
367 FUNCTION_DVLOG(2) << output; 376 FUNCTION_DVLOG(2) << ": " << output->timestamp().InMilliseconds() << " ms";
368 DCHECK(output); 377 DCHECK(output);
378 DCHECK(!output->end_of_stream());
369 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 379 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
370 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) 380 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
371 << state_; 381 << state_;
372 382
373 if (state_ == STATE_ERROR) { 383 if (state_ == STATE_ERROR) {
374 DCHECK(read_cb_.is_null()); 384 DCHECK(read_cb_.is_null());
375 return; 385 return;
376 } 386 }
377 387
378 // Drop decoding result if Reset() was called during decoding. 388 // Drop decoding result if Reset() was called during decoding.
379 // The resetting process will be handled when the decoder is reset. 389 // The resetting process will be handled when the decoder is reset.
380 if (!reset_cb_.is_null()) 390 if (!reset_cb_.is_null())
381 return; 391 return;
382 392
383 if (state_ == STATE_FLUSHING_DECODER && output->end_of_stream()) {
384 // ReinitializeDecoder() will be called from OnDecodeDone().
385 return;
386 }
387
388 // Store decoded output. 393 // Store decoded output.
389 ready_outputs_.push_back(output); 394 ready_outputs_.push_back(output);
390 395
396 if (read_cb_.is_null())
397 return;
398
391 // Satisfy outstanding read request, if any. 399 // Satisfy outstanding read request, if any.
392 if (!read_cb_.is_null()) { 400 scoped_refptr<Output> read_result = ready_outputs_.front();
393 scoped_refptr<Output> read_result = ready_outputs_.front(); 401 ready_outputs_.pop_front();
394 ready_outputs_.pop_front(); 402 SatisfyRead(OK, output);
395 SatisfyRead(OK, output);
396 }
397 } 403 }
398 404
399 template <DemuxerStream::Type StreamType> 405 template <DemuxerStream::Type StreamType>
400 void DecoderStream<StreamType>::ReadFromDemuxerStream() { 406 void DecoderStream<StreamType>::ReadFromDemuxerStream() {
401 FUNCTION_DVLOG(2); 407 FUNCTION_DVLOG(2);
402 DCHECK_EQ(state_, STATE_NORMAL) << state_; 408 DCHECK_EQ(state_, STATE_NORMAL) << state_;
403 DCHECK(CanDecodeMore()); 409 DCHECK(CanDecodeMore());
404 DCHECK(reset_cb_.is_null()); 410 DCHECK(reset_cb_.is_null());
405 DCHECK(stop_cb_.is_null()); 411 DCHECK(stop_cb_.is_null());
406 412
407 state_ = STATE_PENDING_DEMUXER_READ; 413 state_ = STATE_PENDING_DEMUXER_READ;
408 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, 414 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady,
409 weak_factory_.GetWeakPtr())); 415 weak_factory_.GetWeakPtr()));
410 } 416 }
411 417
412 template <DemuxerStream::Type StreamType> 418 template <DemuxerStream::Type StreamType>
413 void DecoderStream<StreamType>::OnBufferReady( 419 void DecoderStream<StreamType>::OnBufferReady(
414 DemuxerStream::Status status, 420 DemuxerStream::Status status,
415 const scoped_refptr<DecoderBuffer>& buffer) { 421 const scoped_refptr<DecoderBuffer>& buffer) {
416 FUNCTION_DVLOG(2) << ": " << status; 422 FUNCTION_DVLOG(2) << ": " << status << ", "
423 << buffer->AsHumanReadableString();
424
417 DCHECK(task_runner_->BelongsToCurrentThread()); 425 DCHECK(task_runner_->BelongsToCurrentThread());
418 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR || 426 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR ||
419 state_ == STATE_STOPPED) 427 state_ == STATE_STOPPED)
420 << state_; 428 << state_;
421 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; 429 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
422 DCHECK(stop_cb_.is_null()); 430 DCHECK(stop_cb_.is_null());
423 431
424 // Decoding has been stopped (e.g due to an error). 432 // Decoding has been stopped (e.g due to an error).
425 if (state_ != STATE_PENDING_DEMUXER_READ) { 433 if (state_ != STATE_PENDING_DEMUXER_READ) {
426 DCHECK(state_ == STATE_ERROR || state_ == STATE_STOPPED); 434 DCHECK(state_ == STATE_ERROR || state_ == STATE_STOPPED);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 } 536 }
529 537
530 ReadFromDemuxerStream(); 538 ReadFromDemuxerStream();
531 } 539 }
532 540
533 template <DemuxerStream::Type StreamType> 541 template <DemuxerStream::Type StreamType>
534 void DecoderStream<StreamType>::ResetDecoder() { 542 void DecoderStream<StreamType>::ResetDecoder() {
535 FUNCTION_DVLOG(2); 543 FUNCTION_DVLOG(2);
536 DCHECK(task_runner_->BelongsToCurrentThread()); 544 DCHECK(task_runner_->BelongsToCurrentThread());
537 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 545 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
538 state_ == STATE_ERROR) << state_; 546 state_ == STATE_ERROR || state_ == STATE_END_OF_STREAM) << state_;
539 DCHECK(!reset_cb_.is_null()); 547 DCHECK(!reset_cb_.is_null());
540 548
541 decoder_->Reset(base::Bind(&DecoderStream<StreamType>::OnDecoderReset, 549 decoder_->Reset(base::Bind(&DecoderStream<StreamType>::OnDecoderReset,
542 weak_factory_.GetWeakPtr())); 550 weak_factory_.GetWeakPtr()));
543 } 551 }
544 552
545 template <DemuxerStream::Type StreamType> 553 template <DemuxerStream::Type StreamType>
546 void DecoderStream<StreamType>::OnDecoderReset() { 554 void DecoderStream<StreamType>::OnDecoderReset() {
547 FUNCTION_DVLOG(2); 555 FUNCTION_DVLOG(2);
548 DCHECK(task_runner_->BelongsToCurrentThread()); 556 DCHECK(task_runner_->BelongsToCurrentThread());
549 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 557 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
550 state_ == STATE_ERROR) << state_; 558 state_ == STATE_ERROR || state_ == STATE_END_OF_STREAM) << state_;
551 // If Reset() was called during pending read, read callback should be fired 559 // If Reset() was called during pending read, read callback should be fired
552 // before the reset callback is fired. 560 // before the reset callback is fired.
553 DCHECK(read_cb_.is_null()); 561 DCHECK(read_cb_.is_null());
554 DCHECK(!reset_cb_.is_null()); 562 DCHECK(!reset_cb_.is_null());
555 DCHECK(stop_cb_.is_null()); 563 DCHECK(stop_cb_.is_null());
556 564
557 if (state_ != STATE_FLUSHING_DECODER) { 565 if (state_ != STATE_FLUSHING_DECODER) {
558 base::ResetAndReturn(&reset_cb_).Run(); 566 base::ResetAndReturn(&reset_cb_).Run();
559 return; 567 return;
560 } 568 }
(...skipping 16 matching lines...) Expand all
577 decrypting_demuxer_stream_.reset(); 585 decrypting_demuxer_stream_.reset();
578 // Post |stop_cb_| because pending |read_cb_| and/or |reset_cb_| are also 586 // Post |stop_cb_| because pending |read_cb_| and/or |reset_cb_| are also
579 // posted in Stop(). 587 // posted in Stop().
580 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); 588 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
581 } 589 }
582 590
583 template class DecoderStream<DemuxerStream::VIDEO>; 591 template class DecoderStream<DemuxerStream::VIDEO>;
584 template class DecoderStream<DemuxerStream::AUDIO>; 592 template class DecoderStream<DemuxerStream::AUDIO>;
585 593
586 } // namespace media 594 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698