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> | |
spang
2014/09/05 20:45:46
Remove gbm #include.
| |
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 | |
spang
2014/09/05 20:45:46
Add a SurfaceFactoryOzone::GetDrmFd() and implemen
| |
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 |