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 void VaapiWrapper::UnmapImage(VAImage* image) { | |
scherkus (not reviewing)
2014/07/29 17:48:55
blank line before this
vignatti (out of this project)
2014/07/30 21:51:30
Done.
| |
582 base::AutoLock auto_lock(va_lock_); | |
583 vaUnmapBuffer(va_display_, image->buf); | |
584 } | |
585 | |
586 bool VaapiWrapper::PutSurfaceIntoImage(VASurfaceID va_surface_id, | |
587 VAImage* image) { | |
588 base::AutoLock auto_lock(va_lock_); | |
589 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | |
590 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | |
591 | |
592 va_res = vaGetImage(va_display_, | |
593 va_surface_id, | |
594 0, | |
595 0, | |
596 image->width, | |
597 image->height, | |
598 image->image_id); | |
599 VA_SUCCESS_OR_RETURN(va_res, "Failed to put surface into image", false); | |
600 return true; | |
601 } | |
602 #endif | |
527 | 603 |
528 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, | 604 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, |
529 VAImage* image, | 605 VAImage* image, |
530 void** mem) { | 606 void** mem) { |
531 base::AutoLock auto_lock(va_lock_); | 607 base::AutoLock auto_lock(va_lock_); |
532 | 608 |
533 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | 609 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
534 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 610 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
535 | 611 |
536 // Derive a VAImage from the VASurface | 612 // 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"); | 737 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
662 | 738 |
663 DCHECK(coded_buffers_.erase(buffer_id)); | 739 DCHECK(coded_buffers_.erase(buffer_id)); |
664 | 740 |
665 return buffer_segment == NULL; | 741 return buffer_segment == NULL; |
666 } | 742 } |
667 | 743 |
668 // static | 744 // static |
669 bool VaapiWrapper::PostSandboxInitialization() { | 745 bool VaapiWrapper::PostSandboxInitialization() { |
670 StubPathMap paths; | 746 StubPathMap paths; |
747 #if defined(USE_X11) | |
671 paths[kModuleVa].push_back(kVaLib); | 748 paths[kModuleVa].push_back(kVaLib); |
749 #else | |
750 paths[kModuleVa_drm].push_back(kVaLib); | |
751 #endif | |
672 | 752 |
673 return InitializeStubs(paths); | 753 return InitializeStubs(paths); |
674 } | 754 } |
675 | 755 |
676 } // namespace content | 756 } // namespace content |
OLD | NEW |