diff options
56 files changed, 665 insertions, 192 deletions
diff --git a/content/browser/devtools/protocol/system_info_handler.cc b/content/browser/devtools/protocol/system_info_handler.cc index f82724a..aa32e58 100644 --- a/content/browser/devtools/protocol/system_info_handler.cc +++ b/content/browser/devtools/protocol/system_info_handler.cc @@ -56,6 +56,10 @@ class AuxGPUInfoEnumerator : public gpu::GPUInfo::Enumerator { void EndGPUDevice() override {} + void BeginVideoDecodeAcceleratorSupportedProfile() override {} + + void EndVideoDecodeAcceleratorSupportedProfile() override {} + void BeginVideoEncodeAcceleratorSupportedProfile() override {} void EndVideoEncodeAcceleratorSupportedProfile() override {} diff --git a/content/common/gpu/client/gpu_video_encode_accelerator_host.cc b/content/common/gpu/client/gpu_video_encode_accelerator_host.cc index 2082dad..214b32d 100644 --- a/content/common/gpu/client/gpu_video_encode_accelerator_host.cc +++ b/content/common/gpu/client/gpu_video_encode_accelerator_host.cc @@ -8,7 +8,7 @@ #include "base/message_loop/message_loop_proxy.h" #include "content/common/gpu/client/gpu_channel_host.h" #include "content/common/gpu/gpu_messages.h" -#include "content/common/gpu/media/gpu_video_encode_accelerator.h" +#include "content/common/gpu/media/gpu_video_accelerator_util.h" #include "media/base/video_frame.h" namespace content { @@ -69,56 +69,15 @@ void GpuVideoEncodeAcceleratorHost::OnChannelError() { NOTIFY_ERROR(kPlatformFailureError) << "OnChannelError()"; } -std::vector<media::VideoEncodeAccelerator::SupportedProfile> +media::VideoEncodeAccelerator::SupportedProfiles GpuVideoEncodeAcceleratorHost::GetSupportedProfiles() { DCHECK(CalledOnValidThread()); if (!channel_) - return std::vector<media::VideoEncodeAccelerator::SupportedProfile>(); - return ConvertGpuToMediaProfiles( + return media::VideoEncodeAccelerator::SupportedProfiles(); + return GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles( channel_->gpu_info().video_encode_accelerator_supported_profiles); } -// Make sure the enum values of media::VideoCodecProfile and -// gpu::VideoCodecProfile match. -#define STATIC_ASSERT_ENUM_MATCH(name) \ - static_assert( \ - media::name == static_cast<media::VideoCodecProfile>(gpu::name), \ - #name " value must match in media and gpu.") - -STATIC_ASSERT_ENUM_MATCH(VIDEO_CODEC_PROFILE_UNKNOWN); -STATIC_ASSERT_ENUM_MATCH(VIDEO_CODEC_PROFILE_MIN); -STATIC_ASSERT_ENUM_MATCH(H264PROFILE_BASELINE); -STATIC_ASSERT_ENUM_MATCH(H264PROFILE_MAIN); -STATIC_ASSERT_ENUM_MATCH(H264PROFILE_EXTENDED); -STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH); -STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH10PROFILE); -STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH422PROFILE); -STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH444PREDICTIVEPROFILE); -STATIC_ASSERT_ENUM_MATCH(H264PROFILE_SCALABLEBASELINE); -STATIC_ASSERT_ENUM_MATCH(H264PROFILE_SCALABLEHIGH); -STATIC_ASSERT_ENUM_MATCH(H264PROFILE_STEREOHIGH); -STATIC_ASSERT_ENUM_MATCH(H264PROFILE_MULTIVIEWHIGH); -STATIC_ASSERT_ENUM_MATCH(VP8PROFILE_ANY); -STATIC_ASSERT_ENUM_MATCH(VP9PROFILE_ANY); -STATIC_ASSERT_ENUM_MATCH(VIDEO_CODEC_PROFILE_MAX); - -std::vector<media::VideoEncodeAccelerator::SupportedProfile> -GpuVideoEncodeAcceleratorHost::ConvertGpuToMediaProfiles(const std::vector< - gpu::VideoEncodeAcceleratorSupportedProfile>& gpu_profiles) { - std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles; - for (size_t i = 0; i < gpu_profiles.size(); i++) { - media::VideoEncodeAccelerator::SupportedProfile profile; - profile.profile = - static_cast<media::VideoCodecProfile>(gpu_profiles[i].profile); - profile.max_resolution = gpu_profiles[i].max_resolution; - profile.max_framerate_numerator = gpu_profiles[i].max_framerate_numerator; - profile.max_framerate_denominator = - gpu_profiles[i].max_framerate_denominator; - profiles.push_back(profile); - } - return profiles; -} - bool GpuVideoEncodeAcceleratorHost::Initialize( media::VideoFrame::Format input_format, const gfx::Size& input_visible_size, diff --git a/content/common/gpu/client/gpu_video_encode_accelerator_host.h b/content/common/gpu/client/gpu_video_encode_accelerator_host.h index 021eff4..4d1e79f 100644 --- a/content/common/gpu/client/gpu_video_encode_accelerator_host.h +++ b/content/common/gpu/client/gpu_video_encode_accelerator_host.h @@ -45,16 +45,12 @@ class GpuVideoEncodeAcceleratorHost GpuVideoEncodeAcceleratorHost(GpuChannelHost* channel, CommandBufferProxyImpl* impl); - static std::vector<media::VideoEncodeAccelerator::SupportedProfile> - ConvertGpuToMediaProfiles(const std::vector< - gpu::VideoEncodeAcceleratorSupportedProfile>& gpu_profiles); - // IPC::Listener implementation. bool OnMessageReceived(const IPC::Message& message) override; void OnChannelError() override; // media::VideoEncodeAccelerator implementation. - std::vector<SupportedProfile> GetSupportedProfiles() override; + SupportedProfiles GetSupportedProfiles() override; bool Initialize(media::VideoFrame::Format input_format, const gfx::Size& input_visible_size, media::VideoCodecProfile output_profile, diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h index 21498900..d984ac3 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h @@ -78,12 +78,12 @@ IPC_STRUCT_BEGIN(GPUCreateCommandBufferConfig) IPC_STRUCT_END() IPC_STRUCT_BEGIN(GpuMsg_CreateGpuMemoryBuffer_Params) -IPC_STRUCT_MEMBER(int32, id) -IPC_STRUCT_MEMBER(gfx::Size, size) -IPC_STRUCT_MEMBER(gfx::GpuMemoryBuffer::Format, format) -IPC_STRUCT_MEMBER(gfx::GpuMemoryBuffer::Usage, usage) -IPC_STRUCT_MEMBER(int32, client_id) -IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, surface_handle) + IPC_STRUCT_MEMBER(int32, id) + IPC_STRUCT_MEMBER(gfx::Size, size) + IPC_STRUCT_MEMBER(gfx::GpuMemoryBuffer::Format, format) + IPC_STRUCT_MEMBER(gfx::GpuMemoryBuffer::Usage, usage) + IPC_STRUCT_MEMBER(int32, client_id) + IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, surface_handle) IPC_STRUCT_END() IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params) @@ -146,6 +146,12 @@ IPC_STRUCT_TRAITS_BEGIN(gpu::GPUInfo::GPUDevice) IPC_STRUCT_TRAITS_MEMBER(device_string) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(gpu::VideoDecodeAcceleratorSupportedProfile) + IPC_STRUCT_TRAITS_MEMBER(profile) + IPC_STRUCT_TRAITS_MEMBER(max_resolution) + IPC_STRUCT_TRAITS_MEMBER(min_resolution) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(gpu::VideoEncodeAcceleratorSupportedProfile) IPC_STRUCT_TRAITS_MEMBER(profile) IPC_STRUCT_TRAITS_MEMBER(max_resolution) @@ -188,6 +194,7 @@ IPC_STRUCT_TRAITS_BEGIN(gpu::GPUInfo) IPC_STRUCT_TRAITS_MEMBER(dx_diagnostics_info_state) IPC_STRUCT_TRAITS_MEMBER(dx_diagnostics) #endif + IPC_STRUCT_TRAITS_MEMBER(video_decode_accelerator_supported_profiles) IPC_STRUCT_TRAITS_MEMBER(video_encode_accelerator_supported_profiles) IPC_STRUCT_TRAITS_END() diff --git a/content/common/gpu/media/android_video_decode_accelerator.cc b/content/common/gpu/media/android_video_decode_accelerator.cc index eb01d27..06d5986 100644 --- a/content/common/gpu/media/android_video_decode_accelerator.cc +++ b/content/common/gpu/media/android_video_decode_accelerator.cc @@ -554,4 +554,20 @@ void AndroidVideoDecodeAccelerator::NotifyError( client_->NotifyError(error); } +// static +media::VideoDecodeAccelerator::SupportedProfiles +AndroidVideoDecodeAccelerator::GetSupportedProfiles() { + SupportedProfiles profiles; + if (media::VideoCodecBridge::IsKnownUnaccelerated( + media::kCodecVP8, media::MEDIA_CODEC_DECODER)) { + return profiles; + } + SupportedProfile profile; + profile.profile = media::VP8PROFILE_ANY; + profile.min_resolution.SetSize(16, 16); + profile.max_resolution.SetSize(1920, 1088); + profiles.push_back(profile); + return profiles; +} + } // namespace content diff --git a/content/common/gpu/media/android_video_decode_accelerator.h b/content/common/gpu/media/android_video_decode_accelerator.h index ae299c8..d5bacfd 100644 --- a/content/common/gpu/media/android_video_decode_accelerator.h +++ b/content/common/gpu/media/android_video_decode_accelerator.h @@ -47,6 +47,9 @@ class CONTENT_EXPORT AndroidVideoDecodeAccelerator void Destroy() override; bool CanDecodeOnIOThread() override; + static media::VideoDecodeAccelerator::SupportedProfiles + GetSupportedProfiles(); + private: enum State { NO_ERROR, diff --git a/content/common/gpu/media/android_video_encode_accelerator.cc b/content/common/gpu/media/android_video_encode_accelerator.cc index 0fe13f5..33a73e0 100644 --- a/content/common/gpu/media/android_video_encode_accelerator.cc +++ b/content/common/gpu/media/android_video_encode_accelerator.cc @@ -104,9 +104,9 @@ AndroidVideoEncodeAccelerator::~AndroidVideoEncodeAccelerator() { DCHECK(thread_checker_.CalledOnValidThread()); } -std::vector<media::VideoEncodeAccelerator::SupportedProfile> +media::VideoEncodeAccelerator::SupportedProfiles AndroidVideoEncodeAccelerator::GetSupportedProfiles() { - std::vector<SupportedProfile> profiles; + SupportedProfiles profiles; #if defined(ENABLE_WEBRTC) const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); diff --git a/content/common/gpu/media/android_video_encode_accelerator.h b/content/common/gpu/media/android_video_encode_accelerator.h index 7f2f4c0..c828de8 100644 --- a/content/common/gpu/media/android_video_encode_accelerator.h +++ b/content/common/gpu/media/android_video_encode_accelerator.h @@ -35,8 +35,8 @@ class CONTENT_EXPORT AndroidVideoEncodeAccelerator ~AndroidVideoEncodeAccelerator() override; // media::VideoEncodeAccelerator implementation. - std::vector<media::VideoEncodeAccelerator::SupportedProfile> - GetSupportedProfiles() override; + media::VideoEncodeAccelerator::SupportedProfiles GetSupportedProfiles() + override; bool Initialize(media::VideoFrame::Format format, const gfx::Size& input_visible_size, media::VideoCodecProfile output_profile, diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.cc b/content/common/gpu/media/dxva_video_decode_accelerator.cc index 801ff57..9431e71 100644 --- a/content/common/gpu/media/dxva_video_decode_accelerator.cc +++ b/content/common/gpu/media/dxva_video_decode_accelerator.cc @@ -103,6 +103,14 @@ DEFINE_GUID(MF_XVP_PLAYBACK_MODE, 0x3c5d293f, 0xad67, 0x4e29, 0xaf, 0x12, namespace content { +static const media::VideoCodecProfile kSupportedProfiles[] = { + media::H264PROFILE_BASELINE, + media::H264PROFILE_MAIN, + media::H264PROFILE_HIGH, + media::VP8PROFILE_ANY, + media::VP9PROFILE_ANY +}; + CreateDXGIDeviceManager DXVAVideoDecodeAccelerator::create_dxgi_device_manager_ = NULL; @@ -534,11 +542,14 @@ bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, main_thread_task_runner_ = base::MessageLoop::current()->task_runner(); - if (profile != media::H264PROFILE_BASELINE && - profile != media::H264PROFILE_MAIN && - profile != media::H264PROFILE_HIGH && - profile != media::VP8PROFILE_ANY && - profile != media::VP9PROFILE_ANY) { + bool profile_supported = false; + for (const auto& supported_profile : kSupportedProfiles) { + if (profile == supported_profile) { + profile_supported = true; + break; + } + } + if (!profile_supported) { RETURN_AND_NOTIFY_ON_FAILURE(false, "Unsupported h.264, vp8, or vp9 profile", PLATFORM_FAILURE, false); } @@ -911,6 +922,25 @@ GLenum DXVAVideoDecodeAccelerator::GetSurfaceInternalFormat() const { return GL_BGRA_EXT; } +// static +media::VideoDecodeAccelerator::SupportedProfiles +DXVAVideoDecodeAccelerator::GetSupportedProfiles() { + // TODO(henryhsu): Need to ensure the profiles are actually supported. + SupportedProfiles profiles; + for (const auto& supported_profile : kSupportedProfiles) { + SupportedProfile profile; + profile.profile = supported_profile; + // Windows Media Foundation H.264 decoding does not support decoding videos + // with any dimension smaller than 48 pixels: + // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815 + profile.min_resolution.SetSize(48, 48); + // Use 1088 to account for 16x16 macroblocks. + profile.max_resolution.SetSize(1920, 1088); + profiles.push_back(profile); + } + return profiles; +} + bool DXVAVideoDecodeAccelerator::InitDecoder(media::VideoCodecProfile profile) { HMODULE decoder_dll = NULL; diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.h b/content/common/gpu/media/dxva_video_decode_accelerator.h index e98f613..0cb9afb 100644 --- a/content/common/gpu/media/dxva_video_decode_accelerator.h +++ b/content/common/gpu/media/dxva_video_decode_accelerator.h @@ -75,6 +75,9 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator bool CanDecodeOnIOThread() override; GLenum GetSurfaceInternalFormat() const override; + static media::VideoDecodeAccelerator::SupportedProfiles + GetSupportedProfiles(); + private: typedef void* EGLConfig; typedef void* EGLSurface; diff --git a/content/common/gpu/media/gpu_video_accelerator_util.cc b/content/common/gpu/media/gpu_video_accelerator_util.cc new file mode 100644 index 0000000..d23c192 --- /dev/null +++ b/content/common/gpu/media/gpu_video_accelerator_util.cc @@ -0,0 +1,133 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/common/gpu/media/gpu_video_accelerator_util.h" + +namespace content { + +// Make sure the enum values of media::VideoCodecProfile and +// gpu::VideoCodecProfile match. +#define STATIC_ASSERT_ENUM_MATCH(name) \ + static_assert( \ + media::name == static_cast<media::VideoCodecProfile>(gpu::name), \ + #name " value must match in media and gpu.") + +STATIC_ASSERT_ENUM_MATCH(VIDEO_CODEC_PROFILE_UNKNOWN); +STATIC_ASSERT_ENUM_MATCH(VIDEO_CODEC_PROFILE_MIN); +STATIC_ASSERT_ENUM_MATCH(H264PROFILE_BASELINE); +STATIC_ASSERT_ENUM_MATCH(H264PROFILE_MAIN); +STATIC_ASSERT_ENUM_MATCH(H264PROFILE_EXTENDED); +STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH); +STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH10PROFILE); +STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH422PROFILE); +STATIC_ASSERT_ENUM_MATCH(H264PROFILE_HIGH444PREDICTIVEPROFILE); +STATIC_ASSERT_ENUM_MATCH(H264PROFILE_SCALABLEBASELINE); +STATIC_ASSERT_ENUM_MATCH(H264PROFILE_SCALABLEHIGH); +STATIC_ASSERT_ENUM_MATCH(H264PROFILE_STEREOHIGH); +STATIC_ASSERT_ENUM_MATCH(H264PROFILE_MULTIVIEWHIGH); +STATIC_ASSERT_ENUM_MATCH(VP8PROFILE_ANY); +STATIC_ASSERT_ENUM_MATCH(VP9PROFILE_ANY); +STATIC_ASSERT_ENUM_MATCH(VIDEO_CODEC_PROFILE_MAX); + +// static +media::VideoDecodeAccelerator::SupportedProfiles +GpuVideoAcceleratorUtil::ConvertGpuToMediaDecodeProfiles(const + gpu::VideoDecodeAcceleratorSupportedProfiles& gpu_profiles) { + media::VideoDecodeAccelerator::SupportedProfiles profiles; + for (const auto& gpu_profile : gpu_profiles) { + media::VideoDecodeAccelerator::SupportedProfile profile; + profile.profile = + static_cast<media::VideoCodecProfile>(gpu_profile.profile); + profile.max_resolution = gpu_profile.max_resolution; + profile.min_resolution = gpu_profile.min_resolution; + profiles.push_back(profile); + } + return profiles; +} + +// static +gpu::VideoDecodeAcceleratorSupportedProfiles +GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeProfiles(const + media::VideoDecodeAccelerator::SupportedProfiles& media_profiles) { + gpu::VideoDecodeAcceleratorSupportedProfiles profiles; + for (const auto& media_profile : media_profiles) { + gpu::VideoDecodeAcceleratorSupportedProfile profile; + profile.profile = + static_cast<gpu::VideoCodecProfile>(media_profile.profile); + profile.max_resolution = media_profile.max_resolution; + profile.min_resolution = media_profile.min_resolution; + profiles.push_back(profile); + } + return profiles; +} + +// static +media::VideoEncodeAccelerator::SupportedProfiles +GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles(const + gpu::VideoEncodeAcceleratorSupportedProfiles& gpu_profiles) { + media::VideoEncodeAccelerator::SupportedProfiles profiles; + for (const auto& gpu_profile : gpu_profiles) { + media::VideoEncodeAccelerator::SupportedProfile profile; + profile.profile = + static_cast<media::VideoCodecProfile>(gpu_profile.profile); + profile.max_resolution = gpu_profile.max_resolution; + profile.max_framerate_numerator = gpu_profile.max_framerate_numerator; + profile.max_framerate_denominator = gpu_profile.max_framerate_denominator; + profiles.push_back(profile); + } + return profiles; +} + +// static +gpu::VideoEncodeAcceleratorSupportedProfiles +GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(const + media::VideoEncodeAccelerator::SupportedProfiles& media_profiles) { + gpu::VideoEncodeAcceleratorSupportedProfiles profiles; + for (const auto& media_profile : media_profiles) { + gpu::VideoEncodeAcceleratorSupportedProfile profile; + profile.profile = + static_cast<gpu::VideoCodecProfile>(media_profile.profile); + profile.max_resolution = media_profile.max_resolution; + profile.max_framerate_numerator = media_profile.max_framerate_numerator; + profile.max_framerate_denominator = media_profile.max_framerate_denominator; + profiles.push_back(profile); + } + return profiles; +} + +// static +void GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles( + const media::VideoDecodeAccelerator::SupportedProfiles& new_profiles, + media::VideoDecodeAccelerator::SupportedProfiles* media_profiles) { + for (const auto& profile : new_profiles) { + bool duplicate = false; + for (const auto& media_profile : *media_profiles) { + if (media_profile.profile == profile.profile) { + duplicate = true; + break; + } + } + if (!duplicate) + media_profiles->push_back(profile); + } +} + +// static +void GpuVideoAcceleratorUtil::InsertUniqueEncodeProfiles( + const media::VideoEncodeAccelerator::SupportedProfiles& new_profiles, + media::VideoEncodeAccelerator::SupportedProfiles* media_profiles) { + for (const auto& profile : new_profiles) { + bool duplicate = false; + for (const auto& media_profile : *media_profiles) { + if (media_profile.profile == profile.profile) { + duplicate = true; + break; + } + } + if (!duplicate) + media_profiles->push_back(profile); + } +} + +} // namespace content diff --git a/content/common/gpu/media/gpu_video_accelerator_util.h b/content/common/gpu/media/gpu_video_accelerator_util.h new file mode 100644 index 0000000..28b11d1 --- /dev/null +++ b/content/common/gpu/media/gpu_video_accelerator_util.h @@ -0,0 +1,53 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_ACCELERATOR_UTIL_H_ +#define CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_ACCELERATOR_UTIL_H_ + +#include <vector> + +#include "gpu/config/gpu_info.h" +#include "media/video/video_decode_accelerator.h" +#include "media/video/video_encode_accelerator.h" + +namespace content { + +class GpuVideoAcceleratorUtil { + public: + // Convert decoder gpu profiles to media profiles. + static media::VideoDecodeAccelerator::SupportedProfiles + ConvertGpuToMediaDecodeProfiles(const + gpu::VideoDecodeAcceleratorSupportedProfiles& gpu_profiles); + + // Convert decoder media profiles to gpu profiles. + static gpu::VideoDecodeAcceleratorSupportedProfiles + ConvertMediaToGpuDecodeProfiles(const + media::VideoDecodeAccelerator::SupportedProfiles& media_profiles); + + // Convert encoder gpu profiles to media profiles. + static media::VideoEncodeAccelerator::SupportedProfiles + ConvertGpuToMediaEncodeProfiles(const + gpu::VideoEncodeAcceleratorSupportedProfiles& gpu_profiles); + + // Convert encoder media profiles to gpu profiles. + static gpu::VideoEncodeAcceleratorSupportedProfiles + ConvertMediaToGpuEncodeProfiles(const + media::VideoEncodeAccelerator::SupportedProfiles& media_profiles); + + // Insert |new_profiles| into |media_profiles|, ensuring no duplicates are + // inserted. + static void InsertUniqueDecodeProfiles( + const media::VideoDecodeAccelerator::SupportedProfiles& new_profiles, + media::VideoDecodeAccelerator::SupportedProfiles* media_profiles); + + // Insert |new_profiles| into |media_profiles|, ensuring no duplicates are + // inserted. + static void InsertUniqueEncodeProfiles( + const media::VideoEncodeAccelerator::SupportedProfiles& new_profiles, + media::VideoEncodeAccelerator::SupportedProfiles* media_profiles); +}; + +} // namespace content + +#endif // CONTENT_COMMON_GPU_MEDIA_GPU_VIDEO_ACCELERATOR_UTIL_H_ diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc index 436428a..0e8af7f 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.cc +++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc @@ -15,6 +15,7 @@ #include "content/common/gpu/gpu_channel.h" #include "content/common/gpu/gpu_messages.h" +#include "content/common/gpu/media/gpu_video_accelerator_util.h" #include "content/public/common/content_switches.h" #include "gpu/command_buffer/common/command_buffer.h" #include "ipc/ipc_message_macros.h" @@ -249,7 +250,8 @@ void GpuVideoDecodeAccelerator::Initialize( #endif // Array of Create..VDA() function pointers, maybe applicable to the current - // platform. This list is ordered by priority of use. + // platform. This list is ordered by priority of use and it should be the + // same as the order of querying supported profiles of VDAs. const GpuVideoDecodeAccelerator::CreateVDAFp create_vda_fps[] = { &GpuVideoDecodeAccelerator::CreateDXVAVDA, &GpuVideoDecodeAccelerator::CreateV4L2VDA, @@ -383,6 +385,39 @@ GpuVideoDecodeAccelerator::CreateAndroidVDA() { return decoder.Pass(); } +// static +gpu::VideoDecodeAcceleratorSupportedProfiles +GpuVideoDecodeAccelerator::GetSupportedProfiles() { + media::VideoDecodeAccelerator::SupportedProfiles profiles; + const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); + if (cmd_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) + return gpu::VideoDecodeAcceleratorSupportedProfiles(); + + // Query supported profiles for each VDA. The order of querying VDAs should + // be the same as the order of initializing VDAs. Then the returned profile + // can be initialized by corresponding VDA successfully. +#if defined(OS_WIN) + profiles = DXVAVideoDecodeAccelerator::GetSupportedProfiles(); +#elif defined(OS_CHROMEOS) + media::VideoDecodeAccelerator::SupportedProfiles vda_profiles; +#if defined(USE_V4L2_CODEC) + vda_profiles = V4L2VideoDecodeAccelerator::GetSupportedProfiles(); + GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(vda_profiles, &profiles); + vda_profiles = V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles(); + GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(vda_profiles, &profiles); +#endif +#if defined(ARCH_CPU_X86_FAMILY) + vda_profiles = VaapiVideoDecodeAccelerator::GetSupportedProfiles(); + GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(vda_profiles, &profiles); +#endif +#elif defined(OS_MACOSX) + profiles = VTVideoDecodeAccelerator::GetSupportedProfiles(); +#elif defined(OS_ANDROID) + profiles = AndroidVideoDecodeAccelerator::GetSupportedProfiles(); +#endif + return GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeProfiles(profiles); +} + // Runs on IO thread if video_decode_accelerator_->CanDecodeOnIOThread() is // true, otherwise on the main thread. void GpuVideoDecodeAccelerator::OnDecode( diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.h b/content/common/gpu/media/gpu_video_decode_accelerator.h index 33e7837..85a4652 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.h +++ b/content/common/gpu/media/gpu_video_decode_accelerator.h @@ -14,6 +14,7 @@ #include "base/synchronization/waitable_event.h" #include "content/common/gpu/gpu_command_buffer_stub.h" #include "gpu/command_buffer/service/texture_manager.h" +#include "gpu/config/gpu_info.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" #include "media/video/video_decode_accelerator.h" @@ -66,6 +67,11 @@ class GpuVideoDecodeAccelerator void Initialize(const media::VideoCodecProfile profile, IPC::Message* init_done_msg); + // Static query for supported profiles. This query calls the appropriate + // platform-specific version. The returned supported profiles vector will + // not contain duplicates. + static gpu::VideoDecodeAcceleratorSupportedProfiles GetSupportedProfiles(); + private: typedef scoped_ptr<media::VideoDecodeAccelerator>( GpuVideoDecodeAccelerator::*CreateVDAFp)(); diff --git a/content/common/gpu/media/gpu_video_encode_accelerator.cc b/content/common/gpu/media/gpu_video_encode_accelerator.cc index 20fe9c3..8fea29e 100644 --- a/content/common/gpu/media/gpu_video_encode_accelerator.cc +++ b/content/common/gpu/media/gpu_video_encode_accelerator.cc @@ -14,6 +14,7 @@ #include "build/build_config.h" #include "content/common/gpu/gpu_channel.h" #include "content/common/gpu/gpu_messages.h" +#include "content/common/gpu/media/gpu_video_accelerator_util.h" #include "content/public/common/content_switches.h" #include "ipc/ipc_message_macros.h" #include "media/base/limits.h" @@ -163,9 +164,9 @@ void GpuVideoEncodeAccelerator::OnWillDestroyStub() { } // static -std::vector<gpu::VideoEncodeAcceleratorSupportedProfile> +gpu::VideoEncodeAcceleratorSupportedProfiles GpuVideoEncodeAccelerator::GetSupportedProfiles() { - std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles; + media::VideoEncodeAccelerator::SupportedProfiles profiles; std::vector<GpuVideoEncodeAccelerator::CreateVEAFp> create_vea_fps = CreateVEAFps(); @@ -174,29 +175,12 @@ GpuVideoEncodeAccelerator::GetSupportedProfiles() { encoder = (*create_vea_fps[i])(); if (!encoder) continue; - std::vector<media::VideoEncodeAccelerator::SupportedProfile> - vea_profiles = encoder->GetSupportedProfiles(); - profiles.insert(profiles.end(), vea_profiles.begin(), vea_profiles.end()); + media::VideoEncodeAccelerator::SupportedProfiles vea_profiles = + encoder->GetSupportedProfiles(); + GpuVideoAcceleratorUtil::InsertUniqueEncodeProfiles( + vea_profiles, &profiles); } - return ConvertMediaToGpuProfiles(profiles); -} - -// static -std::vector<gpu::VideoEncodeAcceleratorSupportedProfile> -GpuVideoEncodeAccelerator::ConvertMediaToGpuProfiles(const std::vector< - media::VideoEncodeAccelerator::SupportedProfile>& media_profiles) { - std::vector<gpu::VideoEncodeAcceleratorSupportedProfile> profiles; - for (size_t i = 0; i < media_profiles.size(); i++) { - gpu::VideoEncodeAcceleratorSupportedProfile profile; - profile.profile = - static_cast<gpu::VideoCodecProfile>(media_profiles[i].profile); - profile.max_resolution = media_profiles[i].max_resolution; - profile.max_framerate_numerator = media_profiles[i].max_framerate_numerator; - profile.max_framerate_denominator = - media_profiles[i].max_framerate_denominator; - profiles.push_back(profile); - } - return profiles; + return GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(profiles); } // static diff --git a/content/common/gpu/media/gpu_video_encode_accelerator.h b/content/common/gpu/media/gpu_video_encode_accelerator.h index e94a2dd..f535f09 100644 --- a/content/common/gpu/media/gpu_video_encode_accelerator.h +++ b/content/common/gpu/media/gpu_video_encode_accelerator.h @@ -58,12 +58,9 @@ class GpuVideoEncodeAccelerator void OnWillDestroyStub() override; // Static query for supported profiles. This query calls the appropriate - // platform-specific version. - static std::vector<gpu::VideoEncodeAcceleratorSupportedProfile> - GetSupportedProfiles(); - static std::vector<gpu::VideoEncodeAcceleratorSupportedProfile> - ConvertMediaToGpuProfiles(const std::vector< - media::VideoEncodeAccelerator::SupportedProfile>& media_profiles); + // platform-specific version. The returned supported profiles vector will + // not contain duplicates. + static gpu::VideoEncodeAcceleratorSupportedProfiles GetSupportedProfiles(); private: typedef scoped_ptr<media::VideoEncodeAccelerator>(*CreateVEAFp)(); diff --git a/content/common/gpu/media/v4l2_device.cc b/content/common/gpu/media/v4l2_device.cc index eed95cc..7629bac 100644 --- a/content/common/gpu/media/v4l2_device.cc +++ b/content/common/gpu/media/v4l2_device.cc @@ -11,11 +11,6 @@ #include "content/common/gpu/media/tegra_v4l2_device.h" #endif -// TODO(posciak): remove this once V4L2 headers are updated. -#define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') -#define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') -#define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F') - namespace content { V4L2Device::~V4L2Device() { diff --git a/content/common/gpu/media/v4l2_device.h b/content/common/gpu/media/v4l2_device.h index 2dc9eac..72af699 100644 --- a/content/common/gpu/media/v4l2_device.h +++ b/content/common/gpu/media/v4l2_device.h @@ -16,6 +16,11 @@ #include "ui/gfx/geometry/size.h" #include "ui/gl/gl_bindings.h" +// TODO(posciak): remove this once V4L2 headers are updated. +#define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') +#define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') +#define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F') + namespace content { class CONTENT_EXPORT V4L2Device diff --git a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc index 3fcba61..53f77b5 100644 --- a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc +++ b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc @@ -2477,4 +2477,45 @@ bool V4L2SliceVideoDecodeAccelerator::CanDecodeOnIOThread() { return true; } +// static +media::VideoDecodeAccelerator::SupportedProfiles +V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles() { + SupportedProfiles profiles; + scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); + if (!device) + return profiles; + + SupportedProfile profile; + profile.min_resolution.SetSize(16, 16); + // NOTE: additional autodetection logic may require updating input buffer size + // selection. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kIgnoreResolutionLimitsForAcceleratedVideoDecode)) + profile.max_resolution.SetSize(4096, 2160); + else + profile.max_resolution.SetSize(1920, 1088); + + v4l2_fmtdesc fmtdesc; + memset(&fmtdesc, 0, sizeof(fmtdesc)); + fmtdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + for (; device->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0; ++fmtdesc.index) { + switch (fmtdesc.pixelformat) { + case V4L2_PIX_FMT_H264_SLICE: + for (uint32 media_profile = media::H264PROFILE_MIN; + media_profile <= media::H264PROFILE_MAX; ++media_profile) { + profile.profile = + static_cast<media::VideoCodecProfile>(media_profile); + profiles.push_back(profile); + } + break; + case V4L2_PIX_FMT_VP8_FRAME: + profile.profile = media::VP8PROFILE_ANY; + profiles.push_back(profile); + break; + } + } + + return profiles; +} + } // namespace content diff --git a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h index 2fdefe9..b6ecf0e 100644 --- a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h +++ b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h @@ -53,6 +53,9 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator void Destroy() override; bool CanDecodeOnIOThread() override; + static media::VideoDecodeAccelerator::SupportedProfiles + GetSupportedProfiles(); + private: class V4L2H264Accelerator; class V4L2VP8Accelerator; diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_video_decode_accelerator.cc index 41b11e3..186d920 100644 --- a/content/common/gpu/media/v4l2_video_decode_accelerator.cc +++ b/content/common/gpu/media/v4l2_video_decode_accelerator.cc @@ -444,6 +444,51 @@ void V4L2VideoDecodeAccelerator::Destroy() { bool V4L2VideoDecodeAccelerator::CanDecodeOnIOThread() { return true; } +// static +media::VideoDecodeAccelerator::SupportedProfiles +V4L2VideoDecodeAccelerator::GetSupportedProfiles() { + SupportedProfiles profiles; + scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kDecoder); + if (!device) + return profiles; + + SupportedProfile profile; + profile.min_resolution.SetSize(16, 16); + // NOTE: additional autodetection logic may require updating input buffer size + // selection. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kIgnoreResolutionLimitsForAcceleratedVideoDecode)) + profile.max_resolution.SetSize(4096, 2160); + else + profile.max_resolution.SetSize(1920, 1088); + + v4l2_fmtdesc fmtdesc; + memset(&fmtdesc, 0, sizeof(fmtdesc)); + fmtdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + for (; device->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0; ++fmtdesc.index) { + switch (fmtdesc.pixelformat) { + case V4L2_PIX_FMT_H264: + for (uint32 media_profile = media::H264PROFILE_MIN; + media_profile <= media::H264PROFILE_MAX; ++media_profile) { + profile.profile = + static_cast<media::VideoCodecProfile>(media_profile); + profiles.push_back(profile); + } + break; + case V4L2_PIX_FMT_VP8: + profile.profile = media::VP8PROFILE_ANY; + profiles.push_back(profile); + break; + case V4L2_PIX_FMT_VP9: + profile.profile = media::VP9PROFILE_ANY; + profiles.push_back(profile); + break; + } + } + + return profiles; +} + void V4L2VideoDecodeAccelerator::DecodeTask( const media::BitstreamBuffer& bitstream_buffer) { DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id(); diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.h b/content/common/gpu/media/v4l2_video_decode_accelerator.h index fbb973e..d0b7d59 100644 --- a/content/common/gpu/media/v4l2_video_decode_accelerator.h +++ b/content/common/gpu/media/v4l2_video_decode_accelerator.h @@ -98,6 +98,9 @@ class CONTENT_EXPORT V4L2VideoDecodeAccelerator void Destroy() override; bool CanDecodeOnIOThread() override; + static media::VideoDecodeAccelerator::SupportedProfiles + GetSupportedProfiles(); + private: // These are rather subjectively tuned. enum { diff --git a/content/common/gpu/media/v4l2_video_encode_accelerator.cc b/content/common/gpu/media/v4l2_video_encode_accelerator.cc index f491274..d075740 100644 --- a/content/common/gpu/media/v4l2_video_encode_accelerator.cc +++ b/content/common/gpu/media/v4l2_video_encode_accelerator.cc @@ -285,9 +285,9 @@ void V4L2VideoEncodeAccelerator::Destroy() { delete this; } -std::vector<media::VideoEncodeAccelerator::SupportedProfile> +media::VideoEncodeAccelerator::SupportedProfiles V4L2VideoEncodeAccelerator::GetSupportedProfiles() { - std::vector<SupportedProfile> profiles; + SupportedProfiles profiles; SupportedProfile profile; profile.max_resolution.SetSize(1920, 1088); profile.max_framerate_numerator = 30; @@ -306,6 +306,10 @@ V4L2VideoEncodeAccelerator::GetSupportedProfiles() { profile.profile = media::VP8PROFILE_ANY; profiles.push_back(profile); break; + case V4L2_PIX_FMT_VP9: + profile.profile = media::VP9PROFILE_ANY; + profiles.push_back(profile); + break; } } diff --git a/content/common/gpu/media/v4l2_video_encode_accelerator.h b/content/common/gpu/media/v4l2_video_encode_accelerator.h index b405583..165da9d 100644 --- a/content/common/gpu/media/v4l2_video_encode_accelerator.h +++ b/content/common/gpu/media/v4l2_video_encode_accelerator.h @@ -46,8 +46,8 @@ class CONTENT_EXPORT V4L2VideoEncodeAccelerator ~V4L2VideoEncodeAccelerator() override; // media::VideoEncodeAccelerator implementation. - std::vector<media::VideoEncodeAccelerator::SupportedProfile> - GetSupportedProfiles() override; + media::VideoEncodeAccelerator::SupportedProfiles GetSupportedProfiles() + override; bool Initialize(media::VideoFrame::Format format, const gfx::Size& input_visible_size, media::VideoCodecProfile output_profile, diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator.cc index 6b8e879..de3a7b5 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.cc @@ -748,4 +748,10 @@ bool VaapiVideoDecodeAccelerator::CanDecodeOnIOThread() { return false; } +// static +media::VideoDecodeAccelerator::SupportedProfiles +VaapiVideoDecodeAccelerator::GetSupportedProfiles() { + return VaapiWrapper::GetSupportedDecodeProfiles(); +} + } // namespace content diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.h b/content/common/gpu/media/vaapi_video_decode_accelerator.h index 0ef25c5..cc7753d 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.h +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.h @@ -65,6 +65,9 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator void Destroy() override; bool CanDecodeOnIOThread() override; + static media::VideoDecodeAccelerator::SupportedProfiles + GetSupportedProfiles(); + private: // Notify the client that an error has occurred and decoding cannot continue. void NotifyError(Error error); diff --git a/content/common/gpu/media/vaapi_video_encode_accelerator.cc b/content/common/gpu/media/vaapi_video_encode_accelerator.cc index a731cb4..71cdaba 100644 --- a/content/common/gpu/media/vaapi_video_encode_accelerator.cc +++ b/content/common/gpu/media/vaapi_video_encode_accelerator.cc @@ -103,9 +103,8 @@ struct VaapiVideoEncodeAccelerator::BitstreamBufferRef { const size_t size; }; -std::vector<media::VideoEncodeAccelerator::SupportedProfile> +media::VideoEncodeAccelerator::SupportedProfiles VaapiVideoEncodeAccelerator::GetSupportedProfiles() { - return VaapiWrapper::GetSupportedEncodeProfiles(); } diff --git a/content/common/gpu/media/vaapi_video_encode_accelerator.h b/content/common/gpu/media/vaapi_video_encode_accelerator.h index 51e1801..2746a23 100644 --- a/content/common/gpu/media/vaapi_video_encode_accelerator.h +++ b/content/common/gpu/media/vaapi_video_encode_accelerator.h @@ -29,8 +29,8 @@ class CONTENT_EXPORT VaapiVideoEncodeAccelerator ~VaapiVideoEncodeAccelerator() override; // media::VideoEncodeAccelerator implementation. - std::vector<media::VideoEncodeAccelerator::SupportedProfile> - GetSupportedProfiles() override; + media::VideoEncodeAccelerator::SupportedProfiles GetSupportedProfiles() + override; bool Initialize(media::VideoFrame::Format format, const gfx::Size& input_visible_size, media::VideoCodecProfile output_profile, diff --git a/content/common/gpu/media/vaapi_wrapper.cc b/content/common/gpu/media/vaapi_wrapper.cc index 01119d0..78d382e 100644 --- a/content/common/gpu/media/vaapi_wrapper.cc +++ b/content/common/gpu/media/vaapi_wrapper.cc @@ -167,9 +167,9 @@ scoped_ptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec( } // static -std::vector<media::VideoEncodeAccelerator::SupportedProfile> +media::VideoEncodeAccelerator::SupportedProfiles VaapiWrapper::GetSupportedEncodeProfiles() { - std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles; + media::VideoEncodeAccelerator::SupportedProfiles profiles; const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); if (cmd_line->HasSwitch(switches::kDisableVaapiAcceleratedVideoEncode)) return profiles; @@ -196,6 +196,31 @@ VaapiWrapper::GetSupportedEncodeProfiles() { return profiles; } +// static +media::VideoDecodeAccelerator::SupportedProfiles +VaapiWrapper::GetSupportedDecodeProfiles() { + media::VideoDecodeAccelerator::SupportedProfiles profiles; + std::vector<ProfileInfo> decode_profile_infos = + profile_infos_.Get().GetSupportedProfileInfosForCodecMode(kDecode); + + for (size_t i = 0; i < arraysize(kProfileMap); ++i) { + VAProfile va_profile = ProfileToVAProfile(kProfileMap[i].profile, kDecode); + if (va_profile == VAProfileNone) + continue; + for (const auto& profile_info : decode_profile_infos) { + if (profile_info.va_profile == va_profile) { + media::VideoDecodeAccelerator::SupportedProfile profile; + profile.profile = kProfileMap[i].profile; + profile.max_resolution = profile_info.max_resolution; + profile.min_resolution.SetSize(16, 16); + profiles.push_back(profile); + break; + } + } + } + return profiles; +} + void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { base::AutoLock auto_lock(va_lock_); VADisplayAttribute item = {VADisplayAttribRenderMode, diff --git a/content/common/gpu/media/vaapi_wrapper.h b/content/common/gpu/media/vaapi_wrapper.h index cb55afb..cd2d2a6 100644 --- a/content/common/gpu/media/vaapi_wrapper.h +++ b/content/common/gpu/media/vaapi_wrapper.h @@ -21,6 +21,7 @@ #include "content/common/gpu/media/va_surface.h" #include "media/base/video_decoder_config.h" #include "media/base/video_frame.h" +#include "media/video/video_decode_accelerator.h" #include "media/video/video_encode_accelerator.h" #include "third_party/libva/va/va.h" #include "third_party/libva/va/va_vpp.h" @@ -67,9 +68,13 @@ class CONTENT_EXPORT VaapiWrapper { const base::Closure& report_error_to_uma_cb); // Return the supported encode profiles. - static std::vector<media::VideoEncodeAccelerator::SupportedProfile> + static media::VideoEncodeAccelerator::SupportedProfiles GetSupportedEncodeProfiles(); + // Return the supported decode profiles. + static media::VideoDecodeAccelerator::SupportedProfiles + GetSupportedDecodeProfiles(); + ~VaapiWrapper(); // Create |num_surfaces| backing surfaces in driver for VASurfaces, each diff --git a/content/common/gpu/media/vt_video_decode_accelerator.cc b/content/common/gpu/media/vt_video_decode_accelerator.cc index dbaafdb..72399c2 100644 --- a/content/common/gpu/media/vt_video_decode_accelerator.cc +++ b/content/common/gpu/media/vt_video_decode_accelerator.cc @@ -33,6 +33,19 @@ using content_common_gpu_media::StubPathMap; namespace content { +// Only H.264 with 4:2:0 chroma sampling is supported. +static const media::VideoCodecProfile kSupportedProfiles[] = { + media::H264PROFILE_BASELINE, + media::H264PROFILE_MAIN, + media::H264PROFILE_EXTENDED, + media::H264PROFILE_HIGH, + media::H264PROFILE_HIGH10PROFILE, + media::H264PROFILE_SCALABLEBASELINE, + media::H264PROFILE_SCALABLEHIGH, + media::H264PROFILE_STEREOHIGH, + media::H264PROFILE_MULTIVIEWHIGH, +}; + // Size to use for NALU length headers in AVC format (can be 1, 2, or 4). static const int kNALUHeaderLength = 4; @@ -289,13 +302,15 @@ bool VTVideoDecodeAccelerator::Initialize( if (!InitializeVideoToolbox()) return false; - // Only H.264 with 4:2:0 chroma sampling is supported. - if (profile < media::H264PROFILE_MIN || - profile > media::H264PROFILE_MAX || - profile == media::H264PROFILE_HIGH422PROFILE || - profile == media::H264PROFILE_HIGH444PREDICTIVEPROFILE) { - return false; + bool profile_supported = false; + for (const auto& supported_profile : kSupportedProfiles) { + if (profile == supported_profile) { + profile_supported = true; + break; + } } + if (!profile_supported) + return false; // Spawn a thread to handle parsing and calling VideoToolbox. if (!decoder_thread_.Start()) @@ -1032,4 +1047,18 @@ bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() { return false; } +// static +media::VideoDecodeAccelerator::SupportedProfiles +VTVideoDecodeAccelerator::GetSupportedProfiles() { + SupportedProfiles profiles; + for (const auto& supported_profile : kSupportedProfiles) { + SupportedProfile profile; + profile.profile = supported_profile; + profile.min_resolution.SetSize(480, 360); + profile.max_resolution.SetSize(4096, 2160); + profiles.push_back(profile); + } + return profiles; +} + } // namespace content diff --git a/content/common/gpu/media/vt_video_decode_accelerator.h b/content/common/gpu/media/vt_video_decode_accelerator.h index 69a8c47..0ec7114 100644 --- a/content/common/gpu/media/vt_video_decode_accelerator.h +++ b/content/common/gpu/media/vt_video_decode_accelerator.h @@ -58,6 +58,9 @@ class VTVideoDecodeAccelerator : public media::VideoDecodeAccelerator { OSStatus status, CVImageBufferRef image_buffer); + static media::VideoDecodeAccelerator::SupportedProfiles + GetSupportedProfiles(); + private: // Logged to UMA, so never reuse values. Make sure to update // VTVDASessionFailureType in histograms.xml to match. diff --git a/content/content_common.gypi b/content/content_common.gypi index c1ae9cf..d0a5c9f 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -331,6 +331,8 @@ 'common/gpu/image_transport_surface_win.cc', 'common/gpu/media/fake_video_decode_accelerator.cc', 'common/gpu/media/fake_video_decode_accelerator.h', + 'common/gpu/media/gpu_video_accelerator_util.cc', + 'common/gpu/media/gpu_video_accelerator_util.h', 'common/gpu/media/gpu_video_decode_accelerator.cc', 'common/gpu/media/gpu_video_decode_accelerator.h', 'common/gpu/media/gpu_video_encode_accelerator.cc', diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc index 76a6020..f3d3c61 100644 --- a/content/gpu/gpu_main.cc +++ b/content/gpu/gpu_main.cc @@ -24,6 +24,7 @@ #include "content/common/content_constants_internal.h" #include "content/common/gpu/gpu_config.h" #include "content/common/gpu/gpu_messages.h" +#include "content/common/gpu/media/gpu_video_decode_accelerator.h" #include "content/common/gpu/media/gpu_video_encode_accelerator.h" #include "content/common/sandbox_linux/sandbox_linux.h" #include "content/gpu/gpu_child_thread.h" @@ -336,6 +337,8 @@ int GpuMain(const MainFunctionParams& parameters) { gpu_info.sandboxed = Sandbox::SandboxIsCurrentlyActive(); #endif + gpu_info.video_decode_accelerator_supported_profiles = + content::GpuVideoDecodeAccelerator::GetSupportedProfiles(); gpu_info.video_encode_accelerator_supported_profiles = content::GpuVideoEncodeAccelerator::GetSupportedProfiles(); } else { diff --git a/content/public/renderer/video_encode_accelerator.cc b/content/public/renderer/video_encode_accelerator.cc index b1ac143..32c6772 100644 --- a/content/public/renderer/video_encode_accelerator.cc +++ b/content/public/renderer/video_encode_accelerator.cc @@ -33,12 +33,12 @@ void CreateVideoEncodeAccelerator( base::Bind(callback, encode_task_runner)); } -std::vector<media::VideoEncodeAccelerator::SupportedProfile> +media::VideoEncodeAccelerator::SupportedProfiles GetSupportedVideoEncodeAcceleratorProfiles() { scoped_refptr<media::GpuVideoAcceleratorFactories> gpu_factories = RenderThreadImpl::current()->GetGpuFactories(); if (!gpu_factories.get()) - return std::vector<media::VideoEncodeAccelerator::SupportedProfile>(); + return media::VideoEncodeAccelerator::SupportedProfiles(); return gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles(); } diff --git a/content/public/renderer/video_encode_accelerator.h b/content/public/renderer/video_encode_accelerator.h index 426b052..e98e443 100644 --- a/content/public/renderer/video_encode_accelerator.h +++ b/content/public/renderer/video_encode_accelerator.h @@ -27,8 +27,8 @@ CreateVideoEncodeAccelerator( const OnCreateVideoEncodeAcceleratorCallback& callback); // Returns list of encoding profiles supported by VideoEncodeAccelerator. -CONTENT_EXPORT std::vector<media::VideoEncodeAccelerator::SupportedProfile> -GetSupportedVideoEncodeAcceleratorProfiles(); +CONTENT_EXPORT media::VideoEncodeAccelerator::SupportedProfiles + GetSupportedVideoEncodeAcceleratorProfiles(); } // namespace content diff --git a/content/renderer/media/renderer_gpu_video_accelerator_factories.cc b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc index 23fd238..0a75c46 100644 --- a/content/renderer/media/renderer_gpu_video_accelerator_factories.cc +++ b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc @@ -12,8 +12,8 @@ #include "content/common/gpu/client/context_provider_command_buffer.h" #include "content/common/gpu/client/gl_helper.h" #include "content/common/gpu/client/gpu_channel_host.h" -#include "content/common/gpu/client/gpu_video_encode_accelerator_host.h" #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" +#include "content/common/gpu/media/gpu_video_accelerator_util.h" #include "content/renderer/render_thread_impl.h" #include "gpu/command_buffer/client/gles2_implementation.h" #include "media/video/video_decode_accelerator.h" @@ -200,10 +200,18 @@ RendererGpuVideoAcceleratorFactories::GetTaskRunner() { return task_runner_; } -std::vector<media::VideoEncodeAccelerator::SupportedProfile> +media::VideoDecodeAccelerator::SupportedProfiles +RendererGpuVideoAcceleratorFactories:: + GetVideoDecodeAcceleratorSupportedProfiles() { + return GpuVideoAcceleratorUtil::ConvertGpuToMediaDecodeProfiles( + gpu_channel_host_->gpu_info() + .video_decode_accelerator_supported_profiles); +} + +media::VideoEncodeAccelerator::SupportedProfiles RendererGpuVideoAcceleratorFactories:: GetVideoEncodeAcceleratorSupportedProfiles() { - return GpuVideoEncodeAcceleratorHost::ConvertGpuToMediaProfiles( + return GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles( gpu_channel_host_->gpu_info() .video_encode_accelerator_supported_profiles); } diff --git a/content/renderer/media/renderer_gpu_video_accelerator_factories.h b/content/renderer/media/renderer_gpu_video_accelerator_factories.h index 6398ad6..2d1299a 100644 --- a/content/renderer/media/renderer_gpu_video_accelerator_factories.h +++ b/content/renderer/media/renderer_gpu_video_accelerator_factories.h @@ -60,8 +60,11 @@ class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories void WaitSyncPoint(uint32 sync_point) override; scoped_ptr<base::SharedMemory> CreateSharedMemory(size_t size) override; scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override; + + std::vector<media::VideoDecodeAccelerator::SupportedProfile> + GetVideoDecodeAcceleratorSupportedProfiles() override; std::vector<media::VideoEncodeAccelerator::SupportedProfile> - GetVideoEncodeAcceleratorSupportedProfiles() override; + GetVideoEncodeAcceleratorSupportedProfiles() override; private: friend class base::RefCountedThreadSafe<RendererGpuVideoAcceleratorFactories>; diff --git a/content/renderer/media/rtc_video_encoder_factory.cc b/content/renderer/media/rtc_video_encoder_factory.cc index d2c5a02..d6fd5b7 100644 --- a/content/renderer/media/rtc_video_encoder_factory.cc +++ b/content/renderer/media/rtc_video_encoder_factory.cc @@ -44,7 +44,7 @@ void VEAToWebRTCCodecs( RTCVideoEncoderFactory::RTCVideoEncoderFactory( const scoped_refptr<media::GpuVideoAcceleratorFactories>& gpu_factories) : gpu_factories_(gpu_factories) { - const std::vector<media::VideoEncodeAccelerator::SupportedProfile>& profiles = + const media::VideoEncodeAccelerator::SupportedProfiles& profiles = gpu_factories_->GetVideoEncodeAcceleratorSupportedProfiles(); for (const auto& profile : profiles) VEAToWebRTCCodecs(&codecs_, profile); diff --git a/content/renderer/pepper/pepper_video_encoder_host.cc b/content/renderer/pepper/pepper_video_encoder_host.cc index 772e188..39292bb 100644 --- a/content/renderer/pepper/pepper_video_encoder_host.cc +++ b/content/renderer/pepper/pepper_video_encoder_host.cc @@ -6,7 +6,7 @@ #include "base/memory/shared_memory.h" #include "base/numerics/safe_math.h" #include "content/common/gpu/client/command_buffer_proxy_impl.h" -#include "content/common/gpu/client/gpu_video_encode_accelerator_host.h" +#include "content/common/gpu/media/gpu_video_accelerator_util.h" #include "content/common/pepper_file_util.h" #include "content/public/renderer/renderer_ppapi_host.h" #include "content/renderer/pepper/gfx_conversion.h" @@ -450,10 +450,10 @@ void PepperVideoEncoderHost::GetSupportedProfiles( std::vector<PP_VideoProfileDescription>* pp_profiles) { DCHECK(RenderThreadImpl::current()); - std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles; + media::VideoEncodeAccelerator::SupportedProfiles profiles; if (EnsureGpuChannel()) { - profiles = GpuVideoEncodeAcceleratorHost::ConvertGpuToMediaProfiles( + profiles = GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles( channel_->gpu_info().video_encode_accelerator_supported_profiles); for (media::VideoEncodeAccelerator::SupportedProfile profile : profiles) { pp_profiles->push_back(PP_FromVideoEncodeAcceleratorSupportedProfile( diff --git a/content/renderer/pepper/video_encoder_shim.cc b/content/renderer/pepper/video_encoder_shim.cc index a89f18c..8866fae 100644 --- a/content/renderer/pepper/video_encoder_shim.cc +++ b/content/renderer/pepper/video_encoder_shim.cc @@ -178,14 +178,14 @@ VideoEncoderShim::~VideoEncoderShim() { base::Owned(encoder_impl_.release()))); } -std::vector<media::VideoEncodeAccelerator::SupportedProfile> +media::VideoEncodeAccelerator::SupportedProfiles VideoEncoderShim::GetSupportedProfiles() { - media::VideoEncodeAccelerator::SupportedProfile profile = { - media::VP8PROFILE_ANY, - gfx::Size(kMaxWidth, kMaxHeight), - media::cast::kDefaultMaxFrameRate, - 1}; - std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles; + media::VideoEncodeAccelerator::SupportedProfile profile; + profile.profile = media::VP8PROFILE_ANY; + profile.max_resolution = gfx::Size(kMaxWidth, kMaxHeight); + profile.max_framerate_numerator = media::cast::kDefaultMaxFrameRate; + profile.max_framerate_denominator = 1; + media::VideoEncodeAccelerator::SupportedProfiles profiles; profiles.push_back(profile); return profiles; } diff --git a/content/renderer/pepper/video_encoder_shim.h b/content/renderer/pepper/video_encoder_shim.h index cee0fa4..29449ab 100644 --- a/content/renderer/pepper/video_encoder_shim.h +++ b/content/renderer/pepper/video_encoder_shim.h @@ -33,8 +33,8 @@ class VideoEncoderShim : public media::VideoEncodeAccelerator { ~VideoEncoderShim() override; // media::VideoEncodeAccelerator implementation. - std::vector<media::VideoEncodeAccelerator::SupportedProfile> - GetSupportedProfiles() override; + media::VideoEncodeAccelerator::SupportedProfiles GetSupportedProfiles() + override; bool Initialize(media::VideoFrame::Format input_format, const gfx::Size& input_visible_size, media::VideoCodecProfile output_profile, diff --git a/gpu/config/gpu_info.cc b/gpu/config/gpu_info.cc index 3653a10..85d26fb 100644 --- a/gpu/config/gpu_info.cc +++ b/gpu/config/gpu_info.cc @@ -6,8 +6,8 @@ namespace { -void EnumerateGPUDevice(gpu::GPUInfo::Enumerator* enumerator, - const gpu::GPUInfo::GPUDevice& device) { +void EnumerateGPUDevice(const gpu::GPUInfo::GPUDevice& device, + gpu::GPUInfo::Enumerator* enumerator) { enumerator->BeginGPUDevice(); enumerator->AddInt("vendorId", device.vendor_id); enumerator->AddInt("deviceId", device.device_id); @@ -17,9 +17,21 @@ void EnumerateGPUDevice(gpu::GPUInfo::Enumerator* enumerator, enumerator->EndGPUDevice(); } +void EnumerateVideoDecodeAcceleratorSupportedProfile( + const gpu::VideoDecodeAcceleratorSupportedProfile& profile, + gpu::GPUInfo::Enumerator* enumerator) { + enumerator->BeginVideoDecodeAcceleratorSupportedProfile(); + enumerator->AddInt("profile", profile.profile); + enumerator->AddInt("maxResolutionWidth", profile.max_resolution.width()); + enumerator->AddInt("maxResolutionHeight", profile.max_resolution.height()); + enumerator->AddInt("minResolutionWidth", profile.min_resolution.width()); + enumerator->AddInt("minResolutionHeight", profile.min_resolution.height()); + enumerator->EndVideoDecodeAcceleratorSupportedProfile(); +} + void EnumerateVideoEncodeAcceleratorSupportedProfile( - gpu::GPUInfo::Enumerator* enumerator, - const gpu::VideoEncodeAcceleratorSupportedProfile profile) { + const gpu::VideoEncodeAcceleratorSupportedProfile& profile, + gpu::GPUInfo::Enumerator* enumerator) { enumerator->BeginVideoEncodeAcceleratorSupportedProfile(); enumerator->AddInt("profile", profile.profile); enumerator->AddInt("maxResolutionWidth", profile.max_resolution.width()); @@ -101,7 +113,9 @@ void GPUInfo::EnumerateFields(Enumerator* enumerator) const { CollectInfoResult dx_diagnostics_info_state; DxDiagNode dx_diagnostics; #endif - std::vector<VideoEncodeAcceleratorSupportedProfile> + VideoDecodeAcceleratorSupportedProfiles + video_decode_accelerator_supported_profiles; + VideoEncodeAcceleratorSupportedProfiles video_encode_accelerator_supported_profiles; }; @@ -115,10 +129,9 @@ void GPUInfo::EnumerateFields(Enumerator* enumerator) const { // Required fields (according to DevTools protocol) first. enumerator->AddString("machineModelName", machine_model_name); enumerator->AddString("machineModelVersion", machine_model_version); - EnumerateGPUDevice(enumerator, gpu); - for (size_t ii = 0; ii < secondary_gpus.size(); ++ii) { - EnumerateGPUDevice(enumerator, secondary_gpus[ii]); - } + EnumerateGPUDevice(gpu, enumerator); + for (const auto& secondary_gpu: secondary_gpus) + EnumerateGPUDevice(secondary_gpu, enumerator); enumerator->BeginAuxAttributes(); enumerator->AddTimeDeltaInSecondsF("initializationTime", @@ -159,11 +172,10 @@ void GPUInfo::EnumerateFields(Enumerator* enumerator) const { enumerator->AddInt("DxDiagnosticsInfoState", dx_diagnostics_info_state); #endif // TODO(kbr): add dx_diagnostics on Windows. - for (size_t ii = 0; ii < video_encode_accelerator_supported_profiles.size(); - ++ii) { - EnumerateVideoEncodeAcceleratorSupportedProfile( - enumerator, video_encode_accelerator_supported_profiles[ii]); - } + for (const auto& profile : video_decode_accelerator_supported_profiles) + EnumerateVideoDecodeAcceleratorSupportedProfile(profile, enumerator); + for (const auto& profile : video_encode_accelerator_supported_profiles) + EnumerateVideoEncodeAcceleratorSupportedProfile(profile, enumerator); enumerator->EndAuxAttributes(); } diff --git a/gpu/config/gpu_info.h b/gpu/config/gpu_info.h index cbd8361..f377698 100644 --- a/gpu/config/gpu_info.h +++ b/gpu/config/gpu_info.h @@ -54,6 +54,15 @@ enum VideoCodecProfile { VIDEO_CODEC_PROFILE_MAX = VP9PROFILE_ANY, }; +// Specification of a decoding profile supported by a hardware decoder. +struct GPU_EXPORT VideoDecodeAcceleratorSupportedProfile { + VideoCodecProfile profile; + gfx::Size max_resolution; + gfx::Size min_resolution; +}; +using VideoDecodeAcceleratorSupportedProfiles = + std::vector<VideoDecodeAcceleratorSupportedProfile>; + // Specification of an encoding profile supported by a hardware encoder. struct GPU_EXPORT VideoEncodeAcceleratorSupportedProfile { VideoCodecProfile profile; @@ -61,6 +70,8 @@ struct GPU_EXPORT VideoEncodeAcceleratorSupportedProfile { uint32 max_framerate_numerator; uint32 max_framerate_denominator; }; +using VideoEncodeAcceleratorSupportedProfiles = + std::vector<VideoEncodeAcceleratorSupportedProfile>; struct GPU_EXPORT GPUInfo { struct GPU_EXPORT GPUDevice { @@ -206,7 +217,9 @@ struct GPU_EXPORT GPUInfo { DxDiagNode dx_diagnostics; #endif - std::vector<VideoEncodeAcceleratorSupportedProfile> + VideoDecodeAcceleratorSupportedProfiles + video_decode_accelerator_supported_profiles; + VideoEncodeAcceleratorSupportedProfiles video_encode_accelerator_supported_profiles; // Note: when adding new members, please remember to update EnumerateFields // in gpu_info.cc. @@ -232,6 +245,11 @@ struct GPU_EXPORT GPUInfo { virtual void BeginGPUDevice() = 0; virtual void EndGPUDevice() = 0; + // Markers indicating that a VideoDecodeAcceleratorSupportedProfile is + // being described. + virtual void BeginVideoDecodeAcceleratorSupportedProfile() = 0; + virtual void EndVideoDecodeAcceleratorSupportedProfile() = 0; + // Markers indicating that a VideoEncodeAcceleratorSupportedProfile is // being described. virtual void BeginVideoEncodeAcceleratorSupportedProfile() = 0; diff --git a/gpu/config/gpu_info_collector.cc b/gpu/config/gpu_info_collector.cc index c673057..2403340 100644 --- a/gpu/config/gpu_info_collector.cc +++ b/gpu/config/gpu_info_collector.cc @@ -163,6 +163,8 @@ void MergeGPUInfoGL(GPUInfo* basic_gpu_info, basic_gpu_info->direct_rendering = context_gpu_info.direct_rendering; basic_gpu_info->context_info_state = context_gpu_info.context_info_state; basic_gpu_info->initialization_time = context_gpu_info.initialization_time; + basic_gpu_info->video_decode_accelerator_supported_profiles = + context_gpu_info.video_decode_accelerator_supported_profiles; basic_gpu_info->video_encode_accelerator_supported_profiles = context_gpu_info.video_encode_accelerator_supported_profiles; } diff --git a/gpu/config/gpu_info_unittest.cc b/gpu/config/gpu_info_unittest.cc index 1d5fa6e..21dd4ff 100644 --- a/gpu/config/gpu_info_unittest.cc +++ b/gpu/config/gpu_info_unittest.cc @@ -33,6 +33,7 @@ TEST(GPUInfoBasicTest, EmptyGPUInfo) { #if defined(OS_WIN) EXPECT_EQ(gpu_info.dx_diagnostics_info_state, kCollectInfoNone); #endif + EXPECT_EQ(gpu_info.video_decode_accelerator_supported_profiles.size(), 0u); EXPECT_EQ(gpu_info.video_encode_accelerator_supported_profiles.size(), 0u); } diff --git a/media/filters/gpu_video_decoder.cc b/media/filters/gpu_video_decoder.cc index d059c0b..64668fa 100644 --- a/media/filters/gpu_video_decoder.cc +++ b/media/filters/gpu_video_decoder.cc @@ -98,35 +98,12 @@ void GpuVideoDecoder::Reset(const base::Closure& closure) { } static bool IsCodedSizeSupported(const gfx::Size& coded_size, - VideoCodecProfile profile) { -#if defined(OS_WIN) - // Windows Media Foundation H.264 decoding does not support decoding videos - // with any dimension smaller than 48 pixels: - // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815 - if (coded_size.width() < 48 || coded_size.height() < 48) - return false; -#endif - - // Only non-Windows, Ivy Bridge+ platforms can support more than 1920x1080. - // We test against 1088 to account for 16x16 macroblocks. - if (coded_size.width() <= 1920 && coded_size.height() <= 1088) - return true; - - // NOTE: additional autodetection logic may require updating input buffer size - // selection in platform-specific implementations, such as - // V4L2VideoDecodeAccelerator. - base::CPU cpu; - bool hw_large_video_support = - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kIgnoreResolutionLimitsForAcceleratedVideoDecode) || - ((cpu.vendor_name() == "GenuineIntel") && cpu.model() >= 55 && - // TODO(posciak, henryhsu): Remove this once we can query in runtime. - profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX); - bool os_large_video_support = true; -#if defined(OS_WIN) - os_large_video_support = false; -#endif - return os_large_video_support && hw_large_video_support; + const gfx::Size& min_resolution, + const gfx::Size& max_resolution) { + return (coded_size.width() <= max_resolution.width() && + coded_size.height() <= max_resolution.height() && + coded_size.width() >= min_resolution.width() && + coded_size.height() >= min_resolution.height()); } // Report |status| to UMA and run |cb| with it. This is super-specific to the @@ -169,7 +146,7 @@ void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config, return; } - if (!IsCodedSizeSupported(config.coded_size(), config.profile())) { + if (!IsProfileSupported(config.profile(), config.coded_size())) { status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); return; } @@ -593,6 +570,21 @@ void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { DestroyVDA(); } +bool GpuVideoDecoder::IsProfileSupported(VideoCodecProfile profile, + const gfx::Size& coded_size) { + DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); + VideoDecodeAccelerator::SupportedProfiles supported_profiles = + factories_->GetVideoDecodeAcceleratorSupportedProfiles(); + for (const auto& supported_profile : supported_profiles) { + if (profile == supported_profile.profile) { + return IsCodedSizeSupported(coded_size, + supported_profile.min_resolution, + supported_profile.max_resolution); + } + } + return false; +} + void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() const { DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); diff --git a/media/filters/gpu_video_decoder.h b/media/filters/gpu_video_decoder.h index a4157b1..49ede61 100644 --- a/media/filters/gpu_video_decoder.h +++ b/media/filters/gpu_video_decoder.h @@ -127,6 +127,10 @@ class MEDIA_EXPORT GpuVideoDecoder // Destroy all PictureBuffers in |buffers|, and delete their textures. void DestroyPictureBuffers(PictureBufferMap* buffers); + // Returns true if the video decoder can support |profile| and |coded_size|. + bool IsProfileSupported(VideoCodecProfile profile, + const gfx::Size& coded_size); + // Assert the contract that this class is operated on the right thread. void DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() const; diff --git a/media/renderers/gpu_video_accelerator_factories.h b/media/renderers/gpu_video_accelerator_factories.h index c77f86a..0980f34 100644 --- a/media/renderers/gpu_video_accelerator_factories.h +++ b/media/renderers/gpu_video_accelerator_factories.h @@ -11,6 +11,7 @@ #include "base/memory/scoped_ptr.h" #include "gpu/command_buffer/common/mailbox.h" #include "media/base/media_export.h" +#include "media/video/video_decode_accelerator.h" #include "media/video/video_encode_accelerator.h" namespace base { @@ -64,8 +65,12 @@ class MEDIA_EXPORT GpuVideoAcceleratorFactories // Returns the task runner the video accelerator runs on. virtual scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() = 0; + // Returns the supported codec profiles of video decode accelerator. + virtual VideoDecodeAccelerator::SupportedProfiles + GetVideoDecodeAcceleratorSupportedProfiles() = 0; + // Returns the supported codec profiles of video encode accelerator. - virtual std::vector<VideoEncodeAccelerator::SupportedProfile> + virtual VideoEncodeAccelerator::SupportedProfiles GetVideoEncodeAcceleratorSupportedProfiles() = 0; protected: diff --git a/media/renderers/mock_gpu_video_accelerator_factories.h b/media/renderers/mock_gpu_video_accelerator_factories.h index 85b1b3d..12a8095 100644 --- a/media/renderers/mock_gpu_video_accelerator_factories.h +++ b/media/renderers/mock_gpu_video_accelerator_factories.h @@ -39,8 +39,10 @@ class MockGpuVideoAcceleratorFactories : public GpuVideoAcceleratorFactories { MOCK_METHOD1(DeleteTexture, void(uint32 texture_id)); MOCK_METHOD1(WaitSyncPoint, void(uint32 sync_point)); MOCK_METHOD0(GetTaskRunner, scoped_refptr<base::SingleThreadTaskRunner>()); + MOCK_METHOD0(GetVideoDecodeAcceleratorSupportedProfiles, + VideoDecodeAccelerator::SupportedProfiles()); MOCK_METHOD0(GetVideoEncodeAcceleratorSupportedProfiles, - std::vector<VideoEncodeAccelerator::SupportedProfile>()); + VideoEncodeAccelerator::SupportedProfiles()); scoped_ptr<base::SharedMemory> CreateSharedMemory(size_t size) override; diff --git a/media/video/fake_video_encode_accelerator.cc b/media/video/fake_video_encode_accelerator.cc index 4ca7a23..8e23df5 100644 --- a/media/video/fake_video_encode_accelerator.cc +++ b/media/video/fake_video_encode_accelerator.cc @@ -26,9 +26,9 @@ FakeVideoEncodeAccelerator::~FakeVideoEncodeAccelerator() { weak_this_factory_.InvalidateWeakPtrs(); } -std::vector<VideoEncodeAccelerator::SupportedProfile> +VideoEncodeAccelerator::SupportedProfiles FakeVideoEncodeAccelerator::GetSupportedProfiles() { - std::vector<VideoEncodeAccelerator::SupportedProfile> profiles; + SupportedProfiles profiles; SupportedProfile profile; profile.max_resolution.SetSize(1920, 1088); profile.max_framerate_numerator = 30; diff --git a/media/video/fake_video_encode_accelerator.h b/media/video/fake_video_encode_accelerator.h index 6c7c348..c421e96 100644 --- a/media/video/fake_video_encode_accelerator.h +++ b/media/video/fake_video_encode_accelerator.h @@ -28,8 +28,7 @@ class MEDIA_EXPORT FakeVideoEncodeAccelerator : public VideoEncodeAccelerator { const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); ~FakeVideoEncodeAccelerator() override; - std::vector<VideoEncodeAccelerator::SupportedProfile> GetSupportedProfiles() - override; + VideoEncodeAccelerator::SupportedProfiles GetSupportedProfiles() override; bool Initialize(VideoFrame::Format input_format, const gfx::Size& input_visible_size, VideoCodecProfile output_profile, diff --git a/media/video/video_decode_accelerator.cc b/media/video/video_decode_accelerator.cc index 21b1d00..6ffbda5 100644 --- a/media/video/video_decode_accelerator.cc +++ b/media/video/video_decode_accelerator.cc @@ -21,6 +21,13 @@ GLenum VideoDecodeAccelerator::GetSurfaceInternalFormat() const { return GL_RGBA; } +VideoDecodeAccelerator::SupportedProfile::SupportedProfile() + : profile(media::VIDEO_CODEC_PROFILE_UNKNOWN) { +} + +VideoDecodeAccelerator::SupportedProfile::~SupportedProfile() { +} + } // namespace media namespace base { diff --git a/media/video/video_decode_accelerator.h b/media/video/video_decode_accelerator.h index a796bdb..5ac87e6 100644 --- a/media/video/video_decode_accelerator.h +++ b/media/video/video_decode_accelerator.h @@ -22,6 +22,17 @@ namespace media { // implement the backend of PPB_VideoDecode_Dev. class MEDIA_EXPORT VideoDecodeAccelerator { public: + // Specification of a decoding profile supported by an decoder. + // |max_resolution| and |min_resolution| are inclusive. + struct MEDIA_EXPORT SupportedProfile { + SupportedProfile(); + ~SupportedProfile(); + VideoCodecProfile profile; + gfx::Size max_resolution; + gfx::Size min_resolution; + }; + using SupportedProfiles = std::vector<SupportedProfile>; + // Enumeration of potential errors generated by the API. // Note: Keep these in sync with PP_VideoDecodeError_Dev. Also do not // rearrange, reuse or remove values as they are used for gathering UMA diff --git a/media/video/video_encode_accelerator.cc b/media/video/video_encode_accelerator.cc index d8a5838..dccd31d 100644 --- a/media/video/video_encode_accelerator.cc +++ b/media/video/video_encode_accelerator.cc @@ -8,6 +8,15 @@ namespace media { VideoEncodeAccelerator::~VideoEncodeAccelerator() {} +VideoEncodeAccelerator::SupportedProfile::SupportedProfile() + : profile(media::VIDEO_CODEC_PROFILE_UNKNOWN), + max_framerate_numerator(0), + max_framerate_denominator(0) { +} + +VideoEncodeAccelerator::SupportedProfile::~SupportedProfile() { +} + } // namespace media namespace base { diff --git a/media/video/video_encode_accelerator.h b/media/video/video_encode_accelerator.h index 9551c22..19a2216 100644 --- a/media/video/video_encode_accelerator.h +++ b/media/video/video_encode_accelerator.h @@ -23,12 +23,15 @@ class VideoFrame; class MEDIA_EXPORT VideoEncodeAccelerator { public: // Specification of an encoding profile supported by an encoder. - struct SupportedProfile { + struct MEDIA_EXPORT SupportedProfile { + SupportedProfile(); + ~SupportedProfile(); VideoCodecProfile profile; gfx::Size max_resolution; uint32 max_framerate_numerator; uint32 max_framerate_denominator; }; + using SupportedProfiles = std::vector<SupportedProfile>; // Enumeration of potential errors generated by the API. enum Error { @@ -92,7 +95,7 @@ class MEDIA_EXPORT VideoEncodeAccelerator { // Returns a list of the supported codec profiles of the video encoder. This // can be called before Initialize(). - virtual std::vector<SupportedProfile> GetSupportedProfiles() = 0; + virtual SupportedProfiles GetSupportedProfiles() = 0; // Initializes the video encoder with specific configuration. Called once per // encoder construction. This call is synchronous and returns true iff |