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 |