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 5e93b994db02dcf52301327e0c285b82a148e001..8931f9b50eeab4e5f746760ced2f70775370aee2 100644 |
--- a/content/common/gpu/media/vaapi_wrapper.cc |
+++ b/content/common/gpu/media/vaapi_wrapper.cc |
@@ -57,6 +57,22 @@ static const VAConfigAttrib kEncodeVAConfigAttribs[] = { |
VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE}, |
}; |
+static std::vector<VAConfigAttrib> GetRequiredAttribs( |
+ VaapiWrapper::CodecMode mode) { |
+ std::vector<VAConfigAttrib> required_attribs; |
+ required_attribs.insert( |
+ required_attribs.end(), |
+ kCommonVAConfigAttribs, |
+ kCommonVAConfigAttribs + arraysize(kCommonVAConfigAttribs)); |
+ if (mode == VaapiWrapper::kEncode) { |
+ required_attribs.insert( |
+ required_attribs.end(), |
+ kEncodeVAConfigAttribs, |
+ kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs)); |
+ } |
+ return required_attribs; |
+} |
+ |
// Maps Profile enum values to VaProfile values. |
static VAProfile ProfileToVAProfile( |
media::VideoCodecProfile profile, |
@@ -139,6 +155,34 @@ scoped_ptr<VaapiWrapper> VaapiWrapper::Create( |
return vaapi_wrapper.Pass(); |
} |
+std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedProfiles( |
+ Display* x_display, |
+ const base::Closure& report_error_to_uma_cb) { |
+ std::vector<media::VideoCodecProfile> supported_profiles; |
+ media::VideoCodecProfile profiles[3] = {media::H264PROFILE_BASELINE, |
Pawel Osciak
2014/09/26 07:15:12
Ideally we'd like to use all va_profiles and use s
wuchengli
2014/09/26 09:02:28
GetSupportedProfiles is called when GPU process st
|
+ media::H264PROFILE_MAIN, |
+ media::H264PROFILE_HIGH}; |
+ |
+ scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper()); |
+ std::vector<VAProfile> va_profiles; |
+ if (!wrapper->VaInitialize(x_display, report_error_to_uma_cb)) { |
+ return supported_profiles; |
+ } |
+ if (!wrapper->GetSupportedVaProfiles(&va_profiles)) |
+ return supported_profiles; |
+ std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode); |
+ for (size_t i = 0; i < arraysize(profiles); i++) { |
+ VAProfile va_profile = ProfileToVAProfile(profiles[i], va_profiles); |
Pawel Osciak
2014/09/26 07:15:12
We have this chunk of code duplicated here and in
wuchengli
2014/09/26 09:02:28
Done.
vaCreateConfig needs VA profile, entrypoint
|
+ if (va_profile != VAProfileNone && |
+ wrapper->IsEntrypointSupported(va_profile, VAEntrypointEncSlice) && |
+ wrapper->IsAttribSupported( |
+ va_profile, VAEntrypointEncSlice, required_attribs)) { |
+ supported_profiles.push_back(profiles[i]); |
+ } |
+ } |
+ return supported_profiles; |
+} |
+ |
void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { |
VADisplayAttribute item = {VADisplayAttribRenderMode, |
1, // At least support '_LOCAL_OVERLAY'. |
@@ -151,10 +195,8 @@ void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { |
DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; |
} |
-bool VaapiWrapper::Initialize(CodecMode mode, |
- media::VideoCodecProfile profile, |
- Display* x_display, |
- const base::Closure& report_error_to_uma_cb) { |
+bool VaapiWrapper::VaInitialize(Display* x_display, |
+ const base::Closure& report_error_to_uma_cb) { |
static bool vaapi_functions_initialized = PostSandboxInitialization(); |
if (!vaapi_functions_initialized) { |
DVLOG(1) << "Failed to initialize VAAPI libs"; |
@@ -179,14 +221,18 @@ bool VaapiWrapper::Initialize(CodecMode mode, |
DVLOG(1) << "VAAPI version < 0.34 is not supported."; |
return false; |
} |
+ return true; |
+} |
+bool VaapiWrapper::GetSupportedVaProfiles(std::vector<VAProfile>* profiles) { |
+ base::AutoLock auto_lock(va_lock_); |
// Query the driver for supported profiles. |
int max_profiles = vaMaxNumProfiles(va_display_); |
std::vector<VAProfile> supported_profiles( |
base::checked_cast<size_t>(max_profiles)); |
int num_supported_profiles; |
- va_res = vaQueryConfigProfiles( |
+ VAStatus va_res = vaQueryConfigProfiles( |
va_display_, &supported_profiles[0], &num_supported_profiles); |
VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); |
if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { |
@@ -195,23 +241,23 @@ bool VaapiWrapper::Initialize(CodecMode mode, |
} |
supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); |
+ *profiles = supported_profiles; |
+ return true; |
+} |
- VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles); |
- if (va_profile == VAProfileNone) { |
- DVLOG(1) << "Unsupported profile"; |
- return false; |
- } |
- |
+bool VaapiWrapper::IsEntrypointSupported(VAProfile va_profile, |
+ VAEntrypoint entrypoint) { |
+ base::AutoLock auto_lock(va_lock_); |
// Query the driver for supported entrypoints. |
int max_entrypoints = vaMaxNumEntrypoints(va_display_); |
std::vector<VAEntrypoint> supported_entrypoints( |
base::checked_cast<size_t>(max_entrypoints)); |
int num_supported_entrypoints; |
- va_res = vaQueryConfigEntrypoints(va_display_, |
- va_profile, |
- &supported_entrypoints[0], |
- &num_supported_entrypoints); |
+ VAStatus va_res = vaQueryConfigEntrypoints(va_display_, |
+ va_profile, |
+ &supported_entrypoints[0], |
+ &num_supported_entrypoints); |
VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false); |
if (num_supported_entrypoints < 0 || |
num_supported_entrypoints > max_entrypoints) { |
@@ -220,34 +266,26 @@ bool VaapiWrapper::Initialize(CodecMode mode, |
return false; |
} |
- VAEntrypoint entrypoint = |
- (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD); |
- |
if (std::find(supported_entrypoints.begin(), |
supported_entrypoints.end(), |
entrypoint) == supported_entrypoints.end()) { |
DVLOG(1) << "Unsupported entrypoint"; |
return false; |
} |
+ return true; |
+} |
+bool VaapiWrapper::IsAttribSupported( |
+ VAProfile va_profile, |
+ VAEntrypoint entrypoint, |
+ const std::vector<VAConfigAttrib>& required_attribs) { |
+ base::AutoLock auto_lock(va_lock_); |
// Query the driver for required attributes. |
- std::vector<VAConfigAttrib> required_attribs; |
- required_attribs.insert( |
- required_attribs.end(), |
- kCommonVAConfigAttribs, |
- kCommonVAConfigAttribs + arraysize(kCommonVAConfigAttribs)); |
- if (mode == kEncode) { |
- required_attribs.insert( |
- required_attribs.end(), |
- kEncodeVAConfigAttribs, |
- kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs)); |
- } |
- |
std::vector<VAConfigAttrib> attribs = required_attribs; |
for (size_t i = 0; i < required_attribs.size(); ++i) |
attribs[i].value = 0; |
- va_res = vaGetConfigAttributes( |
+ VAStatus va_res = vaGetConfigAttributes( |
va_display_, va_profile, entrypoint, &attribs[0], attribs.size()); |
VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false); |
@@ -260,15 +298,39 @@ bool VaapiWrapper::Initialize(CodecMode mode, |
return false; |
} |
} |
+ return true; |
+} |
+ |
+bool VaapiWrapper::Initialize(CodecMode mode, |
+ media::VideoCodecProfile profile, |
+ Display* x_display, |
+ const base::Closure& report_error_to_uma_cb) { |
+ if (!VaInitialize(x_display, report_error_to_uma_cb)) |
+ return false; |
+ std::vector<VAProfile> supported_profiles; |
+ if (!GetSupportedVaProfiles(&supported_profiles)) |
+ return false; |
+ VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles); |
+ 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 (!IsAttribSupported(va_profile, entrypoint, required_attribs)) |
+ return false; |
TryToSetVADisplayAttributeToLocalGPU(); |
- va_res = vaCreateConfig(va_display_, |
- va_profile, |
- entrypoint, |
- &required_attribs[0], |
- required_attribs.size(), |
- &va_config_id_); |
+ VAStatus va_res = vaCreateConfig(va_display_, |
kcwu
2014/09/26 07:50:45
va_lock_ for this?
wuchengli
2014/09/26 09:02:28
Done. Thanks for catching this.
|
+ va_profile, |
+ entrypoint, |
+ &required_attribs[0], |
+ required_attribs.size(), |
+ &va_config_id_); |
VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false); |
return true; |