| 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 #if defined(USE_X11) |
| 17 #include "third_party/libva/va/va_x11.h" |
| 18 #include "ui/gfx/x/x11_types.h" |
| 19 #else |
| 20 #include <gbm.h> |
| 21 #include "third_party/libva/va/drm/va_drm.h" |
| 22 #include "third_party/libva/va/va_drmcommon.h" |
| 23 #include "ui/ozone/public/ozone_platform.h" |
| 24 #include "ui/ozone/public/surface_factory_ozone.h" |
| 25 #endif // USE_X11 |
| 26 #include "ui/gl/gl_bindings.h" |
| 16 | 27 |
| 17 using content_common_gpu_media::kModuleVa; | 28 using content_common_gpu_media::kModuleVa; |
| 29 #if defined(USE_X11) |
| 30 using content_common_gpu_media::kModuleVa_x11; |
| 31 #else |
| 32 using content_common_gpu_media::kModuleVa_drm; |
| 33 #endif // USE_X11 |
| 18 using content_common_gpu_media::InitializeStubs; | 34 using content_common_gpu_media::InitializeStubs; |
| 19 using content_common_gpu_media::StubPathMap; | 35 using content_common_gpu_media::StubPathMap; |
| 20 | 36 |
| 21 // libva-x11 depends on libva, so dlopen libva-x11 is enough | |
| 22 static const base::FilePath::CharType kVaLib[] = | |
| 23 FILE_PATH_LITERAL("libva-x11.so.1"); | |
| 24 | |
| 25 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ | 37 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ |
| 26 do { \ | 38 do { \ |
| 27 DVLOG(1) << err_msg \ | 39 DVLOG(1) << err_msg \ |
| 28 << " VA error: " << vaErrorStr(va_error); \ | 40 << " VA error: " << vaErrorStr(va_error); \ |
| 29 report_error_to_uma_cb_.Run(); \ | 41 report_error_to_uma_cb_.Run(); \ |
| 30 } while (0) | 42 } while (0) |
| 31 | 43 |
| 32 #define VA_LOG_ON_ERROR(va_error, err_msg) \ | 44 #define VA_LOG_ON_ERROR(va_error, err_msg) \ |
| 33 do { \ | 45 do { \ |
| 34 if ((va_error) != VA_STATUS_SUCCESS) \ | 46 if ((va_error) != VA_STATUS_SUCCESS) \ |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 : va_surface_id_(va_surface_id), | 118 : va_surface_id_(va_surface_id), |
| 107 release_cb_(release_cb) { | 119 release_cb_(release_cb) { |
| 108 DCHECK(!release_cb_.is_null()); | 120 DCHECK(!release_cb_.is_null()); |
| 109 } | 121 } |
| 110 | 122 |
| 111 VASurface::~VASurface() { | 123 VASurface::~VASurface() { |
| 112 release_cb_.Run(va_surface_id_); | 124 release_cb_.Run(va_surface_id_); |
| 113 } | 125 } |
| 114 | 126 |
| 115 VaapiWrapper::VaapiWrapper() | 127 VaapiWrapper::VaapiWrapper() |
| 116 : va_display_(NULL), | 128 : va_config_id_(VA_INVALID_ID), va_context_id_(VA_INVALID_ID) { |
| 117 va_config_id_(VA_INVALID_ID), | |
| 118 va_context_id_(VA_INVALID_ID) { | |
| 119 } | 129 } |
| 120 | 130 |
| 121 VaapiWrapper::~VaapiWrapper() { | 131 VaapiWrapper::~VaapiWrapper() { |
| 122 DestroyPendingBuffers(); | 132 DestroyPendingBuffers(); |
| 123 DestroyCodedBuffers(); | 133 DestroyCodedBuffers(); |
| 124 DestroySurfaces(); | 134 DestroySurfaces(); |
| 125 Deinitialize(); | 135 Deinitialize(); |
| 126 } | 136 } |
| 127 | 137 |
| 128 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( | 138 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( |
| 129 CodecMode mode, | 139 CodecMode mode, |
| 130 media::VideoCodecProfile profile, | 140 media::VideoCodecProfile profile, |
| 131 Display* x_display, | |
| 132 const base::Closure& report_error_to_uma_cb) { | 141 const base::Closure& report_error_to_uma_cb) { |
| 142 static bool vaapi_functions_initialized = PostSandboxInitialization(); |
| 133 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); | 143 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); |
| 134 | 144 |
| 135 if (!vaapi_wrapper->Initialize( | 145 if (!vaapi_functions_initialized) { |
| 136 mode, profile, x_display, report_error_to_uma_cb)) | 146 DVLOG(1) << "Failed to initialize VAAPI libs"; |
| 147 return vaapi_wrapper.Pass(); |
| 148 } |
| 149 |
| 150 VADisplay va_display = NULL; |
| 151 #if defined(USE_X11) |
| 152 va_display = vaGetDisplay(gfx::GetXDisplay()); |
| 153 #else |
| 154 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); |
| 155 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); |
| 156 gbm_device* device = |
| 157 reinterpret_cast<gbm_device*>(factory->GetNativeDisplay()); |
| 158 |
| 159 va_display = vaGetDisplayDRM(gbm_device_get_fd(device)); |
| 160 #endif // USE_X11 |
| 161 |
| 162 if (!va_display || !vaapi_wrapper->Initialize(va_display, |
| 163 mode, |
| 164 profile, |
| 165 report_error_to_uma_cb)) |
| 137 vaapi_wrapper.reset(); | 166 vaapi_wrapper.reset(); |
| 138 | 167 |
| 139 return vaapi_wrapper.Pass(); | 168 return vaapi_wrapper.Pass(); |
| 140 } | 169 } |
| 141 | 170 |
| 142 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { | 171 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { |
| 143 VADisplayAttribute item = {VADisplayAttribRenderMode, | 172 VADisplayAttribute item = {VADisplayAttribRenderMode, |
| 144 1, // At least support '_LOCAL_OVERLAY'. | 173 1, // At least support '_LOCAL_OVERLAY'. |
| 145 -1, // The maximum possible support 'ALL'. | 174 -1, // The maximum possible support 'ALL'. |
| 146 VA_RENDER_MODE_LOCAL_GPU, | 175 VA_RENDER_MODE_LOCAL_GPU, |
| 147 VA_DISPLAY_ATTRIB_SETTABLE}; | 176 VA_DISPLAY_ATTRIB_SETTABLE}; |
| 148 | 177 |
| 149 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); | 178 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); |
| 150 if (va_res != VA_STATUS_SUCCESS) | 179 if (va_res != VA_STATUS_SUCCESS) |
| 151 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; | 180 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; |
| 152 } | 181 } |
| 153 | 182 |
| 154 bool VaapiWrapper::Initialize(CodecMode mode, | 183 bool VaapiWrapper::Initialize( |
| 155 media::VideoCodecProfile profile, | 184 VADisplay va_display, |
| 156 Display* x_display, | 185 CodecMode mode, |
| 157 const base::Closure& report_error_to_uma_cb) { | 186 media::VideoCodecProfile profile, |
| 158 static bool vaapi_functions_initialized = PostSandboxInitialization(); | 187 const base::Closure& report_error_to_uma_cb) { |
| 159 if (!vaapi_functions_initialized) { | |
| 160 DVLOG(1) << "Failed to initialize VAAPI libs"; | |
| 161 return false; | |
| 162 } | |
| 163 | |
| 164 report_error_to_uma_cb_ = report_error_to_uma_cb; | 188 report_error_to_uma_cb_ = report_error_to_uma_cb; |
| 165 | 189 |
| 166 base::AutoLock auto_lock(va_lock_); | 190 base::AutoLock auto_lock(va_lock_); |
| 167 | 191 |
| 168 va_display_ = vaGetDisplay(x_display); | 192 va_display_ = va_display; |
| 169 if (!vaDisplayIsValid(va_display_)) { | 193 if (!vaDisplayIsValid(va_display_)) { |
| 170 DVLOG(1) << "Could not get a valid VA display"; | 194 DVLOG(1) << "Could not get a valid VA display"; |
| 171 return false; | 195 return false; |
| 172 } | 196 } |
| 173 | 197 |
| 174 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); | 198 VAStatus va_res = |
| 199 vaInitialize(va_display_, &major_version_, &minor_version_); |
| 175 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); | 200 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); |
| 176 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; | 201 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; |
| 177 | 202 |
| 178 if (VAAPIVersionLessThan(0, 34)) { | 203 if (VAAPIVersionLessThan(0, 34)) { |
| 179 DVLOG(1) << "VAAPI version < 0.34 is not supported."; | 204 DVLOG(1) << "VAAPI version < 0.34 is not supported."; |
| 180 return false; | 205 return false; |
| 181 } | 206 } |
| 182 | 207 |
| 183 // Query the driver for supported profiles. | 208 // Query the driver for supported profiles. |
| 184 int max_profiles = vaMaxNumProfiles(va_display_); | 209 int max_profiles = vaMaxNumProfiles(va_display_); |
| 185 std::vector<VAProfile> supported_profiles( | 210 std::vector<VAProfile> supported_profiles( |
| 186 base::checked_cast<size_t>(max_profiles)); | 211 base::checked_cast<size_t>(max_profiles)); |
| 187 | 212 |
| 188 int num_supported_profiles; | 213 int num_supported_profiles; |
| 189 va_res = vaQueryConfigProfiles( | 214 va_res = vaQueryConfigProfiles( |
| 190 va_display_, &supported_profiles[0], &num_supported_profiles); | 215 va_display_, &supported_profiles[0], &num_supported_profiles); |
| 191 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); | 216 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); |
| 192 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { | 217 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { |
| 193 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles; | 218 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles; |
| 194 return false; | 219 return false; |
| 195 } | 220 } |
| 196 | 221 |
| 197 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); | 222 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); |
| 198 | 223 |
| 199 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles); | 224 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles); |
| 200 if (va_profile == VAProfileNone) { | 225 if (va_profile == VAProfileNone) { |
| 201 DVLOG(1) << "Unsupported profile"; | 226 DVLOG(1) << "Unsupported profile : " << profile; |
| 202 return false; | 227 return false; |
| 203 } | 228 } |
| 204 | 229 |
| 205 // Query the driver for supported entrypoints. | 230 // Query the driver for supported entrypoints. |
| 206 int max_entrypoints = vaMaxNumEntrypoints(va_display_); | 231 int max_entrypoints = vaMaxNumEntrypoints(va_display_); |
| 207 std::vector<VAEntrypoint> supported_entrypoints( | 232 std::vector<VAEntrypoint> supported_entrypoints( |
| 208 base::checked_cast<size_t>(max_entrypoints)); | 233 base::checked_cast<size_t>(max_entrypoints)); |
| 209 | 234 |
| 210 int num_supported_entrypoints; | 235 int num_supported_entrypoints; |
| 211 va_res = vaQueryConfigEntrypoints(va_display_, | 236 va_res = vaQueryConfigEntrypoints(va_display_, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 240 required_attribs.insert( | 265 required_attribs.insert( |
| 241 required_attribs.end(), | 266 required_attribs.end(), |
| 242 kEncodeVAConfigAttribs, | 267 kEncodeVAConfigAttribs, |
| 243 kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs)); | 268 kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs)); |
| 244 } | 269 } |
| 245 | 270 |
| 246 std::vector<VAConfigAttrib> attribs = required_attribs; | 271 std::vector<VAConfigAttrib> attribs = required_attribs; |
| 247 for (size_t i = 0; i < required_attribs.size(); ++i) | 272 for (size_t i = 0; i < required_attribs.size(); ++i) |
| 248 attribs[i].value = 0; | 273 attribs[i].value = 0; |
| 249 | 274 |
| 250 va_res = vaGetConfigAttributes( | 275 va_res = vaGetConfigAttributes(va_display_, |
| 251 va_display_, va_profile, entrypoint, &attribs[0], attribs.size()); | 276 va_profile, |
| 277 entrypoint, |
| 278 &attribs[0], |
| 279 attribs.size()); |
| 252 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false); | 280 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false); |
| 253 | 281 |
| 254 for (size_t i = 0; i < required_attribs.size(); ++i) { | 282 for (size_t i = 0; i < required_attribs.size(); ++i) { |
| 255 if (attribs[i].type != required_attribs[i].type || | 283 if (attribs[i].type != required_attribs[i].type || |
| 256 (attribs[i].value & required_attribs[i].value) != | 284 (attribs[i].value & required_attribs[i].value) != |
| 257 required_attribs[i].value) { | 285 required_attribs[i].value) { |
| 258 DVLOG(1) << "Unsupported value " << required_attribs[i].value | 286 DVLOG(1) << "Unsupported value " << required_attribs[i].value |
| 259 << " for attribute type " << required_attribs[i].type; | 287 << " for attribute type " << required_attribs[i].type; |
| 260 return false; | 288 return false; |
| 261 } | 289 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 289 | 317 |
| 290 va_config_id_ = VA_INVALID_ID; | 318 va_config_id_ = VA_INVALID_ID; |
| 291 va_display_ = NULL; | 319 va_display_ = NULL; |
| 292 } | 320 } |
| 293 | 321 |
| 294 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { | 322 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { |
| 295 return (major_version_ < major) || | 323 return (major_version_ < major) || |
| 296 (major_version_ == major && minor_version_ < minor); | 324 (major_version_ == major && minor_version_ < minor); |
| 297 } | 325 } |
| 298 | 326 |
| 299 bool VaapiWrapper::CreateSurfaces(gfx::Size size, | 327 bool VaapiWrapper::CreateSurfaces(const gfx::Size& size, |
| 300 size_t num_surfaces, | 328 size_t num_surfaces, |
| 301 std::vector<VASurfaceID>* va_surfaces) { | 329 std::vector<VASurfaceID>* va_surfaces) { |
| 302 base::AutoLock auto_lock(va_lock_); | 330 base::AutoLock auto_lock(va_lock_); |
| 303 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; | 331 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; |
| 304 | 332 |
| 305 DCHECK(va_surfaces->empty()); | 333 DCHECK(va_surfaces->empty()); |
| 306 DCHECK(va_surface_ids_.empty()); | 334 DCHECK(va_surface_ids_.empty()); |
| 307 va_surface_ids_.resize(num_surfaces); | 335 va_surface_ids_.resize(num_surfaces); |
| 308 | 336 |
| 309 // Allocate surfaces in driver. | 337 // Allocate surfaces in driver. |
| 310 VAStatus va_res = vaCreateSurfaces(va_display_, | 338 VAStatus va_res = vaCreateSurfaces(va_display_, |
| 311 VA_RT_FORMAT_YUV420, | 339 VA_RT_FORMAT_YUV420, |
| 312 size.width(), size.height(), | 340 size.width(), |
| 341 size.height(), |
| 313 &va_surface_ids_[0], | 342 &va_surface_ids_[0], |
| 314 va_surface_ids_.size(), | 343 va_surface_ids_.size(), |
| 315 NULL, 0); | 344 NULL, |
| 316 | 345 0); |
| 317 VA_LOG_ON_ERROR(va_res, "vaCreateSurfaces failed"); | 346 VA_LOG_ON_ERROR(va_res, "vaCreateSurfaces failed"); |
| 318 if (va_res != VA_STATUS_SUCCESS) { | 347 if (va_res != VA_STATUS_SUCCESS) { |
| 319 va_surface_ids_.clear(); | 348 va_surface_ids_.clear(); |
| 320 return false; | 349 return false; |
| 321 } | 350 } |
| 322 | 351 |
| 323 // And create a context associated with them. | 352 // And create a context associated with them. |
| 324 va_res = vaCreateContext(va_display_, va_config_id_, | 353 va_res = vaCreateContext(va_display_, |
| 325 size.width(), size.height(), VA_PROGRESSIVE, | 354 va_config_id_, |
| 326 &va_surface_ids_[0], va_surface_ids_.size(), | 355 size.width(), |
| 356 size.height(), |
| 357 VA_PROGRESSIVE, |
| 358 &va_surface_ids_[0], |
| 359 va_surface_ids_.size(), |
| 327 &va_context_id_); | 360 &va_context_id_); |
| 328 | 361 |
| 329 VA_LOG_ON_ERROR(va_res, "vaCreateContext failed"); | 362 VA_LOG_ON_ERROR(va_res, "vaCreateContext failed"); |
| 330 if (va_res != VA_STATUS_SUCCESS) { | 363 if (va_res != VA_STATUS_SUCCESS) { |
| 331 DestroySurfaces(); | 364 DestroySurfaces(); |
| 332 return false; | 365 return false; |
| 333 } | 366 } |
| 334 | 367 |
| 335 *va_surfaces = va_surface_ids_; | 368 *va_surfaces = va_surface_ids_; |
| 336 return true; | 369 return true; |
| 337 } | 370 } |
| 338 | 371 |
| 339 void VaapiWrapper::DestroySurfaces() { | 372 void VaapiWrapper::DestroySurfaces() { |
| 340 base::AutoLock auto_lock(va_lock_); | 373 base::AutoLock auto_lock(va_lock_); |
| 341 DVLOG(2) << "Destroying " << va_surface_ids_.size() << " surfaces"; | 374 DVLOG(2) << "Destroying " << va_surface_ids_.size() << " surfaces"; |
| 342 | 375 |
| 343 if (va_context_id_ != VA_INVALID_ID) { | 376 if (va_context_id_ != VA_INVALID_ID) { |
| 344 VAStatus va_res = vaDestroyContext(va_display_, va_context_id_); | 377 VAStatus va_res = vaDestroyContext(va_display_, va_context_id_); |
| 345 VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed"); | 378 VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed"); |
| 346 } | 379 } |
| 347 | 380 |
| 348 if (!va_surface_ids_.empty()) { | 381 if (!va_surface_ids_.empty()) { |
| 349 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], | 382 VAStatus va_res = vaDestroySurfaces( |
| 350 va_surface_ids_.size()); | 383 va_display_, &va_surface_ids_[0], va_surface_ids_.size()); |
| 351 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); | 384 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); |
| 352 } | 385 } |
| 353 | 386 |
| 354 va_surface_ids_.clear(); | 387 va_surface_ids_.clear(); |
| 355 va_context_id_ = VA_INVALID_ID; | 388 va_context_id_ = VA_INVALID_ID; |
| 356 } | 389 } |
| 357 | 390 |
| 358 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, | 391 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, |
| 359 size_t size, | 392 size_t size, |
| 360 void* buffer) { | 393 void* buffer) { |
| 361 base::AutoLock auto_lock(va_lock_); | 394 base::AutoLock auto_lock(va_lock_); |
| 362 | 395 |
| 363 VABufferID buffer_id; | 396 VABufferID buffer_id; |
| 364 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, | 397 VAStatus va_res = vaCreateBuffer(va_display_, |
| 365 va_buffer_type, size, | 398 va_context_id_, |
| 366 1, buffer, &buffer_id); | 399 va_buffer_type, |
| 400 size, |
| 401 1, |
| 402 buffer, |
| 403 &buffer_id); |
| 367 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); | 404 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); |
| 368 | 405 |
| 369 switch (va_buffer_type) { | 406 switch (va_buffer_type) { |
| 370 case VASliceParameterBufferType: | 407 case VASliceParameterBufferType: |
| 371 case VASliceDataBufferType: | 408 case VASliceDataBufferType: |
| 372 case VAEncSliceParameterBufferType: | 409 case VAEncSliceParameterBufferType: |
| 373 pending_slice_bufs_.push_back(buffer_id); | 410 pending_slice_bufs_.push_back(buffer_id); |
| 374 break; | 411 break; |
| 375 | 412 |
| 376 default: | 413 default: |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); | 452 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); |
| 416 | 453 |
| 417 pending_va_bufs_.push_back(buffer_id); | 454 pending_va_bufs_.push_back(buffer_id); |
| 418 return true; | 455 return true; |
| 419 } | 456 } |
| 420 | 457 |
| 421 void VaapiWrapper::DestroyPendingBuffers() { | 458 void VaapiWrapper::DestroyPendingBuffers() { |
| 422 base::AutoLock auto_lock(va_lock_); | 459 base::AutoLock auto_lock(va_lock_); |
| 423 | 460 |
| 424 for (size_t i = 0; i < pending_va_bufs_.size(); ++i) { | 461 for (size_t i = 0; i < pending_va_bufs_.size(); ++i) { |
| 425 VAStatus va_res = vaDestroyBuffer(va_display_, pending_va_bufs_[i]); | 462 VAStatus va_res = |
| 463 vaDestroyBuffer(va_display_, pending_va_bufs_[i]); |
| 426 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); | 464 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
| 427 } | 465 } |
| 428 | 466 |
| 429 for (size_t i = 0; i < pending_slice_bufs_.size(); ++i) { | 467 for (size_t i = 0; i < pending_slice_bufs_.size(); ++i) { |
| 430 VAStatus va_res = vaDestroyBuffer(va_display_, pending_slice_bufs_[i]); | 468 VAStatus va_res = |
| 469 vaDestroyBuffer(va_display_, pending_slice_bufs_[i]); |
| 431 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); | 470 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
| 432 } | 471 } |
| 433 | 472 |
| 434 pending_va_bufs_.clear(); | 473 pending_va_bufs_.clear(); |
| 435 pending_slice_bufs_.clear(); | 474 pending_slice_bufs_.clear(); |
| 436 } | 475 } |
| 437 | 476 |
| 438 bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) { | 477 bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) { |
| 439 base::AutoLock auto_lock(va_lock_); | 478 base::AutoLock auto_lock(va_lock_); |
| 440 VAStatus va_res = vaCreateBuffer(va_display_, | 479 VAStatus va_res = vaCreateBuffer(va_display_, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 464 } | 503 } |
| 465 | 504 |
| 466 bool VaapiWrapper::Execute(VASurfaceID va_surface_id) { | 505 bool VaapiWrapper::Execute(VASurfaceID va_surface_id) { |
| 467 base::AutoLock auto_lock(va_lock_); | 506 base::AutoLock auto_lock(va_lock_); |
| 468 | 507 |
| 469 DVLOG(4) << "Pending VA bufs to commit: " << pending_va_bufs_.size(); | 508 DVLOG(4) << "Pending VA bufs to commit: " << pending_va_bufs_.size(); |
| 470 DVLOG(4) << "Pending slice bufs to commit: " << pending_slice_bufs_.size(); | 509 DVLOG(4) << "Pending slice bufs to commit: " << pending_slice_bufs_.size(); |
| 471 DVLOG(4) << "Target VA surface " << va_surface_id; | 510 DVLOG(4) << "Target VA surface " << va_surface_id; |
| 472 | 511 |
| 473 // Get ready to execute for given surface. | 512 // Get ready to execute for given surface. |
| 474 VAStatus va_res = vaBeginPicture(va_display_, va_context_id_, | 513 VAStatus va_res = |
| 475 va_surface_id); | 514 vaBeginPicture(va_display_, va_context_id_, va_surface_id); |
| 476 VA_SUCCESS_OR_RETURN(va_res, "vaBeginPicture failed", false); | 515 VA_SUCCESS_OR_RETURN(va_res, "vaBeginPicture failed", false); |
| 477 | 516 |
| 478 if (pending_va_bufs_.size() > 0) { | 517 if (pending_va_bufs_.size() > 0) { |
| 479 // Commit parameter and slice buffers. | 518 // Commit parameter and slice buffers. |
| 480 va_res = vaRenderPicture(va_display_, | 519 va_res = vaRenderPicture(va_display_, |
| 481 va_context_id_, | 520 va_context_id_, |
| 482 &pending_va_bufs_[0], | 521 &pending_va_bufs_[0], |
| 483 pending_va_bufs_.size()); | 522 pending_va_bufs_.size()); |
| 484 VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for va_bufs failed", false); | 523 VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for va_bufs failed", false); |
| 485 } | 524 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 499 | 538 |
| 500 return true; | 539 return true; |
| 501 } | 540 } |
| 502 | 541 |
| 503 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { | 542 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { |
| 504 bool result = Execute(va_surface_id); | 543 bool result = Execute(va_surface_id); |
| 505 DestroyPendingBuffers(); | 544 DestroyPendingBuffers(); |
| 506 return result; | 545 return result; |
| 507 } | 546 } |
| 508 | 547 |
| 509 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, | |
| 510 Pixmap x_pixmap, | |
| 511 gfx::Size dest_size) { | |
| 512 base::AutoLock auto_lock(va_lock_); | |
| 513 | |
| 514 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | |
| 515 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | |
| 516 | |
| 517 // Put the data into an X Pixmap. | |
| 518 va_res = vaPutSurface(va_display_, | |
| 519 va_surface_id, | |
| 520 x_pixmap, | |
| 521 0, 0, dest_size.width(), dest_size.height(), | |
| 522 0, 0, dest_size.width(), dest_size.height(), | |
| 523 NULL, 0, 0); | |
| 524 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); | |
| 525 return true; | |
| 526 } | |
| 527 | |
| 528 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, | 548 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, |
| 529 VAImage* image, | 549 VAImage* image, |
| 530 void** mem) { | 550 void** mem) { |
| 531 base::AutoLock auto_lock(va_lock_); | 551 base::AutoLock auto_lock(va_lock_); |
| 532 | 552 |
| 533 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | 553 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
| 534 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 554 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
| 535 | 555 |
| 536 // Derive a VAImage from the VASurface | 556 // Derive a VAImage from the VASurface |
| 537 va_res = vaDeriveImage(va_display_, va_surface_id, image); | 557 va_res = vaDeriveImage(va_display_, va_surface_id, image); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 565 if (image.image_id != VA_INVALID_ID) | 585 if (image.image_id != VA_INVALID_ID) |
| 566 vaDestroyImage(va_display, image.image_id); | 586 vaDestroyImage(va_display, image.image_id); |
| 567 } | 587 } |
| 568 | 588 |
| 569 bool VaapiWrapper::UploadVideoFrameToSurface( | 589 bool VaapiWrapper::UploadVideoFrameToSurface( |
| 570 const scoped_refptr<media::VideoFrame>& frame, | 590 const scoped_refptr<media::VideoFrame>& frame, |
| 571 VASurfaceID va_surface_id) { | 591 VASurfaceID va_surface_id) { |
| 572 base::AutoLock auto_lock(va_lock_); | 592 base::AutoLock auto_lock(va_lock_); |
| 573 | 593 |
| 574 VAImage image; | 594 VAImage image; |
| 575 VAStatus va_res = vaDeriveImage(va_display_, va_surface_id, &image); | 595 VAStatus va_res = |
| 596 vaDeriveImage(va_display_, va_surface_id, &image); |
| 576 VA_SUCCESS_OR_RETURN(va_res, "vaDeriveImage failed", false); | 597 VA_SUCCESS_OR_RETURN(va_res, "vaDeriveImage failed", false); |
| 577 base::ScopedClosureRunner vaimage_deleter( | 598 base::ScopedClosureRunner vaimage_deleter( |
| 578 base::Bind(&DestroyVAImage, va_display_, image)); | 599 base::Bind(&DestroyVAImage, va_display_, image)); |
| 579 | 600 |
| 580 if (image.format.fourcc != VA_FOURCC_NV12) { | 601 if (image.format.fourcc != VA_FOURCC_NV12) { |
| 581 DVLOG(1) << "Unsupported image format: " << image.format.fourcc; | 602 DVLOG(1) << "Unsupported image format: " << image.format.fourcc; |
| 582 return false; | 603 return false; |
| 583 } | 604 } |
| 584 | 605 |
| 585 if (gfx::Rect(image.width, image.height) < gfx::Rect(frame->coded_size())) { | 606 if (gfx::Rect(image.width, image.height) < gfx::Rect(frame->coded_size())) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 VASurfaceID sync_surface_id, | 640 VASurfaceID sync_surface_id, |
| 620 uint8* target_ptr, | 641 uint8* target_ptr, |
| 621 size_t target_size, | 642 size_t target_size, |
| 622 size_t* coded_data_size) { | 643 size_t* coded_data_size) { |
| 623 base::AutoLock auto_lock(va_lock_); | 644 base::AutoLock auto_lock(va_lock_); |
| 624 | 645 |
| 625 VAStatus va_res = vaSyncSurface(va_display_, sync_surface_id); | 646 VAStatus va_res = vaSyncSurface(va_display_, sync_surface_id); |
| 626 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 647 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
| 627 | 648 |
| 628 VACodedBufferSegment* buffer_segment = NULL; | 649 VACodedBufferSegment* buffer_segment = NULL; |
| 629 va_res = vaMapBuffer( | 650 va_res = vaMapBuffer(va_display_, |
| 630 va_display_, buffer_id, reinterpret_cast<void**>(&buffer_segment)); | 651 buffer_id, |
| 652 reinterpret_cast<void**>(&buffer_segment)); |
| 631 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false); | 653 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false); |
| 632 DCHECK(target_ptr); | 654 DCHECK(target_ptr); |
| 633 | 655 |
| 634 { | 656 { |
| 635 base::AutoUnlock auto_unlock(va_lock_); | 657 base::AutoUnlock auto_unlock(va_lock_); |
| 636 *coded_data_size = 0; | 658 *coded_data_size = 0; |
| 637 | 659 |
| 638 while (buffer_segment) { | 660 while (buffer_segment) { |
| 639 DCHECK(buffer_segment->buf); | 661 DCHECK(buffer_segment->buf); |
| 640 | 662 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 658 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); | 680 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); |
| 659 | 681 |
| 660 va_res = vaDestroyBuffer(va_display_, buffer_id); | 682 va_res = vaDestroyBuffer(va_display_, buffer_id); |
| 661 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); | 683 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
| 662 | 684 |
| 663 DCHECK(coded_buffers_.erase(buffer_id)); | 685 DCHECK(coded_buffers_.erase(buffer_id)); |
| 664 | 686 |
| 665 return buffer_segment == NULL; | 687 return buffer_segment == NULL; |
| 666 } | 688 } |
| 667 | 689 |
| 690 VADisplay VaapiWrapper::GetDisplay() { |
| 691 return va_display_; |
| 692 } |
| 693 |
| 694 |
| 668 // static | 695 // static |
| 669 bool VaapiWrapper::PostSandboxInitialization() { | 696 bool VaapiWrapper::PostSandboxInitialization() { |
| 670 StubPathMap paths; | 697 StubPathMap paths; |
| 671 paths[kModuleVa].push_back(kVaLib); | 698 |
| 699 paths[kModuleVa].push_back("libva.so.1"); |
| 700 |
| 701 #if defined(USE_X11) |
| 702 paths[kModuleVa_x11].push_back("libva-x11.so.1"); |
| 703 #else |
| 704 paths[kModuleVa_drm].push_back("libva-drm.so.1"); |
| 705 #endif |
| 672 | 706 |
| 673 return InitializeStubs(paths); | 707 return InitializeStubs(paths); |
| 674 } | 708 } |
| 675 | 709 |
| 676 } // namespace content | 710 } // namespace content |
| OLD | NEW |