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

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: rebase only 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
« no previous file with comments | « media/filters/decoder_stream.h ('k') | media/filters/decoder_stream_traits.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // TODO(xhwang): VideoDecoder doesn't need to return EOS after it's flushed. 393 // TODO(xhwang): VideoDecoder doesn't need to return EOS after it's flushed.
384 // Fix all decoders and remove this block. 394 // Fix all decoders and remove this block.
385 if (state_ == STATE_FLUSHING_DECODER && output->end_of_stream()) {
386 // ReinitializeDecoder() will be called from OnDecodeDone().
387 return;
388 }
389
390 // Store decoded output. 395 // Store decoded output.
391 ready_outputs_.push_back(output); 396 ready_outputs_.push_back(output);
392 397
398 if (read_cb_.is_null())
399 return;
400
393 // Satisfy outstanding read request, if any. 401 // Satisfy outstanding read request, if any.
394 if (!read_cb_.is_null()) { 402 scoped_refptr<Output> read_result = ready_outputs_.front();
395 scoped_refptr<Output> read_result = ready_outputs_.front(); 403 ready_outputs_.pop_front();
396 ready_outputs_.pop_front(); 404 SatisfyRead(OK, output);
397 SatisfyRead(OK, output);
398 }
399 } 405 }
400 406
401 template <DemuxerStream::Type StreamType> 407 template <DemuxerStream::Type StreamType>
402 void DecoderStream<StreamType>::ReadFromDemuxerStream() { 408 void DecoderStream<StreamType>::ReadFromDemuxerStream() {
403 FUNCTION_DVLOG(2); 409 FUNCTION_DVLOG(2);
404 DCHECK_EQ(state_, STATE_NORMAL) << state_; 410 DCHECK_EQ(state_, STATE_NORMAL) << state_;
405 DCHECK(CanDecodeMore()); 411 DCHECK(CanDecodeMore());
406 DCHECK(reset_cb_.is_null()); 412 DCHECK(reset_cb_.is_null());
407 DCHECK(stop_cb_.is_null()); 413 DCHECK(stop_cb_.is_null());
408 414
409 state_ = STATE_PENDING_DEMUXER_READ; 415 state_ = STATE_PENDING_DEMUXER_READ;
410 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, 416 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady,
411 weak_factory_.GetWeakPtr())); 417 weak_factory_.GetWeakPtr()));
412 } 418 }
413 419
414 template <DemuxerStream::Type StreamType> 420 template <DemuxerStream::Type StreamType>
415 void DecoderStream<StreamType>::OnBufferReady( 421 void DecoderStream<StreamType>::OnBufferReady(
416 DemuxerStream::Status status, 422 DemuxerStream::Status status,
417 const scoped_refptr<DecoderBuffer>& buffer) { 423 const scoped_refptr<DecoderBuffer>& buffer) {
418 FUNCTION_DVLOG(2) << ": " << status; 424 FUNCTION_DVLOG(2) << ": " << status << ", "
425 << buffer->AsHumanReadableString();
426
419 DCHECK(task_runner_->BelongsToCurrentThread()); 427 DCHECK(task_runner_->BelongsToCurrentThread());
420 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR || 428 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR ||
421 state_ == STATE_STOPPED) 429 state_ == STATE_STOPPED)
422 << state_; 430 << state_;
423 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; 431 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status;
424 DCHECK(stop_cb_.is_null()); 432 DCHECK(stop_cb_.is_null());
425 433
426 // Decoding has been stopped (e.g due to an error). 434 // Decoding has been stopped (e.g due to an error).
427 if (state_ != STATE_PENDING_DEMUXER_READ) { 435 if (state_ != STATE_PENDING_DEMUXER_READ) {
428 DCHECK(state_ == STATE_ERROR || state_ == STATE_STOPPED); 436 DCHECK(state_ == STATE_ERROR || state_ == STATE_STOPPED);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 } 538 }
531 539
532 ReadFromDemuxerStream(); 540 ReadFromDemuxerStream();
533 } 541 }
534 542
535 template <DemuxerStream::Type StreamType> 543 template <DemuxerStream::Type StreamType>
536 void DecoderStream<StreamType>::ResetDecoder() { 544 void DecoderStream<StreamType>::ResetDecoder() {
537 FUNCTION_DVLOG(2); 545 FUNCTION_DVLOG(2);
538 DCHECK(task_runner_->BelongsToCurrentThread()); 546 DCHECK(task_runner_->BelongsToCurrentThread());
539 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 547 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
540 state_ == STATE_ERROR) << state_; 548 state_ == STATE_ERROR || state_ == STATE_END_OF_STREAM) << state_;
541 DCHECK(!reset_cb_.is_null()); 549 DCHECK(!reset_cb_.is_null());
542 550
543 decoder_->Reset(base::Bind(&DecoderStream<StreamType>::OnDecoderReset, 551 decoder_->Reset(base::Bind(&DecoderStream<StreamType>::OnDecoderReset,
544 weak_factory_.GetWeakPtr())); 552 weak_factory_.GetWeakPtr()));
545 } 553 }
546 554
547 template <DemuxerStream::Type StreamType> 555 template <DemuxerStream::Type StreamType>
548 void DecoderStream<StreamType>::OnDecoderReset() { 556 void DecoderStream<StreamType>::OnDecoderReset() {
549 FUNCTION_DVLOG(2); 557 FUNCTION_DVLOG(2);
550 DCHECK(task_runner_->BelongsToCurrentThread()); 558 DCHECK(task_runner_->BelongsToCurrentThread());
551 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || 559 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
552 state_ == STATE_ERROR) << state_; 560 state_ == STATE_ERROR || state_ == STATE_END_OF_STREAM) << state_;
553 // If Reset() was called during pending read, read callback should be fired 561 // If Reset() was called during pending read, read callback should be fired
554 // before the reset callback is fired. 562 // before the reset callback is fired.
555 DCHECK(read_cb_.is_null()); 563 DCHECK(read_cb_.is_null());
556 DCHECK(!reset_cb_.is_null()); 564 DCHECK(!reset_cb_.is_null());
557 DCHECK(stop_cb_.is_null()); 565 DCHECK(stop_cb_.is_null());
558 566
559 if (state_ != STATE_FLUSHING_DECODER) { 567 if (state_ != STATE_FLUSHING_DECODER) {
568 state_ = STATE_NORMAL;
560 base::ResetAndReturn(&reset_cb_).Run(); 569 base::ResetAndReturn(&reset_cb_).Run();
561 return; 570 return;
562 } 571 }
563 572
564 // The resetting process will be continued in OnDecoderReinitialized(). 573 // The resetting process will be continued in OnDecoderReinitialized().
565 ReinitializeDecoder(); 574 ReinitializeDecoder();
566 } 575 }
567 576
568 template <DemuxerStream::Type StreamType> 577 template <DemuxerStream::Type StreamType>
569 void DecoderStream<StreamType>::StopDecoder() { 578 void DecoderStream<StreamType>::StopDecoder() {
570 FUNCTION_DVLOG(2); 579 FUNCTION_DVLOG(2);
571 DCHECK(task_runner_->BelongsToCurrentThread()); 580 DCHECK(task_runner_->BelongsToCurrentThread());
572 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; 581 DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
573 DCHECK(!stop_cb_.is_null()); 582 DCHECK(!stop_cb_.is_null());
574 583
575 state_ = STATE_STOPPED; 584 state_ = STATE_STOPPED;
576 decoder_->Stop(); 585 decoder_->Stop();
577 stream_ = NULL; 586 stream_ = NULL;
578 decoder_.reset(); 587 decoder_.reset();
579 decrypting_demuxer_stream_.reset(); 588 decrypting_demuxer_stream_.reset();
580 // Post |stop_cb_| because pending |read_cb_| and/or |reset_cb_| are also 589 // Post |stop_cb_| because pending |read_cb_| and/or |reset_cb_| are also
581 // posted in Stop(). 590 // posted in Stop().
582 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_)); 591 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
583 } 592 }
584 593
585 template class DecoderStream<DemuxerStream::VIDEO>; 594 template class DecoderStream<DemuxerStream::VIDEO>;
586 template class DecoderStream<DemuxerStream::AUDIO>; 595 template class DecoderStream<DemuxerStream::AUDIO>;
587 596
588 } // namespace media 597 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/decoder_stream.h ('k') | media/filters/decoder_stream_traits.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698