| 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 "media/gpu/android_video_decode_accelerator.h" | 5 #include "media/gpu/android_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 } | 296 } |
| 297 | 297 |
| 298 if (codec_config_->codec == kCodecH264) { | 298 if (codec_config_->codec == kCodecH264) { |
| 299 codec_config_->csd0 = config.sps; | 299 codec_config_->csd0 = config.sps; |
| 300 codec_config_->csd1 = config.pps; | 300 codec_config_->csd1 = config.pps; |
| 301 } | 301 } |
| 302 | 302 |
| 303 // Only use MediaCodec for VP8/9 if it's likely backed by hardware | 303 // Only use MediaCodec for VP8/9 if it's likely backed by hardware |
| 304 // or if the stream is encrypted. | 304 // or if the stream is encrypted. |
| 305 if (IsMediaCodecSoftwareDecodingForbidden() && | 305 if (IsMediaCodecSoftwareDecodingForbidden() && |
| 306 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec, | 306 MediaCodecUtil::IsKnownUnaccelerated(codec_config_->codec, |
| 307 MEDIA_CODEC_DECODER)) { | 307 MediaCodecDirection::DECODER)) { |
| 308 DVLOG(1) << "Initialization failed: " | 308 DVLOG(1) << "Initialization failed: " << GetCodecName(codec_config_->codec) |
| 309 << (codec_config_->codec == kCodecVP8 ? "vp8" : "vp9") | |
| 310 << " is not hardware accelerated"; | 309 << " is not hardware accelerated"; |
| 311 return false; | 310 return false; |
| 312 } | 311 } |
| 313 | 312 |
| 314 auto gles_decoder = get_gles2_decoder_cb_.Run(); | 313 auto gles_decoder = get_gles2_decoder_cb_.Run(); |
| 315 if (!gles_decoder) { | 314 if (!gles_decoder) { |
| 316 DLOG(ERROR) << "Failed to get gles2 decoder instance."; | 315 DLOG(ERROR) << "Failed to get gles2 decoder instance."; |
| 317 return false; | 316 return false; |
| 318 } | 317 } |
| 319 | 318 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 | 473 |
| 475 int input_buf_index = pending_input_buf_index_; | 474 int input_buf_index = pending_input_buf_index_; |
| 476 | 475 |
| 477 // Do not dequeue a new input buffer if we failed with MEDIA_CODEC_NO_KEY. | 476 // Do not dequeue a new input buffer if we failed with MEDIA_CODEC_NO_KEY. |
| 478 // That status does not return this buffer back to the pool of | 477 // That status does not return this buffer back to the pool of |
| 479 // available input buffers. We have to reuse it in QueueSecureInputBuffer(). | 478 // available input buffers. We have to reuse it in QueueSecureInputBuffer(). |
| 480 if (input_buf_index == -1) { | 479 if (input_buf_index == -1) { |
| 481 MediaCodecStatus status = | 480 MediaCodecStatus status = |
| 482 media_codec_->DequeueInputBuffer(NoWaitTimeOut, &input_buf_index); | 481 media_codec_->DequeueInputBuffer(NoWaitTimeOut, &input_buf_index); |
| 483 switch (status) { | 482 switch (status) { |
| 484 case MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER: | 483 case MEDIA_CODEC_TRY_AGAIN_LATER: |
| 485 return false; | 484 return false; |
| 486 case MEDIA_CODEC_ERROR: | 485 case MEDIA_CODEC_ERROR: |
| 487 NOTIFY_ERROR(PLATFORM_FAILURE, "DequeueInputBuffer failed"); | 486 NOTIFY_ERROR(PLATFORM_FAILURE, "DequeueInputBuffer failed"); |
| 488 return false; | 487 return false; |
| 489 case MEDIA_CODEC_OK: | 488 case MEDIA_CODEC_OK: |
| 490 break; | 489 break; |
| 491 default: | 490 default: |
| 492 NOTREACHED(); | 491 NOTREACHED(); |
| 493 return false; | 492 return false; |
| 494 } | 493 } |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 // Instead, signal completion of the drain. | 643 // Instead, signal completion of the drain. |
| 645 if (IsDrainingForResetOrDestroy()) { | 644 if (IsDrainingForResetOrDestroy()) { |
| 646 DVLOG(1) << __func__ << ": error while draining"; | 645 DVLOG(1) << __func__ << ": error while draining"; |
| 647 state_ = ERROR; | 646 state_ = ERROR; |
| 648 OnDrainCompleted(); | 647 OnDrainCompleted(); |
| 649 } else { | 648 } else { |
| 650 NOTIFY_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); | 649 NOTIFY_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); |
| 651 } | 650 } |
| 652 return false; | 651 return false; |
| 653 | 652 |
| 654 case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: | 653 case MEDIA_CODEC_TRY_AGAIN_LATER: |
| 655 return false; | 654 return false; |
| 656 | 655 |
| 657 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { | 656 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { |
| 658 // An OUTPUT_FORMAT_CHANGED is not reported after flush() if the frame | 657 // An OUTPUT_FORMAT_CHANGED is not reported after flush() if the frame |
| 659 // size does not change. Therefore we have to keep track on the format | 658 // size does not change. Therefore we have to keep track on the format |
| 660 // even if draining, unless we are draining for destroy. | 659 // even if draining, unless we are draining for destroy. |
| 661 if (drain_type_ == DRAIN_FOR_DESTROY) | 660 if (drain_type_ == DRAIN_FOR_DESTROY) |
| 662 return true; // ignore | 661 return true; // ignore |
| 663 | 662 |
| 664 if (media_codec_->GetOutputSize(&size_) != MEDIA_CODEC_OK) { | 663 if (media_codec_->GetOutputSize(&size_) != MEDIA_CODEC_OK) { |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 958 | 957 |
| 959 base::Optional<TaskType> task_type = | 958 base::Optional<TaskType> task_type = |
| 960 AVDACodecAllocator::Instance()->TaskTypeForAllocation(); | 959 AVDACodecAllocator::Instance()->TaskTypeForAllocation(); |
| 961 if (!task_type) { | 960 if (!task_type) { |
| 962 // If there is no free thread, then just fail. | 961 // If there is no free thread, then just fail. |
| 963 OnCodecConfigured(nullptr); | 962 OnCodecConfigured(nullptr); |
| 964 return; | 963 return; |
| 965 } | 964 } |
| 966 | 965 |
| 967 codec_config_->task_type = task_type.value(); | 966 codec_config_->task_type = task_type.value(); |
| 968 std::unique_ptr<VideoCodecBridge> media_codec = | 967 std::unique_ptr<MediaCodecBridge> media_codec = |
| 969 AVDACodecAllocator::Instance()->CreateMediaCodecSync(codec_config_); | 968 AVDACodecAllocator::Instance()->CreateMediaCodecSync(codec_config_); |
| 970 // Note that |media_codec| might be null, which will NotifyError. | 969 // Note that |media_codec| might be null, which will NotifyError. |
| 971 OnCodecConfigured(std::move(media_codec)); | 970 OnCodecConfigured(std::move(media_codec)); |
| 972 } | 971 } |
| 973 | 972 |
| 974 void AndroidVideoDecodeAccelerator::OnCodecConfigured( | 973 void AndroidVideoDecodeAccelerator::OnCodecConfigured( |
| 975 std::unique_ptr<VideoCodecBridge> media_codec) { | 974 std::unique_ptr<MediaCodecBridge> media_codec) { |
| 976 DCHECK(thread_checker_.CalledOnValidThread()); | 975 DCHECK(thread_checker_.CalledOnValidThread()); |
| 977 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); | 976 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); |
| 978 | 977 |
| 979 // If we are supposed to notify that initialization is complete, then do so | 978 // If we are supposed to notify that initialization is complete, then do so |
| 980 // before returning. Otherwise, this is a reconfiguration. | 979 // before returning. Otherwise, this is a reconfiguration. |
| 981 | 980 |
| 982 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec, | 981 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec, |
| 983 // then the codec is already invalid so we return early and drop it. | 982 // then the codec is already invalid so we return early and drop it. |
| 984 // TODO(liberato): We're going to drop the codec when |media_codec| goes out | 983 // TODO(liberato): We're going to drop the codec when |media_codec| goes out |
| 985 // of scope, on this thread. We really should post it to the proper thread | 984 // of scope, on this thread. We really should post it to the proper thread |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1440 // support for it. Let libvpx decode it, and save a MediaCodec instance. | 1439 // support for it. Let libvpx decode it, and save a MediaCodec instance. |
| 1441 // Note that we allow it anyway for encrypted content, since we push a | 1440 // Note that we allow it anyway for encrypted content, since we push a |
| 1442 // separate profile for that. | 1441 // separate profile for that. |
| 1443 profile.min_resolution.SetSize(480, 360); | 1442 profile.min_resolution.SetSize(480, 360); |
| 1444 profile.max_resolution.SetSize(3840, 2160); | 1443 profile.max_resolution.SetSize(3840, 2160); |
| 1445 // If we know MediaCodec will just create a software codec, prefer our | 1444 // If we know MediaCodec will just create a software codec, prefer our |
| 1446 // internal software decoder instead. It's more up to date and secured | 1445 // internal software decoder instead. It's more up to date and secured |
| 1447 // within the renderer sandbox. However if the content is encrypted, we | 1446 // within the renderer sandbox. However if the content is encrypted, we |
| 1448 // must use MediaCodec anyways since MediaDrm offers no way to decrypt | 1447 // must use MediaCodec anyways since MediaDrm offers no way to decrypt |
| 1449 // the buffers and let us use our internal software decoders. | 1448 // the buffers and let us use our internal software decoders. |
| 1450 profile.encrypted_only = | 1449 profile.encrypted_only = MediaCodecUtil::IsKnownUnaccelerated( |
| 1451 VideoCodecBridge::IsKnownUnaccelerated(kCodecVP8, MEDIA_CODEC_DECODER); | 1450 kCodecVP8, MediaCodecDirection::DECODER); |
| 1452 profiles.push_back(profile); | 1451 profiles.push_back(profile); |
| 1453 | 1452 |
| 1454 // Always allow encrypted content, even at low resolutions. | 1453 // Always allow encrypted content, even at low resolutions. |
| 1455 profile.min_resolution.SetSize(0, 0); | 1454 profile.min_resolution.SetSize(0, 0); |
| 1456 profile.encrypted_only = true; | 1455 profile.encrypted_only = true; |
| 1457 profiles.push_back(profile); | 1456 profiles.push_back(profile); |
| 1458 } | 1457 } |
| 1459 | 1458 |
| 1460 if (MediaCodecUtil::IsVp9DecoderAvailable()) { | 1459 if (MediaCodecUtil::IsVp9DecoderAvailable()) { |
| 1461 const VideoCodecProfile profile_types[] = { | 1460 const VideoCodecProfile profile_types[] = { |
| 1462 VP9PROFILE_PROFILE0, VP9PROFILE_PROFILE1, VP9PROFILE_PROFILE2, | 1461 VP9PROFILE_PROFILE0, VP9PROFILE_PROFILE1, VP9PROFILE_PROFILE2, |
| 1463 VP9PROFILE_PROFILE3, VIDEO_CODEC_PROFILE_UNKNOWN}; | 1462 VP9PROFILE_PROFILE3, VIDEO_CODEC_PROFILE_UNKNOWN}; |
| 1464 const bool is_known_unaccelerated = | 1463 const bool is_known_unaccelerated = MediaCodecUtil::IsKnownUnaccelerated( |
| 1465 VideoCodecBridge::IsKnownUnaccelerated(kCodecVP9, MEDIA_CODEC_DECODER); | 1464 kCodecVP9, MediaCodecDirection::DECODER); |
| 1466 for (int i = 0; profile_types[i] != VIDEO_CODEC_PROFILE_UNKNOWN; i++) { | 1465 for (int i = 0; profile_types[i] != VIDEO_CODEC_PROFILE_UNKNOWN; i++) { |
| 1467 SupportedProfile profile; | 1466 SupportedProfile profile; |
| 1468 // Limit to 360p, like we do for vp8. See above. | 1467 // Limit to 360p, like we do for vp8. See above. |
| 1469 profile.min_resolution.SetSize(480, 360); | 1468 profile.min_resolution.SetSize(480, 360); |
| 1470 profile.max_resolution.SetSize(3840, 2160); | 1469 profile.max_resolution.SetSize(3840, 2160); |
| 1471 // If we know MediaCodec will just create a software codec, prefer our | 1470 // If we know MediaCodec will just create a software codec, prefer our |
| 1472 // internal software decoder instead. It's more up to date and secured | 1471 // internal software decoder instead. It's more up to date and secured |
| 1473 // within the renderer sandbox. However if the content is encrypted, we | 1472 // within the renderer sandbox. However if the content is encrypted, we |
| 1474 // must use MediaCodec anyways since MediaDrm offers no way to decrypt | 1473 // must use MediaCodec anyways since MediaDrm offers no way to decrypt |
| 1475 // the buffers and let us use our internal software decoders. | 1474 // the buffers and let us use our internal software decoders. |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1593 if (!media_codec_) | 1592 if (!media_codec_) |
| 1594 return; | 1593 return; |
| 1595 | 1594 |
| 1596 picture_buffer_manager_.CodecChanged(nullptr); | 1595 picture_buffer_manager_.CodecChanged(nullptr); |
| 1597 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | 1596 AVDACodecAllocator::Instance()->ReleaseMediaCodec( |
| 1598 std::move(media_codec_), codec_config_->task_type, config_.surface_id); | 1597 std::move(media_codec_), codec_config_->task_type, config_.surface_id); |
| 1599 last_release_task_type_ = codec_config_->task_type; | 1598 last_release_task_type_ = codec_config_->task_type; |
| 1600 } | 1599 } |
| 1601 | 1600 |
| 1602 } // namespace media | 1601 } // namespace media |
| OLD | NEW |