Chromium Code Reviews| 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 DVLOG(1) << err_msg \ | 37 DVLOG(1) << 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 VAProfileH264ConstrainedBaseline) != | 105 VAProfileH264ConstrainedBaseline) != |
| 96 supported_profiles.end()) { | 106 supported_profiles.end()) { |
| 97 va_profile = VAProfileH264ConstrainedBaseline; | 107 va_profile = VAProfileH264ConstrainedBaseline; |
| 98 DVLOG(1) << "Falling back to constrained baseline profile."; | 108 DVLOG(1) << "Falling back to constrained baseline profile."; |
| 99 } | 109 } |
| 100 } | 110 } |
| 101 | 111 |
| 102 return va_profile; | 112 return va_profile; |
| 103 } | 113 } |
| 104 | 114 |
| 105 VASurface::VASurface(VASurfaceID va_surface_id, const ReleaseCB& release_cb) | 115 VASurface::VASurface(VASurfaceID va_surface_id, |
| 106 : va_surface_id_(va_surface_id), | 116 const gfx::Size& size, |
| 107 release_cb_(release_cb) { | 117 const ReleaseCB& release_cb) |
| 118 : va_surface_id_(va_surface_id), size_(size), release_cb_(release_cb) { | |
| 108 DCHECK(!release_cb_.is_null()); | 119 DCHECK(!release_cb_.is_null()); |
| 109 } | 120 } |
| 110 | 121 |
| 111 VASurface::~VASurface() { | 122 VASurface::~VASurface() { |
| 112 release_cb_.Run(va_surface_id_); | 123 release_cb_.Run(va_surface_id_); |
| 113 } | 124 } |
| 114 | 125 |
| 115 VaapiWrapper::VaapiWrapper() | 126 VaapiWrapper::VaapiWrapper() |
| 116 : va_display_(NULL), | 127 : va_display_(NULL), |
| 117 va_config_id_(VA_INVALID_ID), | 128 va_config_id_(VA_INVALID_ID), |
| 118 va_context_id_(VA_INVALID_ID) { | 129 va_context_id_(VA_INVALID_ID), |
| 130 va_vpp_config_(VA_INVALID_ID), | |
| 131 va_vpp_context_(VA_INVALID_ID), | |
| 132 va_vpp_buffer_(VA_INVALID_ID) { | |
| 119 } | 133 } |
| 120 | 134 |
| 121 VaapiWrapper::~VaapiWrapper() { | 135 VaapiWrapper::~VaapiWrapper() { |
| 122 DestroyPendingBuffers(); | 136 DestroyPendingBuffers(); |
| 123 DestroyCodedBuffers(); | 137 DestroyCodedBuffers(); |
| 124 DestroySurfaces(); | 138 DestroySurfaces(); |
| 139 DeinitializeVpp(); | |
| 125 Deinitialize(); | 140 Deinitialize(); |
| 126 } | 141 } |
| 127 | 142 |
| 128 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( | 143 scoped_refptr<VaapiWrapper> VaapiWrapper::Create( |
| 129 CodecMode mode, | 144 CodecMode mode, |
| 130 media::VideoCodecProfile profile, | 145 media::VideoCodecProfile profile, |
| 131 Display* x_display, | |
| 132 const base::Closure& report_error_to_uma_cb) { | 146 const base::Closure& report_error_to_uma_cb) { |
| 133 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); | 147 static bool vaapi_functions_initialized = PostSandboxInitialization(); |
| 148 scoped_refptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); | |
| 134 | 149 |
| 135 if (!vaapi_wrapper->Initialize( | 150 if (!vaapi_functions_initialized) { |
| 136 mode, profile, x_display, report_error_to_uma_cb)) | 151 DVLOG(1) << "Failed to initialize VAAPI libs"; |
| 137 vaapi_wrapper.reset(); | 152 vaapi_wrapper = NULL; |
| 153 return vaapi_wrapper; | |
| 154 } | |
| 138 | 155 |
| 139 return vaapi_wrapper.Pass(); | 156 VADisplay va_display = NULL; |
| 157 #if defined(USE_X11) | |
| 158 va_display = vaGetDisplay(gfx::GetXDisplay()); | |
| 159 #else | |
| 160 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); | |
| 161 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); | |
| 162 | |
| 163 va_display = vaGetDisplayDRM(factory->GetDrmFd()); | |
| 164 #endif // USE_X11 | |
| 165 | |
| 166 if (!va_display || | |
| 167 !vaapi_wrapper->Initialize( | |
| 168 va_display, mode, profile, report_error_to_uma_cb)) | |
| 169 vaapi_wrapper = NULL; | |
| 170 | |
| 171 return vaapi_wrapper; | |
| 140 } | 172 } |
| 141 | 173 |
| 142 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { | 174 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { |
| 143 VADisplayAttribute item = {VADisplayAttribRenderMode, | 175 VADisplayAttribute item = {VADisplayAttribRenderMode, |
| 144 1, // At least support '_LOCAL_OVERLAY'. | 176 1, // At least support '_LOCAL_OVERLAY'. |
| 145 -1, // The maximum possible support 'ALL'. | 177 -1, // The maximum possible support 'ALL'. |
| 146 VA_RENDER_MODE_LOCAL_GPU, | 178 VA_RENDER_MODE_LOCAL_GPU, |
| 147 VA_DISPLAY_ATTRIB_SETTABLE}; | 179 VA_DISPLAY_ATTRIB_SETTABLE}; |
| 148 | 180 |
| 149 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); | 181 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); |
| 150 if (va_res != VA_STATUS_SUCCESS) | 182 if (va_res != VA_STATUS_SUCCESS) |
| 151 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; | 183 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; |
| 152 } | 184 } |
| 153 | 185 |
| 154 bool VaapiWrapper::Initialize(CodecMode mode, | 186 bool VaapiWrapper::Initialize(VADisplay va_display, |
| 187 CodecMode mode, | |
| 155 media::VideoCodecProfile profile, | 188 media::VideoCodecProfile profile, |
| 156 Display* x_display, | |
| 157 const base::Closure& report_error_to_uma_cb) { | 189 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; | 190 report_error_to_uma_cb_ = report_error_to_uma_cb; |
| 165 | 191 |
| 166 base::AutoLock auto_lock(va_lock_); | 192 base::AutoLock auto_lock(va_lock_); |
| 167 | 193 |
| 168 va_display_ = vaGetDisplay(x_display); | 194 va_display_ = va_display; |
| 169 if (!vaDisplayIsValid(va_display_)) { | 195 if (!vaDisplayIsValid(va_display_)) { |
| 170 DVLOG(1) << "Could not get a valid VA display"; | 196 DVLOG(1) << "Could not get a valid VA display"; |
| 171 return false; | 197 return false; |
| 172 } | 198 } |
| 173 | 199 |
| 174 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); | 200 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); |
| 175 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); | 201 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); |
| 176 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; | 202 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; |
| 177 | 203 |
| 178 if (VAAPIVersionLessThan(0, 34)) { | 204 if (VAAPIVersionLessThan(0, 34)) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 191 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); | 217 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); |
| 192 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { | 218 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { |
| 193 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles; | 219 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles; |
| 194 return false; | 220 return false; |
| 195 } | 221 } |
| 196 | 222 |
| 197 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); | 223 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); |
| 198 | 224 |
| 199 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles); | 225 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles); |
| 200 if (va_profile == VAProfileNone) { | 226 if (va_profile == VAProfileNone) { |
| 201 DVLOG(1) << "Unsupported profile"; | 227 DVLOG(1) << "Unsupported profile : " << profile; |
| 202 return false; | 228 return false; |
| 203 } | 229 } |
| 204 | 230 |
| 205 // Query the driver for supported entrypoints. | 231 // Query the driver for supported entrypoints. |
| 206 int max_entrypoints = vaMaxNumEntrypoints(va_display_); | 232 int max_entrypoints = vaMaxNumEntrypoints(va_display_); |
| 207 std::vector<VAEntrypoint> supported_entrypoints( | 233 std::vector<VAEntrypoint> supported_entrypoints( |
| 208 base::checked_cast<size_t>(max_entrypoints)); | 234 base::checked_cast<size_t>(max_entrypoints)); |
| 209 | 235 |
| 210 int num_supported_entrypoints; | 236 int num_supported_entrypoints; |
| 211 va_res = vaQueryConfigEntrypoints(va_display_, | 237 va_res = vaQueryConfigEntrypoints(va_display_, |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 289 | 315 |
| 290 va_config_id_ = VA_INVALID_ID; | 316 va_config_id_ = VA_INVALID_ID; |
| 291 va_display_ = NULL; | 317 va_display_ = NULL; |
| 292 } | 318 } |
| 293 | 319 |
| 294 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { | 320 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { |
| 295 return (major_version_ < major) || | 321 return (major_version_ < major) || |
| 296 (major_version_ == major && minor_version_ < minor); | 322 (major_version_ == major && minor_version_ < minor); |
| 297 } | 323 } |
| 298 | 324 |
| 299 bool VaapiWrapper::CreateSurfaces(gfx::Size size, | 325 bool VaapiWrapper::CreateSurfaces(const gfx::Size& size, |
| 300 size_t num_surfaces, | 326 size_t num_surfaces, |
| 301 std::vector<VASurfaceID>* va_surfaces) { | 327 std::vector<VASurfaceID>* va_surfaces) { |
| 302 base::AutoLock auto_lock(va_lock_); | 328 base::AutoLock auto_lock(va_lock_); |
| 303 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; | 329 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; |
| 304 | 330 |
| 305 DCHECK(va_surfaces->empty()); | 331 DCHECK(va_surfaces->empty()); |
| 306 DCHECK(va_surface_ids_.empty()); | 332 DCHECK(va_surface_ids_.empty()); |
| 307 va_surface_ids_.resize(num_surfaces); | 333 va_surface_ids_.resize(num_surfaces); |
| 308 | 334 |
| 309 // Allocate surfaces in driver. | 335 // Allocate surfaces in driver. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 348 if (!va_surface_ids_.empty()) { | 374 if (!va_surface_ids_.empty()) { |
| 349 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], | 375 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], |
| 350 va_surface_ids_.size()); | 376 va_surface_ids_.size()); |
| 351 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); | 377 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); |
| 352 } | 378 } |
| 353 | 379 |
| 354 va_surface_ids_.clear(); | 380 va_surface_ids_.clear(); |
| 355 va_context_id_ = VA_INVALID_ID; | 381 va_context_id_ = VA_INVALID_ID; |
| 356 } | 382 } |
| 357 | 383 |
| 384 bool VaapiWrapper::CreateOutputSurface(unsigned int va_format, | |
| 385 const gfx::Size& size, | |
| 386 VASurfaceAttrib* va_attribs, | |
| 387 size_t num_va_attribs, | |
| 388 VASurfaceID* va_surface) { | |
| 389 base::AutoLock auto_lock(va_lock_); | |
| 390 | |
| 391 VAStatus va_res = vaCreateSurfaces(va_display_, | |
| 392 va_format, | |
| 393 size.width(), | |
| 394 size.height(), | |
| 395 va_surface, | |
| 396 1, | |
| 397 va_attribs, | |
| 398 num_va_attribs); | |
| 399 VA_SUCCESS_OR_RETURN(va_res, "Failed to create output VASurface", false); | |
| 400 return true; | |
| 401 } | |
| 402 | |
| 403 void VaapiWrapper::DestroyOutputSurface(VASurfaceID va_surface) { | |
| 404 base::AutoLock auto_lock(va_lock_); | |
| 405 | |
| 406 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface, 1); | |
| 407 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on output surface failed"); | |
| 408 } | |
| 409 | |
| 358 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, | 410 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, |
| 359 size_t size, | 411 size_t size, |
| 360 void* buffer) { | 412 void* buffer) { |
| 361 base::AutoLock auto_lock(va_lock_); | 413 base::AutoLock auto_lock(va_lock_); |
| 362 | 414 |
| 363 VABufferID buffer_id; | 415 VABufferID buffer_id; |
| 364 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, | 416 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, |
| 365 va_buffer_type, size, | 417 va_buffer_type, size, |
| 366 1, buffer, &buffer_id); | 418 1, buffer, &buffer_id); |
| 367 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); | 419 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... | |
| 499 | 551 |
| 500 return true; | 552 return true; |
| 501 } | 553 } |
| 502 | 554 |
| 503 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { | 555 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { |
| 504 bool result = Execute(va_surface_id); | 556 bool result = Execute(va_surface_id); |
| 505 DestroyPendingBuffers(); | 557 DestroyPendingBuffers(); |
| 506 return result; | 558 return result; |
| 507 } | 559 } |
| 508 | 560 |
| 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, | 561 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, |
| 529 VAImage* image, | 562 VAImage* image, |
| 530 void** mem) { | 563 void** mem) { |
| 531 base::AutoLock auto_lock(va_lock_); | 564 base::AutoLock auto_lock(va_lock_); |
| 532 | 565 |
| 533 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | 566 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
| 534 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 567 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
| 535 | 568 |
| 536 // Derive a VAImage from the VASurface | 569 // Derive a VAImage from the VASurface |
| 537 va_res = vaDeriveImage(va_display_, va_surface_id, image); | 570 va_res = vaDeriveImage(va_display_, va_surface_id, image); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 658 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); | 691 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); |
| 659 | 692 |
| 660 va_res = vaDestroyBuffer(va_display_, buffer_id); | 693 va_res = vaDestroyBuffer(va_display_, buffer_id); |
| 661 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); | 694 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
| 662 | 695 |
| 663 DCHECK(coded_buffers_.erase(buffer_id)); | 696 DCHECK(coded_buffers_.erase(buffer_id)); |
| 664 | 697 |
| 665 return buffer_segment == NULL; | 698 return buffer_segment == NULL; |
| 666 } | 699 } |
| 667 | 700 |
| 701 bool VaapiWrapper::PutSurfaceIntoSurface(VASurfaceID va_surface_id_src, | |
| 702 const gfx::Size& src_size, | |
| 703 VASurfaceID va_surface_id_dest, | |
| 704 const gfx::Size& dest_size) { | |
| 705 VAProcPipelineParameterBuffer* pipeline_param; | |
| 706 VARectangle input_region, output_region; | |
|
Pawel Osciak
2014/10/26 13:06:47
Please define variables as late as possible. Here
llandwerlin-old
2014/10/29 13:52:48
Acknowledged.
| |
| 707 | |
| 708 // If the source size is changed, we need to reconfigure the VPP | |
| 709 // pipeline. | |
| 710 if (src_size != vpp_picture_size_) { | |
| 711 DeinitializeVpp(); | |
| 712 if (!InitializeVpp(dest_size)) | |
| 713 return false; | |
| 714 } | |
| 715 | |
| 716 base::AutoLock auto_lock(va_lock_); | |
|
Pawel Osciak
2014/10/26 13:06:47
You need the lock for the duration of the entire m
llandwerlin-old
2014/10/29 13:52:48
Acknowledged.
| |
| 717 | |
| 718 VA_SUCCESS_OR_RETURN(vaSyncSurface(va_display_, va_surface_id_src), | |
|
Pawel Osciak
2014/10/26 13:06:47
I think we could move this even lower to give it m
llandwerlin-old
2014/10/29 13:52:48
That's true, since it's all coming from the GPU, w
| |
| 719 "Failed syncing surface", | |
| 720 false); | |
| 721 | |
| 722 VA_SUCCESS_OR_RETURN( | |
| 723 vaMapBuffer(va_display_, va_vpp_buffer_, (void**)&pipeline_param), | |
|
Pawel Osciak
2014/10/26 13:06:47
Please no c-style casts. reinterpret_cast.
llandwerlin-old
2014/10/29 13:52:48
Acknowledged.
| |
| 724 "Couldn't map vpp buffer", | |
| 725 false); | |
| 726 | |
| 727 memset(pipeline_param, 0, sizeof *pipeline_param); | |
| 728 | |
| 729 input_region.x = input_region.y = 0; | |
| 730 input_region.width = src_size.width(); | |
| 731 input_region.height = src_size.height(); | |
| 732 pipeline_param->surface_region = &input_region; | |
| 733 pipeline_param->surface = va_surface_id_src; | |
| 734 pipeline_param->surface_color_standard = VAProcColorStandardNone; | |
| 735 | |
| 736 output_region.x = output_region.y = 0; | |
| 737 output_region.width = dest_size.width(); | |
| 738 output_region.height = dest_size.height(); | |
| 739 pipeline_param->output_region = &output_region; | |
| 740 pipeline_param->output_background_color = 0xff000000; | |
| 741 pipeline_param->output_color_standard = VAProcColorStandardNone; | |
| 742 | |
| 743 VA_SUCCESS_OR_RETURN(vaUnmapBuffer(va_display_, va_vpp_buffer_), | |
| 744 "Couldn't unmap vpp buffer", | |
| 745 false); | |
| 746 | |
| 747 VA_SUCCESS_OR_RETURN( | |
| 748 vaBeginPicture(va_display_, va_vpp_context_, va_surface_id_dest), | |
| 749 "Couldn't begin picture", | |
| 750 false); | |
| 751 | |
| 752 VA_SUCCESS_OR_RETURN( | |
| 753 vaRenderPicture(va_display_, va_vpp_context_, &va_vpp_buffer_, 1), | |
| 754 "Couldn't render picture", | |
| 755 false); | |
| 756 | |
| 757 VA_SUCCESS_OR_RETURN(vaEndPicture(va_display_, va_vpp_context_), | |
| 758 "Couldn't end picture", | |
| 759 false); | |
| 760 | |
| 761 return true; | |
| 762 } | |
| 763 | |
| 764 bool VaapiWrapper::InitializeVpp(const gfx::Size& size) { | |
| 765 base::AutoLock auto_lock(va_lock_); | |
| 766 | |
| 767 VA_SUCCESS_OR_RETURN(vaCreateConfig(va_display_, | |
| 768 VAProfileNone, | |
| 769 VAEntrypointVideoProc, | |
| 770 NULL, | |
| 771 0, | |
| 772 &va_vpp_config_), | |
| 773 "Couldn't create config", | |
| 774 false); | |
| 775 | |
| 776 VA_SUCCESS_OR_RETURN(vaCreateContext(va_display_, | |
| 777 va_vpp_config_, | |
| 778 size.width(), | |
| 779 size.height(), | |
| 780 0, | |
| 781 NULL, | |
| 782 0, | |
| 783 &va_vpp_context_), | |
| 784 "Couldn't create context", | |
| 785 false); | |
| 786 | |
| 787 VA_SUCCESS_OR_RETURN(vaCreateBuffer(va_display_, | |
| 788 va_vpp_context_, | |
| 789 VAProcPipelineParameterBufferType, | |
| 790 sizeof(VAProcPipelineParameterBuffer), | |
| 791 1, | |
| 792 NULL, | |
| 793 &va_vpp_buffer_), | |
| 794 "Couldn't create buffer", | |
| 795 false); | |
| 796 | |
| 797 vpp_picture_size_ = size; | |
| 798 | |
| 799 return true; | |
| 800 } | |
| 801 | |
| 802 void VaapiWrapper::DeinitializeVpp() { | |
| 803 base::AutoLock auto_lock(va_lock_); | |
| 804 | |
| 805 if (va_vpp_buffer_ != VA_INVALID_ID) { | |
| 806 vaDestroyBuffer(va_display_, va_vpp_buffer_); | |
| 807 va_vpp_buffer_ = VA_INVALID_ID; | |
| 808 } | |
| 809 if (va_vpp_context_ != VA_INVALID_ID) { | |
| 810 vaDestroyContext(va_display_, va_vpp_context_); | |
| 811 va_vpp_context_ = VA_INVALID_ID; | |
| 812 } | |
| 813 if (va_vpp_config_ != VA_INVALID_ID) { | |
| 814 vaDestroyConfig(va_display_, va_vpp_config_); | |
| 815 va_vpp_config_ = VA_INVALID_ID; | |
| 816 } | |
| 817 } | |
| 818 | |
| 819 #if defined(USE_X11) | |
| 820 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, | |
| 821 Pixmap x_pixmap, | |
| 822 gfx::Size dest_size) { | |
| 823 base::AutoLock auto_lock(va_lock_); | |
| 824 | |
| 825 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | |
| 826 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | |
| 827 | |
| 828 // Put the data into an X Pixmap. | |
| 829 va_res = vaPutSurface(va_display_, | |
| 830 va_surface_id, | |
| 831 x_pixmap, | |
| 832 0, | |
| 833 0, | |
| 834 dest_size.width(), | |
| 835 dest_size.height(), | |
| 836 0, | |
| 837 0, | |
| 838 dest_size.width(), | |
| 839 dest_size.height(), | |
| 840 NULL, | |
| 841 0, | |
| 842 0); | |
| 843 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); | |
| 844 return true; | |
| 845 } | |
| 846 #endif // USE_X11 | |
| 847 | |
| 668 // static | 848 // static |
| 669 bool VaapiWrapper::PostSandboxInitialization() { | 849 bool VaapiWrapper::PostSandboxInitialization() { |
| 670 StubPathMap paths; | 850 StubPathMap paths; |
| 671 paths[kModuleVa].push_back(kVaLib); | 851 |
| 852 paths[kModuleVa].push_back("libva.so.1"); | |
| 853 | |
| 854 #if defined(USE_X11) | |
| 855 paths[kModuleVa_x11].push_back("libva-x11.so.1"); | |
| 856 #else | |
| 857 paths[kModuleVa_drm].push_back("libva-drm.so.1"); | |
| 858 #endif | |
| 672 | 859 |
| 673 return InitializeStubs(paths); | 860 return InitializeStubs(paths); |
| 674 } | 861 } |
| 675 | 862 |
| 676 } // namespace content | 863 } // namespace content |
| OLD | NEW |