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 "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 <array> | |
| 9 #include <memory> | 10 #include <memory> |
| 10 | 11 |
| 11 #include "base/android/build_info.h" | 12 #include "base/android/build_info.h" |
| 12 #include "base/auto_reset.h" | 13 #include "base/auto_reset.h" |
| 13 #include "base/bind.h" | 14 #include "base/bind.h" |
| 14 #include "base/bind_helpers.h" | 15 #include "base/bind_helpers.h" |
| 15 #include "base/callback_helpers.h" | 16 #include "base/callback_helpers.h" |
| 16 #include "base/command_line.h" | 17 #include "base/command_line.h" |
| 17 #include "base/lazy_instance.h" | 18 #include "base/lazy_instance.h" |
| 18 #include "base/logging.h" | 19 #include "base/logging.h" |
| 19 #include "base/message_loop/message_loop.h" | 20 #include "base/message_loop/message_loop.h" |
| 20 #include "base/metrics/histogram.h" | 21 #include "base/metrics/histogram.h" |
| 21 #include "base/sys_info.h" | 22 #include "base/sys_info.h" |
| 22 #include "base/task_runner_util.h" | 23 #include "base/task_runner_util.h" |
| 23 #include "base/threading/thread_checker.h" | 24 #include "base/threading/thread_checker.h" |
| 24 #include "base/threading/thread_task_runner_handle.h" | 25 #include "base/threading/thread_task_runner_handle.h" |
| 25 #include "base/trace_event/trace_event.h" | 26 #include "base/trace_event/trace_event.h" |
| 26 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 27 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 27 #include "gpu/command_buffer/service/mailbox_manager.h" | 28 #include "gpu/command_buffer/service/mailbox_manager.h" |
| 28 #include "gpu/ipc/service/gpu_channel.h" | 29 #include "gpu/ipc/service/gpu_channel.h" |
| 29 #include "media/base/android/media_codec_bridge.h" | 30 #include "media/base/android/media_codec_bridge.h" |
| 30 #include "media/base/android/media_codec_util.h" | 31 #include "media/base/android/media_codec_util.h" |
| 31 #include "media/base/bind_to_current_loop.h" | 32 #include "media/base/bind_to_current_loop.h" |
| 32 #include "media/base/bitstream_buffer.h" | 33 #include "media/base/bitstream_buffer.h" |
| 33 #include "media/base/limits.h" | 34 #include "media/base/limits.h" |
| 34 #include "media/base/media.h" | 35 #include "media/base/media.h" |
| 35 #include "media/base/timestamp_constants.h" | 36 #include "media/base/timestamp_constants.h" |
| 36 #include "media/base/video_decoder_config.h" | 37 #include "media/base/video_decoder_config.h" |
| 38 #include "media/formats/mp4/box_definitions.h" | |
| 37 #include "media/gpu/avda_picture_buffer_manager.h" | 39 #include "media/gpu/avda_picture_buffer_manager.h" |
| 38 #include "media/gpu/shared_memory_region.h" | 40 #include "media/gpu/shared_memory_region.h" |
| 39 #include "media/video/picture.h" | 41 #include "media/video/picture.h" |
| 40 #include "ui/gl/android/scoped_java_surface.h" | 42 #include "ui/gl/android/scoped_java_surface.h" |
| 41 #include "ui/gl/android/surface_texture.h" | 43 #include "ui/gl/android/surface_texture.h" |
| 42 #include "ui/gl/gl_bindings.h" | 44 #include "ui/gl/gl_bindings.h" |
| 43 | 45 |
| 44 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 46 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 45 #include "media/mojo/services/mojo_cdm_service.h" | 47 #include "media/mojo/services/mojo_cdm_service.h" |
| 46 #endif | 48 #endif |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 // or if the stream is encrypted. | 499 // or if the stream is encrypted. |
| 498 if (IsMediaCodecSoftwareDecodingForbidden() && | 500 if (IsMediaCodecSoftwareDecodingForbidden() && |
| 499 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec_, | 501 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec_, |
| 500 MEDIA_CODEC_DECODER)) { | 502 MEDIA_CODEC_DECODER)) { |
| 501 DVLOG(1) << "Initialization failed: " | 503 DVLOG(1) << "Initialization failed: " |
| 502 << (codec_config_->codec_ == kCodecVP8 ? "vp8" : "vp9") | 504 << (codec_config_->codec_ == kCodecVP8 ? "vp8" : "vp9") |
| 503 << " is not hardware accelerated"; | 505 << " is not hardware accelerated"; |
| 504 return false; | 506 return false; |
| 505 } | 507 } |
| 506 | 508 |
| 509 SetCsd(config.extra_data); | |
| 510 | |
| 507 auto gles_decoder = get_gles2_decoder_cb_.Run(); | 511 auto gles_decoder = get_gles2_decoder_cb_.Run(); |
| 508 if (!gles_decoder) { | 512 if (!gles_decoder) { |
| 509 LOG(ERROR) << "Failed to get gles2 decoder instance."; | 513 LOG(ERROR) << "Failed to get gles2 decoder instance."; |
| 510 return false; | 514 return false; |
| 511 } | 515 } |
| 512 | 516 |
| 513 // If we're low on resources, we may decide to defer creation of the surface | 517 // If we're low on resources, we may decide to defer creation of the surface |
| 514 // until the codec is actually used. | 518 // until the codec is actually used. |
| 515 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(config_.surface_id, | 519 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(config_.surface_id, |
| 516 codec_config_->codec_)) { | 520 codec_config_->codec_)) { |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1140 : nullptr; | 1144 : nullptr; |
| 1141 | 1145 |
| 1142 // |needs_protected_surface_| implies encrypted stream. | 1146 // |needs_protected_surface_| implies encrypted stream. |
| 1143 DCHECK(!codec_config->needs_protected_surface_ || media_crypto); | 1147 DCHECK(!codec_config->needs_protected_surface_ || media_crypto); |
| 1144 | 1148 |
| 1145 const bool require_software_codec = !codec_config->allow_autodetection_; | 1149 const bool require_software_codec = !codec_config->allow_autodetection_; |
| 1146 | 1150 |
| 1147 std::unique_ptr<VideoCodecBridge> codec(VideoCodecBridge::CreateDecoder( | 1151 std::unique_ptr<VideoCodecBridge> codec(VideoCodecBridge::CreateDecoder( |
| 1148 codec_config->codec_, codec_config->needs_protected_surface_, | 1152 codec_config->codec_, codec_config->needs_protected_surface_, |
| 1149 codec_config->initial_expected_coded_size_, | 1153 codec_config->initial_expected_coded_size_, |
| 1150 codec_config->surface_.j_surface().obj(), media_crypto, true, | 1154 codec_config->surface_.j_surface().obj(), media_crypto, |
| 1151 require_software_codec)); | 1155 codec_config->csd0_, codec_config->csd1_, true, require_software_codec)); |
| 1152 | 1156 |
| 1153 return codec; | 1157 return codec; |
| 1154 } | 1158 } |
| 1155 | 1159 |
| 1156 void AndroidVideoDecodeAccelerator::OnCodecConfigured( | 1160 void AndroidVideoDecodeAccelerator::OnCodecConfigured( |
| 1157 std::unique_ptr<VideoCodecBridge> media_codec) { | 1161 std::unique_ptr<VideoCodecBridge> media_codec) { |
| 1158 DCHECK(thread_checker_.CalledOnValidThread()); | 1162 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1159 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); | 1163 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); |
| 1160 | 1164 |
| 1161 // Record one instance of the codec being initialized. | 1165 // Record one instance of the codec being initialized. |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1593 // the stored value as a proxy for whether the MediaCodec is software backed | 1597 // the stored value as a proxy for whether the MediaCodec is software backed |
| 1594 // or not. | 1598 // or not. |
| 1595 if (!codec_config_->allow_autodetection_) { | 1599 if (!codec_config_->allow_autodetection_) { |
| 1596 media_codec_.reset(); | 1600 media_codec_.reset(); |
| 1597 } else { | 1601 } else { |
| 1598 g_avda_manager.Get().ConstructionTaskRunner()->DeleteSoon( | 1602 g_avda_manager.Get().ConstructionTaskRunner()->DeleteSoon( |
| 1599 FROM_HERE, media_codec_.release()); | 1603 FROM_HERE, media_codec_.release()); |
| 1600 } | 1604 } |
| 1601 } | 1605 } |
| 1602 | 1606 |
| 1607 void AndroidVideoDecodeAccelerator::SetCsd( | |
| 1608 const std::vector<uint8_t>& extra_data) { | |
| 1609 DCHECK_NE(codec_config_->codec_, kUnknownVideoCodec); | |
| 1610 | |
| 1611 // We currently only set csd for H264. | |
| 1612 if (codec_config_->codec_ != kCodecH264 || extra_data.empty()) | |
|
sandersd (OOO until July 31)
2016/09/27 20:03:16
I don't like this dependency, it seems to me that
watk
2016/09/27 21:44:36
Done.
| |
| 1613 return; | |
| 1614 | |
| 1615 mp4::AVCDecoderConfigurationRecord record; | |
| 1616 if (!record.Parse(extra_data.data(), extra_data.size())) { | |
| 1617 DVLOG(1) << "Failed to parse the AVCC."; | |
| 1618 return; | |
|
sandersd (OOO until July 31)
2016/09/27 20:03:16
Perhaps we should return a bool? Explicitly ignori
watk
2016/09/27 21:44:36
Done.
| |
| 1619 } | |
| 1620 | |
| 1621 const std::array<uint8_t, 4> prefix = {0, 0, 0, 1}; | |
| 1622 for (const std::vector<uint8_t>& sps : record.sps_list) { | |
| 1623 auto& csd0 = codec_config_->csd0_; | |
| 1624 csd0.insert(csd0.end(), prefix.begin(), prefix.end()); | |
| 1625 csd0.insert(csd0.end(), sps.begin(), sps.end()); | |
| 1626 } | |
| 1627 | |
| 1628 for (const std::vector<uint8_t>& pps : record.pps_list) { | |
| 1629 auto& csd1 = codec_config_->csd1_; | |
| 1630 csd1.insert(csd1.end(), prefix.begin(), prefix.end()); | |
| 1631 csd1.insert(csd1.end(), pps.begin(), pps.end()); | |
| 1632 } | |
| 1633 } | |
| 1634 | |
| 1603 // static | 1635 // static |
| 1604 VideoDecodeAccelerator::Capabilities | 1636 VideoDecodeAccelerator::Capabilities |
| 1605 AndroidVideoDecodeAccelerator::GetCapabilities( | 1637 AndroidVideoDecodeAccelerator::GetCapabilities( |
| 1606 const gpu::GpuPreferences& gpu_preferences) { | 1638 const gpu::GpuPreferences& gpu_preferences) { |
| 1607 Capabilities capabilities; | 1639 Capabilities capabilities; |
| 1608 SupportedProfiles& profiles = capabilities.supported_profiles; | 1640 SupportedProfiles& profiles = capabilities.supported_profiles; |
| 1609 | 1641 |
| 1610 if (MediaCodecUtil::IsVp8DecoderAvailable()) { | 1642 if (MediaCodecUtil::IsVp8DecoderAvailable()) { |
| 1611 SupportedProfile profile; | 1643 SupportedProfile profile; |
| 1612 profile.profile = VP8PROFILE_ANY; | 1644 profile.profile = VP8PROFILE_ANY; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1700 | 1732 |
| 1701 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() | 1733 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() |
| 1702 const { | 1734 const { |
| 1703 // Prevent MediaCodec from using its internal software decoders when we have | 1735 // Prevent MediaCodec from using its internal software decoders when we have |
| 1704 // more secure and up to date versions in the renderer process. | 1736 // more secure and up to date versions in the renderer process. |
| 1705 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || | 1737 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || |
| 1706 codec_config_->codec_ == kCodecVP9); | 1738 codec_config_->codec_ == kCodecVP9); |
| 1707 } | 1739 } |
| 1708 | 1740 |
| 1709 } // namespace media | 1741 } // namespace media |
| OLD | NEW |