| 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);
|
|
|