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 219e370e5bdc29475be4555ccc20660528d03500..fb5753edca50a4fa83c5b781739f87827c8069a7 100644 |
--- a/content/common/gpu/media/vaapi_wrapper.cc |
+++ b/content/common/gpu/media/vaapi_wrapper.cc |
@@ -62,6 +62,11 @@ namespace content { |
// and not taken from HW documentation. |
const int kMaxEncoderFramerate = 30; |
+#if defined(USE_OZONE) |
+base::LazyInstance<VaapiWrapper::VADisplayState> |
+ VaapiWrapper::g_va_display_state_ = LAZY_INSTANCE_INITIALIZER; |
+#endif |
+ |
base::LazyInstance<VaapiWrapper::LazyProfileInfos> |
VaapiWrapper::profile_infos_ = LAZY_INSTANCE_INITIALIZER; |
@@ -123,7 +128,6 @@ VaapiWrapper::VaapiWrapper() |
: va_display_(NULL), |
va_config_id_(VA_INVALID_ID), |
va_context_id_(VA_INVALID_ID), |
- va_initialized_(false), |
va_vpp_config_id_(VA_INVALID_ID), |
va_vpp_context_id_(VA_INVALID_ID), |
va_vpp_buffer_id_(VA_INVALID_ID) { |
@@ -314,30 +318,27 @@ bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) { |
base::AutoLock auto_lock(va_lock_); |
+ VADisplayState* va_display_state = nullptr; |
+ |
#if defined(USE_X11) |
- va_display_ = vaGetDisplay(gfx::GetXDisplay()); |
+ va_display_state = new VADisplayState(); |
+ va_display_state_.reset(va_display_state); |
#elif defined(USE_OZONE) |
- const char* kDriRenderNode0Path = "/dev/dri/renderD128"; |
- drm_file_ = base::File(base::FilePath::FromUTF8Unsafe(kDriRenderNode0Path), |
- base::File::FLAG_OPEN | base::File::FLAG_READ | |
- base::File::FLAG_WRITE); |
- va_display_ = vaGetDisplayDRM(drm_file_.GetPlatformFile()); |
+ va_display_state = &g_va_display_state_.Get(); |
#endif // USE_X11 |
- if (!vaDisplayIsValid(va_display_)) { |
- LOG(ERROR) << "Could not get a valid VA display"; |
+ if (!va_display_state) { |
+ LOG(ERROR) << "Could not allocate VA display state"; |
return false; |
} |
- VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); |
- VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); |
- va_initialized_ = true; |
- DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; |
- |
- if (VAAPIVersionLessThan(0, 34)) { |
- LOG(ERROR) << "VAAPI version < 0.34 is not supported."; |
+ VAStatus va_res = VA_STATUS_SUCCESS; |
+ if (!va_display_state->Initialize(&va_res)) { |
+ VA_LOG_ON_ERROR(va_res, "vaInitialize failed"); |
return false; |
} |
+ |
+ va_display_ = va_display_state->GetVADisplay(); |
return true; |
} |
@@ -492,24 +493,22 @@ void VaapiWrapper::Deinitialize() { |
VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed"); |
} |
- // Must check if vaInitialize completed successfully, to work around a bug in |
- // libva. The bug was fixed upstream: |
- // http://lists.freedesktop.org/archives/libva/2013-July/001807.html |
- // TODO(mgiuca): Remove this check, and the |va_initialized_| variable, once |
- // the fix has rolled out sufficiently. |
- if (va_initialized_ && va_display_) { |
- VAStatus va_res = vaTerminate(va_display_); |
+ VADisplayState* va_display_state = nullptr; |
+ |
+#if defined(USE_X11) |
+ va_display_state = va_display_state_.get(); |
+#elif defined(USE_OZONE) |
+ va_display_state = &g_va_display_state_.Get(); |
+#endif // USE_X11 |
+ |
+ if (va_display_state) { |
+ VAStatus va_res = VA_STATUS_SUCCESS; |
+ va_display_state->Deinitialize(&va_res); |
VA_LOG_ON_ERROR(va_res, "vaTerminate failed"); |
} |
va_config_id_ = VA_INVALID_ID; |
va_display_ = NULL; |
- va_initialized_ = false; |
-} |
- |
-bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { |
- return (major_version_ < major) || |
- (major_version_ == major && minor_version_ < minor); |
} |
bool VaapiWrapper::CreateSurfaces(const gfx::Size& size, |
@@ -1042,6 +1041,17 @@ void VaapiWrapper::DeinitializeVpp() { |
} |
// static |
+void VaapiWrapper::PreSandboxInitialization() { |
+#if defined(USE_OZONE) |
+ const char* kDriRenderNode0Path = "/dev/dri/renderD128"; |
+ base::File drm_file = base::File( |
+ base::FilePath::FromUTF8Unsafe(kDriRenderNode0Path), |
+ base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE); |
+ g_va_display_state_.Get().SetDrmFd(drm_file.GetPlatformFile()); |
+#endif |
+} |
+ |
+// static |
bool VaapiWrapper::PostSandboxInitialization() { |
StubPathMap paths; |
@@ -1087,4 +1097,71 @@ bool VaapiWrapper::LazyProfileInfos::IsProfileSupported( |
return false; |
} |
+VaapiWrapper::VADisplayState::VADisplayState() |
+ : refcount_(0), |
+ va_display_(nullptr), |
+ major_version_(-1), |
+ minor_version_(-1), |
+ va_initialized_(false) {} |
+ |
+VaapiWrapper::VADisplayState::~VADisplayState() {} |
+ |
+bool VaapiWrapper::VADisplayState::Initialize(VAStatus* status) { |
+ if (refcount_++ == 0) { |
+#if defined(USE_X11) |
+ va_display_ = vaGetDisplay(gfx::GetXDisplay()); |
+#elif defined(USE_OZONE) |
+ va_display_ = vaGetDisplayDRM(drm_fd_.get()); |
+#endif // USE_X11 |
+ |
+ if (!vaDisplayIsValid(va_display_)) { |
+ LOG(ERROR) << "Could not get a valid VA display"; |
+ return false; |
+ } |
+ |
+ *status = vaInitialize(va_display_, &major_version_, &minor_version_); |
+ if (*status != VA_STATUS_SUCCESS) |
+ return false; |
+ |
+ va_initialized_ = true; |
+ DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; |
+ } |
+ |
+ if (VAAPIVersionLessThan(0, 34)) { |
+ LOG(ERROR) << "VAAPI version < 0.34 is not supported."; |
+ return false; |
+ } |
+ return true; |
+} |
+ |
+void VaapiWrapper::VADisplayState::Deinitialize(VAStatus* status) { |
+ if (--refcount_ > 0) |
+ return; |
+ |
+ // Must check if vaInitialize completed successfully, to work around a bug in |
+ // libva. The bug was fixed upstream: |
+ // http://lists.freedesktop.org/archives/libva/2013-July/001807.html |
+ // TODO(mgiuca): Remove this check, and the |va_initialized_| variable, once |
+ // the fix has rolled out sufficiently. |
+ if (va_initialized_ && va_display_) { |
+ *status = vaTerminate(va_display_); |
+ } |
+ va_initialized_ = false; |
+} |
+ |
+VADisplay VaapiWrapper::VADisplayState::GetVADisplay() const { |
+ return va_display_; |
+} |
+ |
+#if defined(USE_OZONE) |
+void VaapiWrapper::VADisplayState::SetDrmFd(base::PlatformFile fd) { |
+ drm_fd_.reset(dup(fd)); |
+} |
+#endif // USE_OZONE |
+ |
+bool VaapiWrapper::VADisplayState::VAAPIVersionLessThan(int major, int minor) { |
+ return (major_version_ < major) || |
+ (major_version_ == major && minor_version_ < minor); |
+} |
+ |
} // namespace content |