| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/base/android/media_codec_decoder.h" | 5 #include "media/base/android/media_codec_decoder.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 break; | 384 break; |
| 385 default: | 385 default: |
| 386 NOTREACHED(); | 386 NOTREACHED(); |
| 387 break; | 387 break; |
| 388 } | 388 } |
| 389 } | 389 } |
| 390 | 390 |
| 391 void MediaCodecDecoder::OnLastFrameRendered(bool eos_encountered) { | 391 void MediaCodecDecoder::OnLastFrameRendered(bool eos_encountered) { |
| 392 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 392 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 393 | 393 |
| 394 DVLOG(1) << class_name() << "::" << __FUNCTION__ | 394 // http://crbug.com/526755 |
| 395 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
| 395 << " eos_encountered:" << eos_encountered; | 396 << " eos_encountered:" << eos_encountered; |
| 396 | 397 |
| 397 decoder_thread_.Stop(); // synchronous | 398 decoder_thread_.Stop(); // synchronous |
| 398 | 399 |
| 399 SetState(kStopped); | 400 SetState(kStopped); |
| 400 completed_ = (eos_encountered && !drain_decoder_); | 401 completed_ = (eos_encountered && !drain_decoder_); |
| 401 | 402 |
| 402 if (completed_ && !preroll_done_cb_.is_null()) { | 403 if (completed_ && !preroll_done_cb_.is_null()) { |
| 403 // http://crbug.com/526755 | 404 // http://crbug.com/526755 |
| 404 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 405 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 void MediaCodecDecoder::SetAlwaysReconfigureForTests() { | 476 void MediaCodecDecoder::SetAlwaysReconfigureForTests() { |
| 476 // UI task runner. | 477 // UI task runner. |
| 477 always_reconfigure_for_tests_ = true; | 478 always_reconfigure_for_tests_ = true; |
| 478 } | 479 } |
| 479 | 480 |
| 480 void MediaCodecDecoder::SetCodecCreatedCallbackForTests(base::Closure cb) { | 481 void MediaCodecDecoder::SetCodecCreatedCallbackForTests(base::Closure cb) { |
| 481 // UI task runner. | 482 // UI task runner. |
| 482 codec_created_for_tests_cb_ = cb; | 483 codec_created_for_tests_cb_ = cb; |
| 483 } | 484 } |
| 484 | 485 |
| 486 // http://crbug.com/526755 |
| 487 void MediaCodecDecoder::SetVerboseForTests(bool value) { |
| 488 // UI task runner. |
| 489 verbose_ = value; |
| 490 } |
| 491 |
| 485 int MediaCodecDecoder::NumDelayedRenderTasks() const { | 492 int MediaCodecDecoder::NumDelayedRenderTasks() const { |
| 486 return 0; | 493 return 0; |
| 487 } | 494 } |
| 488 | 495 |
| 489 void MediaCodecDecoder::DoEmergencyStop() { | 496 void MediaCodecDecoder::DoEmergencyStop() { |
| 490 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 497 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 491 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 498 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
| 492 | 499 |
| 493 // After this method returns, decoder thread will not be running. | 500 // After this method returns, decoder thread will not be running. |
| 494 | 501 |
| 495 // Set [kInEmergencyStop| state to block already posted ProcessNextFrame(). | 502 // Set [kInEmergencyStop| state to block already posted ProcessNextFrame(). |
| 496 SetState(kInEmergencyStop); | 503 SetState(kInEmergencyStop); |
| 497 | 504 |
| 498 decoder_thread_.Stop(); // synchronous | 505 decoder_thread_.Stop(); // synchronous |
| 499 | 506 |
| 500 SetState(kStopped); | 507 SetState(kStopped); |
| 501 } | 508 } |
| 502 | 509 |
| 503 void MediaCodecDecoder::CheckLastFrame(bool eos_encountered, | 510 void MediaCodecDecoder::CheckLastFrame(bool eos_encountered, |
| 504 bool has_delayed_tasks) { | 511 bool has_delayed_tasks) { |
| 505 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); | 512 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); |
| 506 | 513 |
| 507 bool last_frame_when_stopping = GetState() == kStopping && !has_delayed_tasks; | 514 bool last_frame_when_stopping = GetState() == kStopping && !has_delayed_tasks; |
| 508 | 515 |
| 509 if (last_frame_when_stopping || eos_encountered) { | 516 if (last_frame_when_stopping || eos_encountered) { |
| 517 if (verbose_) { |
| 518 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
| 519 << " last_frame_when_stopping:" << last_frame_when_stopping |
| 520 << " eos_encountered:" << eos_encountered |
| 521 << ", posting MediaCodecDecoder::OnLastFrameRendered"; |
| 522 } |
| 523 |
| 510 media_task_runner_->PostTask( | 524 media_task_runner_->PostTask( |
| 511 FROM_HERE, base::Bind(&MediaCodecDecoder::OnLastFrameRendered, | 525 FROM_HERE, base::Bind(&MediaCodecDecoder::OnLastFrameRendered, |
| 512 weak_factory_.GetWeakPtr(), eos_encountered)); | 526 weak_factory_.GetWeakPtr(), eos_encountered)); |
| 513 last_frame_posted_ = true; | 527 last_frame_posted_ = true; |
| 514 } | 528 } |
| 515 } | 529 } |
| 516 | 530 |
| 517 void MediaCodecDecoder::OnCodecError() { | 531 void MediaCodecDecoder::OnCodecError() { |
| 518 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 532 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
| 519 | 533 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 | 580 |
| 567 DecoderState state = GetState(); | 581 DecoderState state = GetState(); |
| 568 | 582 |
| 569 if (state != kPrerolling && state != kRunning && state != kStopping) { | 583 if (state != kPrerolling && state != kRunning && state != kStopping) { |
| 570 DVLOG(1) << class_name() << "::" << __FUNCTION__ << ": not running"; | 584 DVLOG(1) << class_name() << "::" << __FUNCTION__ << ": not running"; |
| 571 return; | 585 return; |
| 572 } | 586 } |
| 573 | 587 |
| 574 if (state == kStopping) { | 588 if (state == kStopping) { |
| 575 if (NumDelayedRenderTasks() == 0 && !last_frame_posted_) { | 589 if (NumDelayedRenderTasks() == 0 && !last_frame_posted_) { |
| 576 DVLOG(1) << class_name() << "::" << __FUNCTION__ | 590 // http://crbug.com/526755 |
| 577 << ": kStopping, posting OnLastFrameRendered"; | 591 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
| 592 << ": kStopping, no delayed tasks, posting OnLastFrameRendered"; |
| 578 media_task_runner_->PostTask( | 593 media_task_runner_->PostTask( |
| 579 FROM_HERE, base::Bind(&MediaCodecDecoder::OnLastFrameRendered, | 594 FROM_HERE, base::Bind(&MediaCodecDecoder::OnLastFrameRendered, |
| 580 weak_factory_.GetWeakPtr(), false)); | 595 weak_factory_.GetWeakPtr(), false)); |
| 581 last_frame_posted_ = true; | 596 last_frame_posted_ = true; |
| 582 } | 597 } |
| 583 | 598 |
| 584 // We can stop processing, the |au_queue_| and MediaCodec queues can freeze. | 599 // We can stop processing, the |au_queue_| and MediaCodec queues can freeze. |
| 585 // We only need to let finish the delayed rendering tasks. | 600 // We only need to let finish the delayed rendering tasks. |
| 586 return; | 601 return; |
| 587 } | 602 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 DVLOG(2) << class_name() << ":: DequeueInputBuffer index:" << index; | 679 DVLOG(2) << class_name() << ":: DequeueInputBuffer index:" << index; |
| 665 | 680 |
| 666 switch (status) { | 681 switch (status) { |
| 667 case MEDIA_CODEC_ERROR: | 682 case MEDIA_CODEC_ERROR: |
| 668 DVLOG(0) << class_name() << "::" << __FUNCTION__ | 683 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
| 669 << ": MEDIA_CODEC_ERROR DequeueInputBuffer failed"; | 684 << ": MEDIA_CODEC_ERROR DequeueInputBuffer failed"; |
| 670 media_task_runner_->PostTask(FROM_HERE, internal_error_cb_); | 685 media_task_runner_->PostTask(FROM_HERE, internal_error_cb_); |
| 671 return false; | 686 return false; |
| 672 | 687 |
| 673 case MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER: | 688 case MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER: |
| 674 DVLOG(0) | 689 DVLOG(2) |
| 675 << class_name() << "::" << __FUNCTION__ | 690 << class_name() << "::" << __FUNCTION__ |
| 676 << ": DequeueInputBuffer returned MediaCodec.INFO_TRY_AGAIN_LATER."; | 691 << ": DequeueInputBuffer returned MediaCodec.INFO_TRY_AGAIN_LATER."; |
| 677 return true; | 692 return true; |
| 678 | 693 |
| 679 default: | 694 default: |
| 680 break; | 695 break; |
| 681 } | 696 } |
| 682 | 697 |
| 683 // We got the buffer | 698 // We got the buffer |
| 684 DCHECK_EQ(status, MEDIA_CODEC_OK); | 699 DCHECK_EQ(status, MEDIA_CODEC_OK); |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 RETURN_STRING(kStopping); | 905 RETURN_STRING(kStopping); |
| 891 RETURN_STRING(kInEmergencyStop); | 906 RETURN_STRING(kInEmergencyStop); |
| 892 RETURN_STRING(kError); | 907 RETURN_STRING(kError); |
| 893 } | 908 } |
| 894 return nullptr; // crash early | 909 return nullptr; // crash early |
| 895 } | 910 } |
| 896 | 911 |
| 897 #undef RETURN_STRING | 912 #undef RETURN_STRING |
| 898 | 913 |
| 899 } // namespace media | 914 } // namespace media |
| OLD | NEW |