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

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

Powered by Google App Engine
This is Rietveld 408576698