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

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: modify description Created 5 years, 11 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 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,
« 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