| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/common/gpu/media/vaapi_wrapper.h" | 5 #include "content/common/gpu/media/vaapi_wrapper.h" |
| 6 | 6 |
| 7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/numerics/safe_conversions.h" | 12 #include "base/numerics/safe_conversions.h" |
| 13 // Auto-generated for dlopen libva libraries | 13 // Auto-generated for dlopen libva libraries |
| 14 #include "content/common/gpu/media/va_stubs.h" | 14 #include "content/common/gpu/media/va_stubs.h" |
| 15 #include "third_party/libyuv/include/libyuv.h" | 15 #include "third_party/libyuv/include/libyuv.h" |
| 16 | 16 |
| 17 using content_common_gpu_media::kModuleVa; | 17 using content_common_gpu_media::kModuleVa; |
| 18 using content_common_gpu_media::InitializeStubs; | 18 using content_common_gpu_media::InitializeStubs; |
| 19 using content_common_gpu_media::StubPathMap; | 19 using content_common_gpu_media::StubPathMap; |
| 20 | 20 |
| 21 // libva-x11 depends on libva, so dlopen libva-x11 is enough | 21 // libva-x11 depends on libva, so dlopen libva-x11 is enough |
| 22 static const base::FilePath::CharType kVaLib[] = | 22 static const base::FilePath::CharType kVaLib[] = |
| 23 FILE_PATH_LITERAL("libva-x11.so.1"); | 23 FILE_PATH_LITERAL("libva-x11.so.1"); |
| 24 | 24 |
| 25 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ | 25 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ |
| 26 do { \ | 26 do { \ |
| 27 DVLOG(1) << err_msg \ | 27 LOG(ERROR) << err_msg \ |
| 28 << " VA error: " << vaErrorStr(va_error); \ | 28 << " VA error: " << vaErrorStr(va_error); \ |
| 29 report_error_to_uma_cb_.Run(); \ | 29 report_error_to_uma_cb_.Run(); \ |
| 30 } while (0) | 30 } while (0) |
| 31 | 31 |
| 32 #define VA_LOG_ON_ERROR(va_error, err_msg) \ | 32 #define VA_LOG_ON_ERROR(va_error, err_msg) \ |
| 33 do { \ | 33 do { \ |
| 34 if ((va_error) != VA_STATUS_SUCCESS) \ | 34 if ((va_error) != VA_STATUS_SUCCESS) \ |
| 35 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ | 35 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ |
| 36 } while (0) | 36 } while (0) |
| 37 | 37 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 | 197 |
| 198 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); | 198 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); |
| 199 if (va_res != VA_STATUS_SUCCESS) | 199 if (va_res != VA_STATUS_SUCCESS) |
| 200 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; | 200 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; |
| 201 } | 201 } |
| 202 | 202 |
| 203 bool VaapiWrapper::VaInitialize(Display* x_display, | 203 bool VaapiWrapper::VaInitialize(Display* x_display, |
| 204 const base::Closure& report_error_to_uma_cb) { | 204 const base::Closure& report_error_to_uma_cb) { |
| 205 static bool vaapi_functions_initialized = PostSandboxInitialization(); | 205 static bool vaapi_functions_initialized = PostSandboxInitialization(); |
| 206 if (!vaapi_functions_initialized) { | 206 if (!vaapi_functions_initialized) { |
| 207 DVLOG(1) << "Failed to initialize VAAPI libs"; | 207 LOG(ERROR) << "Failed to initialize VAAPI libs"; |
| 208 return false; | 208 return false; |
| 209 } | 209 } |
| 210 | 210 |
| 211 report_error_to_uma_cb_ = report_error_to_uma_cb; | 211 report_error_to_uma_cb_ = report_error_to_uma_cb; |
| 212 | 212 |
| 213 base::AutoLock auto_lock(va_lock_); | 213 base::AutoLock auto_lock(va_lock_); |
| 214 | 214 |
| 215 va_display_ = vaGetDisplay(x_display); | 215 va_display_ = vaGetDisplay(x_display); |
| 216 if (!vaDisplayIsValid(va_display_)) { | 216 if (!vaDisplayIsValid(va_display_)) { |
| 217 DVLOG(1) << "Could not get a valid VA display"; | 217 LOG(ERROR) << "Could not get a valid VA display"; |
| 218 return false; | 218 return false; |
| 219 } | 219 } |
| 220 | 220 |
| 221 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); | 221 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); |
| 222 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); | 222 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); |
| 223 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; | 223 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; |
| 224 | 224 |
| 225 if (VAAPIVersionLessThan(0, 34)) { | 225 if (VAAPIVersionLessThan(0, 34)) { |
| 226 DVLOG(1) << "VAAPI version < 0.34 is not supported."; | 226 LOG(ERROR) << "VAAPI version < 0.34 is not supported."; |
| 227 return false; | 227 return false; |
| 228 } | 228 } |
| 229 return true; | 229 return true; |
| 230 } | 230 } |
| 231 | 231 |
| 232 bool VaapiWrapper::GetSupportedVaProfiles(std::vector<VAProfile>* profiles) { | 232 bool VaapiWrapper::GetSupportedVaProfiles(std::vector<VAProfile>* profiles) { |
| 233 base::AutoLock auto_lock(va_lock_); | 233 base::AutoLock auto_lock(va_lock_); |
| 234 // Query the driver for supported profiles. | 234 // Query the driver for supported profiles. |
| 235 int max_profiles = vaMaxNumProfiles(va_display_); | 235 int max_profiles = vaMaxNumProfiles(va_display_); |
| 236 std::vector<VAProfile> supported_profiles( | 236 std::vector<VAProfile> supported_profiles( |
| 237 base::checked_cast<size_t>(max_profiles)); | 237 base::checked_cast<size_t>(max_profiles)); |
| 238 | 238 |
| 239 int num_supported_profiles; | 239 int num_supported_profiles; |
| 240 VAStatus va_res = vaQueryConfigProfiles( | 240 VAStatus va_res = vaQueryConfigProfiles( |
| 241 va_display_, &supported_profiles[0], &num_supported_profiles); | 241 va_display_, &supported_profiles[0], &num_supported_profiles); |
| 242 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); | 242 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); |
| 243 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { | 243 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { |
| 244 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles; | 244 LOG(ERROR) << "vaQueryConfigProfiles returned: " << num_supported_profiles; |
| 245 return false; | 245 return false; |
| 246 } | 246 } |
| 247 | 247 |
| 248 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); | 248 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); |
| 249 *profiles = supported_profiles; | 249 *profiles = supported_profiles; |
| 250 return true; | 250 return true; |
| 251 } | 251 } |
| 252 | 252 |
| 253 bool VaapiWrapper::IsEntrypointSupported(VAProfile va_profile, | 253 bool VaapiWrapper::IsEntrypointSupported(VAProfile va_profile, |
| 254 VAEntrypoint entrypoint) { | 254 VAEntrypoint entrypoint) { |
| 255 base::AutoLock auto_lock(va_lock_); | 255 base::AutoLock auto_lock(va_lock_); |
| 256 // Query the driver for supported entrypoints. | 256 // Query the driver for supported entrypoints. |
| 257 int max_entrypoints = vaMaxNumEntrypoints(va_display_); | 257 int max_entrypoints = vaMaxNumEntrypoints(va_display_); |
| 258 std::vector<VAEntrypoint> supported_entrypoints( | 258 std::vector<VAEntrypoint> supported_entrypoints( |
| 259 base::checked_cast<size_t>(max_entrypoints)); | 259 base::checked_cast<size_t>(max_entrypoints)); |
| 260 | 260 |
| 261 int num_supported_entrypoints; | 261 int num_supported_entrypoints; |
| 262 VAStatus va_res = vaQueryConfigEntrypoints(va_display_, | 262 VAStatus va_res = vaQueryConfigEntrypoints(va_display_, |
| 263 va_profile, | 263 va_profile, |
| 264 &supported_entrypoints[0], | 264 &supported_entrypoints[0], |
| 265 &num_supported_entrypoints); | 265 &num_supported_entrypoints); |
| 266 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false); | 266 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false); |
| 267 if (num_supported_entrypoints < 0 || | 267 if (num_supported_entrypoints < 0 || |
| 268 num_supported_entrypoints > max_entrypoints) { | 268 num_supported_entrypoints > max_entrypoints) { |
| 269 DVLOG(1) << "vaQueryConfigEntrypoints returned: " | 269 LOG(ERROR) << "vaQueryConfigEntrypoints returned: " |
| 270 << num_supported_entrypoints; | 270 << num_supported_entrypoints; |
| 271 return false; | 271 return false; |
| 272 } | 272 } |
| 273 | 273 |
| 274 if (std::find(supported_entrypoints.begin(), | 274 if (std::find(supported_entrypoints.begin(), |
| 275 supported_entrypoints.end(), | 275 supported_entrypoints.end(), |
| 276 entrypoint) == supported_entrypoints.end()) { | 276 entrypoint) == supported_entrypoints.end()) { |
| 277 DVLOG(1) << "Unsupported entrypoint"; | 277 DVLOG(1) << "Unsupported entrypoint"; |
| 278 return false; | 278 return false; |
| 279 } | 279 } |
| 280 return true; | 280 return true; |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 VASurfaceID va_surface_id) { | 639 VASurfaceID va_surface_id) { |
| 640 base::AutoLock auto_lock(va_lock_); | 640 base::AutoLock auto_lock(va_lock_); |
| 641 | 641 |
| 642 VAImage image; | 642 VAImage image; |
| 643 VAStatus va_res = vaDeriveImage(va_display_, va_surface_id, &image); | 643 VAStatus va_res = vaDeriveImage(va_display_, va_surface_id, &image); |
| 644 VA_SUCCESS_OR_RETURN(va_res, "vaDeriveImage failed", false); | 644 VA_SUCCESS_OR_RETURN(va_res, "vaDeriveImage failed", false); |
| 645 base::ScopedClosureRunner vaimage_deleter( | 645 base::ScopedClosureRunner vaimage_deleter( |
| 646 base::Bind(&DestroyVAImage, va_display_, image)); | 646 base::Bind(&DestroyVAImage, va_display_, image)); |
| 647 | 647 |
| 648 if (image.format.fourcc != VA_FOURCC_NV12) { | 648 if (image.format.fourcc != VA_FOURCC_NV12) { |
| 649 DVLOG(1) << "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 DVLOG(1) << "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 = NULL; |
| 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 { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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) { |
| 707 DCHECK(buffer_segment->buf); | 707 DCHECK(buffer_segment->buf); |
| 708 | 708 |
| 709 if (buffer_segment->size > target_size) { | 709 if (buffer_segment->size > target_size) { |
| 710 DVLOG(1) << "Insufficient output buffer size"; | 710 LOG(ERROR) << "Insufficient output buffer size"; |
| 711 break; | 711 break; |
| 712 } | 712 } |
| 713 | 713 |
| 714 memcpy(target_ptr, buffer_segment->buf, buffer_segment->size); | 714 memcpy(target_ptr, buffer_segment->buf, buffer_segment->size); |
| 715 | 715 |
| 716 target_ptr += buffer_segment->size; | 716 target_ptr += buffer_segment->size; |
| 717 *coded_data_size += buffer_segment->size; | 717 *coded_data_size += buffer_segment->size; |
| 718 target_size -= buffer_segment->size; | 718 target_size -= buffer_segment->size; |
| 719 | 719 |
| 720 buffer_segment = | 720 buffer_segment = |
| (...skipping 14 matching lines...) Expand all Loading... |
| 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 |