| 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..f317198126cc5535ce7a8f07cf4dba0171f203b7 100644
|
| --- a/content/common/gpu/media/vaapi_wrapper.cc
|
| +++ b/content/common/gpu/media/vaapi_wrapper.cc
|
| @@ -57,27 +57,47 @@ static const VAConfigAttrib kEncodeVAConfigAttribs[] = {
|
| VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE},
|
| };
|
|
|
| +struct ProfileMap {
|
| + media::VideoCodecProfile profile;
|
| + VAProfile va_profile;
|
| +};
|
| +
|
| +// A map between VideoCodecProfile and VAProfile.
|
| +static const ProfileMap kProfileMap[] = {
|
| + {media::H264PROFILE_BASELINE, VAProfileH264Baseline},
|
| + {media::H264PROFILE_MAIN, VAProfileH264Main},
|
| + // TODO(posciak): See if we can/want support other variants of
|
| + // media::H264PROFILE_HIGH*.
|
| + {media::H264PROFILE_HIGH, VAProfileH264High},
|
| +};
|
| +
|
| +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,
|
| const std::vector<VAProfile>& supported_profiles) {
|
|
|
| VAProfile va_profile = VAProfileNone;
|
| -
|
| - switch (profile) {
|
| - case media::H264PROFILE_BASELINE:
|
| - va_profile = VAProfileH264Baseline;
|
| - break;
|
| - case media::H264PROFILE_MAIN:
|
| - va_profile = VAProfileH264Main;
|
| - break;
|
| - // TODO(posciak): See if we can/want support other variants
|
| - // of media::H264PROFILE_HIGH*.
|
| - case media::H264PROFILE_HIGH:
|
| - va_profile = VAProfileH264High;
|
| - break;
|
| - default:
|
| + for (size_t i = 0; i < arraysize(kProfileMap); i++) {
|
| + if (kProfileMap[i].profile == profile) {
|
| + va_profile = kProfileMap[i].va_profile;
|
| break;
|
| + }
|
| }
|
|
|
| bool supported = std::find(supported_profiles.begin(),
|
| @@ -139,7 +159,36 @@ scoped_ptr<VaapiWrapper> VaapiWrapper::Create(
|
| return vaapi_wrapper.Pass();
|
| }
|
|
|
| +std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles(
|
| + Display* x_display,
|
| + const base::Closure& report_error_to_uma_cb) {
|
| + std::vector<media::VideoCodecProfile> supported_profiles;
|
| +
|
| + scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper());
|
| + if (!wrapper->VaInitialize(x_display, report_error_to_uma_cb)) {
|
| + 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);
|
| + }
|
| + }
|
| + return supported_profiles;
|
| +}
|
| +
|
| void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
|
| + base::AutoLock auto_lock(va_lock_);
|
| VADisplayAttribute item = {VADisplayAttribRenderMode,
|
| 1, // At least support '_LOCAL_OVERLAY'.
|
| -1, // The maximum possible support 'ALL'.
|
| @@ -151,10 +200,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 +226,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 +246,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 +271,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::AreAttribsSupported(
|
| + 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 +303,40 @@ 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_va_profiles;
|
| + if (!GetSupportedVaProfiles(&supported_va_profiles))
|
| + return false;
|
| + VAProfile va_profile = ProfileToVAProfile(profile, supported_va_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 (!AreAttribsSupported(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_);
|
| + base::AutoLock auto_lock(va_lock_);
|
| + VAStatus va_res = vaCreateConfig(va_display_,
|
| + va_profile,
|
| + entrypoint,
|
| + &required_attribs[0],
|
| + required_attribs.size(),
|
| + &va_config_id_);
|
| VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false);
|
|
|
| return true;
|
|
|