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..f920c6178a837d6caee9c7a6095a1c8508b960cb 100644 |
--- a/content/common/gpu/media/vaapi_wrapper.cc |
+++ b/content/common/gpu/media/vaapi_wrapper.cc |
@@ -99,10 +99,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,17 +107,22 @@ static VAProfile ProfileToVAProfile( |
break; |
} |
} |
+ return va_profile; |
+} |
+// 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). |
+static VAProfile FallbackVaProfileIfNecessary( |
+ 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) != |
@@ -164,12 +166,27 @@ VaapiWrapper::~VaapiWrapper() { |
scoped_ptr<VaapiWrapper> VaapiWrapper::Create( |
CodecMode mode, |
+ VAProfile va_profile, |
+ const base::Closure& report_error_to_uma_cb) { |
+ scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); |
+ |
+ if (!vaapi_wrapper->Initialize(mode, va_profile, false, |
+ report_error_to_uma_cb)) |
+ return nullptr; |
+ |
+ return vaapi_wrapper.Pass(); |
+} |
+ |
+scoped_ptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec( |
+ CodecMode mode, |
media::VideoCodecProfile profile, |
const base::Closure& report_error_to_uma_cb) { |
scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); |
- if (!vaapi_wrapper->Initialize(mode, profile, report_error_to_uma_cb)) |
- vaapi_wrapper.reset(); |
+ VAProfile va_profile = ProfileToVAProfile(profile); |
+ if (!vaapi_wrapper->Initialize(mode, va_profile, true, |
+ report_error_to_uma_cb)) |
+ return nullptr; |
return vaapi_wrapper.Pass(); |
} |
@@ -189,8 +206,8 @@ std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles( |
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); |
+ VAProfile va_profile = ProfileToVAProfile(kProfileMap[i].profile); |
+ va_profile = FallbackVaProfileIfNecessary(va_profile, va_profiles); |
if (va_profile != VAProfileNone && |
wrapper->IsEntrypointSupported(va_profile, VAEntrypointEncSlice) && |
wrapper->AreAttribsSupported( |
@@ -339,14 +356,18 @@ bool VaapiWrapper::AreAttribsSupported( |
} |
bool VaapiWrapper::Initialize(CodecMode mode, |
- media::VideoCodecProfile profile, |
+ VAProfile va_profile, |
+ bool va_profile_degraded, |
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)) |
- return false; |
- VAProfile va_profile = ProfileToVAProfile(profile, supported_va_profiles); |
+ if (va_profile_degraded) { |
+ std::vector<VAProfile> supported_va_profiles; |
+ if (!GetSupportedVaProfiles(&supported_va_profiles)) |
+ return false; |
+ va_profile = |
+ FallbackVaProfileIfNecessary(va_profile, supported_va_profiles); |
+ } |
if (va_profile == VAProfileNone) { |
DVLOG(1) << "Unsupported profile"; |
return false; |
@@ -665,9 +686,9 @@ bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, |
} |
#endif // USE_X11 |
-bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, |
- VAImage* image, |
- void** mem) { |
+bool VaapiWrapper::GetDerivedVaImage(VASurfaceID va_surface_id, |
+ VAImage* image, |
+ void** mem) { |
base::AutoLock auto_lock(va_lock_); |
VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
@@ -691,7 +712,40 @@ bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, |
return false; |
} |
-void VaapiWrapper::ReturnVaImageForTesting(VAImage* image) { |
+bool VaapiWrapper::GetVaImage(VASurfaceID va_surface_id, |
+ VAImageFormat* format, |
+ const gfx::Size& size, |
+ VAImage* image, |
+ void** mem) { |
+ base::AutoLock auto_lock(va_lock_); |
+ |
+ VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
+ VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
+ |
+ va_res = |
+ vaCreateImage(va_display_, format, size.width(), size.height(), image); |
+ VA_SUCCESS_OR_RETURN(va_res, "vaCreateImage failed", false); |
+ |
+ va_res = vaGetImage(va_display_, va_surface_id, 0, 0, size.width(), |
+ size.height(), image->image_id); |
+ VA_LOG_ON_ERROR(va_res, "vaGetImage failed"); |
+ |
+ if (va_res == VA_STATUS_SUCCESS) { |
+ // Map the VAImage into memory |
+ va_res = vaMapBuffer(va_display_, image->buf, mem); |
+ VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); |
+ } |
+ |
+ if (va_res != VA_STATUS_SUCCESS) { |
+ va_res = vaDestroyImage(va_display_, image->image_id); |
+ VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed"); |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+void VaapiWrapper::ReturnVaImage(VAImage* image) { |
base::AutoLock auto_lock(va_lock_); |
VAStatus va_res = vaUnmapBuffer(va_display_, image->buf); |