Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: content/common/gpu/media/vaapi_wrapper.cc

Issue 1137483002: VAAPI Wrapper: refactor management of drm file (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move va_lock_ into VADisplayState and ensure its validity for lifetime of VaapiWrapper. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 return (ret); \ 55 return (ret); \
56 } \ 56 } \
57 } while (0) 57 } while (0)
58 58
59 namespace content { 59 namespace content {
60 60
61 // Maximum framerate of encoded profile. This value is an arbitary limit 61 // Maximum framerate of encoded profile. This value is an arbitary limit
62 // and not taken from HW documentation. 62 // and not taken from HW documentation.
63 const int kMaxEncoderFramerate = 30; 63 const int kMaxEncoderFramerate = 30;
64 64
65 #if defined(USE_OZONE)
66 base::LazyInstance<VaapiWrapper::VADisplayState>
67 VaapiWrapper::g_va_display_state_ = LAZY_INSTANCE_INITIALIZER;
68 #endif
69
65 base::LazyInstance<VaapiWrapper::LazyProfileInfos> 70 base::LazyInstance<VaapiWrapper::LazyProfileInfos>
66 VaapiWrapper::profile_infos_ = LAZY_INSTANCE_INITIALIZER; 71 VaapiWrapper::profile_infos_ = LAZY_INSTANCE_INITIALIZER;
67 72
68 // Config attributes common for both encode and decode. 73 // Config attributes common for both encode and decode.
69 static const VAConfigAttrib kCommonVAConfigAttribs[] = { 74 static const VAConfigAttrib kCommonVAConfigAttribs[] = {
70 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420}, 75 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420},
71 }; 76 };
72 77
73 // Attributes required for encode. 78 // Attributes required for encode.
74 static const VAConfigAttrib kEncodeVAConfigAttribs[] = { 79 static const VAConfigAttrib kEncodeVAConfigAttribs[] = {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 } 121 }
117 122
118 VASurface::~VASurface() { 123 VASurface::~VASurface() {
119 release_cb_.Run(va_surface_id_); 124 release_cb_.Run(va_surface_id_);
120 } 125 }
121 126
122 VaapiWrapper::VaapiWrapper() 127 VaapiWrapper::VaapiWrapper()
123 : va_display_(NULL), 128 : va_display_(NULL),
124 va_config_id_(VA_INVALID_ID), 129 va_config_id_(VA_INVALID_ID),
125 va_context_id_(VA_INVALID_ID), 130 va_context_id_(VA_INVALID_ID),
126 va_initialized_(false),
127 va_vpp_config_id_(VA_INVALID_ID), 131 va_vpp_config_id_(VA_INVALID_ID),
128 va_vpp_context_id_(VA_INVALID_ID), 132 va_vpp_context_id_(VA_INVALID_ID),
129 va_vpp_buffer_id_(VA_INVALID_ID) { 133 va_vpp_buffer_id_(VA_INVALID_ID) {
134 #if defined(USE_X11)
135 va_display_state_.reset(new VADisplayState());
136 va_lock_ = va_display_state_->va_lock();
137 #elif defined(USE_OZONE)
138 va_lock_ = g_va_display_state_.Get().va_lock();
139 #endif // USE_X11
130 } 140 }
131 141
132 VaapiWrapper::~VaapiWrapper() { 142 VaapiWrapper::~VaapiWrapper() {
133 DestroyPendingBuffers(); 143 DestroyPendingBuffers();
134 DestroyCodedBuffers(); 144 DestroyCodedBuffers();
135 DestroySurfaces(); 145 DestroySurfaces();
136 DeinitializeVpp(); 146 DeinitializeVpp();
137 Deinitialize(); 147 Deinitialize();
138 } 148 }
139 149
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 profile.min_resolution.SetSize(16, 16); 226 profile.min_resolution.SetSize(16, 16);
217 profiles.push_back(profile); 227 profiles.push_back(profile);
218 break; 228 break;
219 } 229 }
220 } 230 }
221 } 231 }
222 return profiles; 232 return profiles;
223 } 233 }
224 234
225 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { 235 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
226 base::AutoLock auto_lock(va_lock_); 236 base::AutoLock auto_lock(*va_lock_);
227 VADisplayAttribute item = {VADisplayAttribRenderMode, 237 VADisplayAttribute item = {VADisplayAttribRenderMode,
228 1, // At least support '_LOCAL_OVERLAY'. 238 1, // At least support '_LOCAL_OVERLAY'.
229 -1, // The maximum possible support 'ALL'. 239 -1, // The maximum possible support 'ALL'.
230 VA_RENDER_MODE_LOCAL_GPU, 240 VA_RENDER_MODE_LOCAL_GPU,
231 VA_DISPLAY_ATTRIB_SETTABLE}; 241 VA_DISPLAY_ATTRIB_SETTABLE};
232 242
233 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); 243 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1);
234 if (va_res != VA_STATUS_SUCCESS) 244 if (va_res != VA_STATUS_SUCCESS)
235 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; 245 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default.";
236 } 246 }
(...skipping 28 matching lines...) Expand all
265 VaapiWrapper::GetSupportedProfileInfosForCodecModeInternal(CodecMode mode) { 275 VaapiWrapper::GetSupportedProfileInfosForCodecModeInternal(CodecMode mode) {
266 std::vector<ProfileInfo> supported_profile_infos; 276 std::vector<ProfileInfo> supported_profile_infos;
267 std::vector<VAProfile> va_profiles; 277 std::vector<VAProfile> va_profiles;
268 if (!GetSupportedVaProfiles(&va_profiles)) 278 if (!GetSupportedVaProfiles(&va_profiles))
269 return supported_profile_infos; 279 return supported_profile_infos;
270 280
271 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode); 281 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode);
272 VAEntrypoint entrypoint = 282 VAEntrypoint entrypoint =
273 (mode == kEncode ? VAEntrypointEncSlice: VAEntrypointVLD); 283 (mode == kEncode ? VAEntrypointEncSlice: VAEntrypointVLD);
274 284
275 base::AutoLock auto_lock(va_lock_); 285 base::AutoLock auto_lock(*va_lock_);
276 for (const auto& va_profile : va_profiles) { 286 for (const auto& va_profile : va_profiles) {
277 if (!IsEntrypointSupported_Locked(va_profile, entrypoint)) 287 if (!IsEntrypointSupported_Locked(va_profile, entrypoint))
278 continue; 288 continue;
279 if (!AreAttribsSupported_Locked(va_profile, entrypoint, required_attribs)) 289 if (!AreAttribsSupported_Locked(va_profile, entrypoint, required_attribs))
280 continue; 290 continue;
281 ProfileInfo profile_info; 291 ProfileInfo profile_info;
282 if (!GetMaxResolution_Locked(va_profile, 292 if (!GetMaxResolution_Locked(va_profile,
283 entrypoint, 293 entrypoint,
284 required_attribs, 294 required_attribs,
285 &profile_info.max_resolution)) { 295 &profile_info.max_resolution)) {
(...skipping 19 matching lines...) Expand all
305 static const char kErrorMsg[] = "Failed to initialize VAAPI libs"; 315 static const char kErrorMsg[] = "Failed to initialize VAAPI libs";
306 if (running_on_chromeos) 316 if (running_on_chromeos)
307 LOG(ERROR) << kErrorMsg; 317 LOG(ERROR) << kErrorMsg;
308 else 318 else
309 DVLOG(1) << kErrorMsg; 319 DVLOG(1) << kErrorMsg;
310 return false; 320 return false;
311 } 321 }
312 322
313 report_error_to_uma_cb_ = report_error_to_uma_cb; 323 report_error_to_uma_cb_ = report_error_to_uma_cb;
314 324
315 base::AutoLock auto_lock(va_lock_); 325 base::AutoLock auto_lock(*va_lock_);
326
327 VADisplayState* va_display_state = nullptr;
316 328
317 #if defined(USE_X11) 329 #if defined(USE_X11)
318 va_display_ = vaGetDisplay(gfx::GetXDisplay()); 330 va_display_state = va_display_state_.get();
319 #elif defined(USE_OZONE) 331 #elif defined(USE_OZONE)
320 const char* kDriRenderNode0Path = "/dev/dri/renderD128"; 332 va_display_state = &g_va_display_state_.Get();
321 drm_file_ = base::File(base::FilePath::FromUTF8Unsafe(kDriRenderNode0Path),
322 base::File::FLAG_OPEN | base::File::FLAG_READ |
323 base::File::FLAG_WRITE);
324 va_display_ = vaGetDisplayDRM(drm_file_.GetPlatformFile());
325 #endif // USE_X11 333 #endif // USE_X11
326 334
327 if (!vaDisplayIsValid(va_display_)) { 335 if (!va_display_state) {
328 LOG(ERROR) << "Could not get a valid VA display"; 336 LOG(ERROR) << "Failed to allocate VA display state";
329 return false; 337 return false;
330 } 338 }
331 339
332 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); 340 VAStatus va_res = VA_STATUS_SUCCESS;
333 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); 341 if (!va_display_state->Initialize(&va_res)) {
334 va_initialized_ = true; 342 VA_LOG_ON_ERROR(va_res, "vaInitialize failed");
335 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_;
336
337 if (VAAPIVersionLessThan(0, 34)) {
338 LOG(ERROR) << "VAAPI version < 0.34 is not supported.";
339 return false; 343 return false;
340 } 344 }
345
346 va_display_ = va_display_state->GetVADisplay();
341 return true; 347 return true;
342 } 348 }
343 349
344 bool VaapiWrapper::GetSupportedVaProfiles(std::vector<VAProfile>* profiles) { 350 bool VaapiWrapper::GetSupportedVaProfiles(std::vector<VAProfile>* profiles) {
345 base::AutoLock auto_lock(va_lock_); 351 base::AutoLock auto_lock(*va_lock_);
346 // Query the driver for supported profiles. 352 // Query the driver for supported profiles.
347 int max_profiles = vaMaxNumProfiles(va_display_); 353 int max_profiles = vaMaxNumProfiles(va_display_);
348 std::vector<VAProfile> supported_profiles( 354 std::vector<VAProfile> supported_profiles(
349 base::checked_cast<size_t>(max_profiles)); 355 base::checked_cast<size_t>(max_profiles));
350 356
351 int num_supported_profiles; 357 int num_supported_profiles;
352 VAStatus va_res = vaQueryConfigProfiles( 358 VAStatus va_res = vaQueryConfigProfiles(
353 va_display_, &supported_profiles[0], &num_supported_profiles); 359 va_display_, &supported_profiles[0], &num_supported_profiles);
354 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); 360 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false);
355 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { 361 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) {
356 LOG(ERROR) << "vaQueryConfigProfiles returned: " << num_supported_profiles; 362 LOG(ERROR) << "vaQueryConfigProfiles returned: " << num_supported_profiles;
357 return false; 363 return false;
358 } 364 }
359 365
360 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); 366 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles));
361 *profiles = supported_profiles; 367 *profiles = supported_profiles;
362 return true; 368 return true;
363 } 369 }
364 370
365 bool VaapiWrapper::IsEntrypointSupported_Locked(VAProfile va_profile, 371 bool VaapiWrapper::IsEntrypointSupported_Locked(VAProfile va_profile,
366 VAEntrypoint entrypoint) { 372 VAEntrypoint entrypoint) {
367 va_lock_.AssertAcquired(); 373 va_lock_->AssertAcquired();
368 // Query the driver for supported entrypoints. 374 // Query the driver for supported entrypoints.
369 int max_entrypoints = vaMaxNumEntrypoints(va_display_); 375 int max_entrypoints = vaMaxNumEntrypoints(va_display_);
370 std::vector<VAEntrypoint> supported_entrypoints( 376 std::vector<VAEntrypoint> supported_entrypoints(
371 base::checked_cast<size_t>(max_entrypoints)); 377 base::checked_cast<size_t>(max_entrypoints));
372 378
373 int num_supported_entrypoints; 379 int num_supported_entrypoints;
374 VAStatus va_res = vaQueryConfigEntrypoints(va_display_, 380 VAStatus va_res = vaQueryConfigEntrypoints(va_display_,
375 va_profile, 381 va_profile,
376 &supported_entrypoints[0], 382 &supported_entrypoints[0],
377 &num_supported_entrypoints); 383 &num_supported_entrypoints);
(...skipping 11 matching lines...) Expand all
389 DVLOG(1) << "Unsupported entrypoint"; 395 DVLOG(1) << "Unsupported entrypoint";
390 return false; 396 return false;
391 } 397 }
392 return true; 398 return true;
393 } 399 }
394 400
395 bool VaapiWrapper::AreAttribsSupported_Locked( 401 bool VaapiWrapper::AreAttribsSupported_Locked(
396 VAProfile va_profile, 402 VAProfile va_profile,
397 VAEntrypoint entrypoint, 403 VAEntrypoint entrypoint,
398 const std::vector<VAConfigAttrib>& required_attribs) { 404 const std::vector<VAConfigAttrib>& required_attribs) {
399 va_lock_.AssertAcquired(); 405 va_lock_->AssertAcquired();
400 // Query the driver for required attributes. 406 // Query the driver for required attributes.
401 std::vector<VAConfigAttrib> attribs = required_attribs; 407 std::vector<VAConfigAttrib> attribs = required_attribs;
402 for (size_t i = 0; i < required_attribs.size(); ++i) 408 for (size_t i = 0; i < required_attribs.size(); ++i)
403 attribs[i].value = 0; 409 attribs[i].value = 0;
404 410
405 VAStatus va_res = vaGetConfigAttributes( 411 VAStatus va_res = vaGetConfigAttributes(
406 va_display_, va_profile, entrypoint, &attribs[0], attribs.size()); 412 va_display_, va_profile, entrypoint, &attribs[0], attribs.size());
407 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false); 413 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false);
408 414
409 for (size_t i = 0; i < required_attribs.size(); ++i) { 415 for (size_t i = 0; i < required_attribs.size(); ++i) {
410 if (attribs[i].type != required_attribs[i].type || 416 if (attribs[i].type != required_attribs[i].type ||
411 (attribs[i].value & required_attribs[i].value) != 417 (attribs[i].value & required_attribs[i].value) !=
412 required_attribs[i].value) { 418 required_attribs[i].value) {
413 DVLOG(1) << "Unsupported value " << required_attribs[i].value 419 DVLOG(1) << "Unsupported value " << required_attribs[i].value
414 << " for attribute type " << required_attribs[i].type; 420 << " for attribute type " << required_attribs[i].type;
415 return false; 421 return false;
416 } 422 }
417 } 423 }
418 return true; 424 return true;
419 } 425 }
420 426
421 bool VaapiWrapper::GetMaxResolution_Locked( 427 bool VaapiWrapper::GetMaxResolution_Locked(
422 VAProfile va_profile, 428 VAProfile va_profile,
423 VAEntrypoint entrypoint, 429 VAEntrypoint entrypoint,
424 std::vector<VAConfigAttrib>& required_attribs, 430 std::vector<VAConfigAttrib>& required_attribs,
425 gfx::Size* resolution) { 431 gfx::Size* resolution) {
426 va_lock_.AssertAcquired(); 432 va_lock_->AssertAcquired();
427 VAConfigID va_config_id; 433 VAConfigID va_config_id;
428 VAStatus va_res = vaCreateConfig( 434 VAStatus va_res = vaCreateConfig(
429 va_display_, 435 va_display_,
430 va_profile, 436 va_profile,
431 entrypoint, 437 entrypoint,
432 &required_attribs[0], 438 &required_attribs[0],
433 required_attribs.size(), 439 required_attribs.size(),
434 &va_config_id); 440 &va_config_id);
435 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false); 441 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false);
436 442
(...skipping 28 matching lines...) Expand all
465 } 471 }
466 return true; 472 return true;
467 } 473 }
468 474
469 bool VaapiWrapper::Initialize(CodecMode mode, VAProfile va_profile) { 475 bool VaapiWrapper::Initialize(CodecMode mode, VAProfile va_profile) {
470 TryToSetVADisplayAttributeToLocalGPU(); 476 TryToSetVADisplayAttributeToLocalGPU();
471 477
472 VAEntrypoint entrypoint = 478 VAEntrypoint entrypoint =
473 (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD); 479 (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD);
474 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode); 480 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode);
475 base::AutoLock auto_lock(va_lock_); 481 base::AutoLock auto_lock(*va_lock_);
476 VAStatus va_res = vaCreateConfig(va_display_, 482 VAStatus va_res = vaCreateConfig(va_display_,
477 va_profile, 483 va_profile,
478 entrypoint, 484 entrypoint,
479 &required_attribs[0], 485 &required_attribs[0],
480 required_attribs.size(), 486 required_attribs.size(),
481 &va_config_id_); 487 &va_config_id_);
482 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false); 488 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false);
483 489
484 return true; 490 return true;
485 } 491 }
486 492
487 void VaapiWrapper::Deinitialize() { 493 void VaapiWrapper::Deinitialize() {
488 base::AutoLock auto_lock(va_lock_); 494 base::AutoLock auto_lock(*va_lock_);
489 495
490 if (va_config_id_ != VA_INVALID_ID) { 496 if (va_config_id_ != VA_INVALID_ID) {
491 VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_); 497 VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_);
492 VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed"); 498 VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed");
493 } 499 }
494 500
495 // Must check if vaInitialize completed successfully, to work around a bug in 501 VADisplayState* va_display_state = nullptr;
496 // libva. The bug was fixed upstream: 502
497 // http://lists.freedesktop.org/archives/libva/2013-July/001807.html 503 #if defined(USE_X11)
498 // TODO(mgiuca): Remove this check, and the |va_initialized_| variable, once 504 va_display_state = va_display_state_.get();
499 // the fix has rolled out sufficiently. 505 #elif defined(USE_OZONE)
500 if (va_initialized_ && va_display_) { 506 va_display_state = &g_va_display_state_.Get();
501 VAStatus va_res = vaTerminate(va_display_); 507 #endif // USE_X11
508
509 if (va_display_state) {
510 VAStatus va_res = VA_STATUS_SUCCESS;
511 va_display_state->Deinitialize(&va_res);
502 VA_LOG_ON_ERROR(va_res, "vaTerminate failed"); 512 VA_LOG_ON_ERROR(va_res, "vaTerminate failed");
503 } 513 }
504 514
505 va_config_id_ = VA_INVALID_ID; 515 va_config_id_ = VA_INVALID_ID;
506 va_display_ = NULL; 516 va_display_ = NULL;
507 va_initialized_ = false;
508 }
509
510 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) {
511 return (major_version_ < major) ||
512 (major_version_ == major && minor_version_ < minor);
513 } 517 }
514 518
515 bool VaapiWrapper::CreateSurfaces(const gfx::Size& size, 519 bool VaapiWrapper::CreateSurfaces(const gfx::Size& size,
516 size_t num_surfaces, 520 size_t num_surfaces,
517 std::vector<VASurfaceID>* va_surfaces) { 521 std::vector<VASurfaceID>* va_surfaces) {
518 base::AutoLock auto_lock(va_lock_); 522 base::AutoLock auto_lock(*va_lock_);
519 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; 523 DVLOG(2) << "Creating " << num_surfaces << " surfaces";
520 524
521 DCHECK(va_surfaces->empty()); 525 DCHECK(va_surfaces->empty());
522 DCHECK(va_surface_ids_.empty()); 526 DCHECK(va_surface_ids_.empty());
523 va_surface_ids_.resize(num_surfaces); 527 va_surface_ids_.resize(num_surfaces);
524 528
525 // Allocate surfaces in driver. 529 // Allocate surfaces in driver.
526 VAStatus va_res = vaCreateSurfaces(va_display_, 530 VAStatus va_res = vaCreateSurfaces(va_display_,
527 VA_RT_FORMAT_YUV420, 531 VA_RT_FORMAT_YUV420,
528 size.width(), size.height(), 532 size.width(), size.height(),
(...skipping 17 matching lines...) Expand all
546 if (va_res != VA_STATUS_SUCCESS) { 550 if (va_res != VA_STATUS_SUCCESS) {
547 DestroySurfaces(); 551 DestroySurfaces();
548 return false; 552 return false;
549 } 553 }
550 554
551 *va_surfaces = va_surface_ids_; 555 *va_surfaces = va_surface_ids_;
552 return true; 556 return true;
553 } 557 }
554 558
555 void VaapiWrapper::DestroySurfaces() { 559 void VaapiWrapper::DestroySurfaces() {
556 base::AutoLock auto_lock(va_lock_); 560 base::AutoLock auto_lock(*va_lock_);
557 DVLOG(2) << "Destroying " << va_surface_ids_.size() << " surfaces"; 561 DVLOG(2) << "Destroying " << va_surface_ids_.size() << " surfaces";
558 562
559 if (va_context_id_ != VA_INVALID_ID) { 563 if (va_context_id_ != VA_INVALID_ID) {
560 VAStatus va_res = vaDestroyContext(va_display_, va_context_id_); 564 VAStatus va_res = vaDestroyContext(va_display_, va_context_id_);
561 VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed"); 565 VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed");
562 } 566 }
563 567
564 if (!va_surface_ids_.empty()) { 568 if (!va_surface_ids_.empty()) {
565 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], 569 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0],
566 va_surface_ids_.size()); 570 va_surface_ids_.size());
567 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); 571 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed");
568 } 572 }
569 573
570 va_surface_ids_.clear(); 574 va_surface_ids_.clear();
571 va_context_id_ = VA_INVALID_ID; 575 va_context_id_ = VA_INVALID_ID;
572 } 576 }
573 577
574 scoped_refptr<VASurface> VaapiWrapper::CreateUnownedSurface( 578 scoped_refptr<VASurface> VaapiWrapper::CreateUnownedSurface(
575 unsigned int va_format, 579 unsigned int va_format,
576 const gfx::Size& size, 580 const gfx::Size& size,
577 const std::vector<VASurfaceAttrib>& va_attribs) { 581 const std::vector<VASurfaceAttrib>& va_attribs) {
578 base::AutoLock auto_lock(va_lock_); 582 base::AutoLock auto_lock(*va_lock_);
579 583
580 std::vector<VASurfaceAttrib> attribs(va_attribs); 584 std::vector<VASurfaceAttrib> attribs(va_attribs);
581 VASurfaceID va_surface_id; 585 VASurfaceID va_surface_id;
582 VAStatus va_res = 586 VAStatus va_res =
583 vaCreateSurfaces(va_display_, va_format, size.width(), size.height(), 587 vaCreateSurfaces(va_display_, va_format, size.width(), size.height(),
584 &va_surface_id, 1, &attribs[0], attribs.size()); 588 &va_surface_id, 1, &attribs[0], attribs.size());
585 589
586 scoped_refptr<VASurface> va_surface; 590 scoped_refptr<VASurface> va_surface;
587 VA_SUCCESS_OR_RETURN(va_res, "Failed to create unowned VASurface", 591 VA_SUCCESS_OR_RETURN(va_res, "Failed to create unowned VASurface",
588 va_surface); 592 va_surface);
589 593
590 // This is safe to use Unretained() here, because the VDA takes care 594 // This is safe to use Unretained() here, because the VDA takes care
591 // of the destruction order. All the surfaces will be destroyed 595 // of the destruction order. All the surfaces will be destroyed
592 // before VaapiWrapper. 596 // before VaapiWrapper.
593 va_surface = new VASurface( 597 va_surface = new VASurface(
594 va_surface_id, size, 598 va_surface_id, size,
595 base::Bind(&VaapiWrapper::DestroyUnownedSurface, base::Unretained(this))); 599 base::Bind(&VaapiWrapper::DestroyUnownedSurface, base::Unretained(this)));
596 600
597 return va_surface; 601 return va_surface;
598 } 602 }
599 603
600 void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface_id) { 604 void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface_id) {
601 base::AutoLock auto_lock(va_lock_); 605 base::AutoLock auto_lock(*va_lock_);
602 606
603 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_id, 1); 607 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_id, 1);
604 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on surface failed"); 608 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on surface failed");
605 } 609 }
606 610
607 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, 611 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type,
608 size_t size, 612 size_t size,
609 void* buffer) { 613 void* buffer) {
610 base::AutoLock auto_lock(va_lock_); 614 base::AutoLock auto_lock(*va_lock_);
611 615
612 VABufferID buffer_id; 616 VABufferID buffer_id;
613 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, 617 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_,
614 va_buffer_type, size, 618 va_buffer_type, size,
615 1, buffer, &buffer_id); 619 1, buffer, &buffer_id);
616 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); 620 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false);
617 621
618 switch (va_buffer_type) { 622 switch (va_buffer_type) {
619 case VASliceParameterBufferType: 623 case VASliceParameterBufferType:
620 case VASliceDataBufferType: 624 case VASliceDataBufferType:
621 case VAEncSliceParameterBufferType: 625 case VAEncSliceParameterBufferType:
622 pending_slice_bufs_.push_back(buffer_id); 626 pending_slice_bufs_.push_back(buffer_id);
623 break; 627 break;
624 628
625 default: 629 default:
626 pending_va_bufs_.push_back(buffer_id); 630 pending_va_bufs_.push_back(buffer_id);
627 break; 631 break;
628 } 632 }
629 633
630 return true; 634 return true;
631 } 635 }
632 636
633 bool VaapiWrapper::SubmitVAEncMiscParamBuffer( 637 bool VaapiWrapper::SubmitVAEncMiscParamBuffer(
634 VAEncMiscParameterType misc_param_type, 638 VAEncMiscParameterType misc_param_type,
635 size_t size, 639 size_t size,
636 void* buffer) { 640 void* buffer) {
637 base::AutoLock auto_lock(va_lock_); 641 base::AutoLock auto_lock(*va_lock_);
638 642
639 VABufferID buffer_id; 643 VABufferID buffer_id;
640 VAStatus va_res = vaCreateBuffer(va_display_, 644 VAStatus va_res = vaCreateBuffer(va_display_,
641 va_context_id_, 645 va_context_id_,
642 VAEncMiscParameterBufferType, 646 VAEncMiscParameterBufferType,
643 sizeof(VAEncMiscParameterBuffer) + size, 647 sizeof(VAEncMiscParameterBuffer) + size,
644 1, 648 1,
645 NULL, 649 NULL,
646 &buffer_id); 650 &buffer_id);
647 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); 651 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false);
(...skipping 13 matching lines...) Expand all
661 misc_param->type = misc_param_type; 665 misc_param->type = misc_param_type;
662 memcpy(misc_param->data, buffer, size); 666 memcpy(misc_param->data, buffer, size);
663 va_res = vaUnmapBuffer(va_display_, buffer_id); 667 va_res = vaUnmapBuffer(va_display_, buffer_id);
664 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); 668 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
665 669
666 pending_va_bufs_.push_back(buffer_id); 670 pending_va_bufs_.push_back(buffer_id);
667 return true; 671 return true;
668 } 672 }
669 673
670 void VaapiWrapper::DestroyPendingBuffers() { 674 void VaapiWrapper::DestroyPendingBuffers() {
671 base::AutoLock auto_lock(va_lock_); 675 base::AutoLock auto_lock(*va_lock_);
672 676
673 for (const auto& pending_va_buf : pending_va_bufs_) { 677 for (const auto& pending_va_buf : pending_va_bufs_) {
674 VAStatus va_res = vaDestroyBuffer(va_display_, pending_va_buf); 678 VAStatus va_res = vaDestroyBuffer(va_display_, pending_va_buf);
675 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); 679 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
676 } 680 }
677 681
678 for (const auto& pending_slice_buf : pending_slice_bufs_) { 682 for (const auto& pending_slice_buf : pending_slice_bufs_) {
679 VAStatus va_res = vaDestroyBuffer(va_display_, pending_slice_buf); 683 VAStatus va_res = vaDestroyBuffer(va_display_, pending_slice_buf);
680 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); 684 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
681 } 685 }
682 686
683 pending_va_bufs_.clear(); 687 pending_va_bufs_.clear();
684 pending_slice_bufs_.clear(); 688 pending_slice_bufs_.clear();
685 } 689 }
686 690
687 bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) { 691 bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) {
688 base::AutoLock auto_lock(va_lock_); 692 base::AutoLock auto_lock(*va_lock_);
689 VAStatus va_res = vaCreateBuffer(va_display_, 693 VAStatus va_res = vaCreateBuffer(va_display_,
690 va_context_id_, 694 va_context_id_,
691 VAEncCodedBufferType, 695 VAEncCodedBufferType,
692 size, 696 size,
693 1, 697 1,
694 NULL, 698 NULL,
695 buffer_id); 699 buffer_id);
696 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a coded buffer", false); 700 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a coded buffer", false);
697 701
698 DCHECK(coded_buffers_.insert(*buffer_id).second); 702 DCHECK(coded_buffers_.insert(*buffer_id).second);
699 return true; 703 return true;
700 } 704 }
701 705
702 void VaapiWrapper::DestroyCodedBuffers() { 706 void VaapiWrapper::DestroyCodedBuffers() {
703 base::AutoLock auto_lock(va_lock_); 707 base::AutoLock auto_lock(*va_lock_);
704 708
705 for (std::set<VABufferID>::const_iterator iter = coded_buffers_.begin(); 709 for (std::set<VABufferID>::const_iterator iter = coded_buffers_.begin();
706 iter != coded_buffers_.end(); 710 iter != coded_buffers_.end();
707 ++iter) { 711 ++iter) {
708 VAStatus va_res = vaDestroyBuffer(va_display_, *iter); 712 VAStatus va_res = vaDestroyBuffer(va_display_, *iter);
709 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); 713 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
710 } 714 }
711 715
712 coded_buffers_.clear(); 716 coded_buffers_.clear();
713 } 717 }
714 718
715 bool VaapiWrapper::Execute(VASurfaceID va_surface_id) { 719 bool VaapiWrapper::Execute(VASurfaceID va_surface_id) {
716 base::AutoLock auto_lock(va_lock_); 720 base::AutoLock auto_lock(*va_lock_);
717 721
718 DVLOG(4) << "Pending VA bufs to commit: " << pending_va_bufs_.size(); 722 DVLOG(4) << "Pending VA bufs to commit: " << pending_va_bufs_.size();
719 DVLOG(4) << "Pending slice bufs to commit: " << pending_slice_bufs_.size(); 723 DVLOG(4) << "Pending slice bufs to commit: " << pending_slice_bufs_.size();
720 DVLOG(4) << "Target VA surface " << va_surface_id; 724 DVLOG(4) << "Target VA surface " << va_surface_id;
721 725
722 // Get ready to execute for given surface. 726 // Get ready to execute for given surface.
723 VAStatus va_res = vaBeginPicture(va_display_, va_context_id_, 727 VAStatus va_res = vaBeginPicture(va_display_, va_context_id_,
724 va_surface_id); 728 va_surface_id);
725 VA_SUCCESS_OR_RETURN(va_res, "vaBeginPicture failed", false); 729 VA_SUCCESS_OR_RETURN(va_res, "vaBeginPicture failed", false);
726 730
(...skipping 25 matching lines...) Expand all
752 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { 756 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) {
753 bool result = Execute(va_surface_id); 757 bool result = Execute(va_surface_id);
754 DestroyPendingBuffers(); 758 DestroyPendingBuffers();
755 return result; 759 return result;
756 } 760 }
757 761
758 #if defined(USE_X11) 762 #if defined(USE_X11)
759 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, 763 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id,
760 Pixmap x_pixmap, 764 Pixmap x_pixmap,
761 gfx::Size dest_size) { 765 gfx::Size dest_size) {
762 base::AutoLock auto_lock(va_lock_); 766 base::AutoLock auto_lock(*va_lock_);
763 767
764 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); 768 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
765 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); 769 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
766 770
767 // Put the data into an X Pixmap. 771 // Put the data into an X Pixmap.
768 va_res = vaPutSurface(va_display_, 772 va_res = vaPutSurface(va_display_,
769 va_surface_id, 773 va_surface_id,
770 x_pixmap, 774 x_pixmap,
771 0, 0, dest_size.width(), dest_size.height(), 775 0, 0, dest_size.width(), dest_size.height(),
772 0, 0, dest_size.width(), dest_size.height(), 776 0, 0, dest_size.width(), dest_size.height(),
773 NULL, 0, 0); 777 NULL, 0, 0);
774 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); 778 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false);
775 return true; 779 return true;
776 } 780 }
777 #endif // USE_X11 781 #endif // USE_X11
778 782
779 bool VaapiWrapper::GetDerivedVaImage(VASurfaceID va_surface_id, 783 bool VaapiWrapper::GetDerivedVaImage(VASurfaceID va_surface_id,
780 VAImage* image, 784 VAImage* image,
781 void** mem) { 785 void** mem) {
782 base::AutoLock auto_lock(va_lock_); 786 base::AutoLock auto_lock(*va_lock_);
783 787
784 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); 788 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
785 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); 789 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
786 790
787 // Derive a VAImage from the VASurface 791 // Derive a VAImage from the VASurface
788 va_res = vaDeriveImage(va_display_, va_surface_id, image); 792 va_res = vaDeriveImage(va_display_, va_surface_id, image);
789 VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed"); 793 VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed");
790 if (va_res != VA_STATUS_SUCCESS) 794 if (va_res != VA_STATUS_SUCCESS)
791 return false; 795 return false;
792 796
793 // Map the VAImage into memory 797 // Map the VAImage into memory
794 va_res = vaMapBuffer(va_display_, image->buf, mem); 798 va_res = vaMapBuffer(va_display_, image->buf, mem);
795 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); 799 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed");
796 if (va_res == VA_STATUS_SUCCESS) 800 if (va_res == VA_STATUS_SUCCESS)
797 return true; 801 return true;
798 802
799 va_res = vaDestroyImage(va_display_, image->image_id); 803 va_res = vaDestroyImage(va_display_, image->image_id);
800 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed"); 804 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed");
801 805
802 return false; 806 return false;
803 } 807 }
804 808
805 bool VaapiWrapper::GetVaImage(VASurfaceID va_surface_id, 809 bool VaapiWrapper::GetVaImage(VASurfaceID va_surface_id,
806 VAImageFormat* format, 810 VAImageFormat* format,
807 const gfx::Size& size, 811 const gfx::Size& size,
808 VAImage* image, 812 VAImage* image,
809 void** mem) { 813 void** mem) {
810 base::AutoLock auto_lock(va_lock_); 814 base::AutoLock auto_lock(*va_lock_);
811 815
812 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); 816 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
813 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); 817 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
814 818
815 va_res = 819 va_res =
816 vaCreateImage(va_display_, format, size.width(), size.height(), image); 820 vaCreateImage(va_display_, format, size.width(), size.height(), image);
817 VA_SUCCESS_OR_RETURN(va_res, "vaCreateImage failed", false); 821 VA_SUCCESS_OR_RETURN(va_res, "vaCreateImage failed", false);
818 822
819 va_res = vaGetImage(va_display_, va_surface_id, 0, 0, size.width(), 823 va_res = vaGetImage(va_display_, va_surface_id, 0, 0, size.width(),
820 size.height(), image->image_id); 824 size.height(), image->image_id);
821 VA_LOG_ON_ERROR(va_res, "vaGetImage failed"); 825 VA_LOG_ON_ERROR(va_res, "vaGetImage failed");
822 826
823 if (va_res == VA_STATUS_SUCCESS) { 827 if (va_res == VA_STATUS_SUCCESS) {
824 // Map the VAImage into memory 828 // Map the VAImage into memory
825 va_res = vaMapBuffer(va_display_, image->buf, mem); 829 va_res = vaMapBuffer(va_display_, image->buf, mem);
826 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); 830 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed");
827 } 831 }
828 832
829 if (va_res != VA_STATUS_SUCCESS) { 833 if (va_res != VA_STATUS_SUCCESS) {
830 va_res = vaDestroyImage(va_display_, image->image_id); 834 va_res = vaDestroyImage(va_display_, image->image_id);
831 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed"); 835 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed");
832 return false; 836 return false;
833 } 837 }
834 838
835 return true; 839 return true;
836 } 840 }
837 841
838 void VaapiWrapper::ReturnVaImage(VAImage* image) { 842 void VaapiWrapper::ReturnVaImage(VAImage* image) {
839 base::AutoLock auto_lock(va_lock_); 843 base::AutoLock auto_lock(*va_lock_);
840 844
841 VAStatus va_res = vaUnmapBuffer(va_display_, image->buf); 845 VAStatus va_res = vaUnmapBuffer(va_display_, image->buf);
842 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); 846 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
843 847
844 va_res = vaDestroyImage(va_display_, image->image_id); 848 va_res = vaDestroyImage(va_display_, image->image_id);
845 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed"); 849 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed");
846 } 850 }
847 851
848 static void DestroyVAImage(VADisplay va_display, VAImage image) { 852 static void DestroyVAImage(VADisplay va_display, VAImage image) {
849 if (image.image_id != VA_INVALID_ID) 853 if (image.image_id != VA_INVALID_ID)
850 vaDestroyImage(va_display, image.image_id); 854 vaDestroyImage(va_display, image.image_id);
851 } 855 }
852 856
853 bool VaapiWrapper::UploadVideoFrameToSurface( 857 bool VaapiWrapper::UploadVideoFrameToSurface(
854 const scoped_refptr<media::VideoFrame>& frame, 858 const scoped_refptr<media::VideoFrame>& frame,
855 VASurfaceID va_surface_id) { 859 VASurfaceID va_surface_id) {
856 base::AutoLock auto_lock(va_lock_); 860 base::AutoLock auto_lock(*va_lock_);
857 861
858 VAImage image; 862 VAImage image;
859 VAStatus va_res = vaDeriveImage(va_display_, va_surface_id, &image); 863 VAStatus va_res = vaDeriveImage(va_display_, va_surface_id, &image);
860 VA_SUCCESS_OR_RETURN(va_res, "vaDeriveImage failed", false); 864 VA_SUCCESS_OR_RETURN(va_res, "vaDeriveImage failed", false);
861 base::ScopedClosureRunner vaimage_deleter( 865 base::ScopedClosureRunner vaimage_deleter(
862 base::Bind(&DestroyVAImage, va_display_, image)); 866 base::Bind(&DestroyVAImage, va_display_, image));
863 867
864 if (image.format.fourcc != VA_FOURCC_NV12) { 868 if (image.format.fourcc != VA_FOURCC_NV12) {
865 LOG(ERROR) << "Unsupported image format: " << image.format.fourcc; 869 LOG(ERROR) << "Unsupported image format: " << image.format.fourcc;
866 return false; 870 return false;
867 } 871 }
868 872
869 if (gfx::Rect(image.width, image.height) < gfx::Rect(frame->coded_size())) { 873 if (gfx::Rect(image.width, image.height) < gfx::Rect(frame->coded_size())) {
870 LOG(ERROR) << "Buffer too small to fit the frame."; 874 LOG(ERROR) << "Buffer too small to fit the frame.";
871 return false; 875 return false;
872 } 876 }
873 877
874 void* image_ptr = NULL; 878 void* image_ptr = NULL;
875 va_res = vaMapBuffer(va_display_, image.buf, &image_ptr); 879 va_res = vaMapBuffer(va_display_, image.buf, &image_ptr);
876 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false); 880 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false);
877 DCHECK(image_ptr); 881 DCHECK(image_ptr);
878 882
879 int ret = 0; 883 int ret = 0;
880 { 884 {
881 base::AutoUnlock auto_unlock(va_lock_); 885 base::AutoUnlock auto_unlock(*va_lock_);
882 ret = libyuv::I420ToNV12(frame->data(media::VideoFrame::kYPlane), 886 ret = libyuv::I420ToNV12(frame->data(media::VideoFrame::kYPlane),
883 frame->stride(media::VideoFrame::kYPlane), 887 frame->stride(media::VideoFrame::kYPlane),
884 frame->data(media::VideoFrame::kUPlane), 888 frame->data(media::VideoFrame::kUPlane),
885 frame->stride(media::VideoFrame::kUPlane), 889 frame->stride(media::VideoFrame::kUPlane),
886 frame->data(media::VideoFrame::kVPlane), 890 frame->data(media::VideoFrame::kVPlane),
887 frame->stride(media::VideoFrame::kVPlane), 891 frame->stride(media::VideoFrame::kVPlane),
888 static_cast<uint8*>(image_ptr) + image.offsets[0], 892 static_cast<uint8*>(image_ptr) + image.offsets[0],
889 image.pitches[0], 893 image.pitches[0],
890 static_cast<uint8*>(image_ptr) + image.offsets[1], 894 static_cast<uint8*>(image_ptr) + image.offsets[1],
891 image.pitches[1], 895 image.pitches[1],
892 image.width, 896 image.width,
893 image.height); 897 image.height);
894 } 898 }
895 899
896 va_res = vaUnmapBuffer(va_display_, image.buf); 900 va_res = vaUnmapBuffer(va_display_, image.buf);
897 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); 901 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
898 902
899 return ret == 0; 903 return ret == 0;
900 } 904 }
901 905
902 bool VaapiWrapper::DownloadAndDestroyCodedBuffer(VABufferID buffer_id, 906 bool VaapiWrapper::DownloadAndDestroyCodedBuffer(VABufferID buffer_id,
903 VASurfaceID sync_surface_id, 907 VASurfaceID sync_surface_id,
904 uint8* target_ptr, 908 uint8* target_ptr,
905 size_t target_size, 909 size_t target_size,
906 size_t* coded_data_size) { 910 size_t* coded_data_size) {
907 base::AutoLock auto_lock(va_lock_); 911 base::AutoLock auto_lock(*va_lock_);
908 912
909 VAStatus va_res = vaSyncSurface(va_display_, sync_surface_id); 913 VAStatus va_res = vaSyncSurface(va_display_, sync_surface_id);
910 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); 914 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
911 915
912 VACodedBufferSegment* buffer_segment = NULL; 916 VACodedBufferSegment* buffer_segment = NULL;
913 va_res = vaMapBuffer( 917 va_res = vaMapBuffer(
914 va_display_, buffer_id, reinterpret_cast<void**>(&buffer_segment)); 918 va_display_, buffer_id, reinterpret_cast<void**>(&buffer_segment));
915 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false); 919 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false);
916 DCHECK(target_ptr); 920 DCHECK(target_ptr);
917 921
918 { 922 {
919 base::AutoUnlock auto_unlock(va_lock_); 923 base::AutoUnlock auto_unlock(*va_lock_);
920 *coded_data_size = 0; 924 *coded_data_size = 0;
921 925
922 while (buffer_segment) { 926 while (buffer_segment) {
923 DCHECK(buffer_segment->buf); 927 DCHECK(buffer_segment->buf);
924 928
925 if (buffer_segment->size > target_size) { 929 if (buffer_segment->size > target_size) {
926 LOG(ERROR) << "Insufficient output buffer size"; 930 LOG(ERROR) << "Insufficient output buffer size";
927 break; 931 break;
928 } 932 }
929 933
(...skipping 16 matching lines...) Expand all
946 950
947 DCHECK(coded_buffers_.erase(buffer_id)); 951 DCHECK(coded_buffers_.erase(buffer_id));
948 952
949 return buffer_segment == NULL; 953 return buffer_segment == NULL;
950 } 954 }
951 955
952 bool VaapiWrapper::BlitSurface(VASurfaceID va_surface_id_src, 956 bool VaapiWrapper::BlitSurface(VASurfaceID va_surface_id_src,
953 const gfx::Size& src_size, 957 const gfx::Size& src_size,
954 VASurfaceID va_surface_id_dest, 958 VASurfaceID va_surface_id_dest,
955 const gfx::Size& dest_size) { 959 const gfx::Size& dest_size) {
956 base::AutoLock auto_lock(va_lock_); 960 base::AutoLock auto_lock(*va_lock_);
957 961
958 // Initialize the post processing engine if not already done. 962 // Initialize the post processing engine if not already done.
959 if (va_vpp_buffer_id_ == VA_INVALID_ID) { 963 if (va_vpp_buffer_id_ == VA_INVALID_ID) {
960 if (!InitializeVpp_Locked()) 964 if (!InitializeVpp_Locked())
961 return false; 965 return false;
962 } 966 }
963 967
964 VAProcPipelineParameterBuffer* pipeline_param; 968 VAProcPipelineParameterBuffer* pipeline_param;
965 VA_SUCCESS_OR_RETURN(vaMapBuffer(va_display_, va_vpp_buffer_id_, 969 VA_SUCCESS_OR_RETURN(vaMapBuffer(va_display_, va_vpp_buffer_id_,
966 reinterpret_cast<void**>(&pipeline_param)), 970 reinterpret_cast<void**>(&pipeline_param)),
(...skipping 28 matching lines...) Expand all
995 vaRenderPicture(va_display_, va_vpp_context_id_, &va_vpp_buffer_id_, 1), 999 vaRenderPicture(va_display_, va_vpp_context_id_, &va_vpp_buffer_id_, 1),
996 "Couldn't render picture", false); 1000 "Couldn't render picture", false);
997 1001
998 VA_SUCCESS_OR_RETURN(vaEndPicture(va_display_, va_vpp_context_id_), 1002 VA_SUCCESS_OR_RETURN(vaEndPicture(va_display_, va_vpp_context_id_),
999 "Couldn't end picture", false); 1003 "Couldn't end picture", false);
1000 1004
1001 return true; 1005 return true;
1002 } 1006 }
1003 1007
1004 bool VaapiWrapper::InitializeVpp_Locked() { 1008 bool VaapiWrapper::InitializeVpp_Locked() {
1005 va_lock_.AssertAcquired(); 1009 va_lock_->AssertAcquired();
1006 1010
1007 VA_SUCCESS_OR_RETURN( 1011 VA_SUCCESS_OR_RETURN(
1008 vaCreateConfig(va_display_, VAProfileNone, VAEntrypointVideoProc, NULL, 0, 1012 vaCreateConfig(va_display_, VAProfileNone, VAEntrypointVideoProc, NULL, 0,
1009 &va_vpp_config_id_), 1013 &va_vpp_config_id_),
1010 "Couldn't create config", false); 1014 "Couldn't create config", false);
1011 1015
1012 // The size of the picture for the context is irrelevant in the case 1016 // The size of the picture for the context is irrelevant in the case
1013 // of the VPP, just passing 1x1. 1017 // of the VPP, just passing 1x1.
1014 VA_SUCCESS_OR_RETURN(vaCreateContext(va_display_, va_vpp_config_id_, 1, 1, 0, 1018 VA_SUCCESS_OR_RETURN(vaCreateContext(va_display_, va_vpp_config_id_, 1, 1, 0,
1015 NULL, 0, &va_vpp_context_id_), 1019 NULL, 0, &va_vpp_context_id_),
1016 "Couldn't create context", false); 1020 "Couldn't create context", false);
1017 1021
1018 VA_SUCCESS_OR_RETURN(vaCreateBuffer(va_display_, va_vpp_context_id_, 1022 VA_SUCCESS_OR_RETURN(vaCreateBuffer(va_display_, va_vpp_context_id_,
1019 VAProcPipelineParameterBufferType, 1023 VAProcPipelineParameterBufferType,
1020 sizeof(VAProcPipelineParameterBuffer), 1, 1024 sizeof(VAProcPipelineParameterBuffer), 1,
1021 NULL, &va_vpp_buffer_id_), 1025 NULL, &va_vpp_buffer_id_),
1022 "Couldn't create buffer", false); 1026 "Couldn't create buffer", false);
1023 1027
1024 return true; 1028 return true;
1025 } 1029 }
1026 1030
1027 void VaapiWrapper::DeinitializeVpp() { 1031 void VaapiWrapper::DeinitializeVpp() {
1028 base::AutoLock auto_lock(va_lock_); 1032 base::AutoLock auto_lock(*va_lock_);
1029 1033
1030 if (va_vpp_buffer_id_ != VA_INVALID_ID) { 1034 if (va_vpp_buffer_id_ != VA_INVALID_ID) {
1031 vaDestroyBuffer(va_display_, va_vpp_buffer_id_); 1035 vaDestroyBuffer(va_display_, va_vpp_buffer_id_);
1032 va_vpp_buffer_id_ = VA_INVALID_ID; 1036 va_vpp_buffer_id_ = VA_INVALID_ID;
1033 } 1037 }
1034 if (va_vpp_context_id_ != VA_INVALID_ID) { 1038 if (va_vpp_context_id_ != VA_INVALID_ID) {
1035 vaDestroyContext(va_display_, va_vpp_context_id_); 1039 vaDestroyContext(va_display_, va_vpp_context_id_);
1036 va_vpp_context_id_ = VA_INVALID_ID; 1040 va_vpp_context_id_ = VA_INVALID_ID;
1037 } 1041 }
1038 if (va_vpp_config_id_ != VA_INVALID_ID) { 1042 if (va_vpp_config_id_ != VA_INVALID_ID) {
1039 vaDestroyConfig(va_display_, va_vpp_config_id_); 1043 vaDestroyConfig(va_display_, va_vpp_config_id_);
1040 va_vpp_config_id_ = VA_INVALID_ID; 1044 va_vpp_config_id_ = VA_INVALID_ID;
1041 } 1045 }
1042 } 1046 }
1043 1047
1044 // static 1048 // static
1049 void VaapiWrapper::PreSandboxInitialization() {
1050 #if defined(USE_OZONE)
1051 const char* kDriRenderNode0Path = "/dev/dri/renderD128";
1052 base::File drm_file = base::File(
1053 base::FilePath::FromUTF8Unsafe(kDriRenderNode0Path),
1054 base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE);
1055 g_va_display_state_.Get().SetDrmFd(drm_file.GetPlatformFile());
1056 #endif
1057 }
1058
1059 // static
1045 bool VaapiWrapper::PostSandboxInitialization() { 1060 bool VaapiWrapper::PostSandboxInitialization() {
1046 StubPathMap paths; 1061 StubPathMap paths;
1047 1062
1048 paths[kModuleVa].push_back("libva.so.1"); 1063 paths[kModuleVa].push_back("libva.so.1");
1049 1064
1050 #if defined(USE_X11) 1065 #if defined(USE_X11)
1051 paths[kModuleVa_x11].push_back("libva-x11.so.1"); 1066 paths[kModuleVa_x11].push_back("libva-x11.so.1");
1052 #elif defined(USE_OZONE) 1067 #elif defined(USE_OZONE)
1053 paths[kModuleVa_drm].push_back("libva-drm.so.1"); 1068 paths[kModuleVa_drm].push_back("libva-drm.so.1");
1054 #endif 1069 #endif
(...skipping 25 matching lines...) Expand all
1080 1095
1081 bool VaapiWrapper::LazyProfileInfos::IsProfileSupported( 1096 bool VaapiWrapper::LazyProfileInfos::IsProfileSupported(
1082 CodecMode mode, VAProfile va_profile) { 1097 CodecMode mode, VAProfile va_profile) {
1083 for (const auto& profile : supported_profiles_[mode]) { 1098 for (const auto& profile : supported_profiles_[mode]) {
1084 if (profile.va_profile == va_profile) 1099 if (profile.va_profile == va_profile)
1085 return true; 1100 return true;
1086 } 1101 }
1087 return false; 1102 return false;
1088 } 1103 }
1089 1104
1105 VaapiWrapper::VADisplayState::VADisplayState()
1106 : refcount_(0),
1107 va_display_(nullptr),
1108 major_version_(-1),
1109 minor_version_(-1),
1110 va_initialized_(false) {}
1111
1112 VaapiWrapper::VADisplayState::~VADisplayState() {}
1113
1114 bool VaapiWrapper::VADisplayState::Initialize(VAStatus* status) {
1115 if (refcount_++ == 0) {
1116 #if defined(USE_X11)
1117 va_display_ = vaGetDisplay(gfx::GetXDisplay());
1118 #elif defined(USE_OZONE)
1119 va_display_ = vaGetDisplayDRM(drm_fd_.get());
1120 #endif // USE_X11
1121
1122 if (!vaDisplayIsValid(va_display_)) {
1123 LOG(ERROR) << "Could not get a valid VA display";
1124 return false;
1125 }
1126
1127 *status = vaInitialize(va_display_, &major_version_, &minor_version_);
1128 if (*status != VA_STATUS_SUCCESS)
1129 return false;
1130
1131 va_initialized_ = true;
1132 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_;
1133 }
1134
1135 if (VAAPIVersionLessThan(0, 34)) {
1136 LOG(ERROR) << "VAAPI version < 0.34 is not supported.";
1137 return false;
1138 }
1139 return true;
1140 }
1141
1142 void VaapiWrapper::VADisplayState::Deinitialize(VAStatus* status) {
1143 if (--refcount_ > 0)
1144 return;
1145
1146 // Must check if vaInitialize completed successfully, to work around a bug in
1147 // libva. The bug was fixed upstream:
1148 // http://lists.freedesktop.org/archives/libva/2013-July/001807.html
1149 // TODO(mgiuca): Remove this check, and the |va_initialized_| variable, once
1150 // the fix has rolled out sufficiently.
1151 if (va_initialized_ && va_display_) {
1152 *status = vaTerminate(va_display_);
1153 }
1154 va_initialized_ = false;
1155 }
1156
1157 #if defined(USE_OZONE)
1158 void VaapiWrapper::VADisplayState::SetDrmFd(base::PlatformFile fd) {
1159 drm_fd_.reset(dup(fd));
piman 2015/05/11 21:54:07 nit: dup needs to be wrapped into a HANDLE_EINTR m
hshi1 2015/05/11 22:26:40 Done.
1160 }
1161 #endif // USE_OZONE
1162
1163 bool VaapiWrapper::VADisplayState::VAAPIVersionLessThan(int major, int minor) {
1164 return (major_version_ < major) ||
1165 (major_version_ == major && minor_version_ < minor);
1166 }
1167
1090 } // namespace content 1168 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698