Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1298)

Unified Diff: content/common/gpu/media/vaapi_wrapper.cc

Issue 872623002: VaapiVEA: Get maximum resolution from libva (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address review comments Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 588fee3981e59072c6118996099258acaa51e82b..756723a0488dc76a75b99292a045a74c0c2499cb 100644
--- a/content/common/gpu/media/vaapi_wrapper.cc
+++ b/content/common/gpu/media/vaapi_wrapper.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
+#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/sys_info.h"
@@ -56,6 +57,9 @@ using content_common_gpu_media::StubPathMap;
namespace content {
+base::LazyInstance<LazyProfileConfig> g_profile_config =
+ LAZY_INSTANCE_INITIALIZER;
+
// Config attributes common for both encode and decode.
static const VAConfigAttrib kCommonVAConfigAttribs[] = {
{VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420},
@@ -80,6 +84,12 @@ static const ProfileMap kProfileMap[] = {
// TODO(posciak): See if we can/want support other variants of
// media::H264PROFILE_HIGH*.
{media::H264PROFILE_HIGH, VAProfileH264High},
+ // 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).
+ {media::H264PROFILE_BASELINE, VAProfileH264ConstrainedBaseline},
kcwu 2015/02/13 07:15:38 This is incorrect. You break the original behavior
kcwu 2015/02/13 07:35:11 offline talked with henry. The code is good. Pleas
henryhsu 2015/02/13 07:35:28 As discuss, the logic is correct. But I'll modify
henryhsu 2015/02/13 17:24:28 Done.
};
static std::vector<VAConfigAttrib> GetRequiredAttribs(
@@ -98,39 +108,16 @@ static std::vector<VAConfigAttrib> GetRequiredAttribs(
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;
+// Maps VaProfile enum values to Profile values.
+static media::VideoCodecProfile VAProfileToProfile(VAProfile va_profile) {
+ media::VideoCodecProfile profile = media::VIDEO_CODEC_PROFILE_UNKNOWN;
for (size_t i = 0; i < arraysize(kProfileMap); i++) {
- if (kProfileMap[i].profile == profile) {
- va_profile = kProfileMap[i].va_profile;
+ if (kProfileMap[i].va_profile == va_profile) {
+ profile = kProfileMap[i].profile;
break;
}
}
-
- 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.";
- }
- }
-
- return va_profile;
+ return profile;
}
VASurface::VASurface(VASurfaceID va_surface_id,
@@ -162,6 +149,7 @@ VaapiWrapper::~VaapiWrapper() {
Deinitialize();
}
+// static
scoped_ptr<VaapiWrapper> VaapiWrapper::Create(
CodecMode mode,
VAProfile va_profile,
@@ -170,12 +158,16 @@ scoped_ptr<VaapiWrapper> VaapiWrapper::Create(
if (!vaapi_wrapper->VaInitialize(report_error_to_uma_cb))
return nullptr;
- if (!vaapi_wrapper->Initialize(mode, va_profile))
+
+ if (!vaapi_wrapper->Initialize(mode, va_profile)) {
+ DVLOG(1) << "Unsupported profile";
wuchengli 2015/02/13 15:38:54 also print |va_profile|
henryhsu 2015/02/13 17:24:28 Done.
return nullptr;
+ }
return vaapi_wrapper.Pass();
}
+// static
scoped_ptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec(
CodecMode mode,
media::VideoCodecProfile profile,
@@ -185,42 +177,41 @@ scoped_ptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec(
if (!vaapi_wrapper->VaInitialize(report_error_to_uma_cb))
return nullptr;
- std::vector<VAProfile> supported_va_profiles;
- if (!vaapi_wrapper->GetSupportedVaProfiles(&supported_va_profiles))
- return nullptr;
-
- VAProfile va_profile = ProfileToVAProfile(profile, supported_va_profiles);
- if (!vaapi_wrapper->Initialize(mode, va_profile))
- return nullptr;
-
- return vaapi_wrapper.Pass();
-}
-
-std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles(
- const base::Closure& report_error_to_uma_cb) {
- std::vector<media::VideoCodecProfile> supported_profiles;
-
- scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper());
- if (!wrapper->VaInitialize(report_error_to_uma_cb)) {
- return supported_profiles;
+ for (size_t i = 0; i < arraysize(kProfileMap); ++i) {
+ if (kProfileMap[i].profile == profile &&
+ vaapi_wrapper->Initialize(mode, kProfileMap[i].va_profile))
+ return vaapi_wrapper.Pass();
}
+ DVLOG(1) << "Unsupported profile";
wuchengli 2015/02/13 15:38:55 also print |profile|
henryhsu 2015/02/13 17:24:28 Done.
+ return nullptr;
+}
- 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
+std::vector<media::VideoEncodeAccelerator::SupportedProfile>
+VaapiWrapper::GetSupportedEncodeProfiles() {
+ std::vector<ProfileConfig> encode_profile_configs =
+ g_profile_config.Get().GetSupportedEncodeProfileConfigs();
+ std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles;
+ media::VideoEncodeAccelerator::SupportedProfile profile;
+ for (size_t i = 0; i < encode_profile_configs.size(); ++i) {
+ media::VideoCodecProfile hw_profile = VAProfileToProfile(
+ encode_profile_configs[i].va_profile);
+ if (hw_profile != media::VIDEO_CODEC_PROFILE_UNKNOWN) {
+ profile.profile = hw_profile;
+ profile.max_resolution = encode_profile_configs[i].max_resolution;
+ profiles.push_back(profile);
}
}
- return supported_profiles;
+ return profiles;
+}
+
+// static
+std::vector<VaapiWrapper::ProfileConfig>
+VaapiWrapper::InitSupportedProfileConfigs() {
+ scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
+ if (!vaapi_wrapper->VaInitialize(base::Bind(&base::DoNothing)))
+ return std::vector<VaapiWrapper::ProfileConfig>();
+ return vaapi_wrapper->GetSupportedProfileConfigs();
}
void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
@@ -236,6 +227,43 @@ void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default.";
}
+std::vector<VaapiWrapper::ProfileConfig>
+VaapiWrapper::GetSupportedProfileConfigs() {
+ std::vector<VaapiWrapper::ProfileConfig> supported_profiles;
+ std::vector<VAProfile> va_profiles;
+ if (!GetSupportedVaProfiles(&va_profiles))
+ return supported_profiles;
+
+ VaapiWrapper::ProfileConfig supported_profile;
+ std::vector<CodecMode> modes({kDecode, kEncode});
+ for (size_t i = 0; i < modes.size(); ++i) {
+ std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(modes[i]);
+ VAEntrypoint entrypoint =
+ (modes[i] == kEncode ? VAEntrypointEncSlice: VAEntrypointVLD);
+ for (size_t j = 0; j < va_profiles.size(); ++j) {
+ if (va_profiles[j] != VAProfileNone &&
wuchengli 2015/02/13 15:38:54 Why this can be VAProfileNone?
henryhsu 2015/02/13 17:24:28 oh...this is typo. In original implementation, we
+ IsEntrypointSupported(va_profiles[j], entrypoint) &&
+ AreAttribsSupported(va_profiles[j], entrypoint, required_attribs)) {
+ supported_profile.va_profile = va_profiles[j];
+ supported_profile.mode = modes[i];
wuchengli 2015/02/13 15:38:54 move l247-248 to l259. No need to do this if it fa
henryhsu 2015/02/13 17:24:28 Done.
+ VAConfigID config_id;
+ VAStatus va_res = vaCreateConfig(
+ va_display_,
+ va_profiles[j],
+ entrypoint,
+ &required_attribs[0],
+ required_attribs.size(),
+ &config_id);
+ if (va_res == VA_STATUS_SUCCESS &&
+ GetVaCodecMaxResolution(config_id,
+ &supported_profile.max_resolution))
wuchengli 2015/02/13 15:38:55 This for loop is hard to read. Can you flatten the
henryhsu 2015/02/13 17:24:28 Done.
+ supported_profiles.push_back(supported_profile);
+ }
+ }
+ }
+ return supported_profiles;
+}
+
bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) {
static bool vaapi_functions_initialized = PostSandboxInitialization();
if (!vaapi_functions_initialized) {
@@ -360,21 +388,58 @@ bool VaapiWrapper::AreAttribsSupported(
return true;
}
-bool VaapiWrapper::Initialize(CodecMode mode, VAProfile va_profile) {
- if (va_profile == VAProfileNone) {
- DVLOG(1) << "Unsupported profile";
- return false;
+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;
+ }
}
- VAEntrypoint entrypoint =
- (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD);
- if (!IsEntrypointSupported(va_profile, entrypoint))
+ if (!resolution->height() || !resolution->width())
wuchengli 2015/02/13 15:38:54 This shouldn't happen. Right? Add LOG(ERROR)
henryhsu 2015/02/13 17:24:28 Done.
return false;
- std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode);
- if (!AreAttribsSupported(va_profile, entrypoint, required_attribs))
+ return true;
+}
+
+bool VaapiWrapper::Initialize(CodecMode mode, VAProfile va_profile) {
+ std::vector<ProfileConfig> profile_configs = (mode == kEncode) ?
+ g_profile_config.Get().GetSupportedEncodeProfileConfigs() :
+ g_profile_config.Get().GetSupportedDecodeProfileConfigs();
+
+ size_t i;
+ for (i = 0; i < profile_configs.size(); ++i)
wuchengli 2015/02/13 15:38:54 This for loops have two lines. Please add braces f
henryhsu 2015/02/13 17:24:28 Done.
+ if (profile_configs[i].va_profile == va_profile)
+ break;
+ if (i == profile_configs.size())
return false;
wuchengli 2015/02/13 15:38:55 Move line 427-436 to a LazyProfileConfig::IsProfil
henryhsu 2015/02/13 17:24:28 Done.
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,
@@ -959,4 +1024,35 @@ bool VaapiWrapper::PostSandboxInitialization() {
return InitializeStubs(paths);
}
+LazyProfileConfig::LazyProfileConfig() {
+ std::vector<VaapiWrapper::ProfileConfig> all_profile_configs =
+ VaapiWrapper::InitSupportedProfileConfigs();
+
+ for (size_t i = 0; i < all_profile_configs.size(); ++i) {
+ switch (all_profile_configs[i].mode) {
+ case VaapiWrapper::kEncode:
+ supported_encode_profiles_.push_back(all_profile_configs[i]);
kcwu 2015/02/13 07:15:38 How about define it something like array of vector
henryhsu 2015/02/13 07:35:28 ok. I'll add kCodecMax and CHECK rule.
+ break;
+ case VaapiWrapper::kDecode:
+ supported_decode_profiles_.push_back(all_profile_configs[i]);
+ break;
+ default:
+ break;
kcwu 2015/02/13 07:15:38 NOTREACHED
+ }
+ }
+}
+
+LazyProfileConfig::~LazyProfileConfig() {
+}
+
+std::vector<VaapiWrapper::ProfileConfig>
+LazyProfileConfig::GetSupportedEncodeProfileConfigs() {
+ return supported_encode_profiles_;
+}
+
+std::vector<VaapiWrapper::ProfileConfig>
+LazyProfileConfig::GetSupportedDecodeProfileConfigs() {
+ return supported_decode_profiles_;
+}
+
} // namespace content
« content/common/gpu/media/vaapi_wrapper.h ('K') | « content/common/gpu/media/vaapi_wrapper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698