Chromium Code Reviews| 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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 150 if (va_res != VA_STATUS_SUCCESS) | 150 if (va_res != VA_STATUS_SUCCESS) |
| 151 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; | 151 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; |
| 152 } | 152 } |
| 153 | 153 |
| 154 bool VaapiWrapper::Initialize(CodecMode mode, | 154 bool VaapiWrapper::Initialize(CodecMode mode, |
| 155 media::VideoCodecProfile profile, | 155 media::VideoCodecProfile profile, |
| 156 Display* x_display, | 156 Display* x_display, |
| 157 const base::Closure& report_error_to_uma_cb) { | 157 const base::Closure& report_error_to_uma_cb) { |
| 158 static bool vaapi_functions_initialized = PostSandboxInitialization(); | 158 static bool vaapi_functions_initialized = PostSandboxInitialization(); |
| 159 if (!vaapi_functions_initialized) { | 159 if (!vaapi_functions_initialized) { |
| 160 DVLOG(1) << "Failed to initialize VAAPI libs"; | 160 LOG(ERROR) << "Failed to initialize VAAPI libs"; |
| 161 return false; | 161 return false; |
| 162 } | 162 } |
| 163 | 163 |
| 164 report_error_to_uma_cb_ = report_error_to_uma_cb; | 164 report_error_to_uma_cb_ = report_error_to_uma_cb; |
| 165 | 165 |
| 166 base::AutoLock auto_lock(va_lock_); | 166 base::AutoLock auto_lock(va_lock_); |
| 167 | 167 |
| 168 va_display_ = vaGetDisplay(x_display); | 168 va_display_ = vaGetDisplay(x_display); |
| 169 if (!vaDisplayIsValid(va_display_)) { | 169 if (!vaDisplayIsValid(va_display_)) { |
| 170 DVLOG(1) << "Could not get a valid VA display"; | 170 LOG(ERROR) << "Could not get a valid VA display"; |
| 171 return false; | 171 return false; |
| 172 } | 172 } |
| 173 | 173 |
| 174 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); | 174 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); |
| 175 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); | 175 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); |
| 176 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; | 176 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; |
| 177 | 177 |
| 178 if (VAAPIVersionLessThan(0, 34)) { | 178 if (VAAPIVersionLessThan(0, 34)) { |
| 179 DVLOG(1) << "VAAPI version < 0.34 is not supported."; | 179 LOG(ERROR) << "VAAPI version < 0.34 is not supported."; |
| 180 return false; | 180 return false; |
| 181 } | 181 } |
| 182 | 182 |
| 183 // Query the driver for supported profiles. | 183 // Query the driver for supported profiles. |
| 184 int max_profiles = vaMaxNumProfiles(va_display_); | 184 int max_profiles = vaMaxNumProfiles(va_display_); |
| 185 std::vector<VAProfile> supported_profiles( | 185 std::vector<VAProfile> supported_profiles( |
| 186 base::checked_cast<size_t>(max_profiles)); | 186 base::checked_cast<size_t>(max_profiles)); |
| 187 | 187 |
| 188 int num_supported_profiles; | 188 int num_supported_profiles; |
| 189 va_res = vaQueryConfigProfiles( | 189 va_res = vaQueryConfigProfiles( |
| 190 va_display_, &supported_profiles[0], &num_supported_profiles); | 190 va_display_, &supported_profiles[0], &num_supported_profiles); |
| 191 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); | 191 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); |
| 192 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { | 192 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { |
| 193 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles; | 193 LOG(ERROR) << "vaQueryConfigProfiles returned: " << num_supported_profiles; |
| 194 return false; | 194 return false; |
| 195 } | 195 } |
| 196 | 196 |
| 197 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); | 197 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); |
| 198 | 198 |
| 199 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles); | 199 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles); |
| 200 if (va_profile == VAProfileNone) { | 200 if (va_profile == VAProfileNone) { |
| 201 DVLOG(1) << "Unsupported profile"; | 201 LOG(ERROR) << "Unsupported profile"; |
|
Pawel Osciak
2014/10/02 08:58:53
This is not an ERROR, will happen on devices that
| |
| 202 return false; | 202 return false; |
| 203 } | 203 } |
| 204 | 204 |
| 205 // Query the driver for supported entrypoints. | 205 // Query the driver for supported entrypoints. |
| 206 int max_entrypoints = vaMaxNumEntrypoints(va_display_); | 206 int max_entrypoints = vaMaxNumEntrypoints(va_display_); |
| 207 std::vector<VAEntrypoint> supported_entrypoints( | 207 std::vector<VAEntrypoint> supported_entrypoints( |
| 208 base::checked_cast<size_t>(max_entrypoints)); | 208 base::checked_cast<size_t>(max_entrypoints)); |
| 209 | 209 |
| 210 int num_supported_entrypoints; | 210 int num_supported_entrypoints; |
| 211 va_res = vaQueryConfigEntrypoints(va_display_, | 211 va_res = vaQueryConfigEntrypoints(va_display_, |
| 212 va_profile, | 212 va_profile, |
| 213 &supported_entrypoints[0], | 213 &supported_entrypoints[0], |
| 214 &num_supported_entrypoints); | 214 &num_supported_entrypoints); |
| 215 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false); | 215 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false); |
| 216 if (num_supported_entrypoints < 0 || | 216 if (num_supported_entrypoints < 0 || |
| 217 num_supported_entrypoints > max_entrypoints) { | 217 num_supported_entrypoints > max_entrypoints) { |
| 218 DVLOG(1) << "vaQueryConfigEntrypoints returned: " | 218 LOG(ERROR) << "vaQueryConfigEntrypoints returned: " |
| 219 << num_supported_entrypoints; | 219 << num_supported_entrypoints; |
| 220 return false; | 220 return false; |
| 221 } | 221 } |
| 222 | 222 |
| 223 VAEntrypoint entrypoint = | 223 VAEntrypoint entrypoint = |
| 224 (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD); | 224 (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD); |
| 225 | 225 |
| 226 if (std::find(supported_entrypoints.begin(), | 226 if (std::find(supported_entrypoints.begin(), |
| 227 supported_entrypoints.end(), | 227 supported_entrypoints.end(), |
| 228 entrypoint) == supported_entrypoints.end()) { | 228 entrypoint) == supported_entrypoints.end()) { |
| 229 DVLOG(1) << "Unsupported entrypoint"; | 229 LOG(ERROR) << "Unsupported entrypoint"; |
|
Pawel Osciak
2014/10/02 08:58:53
Ditto.
| |
| 230 return false; | 230 return false; |
| 231 } | 231 } |
| 232 | 232 |
| 233 // Query the driver for required attributes. | 233 // Query the driver for required attributes. |
| 234 std::vector<VAConfigAttrib> required_attribs; | 234 std::vector<VAConfigAttrib> required_attribs; |
| 235 required_attribs.insert( | 235 required_attribs.insert( |
| 236 required_attribs.end(), | 236 required_attribs.end(), |
| 237 kCommonVAConfigAttribs, | 237 kCommonVAConfigAttribs, |
| 238 kCommonVAConfigAttribs + arraysize(kCommonVAConfigAttribs)); | 238 kCommonVAConfigAttribs + arraysize(kCommonVAConfigAttribs)); |
| 239 if (mode == kEncode) { | 239 if (mode == kEncode) { |
| 240 required_attribs.insert( | 240 required_attribs.insert( |
| 241 required_attribs.end(), | 241 required_attribs.end(), |
| 242 kEncodeVAConfigAttribs, | 242 kEncodeVAConfigAttribs, |
| 243 kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs)); | 243 kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs)); |
| 244 } | 244 } |
| 245 | 245 |
| 246 std::vector<VAConfigAttrib> attribs = required_attribs; | 246 std::vector<VAConfigAttrib> attribs = required_attribs; |
| 247 for (size_t i = 0; i < required_attribs.size(); ++i) | 247 for (size_t i = 0; i < required_attribs.size(); ++i) |
| 248 attribs[i].value = 0; | 248 attribs[i].value = 0; |
| 249 | 249 |
| 250 va_res = vaGetConfigAttributes( | 250 va_res = vaGetConfigAttributes( |
| 251 va_display_, va_profile, entrypoint, &attribs[0], attribs.size()); | 251 va_display_, va_profile, entrypoint, &attribs[0], attribs.size()); |
| 252 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false); | 252 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false); |
| 253 | 253 |
| 254 for (size_t i = 0; i < required_attribs.size(); ++i) { | 254 for (size_t i = 0; i < required_attribs.size(); ++i) { |
| 255 if (attribs[i].type != required_attribs[i].type || | 255 if (attribs[i].type != required_attribs[i].type || |
| 256 (attribs[i].value & required_attribs[i].value) != | 256 (attribs[i].value & required_attribs[i].value) != |
| 257 required_attribs[i].value) { | 257 required_attribs[i].value) { |
| 258 DVLOG(1) << "Unsupported value " << required_attribs[i].value | 258 LOG(ERROR) << "Unsupported value " << required_attribs[i].value |
|
Pawel Osciak
2014/10/02 08:58:54
Also not an error to report.
| |
| 259 << " for attribute type " << required_attribs[i].type; | 259 << " for attribute type " << required_attribs[i].type; |
| 260 return false; | 260 return false; |
| 261 } | 261 } |
| 262 } | 262 } |
| 263 | 263 |
| 264 TryToSetVADisplayAttributeToLocalGPU(); | 264 TryToSetVADisplayAttributeToLocalGPU(); |
| 265 | 265 |
| 266 va_res = vaCreateConfig(va_display_, | 266 va_res = vaCreateConfig(va_display_, |
| 267 va_profile, | 267 va_profile, |
| 268 entrypoint, | 268 entrypoint, |
| 269 &required_attribs[0], | 269 &required_attribs[0], |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 571 VASurfaceID va_surface_id) { | 571 VASurfaceID va_surface_id) { |
| 572 base::AutoLock auto_lock(va_lock_); | 572 base::AutoLock auto_lock(va_lock_); |
| 573 | 573 |
| 574 VAImage image; | 574 VAImage image; |
| 575 VAStatus va_res = vaDeriveImage(va_display_, va_surface_id, &image); | 575 VAStatus va_res = vaDeriveImage(va_display_, va_surface_id, &image); |
| 576 VA_SUCCESS_OR_RETURN(va_res, "vaDeriveImage failed", false); | 576 VA_SUCCESS_OR_RETURN(va_res, "vaDeriveImage failed", false); |
| 577 base::ScopedClosureRunner vaimage_deleter( | 577 base::ScopedClosureRunner vaimage_deleter( |
| 578 base::Bind(&DestroyVAImage, va_display_, image)); | 578 base::Bind(&DestroyVAImage, va_display_, image)); |
| 579 | 579 |
| 580 if (image.format.fourcc != VA_FOURCC_NV12) { | 580 if (image.format.fourcc != VA_FOURCC_NV12) { |
| 581 DVLOG(1) << "Unsupported image format: " << image.format.fourcc; | 581 LOG(ERROR) << "Unsupported image format: " << image.format.fourcc; |
| 582 return false; | 582 return false; |
| 583 } | 583 } |
| 584 | 584 |
| 585 if (gfx::Rect(image.width, image.height) < gfx::Rect(frame->coded_size())) { | 585 if (gfx::Rect(image.width, image.height) < gfx::Rect(frame->coded_size())) { |
| 586 DVLOG(1) << "Buffer too small to fit the frame."; | 586 LOG(ERROR) << "Buffer too small to fit the frame."; |
| 587 return false; | 587 return false; |
| 588 } | 588 } |
| 589 | 589 |
| 590 void* image_ptr = NULL; | 590 void* image_ptr = NULL; |
| 591 va_res = vaMapBuffer(va_display_, image.buf, &image_ptr); | 591 va_res = vaMapBuffer(va_display_, image.buf, &image_ptr); |
| 592 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false); | 592 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false); |
| 593 DCHECK(image_ptr); | 593 DCHECK(image_ptr); |
| 594 | 594 |
| 595 int ret = 0; | 595 int ret = 0; |
| 596 { | 596 { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 667 | 667 |
| 668 // static | 668 // static |
| 669 bool VaapiWrapper::PostSandboxInitialization() { | 669 bool VaapiWrapper::PostSandboxInitialization() { |
| 670 StubPathMap paths; | 670 StubPathMap paths; |
| 671 paths[kModuleVa].push_back(kVaLib); | 671 paths[kModuleVa].push_back(kVaLib); |
| 672 | 672 |
| 673 return InitializeStubs(paths); | 673 return InitializeStubs(paths); |
| 674 } | 674 } |
| 675 | 675 |
| 676 } // namespace content | 676 } // namespace content |
| OLD | NEW |