Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "content/common/gpu/media/android_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/android_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/android/build_info.h" | 9 #include "base/android/build_info.h" |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 401 | 401 |
| 402 NOTIMPLEMENTED(); | 402 NOTIMPLEMENTED(); |
| 403 NotifyCdmAttached(false); | 403 NotifyCdmAttached(false); |
| 404 | 404 |
| 405 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 405 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 406 } | 406 } |
| 407 | 407 |
| 408 void AndroidVideoDecodeAccelerator::DoIOTask() { | 408 void AndroidVideoDecodeAccelerator::DoIOTask() { |
| 409 DCHECK(thread_checker_.CalledOnValidThread()); | 409 DCHECK(thread_checker_.CalledOnValidThread()); |
| 410 TRACE_EVENT0("media", "AVDA::DoIOTask"); | 410 TRACE_EVENT0("media", "AVDA::DoIOTask"); |
| 411 | |
| 411 if (state_ == ERROR) { | 412 if (state_ == ERROR) { |
| 412 return; | 413 return; |
| 414 } else if (state_ == PENDING_CODEC_RECONFIGURE) { | |
|
watk
2016/03/24 01:02:58
Should probably put this in Decode().
liberato (no reviews please)
2016/03/29 14:54:40
probably, yes, since the codec can't take any acti
| |
| 415 // Defer errors here in case we're about to be destroyed because the | |
| 416 // pipeline is suspending. | |
| 417 base::AutoReset<bool> auto_reset(&defer_errors_, true); | |
| 418 if (!ConfigureMediaCodec()) { | |
| 419 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); | |
| 420 return; | |
| 421 } | |
| 422 state_ = NO_ERROR; | |
| 413 } | 423 } |
| 414 | 424 |
| 415 bool did_work = QueueInput(); | 425 bool did_work = QueueInput(); |
| 416 while (DequeueOutput()) | 426 while (DequeueOutput()) |
| 417 did_work = true; | 427 did_work = true; |
| 418 | 428 |
| 419 ManageTimer(did_work); | 429 ManageTimer(did_work); |
| 420 } | 430 } |
| 421 | 431 |
| 422 bool AndroidVideoDecodeAccelerator::QueueInput() { | 432 bool AndroidVideoDecodeAccelerator::QueueInput() { |
| 423 DCHECK(thread_checker_.CalledOnValidThread()); | 433 DCHECK(thread_checker_.CalledOnValidThread()); |
| 434 DCHECK_NE(state_, PENDING_CODEC_RECONFIGURE); | |
| 424 TRACE_EVENT0("media", "AVDA::QueueInput"); | 435 TRACE_EVENT0("media", "AVDA::QueueInput"); |
| 425 base::AutoReset<bool> auto_reset(&defer_errors_, true); | 436 base::AutoReset<bool> auto_reset(&defer_errors_, true); |
| 426 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance) | 437 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance) |
| 427 return false; | 438 return false; |
| 428 if (pending_bitstream_buffers_.empty()) | 439 if (pending_bitstream_buffers_.empty()) |
| 429 return false; | 440 return false; |
| 430 if (state_ == WAITING_FOR_KEY) | 441 if (state_ == WAITING_FOR_KEY) |
| 431 return false; | 442 return false; |
| 432 | 443 |
| 433 int input_buf_index = pending_input_buf_index_; | 444 int input_buf_index = pending_input_buf_index_; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 528 DVLOG(1) << "QueueSecureInputBuffer failed: NO_KEY"; | 539 DVLOG(1) << "QueueSecureInputBuffer failed: NO_KEY"; |
| 529 pending_input_buf_index_ = input_buf_index; | 540 pending_input_buf_index_ = input_buf_index; |
| 530 state_ = WAITING_FOR_KEY; | 541 state_ = WAITING_FOR_KEY; |
| 531 return false; | 542 return false; |
| 532 } | 543 } |
| 533 | 544 |
| 534 pending_input_buf_index_ = -1; | 545 pending_input_buf_index_ = -1; |
| 535 pending_bitstream_buffers_.pop(); | 546 pending_bitstream_buffers_.pop(); |
| 536 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", | 547 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", |
| 537 pending_bitstream_buffers_.size()); | 548 pending_bitstream_buffers_.size()); |
| 538 | |
| 539 if (status != media::MEDIA_CODEC_OK) { | |
| 540 POST_ERROR(PLATFORM_FAILURE, "Failed to QueueInputBuffer: " << status); | |
| 541 return false; | |
| 542 } | |
| 543 | |
| 544 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output | 549 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output |
| 545 // will be returned from the bitstream buffer. However, MediaCodec API is | 550 // will be returned from the bitstream buffer. However, MediaCodec API is |
| 546 // not enough to guarantee it. | 551 // not enough to guarantee it. |
| 547 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to | 552 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to |
| 548 // keep getting more bitstreams from the client, and throttle them by using | 553 // keep getting more bitstreams from the client, and throttle them by using |
| 549 // |bitstreams_notified_in_advance_|. | 554 // |bitstreams_notified_in_advance_|. |
| 550 // TODO(dwkang): check if there is a way to remove this workaround. | 555 // TODO(dwkang): check if there is a way to remove this workaround. |
| 551 base::MessageLoop::current()->PostTask( | 556 base::MessageLoop::current()->PostTask( |
| 552 FROM_HERE, | 557 FROM_HERE, |
| 553 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, | 558 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, |
| 554 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id())); | 559 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id())); |
| 555 bitstreams_notified_in_advance_.push_back(bitstream_buffer.id()); | 560 bitstreams_notified_in_advance_.push_back(bitstream_buffer.id()); |
| 556 | 561 |
| 562 if (status != media::MEDIA_CODEC_OK) { | |
| 563 POST_ERROR(PLATFORM_FAILURE, "Failed to QueueInputBuffer: " << status); | |
| 564 return false; | |
|
watk
2016/03/24 01:02:58
This has to be moved because otherwise we might po
| |
| 565 } | |
| 566 | |
| 557 return true; | 567 return true; |
| 558 } | 568 } |
| 559 | 569 |
| 560 bool AndroidVideoDecodeAccelerator::DequeueOutput() { | 570 bool AndroidVideoDecodeAccelerator::DequeueOutput() { |
| 561 DCHECK(thread_checker_.CalledOnValidThread()); | 571 DCHECK(thread_checker_.CalledOnValidThread()); |
| 572 DCHECK_NE(state_, PENDING_CODEC_RECONFIGURE); | |
| 562 TRACE_EVENT0("media", "AVDA::DequeueOutput"); | 573 TRACE_EVENT0("media", "AVDA::DequeueOutput"); |
| 563 base::AutoReset<bool> auto_reset(&defer_errors_, true); | 574 base::AutoReset<bool> auto_reset(&defer_errors_, true); |
| 564 if (picturebuffers_requested_ && output_picture_buffers_.empty()) | 575 if (picturebuffers_requested_ && output_picture_buffers_.empty()) |
| 565 return false; | 576 return false; |
| 566 | 577 |
| 567 if (!output_picture_buffers_.empty() && free_picture_ids_.empty()) { | 578 if (!output_picture_buffers_.empty() && free_picture_ids_.empty()) { |
| 568 // Don't have any picture buffer to send. Need to wait more. | 579 // Don't have any picture buffer to send. Need to wait more. |
| 569 return false; | 580 return false; |
| 570 } | 581 } |
| 571 | 582 |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 904 // The data for that index exists in the input buffer, but corresponding | 915 // The data for that index exists in the input buffer, but corresponding |
| 905 // shm block been deleted. Check that it is safe to flush the coec, i.e. | 916 // shm block been deleted. Check that it is safe to flush the coec, i.e. |
| 906 // |pending_bitstream_buffers_| is empty. | 917 // |pending_bitstream_buffers_| is empty. |
| 907 // TODO(timav): keep shm block for that buffer and remove this restriction. | 918 // TODO(timav): keep shm block for that buffer and remove this restriction. |
| 908 DCHECK(pending_bitstream_buffers_.empty()); | 919 DCHECK(pending_bitstream_buffers_.empty()); |
| 909 pending_input_buf_index_ = -1; | 920 pending_input_buf_index_ = -1; |
| 910 } | 921 } |
| 911 | 922 |
| 912 if (state_ == WAITING_FOR_KEY) | 923 if (state_ == WAITING_FOR_KEY) |
| 913 state_ = NO_ERROR; | 924 state_ = NO_ERROR; |
| 914 | 925 |
|
liberato (no reviews please)
2016/03/29 14:54:40
should this early out here if |state_| is already
| |
| 915 // We might increment error_sequence_token here to cancel any delayed errors, | 926 // We might increment error_sequence_token here to cancel any delayed errors, |
| 916 // but right now it's unclear that it's safe to do so. If we are in an error | 927 // but right now it's unclear that it's safe to do so. If we are in an error |
| 917 // state because of a codec error, then it would be okay. Otherwise, it's | 928 // state because of a codec error, then it would be okay. Otherwise, it's |
| 918 // less obvious that we are exiting the error state. Since deferred errors | 929 // less obvious that we are exiting the error state. Since deferred errors |
| 919 // are only intended for fullscreen transitions right now, we take the more | 930 // are only intended for fullscreen transitions right now, we take the more |
| 920 // conservative approach and let the errors post. | 931 // conservative approach and let the errors post. |
| 921 // TODO(liberato): revisit this once we sort out the error state a bit more. | 932 // TODO(liberato): revisit this once we sort out the error state a bit more. |
| 922 | 933 |
| 923 // When codec is not in error state we can quickly reset (internally calls | 934 // When codec is not in error state we can quickly reset (internally calls |
| 924 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs | 935 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs |
| 925 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new | 936 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new |
| 926 // one. The full reconfigure is much slower and may cause visible freezing if | 937 // one. The full reconfigure is much slower and may cause visible freezing if |
| 927 // done mid-stream. | 938 // done mid-stream. |
| 928 if (state_ == NO_ERROR && | 939 if (state_ == NO_ERROR && |
| 929 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) { | 940 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) { |
| 930 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush)."; | 941 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush)."; |
| 931 media_codec_->Reset(); | 942 media_codec_->Reset(); |
| 932 // Since we just flushed all the output buffers, make sure that nothing is | 943 // Since we just flushed all the output buffers, make sure that nothing is |
| 933 // using them. | 944 // using them. |
| 934 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); | 945 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); |
| 935 } else { | 946 } else { |
| 936 DVLOG(3) << __FUNCTION__ | 947 DVLOG(3) << __FUNCTION__ |
| 937 << " Deleting the MediaCodec and creating a new one."; | 948 << " Deleting the MediaCodec and creating a new one."; |
| 938 g_avda_timer.Pointer()->StopTimer(this); | 949 g_avda_timer.Pointer()->StopTimer(this); |
| 939 media_codec_.reset(); | 950 media_codec_.reset(); |
| 951 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); | |
| 940 // Changing the codec will also notify the strategy to forget about any | 952 // Changing the codec will also notify the strategy to forget about any |
| 941 // output buffers it has currently. | 953 // output buffers it has currently. |
| 942 state_ = NO_ERROR; | 954 state_ = PENDING_CODEC_RECONFIGURE; |
|
liberato (no reviews please)
2016/03/29 14:54:40
you might consider not deferring the reset in the
| |
| 943 if (!ConfigureMediaCodec()) | |
| 944 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); | |
| 945 } | 955 } |
| 946 } | 956 } |
| 947 | 957 |
| 948 void AndroidVideoDecodeAccelerator::DismissPictureBuffers() { | 958 void AndroidVideoDecodeAccelerator::DismissPictureBuffers() { |
| 949 DCHECK(thread_checker_.CalledOnValidThread()); | 959 DCHECK(thread_checker_.CalledOnValidThread()); |
| 950 DVLOG(3) << __FUNCTION__; | 960 DVLOG(3) << __FUNCTION__; |
| 951 | 961 |
| 952 for (const auto& pb : output_picture_buffers_) { | 962 for (const auto& pb : output_picture_buffers_) { |
| 953 strategy_->DismissOnePictureBuffer(pb.second); | 963 strategy_->DismissOnePictureBuffer(pb.second); |
| 954 client_->DismissPictureBuffer(pb.first); | 964 client_->DismissPictureBuffer(pb.first); |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1209 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: | 1219 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: |
| 1210 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | | 1220 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | |
| 1211 media::VideoDecodeAccelerator::Capabilities:: | 1221 media::VideoDecodeAccelerator::Capabilities:: |
| 1212 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; | 1222 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
| 1213 } | 1223 } |
| 1214 | 1224 |
| 1215 return capabilities; | 1225 return capabilities; |
| 1216 } | 1226 } |
| 1217 | 1227 |
| 1218 } // namespace content | 1228 } // namespace content |
| OLD | NEW |