Index: content/common/gpu/media/vaapi_wrapper.cc |
diff --git a/content/common/gpu/media/vaapi_wrapper.cc b/content/common/gpu/media/vaapi_wrapper.cc |
index 63450b4a58001dba70505640f3b9197e7f75c896..2ea163c8b50417e022be6b12be8d0f77baea306f 100644 |
--- a/content/common/gpu/media/vaapi_wrapper.cc |
+++ b/content/common/gpu/media/vaapi_wrapper.cc |
@@ -56,6 +56,11 @@ using content_common_gpu_media::StubPathMap; |
namespace content { |
+bool VaapiWrapper::is_initialize_profile_; |
+VaapiWrapper::ProfileConfig |
+ VaapiWrapper::supported_profiles_[media::VIDEO_CODEC_PROFILE_MAX * 2] = |
kcwu
2015/02/02 10:11:01
MAX*2+1
henryhsu
2015/02/13 04:01:03
Not used anymore
|
+ {{media::VIDEO_CODEC_PROFILE_UNKNOWN}}; |
kcwu
2015/02/02 10:11:01
add comment that UNKNOWN is guard.
henryhsu
2015/02/13 04:01:03
Not used anymore
|
+ |
// Config attributes common for both encode and decode. |
static const VAConfigAttrib kCommonVAConfigAttribs[] = { |
{VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420}, |
@@ -99,10 +104,7 @@ static std::vector<VAConfigAttrib> GetRequiredAttribs( |
} |
// Maps Profile enum values to VaProfile values. |
-static VAProfile ProfileToVAProfile( |
- media::VideoCodecProfile profile, |
- const std::vector<VAProfile>& supported_profiles) { |
- |
+static VAProfile ProfileToVAProfile(media::VideoCodecProfile profile) { |
VAProfile va_profile = VAProfileNone; |
for (size_t i = 0; i < arraysize(kProfileMap); i++) { |
if (kProfileMap[i].profile == profile) { |
@@ -110,23 +112,33 @@ static VAProfile ProfileToVAProfile( |
break; |
} |
} |
+ return va_profile; |
+} |
+// checks VaProfile is supported. |
+static VAProfile GetSupportedVaProfile( |
+ VAProfile va_profile, |
+ const std::vector<VAProfile>& supported_profiles) { |
bool supported = std::find(supported_profiles.begin(), |
supported_profiles.end(), |
va_profile) != supported_profiles.end(); |
- if (!supported && va_profile == VAProfileH264Baseline) { |
- // crbug.com/345569: media::ProfileIDToVideoCodecProfile() currently strips |
- // the information whether the profile is constrained or not, so we have no |
- // way to know here. Try for baseline first, but if it is not supported, |
- // try constrained baseline and hope this is what it actually is |
- // (which in practice is true for a great majority of cases). |
- if (std::find(supported_profiles.begin(), |
- supported_profiles.end(), |
- VAProfileH264ConstrainedBaseline) != |
- supported_profiles.end()) { |
- va_profile = VAProfileH264ConstrainedBaseline; |
- DVLOG(1) << "Falling back to constrained baseline profile."; |
+ if (!supported) { |
+ if (va_profile == VAProfileH264Baseline) { |
+ // crbug.com/345569: media::ProfileIDToVideoCodecProfile() currently |
+ // strips the information whether the profile is constrained or not, so we |
+ // have no way to know here. Try for baseline first, but if it is not |
+ // supported, try constrained baseline and hope this is what it actually |
+ // is (which in practice is true for a great majority of cases). |
+ if (std::find(supported_profiles.begin(), |
+ supported_profiles.end(), |
+ VAProfileH264ConstrainedBaseline) != |
+ supported_profiles.end()) { |
+ va_profile = VAProfileH264ConstrainedBaseline; |
+ DVLOG(1) << "Falling back to constrained baseline profile."; |
+ } |
+ } else { |
+ va_profile = VAProfileNone; |
} |
} |
@@ -162,43 +174,61 @@ VaapiWrapper::~VaapiWrapper() { |
Deinitialize(); |
} |
+// static |
+scoped_ptr<VaapiWrapper> VaapiWrapper::CreateInstance( |
+ const base::Closure& report_error_to_uma_cb) { |
+ scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); |
+ if (!vaapi_wrapper->VaInitialize(report_error_to_uma_cb)) |
+ vaapi_wrapper.reset(); |
+ else |
+ vaapi_wrapper->InitializeSupportedProfiles(); |
+ return vaapi_wrapper.Pass(); |
+} |
+ |
+// static |
scoped_ptr<VaapiWrapper> VaapiWrapper::Create( |
kcwu
2015/02/02 10:11:01
you need to rebase since I modified these function
henryhsu
2015/02/13 04:01:03
Done.
|
CodecMode mode, |
media::VideoCodecProfile profile, |
const base::Closure& report_error_to_uma_cb) { |
- scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); |
+ scoped_ptr<VaapiWrapper> vaapi_wrapper = |
+ CreateInstance(report_error_to_uma_cb); |
- if (!vaapi_wrapper->Initialize(mode, profile, report_error_to_uma_cb)) |
+ if (vaapi_wrapper && |
+ !vaapi_wrapper->Initialize(mode, profile)) |
vaapi_wrapper.reset(); |
return vaapi_wrapper.Pass(); |
} |
-std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles( |
- const base::Closure& report_error_to_uma_cb) { |
+// static |
+std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedProfiles( |
+ CodecMode mode) { |
std::vector<media::VideoCodecProfile> supported_profiles; |
- |
- scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper()); |
- if (!wrapper->VaInitialize(report_error_to_uma_cb)) { |
+ if (!CreateInstance(base::Bind(&base::DoNothing))) |
return supported_profiles; |
+ for (size_t i = 0; |
+ supported_profiles_[i].profile != media::VIDEO_CODEC_PROFILE_UNKNOWN; |
+ ++i) { |
+ if (supported_profiles_[i].mode == mode) |
+ supported_profiles.push_back(supported_profiles_[i].profile); |
} |
+ return supported_profiles; |
+} |
- std::vector<VAProfile> va_profiles; |
- if (!wrapper->GetSupportedVaProfiles(&va_profiles)) |
- return supported_profiles; |
- |
- std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode); |
- for (size_t i = 0; i < arraysize(kProfileMap); i++) { |
- VAProfile va_profile = |
- ProfileToVAProfile(kProfileMap[i].profile, va_profiles); |
- if (va_profile != VAProfileNone && |
- wrapper->IsEntrypointSupported(va_profile, VAEntrypointEncSlice) && |
- wrapper->AreAttribsSupported( |
- va_profile, VAEntrypointEncSlice, required_attribs)) { |
- supported_profiles.push_back(kProfileMap[i].profile); |
- } |
+// static |
+gfx::Size VaapiWrapper::GetCodecMaxResolution( |
+ media::VideoCodecProfile profile, |
+ CodecMode mode) { |
+ if (!CreateInstance(base::Bind(&base::DoNothing))) |
+ return gfx::Size(0, 0); |
+ for (size_t i = 0; |
+ supported_profiles_[i].profile != media::VIDEO_CODEC_PROFILE_UNKNOWN; |
+ ++i) { |
+ if (supported_profiles_[i].profile == profile && |
+ supported_profiles_[i].mode == mode) |
+ return supported_profiles_[i].max_resolution; |
} |
- return supported_profiles; |
+ return gfx::Size(0, 0); |
} |
void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { |
@@ -214,6 +244,48 @@ void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { |
DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; |
} |
+void VaapiWrapper::InitializeSupportedProfiles() { |
+ if (is_initialize_profile_) |
wuchengli
2015/02/03 03:17:33
Originally this class is thread-safe. You need |va
henryhsu
2015/02/13 04:01:03
Done.
|
+ return; |
+ std::vector<VAProfile> va_profiles; |
+ if (!GetSupportedVaProfiles(&va_profiles)) |
+ return; |
+ |
+ size_t num_profiles = 0; |
+ std::vector<CodecMode> modes({kDecode, kEncode}); |
+ for (size_t i = 0; i < arraysize(kProfileMap); i++) { |
kcwu
2015/02/02 10:11:01
DCHECK_LT(arraysize(kProfileMap) * modes.size(), a
henryhsu
2015/02/13 04:01:03
Not used anymore
|
+ VAProfile va_profile = kProfileMap[i].va_profile; |
+ for (size_t j = 0; j < modes.size(); j++) { |
+ std::vector<VAConfigAttrib> required_attribs = |
+ GetRequiredAttribs(modes[j]); |
+ VAEntrypoint entrypoint = |
+ (modes[j] == kEncode ? VAEntrypointEncSlice: VAEntrypointVLD); |
+ if (GetSupportedVaProfile(va_profile, va_profiles) != VAProfileNone && |
+ IsEntrypointSupported(va_profile, entrypoint) && |
+ AreAttribsSupported(va_profile, entrypoint, required_attribs)) { |
+ supported_profiles_[num_profiles].profile = kProfileMap[i].profile; |
+ supported_profiles_[num_profiles].mode = modes[j]; |
+ VAConfigID config_id; |
+ VAStatus va_res = vaCreateConfig( |
+ va_display_, |
+ va_profile, |
+ entrypoint, |
+ &required_attribs[0], |
+ required_attribs.size(), |
+ &config_id); |
+ if (va_res == VA_STATUS_SUCCESS) { |
+ GetVaCodecMaxResolution(config_id, |
kcwu
2015/02/02 10:11:02
didn't check return value?
henryhsu
2015/02/13 04:01:03
Done.
|
+ &supported_profiles_[num_profiles].max_resolution); |
+ num_profiles++; |
+ } |
+ } |
+ } |
+ } |
+ supported_profiles_[num_profiles].profile = |
+ media::VIDEO_CODEC_PROFILE_UNKNOWN; |
+ is_initialize_profile_ = true; |
+} |
+ |
bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) { |
static bool vaapi_functions_initialized = PostSandboxInitialization(); |
if (!vaapi_functions_initialized) { |
@@ -338,29 +410,61 @@ bool VaapiWrapper::AreAttribsSupported( |
return true; |
} |
+bool VaapiWrapper::GetVaCodecMaxResolution(VAConfigID config_id, |
+ gfx::Size* resolution) { |
+ base::AutoLock auto_lock(va_lock_); |
+ unsigned int num_attribs; |
+ VAStatus va_res; |
+ |
+ va_res = vaQuerySurfaceAttributes( |
+ va_display_, config_id, NULL, &num_attribs); |
+ VA_SUCCESS_OR_RETURN(va_res, "vaQuerySurfaceAttributes failed", false); |
+ |
+ std::vector<VASurfaceAttrib> attrib_list( |
+ base::checked_cast<size_t>(num_attribs)); |
+ |
+ va_res = vaQuerySurfaceAttributes( |
+ va_display_, config_id, &attrib_list[0], &num_attribs); |
+ VA_SUCCESS_OR_RETURN(va_res, "vaQuerySurfaceAttributes failed", false); |
+ |
+ resolution->SetSize(0, 0); |
+ for (size_t i = 0; i < num_attribs; i++) { |
+ switch (attrib_list[i].type) { |
+ case VASurfaceAttribMaxWidth: |
+ resolution->set_width(attrib_list[i].value.value.i); |
+ break; |
+ case VASurfaceAttribMaxHeight: |
+ resolution->set_height(attrib_list[i].value.value.i); |
+ break; |
+ default: |
+ break; |
+ } |
+ } |
+ return true; |
kcwu
2015/02/02 10:11:02
Is it guaranteed that there are always VaSurfaceAt
henryhsu
2015/02/02 10:42:24
No. If attributes don't include MaxWidth and MaxHe
|
+} |
+ |
bool VaapiWrapper::Initialize(CodecMode mode, |
- media::VideoCodecProfile profile, |
- const base::Closure& report_error_to_uma_cb) { |
- if (!VaInitialize(report_error_to_uma_cb)) |
- return false; |
- std::vector<VAProfile> supported_va_profiles; |
- if (!GetSupportedVaProfiles(&supported_va_profiles)) |
+ media::VideoCodecProfile profile) { |
+ std::vector<media::VideoCodecProfile> supported_profiles = |
+ GetSupportedProfiles(mode); |
+ if (std::find(supported_profiles.begin(), |
+ supported_profiles.end(), |
+ profile) == supported_profiles.end()) { |
+ DVLOG(1) << "Unsupported profile"; |
return false; |
- VAProfile va_profile = ProfileToVAProfile(profile, supported_va_profiles); |
+ } |
+ |
+ VAProfile va_profile = ProfileToVAProfile(profile); |
if (va_profile == VAProfileNone) { |
DVLOG(1) << "Unsupported profile"; |
return false; |
} |
- VAEntrypoint entrypoint = |
- (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD); |
- if (!IsEntrypointSupported(va_profile, entrypoint)) |
- return false; |
- std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode); |
- if (!AreAttribsSupported(va_profile, entrypoint, required_attribs)) |
- return false; |
TryToSetVADisplayAttributeToLocalGPU(); |
+ VAEntrypoint entrypoint = |
+ (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD); |
+ std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode); |
base::AutoLock auto_lock(va_lock_); |
VAStatus va_res = vaCreateConfig(va_display_, |
va_profile, |