OLD | NEW |
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 | 16 |
| 17 #if defined(USE_X11) |
17 using content_common_gpu_media::kModuleVa; | 18 using content_common_gpu_media::kModuleVa; |
| 19 #else |
| 20 using content_common_gpu_media::kModuleVa_drm; |
| 21 #endif |
18 using content_common_gpu_media::InitializeStubs; | 22 using content_common_gpu_media::InitializeStubs; |
19 using content_common_gpu_media::StubPathMap; | 23 using content_common_gpu_media::StubPathMap; |
20 | 24 |
21 // libva-x11 depends on libva, so dlopen libva-x11 is enough | 25 // libva-x11 depends on libva, so dlopen libva-x11 is enough |
22 static const base::FilePath::CharType kVaLib[] = | 26 static const base::FilePath::CharType kVaLib[] = |
| 27 #if defined(USE_X11) |
23 FILE_PATH_LITERAL("libva-x11.so.1"); | 28 FILE_PATH_LITERAL("libva-x11.so.1"); |
| 29 #else |
| 30 FILE_PATH_LITERAL("libva-drm.so.1"); |
| 31 #endif |
24 | 32 |
25 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ | 33 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ |
26 do { \ | 34 do { \ |
27 DVLOG(1) << err_msg \ | 35 DVLOG(1) << err_msg \ |
28 << " VA error: " << vaErrorStr(va_error); \ | 36 << " VA error: " << vaErrorStr(va_error); \ |
29 report_error_to_uma_cb_.Run(); \ | 37 report_error_to_uma_cb_.Run(); \ |
30 } while (0) | 38 } while (0) |
31 | 39 |
32 #define VA_LOG_ON_ERROR(va_error, err_msg) \ | 40 #define VA_LOG_ON_ERROR(va_error, err_msg) \ |
33 do { \ | 41 do { \ |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 VaapiWrapper::~VaapiWrapper() { | 129 VaapiWrapper::~VaapiWrapper() { |
122 DestroyPendingBuffers(); | 130 DestroyPendingBuffers(); |
123 DestroyCodedBuffers(); | 131 DestroyCodedBuffers(); |
124 DestroySurfaces(); | 132 DestroySurfaces(); |
125 Deinitialize(); | 133 Deinitialize(); |
126 } | 134 } |
127 | 135 |
128 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( | 136 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( |
129 CodecMode mode, | 137 CodecMode mode, |
130 media::VideoCodecProfile profile, | 138 media::VideoCodecProfile profile, |
131 Display* x_display, | 139 #if defined(USE_X11) |
| 140 Display* display, |
| 141 #else |
| 142 int display, |
| 143 #endif |
132 const base::Closure& report_error_to_uma_cb) { | 144 const base::Closure& report_error_to_uma_cb) { |
133 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); | 145 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); |
134 | 146 |
135 if (!vaapi_wrapper->Initialize( | 147 if (!vaapi_wrapper->Initialize( |
136 mode, profile, x_display, report_error_to_uma_cb)) | 148 mode, profile, display, report_error_to_uma_cb)) |
137 vaapi_wrapper.reset(); | 149 vaapi_wrapper.reset(); |
138 | 150 |
139 return vaapi_wrapper.Pass(); | 151 return vaapi_wrapper.Pass(); |
140 } | 152 } |
141 | 153 |
142 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { | 154 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { |
143 VADisplayAttribute item = {VADisplayAttribRenderMode, | 155 VADisplayAttribute item = {VADisplayAttribRenderMode, |
144 1, // At least support '_LOCAL_OVERLAY'. | 156 1, // At least support '_LOCAL_OVERLAY'. |
145 -1, // The maximum possible support 'ALL'. | 157 -1, // The maximum possible support 'ALL'. |
146 VA_RENDER_MODE_LOCAL_GPU, | 158 VA_RENDER_MODE_LOCAL_GPU, |
147 VA_DISPLAY_ATTRIB_SETTABLE}; | 159 VA_DISPLAY_ATTRIB_SETTABLE}; |
148 | 160 |
149 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); | 161 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); |
150 if (va_res != VA_STATUS_SUCCESS) | 162 if (va_res != VA_STATUS_SUCCESS) |
151 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; | 163 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; |
152 } | 164 } |
153 | 165 |
154 bool VaapiWrapper::Initialize(CodecMode mode, | 166 bool VaapiWrapper::Initialize(CodecMode mode, |
155 media::VideoCodecProfile profile, | 167 media::VideoCodecProfile profile, |
| 168 #if defined(USE_X11) |
156 Display* x_display, | 169 Display* x_display, |
| 170 #else |
| 171 int display, |
| 172 #endif |
157 const base::Closure& report_error_to_uma_cb) { | 173 const base::Closure& report_error_to_uma_cb) { |
158 static bool vaapi_functions_initialized = PostSandboxInitialization(); | 174 static bool vaapi_functions_initialized = PostSandboxInitialization(); |
159 if (!vaapi_functions_initialized) { | 175 if (!vaapi_functions_initialized) { |
160 DVLOG(1) << "Failed to initialize VAAPI libs"; | 176 DVLOG(1) << "Failed to initialize VAAPI libs"; |
161 return false; | 177 return false; |
162 } | 178 } |
163 | 179 |
164 report_error_to_uma_cb_ = report_error_to_uma_cb; | 180 report_error_to_uma_cb_ = report_error_to_uma_cb; |
165 | 181 |
166 base::AutoLock auto_lock(va_lock_); | 182 base::AutoLock auto_lock(va_lock_); |
167 | 183 #if defined(USE_X11) |
168 va_display_ = vaGetDisplay(x_display); | 184 va_display_ = vaGetDisplay(x_display); |
| 185 #else |
| 186 va_display_ = vaGetDisplayDRM(display); |
| 187 #endif |
169 if (!vaDisplayIsValid(va_display_)) { | 188 if (!vaDisplayIsValid(va_display_)) { |
170 DVLOG(1) << "Could not get a valid VA display"; | 189 DVLOG(1) << "Could not get a valid VA display"; |
171 return false; | 190 return false; |
172 } | 191 } |
173 | 192 |
174 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); | 193 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); |
175 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); | 194 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); |
176 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; | 195 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; |
177 | 196 |
178 if (VAAPIVersionLessThan(0, 34)) { | 197 if (VAAPIVersionLessThan(0, 34)) { |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 | 518 |
500 return true; | 519 return true; |
501 } | 520 } |
502 | 521 |
503 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { | 522 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { |
504 bool result = Execute(va_surface_id); | 523 bool result = Execute(va_surface_id); |
505 DestroyPendingBuffers(); | 524 DestroyPendingBuffers(); |
506 return result; | 525 return result; |
507 } | 526 } |
508 | 527 |
| 528 #if defined(USE_X11) |
509 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, | 529 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, |
510 Pixmap x_pixmap, | 530 Pixmap x_pixmap, |
511 gfx::Size dest_size) { | 531 gfx::Size dest_size) { |
512 base::AutoLock auto_lock(va_lock_); | 532 base::AutoLock auto_lock(va_lock_); |
513 | 533 |
514 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | 534 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
515 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 535 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
516 | 536 |
517 // Put the data into an X Pixmap. | 537 // Put the data into an X Pixmap. |
518 va_res = vaPutSurface(va_display_, | 538 va_res = vaPutSurface(va_display_, |
519 va_surface_id, | 539 va_surface_id, |
520 x_pixmap, | 540 x_pixmap, |
521 0, 0, dest_size.width(), dest_size.height(), | 541 0, 0, dest_size.width(), dest_size.height(), |
522 0, 0, dest_size.width(), dest_size.height(), | 542 0, 0, dest_size.width(), dest_size.height(), |
523 NULL, 0, 0); | 543 NULL, 0, 0); |
524 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); | 544 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); |
525 return true; | 545 return true; |
526 } | 546 } |
| 547 #else |
| 548 bool VaapiWrapper::CreateRGBImage(gfx::Size size, VAImage* image) { |
| 549 base::AutoLock auto_lock(va_lock_); |
| 550 VAStatus va_res; |
| 551 VAImageFormat format; |
| 552 format.fourcc = VA_FOURCC_RGBX; |
| 553 format.byte_order = VA_LSB_FIRST; |
| 554 format.bits_per_pixel = 32; |
| 555 format.depth = 24; |
| 556 format.red_mask = 0xff; |
| 557 format.green_mask = 0xff00; |
| 558 format.blue_mask = 0xff0000; |
| 559 format.alpha_mask = 0; |
| 560 va_res = vaCreateImage(va_display_, |
| 561 &format, |
| 562 size.width(), |
| 563 size.height(), |
| 564 image); |
| 565 VA_SUCCESS_OR_RETURN(va_res, "Failed to create image", false); |
| 566 return true; |
| 567 } |
| 568 |
| 569 void VaapiWrapper::DestroyImage(VAImage* image) { |
| 570 base::AutoLock auto_lock(va_lock_); |
| 571 vaDestroyImage(va_display_, image->image_id); |
| 572 } |
| 573 |
| 574 bool VaapiWrapper::MapImage(VAImage* image, void** buffer) { |
| 575 base::AutoLock auto_lock(va_lock_); |
| 576 |
| 577 VAStatus va_res = vaMapBuffer(va_display_, image->buf, buffer); |
| 578 VA_SUCCESS_OR_RETURN(va_res, "Failed to map image", false); |
| 579 return true; |
| 580 } |
| 581 |
| 582 void VaapiWrapper::UnmapImage(VAImage* image) { |
| 583 base::AutoLock auto_lock(va_lock_); |
| 584 vaUnmapBuffer(va_display_, image->buf); |
| 585 } |
| 586 |
| 587 bool VaapiWrapper::PutSurfaceIntoImage(VASurfaceID va_surface_id, |
| 588 VAImage* image) { |
| 589 base::AutoLock auto_lock(va_lock_); |
| 590 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
| 591 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
| 592 |
| 593 va_res = vaGetImage(va_display_, |
| 594 va_surface_id, |
| 595 0, |
| 596 0, |
| 597 image->width, |
| 598 image->height, |
| 599 image->image_id); |
| 600 VA_SUCCESS_OR_RETURN(va_res, "Failed to put surface into image", false); |
| 601 return true; |
| 602 } |
| 603 #endif |
527 | 604 |
528 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, | 605 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, |
529 VAImage* image, | 606 VAImage* image, |
530 void** mem) { | 607 void** mem) { |
531 base::AutoLock auto_lock(va_lock_); | 608 base::AutoLock auto_lock(va_lock_); |
532 | 609 |
533 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | 610 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
534 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 611 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
535 | 612 |
536 // Derive a VAImage from the VASurface | 613 // Derive a VAImage from the VASurface |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); | 738 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
662 | 739 |
663 DCHECK(coded_buffers_.erase(buffer_id)); | 740 DCHECK(coded_buffers_.erase(buffer_id)); |
664 | 741 |
665 return buffer_segment == NULL; | 742 return buffer_segment == NULL; |
666 } | 743 } |
667 | 744 |
668 // static | 745 // static |
669 bool VaapiWrapper::PostSandboxInitialization() { | 746 bool VaapiWrapper::PostSandboxInitialization() { |
670 StubPathMap paths; | 747 StubPathMap paths; |
| 748 #if defined(USE_X11) |
671 paths[kModuleVa].push_back(kVaLib); | 749 paths[kModuleVa].push_back(kVaLib); |
| 750 #else |
| 751 paths[kModuleVa_drm].push_back(kVaLib); |
| 752 #endif |
672 | 753 |
673 return InitializeStubs(paths); | 754 return InitializeStubs(paths); |
674 } | 755 } |
675 | 756 |
676 } // namespace content | 757 } // namespace content |
OLD | NEW |