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 "content/common/gpu/media/vaapi_picture.h" | |
15 #include "third_party/libyuv/include/libyuv.h" | 16 #include "third_party/libyuv/include/libyuv.h" |
17 #include "ui/gl/gl_bindings.h" | |
18 #if defined(USE_X11) | |
19 #include "content/common/gpu/media/vaapi_tfp_picture.h" | |
20 #include "ui/gfx/x/x11_types.h" | |
21 #else | |
22 #include "content/common/gpu/media/vaapi_drm_picture.h" | |
23 #include "third_party/libva/va/drm/va_drm.h" | |
24 #include "third_party/libva/va/va_drmcommon.h" | |
25 #include "ui/ozone/public/ozone_platform.h" | |
26 #include "ui/ozone/public/surface_factory_ozone.h" | |
27 #endif // USE_X11 | |
16 | 28 |
17 using content_common_gpu_media::kModuleVa; | 29 using content_common_gpu_media::kModuleVa; |
30 #if defined(USE_X11) | |
31 using content_common_gpu_media::kModuleVa_x11; | |
32 #else | |
33 using content_common_gpu_media::kModuleVa_drm; | |
34 #endif // USE_X11 | |
18 using content_common_gpu_media::InitializeStubs; | 35 using content_common_gpu_media::InitializeStubs; |
19 using content_common_gpu_media::StubPathMap; | 36 using content_common_gpu_media::StubPathMap; |
20 | 37 |
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) \ | 38 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ |
26 do { \ | 39 do { \ |
27 LOG(ERROR) << err_msg \ | 40 LOG(ERROR) << err_msg \ |
28 << " VA error: " << vaErrorStr(va_error); \ | 41 << " VA error: " << vaErrorStr(va_error); \ |
29 report_error_to_uma_cb_.Run(); \ | 42 report_error_to_uma_cb_.Run(); \ |
30 } while (0) | 43 } while (0) |
31 | 44 |
32 #define VA_LOG_ON_ERROR(va_error, err_msg) \ | 45 #define VA_LOG_ON_ERROR(va_error, err_msg) \ |
33 do { \ | 46 do { \ |
34 if ((va_error) != VA_STATUS_SUCCESS) \ | 47 if ((va_error) != VA_STATUS_SUCCESS) \ |
35 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ | 48 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ |
36 } while (0) | 49 } while (0) |
37 | 50 |
38 #define VA_SUCCESS_OR_RETURN(va_error, err_msg, ret) \ | 51 #define VA_SUCCESS_OR_RETURN(va_error, err_msg, ret) \ |
39 do { \ | 52 do { \ |
40 if ((va_error) != VA_STATUS_SUCCESS) { \ | 53 if ((va_error) != VA_STATUS_SUCCESS) { \ |
41 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ | 54 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ |
42 return (ret); \ | 55 return (ret); \ |
43 } \ | 56 } \ |
44 } while (0) | 57 } while (0) |
45 | 58 |
59 namespace gfx { | |
60 class GLContextGLX; | |
61 } | |
62 | |
46 namespace content { | 63 namespace content { |
47 | 64 |
65 class VaapiWrapper; | |
Pawel Osciak
2014/12/08 10:55:16
This is needed?
llandwerlin-old
2014/12/08 16:42:07
Removing.
| |
66 | |
48 // Config attributes common for both encode and decode. | 67 // Config attributes common for both encode and decode. |
49 static const VAConfigAttrib kCommonVAConfigAttribs[] = { | 68 static const VAConfigAttrib kCommonVAConfigAttribs[] = { |
50 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420}, | 69 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420}, |
51 }; | 70 }; |
52 | 71 |
53 // Attributes required for encode. | 72 // Attributes required for encode. |
54 static const VAConfigAttrib kEncodeVAConfigAttribs[] = { | 73 static const VAConfigAttrib kEncodeVAConfigAttribs[] = { |
55 {VAConfigAttribRateControl, VA_RC_CBR}, | 74 {VAConfigAttribRateControl, VA_RC_CBR}, |
56 {VAConfigAttribEncPackedHeaders, | 75 {VAConfigAttribEncPackedHeaders, |
57 VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE}, | 76 VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE}, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
115 VAProfileH264ConstrainedBaseline) != | 134 VAProfileH264ConstrainedBaseline) != |
116 supported_profiles.end()) { | 135 supported_profiles.end()) { |
117 va_profile = VAProfileH264ConstrainedBaseline; | 136 va_profile = VAProfileH264ConstrainedBaseline; |
118 DVLOG(1) << "Falling back to constrained baseline profile."; | 137 DVLOG(1) << "Falling back to constrained baseline profile."; |
119 } | 138 } |
120 } | 139 } |
121 | 140 |
122 return va_profile; | 141 return va_profile; |
123 } | 142 } |
124 | 143 |
125 VASurface::VASurface(VASurfaceID va_surface_id, const ReleaseCB& release_cb) | 144 VASurface::VASurface(VASurfaceID va_surface_id, |
126 : va_surface_id_(va_surface_id), | 145 const gfx::Size& size, |
127 release_cb_(release_cb) { | 146 const ReleaseCB& release_cb) |
147 : va_surface_id_(va_surface_id), size_(size), release_cb_(release_cb) { | |
128 DCHECK(!release_cb_.is_null()); | 148 DCHECK(!release_cb_.is_null()); |
129 } | 149 } |
130 | 150 |
131 VASurface::~VASurface() { | 151 VASurface::~VASurface() { |
132 release_cb_.Run(va_surface_id_); | 152 release_cb_.Run(va_surface_id_); |
133 } | 153 } |
134 | 154 |
135 VaapiWrapper::VaapiWrapper() | 155 VaapiWrapper::VaapiWrapper() |
136 : va_display_(NULL), | 156 : va_display_(NULL), |
137 va_config_id_(VA_INVALID_ID), | 157 va_config_id_(VA_INVALID_ID), |
138 va_context_id_(VA_INVALID_ID) { | 158 va_context_id_(VA_INVALID_ID), |
159 va_vpp_config_id_(VA_INVALID_ID), | |
160 va_vpp_context_id_(VA_INVALID_ID), | |
161 va_vpp_buffer_id_(VA_INVALID_ID) { | |
139 } | 162 } |
140 | 163 |
141 VaapiWrapper::~VaapiWrapper() { | 164 VaapiWrapper::~VaapiWrapper() { |
142 DestroyPendingBuffers(); | 165 DestroyPendingBuffers(); |
143 DestroyCodedBuffers(); | 166 DestroyCodedBuffers(); |
144 DestroySurfaces(); | 167 DestroySurfaces(); |
168 DeinitializeVpp(); | |
145 Deinitialize(); | 169 Deinitialize(); |
146 } | 170 } |
147 | 171 |
148 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( | 172 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( |
149 CodecMode mode, | 173 CodecMode mode, |
150 media::VideoCodecProfile profile, | 174 media::VideoCodecProfile profile, |
151 Display* x_display, | |
152 const base::Closure& report_error_to_uma_cb) { | 175 const base::Closure& report_error_to_uma_cb) { |
153 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); | 176 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); |
154 | 177 |
155 if (!vaapi_wrapper->Initialize( | 178 if (!vaapi_wrapper->Initialize(mode, profile, report_error_to_uma_cb)) |
156 mode, profile, x_display, report_error_to_uma_cb)) | 179 vaapi_wrapper = NULL; |
Pawel Osciak
2014/12/08 10:55:16
please keep reset()
llandwerlin-old
2014/12/08 16:42:07
Done.
Pawel Osciak
2014/12/09 01:19:25
Did you miss it?
llandwerlin-old
2014/12/09 11:19:48
There is no reset() method on scoped_refptr. Shoul
| |
157 vaapi_wrapper.reset(); | |
158 | 180 |
159 return vaapi_wrapper.Pass(); | 181 return vaapi_wrapper.Pass(); |
160 } | 182 } |
161 | 183 |
162 std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles( | 184 std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles( |
163 Display* x_display, | |
164 const base::Closure& report_error_to_uma_cb) { | 185 const base::Closure& report_error_to_uma_cb) { |
165 std::vector<media::VideoCodecProfile> supported_profiles; | 186 std::vector<media::VideoCodecProfile> supported_profiles; |
166 | 187 |
167 scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper()); | 188 scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper()); |
168 if (!wrapper->VaInitialize(x_display, report_error_to_uma_cb)) { | 189 if (!wrapper->VaInitialize(report_error_to_uma_cb)) { |
169 return supported_profiles; | 190 return supported_profiles; |
170 } | 191 } |
171 | 192 |
172 std::vector<VAProfile> va_profiles; | 193 std::vector<VAProfile> va_profiles; |
173 if (!wrapper->GetSupportedVaProfiles(&va_profiles)) | 194 if (!wrapper->GetSupportedVaProfiles(&va_profiles)) |
174 return supported_profiles; | 195 return supported_profiles; |
175 | 196 |
176 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode); | 197 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode); |
177 for (size_t i = 0; i < arraysize(kProfileMap); i++) { | 198 for (size_t i = 0; i < arraysize(kProfileMap); i++) { |
178 VAProfile va_profile = | 199 VAProfile va_profile = |
(...skipping 14 matching lines...) Expand all Loading... | |
193 1, // At least support '_LOCAL_OVERLAY'. | 214 1, // At least support '_LOCAL_OVERLAY'. |
194 -1, // The maximum possible support 'ALL'. | 215 -1, // The maximum possible support 'ALL'. |
195 VA_RENDER_MODE_LOCAL_GPU, | 216 VA_RENDER_MODE_LOCAL_GPU, |
196 VA_DISPLAY_ATTRIB_SETTABLE}; | 217 VA_DISPLAY_ATTRIB_SETTABLE}; |
197 | 218 |
198 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); | 219 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); |
199 if (va_res != VA_STATUS_SUCCESS) | 220 if (va_res != VA_STATUS_SUCCESS) |
200 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; | 221 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; |
201 } | 222 } |
202 | 223 |
203 bool VaapiWrapper::VaInitialize(Display* x_display, | 224 bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) { |
204 const base::Closure& report_error_to_uma_cb) { | |
205 static bool vaapi_functions_initialized = PostSandboxInitialization(); | 225 static bool vaapi_functions_initialized = PostSandboxInitialization(); |
206 if (!vaapi_functions_initialized) { | 226 if (!vaapi_functions_initialized) { |
207 LOG(ERROR) << "Failed to initialize VAAPI libs"; | 227 LOG(ERROR) << "Failed to initialize VAAPI libs"; |
208 return false; | 228 return false; |
209 } | 229 } |
210 | 230 |
211 report_error_to_uma_cb_ = report_error_to_uma_cb; | 231 report_error_to_uma_cb_ = report_error_to_uma_cb; |
212 | 232 |
213 base::AutoLock auto_lock(va_lock_); | 233 base::AutoLock auto_lock(va_lock_); |
214 | 234 |
215 va_display_ = vaGetDisplay(x_display); | 235 #if defined(USE_X11) |
236 va_display_ = vaGetDisplay(gfx::GetXDisplay()); | |
237 #else | |
238 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); | |
239 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); | |
Pawel Osciak
2014/12/08 10:55:16
Do we need to check these succeeded?
llandwerlin-old
2014/12/08 16:42:07
I don't think this is necessary. At this point the
| |
240 | |
241 va_display_ = vaGetDisplayDRM(factory->GetDrmFd()); | |
242 #endif // USE_X11 | |
243 | |
216 if (!vaDisplayIsValid(va_display_)) { | 244 if (!vaDisplayIsValid(va_display_)) { |
217 LOG(ERROR) << "Could not get a valid VA display"; | 245 LOG(ERROR) << "Could not get a valid VA display"; |
218 return false; | 246 return false; |
219 } | 247 } |
220 | 248 |
221 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); | 249 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); |
222 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); | 250 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); |
223 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; | 251 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; |
224 | 252 |
225 if (VAAPIVersionLessThan(0, 34)) { | 253 if (VAAPIVersionLessThan(0, 34)) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
301 DVLOG(1) << "Unsupported value " << required_attribs[i].value | 329 DVLOG(1) << "Unsupported value " << required_attribs[i].value |
302 << " for attribute type " << required_attribs[i].type; | 330 << " for attribute type " << required_attribs[i].type; |
303 return false; | 331 return false; |
304 } | 332 } |
305 } | 333 } |
306 return true; | 334 return true; |
307 } | 335 } |
308 | 336 |
309 bool VaapiWrapper::Initialize(CodecMode mode, | 337 bool VaapiWrapper::Initialize(CodecMode mode, |
310 media::VideoCodecProfile profile, | 338 media::VideoCodecProfile profile, |
311 Display* x_display, | |
312 const base::Closure& report_error_to_uma_cb) { | 339 const base::Closure& report_error_to_uma_cb) { |
313 if (!VaInitialize(x_display, report_error_to_uma_cb)) | 340 if (!VaInitialize(report_error_to_uma_cb)) |
314 return false; | 341 return false; |
315 std::vector<VAProfile> supported_va_profiles; | 342 std::vector<VAProfile> supported_va_profiles; |
316 if (!GetSupportedVaProfiles(&supported_va_profiles)) | 343 if (!GetSupportedVaProfiles(&supported_va_profiles)) |
317 return false; | 344 return false; |
318 VAProfile va_profile = ProfileToVAProfile(profile, supported_va_profiles); | 345 VAProfile va_profile = ProfileToVAProfile(profile, supported_va_profiles); |
319 if (va_profile == VAProfileNone) { | 346 if (va_profile == VAProfileNone) { |
320 DVLOG(1) << "Unsupported profile"; | 347 DVLOG(1) << "Unsupported profile"; |
321 return false; | 348 return false; |
322 } | 349 } |
323 VAEntrypoint entrypoint = | 350 VAEntrypoint entrypoint = |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
357 | 384 |
358 va_config_id_ = VA_INVALID_ID; | 385 va_config_id_ = VA_INVALID_ID; |
359 va_display_ = NULL; | 386 va_display_ = NULL; |
360 } | 387 } |
361 | 388 |
362 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { | 389 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { |
363 return (major_version_ < major) || | 390 return (major_version_ < major) || |
364 (major_version_ == major && minor_version_ < minor); | 391 (major_version_ == major && minor_version_ < minor); |
365 } | 392 } |
366 | 393 |
367 bool VaapiWrapper::CreateSurfaces(gfx::Size size, | 394 bool VaapiWrapper::CreateSurfaces(const gfx::Size& size, |
368 size_t num_surfaces, | 395 size_t num_surfaces, |
369 std::vector<VASurfaceID>* va_surfaces) { | 396 std::vector<VASurfaceID>* va_surfaces) { |
370 base::AutoLock auto_lock(va_lock_); | 397 base::AutoLock auto_lock(va_lock_); |
371 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; | 398 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; |
372 | 399 |
373 DCHECK(va_surfaces->empty()); | 400 DCHECK(va_surfaces->empty()); |
374 DCHECK(va_surface_ids_.empty()); | 401 DCHECK(va_surface_ids_.empty()); |
375 va_surface_ids_.resize(num_surfaces); | 402 va_surface_ids_.resize(num_surfaces); |
376 | 403 |
377 // Allocate surfaces in driver. | 404 // Allocate surfaces in driver. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 if (!va_surface_ids_.empty()) { | 443 if (!va_surface_ids_.empty()) { |
417 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], | 444 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], |
418 va_surface_ids_.size()); | 445 va_surface_ids_.size()); |
419 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); | 446 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); |
420 } | 447 } |
421 | 448 |
422 va_surface_ids_.clear(); | 449 va_surface_ids_.clear(); |
423 va_context_id_ = VA_INVALID_ID; | 450 va_context_id_ = VA_INVALID_ID; |
424 } | 451 } |
425 | 452 |
453 scoped_refptr<VASurface> VaapiWrapper::CreateUnownedSurface( | |
454 unsigned int va_format, | |
455 const gfx::Size& size, | |
456 VASurfaceAttrib* va_attribs, | |
457 size_t num_va_attribs) { | |
458 base::AutoLock auto_lock(va_lock_); | |
459 VASurfaceID va_surface_id; | |
460 scoped_refptr<VASurface> va_surface; | |
461 | |
462 VAStatus va_res = vaCreateSurfaces(va_display_, | |
463 va_format, | |
464 size.width(), | |
465 size.height(), | |
466 &va_surface_id, | |
467 1, | |
468 va_attribs, | |
469 num_va_attribs); | |
470 VA_SUCCESS_OR_RETURN( | |
471 va_res, "Failed to create unowned VASurface", va_surface); | |
472 | |
473 va_surface = new VASurface( | |
474 va_surface_id, | |
475 size, | |
476 base::Bind(&VaapiWrapper::DestroyUnownedSurface, AsWeakPtr())); | |
477 | |
478 return va_surface; | |
479 } | |
480 | |
481 linked_ptr<VaapiPicture> VaapiWrapper::CreatePicture( | |
Pawel Osciak
2014/12/08 10:55:16
Please instead have CreatePicture as a static memb
llandwerlin-old
2014/12/08 16:42:07
Done.
| |
482 gfx::GLContext* gl_context, | |
483 const base::Callback<bool(void)> make_context_current, | |
484 int32 picture_buffer_id, | |
485 uint32 texture_id, | |
486 const gfx::Size& size) { | |
487 linked_ptr<VaapiPicture> picture; | |
488 #if defined(USE_X11) | |
489 picture.reset( | |
490 new VaapiTFPPicture(AsWeakPtr(), | |
491 reinterpret_cast<gfx::GLContextGLX*>(gl_context), | |
492 make_context_current, | |
493 picture_buffer_id, | |
494 texture_id, | |
495 size)); | |
496 #else | |
497 picture.reset(new VaapiDrmPicture( | |
498 AsWeakPtr(), make_context_current, picture_buffer_id, texture_id, size)); | |
499 #endif // USE_X11 | |
500 | |
501 if (!picture->Initialize()) | |
502 picture.reset(); | |
503 | |
504 return picture; | |
505 } | |
506 | |
507 void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface) { | |
508 base::AutoLock auto_lock(va_lock_); | |
509 | |
510 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface, 1); | |
511 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on output surface failed"); | |
512 } | |
513 | |
426 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, | 514 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, |
427 size_t size, | 515 size_t size, |
428 void* buffer) { | 516 void* buffer) { |
429 base::AutoLock auto_lock(va_lock_); | 517 base::AutoLock auto_lock(va_lock_); |
430 | 518 |
431 VABufferID buffer_id; | 519 VABufferID buffer_id; |
432 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, | 520 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, |
433 va_buffer_type, size, | 521 va_buffer_type, size, |
434 1, buffer, &buffer_id); | 522 1, buffer, &buffer_id); |
435 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); | 523 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
567 | 655 |
568 return true; | 656 return true; |
569 } | 657 } |
570 | 658 |
571 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { | 659 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { |
572 bool result = Execute(va_surface_id); | 660 bool result = Execute(va_surface_id); |
573 DestroyPendingBuffers(); | 661 DestroyPendingBuffers(); |
574 return result; | 662 return result; |
575 } | 663 } |
576 | 664 |
577 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, | |
578 Pixmap x_pixmap, | |
579 gfx::Size dest_size) { | |
580 base::AutoLock auto_lock(va_lock_); | |
581 | |
582 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | |
583 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | |
584 | |
585 // Put the data into an X Pixmap. | |
586 va_res = vaPutSurface(va_display_, | |
587 va_surface_id, | |
588 x_pixmap, | |
589 0, 0, dest_size.width(), dest_size.height(), | |
590 0, 0, dest_size.width(), dest_size.height(), | |
591 NULL, 0, 0); | |
592 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); | |
593 return true; | |
594 } | |
595 | |
596 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, | 665 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, |
597 VAImage* image, | 666 VAImage* image, |
598 void** mem) { | 667 void** mem) { |
599 base::AutoLock auto_lock(va_lock_); | 668 base::AutoLock auto_lock(va_lock_); |
600 | 669 |
601 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | 670 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
602 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 671 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
603 | 672 |
604 // Derive a VAImage from the VASurface | 673 // Derive a VAImage from the VASurface |
605 va_res = vaDeriveImage(va_display_, va_surface_id, image); | 674 va_res = vaDeriveImage(va_display_, va_surface_id, image); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
726 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); | 795 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); |
727 | 796 |
728 va_res = vaDestroyBuffer(va_display_, buffer_id); | 797 va_res = vaDestroyBuffer(va_display_, buffer_id); |
729 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); | 798 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
730 | 799 |
731 DCHECK(coded_buffers_.erase(buffer_id)); | 800 DCHECK(coded_buffers_.erase(buffer_id)); |
732 | 801 |
733 return buffer_segment == NULL; | 802 return buffer_segment == NULL; |
734 } | 803 } |
735 | 804 |
805 bool VaapiWrapper::BlitSurface(VASurfaceID va_surface_id_src, | |
806 const gfx::Size& src_size, | |
807 VASurfaceID va_surface_id_dest, | |
808 const gfx::Size& dest_size) { | |
809 base::AutoLock auto_lock(va_lock_); | |
810 | |
811 // Initialize the post processing engine if not already done. | |
812 if (va_vpp_buffer_id_ == VA_INVALID_ID) | |
813 if (!InitializeVpp_Locked()) | |
814 return false; | |
815 | |
816 VAProcPipelineParameterBuffer* pipeline_param; | |
817 VA_SUCCESS_OR_RETURN(vaMapBuffer(va_display_, | |
818 va_vpp_buffer_id_, | |
819 reinterpret_cast<void**>(&pipeline_param)), | |
820 "Couldn't map vpp buffer", | |
821 false); | |
822 | |
823 memset(pipeline_param, 0, sizeof *pipeline_param); | |
824 | |
825 VARectangle input_region; | |
826 input_region.x = input_region.y = 0; | |
827 input_region.width = src_size.width(); | |
828 input_region.height = src_size.height(); | |
829 pipeline_param->surface_region = &input_region; | |
830 pipeline_param->surface = va_surface_id_src; | |
831 pipeline_param->surface_color_standard = VAProcColorStandardNone; | |
832 | |
833 VARectangle output_region; | |
834 output_region.x = output_region.y = 0; | |
835 output_region.width = dest_size.width(); | |
836 output_region.height = dest_size.height(); | |
837 pipeline_param->output_region = &output_region; | |
838 pipeline_param->output_background_color = 0xff000000; | |
839 pipeline_param->output_color_standard = VAProcColorStandardNone; | |
840 | |
841 VA_SUCCESS_OR_RETURN(vaUnmapBuffer(va_display_, va_vpp_buffer_id_), | |
842 "Couldn't unmap vpp buffer", | |
843 false); | |
844 | |
845 VA_SUCCESS_OR_RETURN( | |
846 vaBeginPicture(va_display_, va_vpp_context_id_, va_surface_id_dest), | |
847 "Couldn't begin picture", | |
848 false); | |
849 | |
850 VA_SUCCESS_OR_RETURN( | |
851 vaRenderPicture(va_display_, va_vpp_context_id_, &va_vpp_buffer_id_, 1), | |
852 "Couldn't render picture", | |
853 false); | |
854 | |
855 VA_SUCCESS_OR_RETURN(vaEndPicture(va_display_, va_vpp_context_id_), | |
856 "Couldn't end picture", | |
857 false); | |
858 | |
859 return true; | |
860 } | |
861 | |
862 bool VaapiWrapper::InitializeVpp_Locked() { | |
863 va_lock_.AssertAcquired(); | |
864 | |
865 VA_SUCCESS_OR_RETURN(vaCreateConfig(va_display_, | |
866 VAProfileNone, | |
867 VAEntrypointVideoProc, | |
868 NULL, | |
869 0, | |
870 &va_vpp_config_id_), | |
871 "Couldn't create config", | |
872 false); | |
873 | |
874 // The size of the picture for the context is irrelevant in the case | |
875 // of the VPP, just passing 1x1. | |
876 VA_SUCCESS_OR_RETURN(vaCreateContext(va_display_, | |
877 va_vpp_config_id_, | |
878 1, | |
879 1, | |
880 0, | |
881 NULL, | |
882 0, | |
883 &va_vpp_context_id_), | |
884 "Couldn't create context", | |
885 false); | |
886 | |
887 VA_SUCCESS_OR_RETURN(vaCreateBuffer(va_display_, | |
888 va_vpp_context_id_, | |
889 VAProcPipelineParameterBufferType, | |
890 sizeof(VAProcPipelineParameterBuffer), | |
891 1, | |
892 NULL, | |
893 &va_vpp_buffer_id_), | |
894 "Couldn't create buffer", | |
895 false); | |
896 | |
897 return true; | |
898 } | |
899 | |
900 void VaapiWrapper::DeinitializeVpp() { | |
901 base::AutoLock auto_lock(va_lock_); | |
902 DeinitializeVpp_Locked(); | |
Pawel Osciak
2014/12/08 10:55:15
This feels unnecessary.
llandwerlin-old
2014/12/08 16:42:06
Thanks, following the changes on the initializatio
| |
903 } | |
904 | |
905 void VaapiWrapper::DeinitializeVpp_Locked() { | |
906 va_lock_.AssertAcquired(); | |
907 | |
908 if (va_vpp_buffer_id_ != VA_INVALID_ID) { | |
909 vaDestroyBuffer(va_display_, va_vpp_buffer_id_); | |
910 va_vpp_buffer_id_ = VA_INVALID_ID; | |
911 } | |
912 if (va_vpp_context_id_ != VA_INVALID_ID) { | |
913 vaDestroyContext(va_display_, va_vpp_context_id_); | |
914 va_vpp_context_id_ = VA_INVALID_ID; | |
915 } | |
916 if (va_vpp_config_id_ != VA_INVALID_ID) { | |
917 vaDestroyConfig(va_display_, va_vpp_config_id_); | |
918 va_vpp_config_id_ = VA_INVALID_ID; | |
919 } | |
920 } | |
921 | |
922 #if defined(USE_X11) | |
923 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, | |
924 Pixmap x_pixmap, | |
925 gfx::Size dest_size) { | |
926 base::AutoLock auto_lock(va_lock_); | |
927 | |
928 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); | |
929 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | |
930 | |
931 // Put the data into an X Pixmap. | |
932 va_res = vaPutSurface(va_display_, | |
933 va_surface_id, | |
934 x_pixmap, | |
935 0, | |
936 0, | |
937 dest_size.width(), | |
938 dest_size.height(), | |
939 0, | |
940 0, | |
941 dest_size.width(), | |
942 dest_size.height(), | |
943 NULL, | |
944 0, | |
945 0); | |
946 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false); | |
947 return true; | |
948 } | |
949 #endif // USE_X11 | |
950 | |
736 // static | 951 // static |
737 bool VaapiWrapper::PostSandboxInitialization() { | 952 bool VaapiWrapper::PostSandboxInitialization() { |
738 StubPathMap paths; | 953 StubPathMap paths; |
739 paths[kModuleVa].push_back(kVaLib); | 954 |
955 paths[kModuleVa].push_back("libva.so.1"); | |
956 | |
957 #if defined(USE_X11) | |
958 paths[kModuleVa_x11].push_back("libva-x11.so.1"); | |
959 #else | |
960 paths[kModuleVa_drm].push_back("libva-drm.so.1"); | |
961 #endif | |
740 | 962 |
741 return InitializeStubs(paths); | 963 return InitializeStubs(paths); |
742 } | 964 } |
743 | 965 |
744 } // namespace content | 966 } // namespace content |
OLD | NEW |