| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/common/gpu/media/vaapi_wrapper.h" | 5 #include "content/common/gpu/media/vaapi_wrapper.h" |
| 6 | 6 |
| 7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 : va_surface_id_(va_surface_id), | 126 : va_surface_id_(va_surface_id), |
| 127 release_cb_(release_cb) { | 127 release_cb_(release_cb) { |
| 128 DCHECK(!release_cb_.is_null()); | 128 DCHECK(!release_cb_.is_null()); |
| 129 } | 129 } |
| 130 | 130 |
| 131 VASurface::~VASurface() { | 131 VASurface::~VASurface() { |
| 132 release_cb_.Run(va_surface_id_); | 132 release_cb_.Run(va_surface_id_); |
| 133 } | 133 } |
| 134 | 134 |
| 135 VaapiWrapper::VaapiWrapper() | 135 VaapiWrapper::VaapiWrapper() |
| 136 : va_display_(NULL), | 136 : va_display_(nullptr), |
| 137 va_config_id_(VA_INVALID_ID), | 137 va_config_id_(VA_INVALID_ID), |
| 138 va_context_id_(VA_INVALID_ID) { | 138 va_context_id_(VA_INVALID_ID) { |
| 139 } | 139 } |
| 140 | 140 |
| 141 VaapiWrapper::~VaapiWrapper() { | 141 VaapiWrapper::~VaapiWrapper() { |
| 142 DestroyPendingBuffers(); | 142 DestroyPendingBuffers(); |
| 143 DestroyCodedBuffers(); | 143 DestroyCodedBuffers(); |
| 144 DestroySurfaces(); | 144 DestroySurfaces(); |
| 145 Deinitialize(); | 145 Deinitialize(); |
| 146 } | 146 } |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_); | 349 VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_); |
| 350 VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed"); | 350 VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed"); |
| 351 } | 351 } |
| 352 | 352 |
| 353 if (va_display_) { | 353 if (va_display_) { |
| 354 VAStatus va_res = vaTerminate(va_display_); | 354 VAStatus va_res = vaTerminate(va_display_); |
| 355 VA_LOG_ON_ERROR(va_res, "vaTerminate failed"); | 355 VA_LOG_ON_ERROR(va_res, "vaTerminate failed"); |
| 356 } | 356 } |
| 357 | 357 |
| 358 va_config_id_ = VA_INVALID_ID; | 358 va_config_id_ = VA_INVALID_ID; |
| 359 va_display_ = NULL; | 359 va_display_ = nullptr; |
| 360 } | 360 } |
| 361 | 361 |
| 362 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { | 362 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { |
| 363 return (major_version_ < major) || | 363 return (major_version_ < major) || |
| 364 (major_version_ == major && minor_version_ < minor); | 364 (major_version_ == major && minor_version_ < minor); |
| 365 } | 365 } |
| 366 | 366 |
| 367 bool VaapiWrapper::CreateSurfaces(gfx::Size size, | 367 bool VaapiWrapper::CreateSurfaces(gfx::Size size, |
| 368 size_t num_surfaces, | 368 size_t num_surfaces, |
| 369 std::vector<VASurfaceID>* va_surfaces) { | 369 std::vector<VASurfaceID>* va_surfaces) { |
| 370 base::AutoLock auto_lock(va_lock_); | 370 base::AutoLock auto_lock(va_lock_); |
| 371 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; | 371 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; |
| 372 | 372 |
| 373 DCHECK(va_surfaces->empty()); | 373 DCHECK(va_surfaces->empty()); |
| 374 DCHECK(va_surface_ids_.empty()); | 374 DCHECK(va_surface_ids_.empty()); |
| 375 va_surface_ids_.resize(num_surfaces); | 375 va_surface_ids_.resize(num_surfaces); |
| 376 | 376 |
| 377 // Allocate surfaces in driver. | 377 // Allocate surfaces in driver. |
| 378 VAStatus va_res = vaCreateSurfaces(va_display_, | 378 VAStatus va_res = vaCreateSurfaces(va_display_, |
| 379 VA_RT_FORMAT_YUV420, | 379 VA_RT_FORMAT_YUV420, |
| 380 size.width(), size.height(), | 380 size.width(), size.height(), |
| 381 &va_surface_ids_[0], | 381 &va_surface_ids_[0], |
| 382 va_surface_ids_.size(), | 382 va_surface_ids_.size(), |
| 383 NULL, 0); | 383 nullptr, 0); |
| 384 | 384 |
| 385 VA_LOG_ON_ERROR(va_res, "vaCreateSurfaces failed"); | 385 VA_LOG_ON_ERROR(va_res, "vaCreateSurfaces failed"); |
| 386 if (va_res != VA_STATUS_SUCCESS) { | 386 if (va_res != VA_STATUS_SUCCESS) { |
| 387 va_surface_ids_.clear(); | 387 va_surface_ids_.clear(); |
| 388 return false; | 388 return false; |
| 389 } | 389 } |
| 390 | 390 |
| 391 // And create a context associated with them. | 391 // And create a context associated with them. |
| 392 va_res = vaCreateContext(va_display_, va_config_id_, | 392 va_res = vaCreateContext(va_display_, va_config_id_, |
| 393 size.width(), size.height(), VA_PROGRESSIVE, | 393 size.width(), size.height(), VA_PROGRESSIVE, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 size_t size, | 454 size_t size, |
| 455 void* buffer) { | 455 void* buffer) { |
| 456 base::AutoLock auto_lock(va_lock_); | 456 base::AutoLock auto_lock(va_lock_); |
| 457 | 457 |
| 458 VABufferID buffer_id; | 458 VABufferID buffer_id; |
| 459 VAStatus va_res = vaCreateBuffer(va_display_, | 459 VAStatus va_res = vaCreateBuffer(va_display_, |
| 460 va_context_id_, | 460 va_context_id_, |
| 461 VAEncMiscParameterBufferType, | 461 VAEncMiscParameterBufferType, |
| 462 sizeof(VAEncMiscParameterBuffer) + size, | 462 sizeof(VAEncMiscParameterBuffer) + size, |
| 463 1, | 463 1, |
| 464 NULL, | 464 nullptr, |
| 465 &buffer_id); | 465 &buffer_id); |
| 466 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); | 466 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); |
| 467 | 467 |
| 468 void* data_ptr = NULL; | 468 void* data_ptr = nullptr; |
| 469 va_res = vaMapBuffer(va_display_, buffer_id, &data_ptr); | 469 va_res = vaMapBuffer(va_display_, buffer_id, &data_ptr); |
| 470 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); | 470 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); |
| 471 if (va_res != VA_STATUS_SUCCESS) { | 471 if (va_res != VA_STATUS_SUCCESS) { |
| 472 vaDestroyBuffer(va_display_, buffer_id); | 472 vaDestroyBuffer(va_display_, buffer_id); |
| 473 return false; | 473 return false; |
| 474 } | 474 } |
| 475 | 475 |
| 476 DCHECK(data_ptr); | 476 DCHECK(data_ptr); |
| 477 | 477 |
| 478 VAEncMiscParameterBuffer* misc_param = | 478 VAEncMiscParameterBuffer* misc_param = |
| (...skipping 24 matching lines...) Expand all Loading... |
| 503 pending_slice_bufs_.clear(); | 503 pending_slice_bufs_.clear(); |
| 504 } | 504 } |
| 505 | 505 |
| 506 bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) { | 506 bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) { |
| 507 base::AutoLock auto_lock(va_lock_); | 507 base::AutoLock auto_lock(va_lock_); |
| 508 VAStatus va_res = vaCreateBuffer(va_display_, | 508 VAStatus va_res = vaCreateBuffer(va_display_, |
| 509 va_context_id_, | 509 va_context_id_, |
| 510 VAEncCodedBufferType, | 510 VAEncCodedBufferType, |
| 511 size, | 511 size, |
| 512 1, | 512 1, |
| 513 NULL, | 513 nullptr, |
| 514 buffer_id); | 514 buffer_id); |
| 515 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a coded buffer", false); | 515 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a coded buffer", false); |
| 516 | 516 |
| 517 DCHECK(coded_buffers_.insert(*buffer_id).second); | 517 DCHECK(coded_buffers_.insert(*buffer_id).second); |
| 518 return true; | 518 return true; |
| 519 } | 519 } |
| 520 | 520 |
| 521 void VaapiWrapper::DestroyCodedBuffers() { | 521 void VaapiWrapper::DestroyCodedBuffers() { |
| 522 base::AutoLock auto_lock(va_lock_); | 522 base::AutoLock auto_lock(va_lock_); |
| 523 | 523 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 | 581 |
| 582 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | 582 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
| 583 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 583 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
| 584 | 584 |
| 585 // Put the data into an X Pixmap. | 585 // Put the data into an X Pixmap. |
| 586 va_res = vaPutSurface(va_display_, | 586 va_res = vaPutSurface(va_display_, |
| 587 va_surface_id, | 587 va_surface_id, |
| 588 x_pixmap, | 588 x_pixmap, |
| 589 0, 0, dest_size.width(), dest_size.height(), | 589 0, 0, dest_size.width(), dest_size.height(), |
| 590 0, 0, dest_size.width(), dest_size.height(), | 590 0, 0, dest_size.width(), dest_size.height(), |
| 591 NULL, 0, 0); | 591 nullptr, 0, 0); |
| 592 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); | 592 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); |
| 593 return true; | 593 return true; |
| 594 } | 594 } |
| 595 | 595 |
| 596 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, | 596 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, |
| 597 VAImage* image, | 597 VAImage* image, |
| 598 void** mem) { | 598 void** mem) { |
| 599 base::AutoLock auto_lock(va_lock_); | 599 base::AutoLock auto_lock(va_lock_); |
| 600 | 600 |
| 601 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | 601 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 if (image.format.fourcc != VA_FOURCC_NV12) { | 648 if (image.format.fourcc != VA_FOURCC_NV12) { |
| 649 LOG(ERROR) << "Unsupported image format: " << image.format.fourcc; | 649 LOG(ERROR) << "Unsupported image format: " << image.format.fourcc; |
| 650 return false; | 650 return false; |
| 651 } | 651 } |
| 652 | 652 |
| 653 if (gfx::Rect(image.width, image.height) < gfx::Rect(frame->coded_size())) { | 653 if (gfx::Rect(image.width, image.height) < gfx::Rect(frame->coded_size())) { |
| 654 LOG(ERROR) << "Buffer too small to fit the frame."; | 654 LOG(ERROR) << "Buffer too small to fit the frame."; |
| 655 return false; | 655 return false; |
| 656 } | 656 } |
| 657 | 657 |
| 658 void* image_ptr = NULL; | 658 void* image_ptr = nullptr; |
| 659 va_res = vaMapBuffer(va_display_, image.buf, &image_ptr); | 659 va_res = vaMapBuffer(va_display_, image.buf, &image_ptr); |
| 660 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false); | 660 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false); |
| 661 DCHECK(image_ptr); | 661 DCHECK(image_ptr); |
| 662 | 662 |
| 663 int ret = 0; | 663 int ret = 0; |
| 664 { | 664 { |
| 665 base::AutoUnlock auto_unlock(va_lock_); | 665 base::AutoUnlock auto_unlock(va_lock_); |
| 666 ret = libyuv::I420ToNV12(frame->data(media::VideoFrame::kYPlane), | 666 ret = libyuv::I420ToNV12(frame->data(media::VideoFrame::kYPlane), |
| 667 frame->stride(media::VideoFrame::kYPlane), | 667 frame->stride(media::VideoFrame::kYPlane), |
| 668 frame->data(media::VideoFrame::kUPlane), | 668 frame->data(media::VideoFrame::kUPlane), |
| (...skipping 17 matching lines...) Expand all Loading... |
| 686 bool VaapiWrapper::DownloadAndDestroyCodedBuffer(VABufferID buffer_id, | 686 bool VaapiWrapper::DownloadAndDestroyCodedBuffer(VABufferID buffer_id, |
| 687 VASurfaceID sync_surface_id, | 687 VASurfaceID sync_surface_id, |
| 688 uint8* target_ptr, | 688 uint8* target_ptr, |
| 689 size_t target_size, | 689 size_t target_size, |
| 690 size_t* coded_data_size) { | 690 size_t* coded_data_size) { |
| 691 base::AutoLock auto_lock(va_lock_); | 691 base::AutoLock auto_lock(va_lock_); |
| 692 | 692 |
| 693 VAStatus va_res = vaSyncSurface(va_display_, sync_surface_id); | 693 VAStatus va_res = vaSyncSurface(va_display_, sync_surface_id); |
| 694 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 694 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
| 695 | 695 |
| 696 VACodedBufferSegment* buffer_segment = NULL; | 696 VACodedBufferSegment* buffer_segment = nullptr; |
| 697 va_res = vaMapBuffer( | 697 va_res = vaMapBuffer( |
| 698 va_display_, buffer_id, reinterpret_cast<void**>(&buffer_segment)); | 698 va_display_, buffer_id, reinterpret_cast<void**>(&buffer_segment)); |
| 699 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false); | 699 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false); |
| 700 DCHECK(target_ptr); | 700 DCHECK(target_ptr); |
| 701 | 701 |
| 702 { | 702 { |
| 703 base::AutoUnlock auto_unlock(va_lock_); | 703 base::AutoUnlock auto_unlock(va_lock_); |
| 704 *coded_data_size = 0; | 704 *coded_data_size = 0; |
| 705 | 705 |
| 706 while (buffer_segment) { | 706 while (buffer_segment) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 723 } | 723 } |
| 724 | 724 |
| 725 va_res = vaUnmapBuffer(va_display_, buffer_id); | 725 va_res = vaUnmapBuffer(va_display_, buffer_id); |
| 726 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); | 726 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); |
| 727 | 727 |
| 728 va_res = vaDestroyBuffer(va_display_, buffer_id); | 728 va_res = vaDestroyBuffer(va_display_, buffer_id); |
| 729 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); | 729 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
| 730 | 730 |
| 731 DCHECK(coded_buffers_.erase(buffer_id)); | 731 DCHECK(coded_buffers_.erase(buffer_id)); |
| 732 | 732 |
| 733 return buffer_segment == NULL; | 733 return buffer_segment == nullptr; |
| 734 } | 734 } |
| 735 | 735 |
| 736 // static | 736 // static |
| 737 bool VaapiWrapper::PostSandboxInitialization() { | 737 bool VaapiWrapper::PostSandboxInitialization() { |
| 738 StubPathMap paths; | 738 StubPathMap paths; |
| 739 paths[kModuleVa].push_back(kVaLib); | 739 paths[kModuleVa].push_back(kVaLib); |
| 740 | 740 |
| 741 return InitializeStubs(paths); | 741 return InitializeStubs(paths); |
| 742 } | 742 } |
| 743 | 743 |
| 744 } // namespace content | 744 } // namespace content |
| OLD | NEW |