Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: content/common/gpu/media/vaapi_wrapper.cc

Issue 490233002: VaapiVideoAccelerator: make Vaapi accelerator work with ozone (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove picture destruction sequence Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698