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