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

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: Don't limit h264_bitstream_buffer_unittest to x11 Created 6 years, 3 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());
jiajia.qin 2014/09/16 11:09:55 Hi, llandwerlin. Does it work for other external d
llandwerlin-old 2014/09/16 12:28:58 What do you mean by external display? Are you usin
spang 2014/09/16 16:31:28 No, it doesn't work with wayland. I'm hoping we ca
159 #endif // USE_X11
160
161 if (!va_display || !vaapi_wrapper->Initialize(va_display,
162 mode,
163 profile,
164 report_error_to_uma_cb))
137 vaapi_wrapper.reset(); 165 vaapi_wrapper.reset();
138 166
139 return vaapi_wrapper.Pass(); 167 return vaapi_wrapper.Pass();
140 } 168 }
141 169
142 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { 170 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
143 VADisplayAttribute item = {VADisplayAttribRenderMode, 171 VADisplayAttribute item = {VADisplayAttribRenderMode,
144 1, // At least support '_LOCAL_OVERLAY'. 172 1, // At least support '_LOCAL_OVERLAY'.
145 -1, // The maximum possible support 'ALL'. 173 -1, // The maximum possible support 'ALL'.
146 VA_RENDER_MODE_LOCAL_GPU, 174 VA_RENDER_MODE_LOCAL_GPU,
147 VA_DISPLAY_ATTRIB_SETTABLE}; 175 VA_DISPLAY_ATTRIB_SETTABLE};
148 176
149 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); 177 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1);
150 if (va_res != VA_STATUS_SUCCESS) 178 if (va_res != VA_STATUS_SUCCESS)
151 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; 179 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default.";
152 } 180 }
153 181
154 bool VaapiWrapper::Initialize(CodecMode mode, 182 bool VaapiWrapper::Initialize(VADisplay va_display,
183 CodecMode mode,
155 media::VideoCodecProfile profile, 184 media::VideoCodecProfile profile,
156 Display* x_display,
157 const base::Closure& report_error_to_uma_cb) { 185 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; 186 report_error_to_uma_cb_ = report_error_to_uma_cb;
165 187
166 base::AutoLock auto_lock(va_lock_); 188 base::AutoLock auto_lock(va_lock_);
167 189
168 va_display_ = vaGetDisplay(x_display); 190 va_display_ = va_display;
169 if (!vaDisplayIsValid(va_display_)) { 191 if (!vaDisplayIsValid(va_display_)) {
170 DVLOG(1) << "Could not get a valid VA display"; 192 DVLOG(1) << "Could not get a valid VA display";
171 return false; 193 return false;
172 } 194 }
173 195
174 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); 196 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_);
175 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); 197 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false);
176 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; 198 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_;
177 199
178 if (VAAPIVersionLessThan(0, 34)) { 200 if (VAAPIVersionLessThan(0, 34)) {
(...skipping 12 matching lines...) Expand all
191 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); 213 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false);
192 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { 214 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) {
193 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles; 215 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles;
194 return false; 216 return false;
195 } 217 }
196 218
197 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); 219 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles));
198 220
199 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles); 221 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles);
200 if (va_profile == VAProfileNone) { 222 if (va_profile == VAProfileNone) {
201 DVLOG(1) << "Unsupported profile"; 223 DVLOG(1) << "Unsupported profile : " << profile;
202 return false; 224 return false;
203 } 225 }
204 226
205 // Query the driver for supported entrypoints. 227 // Query the driver for supported entrypoints.
206 int max_entrypoints = vaMaxNumEntrypoints(va_display_); 228 int max_entrypoints = vaMaxNumEntrypoints(va_display_);
207 std::vector<VAEntrypoint> supported_entrypoints( 229 std::vector<VAEntrypoint> supported_entrypoints(
208 base::checked_cast<size_t>(max_entrypoints)); 230 base::checked_cast<size_t>(max_entrypoints));
209 231
210 int num_supported_entrypoints; 232 int num_supported_entrypoints;
211 va_res = vaQueryConfigEntrypoints(va_display_, 233 va_res = vaQueryConfigEntrypoints(va_display_,
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 311
290 va_config_id_ = VA_INVALID_ID; 312 va_config_id_ = VA_INVALID_ID;
291 va_display_ = NULL; 313 va_display_ = NULL;
292 } 314 }
293 315
294 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { 316 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) {
295 return (major_version_ < major) || 317 return (major_version_ < major) ||
296 (major_version_ == major && minor_version_ < minor); 318 (major_version_ == major && minor_version_ < minor);
297 } 319 }
298 320
299 bool VaapiWrapper::CreateSurfaces(gfx::Size size, 321 bool VaapiWrapper::CreateSurfaces(const gfx::Size& size,
300 size_t num_surfaces, 322 size_t num_surfaces,
301 std::vector<VASurfaceID>* va_surfaces) { 323 std::vector<VASurfaceID>* va_surfaces) {
302 base::AutoLock auto_lock(va_lock_); 324 base::AutoLock auto_lock(va_lock_);
303 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; 325 DVLOG(2) << "Creating " << num_surfaces << " surfaces";
304 326
305 DCHECK(va_surfaces->empty()); 327 DCHECK(va_surfaces->empty());
306 DCHECK(va_surface_ids_.empty()); 328 DCHECK(va_surface_ids_.empty());
307 va_surface_ids_.resize(num_surfaces); 329 va_surface_ids_.resize(num_surfaces);
308 330
309 // Allocate surfaces in driver. 331 // Allocate surfaces in driver.
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 521
500 return true; 522 return true;
501 } 523 }
502 524
503 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { 525 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) {
504 bool result = Execute(va_surface_id); 526 bool result = Execute(va_surface_id);
505 DestroyPendingBuffers(); 527 DestroyPendingBuffers();
506 return result; 528 return result;
507 } 529 }
508 530
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, 531 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id,
529 VAImage* image, 532 VAImage* image,
530 void** mem) { 533 void** mem) {
531 base::AutoLock auto_lock(va_lock_); 534 base::AutoLock auto_lock(va_lock_);
532 535
533 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); 536 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
534 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); 537 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
535 538
536 // Derive a VAImage from the VASurface 539 // Derive a VAImage from the VASurface
537 va_res = vaDeriveImage(va_display_, va_surface_id, image); 540 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"); 661 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
659 662
660 va_res = vaDestroyBuffer(va_display_, buffer_id); 663 va_res = vaDestroyBuffer(va_display_, buffer_id);
661 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); 664 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
662 665
663 DCHECK(coded_buffers_.erase(buffer_id)); 666 DCHECK(coded_buffers_.erase(buffer_id));
664 667
665 return buffer_segment == NULL; 668 return buffer_segment == NULL;
666 } 669 }
667 670
671 VADisplay VaapiWrapper::GetDisplay() {
672 return va_display_;
673 }
674
675
668 // static 676 // static
669 bool VaapiWrapper::PostSandboxInitialization() { 677 bool VaapiWrapper::PostSandboxInitialization() {
670 StubPathMap paths; 678 StubPathMap paths;
671 paths[kModuleVa].push_back(kVaLib); 679
680 paths[kModuleVa].push_back("libva.so.1");
681
682 #if defined(USE_X11)
683 paths[kModuleVa_x11].push_back("libva-x11.so.1");
684 #else
685 paths[kModuleVa_drm].push_back("libva-drm.so.1");
686 #endif
672 687
673 return InitializeStubs(paths); 688 return InitializeStubs(paths);
674 } 689 }
675 690
676 } // namespace content 691 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698