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

Side by Side Diff: content/common/gpu/media/vaapi_wrapper.cc

Issue 490233002: VaapiVideoAccelerator: make Vaapi accelerator work with ozone (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Missing modifications in video accelerators Created 6 years, 2 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"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/numerics/safe_conversions.h" 12 #include "base/numerics/safe_conversions.h"
13 // Auto-generated for dlopen libva libraries 13 // Auto-generated for dlopen libva libraries
14 #include "content/common/gpu/media/va_stubs.h" 14 #include "content/common/gpu/media/va_stubs.h"
15 #include "third_party/libyuv/include/libyuv.h" 15 #include "third_party/libyuv/include/libyuv.h"
16 #if defined(USE_X11)
17 #include "third_party/libva/va/va_x11.h"
18 #include "ui/gfx/x/x11_types.h"
19 #else
20 #include "third_party/libva/va/drm/va_drm.h"
21 #include "third_party/libva/va/va_drmcommon.h"
22 #include "ui/ozone/public/ozone_platform.h"
23 #include "ui/ozone/public/surface_factory_ozone.h"
24 #endif // USE_X11
25 #include "ui/gl/gl_bindings.h"
16 26
17 using content_common_gpu_media::kModuleVa; 27 using content_common_gpu_media::kModuleVa;
28 #if defined(USE_X11)
29 using content_common_gpu_media::kModuleVa_x11;
30 #else
31 using content_common_gpu_media::kModuleVa_drm;
32 #endif // USE_X11
18 using content_common_gpu_media::InitializeStubs; 33 using content_common_gpu_media::InitializeStubs;
19 using content_common_gpu_media::StubPathMap; 34 using content_common_gpu_media::StubPathMap;
20 35
21 // libva-x11 depends on libva, so dlopen libva-x11 is enough
22 static const base::FilePath::CharType kVaLib[] =
23 FILE_PATH_LITERAL("libva-x11.so.1");
24
25 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ 36 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \
26 do { \ 37 do { \
27 DVLOG(1) << err_msg \ 38 DVLOG(1) << err_msg \
28 << " VA error: " << vaErrorStr(va_error); \ 39 << " VA error: " << vaErrorStr(va_error); \
29 report_error_to_uma_cb_.Run(); \ 40 report_error_to_uma_cb_.Run(); \
30 } while (0) 41 } while (0)
31 42
32 #define VA_LOG_ON_ERROR(va_error, err_msg) \ 43 #define VA_LOG_ON_ERROR(va_error, err_msg) \
33 do { \ 44 do { \
34 if ((va_error) != VA_STATUS_SUCCESS) \ 45 if ((va_error) != VA_STATUS_SUCCESS) \
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 VaapiWrapper::~VaapiWrapper() { 132 VaapiWrapper::~VaapiWrapper() {
122 DestroyPendingBuffers(); 133 DestroyPendingBuffers();
123 DestroyCodedBuffers(); 134 DestroyCodedBuffers();
124 DestroySurfaces(); 135 DestroySurfaces();
125 Deinitialize(); 136 Deinitialize();
126 } 137 }
127 138
128 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( 139 scoped_ptr<VaapiWrapper> VaapiWrapper::Create(
129 CodecMode mode, 140 CodecMode mode,
130 media::VideoCodecProfile profile, 141 media::VideoCodecProfile profile,
131 Display* x_display,
132 const base::Closure& report_error_to_uma_cb) { 142 const base::Closure& report_error_to_uma_cb) {
143 static bool vaapi_functions_initialized = PostSandboxInitialization();
133 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); 144 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
134 145
135 if (!vaapi_wrapper->Initialize( 146 if (!vaapi_functions_initialized) {
136 mode, profile, x_display, report_error_to_uma_cb)) 147 DVLOG(1) << "Failed to initialize VAAPI libs";
148 return vaapi_wrapper.Pass();
149 }
150
151 VADisplay va_display = NULL;
152 #if defined(USE_X11)
153 va_display = vaGetDisplay(gfx::GetXDisplay());
154 #else
155 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance();
156 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone();
157
158 va_display = vaGetDisplayDRM(factory->GetDrmFd());
Pawel Osciak 2014/10/08 08:17:22 Do we need to close the fd somewhere?
llandwerlin-old 2014/10/13 16:53:00 I don't think we need to do anything here. The fil
159 #endif // USE_X11
160
161 if (!va_display ||
162 !vaapi_wrapper->Initialize(
163 va_display, mode, profile, report_error_to_uma_cb))
137 vaapi_wrapper.reset(); 164 vaapi_wrapper.reset();
138 165
139 return vaapi_wrapper.Pass(); 166 return vaapi_wrapper.Pass();
140 } 167 }
141 168
142 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { 169 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
143 VADisplayAttribute item = {VADisplayAttribRenderMode, 170 VADisplayAttribute item = {VADisplayAttribRenderMode,
144 1, // At least support '_LOCAL_OVERLAY'. 171 1, // At least support '_LOCAL_OVERLAY'.
145 -1, // The maximum possible support 'ALL'. 172 -1, // The maximum possible support 'ALL'.
146 VA_RENDER_MODE_LOCAL_GPU, 173 VA_RENDER_MODE_LOCAL_GPU,
147 VA_DISPLAY_ATTRIB_SETTABLE}; 174 VA_DISPLAY_ATTRIB_SETTABLE};
148 175
149 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); 176 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1);
150 if (va_res != VA_STATUS_SUCCESS) 177 if (va_res != VA_STATUS_SUCCESS)
151 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; 178 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default.";
152 } 179 }
153 180
154 bool VaapiWrapper::Initialize(CodecMode mode, 181 bool VaapiWrapper::Initialize(VADisplay va_display,
182 CodecMode mode,
155 media::VideoCodecProfile profile, 183 media::VideoCodecProfile profile,
156 Display* x_display,
157 const base::Closure& report_error_to_uma_cb) { 184 const base::Closure& report_error_to_uma_cb) {
158 static bool vaapi_functions_initialized = PostSandboxInitialization();
159 if (!vaapi_functions_initialized) {
160 DVLOG(1) << "Failed to initialize VAAPI libs";
161 return false;
162 }
163
164 report_error_to_uma_cb_ = report_error_to_uma_cb; 185 report_error_to_uma_cb_ = report_error_to_uma_cb;
165 186
166 base::AutoLock auto_lock(va_lock_); 187 base::AutoLock auto_lock(va_lock_);
167 188
168 va_display_ = vaGetDisplay(x_display); 189 va_display_ = va_display;
169 if (!vaDisplayIsValid(va_display_)) { 190 if (!vaDisplayIsValid(va_display_)) {
170 DVLOG(1) << "Could not get a valid VA display"; 191 DVLOG(1) << "Could not get a valid VA display";
171 return false; 192 return false;
172 } 193 }
173 194
174 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); 195 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_);
175 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); 196 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false);
176 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; 197 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_;
177 198
178 if (VAAPIVersionLessThan(0, 34)) { 199 if (VAAPIVersionLessThan(0, 34)) {
(...skipping 12 matching lines...) Expand all
191 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); 212 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false);
192 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { 213 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) {
193 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles; 214 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles;
194 return false; 215 return false;
195 } 216 }
196 217
197 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); 218 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles));
198 219
199 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles); 220 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles);
200 if (va_profile == VAProfileNone) { 221 if (va_profile == VAProfileNone) {
201 DVLOG(1) << "Unsupported profile"; 222 DVLOG(1) << "Unsupported profile : " << profile;
202 return false; 223 return false;
203 } 224 }
204 225
205 // Query the driver for supported entrypoints. 226 // Query the driver for supported entrypoints.
206 int max_entrypoints = vaMaxNumEntrypoints(va_display_); 227 int max_entrypoints = vaMaxNumEntrypoints(va_display_);
207 std::vector<VAEntrypoint> supported_entrypoints( 228 std::vector<VAEntrypoint> supported_entrypoints(
208 base::checked_cast<size_t>(max_entrypoints)); 229 base::checked_cast<size_t>(max_entrypoints));
209 230
210 int num_supported_entrypoints; 231 int num_supported_entrypoints;
211 va_res = vaQueryConfigEntrypoints(va_display_, 232 va_res = vaQueryConfigEntrypoints(va_display_,
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 310
290 va_config_id_ = VA_INVALID_ID; 311 va_config_id_ = VA_INVALID_ID;
291 va_display_ = NULL; 312 va_display_ = NULL;
292 } 313 }
293 314
294 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { 315 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) {
295 return (major_version_ < major) || 316 return (major_version_ < major) ||
296 (major_version_ == major && minor_version_ < minor); 317 (major_version_ == major && minor_version_ < minor);
297 } 318 }
298 319
299 bool VaapiWrapper::CreateSurfaces(gfx::Size size, 320 bool VaapiWrapper::CreateSurfaces(const gfx::Size& size,
300 size_t num_surfaces, 321 size_t num_surfaces,
301 std::vector<VASurfaceID>* va_surfaces) { 322 std::vector<VASurfaceID>* va_surfaces) {
302 base::AutoLock auto_lock(va_lock_); 323 base::AutoLock auto_lock(va_lock_);
303 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; 324 DVLOG(2) << "Creating " << num_surfaces << " surfaces";
304 325
305 DCHECK(va_surfaces->empty()); 326 DCHECK(va_surfaces->empty());
306 DCHECK(va_surface_ids_.empty()); 327 DCHECK(va_surface_ids_.empty());
307 va_surface_ids_.resize(num_surfaces); 328 va_surface_ids_.resize(num_surfaces);
308 329
309 // Allocate surfaces in driver. 330 // Allocate surfaces in driver.
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 520
500 return true; 521 return true;
501 } 522 }
502 523
503 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { 524 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) {
504 bool result = Execute(va_surface_id); 525 bool result = Execute(va_surface_id);
505 DestroyPendingBuffers(); 526 DestroyPendingBuffers();
506 return result; 527 return result;
507 } 528 }
508 529
509 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id,
510 Pixmap x_pixmap,
511 gfx::Size dest_size) {
512 base::AutoLock auto_lock(va_lock_);
513
514 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
515 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
516
517 // Put the data into an X Pixmap.
518 va_res = vaPutSurface(va_display_,
519 va_surface_id,
520 x_pixmap,
521 0, 0, dest_size.width(), dest_size.height(),
522 0, 0, dest_size.width(), dest_size.height(),
523 NULL, 0, 0);
524 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false);
525 return true;
526 }
527
528 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, 530 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id,
529 VAImage* image, 531 VAImage* image,
530 void** mem) { 532 void** mem) {
531 base::AutoLock auto_lock(va_lock_); 533 base::AutoLock auto_lock(va_lock_);
532 534
533 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); 535 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
534 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); 536 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
535 537
536 // Derive a VAImage from the VASurface 538 // Derive a VAImage from the VASurface
537 va_res = vaDeriveImage(va_display_, va_surface_id, image); 539 va_res = vaDeriveImage(va_display_, va_surface_id, image);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); 660 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
659 661
660 va_res = vaDestroyBuffer(va_display_, buffer_id); 662 va_res = vaDestroyBuffer(va_display_, buffer_id);
661 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); 663 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
662 664
663 DCHECK(coded_buffers_.erase(buffer_id)); 665 DCHECK(coded_buffers_.erase(buffer_id));
664 666
665 return buffer_segment == NULL; 667 return buffer_segment == NULL;
666 } 668 }
667 669
670 VADisplay VaapiWrapper::GetDisplay() {
671 return va_display_;
672 }
673
668 // static 674 // static
669 bool VaapiWrapper::PostSandboxInitialization() { 675 bool VaapiWrapper::PostSandboxInitialization() {
670 StubPathMap paths; 676 StubPathMap paths;
671 paths[kModuleVa].push_back(kVaLib); 677
678 paths[kModuleVa].push_back("libva.so.1");
679
680 #if defined(USE_X11)
681 paths[kModuleVa_x11].push_back("libva-x11.so.1");
682 #else
683 paths[kModuleVa_drm].push_back("libva-drm.so.1");
684 #endif
672 685
673 return InitializeStubs(paths); 686 return InitializeStubs(paths);
674 } 687 }
675 688
676 } // namespace content 689 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698