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

Side by Side 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: Make va_display_state_ a scoped_ptr for X11 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/gpu/media/vaapi_wrapper.h" 5 #include "content/common/gpu/media/vaapi_wrapper.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 return (ret); \ 55 return (ret); \
56 } \ 56 } \
57 } while (0) 57 } while (0)
58 58
59 namespace content { 59 namespace content {
60 60
61 // Maximum framerate of encoded profile. This value is an arbitary limit 61 // Maximum framerate of encoded profile. This value is an arbitary limit
62 // and not taken from HW documentation. 62 // and not taken from HW documentation.
63 const int kMaxEncoderFramerate = 30; 63 const int kMaxEncoderFramerate = 30;
64 64
65 #if defined(USE_OZONE)
66 base::LazyInstance<VaapiWrapper::VADisplayState>
67 VaapiWrapper::g_va_display_state_ = LAZY_INSTANCE_INITIALIZER;
68 #endif
69
65 base::LazyInstance<VaapiWrapper::LazyProfileInfos> 70 base::LazyInstance<VaapiWrapper::LazyProfileInfos>
66 VaapiWrapper::profile_infos_ = LAZY_INSTANCE_INITIALIZER; 71 VaapiWrapper::profile_infos_ = LAZY_INSTANCE_INITIALIZER;
67 72
68 // Config attributes common for both encode and decode. 73 // Config attributes common for both encode and decode.
69 static const VAConfigAttrib kCommonVAConfigAttribs[] = { 74 static const VAConfigAttrib kCommonVAConfigAttribs[] = {
70 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420}, 75 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420},
71 }; 76 };
72 77
73 // Attributes required for encode. 78 // Attributes required for encode.
74 static const VAConfigAttrib kEncodeVAConfigAttribs[] = { 79 static const VAConfigAttrib kEncodeVAConfigAttribs[] = {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 } 121 }
117 122
118 VASurface::~VASurface() { 123 VASurface::~VASurface() {
119 release_cb_.Run(va_surface_id_); 124 release_cb_.Run(va_surface_id_);
120 } 125 }
121 126
122 VaapiWrapper::VaapiWrapper() 127 VaapiWrapper::VaapiWrapper()
123 : va_display_(NULL), 128 : va_display_(NULL),
124 va_config_id_(VA_INVALID_ID), 129 va_config_id_(VA_INVALID_ID),
125 va_context_id_(VA_INVALID_ID), 130 va_context_id_(VA_INVALID_ID),
126 va_initialized_(false),
127 va_vpp_config_id_(VA_INVALID_ID), 131 va_vpp_config_id_(VA_INVALID_ID),
128 va_vpp_context_id_(VA_INVALID_ID), 132 va_vpp_context_id_(VA_INVALID_ID),
129 va_vpp_buffer_id_(VA_INVALID_ID) { 133 va_vpp_buffer_id_(VA_INVALID_ID) {
130 } 134 }
131 135
132 VaapiWrapper::~VaapiWrapper() { 136 VaapiWrapper::~VaapiWrapper() {
133 DestroyPendingBuffers(); 137 DestroyPendingBuffers();
134 DestroyCodedBuffers(); 138 DestroyCodedBuffers();
135 DestroySurfaces(); 139 DestroySurfaces();
136 DeinitializeVpp(); 140 DeinitializeVpp();
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 LOG(ERROR) << kErrorMsg; 311 LOG(ERROR) << kErrorMsg;
308 else 312 else
309 DVLOG(1) << kErrorMsg; 313 DVLOG(1) << kErrorMsg;
310 return false; 314 return false;
311 } 315 }
312 316
313 report_error_to_uma_cb_ = report_error_to_uma_cb; 317 report_error_to_uma_cb_ = report_error_to_uma_cb;
314 318
315 base::AutoLock auto_lock(va_lock_); 319 base::AutoLock auto_lock(va_lock_);
316 320
321 VADisplayState* va_display_state = nullptr;
322
317 #if defined(USE_X11) 323 #if defined(USE_X11)
318 va_display_ = vaGetDisplay(gfx::GetXDisplay()); 324 va_display_state = new VADisplayState();
325 va_display_state_.reset(va_display_state);
319 #elif defined(USE_OZONE) 326 #elif defined(USE_OZONE)
320 const char* kDriRenderNode0Path = "/dev/dri/renderD128"; 327 va_display_state = &g_va_display_state_.Get();
321 drm_file_ = base::File(base::FilePath::FromUTF8Unsafe(kDriRenderNode0Path),
322 base::File::FLAG_OPEN | base::File::FLAG_READ |
323 base::File::FLAG_WRITE);
324 va_display_ = vaGetDisplayDRM(drm_file_.GetPlatformFile());
325 #endif // USE_X11 328 #endif // USE_X11
326 329
327 if (!vaDisplayIsValid(va_display_)) { 330 if (!va_display_state) {
328 LOG(ERROR) << "Could not get a valid VA display"; 331 LOG(ERROR) << "Could not allocate VA display state";
329 return false; 332 return false;
330 } 333 }
331 334
332 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); 335 VAStatus va_res = VA_STATUS_SUCCESS;
333 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); 336 if (!va_display_state->Initialize(&va_res)) {
334 va_initialized_ = true; 337 VA_LOG_ON_ERROR(va_res, "vaInitialize failed");
335 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_;
336
337 if (VAAPIVersionLessThan(0, 34)) {
338 LOG(ERROR) << "VAAPI version < 0.34 is not supported.";
339 return false; 338 return false;
340 } 339 }
340
341 va_display_ = va_display_state->GetVADisplay();
341 return true; 342 return true;
342 } 343 }
343 344
344 bool VaapiWrapper::GetSupportedVaProfiles(std::vector<VAProfile>* profiles) { 345 bool VaapiWrapper::GetSupportedVaProfiles(std::vector<VAProfile>* profiles) {
345 base::AutoLock auto_lock(va_lock_); 346 base::AutoLock auto_lock(va_lock_);
346 // Query the driver for supported profiles. 347 // Query the driver for supported profiles.
347 int max_profiles = vaMaxNumProfiles(va_display_); 348 int max_profiles = vaMaxNumProfiles(va_display_);
348 std::vector<VAProfile> supported_profiles( 349 std::vector<VAProfile> supported_profiles(
349 base::checked_cast<size_t>(max_profiles)); 350 base::checked_cast<size_t>(max_profiles));
350 351
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 } 486 }
486 487
487 void VaapiWrapper::Deinitialize() { 488 void VaapiWrapper::Deinitialize() {
488 base::AutoLock auto_lock(va_lock_); 489 base::AutoLock auto_lock(va_lock_);
489 490
490 if (va_config_id_ != VA_INVALID_ID) { 491 if (va_config_id_ != VA_INVALID_ID) {
491 VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_); 492 VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_);
492 VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed"); 493 VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed");
493 } 494 }
494 495
495 // Must check if vaInitialize completed successfully, to work around a bug in 496 VADisplayState* va_display_state = nullptr;
496 // libva. The bug was fixed upstream: 497
497 // http://lists.freedesktop.org/archives/libva/2013-July/001807.html 498 #if defined(USE_X11)
498 // TODO(mgiuca): Remove this check, and the |va_initialized_| variable, once 499 va_display_state = va_display_state_.get();
499 // the fix has rolled out sufficiently. 500 #elif defined(USE_OZONE)
500 if (va_initialized_ && va_display_) { 501 va_display_state = &g_va_display_state_.Get();
501 VAStatus va_res = vaTerminate(va_display_); 502 #endif // USE_X11
503
504 if (va_display_state) {
505 VAStatus va_res = VA_STATUS_SUCCESS;
506 va_display_state->Deinitialize(&va_res);
502 VA_LOG_ON_ERROR(va_res, "vaTerminate failed"); 507 VA_LOG_ON_ERROR(va_res, "vaTerminate failed");
503 } 508 }
504 509
505 va_config_id_ = VA_INVALID_ID; 510 va_config_id_ = VA_INVALID_ID;
506 va_display_ = NULL; 511 va_display_ = NULL;
507 va_initialized_ = false;
508 }
509
510 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) {
511 return (major_version_ < major) ||
512 (major_version_ == major && minor_version_ < minor);
513 } 512 }
514 513
515 bool VaapiWrapper::CreateSurfaces(const gfx::Size& size, 514 bool VaapiWrapper::CreateSurfaces(const gfx::Size& size,
516 size_t num_surfaces, 515 size_t num_surfaces,
517 std::vector<VASurfaceID>* va_surfaces) { 516 std::vector<VASurfaceID>* va_surfaces) {
518 base::AutoLock auto_lock(va_lock_); 517 base::AutoLock auto_lock(va_lock_);
519 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; 518 DVLOG(2) << "Creating " << num_surfaces << " surfaces";
520 519
521 DCHECK(va_surfaces->empty()); 520 DCHECK(va_surfaces->empty());
522 DCHECK(va_surface_ids_.empty()); 521 DCHECK(va_surface_ids_.empty());
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 vaDestroyContext(va_display_, va_vpp_context_id_); 1034 vaDestroyContext(va_display_, va_vpp_context_id_);
1036 va_vpp_context_id_ = VA_INVALID_ID; 1035 va_vpp_context_id_ = VA_INVALID_ID;
1037 } 1036 }
1038 if (va_vpp_config_id_ != VA_INVALID_ID) { 1037 if (va_vpp_config_id_ != VA_INVALID_ID) {
1039 vaDestroyConfig(va_display_, va_vpp_config_id_); 1038 vaDestroyConfig(va_display_, va_vpp_config_id_);
1040 va_vpp_config_id_ = VA_INVALID_ID; 1039 va_vpp_config_id_ = VA_INVALID_ID;
1041 } 1040 }
1042 } 1041 }
1043 1042
1044 // static 1043 // static
1044 void VaapiWrapper::PreSandboxInitialization() {
1045 #if defined(USE_OZONE)
1046 const char* kDriRenderNode0Path = "/dev/dri/renderD128";
1047 base::File drm_file = base::File(
1048 base::FilePath::FromUTF8Unsafe(kDriRenderNode0Path),
1049 base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE);
1050 g_va_display_state_.Get().SetDrmFd(drm_file.GetPlatformFile());
1051 #endif
1052 }
1053
1054 // static
1045 bool VaapiWrapper::PostSandboxInitialization() { 1055 bool VaapiWrapper::PostSandboxInitialization() {
1046 StubPathMap paths; 1056 StubPathMap paths;
1047 1057
1048 paths[kModuleVa].push_back("libva.so.1"); 1058 paths[kModuleVa].push_back("libva.so.1");
1049 1059
1050 #if defined(USE_X11) 1060 #if defined(USE_X11)
1051 paths[kModuleVa_x11].push_back("libva-x11.so.1"); 1061 paths[kModuleVa_x11].push_back("libva-x11.so.1");
1052 #elif defined(USE_OZONE) 1062 #elif defined(USE_OZONE)
1053 paths[kModuleVa_drm].push_back("libva-drm.so.1"); 1063 paths[kModuleVa_drm].push_back("libva-drm.so.1");
1054 #endif 1064 #endif
(...skipping 25 matching lines...) Expand all
1080 1090
1081 bool VaapiWrapper::LazyProfileInfos::IsProfileSupported( 1091 bool VaapiWrapper::LazyProfileInfos::IsProfileSupported(
1082 CodecMode mode, VAProfile va_profile) { 1092 CodecMode mode, VAProfile va_profile) {
1083 for (const auto& profile : supported_profiles_[mode]) { 1093 for (const auto& profile : supported_profiles_[mode]) {
1084 if (profile.va_profile == va_profile) 1094 if (profile.va_profile == va_profile)
1085 return true; 1095 return true;
1086 } 1096 }
1087 return false; 1097 return false;
1088 } 1098 }
1089 1099
1100 VaapiWrapper::VADisplayState::VADisplayState()
1101 : refcount_(0),
1102 va_display_(nullptr),
1103 major_version_(-1),
1104 minor_version_(-1),
1105 va_initialized_(false) {}
1106
1107 VaapiWrapper::VADisplayState::~VADisplayState() {}
1108
1109 bool VaapiWrapper::VADisplayState::Initialize(VAStatus* status) {
1110 if (refcount_++ == 0) {
1111 #if defined(USE_X11)
1112 va_display_ = vaGetDisplay(gfx::GetXDisplay());
1113 #elif defined(USE_OZONE)
1114 va_display_ = vaGetDisplayDRM(drm_fd_.get());
1115 #endif // USE_X11
1116
1117 if (!vaDisplayIsValid(va_display_)) {
1118 LOG(ERROR) << "Could not get a valid VA display";
1119 return false;
1120 }
1121
1122 *status = vaInitialize(va_display_, &major_version_, &minor_version_);
1123 if (*status != VA_STATUS_SUCCESS)
1124 return false;
1125
1126 va_initialized_ = true;
1127 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_;
1128 }
1129
1130 if (VAAPIVersionLessThan(0, 34)) {
1131 LOG(ERROR) << "VAAPI version < 0.34 is not supported.";
1132 return false;
1133 }
1134 return true;
1135 }
1136
1137 void VaapiWrapper::VADisplayState::Deinitialize(VAStatus* status) {
1138 if (--refcount_ > 0)
1139 return;
1140
1141 // Must check if vaInitialize completed successfully, to work around a bug in
1142 // libva. The bug was fixed upstream:
1143 // http://lists.freedesktop.org/archives/libva/2013-July/001807.html
1144 // TODO(mgiuca): Remove this check, and the |va_initialized_| variable, once
1145 // the fix has rolled out sufficiently.
1146 if (va_initialized_ && va_display_) {
1147 *status = vaTerminate(va_display_);
1148 }
1149 va_initialized_ = false;
1150 }
1151
1152 VADisplay VaapiWrapper::VADisplayState::GetVADisplay() const {
1153 return va_display_;
1154 }
1155
1156 #if defined(USE_OZONE)
1157 void VaapiWrapper::VADisplayState::SetDrmFd(base::PlatformFile fd) {
1158 drm_fd_.reset(dup(fd));
1159 }
1160 #endif // USE_OZONE
1161
1162 bool VaapiWrapper::VADisplayState::VAAPIVersionLessThan(int major, int minor) {
1163 return (major_version_ < major) ||
1164 (major_version_ == major && minor_version_ < minor);
1165 }
1166
1090 } // namespace content 1167 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698