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 #include "ui/gl/gl_bindings.h" |
| 17 #if defined(USE_X11) |
| 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 |
16 | 25 |
17 using content_common_gpu_media::kModuleVa; | 26 using content_common_gpu_media::kModuleVa; |
| 27 #if defined(USE_X11) |
| 28 using content_common_gpu_media::kModuleVa_x11; |
| 29 #else |
| 30 using content_common_gpu_media::kModuleVa_drm; |
| 31 #endif // USE_X11 |
18 using content_common_gpu_media::InitializeStubs; | 32 using content_common_gpu_media::InitializeStubs; |
19 using content_common_gpu_media::StubPathMap; | 33 using content_common_gpu_media::StubPathMap; |
20 | 34 |
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) \ | 35 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ |
26 do { \ | 36 do { \ |
27 LOG(ERROR) << err_msg \ | 37 LOG(ERROR) << err_msg \ |
28 << " VA error: " << vaErrorStr(va_error); \ | 38 << " VA error: " << vaErrorStr(va_error); \ |
29 report_error_to_uma_cb_.Run(); \ | 39 report_error_to_uma_cb_.Run(); \ |
30 } while (0) | 40 } while (0) |
31 | 41 |
32 #define VA_LOG_ON_ERROR(va_error, err_msg) \ | 42 #define VA_LOG_ON_ERROR(va_error, err_msg) \ |
33 do { \ | 43 do { \ |
34 if ((va_error) != VA_STATUS_SUCCESS) \ | 44 if ((va_error) != VA_STATUS_SUCCESS) \ |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 VAProfileH264ConstrainedBaseline) != | 125 VAProfileH264ConstrainedBaseline) != |
116 supported_profiles.end()) { | 126 supported_profiles.end()) { |
117 va_profile = VAProfileH264ConstrainedBaseline; | 127 va_profile = VAProfileH264ConstrainedBaseline; |
118 DVLOG(1) << "Falling back to constrained baseline profile."; | 128 DVLOG(1) << "Falling back to constrained baseline profile."; |
119 } | 129 } |
120 } | 130 } |
121 | 131 |
122 return va_profile; | 132 return va_profile; |
123 } | 133 } |
124 | 134 |
125 VASurface::VASurface(VASurfaceID va_surface_id, const ReleaseCB& release_cb) | 135 VASurface::VASurface(VASurfaceID va_surface_id, |
126 : va_surface_id_(va_surface_id), | 136 const gfx::Size& size, |
127 release_cb_(release_cb) { | 137 const ReleaseCB& release_cb) |
| 138 : va_surface_id_(va_surface_id), size_(size), release_cb_(release_cb) { |
128 DCHECK(!release_cb_.is_null()); | 139 DCHECK(!release_cb_.is_null()); |
129 } | 140 } |
130 | 141 |
131 VASurface::~VASurface() { | 142 VASurface::~VASurface() { |
132 release_cb_.Run(va_surface_id_); | 143 release_cb_.Run(va_surface_id_); |
133 } | 144 } |
134 | 145 |
135 VaapiWrapper::VaapiWrapper() | 146 VaapiWrapper::VaapiWrapper() |
136 : va_display_(NULL), | 147 : va_display_(NULL), |
137 va_config_id_(VA_INVALID_ID), | 148 va_config_id_(VA_INVALID_ID), |
138 va_context_id_(VA_INVALID_ID) { | 149 va_context_id_(VA_INVALID_ID), |
| 150 va_vpp_config_id_(VA_INVALID_ID), |
| 151 va_vpp_context_id_(VA_INVALID_ID), |
| 152 va_vpp_buffer_id_(VA_INVALID_ID) { |
139 } | 153 } |
140 | 154 |
141 VaapiWrapper::~VaapiWrapper() { | 155 VaapiWrapper::~VaapiWrapper() { |
142 DestroyPendingBuffers(); | 156 DestroyPendingBuffers(); |
143 DestroyCodedBuffers(); | 157 DestroyCodedBuffers(); |
144 DestroySurfaces(); | 158 DestroySurfaces(); |
| 159 DeinitializeVpp(); |
145 Deinitialize(); | 160 Deinitialize(); |
146 } | 161 } |
147 | 162 |
148 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( | 163 scoped_refptr<VaapiWrapper> VaapiWrapper::Create( |
149 CodecMode mode, | 164 CodecMode mode, |
150 media::VideoCodecProfile profile, | 165 media::VideoCodecProfile profile, |
151 Display* x_display, | |
152 const base::Closure& report_error_to_uma_cb) { | 166 const base::Closure& report_error_to_uma_cb) { |
153 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); | 167 scoped_refptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); |
154 | 168 |
155 if (!vaapi_wrapper->Initialize( | 169 if (!vaapi_wrapper->Initialize(mode, profile, report_error_to_uma_cb)) |
156 mode, profile, x_display, report_error_to_uma_cb)) | 170 vaapi_wrapper = NULL; |
157 vaapi_wrapper.reset(); | |
158 | 171 |
159 return vaapi_wrapper.Pass(); | 172 return vaapi_wrapper; |
160 } | 173 } |
161 | 174 |
162 std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles( | 175 std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles( |
163 Display* x_display, | |
164 const base::Closure& report_error_to_uma_cb) { | 176 const base::Closure& report_error_to_uma_cb) { |
165 std::vector<media::VideoCodecProfile> supported_profiles; | 177 std::vector<media::VideoCodecProfile> supported_profiles; |
166 | 178 |
167 scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper()); | 179 scoped_refptr<VaapiWrapper> wrapper(new VaapiWrapper()); |
168 if (!wrapper->VaInitialize(x_display, report_error_to_uma_cb)) { | 180 if (!wrapper->VaInitialize(report_error_to_uma_cb)) { |
169 return supported_profiles; | 181 return supported_profiles; |
170 } | 182 } |
171 | 183 |
172 std::vector<VAProfile> va_profiles; | 184 std::vector<VAProfile> va_profiles; |
173 if (!wrapper->GetSupportedVaProfiles(&va_profiles)) | 185 if (!wrapper->GetSupportedVaProfiles(&va_profiles)) |
174 return supported_profiles; | 186 return supported_profiles; |
175 | 187 |
176 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode); | 188 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode); |
177 for (size_t i = 0; i < arraysize(kProfileMap); i++) { | 189 for (size_t i = 0; i < arraysize(kProfileMap); i++) { |
178 VAProfile va_profile = | 190 VAProfile va_profile = |
(...skipping 14 matching lines...) Expand all Loading... |
193 1, // At least support '_LOCAL_OVERLAY'. | 205 1, // At least support '_LOCAL_OVERLAY'. |
194 -1, // The maximum possible support 'ALL'. | 206 -1, // The maximum possible support 'ALL'. |
195 VA_RENDER_MODE_LOCAL_GPU, | 207 VA_RENDER_MODE_LOCAL_GPU, |
196 VA_DISPLAY_ATTRIB_SETTABLE}; | 208 VA_DISPLAY_ATTRIB_SETTABLE}; |
197 | 209 |
198 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); | 210 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); |
199 if (va_res != VA_STATUS_SUCCESS) | 211 if (va_res != VA_STATUS_SUCCESS) |
200 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; | 212 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; |
201 } | 213 } |
202 | 214 |
203 bool VaapiWrapper::VaInitialize(Display* x_display, | 215 bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) { |
204 const base::Closure& report_error_to_uma_cb) { | |
205 static bool vaapi_functions_initialized = PostSandboxInitialization(); | 216 static bool vaapi_functions_initialized = PostSandboxInitialization(); |
206 if (!vaapi_functions_initialized) { | 217 if (!vaapi_functions_initialized) { |
207 LOG(ERROR) << "Failed to initialize VAAPI libs"; | 218 LOG(ERROR) << "Failed to initialize VAAPI libs"; |
208 return false; | 219 return false; |
209 } | 220 } |
210 | 221 |
211 report_error_to_uma_cb_ = report_error_to_uma_cb; | 222 report_error_to_uma_cb_ = report_error_to_uma_cb; |
212 | 223 |
213 base::AutoLock auto_lock(va_lock_); | 224 base::AutoLock auto_lock(va_lock_); |
214 | 225 |
215 va_display_ = vaGetDisplay(x_display); | 226 #if defined(USE_X11) |
| 227 va_display_ = vaGetDisplay(gfx::GetXDisplay()); |
| 228 #else |
| 229 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); |
| 230 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); |
| 231 |
| 232 va_display_ = vaGetDisplayDRM(factory->GetDrmFd()); |
| 233 #endif // USE_X11 |
| 234 |
216 if (!vaDisplayIsValid(va_display_)) { | 235 if (!vaDisplayIsValid(va_display_)) { |
217 LOG(ERROR) << "Could not get a valid VA display"; | 236 LOG(ERROR) << "Could not get a valid VA display"; |
218 return false; | 237 return false; |
219 } | 238 } |
220 | 239 |
221 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); | 240 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); |
222 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); | 241 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); |
223 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; | 242 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; |
224 | 243 |
225 if (VAAPIVersionLessThan(0, 34)) { | 244 if (VAAPIVersionLessThan(0, 34)) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 DVLOG(1) << "Unsupported value " << required_attribs[i].value | 320 DVLOG(1) << "Unsupported value " << required_attribs[i].value |
302 << " for attribute type " << required_attribs[i].type; | 321 << " for attribute type " << required_attribs[i].type; |
303 return false; | 322 return false; |
304 } | 323 } |
305 } | 324 } |
306 return true; | 325 return true; |
307 } | 326 } |
308 | 327 |
309 bool VaapiWrapper::Initialize(CodecMode mode, | 328 bool VaapiWrapper::Initialize(CodecMode mode, |
310 media::VideoCodecProfile profile, | 329 media::VideoCodecProfile profile, |
311 Display* x_display, | |
312 const base::Closure& report_error_to_uma_cb) { | 330 const base::Closure& report_error_to_uma_cb) { |
313 if (!VaInitialize(x_display, report_error_to_uma_cb)) | 331 if (!VaInitialize(report_error_to_uma_cb)) |
314 return false; | 332 return false; |
315 std::vector<VAProfile> supported_va_profiles; | 333 std::vector<VAProfile> supported_va_profiles; |
316 if (!GetSupportedVaProfiles(&supported_va_profiles)) | 334 if (!GetSupportedVaProfiles(&supported_va_profiles)) |
317 return false; | 335 return false; |
318 VAProfile va_profile = ProfileToVAProfile(profile, supported_va_profiles); | 336 VAProfile va_profile = ProfileToVAProfile(profile, supported_va_profiles); |
319 if (va_profile == VAProfileNone) { | 337 if (va_profile == VAProfileNone) { |
320 DVLOG(1) << "Unsupported profile"; | 338 DVLOG(1) << "Unsupported profile"; |
321 return false; | 339 return false; |
322 } | 340 } |
323 VAEntrypoint entrypoint = | 341 VAEntrypoint entrypoint = |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 | 375 |
358 va_config_id_ = VA_INVALID_ID; | 376 va_config_id_ = VA_INVALID_ID; |
359 va_display_ = NULL; | 377 va_display_ = NULL; |
360 } | 378 } |
361 | 379 |
362 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { | 380 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { |
363 return (major_version_ < major) || | 381 return (major_version_ < major) || |
364 (major_version_ == major && minor_version_ < minor); | 382 (major_version_ == major && minor_version_ < minor); |
365 } | 383 } |
366 | 384 |
367 bool VaapiWrapper::CreateSurfaces(gfx::Size size, | 385 bool VaapiWrapper::CreateSurfaces(const gfx::Size& size, |
368 size_t num_surfaces, | 386 size_t num_surfaces, |
369 std::vector<VASurfaceID>* va_surfaces) { | 387 std::vector<VASurfaceID>* va_surfaces) { |
370 base::AutoLock auto_lock(va_lock_); | 388 base::AutoLock auto_lock(va_lock_); |
371 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; | 389 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; |
372 | 390 |
373 DCHECK(va_surfaces->empty()); | 391 DCHECK(va_surfaces->empty()); |
374 DCHECK(va_surface_ids_.empty()); | 392 DCHECK(va_surface_ids_.empty()); |
375 va_surface_ids_.resize(num_surfaces); | 393 va_surface_ids_.resize(num_surfaces); |
376 | 394 |
377 // Allocate surfaces in driver. | 395 // Allocate surfaces in driver. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 if (!va_surface_ids_.empty()) { | 434 if (!va_surface_ids_.empty()) { |
417 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], | 435 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], |
418 va_surface_ids_.size()); | 436 va_surface_ids_.size()); |
419 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); | 437 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); |
420 } | 438 } |
421 | 439 |
422 va_surface_ids_.clear(); | 440 va_surface_ids_.clear(); |
423 va_context_id_ = VA_INVALID_ID; | 441 va_context_id_ = VA_INVALID_ID; |
424 } | 442 } |
425 | 443 |
| 444 scoped_refptr<VASurface> VaapiWrapper::CreateUnownedSurface( |
| 445 unsigned int va_format, |
| 446 const gfx::Size& size, |
| 447 VASurfaceAttrib* va_attribs, |
| 448 size_t num_va_attribs) { |
| 449 base::AutoLock auto_lock(va_lock_); |
| 450 VASurfaceID va_surface_id; |
| 451 scoped_refptr<VASurface> va_surface; |
| 452 |
| 453 VAStatus va_res = vaCreateSurfaces(va_display_, |
| 454 va_format, |
| 455 size.width(), |
| 456 size.height(), |
| 457 &va_surface_id, |
| 458 1, |
| 459 va_attribs, |
| 460 num_va_attribs); |
| 461 VA_SUCCESS_OR_RETURN( |
| 462 va_res, "Failed to create unowned VASurface", va_surface); |
| 463 |
| 464 va_surface = |
| 465 new VASurface(va_surface_id, |
| 466 size, |
| 467 base::Bind(&VaapiWrapper::DestroyUnownedSurface, this)); |
| 468 |
| 469 return va_surface; |
| 470 } |
| 471 |
| 472 void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface) { |
| 473 base::AutoLock auto_lock(va_lock_); |
| 474 |
| 475 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface, 1); |
| 476 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on output surface failed"); |
| 477 } |
| 478 |
426 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, | 479 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, |
427 size_t size, | 480 size_t size, |
428 void* buffer) { | 481 void* buffer) { |
429 base::AutoLock auto_lock(va_lock_); | 482 base::AutoLock auto_lock(va_lock_); |
430 | 483 |
431 VABufferID buffer_id; | 484 VABufferID buffer_id; |
432 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, | 485 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, |
433 va_buffer_type, size, | 486 va_buffer_type, size, |
434 1, buffer, &buffer_id); | 487 1, buffer, &buffer_id); |
435 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); | 488 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 | 620 |
568 return true; | 621 return true; |
569 } | 622 } |
570 | 623 |
571 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { | 624 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { |
572 bool result = Execute(va_surface_id); | 625 bool result = Execute(va_surface_id); |
573 DestroyPendingBuffers(); | 626 DestroyPendingBuffers(); |
574 return result; | 627 return result; |
575 } | 628 } |
576 | 629 |
577 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, | |
578 Pixmap x_pixmap, | |
579 gfx::Size dest_size) { | |
580 base::AutoLock auto_lock(va_lock_); | |
581 | |
582 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | |
583 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | |
584 | |
585 // Put the data into an X Pixmap. | |
586 va_res = vaPutSurface(va_display_, | |
587 va_surface_id, | |
588 x_pixmap, | |
589 0, 0, dest_size.width(), dest_size.height(), | |
590 0, 0, dest_size.width(), dest_size.height(), | |
591 NULL, 0, 0); | |
592 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); | |
593 return true; | |
594 } | |
595 | |
596 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, | 630 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, |
597 VAImage* image, | 631 VAImage* image, |
598 void** mem) { | 632 void** mem) { |
599 base::AutoLock auto_lock(va_lock_); | 633 base::AutoLock auto_lock(va_lock_); |
600 | 634 |
601 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | 635 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
602 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 636 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
603 | 637 |
604 // Derive a VAImage from the VASurface | 638 // Derive a VAImage from the VASurface |
605 va_res = vaDeriveImage(va_display_, va_surface_id, image); | 639 va_res = vaDeriveImage(va_display_, va_surface_id, image); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); | 760 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); |
727 | 761 |
728 va_res = vaDestroyBuffer(va_display_, buffer_id); | 762 va_res = vaDestroyBuffer(va_display_, buffer_id); |
729 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); | 763 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
730 | 764 |
731 DCHECK(coded_buffers_.erase(buffer_id)); | 765 DCHECK(coded_buffers_.erase(buffer_id)); |
732 | 766 |
733 return buffer_segment == NULL; | 767 return buffer_segment == NULL; |
734 } | 768 } |
735 | 769 |
| 770 bool VaapiWrapper::BlitSurface(VASurfaceID va_surface_id_src, |
| 771 const gfx::Size& src_size, |
| 772 VASurfaceID va_surface_id_dest, |
| 773 const gfx::Size& dest_size) { |
| 774 base::AutoLock auto_lock(va_lock_); |
| 775 |
| 776 // Initialize the post processing engine if not already done. |
| 777 if (va_vpp_buffer_id_ == VA_INVALID_ID) |
| 778 if (!InitializeVpp_Locked()) |
| 779 return false; |
| 780 |
| 781 // VA_SUCCESS_OR_RETURN(vaSyncSurface(va_display_, va_surface_id_src), |
| 782 // "Failed syncing surface", |
| 783 // false); |
| 784 |
| 785 VAProcPipelineParameterBuffer* pipeline_param; |
| 786 VA_SUCCESS_OR_RETURN(vaMapBuffer(va_display_, |
| 787 va_vpp_buffer_id_, |
| 788 reinterpret_cast<void**>(&pipeline_param)), |
| 789 "Couldn't map vpp buffer", |
| 790 false); |
| 791 |
| 792 memset(pipeline_param, 0, sizeof *pipeline_param); |
| 793 |
| 794 VARectangle input_region; |
| 795 input_region.x = input_region.y = 0; |
| 796 input_region.width = src_size.width(); |
| 797 input_region.height = src_size.height(); |
| 798 pipeline_param->surface_region = &input_region; |
| 799 pipeline_param->surface = va_surface_id_src; |
| 800 pipeline_param->surface_color_standard = VAProcColorStandardNone; |
| 801 |
| 802 VARectangle output_region; |
| 803 output_region.x = output_region.y = 0; |
| 804 output_region.width = dest_size.width(); |
| 805 output_region.height = dest_size.height(); |
| 806 pipeline_param->output_region = &output_region; |
| 807 pipeline_param->output_background_color = 0xff000000; |
| 808 pipeline_param->output_color_standard = VAProcColorStandardNone; |
| 809 |
| 810 VA_SUCCESS_OR_RETURN(vaUnmapBuffer(va_display_, va_vpp_buffer_id_), |
| 811 "Couldn't unmap vpp buffer", |
| 812 false); |
| 813 |
| 814 VA_SUCCESS_OR_RETURN( |
| 815 vaBeginPicture(va_display_, va_vpp_context_id_, va_surface_id_dest), |
| 816 "Couldn't begin picture", |
| 817 false); |
| 818 |
| 819 VA_SUCCESS_OR_RETURN( |
| 820 vaRenderPicture(va_display_, va_vpp_context_id_, &va_vpp_buffer_id_, 1), |
| 821 "Couldn't render picture", |
| 822 false); |
| 823 |
| 824 VA_SUCCESS_OR_RETURN(vaEndPicture(va_display_, va_vpp_context_id_), |
| 825 "Couldn't end picture", |
| 826 false); |
| 827 |
| 828 return true; |
| 829 } |
| 830 |
| 831 bool VaapiWrapper::InitializeVpp_Locked() { |
| 832 va_lock_.AssertAcquired(); |
| 833 |
| 834 VA_SUCCESS_OR_RETURN(vaCreateConfig(va_display_, |
| 835 VAProfileNone, |
| 836 VAEntrypointVideoProc, |
| 837 NULL, |
| 838 0, |
| 839 &va_vpp_config_id_), |
| 840 "Couldn't create config", |
| 841 false); |
| 842 |
| 843 // The size of the picture for the context is irrelevant in the case |
| 844 // of the VPP, just passing 1x1. |
| 845 VA_SUCCESS_OR_RETURN(vaCreateContext(va_display_, |
| 846 va_vpp_config_id_, |
| 847 1, |
| 848 1, |
| 849 0, |
| 850 NULL, |
| 851 0, |
| 852 &va_vpp_context_id_), |
| 853 "Couldn't create context", |
| 854 false); |
| 855 |
| 856 VA_SUCCESS_OR_RETURN(vaCreateBuffer(va_display_, |
| 857 va_vpp_context_id_, |
| 858 VAProcPipelineParameterBufferType, |
| 859 sizeof(VAProcPipelineParameterBuffer), |
| 860 1, |
| 861 NULL, |
| 862 &va_vpp_buffer_id_), |
| 863 "Couldn't create buffer", |
| 864 false); |
| 865 |
| 866 return true; |
| 867 } |
| 868 |
| 869 void VaapiWrapper::DeinitializeVpp() { |
| 870 base::AutoLock auto_lock(va_lock_); |
| 871 DeinitializeVpp_Locked(); |
| 872 } |
| 873 |
| 874 void VaapiWrapper::DeinitializeVpp_Locked() { |
| 875 va_lock_.AssertAcquired(); |
| 876 |
| 877 if (va_vpp_buffer_id_ != VA_INVALID_ID) { |
| 878 vaDestroyBuffer(va_display_, va_vpp_buffer_id_); |
| 879 va_vpp_buffer_id_ = VA_INVALID_ID; |
| 880 } |
| 881 if (va_vpp_context_id_ != VA_INVALID_ID) { |
| 882 vaDestroyContext(va_display_, va_vpp_context_id_); |
| 883 va_vpp_context_id_ = VA_INVALID_ID; |
| 884 } |
| 885 if (va_vpp_config_id_ != VA_INVALID_ID) { |
| 886 vaDestroyConfig(va_display_, va_vpp_config_id_); |
| 887 va_vpp_config_id_ = VA_INVALID_ID; |
| 888 } |
| 889 } |
| 890 |
| 891 #if defined(USE_X11) |
| 892 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, |
| 893 Pixmap x_pixmap, |
| 894 gfx::Size dest_size) { |
| 895 base::AutoLock auto_lock(va_lock_); |
| 896 |
| 897 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
| 898 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
| 899 |
| 900 // Put the data into an X Pixmap. |
| 901 va_res = vaPutSurface(va_display_, |
| 902 va_surface_id, |
| 903 x_pixmap, |
| 904 0, |
| 905 0, |
| 906 dest_size.width(), |
| 907 dest_size.height(), |
| 908 0, |
| 909 0, |
| 910 dest_size.width(), |
| 911 dest_size.height(), |
| 912 NULL, |
| 913 0, |
| 914 0); |
| 915 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); |
| 916 return true; |
| 917 } |
| 918 #endif // USE_X11 |
| 919 |
736 // static | 920 // static |
737 bool VaapiWrapper::PostSandboxInitialization() { | 921 bool VaapiWrapper::PostSandboxInitialization() { |
738 StubPathMap paths; | 922 StubPathMap paths; |
739 paths[kModuleVa].push_back(kVaLib); | 923 |
| 924 paths[kModuleVa].push_back("libva.so.1"); |
| 925 |
| 926 #if defined(USE_X11) |
| 927 paths[kModuleVa_x11].push_back("libva-x11.so.1"); |
| 928 #else |
| 929 paths[kModuleVa_drm].push_back("libva-drm.so.1"); |
| 930 #endif |
740 | 931 |
741 return InitializeStubs(paths); | 932 return InitializeStubs(paths); |
742 } | 933 } |
743 | 934 |
744 } // namespace content | 935 } // namespace content |
OLD | NEW |