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 #include "base/sys_info.h" | 13 #include "base/sys_info.h" |
| 14 // Auto-generated for dlopen libva libraries | 14 // Auto-generated for dlopen libva libraries |
| 15 #include "content/common/gpu/media/va_stubs.h" | 15 #include "content/common/gpu/media/va_stubs.h" |
| 16 #include "content/common/gpu/media/vaapi_picture.h" | |
| 16 #include "third_party/libyuv/include/libyuv.h" | 17 #include "third_party/libyuv/include/libyuv.h" |
| 18 #include "ui/gl/gl_bindings.h" | |
| 19 #if defined(USE_X11) | |
| 20 #include "content/common/gpu/media/vaapi_tfp_picture.h" | |
| 21 #include "ui/gfx/x/x11_types.h" | |
| 22 #else | |
| 23 #include "content/common/gpu/media/vaapi_drm_picture.h" | |
| 24 #include "third_party/libva/va/drm/va_drm.h" | |
| 25 #include "third_party/libva/va/va_drmcommon.h" | |
| 26 #include "ui/ozone/public/ozone_platform.h" | |
| 27 #include "ui/ozone/public/surface_factory_ozone.h" | |
| 28 #endif // USE_X11 | |
| 17 | 29 |
| 18 using content_common_gpu_media::kModuleVa; | 30 using content_common_gpu_media::kModuleVa; |
| 31 #if defined(USE_X11) | |
| 32 using content_common_gpu_media::kModuleVa_x11; | |
| 33 #else | |
| 34 using content_common_gpu_media::kModuleVa_drm; | |
| 35 #endif // USE_X11 | |
| 19 using content_common_gpu_media::InitializeStubs; | 36 using content_common_gpu_media::InitializeStubs; |
| 20 using content_common_gpu_media::StubPathMap; | 37 using content_common_gpu_media::StubPathMap; |
| 21 | 38 |
| 22 // libva-x11 depends on libva, so dlopen libva-x11 is enough | |
| 23 static const base::FilePath::CharType kVaLib[] = | |
| 24 FILE_PATH_LITERAL("libva-x11.so.1"); | |
| 25 | |
| 26 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ | 39 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ |
| 27 do { \ | 40 do { \ |
| 28 LOG(ERROR) << err_msg \ | 41 LOG(ERROR) << err_msg \ |
| 29 << " VA error: " << vaErrorStr(va_error); \ | 42 << " VA error: " << vaErrorStr(va_error); \ |
| 30 report_error_to_uma_cb_.Run(); \ | 43 report_error_to_uma_cb_.Run(); \ |
| 31 } while (0) | 44 } while (0) |
| 32 | 45 |
| 33 #define VA_LOG_ON_ERROR(va_error, err_msg) \ | 46 #define VA_LOG_ON_ERROR(va_error, err_msg) \ |
| 34 do { \ | 47 do { \ |
| 35 if ((va_error) != VA_STATUS_SUCCESS) \ | 48 if ((va_error) != VA_STATUS_SUCCESS) \ |
| 36 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ | 49 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ |
| 37 } while (0) | 50 } while (0) |
| 38 | 51 |
| 39 #define VA_SUCCESS_OR_RETURN(va_error, err_msg, ret) \ | 52 #define VA_SUCCESS_OR_RETURN(va_error, err_msg, ret) \ |
| 40 do { \ | 53 do { \ |
| 41 if ((va_error) != VA_STATUS_SUCCESS) { \ | 54 if ((va_error) != VA_STATUS_SUCCESS) { \ |
| 42 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ | 55 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ |
| 43 return (ret); \ | 56 return (ret); \ |
| 44 } \ | 57 } \ |
| 45 } while (0) | 58 } while (0) |
| 46 | 59 |
| 60 namespace gfx { | |
| 61 class GLContextGLX; | |
| 62 } | |
|
piman
2014/12/16 20:46:43
Doesn't look like this is needed.
llandwerlin-old
2014/12/17 11:46:38
Acknowledged.
| |
| 63 | |
| 47 namespace content { | 64 namespace content { |
| 48 | 65 |
| 49 // Config attributes common for both encode and decode. | 66 // Config attributes common for both encode and decode. |
| 50 static const VAConfigAttrib kCommonVAConfigAttribs[] = { | 67 static const VAConfigAttrib kCommonVAConfigAttribs[] = { |
| 51 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420}, | 68 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420}, |
| 52 }; | 69 }; |
| 53 | 70 |
| 54 // Attributes required for encode. | 71 // Attributes required for encode. |
| 55 static const VAConfigAttrib kEncodeVAConfigAttribs[] = { | 72 static const VAConfigAttrib kEncodeVAConfigAttribs[] = { |
| 56 {VAConfigAttribRateControl, VA_RC_CBR}, | 73 {VAConfigAttribRateControl, VA_RC_CBR}, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 VAProfileH264ConstrainedBaseline) != | 133 VAProfileH264ConstrainedBaseline) != |
| 117 supported_profiles.end()) { | 134 supported_profiles.end()) { |
| 118 va_profile = VAProfileH264ConstrainedBaseline; | 135 va_profile = VAProfileH264ConstrainedBaseline; |
| 119 DVLOG(1) << "Falling back to constrained baseline profile."; | 136 DVLOG(1) << "Falling back to constrained baseline profile."; |
| 120 } | 137 } |
| 121 } | 138 } |
| 122 | 139 |
| 123 return va_profile; | 140 return va_profile; |
| 124 } | 141 } |
| 125 | 142 |
| 126 VASurface::VASurface(VASurfaceID va_surface_id, const ReleaseCB& release_cb) | 143 VASurface::VASurface(VASurfaceID va_surface_id, |
| 127 : va_surface_id_(va_surface_id), | 144 const gfx::Size& size, |
| 128 release_cb_(release_cb) { | 145 const ReleaseCB& release_cb) |
| 146 : va_surface_id_(va_surface_id), size_(size), release_cb_(release_cb) { | |
| 129 DCHECK(!release_cb_.is_null()); | 147 DCHECK(!release_cb_.is_null()); |
| 130 } | 148 } |
| 131 | 149 |
| 132 VASurface::~VASurface() { | 150 VASurface::~VASurface() { |
| 133 release_cb_.Run(va_surface_id_); | 151 release_cb_.Run(va_surface_id_); |
| 134 } | 152 } |
| 135 | 153 |
| 136 VaapiWrapper::VaapiWrapper() | 154 VaapiWrapper::VaapiWrapper() |
| 137 : va_display_(NULL), | 155 : va_display_(NULL), |
| 138 va_config_id_(VA_INVALID_ID), | 156 va_config_id_(VA_INVALID_ID), |
| 139 va_context_id_(VA_INVALID_ID), | 157 va_context_id_(VA_INVALID_ID), |
| 140 va_initialized_(false) { | 158 va_initialized_(false), |
| 159 va_vpp_config_id_(VA_INVALID_ID), | |
| 160 va_vpp_context_id_(VA_INVALID_ID), | |
| 161 va_vpp_buffer_id_(VA_INVALID_ID) { | |
| 141 } | 162 } |
| 142 | 163 |
| 143 VaapiWrapper::~VaapiWrapper() { | 164 VaapiWrapper::~VaapiWrapper() { |
| 144 DestroyPendingBuffers(); | 165 DestroyPendingBuffers(); |
| 145 DestroyCodedBuffers(); | 166 DestroyCodedBuffers(); |
| 146 DestroySurfaces(); | 167 DestroySurfaces(); |
| 168 DeinitializeVpp(); | |
| 147 Deinitialize(); | 169 Deinitialize(); |
| 148 } | 170 } |
| 149 | 171 |
| 150 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( | 172 scoped_refptr<VaapiWrapper> VaapiWrapper::Create( |
| 151 CodecMode mode, | 173 CodecMode mode, |
| 152 media::VideoCodecProfile profile, | 174 media::VideoCodecProfile profile, |
| 153 Display* x_display, | |
| 154 const base::Closure& report_error_to_uma_cb) { | 175 const base::Closure& report_error_to_uma_cb) { |
| 155 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); | 176 scoped_refptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); |
| 156 | 177 |
| 157 if (!vaapi_wrapper->Initialize( | 178 if (!vaapi_wrapper->Initialize(mode, profile, report_error_to_uma_cb)) |
| 158 mode, profile, x_display, report_error_to_uma_cb)) | 179 vaapi_wrapper = NULL; |
| 159 vaapi_wrapper.reset(); | |
| 160 | 180 |
| 161 return vaapi_wrapper.Pass(); | 181 return vaapi_wrapper; |
| 162 } | 182 } |
| 163 | 183 |
| 164 std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles( | 184 std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles( |
| 165 Display* x_display, | |
| 166 const base::Closure& report_error_to_uma_cb) { | 185 const base::Closure& report_error_to_uma_cb) { |
| 167 std::vector<media::VideoCodecProfile> supported_profiles; | 186 std::vector<media::VideoCodecProfile> supported_profiles; |
| 168 | 187 |
| 169 scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper()); | 188 scoped_refptr<VaapiWrapper> wrapper(new VaapiWrapper()); |
| 170 if (!wrapper->VaInitialize(x_display, report_error_to_uma_cb)) { | 189 if (!wrapper->VaInitialize(report_error_to_uma_cb)) { |
| 171 return supported_profiles; | 190 return supported_profiles; |
| 172 } | 191 } |
| 173 | 192 |
| 174 std::vector<VAProfile> va_profiles; | 193 std::vector<VAProfile> va_profiles; |
| 175 if (!wrapper->GetSupportedVaProfiles(&va_profiles)) | 194 if (!wrapper->GetSupportedVaProfiles(&va_profiles)) |
| 176 return supported_profiles; | 195 return supported_profiles; |
| 177 | 196 |
| 178 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode); | 197 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode); |
| 179 for (size_t i = 0; i < arraysize(kProfileMap); i++) { | 198 for (size_t i = 0; i < arraysize(kProfileMap); i++) { |
| 180 VAProfile va_profile = | 199 VAProfile va_profile = |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 195 1, // At least support '_LOCAL_OVERLAY'. | 214 1, // At least support '_LOCAL_OVERLAY'. |
| 196 -1, // The maximum possible support 'ALL'. | 215 -1, // The maximum possible support 'ALL'. |
| 197 VA_RENDER_MODE_LOCAL_GPU, | 216 VA_RENDER_MODE_LOCAL_GPU, |
| 198 VA_DISPLAY_ATTRIB_SETTABLE}; | 217 VA_DISPLAY_ATTRIB_SETTABLE}; |
| 199 | 218 |
| 200 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); | 219 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); |
| 201 if (va_res != VA_STATUS_SUCCESS) | 220 if (va_res != VA_STATUS_SUCCESS) |
| 202 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; | 221 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; |
| 203 } | 222 } |
| 204 | 223 |
| 205 bool VaapiWrapper::VaInitialize(Display* x_display, | 224 bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) { |
| 206 const base::Closure& report_error_to_uma_cb) { | |
| 207 static bool vaapi_functions_initialized = PostSandboxInitialization(); | 225 static bool vaapi_functions_initialized = PostSandboxInitialization(); |
| 208 if (!vaapi_functions_initialized) { | 226 if (!vaapi_functions_initialized) { |
| 209 bool running_on_chromeos = false; | 227 bool running_on_chromeos = false; |
| 210 #if defined(OS_CHROMEOS) | 228 #if defined(OS_CHROMEOS) |
| 211 // When chrome runs on linux with chromeos=1, do not log error message | 229 // When chrome runs on linux with chromeos=1, do not log error message |
| 212 // without VAAPI libraries. | 230 // without VAAPI libraries. |
| 213 running_on_chromeos = base::SysInfo::IsRunningOnChromeOS(); | 231 running_on_chromeos = base::SysInfo::IsRunningOnChromeOS(); |
| 214 #endif | 232 #endif |
| 215 static const char kErrorMsg[] = "Failed to initialize VAAPI libs"; | 233 static const char kErrorMsg[] = "Failed to initialize VAAPI libs"; |
| 216 if (running_on_chromeos) | 234 if (running_on_chromeos) |
| 217 LOG(ERROR) << kErrorMsg; | 235 LOG(ERROR) << kErrorMsg; |
| 218 else | 236 else |
| 219 DVLOG(1) << kErrorMsg; | 237 DVLOG(1) << kErrorMsg; |
| 220 return false; | 238 return false; |
| 221 } | 239 } |
| 222 | 240 |
| 223 report_error_to_uma_cb_ = report_error_to_uma_cb; | 241 report_error_to_uma_cb_ = report_error_to_uma_cb; |
| 224 | 242 |
| 225 base::AutoLock auto_lock(va_lock_); | 243 base::AutoLock auto_lock(va_lock_); |
| 226 | 244 |
| 227 va_display_ = vaGetDisplay(x_display); | 245 #if defined(USE_X11) |
| 246 va_display_ = vaGetDisplay(gfx::GetXDisplay()); | |
| 247 #else | |
| 248 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); | |
| 249 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); | |
| 250 | |
| 251 va_display_ = vaGetDisplayDRM(factory->GetDrmFd()); | |
| 252 #endif // USE_X11 | |
| 253 | |
| 228 if (!vaDisplayIsValid(va_display_)) { | 254 if (!vaDisplayIsValid(va_display_)) { |
| 229 LOG(ERROR) << "Could not get a valid VA display"; | 255 LOG(ERROR) << "Could not get a valid VA display"; |
| 230 return false; | 256 return false; |
| 231 } | 257 } |
| 232 | 258 |
| 233 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); | 259 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); |
| 234 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); | 260 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); |
| 235 va_initialized_ = true; | 261 va_initialized_ = true; |
| 236 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; | 262 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; |
| 237 | 263 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 314 DVLOG(1) << "Unsupported value " << required_attribs[i].value | 340 DVLOG(1) << "Unsupported value " << required_attribs[i].value |
| 315 << " for attribute type " << required_attribs[i].type; | 341 << " for attribute type " << required_attribs[i].type; |
| 316 return false; | 342 return false; |
| 317 } | 343 } |
| 318 } | 344 } |
| 319 return true; | 345 return true; |
| 320 } | 346 } |
| 321 | 347 |
| 322 bool VaapiWrapper::Initialize(CodecMode mode, | 348 bool VaapiWrapper::Initialize(CodecMode mode, |
| 323 media::VideoCodecProfile profile, | 349 media::VideoCodecProfile profile, |
| 324 Display* x_display, | |
| 325 const base::Closure& report_error_to_uma_cb) { | 350 const base::Closure& report_error_to_uma_cb) { |
| 326 if (!VaInitialize(x_display, report_error_to_uma_cb)) | 351 if (!VaInitialize(report_error_to_uma_cb)) |
| 327 return false; | 352 return false; |
| 328 std::vector<VAProfile> supported_va_profiles; | 353 std::vector<VAProfile> supported_va_profiles; |
| 329 if (!GetSupportedVaProfiles(&supported_va_profiles)) | 354 if (!GetSupportedVaProfiles(&supported_va_profiles)) |
| 330 return false; | 355 return false; |
| 331 VAProfile va_profile = ProfileToVAProfile(profile, supported_va_profiles); | 356 VAProfile va_profile = ProfileToVAProfile(profile, supported_va_profiles); |
| 332 if (va_profile == VAProfileNone) { | 357 if (va_profile == VAProfileNone) { |
| 333 DVLOG(1) << "Unsupported profile"; | 358 DVLOG(1) << "Unsupported profile"; |
| 334 return false; | 359 return false; |
| 335 } | 360 } |
| 336 VAEntrypoint entrypoint = | 361 VAEntrypoint entrypoint = |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 376 va_config_id_ = VA_INVALID_ID; | 401 va_config_id_ = VA_INVALID_ID; |
| 377 va_display_ = NULL; | 402 va_display_ = NULL; |
| 378 va_initialized_ = false; | 403 va_initialized_ = false; |
| 379 } | 404 } |
| 380 | 405 |
| 381 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { | 406 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { |
| 382 return (major_version_ < major) || | 407 return (major_version_ < major) || |
| 383 (major_version_ == major && minor_version_ < minor); | 408 (major_version_ == major && minor_version_ < minor); |
| 384 } | 409 } |
| 385 | 410 |
| 386 bool VaapiWrapper::CreateSurfaces(gfx::Size size, | 411 bool VaapiWrapper::CreateSurfaces(const gfx::Size& size, |
| 387 size_t num_surfaces, | 412 size_t num_surfaces, |
| 388 std::vector<VASurfaceID>* va_surfaces) { | 413 std::vector<VASurfaceID>* va_surfaces) { |
| 389 base::AutoLock auto_lock(va_lock_); | 414 base::AutoLock auto_lock(va_lock_); |
| 390 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; | 415 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; |
| 391 | 416 |
| 392 DCHECK(va_surfaces->empty()); | 417 DCHECK(va_surfaces->empty()); |
| 393 DCHECK(va_surface_ids_.empty()); | 418 DCHECK(va_surface_ids_.empty()); |
| 394 va_surface_ids_.resize(num_surfaces); | 419 va_surface_ids_.resize(num_surfaces); |
| 395 | 420 |
| 396 // Allocate surfaces in driver. | 421 // Allocate surfaces in driver. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 435 if (!va_surface_ids_.empty()) { | 460 if (!va_surface_ids_.empty()) { |
| 436 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], | 461 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], |
| 437 va_surface_ids_.size()); | 462 va_surface_ids_.size()); |
| 438 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); | 463 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); |
| 439 } | 464 } |
| 440 | 465 |
| 441 va_surface_ids_.clear(); | 466 va_surface_ids_.clear(); |
| 442 va_context_id_ = VA_INVALID_ID; | 467 va_context_id_ = VA_INVALID_ID; |
| 443 } | 468 } |
| 444 | 469 |
| 470 scoped_refptr<VASurface> VaapiWrapper::CreateUnownedSurface( | |
| 471 unsigned int va_format, | |
| 472 const gfx::Size& size, | |
| 473 VASurfaceAttrib* va_attribs, | |
| 474 size_t num_va_attribs) { | |
| 475 base::AutoLock auto_lock(va_lock_); | |
|
piman
2014/12/16 20:46:43
I see you're using a lock everywhere. I take it th
llandwerlin-old
2014/12/17 11:46:38
It's a good question, as far as I can tell, VaapiW
| |
| 476 VASurfaceID va_surface_id; | |
| 477 scoped_refptr<VASurface> va_surface; | |
| 478 | |
| 479 VAStatus va_res = | |
| 480 vaCreateSurfaces(va_display_, va_format, size.width(), size.height(), | |
| 481 &va_surface_id, 1, va_attribs, num_va_attribs); | |
| 482 VA_SUCCESS_OR_RETURN(va_res, "Failed to create unowned VASurface", | |
| 483 va_surface); | |
| 484 | |
| 485 va_surface = new VASurface(va_surface_id, size, | |
| 486 base::Bind(&VaapiWrapper::DestroyUnownedSurface, | |
| 487 make_scoped_refptr(this))); | |
| 488 | |
| 489 return va_surface; | |
| 490 } | |
| 491 | |
| 492 void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface) { | |
| 493 base::AutoLock auto_lock(va_lock_); | |
| 494 | |
| 495 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface, 1); | |
| 496 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on output surface failed"); | |
| 497 } | |
| 498 | |
| 445 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, | 499 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, |
| 446 size_t size, | 500 size_t size, |
| 447 void* buffer) { | 501 void* buffer) { |
| 448 base::AutoLock auto_lock(va_lock_); | 502 base::AutoLock auto_lock(va_lock_); |
| 449 | 503 |
| 450 VABufferID buffer_id; | 504 VABufferID buffer_id; |
| 451 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, | 505 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, |
| 452 va_buffer_type, size, | 506 va_buffer_type, size, |
| 453 1, buffer, &buffer_id); | 507 1, buffer, &buffer_id); |
| 454 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); | 508 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... | |
| 586 | 640 |
| 587 return true; | 641 return true; |
| 588 } | 642 } |
| 589 | 643 |
| 590 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { | 644 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { |
| 591 bool result = Execute(va_surface_id); | 645 bool result = Execute(va_surface_id); |
| 592 DestroyPendingBuffers(); | 646 DestroyPendingBuffers(); |
| 593 return result; | 647 return result; |
| 594 } | 648 } |
| 595 | 649 |
| 596 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, | |
| 597 Pixmap x_pixmap, | |
| 598 gfx::Size dest_size) { | |
| 599 base::AutoLock auto_lock(va_lock_); | |
| 600 | |
| 601 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | |
| 602 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | |
| 603 | |
| 604 // Put the data into an X Pixmap. | |
| 605 va_res = vaPutSurface(va_display_, | |
| 606 va_surface_id, | |
| 607 x_pixmap, | |
| 608 0, 0, dest_size.width(), dest_size.height(), | |
| 609 0, 0, dest_size.width(), dest_size.height(), | |
| 610 NULL, 0, 0); | |
| 611 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); | |
| 612 return true; | |
| 613 } | |
| 614 | |
| 615 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, | 650 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, |
| 616 VAImage* image, | 651 VAImage* image, |
| 617 void** mem) { | 652 void** mem) { |
| 618 base::AutoLock auto_lock(va_lock_); | 653 base::AutoLock auto_lock(va_lock_); |
| 619 | 654 |
| 620 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | 655 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
| 621 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 656 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
| 622 | 657 |
| 623 // Derive a VAImage from the VASurface | 658 // Derive a VAImage from the VASurface |
| 624 va_res = vaDeriveImage(va_display_, va_surface_id, image); | 659 va_res = vaDeriveImage(va_display_, va_surface_id, image); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 745 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); | 780 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); |
| 746 | 781 |
| 747 va_res = vaDestroyBuffer(va_display_, buffer_id); | 782 va_res = vaDestroyBuffer(va_display_, buffer_id); |
| 748 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); | 783 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
| 749 | 784 |
| 750 DCHECK(coded_buffers_.erase(buffer_id)); | 785 DCHECK(coded_buffers_.erase(buffer_id)); |
| 751 | 786 |
| 752 return buffer_segment == NULL; | 787 return buffer_segment == NULL; |
| 753 } | 788 } |
| 754 | 789 |
| 790 bool VaapiWrapper::BlitSurface(VASurfaceID va_surface_id_src, | |
| 791 const gfx::Size& src_size, | |
| 792 VASurfaceID va_surface_id_dest, | |
| 793 const gfx::Size& dest_size) { | |
| 794 base::AutoLock auto_lock(va_lock_); | |
| 795 | |
| 796 // Initialize the post processing engine if not already done. | |
| 797 if (va_vpp_buffer_id_ == VA_INVALID_ID) | |
|
piman
2014/12/16 20:46:43
nit: you need {} per style guide.
llandwerlin-old
2014/12/17 11:46:37
Acknowledged.
| |
| 798 if (!InitializeVpp_Locked()) | |
| 799 return false; | |
| 800 | |
| 801 VAProcPipelineParameterBuffer* pipeline_param; | |
| 802 VA_SUCCESS_OR_RETURN(vaMapBuffer(va_display_, va_vpp_buffer_id_, | |
| 803 reinterpret_cast<void**>(&pipeline_param)), | |
| 804 "Couldn't map vpp buffer", false); | |
| 805 | |
| 806 memset(pipeline_param, 0, sizeof *pipeline_param); | |
| 807 | |
| 808 VARectangle input_region; | |
| 809 input_region.x = input_region.y = 0; | |
| 810 input_region.width = src_size.width(); | |
| 811 input_region.height = src_size.height(); | |
| 812 pipeline_param->surface_region = &input_region; | |
| 813 pipeline_param->surface = va_surface_id_src; | |
| 814 pipeline_param->surface_color_standard = VAProcColorStandardNone; | |
| 815 | |
| 816 VARectangle output_region; | |
| 817 output_region.x = output_region.y = 0; | |
| 818 output_region.width = dest_size.width(); | |
| 819 output_region.height = dest_size.height(); | |
| 820 pipeline_param->output_region = &output_region; | |
| 821 pipeline_param->output_background_color = 0xff000000; | |
| 822 pipeline_param->output_color_standard = VAProcColorStandardNone; | |
| 823 | |
| 824 VA_SUCCESS_OR_RETURN(vaUnmapBuffer(va_display_, va_vpp_buffer_id_), | |
| 825 "Couldn't unmap vpp buffer", false); | |
| 826 | |
| 827 VA_SUCCESS_OR_RETURN( | |
| 828 vaBeginPicture(va_display_, va_vpp_context_id_, va_surface_id_dest), | |
| 829 "Couldn't begin picture", false); | |
| 830 | |
| 831 VA_SUCCESS_OR_RETURN( | |
| 832 vaRenderPicture(va_display_, va_vpp_context_id_, &va_vpp_buffer_id_, 1), | |
| 833 "Couldn't render picture", false); | |
| 834 | |
| 835 VA_SUCCESS_OR_RETURN(vaEndPicture(va_display_, va_vpp_context_id_), | |
| 836 "Couldn't end picture", false); | |
| 837 | |
| 838 return true; | |
| 839 } | |
| 840 | |
| 841 bool VaapiWrapper::InitializeVpp_Locked() { | |
| 842 va_lock_.AssertAcquired(); | |
| 843 | |
| 844 VA_SUCCESS_OR_RETURN( | |
| 845 vaCreateConfig(va_display_, VAProfileNone, VAEntrypointVideoProc, NULL, 0, | |
| 846 &va_vpp_config_id_), | |
| 847 "Couldn't create config", false); | |
| 848 | |
| 849 // The size of the picture for the context is irrelevant in the case | |
| 850 // of the VPP, just passing 1x1. | |
| 851 VA_SUCCESS_OR_RETURN(vaCreateContext(va_display_, va_vpp_config_id_, 1, 1, 0, | |
| 852 NULL, 0, &va_vpp_context_id_), | |
| 853 "Couldn't create context", false); | |
| 854 | |
| 855 VA_SUCCESS_OR_RETURN(vaCreateBuffer(va_display_, va_vpp_context_id_, | |
| 856 VAProcPipelineParameterBufferType, | |
| 857 sizeof(VAProcPipelineParameterBuffer), 1, | |
| 858 NULL, &va_vpp_buffer_id_), | |
| 859 "Couldn't create buffer", false); | |
| 860 | |
| 861 return true; | |
| 862 } | |
| 863 | |
| 864 void VaapiWrapper::DeinitializeVpp() { | |
| 865 base::AutoLock auto_lock(va_lock_); | |
| 866 | |
| 867 if (va_vpp_buffer_id_ != VA_INVALID_ID) { | |
| 868 vaDestroyBuffer(va_display_, va_vpp_buffer_id_); | |
| 869 va_vpp_buffer_id_ = VA_INVALID_ID; | |
| 870 } | |
| 871 if (va_vpp_context_id_ != VA_INVALID_ID) { | |
| 872 vaDestroyContext(va_display_, va_vpp_context_id_); | |
| 873 va_vpp_context_id_ = VA_INVALID_ID; | |
| 874 } | |
| 875 if (va_vpp_config_id_ != VA_INVALID_ID) { | |
| 876 vaDestroyConfig(va_display_, va_vpp_config_id_); | |
| 877 va_vpp_config_id_ = VA_INVALID_ID; | |
| 878 } | |
| 879 } | |
| 880 | |
| 881 #if defined(USE_X11) | |
| 882 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, | |
| 883 Pixmap x_pixmap, | |
| 884 gfx::Size dest_size) { | |
| 885 base::AutoLock auto_lock(va_lock_); | |
| 886 | |
| 887 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | |
| 888 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | |
| 889 | |
| 890 // Put the data into an X Pixmap. | |
| 891 va_res = vaPutSurface(va_display_, va_surface_id, x_pixmap, 0, 0, | |
| 892 dest_size.width(), dest_size.height(), 0, 0, | |
| 893 dest_size.width(), dest_size.height(), NULL, 0, 0); | |
| 894 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); | |
| 895 return true; | |
| 896 } | |
| 897 #endif // USE_X11 | |
| 898 | |
| 755 // static | 899 // static |
| 756 bool VaapiWrapper::PostSandboxInitialization() { | 900 bool VaapiWrapper::PostSandboxInitialization() { |
| 757 StubPathMap paths; | 901 StubPathMap paths; |
| 758 paths[kModuleVa].push_back(kVaLib); | 902 |
| 903 paths[kModuleVa].push_back("libva.so.1"); | |
| 904 | |
| 905 #if defined(USE_X11) | |
| 906 paths[kModuleVa_x11].push_back("libva-x11.so.1"); | |
| 907 #else | |
| 908 paths[kModuleVa_drm].push_back("libva-drm.so.1"); | |
| 909 #endif | |
| 759 | 910 |
| 760 return InitializeStubs(paths); | 911 return InitializeStubs(paths); |
| 761 } | 912 } |
| 762 | 913 |
| 763 } // namespace content | 914 } // namespace content |
| OLD | NEW |