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

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

Issue 1137483002: VAAPI Wrapper: refactor management of drm file (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move va_lock_ into VADisplayState and ensure its validity for lifetime of VaapiWrapper. Created 5 years, 7 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 219e370e5bdc29475be4555ccc20660528d03500..6be12d237f64f10f71f9af496379041ac198d563 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,10 +128,15 @@ 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) {
+#if defined(USE_X11)
+ va_display_state_.reset(new VADisplayState());
+ va_lock_ = va_display_state_->va_lock();
+#elif defined(USE_OZONE)
+ va_lock_ = g_va_display_state_.Get().va_lock();
+#endif // USE_X11
}
VaapiWrapper::~VaapiWrapper() {
@@ -223,7 +233,7 @@ VaapiWrapper::GetSupportedDecodeProfiles() {
}
void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
VADisplayAttribute item = {VADisplayAttribRenderMode,
1, // At least support '_LOCAL_OVERLAY'.
-1, // The maximum possible support 'ALL'.
@@ -272,7 +282,7 @@ VaapiWrapper::GetSupportedProfileInfosForCodecModeInternal(CodecMode mode) {
VAEntrypoint entrypoint =
(mode == kEncode ? VAEntrypointEncSlice: VAEntrypointVLD);
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
for (const auto& va_profile : va_profiles) {
if (!IsEntrypointSupported_Locked(va_profile, entrypoint))
continue;
@@ -312,37 +322,33 @@ bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) {
report_error_to_uma_cb_ = report_error_to_uma_cb;
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
+
+ VADisplayState* va_display_state = nullptr;
#if defined(USE_X11)
- va_display_ = vaGetDisplay(gfx::GetXDisplay());
+ va_display_state = va_display_state_.get();
#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) << "Failed to 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;
}
bool VaapiWrapper::GetSupportedVaProfiles(std::vector<VAProfile>* profiles) {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
// Query the driver for supported profiles.
int max_profiles = vaMaxNumProfiles(va_display_);
std::vector<VAProfile> supported_profiles(
@@ -364,7 +370,7 @@ bool VaapiWrapper::GetSupportedVaProfiles(std::vector<VAProfile>* profiles) {
bool VaapiWrapper::IsEntrypointSupported_Locked(VAProfile va_profile,
VAEntrypoint entrypoint) {
- va_lock_.AssertAcquired();
+ va_lock_->AssertAcquired();
// Query the driver for supported entrypoints.
int max_entrypoints = vaMaxNumEntrypoints(va_display_);
std::vector<VAEntrypoint> supported_entrypoints(
@@ -396,7 +402,7 @@ bool VaapiWrapper::AreAttribsSupported_Locked(
VAProfile va_profile,
VAEntrypoint entrypoint,
const std::vector<VAConfigAttrib>& required_attribs) {
- va_lock_.AssertAcquired();
+ va_lock_->AssertAcquired();
// Query the driver for required attributes.
std::vector<VAConfigAttrib> attribs = required_attribs;
for (size_t i = 0; i < required_attribs.size(); ++i)
@@ -423,7 +429,7 @@ bool VaapiWrapper::GetMaxResolution_Locked(
VAEntrypoint entrypoint,
std::vector<VAConfigAttrib>& required_attribs,
gfx::Size* resolution) {
- va_lock_.AssertAcquired();
+ va_lock_->AssertAcquired();
VAConfigID va_config_id;
VAStatus va_res = vaCreateConfig(
va_display_,
@@ -472,7 +478,7 @@ bool VaapiWrapper::Initialize(CodecMode mode, VAProfile va_profile) {
VAEntrypoint entrypoint =
(mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD);
std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode);
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
VAStatus va_res = vaCreateConfig(va_display_,
va_profile,
entrypoint,
@@ -485,37 +491,35 @@ bool VaapiWrapper::Initialize(CodecMode mode, VAProfile va_profile) {
}
void VaapiWrapper::Deinitialize() {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
if (va_config_id_ != VA_INVALID_ID) {
VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_);
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,
size_t num_surfaces,
std::vector<VASurfaceID>* va_surfaces) {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
DVLOG(2) << "Creating " << num_surfaces << " surfaces";
DCHECK(va_surfaces->empty());
@@ -553,7 +557,7 @@ bool VaapiWrapper::CreateSurfaces(const gfx::Size& size,
}
void VaapiWrapper::DestroySurfaces() {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
DVLOG(2) << "Destroying " << va_surface_ids_.size() << " surfaces";
if (va_context_id_ != VA_INVALID_ID) {
@@ -575,7 +579,7 @@ scoped_refptr<VASurface> VaapiWrapper::CreateUnownedSurface(
unsigned int va_format,
const gfx::Size& size,
const std::vector<VASurfaceAttrib>& va_attribs) {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
std::vector<VASurfaceAttrib> attribs(va_attribs);
VASurfaceID va_surface_id;
@@ -598,7 +602,7 @@ scoped_refptr<VASurface> VaapiWrapper::CreateUnownedSurface(
}
void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface_id) {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_id, 1);
VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on surface failed");
@@ -607,7 +611,7 @@ void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface_id) {
bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type,
size_t size,
void* buffer) {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
VABufferID buffer_id;
VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_,
@@ -634,7 +638,7 @@ bool VaapiWrapper::SubmitVAEncMiscParamBuffer(
VAEncMiscParameterType misc_param_type,
size_t size,
void* buffer) {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
VABufferID buffer_id;
VAStatus va_res = vaCreateBuffer(va_display_,
@@ -668,7 +672,7 @@ bool VaapiWrapper::SubmitVAEncMiscParamBuffer(
}
void VaapiWrapper::DestroyPendingBuffers() {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
for (const auto& pending_va_buf : pending_va_bufs_) {
VAStatus va_res = vaDestroyBuffer(va_display_, pending_va_buf);
@@ -685,7 +689,7 @@ void VaapiWrapper::DestroyPendingBuffers() {
}
bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
VAStatus va_res = vaCreateBuffer(va_display_,
va_context_id_,
VAEncCodedBufferType,
@@ -700,7 +704,7 @@ bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) {
}
void VaapiWrapper::DestroyCodedBuffers() {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
for (std::set<VABufferID>::const_iterator iter = coded_buffers_.begin();
iter != coded_buffers_.end();
@@ -713,7 +717,7 @@ void VaapiWrapper::DestroyCodedBuffers() {
}
bool VaapiWrapper::Execute(VASurfaceID va_surface_id) {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
DVLOG(4) << "Pending VA bufs to commit: " << pending_va_bufs_.size();
DVLOG(4) << "Pending slice bufs to commit: " << pending_slice_bufs_.size();
@@ -759,7 +763,7 @@ bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) {
bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id,
Pixmap x_pixmap,
gfx::Size dest_size) {
- base::AutoLock auto_lock(va_lock_);
+ 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);
@@ -779,7 +783,7 @@ bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id,
bool VaapiWrapper::GetDerivedVaImage(VASurfaceID va_surface_id,
VAImage* image,
void** mem) {
- base::AutoLock auto_lock(va_lock_);
+ 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);
@@ -807,7 +811,7 @@ bool VaapiWrapper::GetVaImage(VASurfaceID va_surface_id,
const gfx::Size& size,
VAImage* image,
void** mem) {
- base::AutoLock auto_lock(va_lock_);
+ 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);
@@ -836,7 +840,7 @@ bool VaapiWrapper::GetVaImage(VASurfaceID va_surface_id,
}
void VaapiWrapper::ReturnVaImage(VAImage* image) {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
VAStatus va_res = vaUnmapBuffer(va_display_, image->buf);
VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
@@ -853,7 +857,7 @@ static void DestroyVAImage(VADisplay va_display, VAImage image) {
bool VaapiWrapper::UploadVideoFrameToSurface(
const scoped_refptr<media::VideoFrame>& frame,
VASurfaceID va_surface_id) {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
VAImage image;
VAStatus va_res = vaDeriveImage(va_display_, va_surface_id, &image);
@@ -878,7 +882,7 @@ bool VaapiWrapper::UploadVideoFrameToSurface(
int ret = 0;
{
- base::AutoUnlock auto_unlock(va_lock_);
+ base::AutoUnlock auto_unlock(*va_lock_);
ret = libyuv::I420ToNV12(frame->data(media::VideoFrame::kYPlane),
frame->stride(media::VideoFrame::kYPlane),
frame->data(media::VideoFrame::kUPlane),
@@ -904,7 +908,7 @@ bool VaapiWrapper::DownloadAndDestroyCodedBuffer(VABufferID buffer_id,
uint8* target_ptr,
size_t target_size,
size_t* coded_data_size) {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
VAStatus va_res = vaSyncSurface(va_display_, sync_surface_id);
VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
@@ -916,7 +920,7 @@ bool VaapiWrapper::DownloadAndDestroyCodedBuffer(VABufferID buffer_id,
DCHECK(target_ptr);
{
- base::AutoUnlock auto_unlock(va_lock_);
+ base::AutoUnlock auto_unlock(*va_lock_);
*coded_data_size = 0;
while (buffer_segment) {
@@ -953,7 +957,7 @@ bool VaapiWrapper::BlitSurface(VASurfaceID va_surface_id_src,
const gfx::Size& src_size,
VASurfaceID va_surface_id_dest,
const gfx::Size& dest_size) {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
// Initialize the post processing engine if not already done.
if (va_vpp_buffer_id_ == VA_INVALID_ID) {
@@ -1002,7 +1006,7 @@ bool VaapiWrapper::BlitSurface(VASurfaceID va_surface_id_src,
}
bool VaapiWrapper::InitializeVpp_Locked() {
- va_lock_.AssertAcquired();
+ va_lock_->AssertAcquired();
VA_SUCCESS_OR_RETURN(
vaCreateConfig(va_display_, VAProfileNone, VAEntrypointVideoProc, NULL, 0,
@@ -1025,7 +1029,7 @@ bool VaapiWrapper::InitializeVpp_Locked() {
}
void VaapiWrapper::DeinitializeVpp() {
- base::AutoLock auto_lock(va_lock_);
+ base::AutoLock auto_lock(*va_lock_);
if (va_vpp_buffer_id_ != VA_INVALID_ID) {
vaDestroyBuffer(va_display_, va_vpp_buffer_id_);
@@ -1042,6 +1046,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 +1102,67 @@ 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;
+}
+
+#if defined(USE_OZONE)
+void VaapiWrapper::VADisplayState::SetDrmFd(base::PlatformFile fd) {
+ drm_fd_.reset(dup(fd));
piman 2015/05/11 21:54:07 nit: dup needs to be wrapped into a HANDLE_EINTR m
hshi1 2015/05/11 22:26:40 Done.
+}
+#endif // USE_OZONE
+
+bool VaapiWrapper::VADisplayState::VAAPIVersionLessThan(int major, int minor) {
+ return (major_version_ < major) ||
+ (major_version_ == major && minor_version_ < minor);
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698