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

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: Created 6 years, 4 months 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/containers/scoped_ptr_hash_map.h"
Pawel Osciak 2014/08/25 01:13:23 Unused?
11 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/scoped_vector.h"
Pawel Osciak 2014/08/25 01:13:24 Unused?
12 #include "base/numerics/safe_conversions.h" 14 #include "base/numerics/safe_conversions.h"
13 // Auto-generated for dlopen libva libraries 15 // Auto-generated for dlopen libva libraries
14 #include "content/common/gpu/media/va_stubs.h" 16 #include "content/common/gpu/media/va_stubs.h"
15 #include "third_party/libyuv/include/libyuv.h" 17 #include "third_party/libyuv/include/libyuv.h"
18 #include "ui/gl/gl_bindings.h"
19 #include "ui/gl/gl_image.h"
20 #if defined(USE_X11)
21 #include "third_party/libva/va/va_x11.h"
22 #include "ui/gl/gl_context_glx.h"
23 #else
24 #include <gbm.h>
25 #include "third_party/libva/va/drm/va_drm.h"
26 #include "third_party/libva/va/va_drmcommon.h"
27 #include "ui/gl/gl_image_egl.h"
28 #include "ui/ozone/public/native_pixmap.h"
29 #include "ui/ozone/public/ozone_platform.h"
30 #include "ui/ozone/public/surface_factory_ozone.h"
31 #include <va/va_vpp.h>
32 #endif // USE_X11
33 #include "ui/gl/scoped_binders.h"
16 34
17 using content_common_gpu_media::kModuleVa; 35 using content_common_gpu_media::kModuleVa;
36 #if defined(USE_X11)
37 using content_common_gpu_media::kModuleVa_x11;
38 #else
39 using content_common_gpu_media::kModuleVa_ozone;
40 #endif // USE_X11
18 using content_common_gpu_media::InitializeStubs; 41 using content_common_gpu_media::InitializeStubs;
19 using content_common_gpu_media::StubPathMap; 42 using content_common_gpu_media::StubPathMap;
20 43
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) \ 44 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \
26 do { \ 45 do { \
27 DVLOG(1) << err_msg \ 46 DVLOG(1) << err_msg \
28 << " VA error: " << vaErrorStr(va_error); \ 47 << " VA error: " << vaErrorStr(va_error); \
29 report_error_to_uma_cb_.Run(); \ 48 report_error_to_uma_cb_.Run(); \
30 } while (0) 49 } while (0)
31 50
32 #define VA_LOG_ON_ERROR(va_error, err_msg) \ 51 #define VA_LOG_ON_ERROR(va_error, err_msg) \
33 do { \ 52 do { \
34 if ((va_error) != VA_STATUS_SUCCESS) \ 53 if ((va_error) != VA_STATUS_SUCCESS) \
35 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ 54 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \
36 } while (0) 55 } while (0)
37 56
38 #define VA_SUCCESS_OR_RETURN(va_error, err_msg, ret) \ 57 #define VA_SUCCESS_OR_RETURN(va_error, err_msg, ret) \
39 do { \ 58 do { \
40 if ((va_error) != VA_STATUS_SUCCESS) { \ 59 if ((va_error) != VA_STATUS_SUCCESS) { \
41 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ 60 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \
42 return (ret); \ 61 return (ret); \
43 } \ 62 } \
44 } while (0) 63 } while (0)
45 64
46 namespace content { 65 namespace content {
47 66
67 class VaapiWrapper::Backend : public base::RefCounted<VaapiWrapper::Backend> {
Pawel Osciak 2014/08/25 01:13:24 Please document all classes that are added.
68 protected:
69 virtual ~Backend() { Deinitialize(); }
70
71 public:
72 virtual VAStatus CreateSurfaces(VASurfaceID* surfaces,
73 uint32 num_surfaces,
74 const gfx::Size& size) = 0;
75
76 virtual linked_ptr<Picture> CreatePicture(int32 picture_buffer_id,
77 uint32 texture_id,
78 const gfx::Size& size) = 0;
79
80 virtual void DestroyPicture(Picture* picture) = 0;
81
82 virtual VAStatus PutSurfaceIntoPicture(VADisplay va_display,
83 VASurfaceID va_surface_id,
84 Picture* picture) = 0;
85
86 virtual VADisplay GetDisplay() = 0;
87
88 virtual bool Initialize() = 0;
89
90 virtual void Deinitialize() {};
Pawel Osciak 2014/08/25 01:13:24 Does this need body?
91
92 static scoped_refptr<Backend> Create(
93 gfx::GLContext* gl_context,
94 const base::Callback<bool(void)> make_context_current);
95
96 private:
97 friend class base::RefCounted<VaapiWrapper::Backend>;
98 };
99
100 #if defined(USE_X11)
101 class VaapiWrapper::TFPPicture : public VaapiWrapper::Picture {
102 public:
103 TFPPicture(scoped_refptr<Backend> backend,
104 int32 picture_buffer_id,
105 uint32 texture_id,
106 const gfx::Size& size,
107 Pixmap x_pixmap,
108 GLXPixmap glx_pixmap)
109 : Picture(picture_buffer_id, texture_id, size),
110 backend_(backend),
111 x_pixmap_(x_pixmap),
112 glx_pixmap_(glx_pixmap) {}
113 virtual ~TFPPicture() { backend_->DestroyPicture(this); }
114
115 Pixmap x_pixmap() const { return x_pixmap_; }
116 GLXPixmap glx_pixmap() const { return glx_pixmap_; }
117
118 private:
119 scoped_refptr<Backend> backend_;
120 Pixmap x_pixmap_;
121 GLXPixmap glx_pixmap_;
122 };
123
124 class XFreeDeleter {
125 public:
126 void operator()(void* x) const { ::XFree(x); }
127 };
128
129 class VaapiWrapper::X11Backend : public VaapiWrapper::Backend {
130 private:
Pawel Osciak 2014/08/25 01:13:24 The proper order of members should start with publ
131 virtual ~X11Backend() {}
132
133 bool BindPicture(Picture* picture) {
134 TFPPicture* tfp_picture = static_cast<TFPPicture*>(picture);
135
136 if (!make_context_current_.Run())
137 return false;
138
139 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D,
140 tfp_picture->texture_id());
141 glXBindTexImageEXT(
142 x_display_, tfp_picture->glx_pixmap(), GLX_FRONT_LEFT_EXT, NULL);
143
144 return true;
145 }
146
147 public:
148 X11Backend(gfx::GLContextGLX* glx_context,
149 const base::Callback<bool(void)> make_context_current)
150 : glx_context_(glx_context),
151 make_context_current_(make_context_current),
152 x_display_(glx_context_->display()),
153 va_display_(NULL) {}
154
155 virtual VAStatus CreateSurfaces(VASurfaceID* surfaces,
156 uint32 num_surfaces,
157 const gfx::Size& size) OVERRIDE {
158 return vaCreateSurfaces(GetDisplay(),
159 VA_RT_FORMAT_YUV420,
160 size.width(),
161 size.height(),
162 surfaces,
163 num_surfaces,
164 NULL,
165 0);
166 }
167
168 virtual linked_ptr<Picture> CreatePicture(int32 picture_buffer_id,
169 uint32 texture_id,
170 const gfx::Size& size) OVERRIDE {
171 linked_ptr<TFPPicture> tfp_picture;
172
173 if (!make_context_current_.Run())
174 return tfp_picture;
175
176 XWindowAttributes win_attr;
177 int screen = DefaultScreen(x_display_);
178 XGetWindowAttributes(x_display_, RootWindow(x_display_, screen), &win_attr);
179 // TODO(posciak): pass the depth required by libva, not the RootWindow's
180 // depth
181 Pixmap x_pixmap = XCreatePixmap(x_display_,
182 RootWindow(x_display_, screen),
183 size.width(),
184 size.height(),
185 win_attr.depth);
186 if (!x_pixmap) {
187 DVLOG(1) << "Failed creating an X Pixmap for TFP";
188 return tfp_picture;
189 }
190
191 static const int pixmap_attr[] = {
192 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_TEXTURE_FORMAT_EXT,
193 GLX_TEXTURE_FORMAT_RGB_EXT, GL_NONE,
194 };
195
196 GLXPixmap glx_pixmap =
197 glXCreatePixmap(x_display_, fb_config_, x_pixmap, pixmap_attr);
198 if (!glx_pixmap) {
199 // x_pixmap_ will be freed in the destructor.
200 DVLOG(1) << "Failed creating a GLX Pixmap for TFP";
201 XFreePixmap(x_display_, x_pixmap);
202 return tfp_picture;
203 }
204
205 tfp_picture.reset(new TFPPicture(make_scoped_refptr(this),
206 picture_buffer_id,
207 texture_id,
208 size,
209 x_pixmap,
210 glx_pixmap));
211
212 return tfp_picture;
213 }
214
215 virtual void DestroyPicture(Picture* picture) OVERRIDE {
216 TFPPicture* tfp_picture = static_cast<TFPPicture*>(picture);
Pawel Osciak 2014/08/25 01:13:23 Please do not cast to children. I think you can so
217
218 // Unbind surface from texture and deallocate resources.
219 if (tfp_picture->glx_pixmap() && make_context_current_.Run()) {
220 glXReleaseTexImageEXT(
221 x_display_, tfp_picture->glx_pixmap(), GLX_FRONT_LEFT_EXT);
222 glXDestroyPixmap(x_display_, tfp_picture->glx_pixmap());
223 }
224
225 if (tfp_picture->x_pixmap())
226 XFreePixmap(x_display_, tfp_picture->x_pixmap());
227 XSync(x_display_, False); // Needed to work around buggy vdpau-driver.
228 }
229
230 virtual VAStatus PutSurfaceIntoPicture(VADisplay va_display,
231 VASurfaceID va_surface_id,
232 Picture* picture) OVERRIDE {
233 TFPPicture* tfp_picture = static_cast<TFPPicture*>(picture);
234 const gfx::Size& size = tfp_picture->size();
235
236 if (!BindPicture(picture))
237 return VA_STATUS_ERROR_OPERATION_FAILED;
238
239 return vaPutSurface(va_display,
240 va_surface_id,
241 tfp_picture->x_pixmap(),
242 0,
243 0,
244 size.width(),
245 size.height(),
246 0,
247 0,
248 size.width(),
249 size.height(),
250 NULL,
251 0,
252 0);
253 }
254
255 virtual VADisplay GetDisplay() OVERRIDE {
256 if (!va_display_)
257 va_display_ = vaGetDisplay(x_display_);
Pawel Osciak 2014/08/25 01:13:24 Why not just call this once in the constructor?
258 return va_display_;
259 }
260
261 virtual bool Initialize() OVERRIDE {
262 if (!make_context_current_.Run()) {
263 DVLOG(1) << "Couldn't make context current";
264 return false;
265 }
266
267 const int fbconfig_attr[] = {
268 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
269 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
270 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE,
271 GLX_Y_INVERTED_EXT, GL_TRUE,
272 GL_NONE,
273 };
274
275 int num_fbconfigs;
276 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs(glXChooseFBConfig(
277 x_display_, DefaultScreen(x_display_), fbconfig_attr, &num_fbconfigs));
278
279 if (!glx_fb_configs) {
280 DVLOG(1) << "Couldn't get glx configs";
281 return false;
282 }
283 if (!num_fbconfigs) {
284 DVLOG(1) << "Couldn't get at least a glx config";
285 return false;
286 }
287
288 fb_config_ = glx_fb_configs.get()[0];
289 return true;
290 }
291
292 virtual void Deinitialize() OVERRIDE { va_display_ = NULL; }
293
294 private:
295 gfx::GLContextGLX* glx_context_;
296 base::Callback<bool(void)> make_context_current_;
297
298 Display* x_display_;
299 GLXFBConfig fb_config_;
300
301 VADisplay va_display_;
302 };
303
304 #else
305
306 class VaapiWrapper::GbmPicture : public VaapiWrapper::Picture {
307 public:
308 GbmPicture(scoped_refptr<Backend> backend,
309 int32 picture_buffer_id,
310 uint32 texture_id,
311 const gfx::Size& size,
312 VASurfaceID va_surface,
313 scoped_refptr<ui::NativePixmap> pixmap,
314 scoped_refptr<gfx::GLImage> gl_image)
315 : Picture(picture_buffer_id, texture_id, size),
316 backend_(backend),
317 va_surface_(va_surface),
318 pixmap_(pixmap),
319 gl_image_(gl_image) {}
320 virtual ~GbmPicture() { backend_->DestroyPicture(this); }
321
322 scoped_refptr<ui::NativePixmap> pixmap() const { return pixmap_; }
Pawel Osciak 2014/08/25 01:13:24 Unused?
323 scoped_refptr<gfx::GLImage> gl_image() const { return gl_image_; }
324 VASurfaceID va_surface() const { return va_surface_; }
325
326 private:
327 scoped_refptr<Backend> backend_;
328 VASurfaceID va_surface_;
329 scoped_refptr<ui::NativePixmap> pixmap_;
330 scoped_refptr<gfx::GLImage> gl_image_;
331 };
332
333 class VaapiWrapper::GbmBackend : public VaapiWrapper::Backend {
334 private:
335 virtual ~GbmBackend() {}
336
337 public:
338 GbmBackend(const base::Callback<bool(void)> make_context_current)
339 : make_context_current_(make_context_current),
340 va_display_(NULL),
341 vpp_config_(VA_INVALID_ID),
342 vpp_context_(VA_INVALID_ID),
343 vpp_buffer_(VA_INVALID_ID) {}
344
345 virtual VAStatus CreateSurfaces(VASurfaceID* surfaces,
346 uint32 num_surfaces,
347 const gfx::Size& size) OVERRIDE {
348 DeinitializeVpp();
349 if (!InitializeVpp(size))
350 return VA_STATUS_ERROR_OPERATION_FAILED;
351
352 return vaCreateSurfaces(GetDisplay(),
353 VA_RT_FORMAT_YUV420,
354 size.width(),
355 size.height(),
356 surfaces,
357 num_surfaces,
358 NULL,
359 0);
360 }
361
362 virtual linked_ptr<Picture> CreatePicture(int32 picture_buffer_id,
363 uint32 texture_id,
364 const gfx::Size& size) OVERRIDE {
365 VASurfaceAttrib va_attribs[2];
366 VASurfaceAttribExternalBuffers va_attrib_extbuf;
367
368 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance();
369 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone();
370
371 scoped_refptr<ui::NativePixmap> pixmap =
372 factory->CreateNativePixmap(size, ui::SurfaceFactoryOzone::RGBA_8888);
373 unsigned long buffer_fd = pixmap->GetDmaBufFd();
374 VASurfaceID va_surface;
375
376 va_attrib_extbuf.pixel_format = VA_FOURCC_BGRX;
377 va_attrib_extbuf.width = size.width();
378 va_attrib_extbuf.height = size.height();
379 va_attrib_extbuf.data_size = size.height() * size.width() * 4;
380 va_attrib_extbuf.num_planes = 1;
381 va_attrib_extbuf.pitches[0] = 4 * size.width();
382 va_attrib_extbuf.offsets[0] = 0;
383 va_attrib_extbuf.buffers = &buffer_fd;
384 va_attrib_extbuf.num_buffers = 1;
385 va_attrib_extbuf.flags = 0;
386 va_attrib_extbuf.private_data = NULL;
387
388 va_attribs[0].type = VASurfaceAttribMemoryType;
389 va_attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
390 va_attribs[0].value.type = VAGenericValueTypeInteger;
391 va_attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
392
393 va_attribs[1].type = VASurfaceAttribExternalBufferDescriptor;
394 va_attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
395 va_attribs[1].value.type = VAGenericValueTypePointer;
396 va_attribs[1].value.value.p = &va_attrib_extbuf;
397
398 VAStatus status = vaCreateSurfaces(GetDisplay(),
399 VA_RT_FORMAT_RGB32,
400 size.width(),
401 size.height(),
402 &va_surface,
403 1,
404 va_attribs,
405 2);
Pawel Osciak 2014/08/25 01:13:24 arraysize(va_attribs)
406
407 linked_ptr<GbmPicture> gbm_picture;
408
409 if (status == VA_STATUS_SUCCESS) {
410 if (!make_context_current_.Run())
411 return gbm_picture;
412
413 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
414 gfx::GLImageEGL* gl_image = new gfx::GLImageEGL(size);
Pawel Osciak 2014/08/25 01:13:23 Could we have a scoper for this instead? Where do
415 gl_image->Initialize(
416 EGL_NATIVE_PIXMAP_KHR, pixmap->GetEGLClientBuffer(), attrs);
417
418 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
Pawel Osciak 2014/08/25 01:13:23 Please don't use CHECK. This crashes the process.
419
420 gbm_picture.reset(new GbmPicture(this,
421 picture_buffer_id,
422 texture_id,
423 size,
424 va_surface,
425 pixmap,
426 gl_image));
427 }
428
429 return gbm_picture;
430 }
431
432 virtual void DestroyPicture(Picture* picture) OVERRIDE {
433 GbmPicture* gbm_picture = static_cast<GbmPicture*>(picture);
434 VASurfaceID va_surface = gbm_picture->va_surface();
435
436 if (!make_context_current_.Run())
437 return;
438
439 // ReleaseTexImage on a GLImageEGL does nothing, do deassociate
440 // the renderer texture from the image, just set the storage of
441 // that texture to NULL
442 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D,
443 gbm_picture->texture_id());
444 glTexImage2D(GL_TEXTURE_2D,
445 0,
446 GL_RGBA,
447 gbm_picture->size().width(),
448 gbm_picture->size().height(),
449 0,
450 GL_RGBA,
451 GL_UNSIGNED_BYTE,
452 NULL);
453
454 gbm_picture->gl_image()->Destroy(true);
455
456 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
457
458 vaDestroySurfaces(GetDisplay(), &va_surface, 1);
459 }
460
461 virtual VAStatus PutSurfaceIntoPicture(VADisplay va_display,
462 VASurfaceID va_surface_id,
463 Picture* picture) OVERRIDE {
464 GbmPicture* gbm_picture = static_cast<GbmPicture*>(picture);
Pawel Osciak 2014/08/25 01:13:23 We cannot cast to child. But you don't really need
465 VAProcPipelineParameterBuffer* pipeline_param;
466 VAStatus status;
467
468 status = vaMapBuffer(GetDisplay(), vpp_buffer_, (void**)&pipeline_param);
469 if (status != VA_STATUS_SUCCESS)
470 return status;
471
472 memset(pipeline_param, 0, sizeof *pipeline_param);
473
474 pipeline_param->surface = va_surface_id;
475 pipeline_param->surface_color_standard = VAProcColorStandardNone;
476
477 pipeline_param->output_background_color = 0xff000000;
478 pipeline_param->output_color_standard = VAProcColorStandardNone;
marcheu 2014/08/29 04:01:09 isn't this going to differ from the X11 path? IIRC
llandwerlin-old 2014/08/29 16:30:55 As far as I can tell the intel driver ignores this
479
480 status = vaUnmapBuffer(GetDisplay(), vpp_buffer_);
481 if (status != VA_STATUS_SUCCESS)
482 return status;
483
484 status =
485 vaBeginPicture(GetDisplay(), vpp_context_, gbm_picture->va_surface());
486 if (status != VA_STATUS_SUCCESS)
487 return status;
488
489 status = vaRenderPicture(GetDisplay(), vpp_context_, &vpp_buffer_, 1);
490 if (status != VA_STATUS_SUCCESS)
491 return status;
492
493 status = vaEndPicture(GetDisplay(), vpp_context_);
494 if (status != VA_STATUS_SUCCESS)
495 return status;
496
497 if (!make_context_current_.Run())
498 return VA_STATUS_ERROR_OPERATION_FAILED;
499
500 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D,
501 gbm_picture->texture_id());
502 gbm_picture->gl_image()->BindTexImage(GL_TEXTURE_2D);
503
504 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
505
506 return VA_STATUS_SUCCESS;
507 }
508
509 virtual VADisplay GetDisplay() OVERRIDE {
510 if (!va_display_) {
511 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance();
512 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone();
513 gbm_device* device =
514 reinterpret_cast<gbm_device*>(factory->GetNativeDisplay());
515
516 va_display_ = vaGetDisplayDRM(gbm_device_get_fd(device));
517 }
518
519 return va_display_;
520 }
521
522 virtual bool Initialize() OVERRIDE { return true; }
523
524 virtual void Deinitialize() OVERRIDE {
525 DeinitializeVpp();
526 va_display_ = NULL;
527 }
528
529 private:
530 bool InitializeVpp(const gfx::Size& size) {
531 VAStatus status;
532
533 status = vaCreateConfig(GetDisplay(),
534 VAProfileNone,
535 VAEntrypointVideoProc,
536 NULL,
537 0,
538 &vpp_config_);
539 if (status != VA_STATUS_SUCCESS) {
540 DVLOG(1) << "Couldn't create VPP config";
541 return false;
542 }
543
544 status = vaCreateContext(GetDisplay(),
545 vpp_config_,
546 size.width(),
547 size.height(),
548 0,
549 NULL,
550 0,
551 &vpp_context_);
552 if (status != VA_STATUS_SUCCESS) {
553 DVLOG(1) << "Couldn't create VPP context";
554 DeinitializeVpp();
Pawel Osciak 2014/08/25 01:13:23 Isn't this called anyway on destruction via Deinit
555 return false;
556 }
557
558 status = vaCreateBuffer(GetDisplay(),
559 vpp_context_,
560 VAProcPipelineParameterBufferType,
561 sizeof(VAProcPipelineParameterBuffer),
562 1,
563 NULL,
564 &vpp_buffer_);
565 if (status != VA_STATUS_SUCCESS) {
566 DVLOG(1) << "Couldn't create VPP pipeline buffer";
567 DeinitializeVpp();
568 return false;
569 }
570
571 return true;
572 }
573
574 bool IsVppInitialized() { return vpp_buffer_ != VA_INVALID_ID; }
575
576 void DeinitializeVpp() {
577 if (vpp_buffer_ != VA_INVALID_ID) {
578 vaDestroyBuffer(GetDisplay(), vpp_buffer_);
579 vpp_buffer_ = VA_INVALID_ID;
580 }
581 if (vpp_context_ != VA_INVALID_ID) {
582 vaDestroyContext(GetDisplay(), vpp_context_);
583 vpp_context_ = VA_INVALID_ID;
584 }
585 if (vpp_config_ != VA_INVALID_ID) {
586 vaDestroyConfig(GetDisplay(), vpp_config_);
587 vpp_config_ = VA_INVALID_ID;
588 }
589 }
590
591 base::Callback<bool(void)> make_context_current_;
592
593 VADisplay va_display_;
594
595 VAConfigID vpp_config_;
596 VAContextID vpp_context_;
597 VABufferID vpp_buffer_;
598 };
599 #endif // USE_X11
600
601 scoped_refptr<VaapiWrapper::Backend> VaapiWrapper::Backend::Create(
602 gfx::GLContext* gl_context,
603 const base::Callback<bool(void)> make_context_current) {
604 scoped_refptr<Backend> backend;
605
606 #if defined(USE_X11)
607 backend = new X11Backend(static_cast<gfx::GLContextGLX*>(gl_context),
608 make_context_current);
609 #else
610 backend = new GbmBackend(make_context_current);
611 #endif // USE_X11
612
613 if (!backend->Initialize())
614 backend = NULL;
615
616 return backend;
617 }
618
48 // Config attributes common for both encode and decode. 619 // Config attributes common for both encode and decode.
49 static const VAConfigAttrib kCommonVAConfigAttribs[] = { 620 static const VAConfigAttrib kCommonVAConfigAttribs[] = {
50 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420}, 621 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420},
51 }; 622 };
52 623
53 // Attributes required for encode. 624 // Attributes required for encode.
54 static const VAConfigAttrib kEncodeVAConfigAttribs[] = { 625 static const VAConfigAttrib kEncodeVAConfigAttribs[] = {
55 {VAConfigAttribRateControl, VA_RC_CBR}, 626 {VAConfigAttribRateControl, VA_RC_CBR},
56 {VAConfigAttribEncPackedHeaders, 627 {VAConfigAttribEncPackedHeaders,
57 VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE}, 628 VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE},
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 : va_surface_id_(va_surface_id), 677 : va_surface_id_(va_surface_id),
107 release_cb_(release_cb) { 678 release_cb_(release_cb) {
108 DCHECK(!release_cb_.is_null()); 679 DCHECK(!release_cb_.is_null());
109 } 680 }
110 681
111 VASurface::~VASurface() { 682 VASurface::~VASurface() {
112 release_cb_.Run(va_surface_id_); 683 release_cb_.Run(va_surface_id_);
113 } 684 }
114 685
115 VaapiWrapper::VaapiWrapper() 686 VaapiWrapper::VaapiWrapper()
116 : va_display_(NULL), 687 : 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 } 688 }
120 689
121 VaapiWrapper::~VaapiWrapper() { 690 VaapiWrapper::~VaapiWrapper() {
122 DestroyPendingBuffers(); 691 DestroyPendingBuffers();
123 DestroyCodedBuffers(); 692 DestroyCodedBuffers();
124 DestroySurfaces(); 693 DestroySurfaces();
125 Deinitialize(); 694 Deinitialize();
126 } 695 }
127 696
128 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( 697 scoped_ptr<VaapiWrapper> VaapiWrapper::Create(
129 CodecMode mode, 698 CodecMode mode,
130 media::VideoCodecProfile profile, 699 media::VideoCodecProfile profile,
131 Display* x_display, 700 gfx::GLContext* gl_context,
701 const base::Callback<bool(void)>& make_context_current,
132 const base::Closure& report_error_to_uma_cb) { 702 const base::Closure& report_error_to_uma_cb) {
133 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); 703 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
134 704
135 if (!vaapi_wrapper->Initialize( 705 if (!vaapi_wrapper->Initialize(mode,
136 mode, profile, x_display, report_error_to_uma_cb)) 706 profile,
707 gl_context,
708 make_context_current,
709 report_error_to_uma_cb))
137 vaapi_wrapper.reset(); 710 vaapi_wrapper.reset();
138 711
139 return vaapi_wrapper.Pass(); 712 return vaapi_wrapper.Pass();
140 } 713 }
141 714
142 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { 715 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
143 VADisplayAttribute item = {VADisplayAttribRenderMode, 716 VADisplayAttribute item = {VADisplayAttribRenderMode,
144 1, // At least support '_LOCAL_OVERLAY'. 717 1, // At least support '_LOCAL_OVERLAY'.
145 -1, // The maximum possible support 'ALL'. 718 -1, // The maximum possible support 'ALL'.
146 VA_RENDER_MODE_LOCAL_GPU, 719 VA_RENDER_MODE_LOCAL_GPU,
147 VA_DISPLAY_ATTRIB_SETTABLE}; 720 VA_DISPLAY_ATTRIB_SETTABLE};
148 721
149 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); 722 VAStatus va_res = vaSetDisplayAttributes(backend_->GetDisplay(), &item, 1);
150 if (va_res != VA_STATUS_SUCCESS) 723 if (va_res != VA_STATUS_SUCCESS)
151 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; 724 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default.";
152 } 725 }
153 726
154 bool VaapiWrapper::Initialize(CodecMode mode, 727 bool VaapiWrapper::Initialize(
155 media::VideoCodecProfile profile, 728 CodecMode mode,
156 Display* x_display, 729 media::VideoCodecProfile profile,
157 const base::Closure& report_error_to_uma_cb) { 730 gfx::GLContext* gl_context,
731 const base::Callback<bool(void)>& make_context_current,
732 const base::Closure& report_error_to_uma_cb) {
158 static bool vaapi_functions_initialized = PostSandboxInitialization(); 733 static bool vaapi_functions_initialized = PostSandboxInitialization();
159 if (!vaapi_functions_initialized) { 734 if (!vaapi_functions_initialized) {
160 DVLOG(1) << "Failed to initialize VAAPI libs"; 735 DVLOG(1) << "Failed to initialize VAAPI libs";
161 return false; 736 return false;
162 } 737 }
163 738
164 report_error_to_uma_cb_ = report_error_to_uma_cb; 739 report_error_to_uma_cb_ = report_error_to_uma_cb;
165 740
166 base::AutoLock auto_lock(va_lock_); 741 base::AutoLock auto_lock(va_lock_);
167 742
168 va_display_ = vaGetDisplay(x_display); 743 backend_ = VaapiWrapper::Backend::Create(gl_context, make_context_current);
Pawel Osciak 2014/08/25 01:13:24 Could we keep va_display_ in VaapiWrapper? We woul
169 if (!vaDisplayIsValid(va_display_)) { 744
745 if (!backend_.get()) {
746 DVLOG(1) << "Failed to initialize VAAPI backend";
747 return false;
748 }
749
750 // va_display_ = backend_->GetDisplay();
751 if (!vaDisplayIsValid(backend_->GetDisplay())) {
170 DVLOG(1) << "Could not get a valid VA display"; 752 DVLOG(1) << "Could not get a valid VA display";
171 return false; 753 return false;
172 } 754 }
173 755
174 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); 756 VAStatus va_res =
757 vaInitialize(backend_->GetDisplay(), &major_version_, &minor_version_);
175 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); 758 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false);
176 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; 759 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_;
177 760
178 if (VAAPIVersionLessThan(0, 34)) { 761 if (VAAPIVersionLessThan(0, 34)) {
179 DVLOG(1) << "VAAPI version < 0.34 is not supported."; 762 DVLOG(1) << "VAAPI version < 0.34 is not supported.";
180 return false; 763 return false;
181 } 764 }
182 765
183 // Query the driver for supported profiles. 766 // Query the driver for supported profiles.
184 int max_profiles = vaMaxNumProfiles(va_display_); 767 int max_profiles = vaMaxNumProfiles(backend_->GetDisplay());
185 std::vector<VAProfile> supported_profiles( 768 std::vector<VAProfile> supported_profiles(
186 base::checked_cast<size_t>(max_profiles)); 769 base::checked_cast<size_t>(max_profiles));
187 770
188 int num_supported_profiles; 771 int num_supported_profiles;
189 va_res = vaQueryConfigProfiles( 772 va_res = vaQueryConfigProfiles(
190 va_display_, &supported_profiles[0], &num_supported_profiles); 773 backend_->GetDisplay(), &supported_profiles[0], &num_supported_profiles);
191 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); 774 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false);
192 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { 775 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) {
193 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles; 776 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles;
194 return false; 777 return false;
195 } 778 }
196 779
197 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); 780 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles));
198 781
199 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles); 782 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles);
200 if (va_profile == VAProfileNone) { 783 if (va_profile == VAProfileNone) {
201 DVLOG(1) << "Unsupported profile"; 784 DVLOG(1) << "Unsupported profile : " << profile;
202 return false; 785 return false;
203 } 786 }
204 787
205 // Query the driver for supported entrypoints. 788 // Query the driver for supported entrypoints.
206 int max_entrypoints = vaMaxNumEntrypoints(va_display_); 789 int max_entrypoints = vaMaxNumEntrypoints(backend_->GetDisplay());
207 std::vector<VAEntrypoint> supported_entrypoints( 790 std::vector<VAEntrypoint> supported_entrypoints(
208 base::checked_cast<size_t>(max_entrypoints)); 791 base::checked_cast<size_t>(max_entrypoints));
209 792
210 int num_supported_entrypoints; 793 int num_supported_entrypoints;
211 va_res = vaQueryConfigEntrypoints(va_display_, 794 va_res = vaQueryConfigEntrypoints(backend_->GetDisplay(),
212 va_profile, 795 va_profile,
213 &supported_entrypoints[0], 796 &supported_entrypoints[0],
214 &num_supported_entrypoints); 797 &num_supported_entrypoints);
215 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false); 798 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false);
216 if (num_supported_entrypoints < 0 || 799 if (num_supported_entrypoints < 0 ||
217 num_supported_entrypoints > max_entrypoints) { 800 num_supported_entrypoints > max_entrypoints) {
218 DVLOG(1) << "vaQueryConfigEntrypoints returned: " 801 DVLOG(1) << "vaQueryConfigEntrypoints returned: "
219 << num_supported_entrypoints; 802 << num_supported_entrypoints;
220 return false; 803 return false;
221 } 804 }
(...skipping 18 matching lines...) Expand all
240 required_attribs.insert( 823 required_attribs.insert(
241 required_attribs.end(), 824 required_attribs.end(),
242 kEncodeVAConfigAttribs, 825 kEncodeVAConfigAttribs,
243 kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs)); 826 kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs));
244 } 827 }
245 828
246 std::vector<VAConfigAttrib> attribs = required_attribs; 829 std::vector<VAConfigAttrib> attribs = required_attribs;
247 for (size_t i = 0; i < required_attribs.size(); ++i) 830 for (size_t i = 0; i < required_attribs.size(); ++i)
248 attribs[i].value = 0; 831 attribs[i].value = 0;
249 832
250 va_res = vaGetConfigAttributes( 833 va_res = vaGetConfigAttributes(backend_->GetDisplay(),
251 va_display_, va_profile, entrypoint, &attribs[0], attribs.size()); 834 va_profile,
835 entrypoint,
836 &attribs[0],
837 attribs.size());
252 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false); 838 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false);
253 839
254 for (size_t i = 0; i < required_attribs.size(); ++i) { 840 for (size_t i = 0; i < required_attribs.size(); ++i) {
255 if (attribs[i].type != required_attribs[i].type || 841 if (attribs[i].type != required_attribs[i].type ||
256 (attribs[i].value & required_attribs[i].value) != 842 (attribs[i].value & required_attribs[i].value) !=
257 required_attribs[i].value) { 843 required_attribs[i].value) {
258 DVLOG(1) << "Unsupported value " << required_attribs[i].value 844 DVLOG(1) << "Unsupported value " << required_attribs[i].value
259 << " for attribute type " << required_attribs[i].type; 845 << " for attribute type " << required_attribs[i].type;
260 return false; 846 return false;
261 } 847 }
262 } 848 }
263 849
264 TryToSetVADisplayAttributeToLocalGPU(); 850 TryToSetVADisplayAttributeToLocalGPU();
265 851
266 va_res = vaCreateConfig(va_display_, 852 va_res = vaCreateConfig(backend_->GetDisplay(),
267 va_profile, 853 va_profile,
268 entrypoint, 854 entrypoint,
269 &required_attribs[0], 855 &required_attribs[0],
270 required_attribs.size(), 856 required_attribs.size(),
271 &va_config_id_); 857 &va_config_id_);
272 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false); 858 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false);
273 859
274 return true; 860 return true;
275 } 861 }
276 862
277 void VaapiWrapper::Deinitialize() { 863 void VaapiWrapper::Deinitialize() {
278 base::AutoLock auto_lock(va_lock_); 864 base::AutoLock auto_lock(va_lock_);
279 865
280 if (va_config_id_ != VA_INVALID_ID) { 866 if (va_config_id_ != VA_INVALID_ID) {
281 VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_); 867 VAStatus va_res = vaDestroyConfig(backend_->GetDisplay(), va_config_id_);
282 VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed"); 868 VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed");
283 } 869 }
284 870
285 if (va_display_) { 871 if (backend_->GetDisplay()) {
286 VAStatus va_res = vaTerminate(va_display_); 872 VAStatus va_res = vaTerminate(backend_->GetDisplay());
287 VA_LOG_ON_ERROR(va_res, "vaTerminate failed"); 873 VA_LOG_ON_ERROR(va_res, "vaTerminate failed");
288 } 874 }
289 875
290 va_config_id_ = VA_INVALID_ID; 876 va_config_id_ = VA_INVALID_ID;
291 va_display_ = NULL; 877 backend_ = NULL;
292 } 878 }
293 879
294 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { 880 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) {
295 return (major_version_ < major) || 881 return (major_version_ < major) ||
296 (major_version_ == major && minor_version_ < minor); 882 (major_version_ == major && minor_version_ < minor);
297 } 883 }
298 884
299 bool VaapiWrapper::CreateSurfaces(gfx::Size size, 885 bool VaapiWrapper::CreateSurfaces(const gfx::Size& size,
300 size_t num_surfaces, 886 size_t num_surfaces,
301 std::vector<VASurfaceID>* va_surfaces) { 887 std::vector<VASurfaceID>* va_surfaces) {
302 base::AutoLock auto_lock(va_lock_); 888 base::AutoLock auto_lock(va_lock_);
303 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; 889 DVLOG(2) << "Creating " << num_surfaces << " surfaces";
304 890
305 DCHECK(va_surfaces->empty()); 891 DCHECK(va_surfaces->empty());
306 DCHECK(va_surface_ids_.empty()); 892 DCHECK(va_surface_ids_.empty());
307 va_surface_ids_.resize(num_surfaces); 893 va_surface_ids_.resize(num_surfaces);
308 894
309 // Allocate surfaces in driver. 895 // Allocate surfaces in driver.
310 VAStatus va_res = vaCreateSurfaces(va_display_, 896 VAStatus va_res = backend_->CreateSurfaces(
311 VA_RT_FORMAT_YUV420, 897 &va_surface_ids_[0], va_surface_ids_.size(), size);
312 size.width(), size.height(),
313 &va_surface_ids_[0],
314 va_surface_ids_.size(),
315 NULL, 0);
316
317 VA_LOG_ON_ERROR(va_res, "vaCreateSurfaces failed"); 898 VA_LOG_ON_ERROR(va_res, "vaCreateSurfaces failed");
318 if (va_res != VA_STATUS_SUCCESS) { 899 if (va_res != VA_STATUS_SUCCESS) {
319 va_surface_ids_.clear(); 900 va_surface_ids_.clear();
320 return false; 901 return false;
321 } 902 }
322 903
323 // And create a context associated with them. 904 // And create a context associated with them.
324 va_res = vaCreateContext(va_display_, va_config_id_, 905 va_res = vaCreateContext(backend_->GetDisplay(),
325 size.width(), size.height(), VA_PROGRESSIVE, 906 va_config_id_,
326 &va_surface_ids_[0], va_surface_ids_.size(), 907 size.width(),
908 size.height(),
909 VA_PROGRESSIVE,
910 &va_surface_ids_[0],
911 va_surface_ids_.size(),
327 &va_context_id_); 912 &va_context_id_);
328 913
329 VA_LOG_ON_ERROR(va_res, "vaCreateContext failed"); 914 VA_LOG_ON_ERROR(va_res, "vaCreateContext failed");
330 if (va_res != VA_STATUS_SUCCESS) { 915 if (va_res != VA_STATUS_SUCCESS) {
331 DestroySurfaces(); 916 DestroySurfaces();
332 return false; 917 return false;
333 } 918 }
334 919
335 *va_surfaces = va_surface_ids_; 920 *va_surfaces = va_surface_ids_;
336 return true; 921 return true;
337 } 922 }
338 923
339 void VaapiWrapper::DestroySurfaces() { 924 void VaapiWrapper::DestroySurfaces() {
340 base::AutoLock auto_lock(va_lock_); 925 base::AutoLock auto_lock(va_lock_);
341 DVLOG(2) << "Destroying " << va_surface_ids_.size() << " surfaces"; 926 DVLOG(2) << "Destroying " << va_surface_ids_.size() << " surfaces";
342 927
343 if (va_context_id_ != VA_INVALID_ID) { 928 if (va_context_id_ != VA_INVALID_ID) {
344 VAStatus va_res = vaDestroyContext(va_display_, va_context_id_); 929 VAStatus va_res = vaDestroyContext(backend_->GetDisplay(), va_context_id_);
345 VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed"); 930 VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed");
346 } 931 }
347 932
348 if (!va_surface_ids_.empty()) { 933 if (!va_surface_ids_.empty()) {
349 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], 934 VAStatus va_res = vaDestroySurfaces(
350 va_surface_ids_.size()); 935 backend_->GetDisplay(), &va_surface_ids_[0], va_surface_ids_.size());
351 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); 936 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed");
352 } 937 }
353 938
354 va_surface_ids_.clear(); 939 va_surface_ids_.clear();
355 va_context_id_ = VA_INVALID_ID; 940 va_context_id_ = VA_INVALID_ID;
356 } 941 }
357 942
943 linked_ptr<VaapiWrapper::Picture> VaapiWrapper::CreatePicture(
944 int32 picture_buffer_id,
945 uint32 texture_id,
946 gfx::Size size) {
947 return backend_->CreatePicture(picture_buffer_id, texture_id, size);
948 }
949
358 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, 950 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type,
359 size_t size, 951 size_t size,
360 void* buffer) { 952 void* buffer) {
361 base::AutoLock auto_lock(va_lock_); 953 base::AutoLock auto_lock(va_lock_);
362 954
363 VABufferID buffer_id; 955 VABufferID buffer_id;
364 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, 956 VAStatus va_res = vaCreateBuffer(backend_->GetDisplay(),
365 va_buffer_type, size, 957 va_context_id_,
366 1, buffer, &buffer_id); 958 va_buffer_type,
959 size,
960 1,
961 buffer,
962 &buffer_id);
367 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); 963 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false);
368 964
369 switch (va_buffer_type) { 965 switch (va_buffer_type) {
370 case VASliceParameterBufferType: 966 case VASliceParameterBufferType:
371 case VASliceDataBufferType: 967 case VASliceDataBufferType:
372 case VAEncSliceParameterBufferType: 968 case VAEncSliceParameterBufferType:
373 pending_slice_bufs_.push_back(buffer_id); 969 pending_slice_bufs_.push_back(buffer_id);
374 break; 970 break;
375 971
376 default: 972 default:
377 pending_va_bufs_.push_back(buffer_id); 973 pending_va_bufs_.push_back(buffer_id);
378 break; 974 break;
379 } 975 }
380 976
381 return true; 977 return true;
382 } 978 }
383 979
384 bool VaapiWrapper::SubmitVAEncMiscParamBuffer( 980 bool VaapiWrapper::SubmitVAEncMiscParamBuffer(
385 VAEncMiscParameterType misc_param_type, 981 VAEncMiscParameterType misc_param_type,
386 size_t size, 982 size_t size,
387 void* buffer) { 983 void* buffer) {
388 base::AutoLock auto_lock(va_lock_); 984 base::AutoLock auto_lock(va_lock_);
389 985
390 VABufferID buffer_id; 986 VABufferID buffer_id;
391 VAStatus va_res = vaCreateBuffer(va_display_, 987 VAStatus va_res = vaCreateBuffer(backend_->GetDisplay(),
392 va_context_id_, 988 va_context_id_,
393 VAEncMiscParameterBufferType, 989 VAEncMiscParameterBufferType,
394 sizeof(VAEncMiscParameterBuffer) + size, 990 sizeof(VAEncMiscParameterBuffer) + size,
395 1, 991 1,
396 NULL, 992 NULL,
397 &buffer_id); 993 &buffer_id);
398 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); 994 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false);
399 995
400 void* data_ptr = NULL; 996 void* data_ptr = NULL;
401 va_res = vaMapBuffer(va_display_, buffer_id, &data_ptr); 997 va_res = vaMapBuffer(backend_->GetDisplay(), buffer_id, &data_ptr);
402 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); 998 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed");
403 if (va_res != VA_STATUS_SUCCESS) { 999 if (va_res != VA_STATUS_SUCCESS) {
404 vaDestroyBuffer(va_display_, buffer_id); 1000 vaDestroyBuffer(backend_->GetDisplay(), buffer_id);
405 return false; 1001 return false;
406 } 1002 }
407 1003
408 DCHECK(data_ptr); 1004 DCHECK(data_ptr);
409 1005
410 VAEncMiscParameterBuffer* misc_param = 1006 VAEncMiscParameterBuffer* misc_param =
411 reinterpret_cast<VAEncMiscParameterBuffer*>(data_ptr); 1007 reinterpret_cast<VAEncMiscParameterBuffer*>(data_ptr);
412 misc_param->type = misc_param_type; 1008 misc_param->type = misc_param_type;
413 memcpy(misc_param->data, buffer, size); 1009 memcpy(misc_param->data, buffer, size);
414 va_res = vaUnmapBuffer(va_display_, buffer_id); 1010 va_res = vaUnmapBuffer(backend_->GetDisplay(), buffer_id);
415 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); 1011 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
416 1012
417 pending_va_bufs_.push_back(buffer_id); 1013 pending_va_bufs_.push_back(buffer_id);
418 return true; 1014 return true;
419 } 1015 }
420 1016
421 void VaapiWrapper::DestroyPendingBuffers() { 1017 void VaapiWrapper::DestroyPendingBuffers() {
422 base::AutoLock auto_lock(va_lock_); 1018 base::AutoLock auto_lock(va_lock_);
423 1019
424 for (size_t i = 0; i < pending_va_bufs_.size(); ++i) { 1020 for (size_t i = 0; i < pending_va_bufs_.size(); ++i) {
425 VAStatus va_res = vaDestroyBuffer(va_display_, pending_va_bufs_[i]); 1021 VAStatus va_res =
1022 vaDestroyBuffer(backend_->GetDisplay(), pending_va_bufs_[i]);
426 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); 1023 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
427 } 1024 }
428 1025
429 for (size_t i = 0; i < pending_slice_bufs_.size(); ++i) { 1026 for (size_t i = 0; i < pending_slice_bufs_.size(); ++i) {
430 VAStatus va_res = vaDestroyBuffer(va_display_, pending_slice_bufs_[i]); 1027 VAStatus va_res =
1028 vaDestroyBuffer(backend_->GetDisplay(), pending_slice_bufs_[i]);
431 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); 1029 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
432 } 1030 }
433 1031
434 pending_va_bufs_.clear(); 1032 pending_va_bufs_.clear();
435 pending_slice_bufs_.clear(); 1033 pending_slice_bufs_.clear();
436 } 1034 }
437 1035
438 bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) { 1036 bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) {
439 base::AutoLock auto_lock(va_lock_); 1037 base::AutoLock auto_lock(va_lock_);
440 VAStatus va_res = vaCreateBuffer(va_display_, 1038 VAStatus va_res = vaCreateBuffer(backend_->GetDisplay(),
441 va_context_id_, 1039 va_context_id_,
442 VAEncCodedBufferType, 1040 VAEncCodedBufferType,
443 size, 1041 size,
444 1, 1042 1,
445 NULL, 1043 NULL,
446 buffer_id); 1044 buffer_id);
447 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a coded buffer", false); 1045 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a coded buffer", false);
448 1046
449 DCHECK(coded_buffers_.insert(*buffer_id).second); 1047 DCHECK(coded_buffers_.insert(*buffer_id).second);
450 return true; 1048 return true;
451 } 1049 }
452 1050
453 void VaapiWrapper::DestroyCodedBuffers() { 1051 void VaapiWrapper::DestroyCodedBuffers() {
454 base::AutoLock auto_lock(va_lock_); 1052 base::AutoLock auto_lock(va_lock_);
455 1053
456 for (std::set<VABufferID>::const_iterator iter = coded_buffers_.begin(); 1054 for (std::set<VABufferID>::const_iterator iter = coded_buffers_.begin();
457 iter != coded_buffers_.end(); 1055 iter != coded_buffers_.end();
458 ++iter) { 1056 ++iter) {
459 VAStatus va_res = vaDestroyBuffer(va_display_, *iter); 1057 VAStatus va_res = vaDestroyBuffer(backend_->GetDisplay(), *iter);
460 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); 1058 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
461 } 1059 }
462 1060
463 coded_buffers_.clear(); 1061 coded_buffers_.clear();
464 } 1062 }
465 1063
466 bool VaapiWrapper::Execute(VASurfaceID va_surface_id) { 1064 bool VaapiWrapper::Execute(VASurfaceID va_surface_id) {
467 base::AutoLock auto_lock(va_lock_); 1065 base::AutoLock auto_lock(va_lock_);
468 1066
469 DVLOG(4) << "Pending VA bufs to commit: " << pending_va_bufs_.size(); 1067 DVLOG(4) << "Pending VA bufs to commit: " << pending_va_bufs_.size();
470 DVLOG(4) << "Pending slice bufs to commit: " << pending_slice_bufs_.size(); 1068 DVLOG(4) << "Pending slice bufs to commit: " << pending_slice_bufs_.size();
471 DVLOG(4) << "Target VA surface " << va_surface_id; 1069 DVLOG(4) << "Target VA surface " << va_surface_id;
472 1070
473 // Get ready to execute for given surface. 1071 // Get ready to execute for given surface.
474 VAStatus va_res = vaBeginPicture(va_display_, va_context_id_, 1072 VAStatus va_res =
475 va_surface_id); 1073 vaBeginPicture(backend_->GetDisplay(), va_context_id_, va_surface_id);
476 VA_SUCCESS_OR_RETURN(va_res, "vaBeginPicture failed", false); 1074 VA_SUCCESS_OR_RETURN(va_res, "vaBeginPicture failed", false);
477 1075
478 if (pending_va_bufs_.size() > 0) { 1076 if (pending_va_bufs_.size() > 0) {
479 // Commit parameter and slice buffers. 1077 // Commit parameter and slice buffers.
480 va_res = vaRenderPicture(va_display_, 1078 va_res = vaRenderPicture(backend_->GetDisplay(),
481 va_context_id_, 1079 va_context_id_,
482 &pending_va_bufs_[0], 1080 &pending_va_bufs_[0],
483 pending_va_bufs_.size()); 1081 pending_va_bufs_.size());
484 VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for va_bufs failed", false); 1082 VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for va_bufs failed", false);
485 } 1083 }
486 1084
487 if (pending_slice_bufs_.size() > 0) { 1085 if (pending_slice_bufs_.size() > 0) {
488 va_res = vaRenderPicture(va_display_, 1086 va_res = vaRenderPicture(backend_->GetDisplay(),
489 va_context_id_, 1087 va_context_id_,
490 &pending_slice_bufs_[0], 1088 &pending_slice_bufs_[0],
491 pending_slice_bufs_.size()); 1089 pending_slice_bufs_.size());
492 VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for slices failed", false); 1090 VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for slices failed", false);
493 } 1091 }
494 1092
495 // Instruct HW codec to start processing committed buffers. 1093 // Instruct HW codec to start processing committed buffers.
496 // Does not block and the job is not finished after this returns. 1094 // Does not block and the job is not finished after this returns.
497 va_res = vaEndPicture(va_display_, va_context_id_); 1095 va_res = vaEndPicture(backend_->GetDisplay(), va_context_id_);
498 VA_SUCCESS_OR_RETURN(va_res, "vaEndPicture failed", false); 1096 VA_SUCCESS_OR_RETURN(va_res, "vaEndPicture failed", false);
499 1097
500 return true; 1098 return true;
501 } 1099 }
502 1100
503 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) { 1101 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) {
504 bool result = Execute(va_surface_id); 1102 bool result = Execute(va_surface_id);
505 DestroyPendingBuffers(); 1103 DestroyPendingBuffers();
506 return result; 1104 return result;
507 } 1105 }
508 1106
509 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, 1107 bool VaapiWrapper::PutSurfaceIntoPicture(VASurfaceID va_surface_id,
510 Pixmap x_pixmap, 1108 Picture* picture) {
511 gfx::Size dest_size) {
512 base::AutoLock auto_lock(va_lock_); 1109 base::AutoLock auto_lock(va_lock_);
513 1110
514 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); 1111 VAStatus va_res = vaSyncSurface(backend_->GetDisplay(), va_surface_id);
515 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); 1112 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
516 1113
517 // Put the data into an X Pixmap. 1114 va_res = backend_->PutSurfaceIntoPicture(
518 va_res = vaPutSurface(va_display_, 1115 backend_->GetDisplay(), va_surface_id, picture);
Pawel Osciak 2014/08/25 01:13:24 We don't need to pass to backend_ its own member.
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); 1116 VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false);
Pawel Osciak 2014/08/25 01:13:24 s/pixmap/picture/?
1117
525 return true; 1118 return true;
526 } 1119 }
527 1120
528 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, 1121 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id,
529 VAImage* image, 1122 VAImage* image,
530 void** mem) { 1123 void** mem) {
531 base::AutoLock auto_lock(va_lock_); 1124 base::AutoLock auto_lock(va_lock_);
532 1125
533 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); 1126 VAStatus va_res = vaSyncSurface(backend_->GetDisplay(), va_surface_id);
534 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); 1127 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
535 1128
536 // Derive a VAImage from the VASurface 1129 // Derive a VAImage from the VASurface
537 va_res = vaDeriveImage(va_display_, va_surface_id, image); 1130 va_res = vaDeriveImage(backend_->GetDisplay(), va_surface_id, image);
538 VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed"); 1131 VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed");
539 if (va_res != VA_STATUS_SUCCESS) 1132 if (va_res != VA_STATUS_SUCCESS)
540 return false; 1133 return false;
541 1134
542 // Map the VAImage into memory 1135 // Map the VAImage into memory
543 va_res = vaMapBuffer(va_display_, image->buf, mem); 1136 va_res = vaMapBuffer(backend_->GetDisplay(), image->buf, mem);
544 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); 1137 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed");
545 if (va_res == VA_STATUS_SUCCESS) 1138 if (va_res == VA_STATUS_SUCCESS)
546 return true; 1139 return true;
547 1140
548 va_res = vaDestroyImage(va_display_, image->image_id); 1141 va_res = vaDestroyImage(backend_->GetDisplay(), image->image_id);
549 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed"); 1142 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed");
550 1143
551 return false; 1144 return false;
552 } 1145 }
553 1146
554 void VaapiWrapper::ReturnVaImageForTesting(VAImage* image) { 1147 void VaapiWrapper::ReturnVaImageForTesting(VAImage* image) {
555 base::AutoLock auto_lock(va_lock_); 1148 base::AutoLock auto_lock(va_lock_);
556 1149
557 VAStatus va_res = vaUnmapBuffer(va_display_, image->buf); 1150 VAStatus va_res = vaUnmapBuffer(backend_->GetDisplay(), image->buf);
558 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); 1151 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
559 1152
560 va_res = vaDestroyImage(va_display_, image->image_id); 1153 va_res = vaDestroyImage(backend_->GetDisplay(), image->image_id);
561 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed"); 1154 VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed");
562 } 1155 }
563 1156
564 static void DestroyVAImage(VADisplay va_display, VAImage image) { 1157 static void DestroyVAImage(VADisplay va_display, VAImage image) {
565 if (image.image_id != VA_INVALID_ID) 1158 if (image.image_id != VA_INVALID_ID)
566 vaDestroyImage(va_display, image.image_id); 1159 vaDestroyImage(va_display, image.image_id);
567 } 1160 }
568 1161
569 bool VaapiWrapper::UploadVideoFrameToSurface( 1162 bool VaapiWrapper::UploadVideoFrameToSurface(
570 const scoped_refptr<media::VideoFrame>& frame, 1163 const scoped_refptr<media::VideoFrame>& frame,
571 VASurfaceID va_surface_id) { 1164 VASurfaceID va_surface_id) {
572 base::AutoLock auto_lock(va_lock_); 1165 base::AutoLock auto_lock(va_lock_);
573 1166
574 VAImage image; 1167 VAImage image;
575 VAStatus va_res = vaDeriveImage(va_display_, va_surface_id, &image); 1168 VAStatus va_res =
1169 vaDeriveImage(backend_->GetDisplay(), va_surface_id, &image);
576 VA_SUCCESS_OR_RETURN(va_res, "vaDeriveImage failed", false); 1170 VA_SUCCESS_OR_RETURN(va_res, "vaDeriveImage failed", false);
577 base::ScopedClosureRunner vaimage_deleter( 1171 base::ScopedClosureRunner vaimage_deleter(
578 base::Bind(&DestroyVAImage, va_display_, image)); 1172 base::Bind(&DestroyVAImage, backend_->GetDisplay(), image));
579 1173
580 if (image.format.fourcc != VA_FOURCC_NV12) { 1174 if (image.format.fourcc != VA_FOURCC_NV12) {
581 DVLOG(1) << "Unsupported image format: " << image.format.fourcc; 1175 DVLOG(1) << "Unsupported image format: " << image.format.fourcc;
582 return false; 1176 return false;
583 } 1177 }
584 1178
585 if (gfx::Rect(image.width, image.height) < gfx::Rect(frame->coded_size())) { 1179 if (gfx::Rect(image.width, image.height) < gfx::Rect(frame->coded_size())) {
586 DVLOG(1) << "Buffer too small to fit the frame."; 1180 DVLOG(1) << "Buffer too small to fit the frame.";
587 return false; 1181 return false;
588 } 1182 }
589 1183
590 void* image_ptr = NULL; 1184 void* image_ptr = NULL;
591 va_res = vaMapBuffer(va_display_, image.buf, &image_ptr); 1185 va_res = vaMapBuffer(backend_->GetDisplay(), image.buf, &image_ptr);
592 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false); 1186 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false);
593 DCHECK(image_ptr); 1187 DCHECK(image_ptr);
594 1188
595 int ret = 0; 1189 int ret = 0;
596 { 1190 {
597 base::AutoUnlock auto_unlock(va_lock_); 1191 base::AutoUnlock auto_unlock(va_lock_);
598 ret = libyuv::I420ToNV12(frame->data(media::VideoFrame::kYPlane), 1192 ret = libyuv::I420ToNV12(frame->data(media::VideoFrame::kYPlane),
599 frame->stride(media::VideoFrame::kYPlane), 1193 frame->stride(media::VideoFrame::kYPlane),
600 frame->data(media::VideoFrame::kUPlane), 1194 frame->data(media::VideoFrame::kUPlane),
601 frame->stride(media::VideoFrame::kUPlane), 1195 frame->stride(media::VideoFrame::kUPlane),
602 frame->data(media::VideoFrame::kVPlane), 1196 frame->data(media::VideoFrame::kVPlane),
603 frame->stride(media::VideoFrame::kVPlane), 1197 frame->stride(media::VideoFrame::kVPlane),
604 static_cast<uint8*>(image_ptr) + image.offsets[0], 1198 static_cast<uint8*>(image_ptr) + image.offsets[0],
605 image.pitches[0], 1199 image.pitches[0],
606 static_cast<uint8*>(image_ptr) + image.offsets[1], 1200 static_cast<uint8*>(image_ptr) + image.offsets[1],
607 image.pitches[1], 1201 image.pitches[1],
608 image.width, 1202 image.width,
609 image.height); 1203 image.height);
610 } 1204 }
611 1205
612 va_res = vaUnmapBuffer(va_display_, image.buf); 1206 va_res = vaUnmapBuffer(backend_->GetDisplay(), image.buf);
613 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); 1207 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
614 1208
615 return ret == 0; 1209 return ret == 0;
616 } 1210 }
617 1211
618 bool VaapiWrapper::DownloadAndDestroyCodedBuffer(VABufferID buffer_id, 1212 bool VaapiWrapper::DownloadAndDestroyCodedBuffer(VABufferID buffer_id,
619 VASurfaceID sync_surface_id, 1213 VASurfaceID sync_surface_id,
620 uint8* target_ptr, 1214 uint8* target_ptr,
621 size_t target_size, 1215 size_t target_size,
622 size_t* coded_data_size) { 1216 size_t* coded_data_size) {
623 base::AutoLock auto_lock(va_lock_); 1217 base::AutoLock auto_lock(va_lock_);
624 1218
625 VAStatus va_res = vaSyncSurface(va_display_, sync_surface_id); 1219 VAStatus va_res = vaSyncSurface(backend_->GetDisplay(), sync_surface_id);
626 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); 1220 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
627 1221
628 VACodedBufferSegment* buffer_segment = NULL; 1222 VACodedBufferSegment* buffer_segment = NULL;
629 va_res = vaMapBuffer( 1223 va_res = vaMapBuffer(backend_->GetDisplay(),
630 va_display_, buffer_id, reinterpret_cast<void**>(&buffer_segment)); 1224 buffer_id,
1225 reinterpret_cast<void**>(&buffer_segment));
631 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false); 1226 VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false);
632 DCHECK(target_ptr); 1227 DCHECK(target_ptr);
633 1228
634 { 1229 {
635 base::AutoUnlock auto_unlock(va_lock_); 1230 base::AutoUnlock auto_unlock(va_lock_);
636 *coded_data_size = 0; 1231 *coded_data_size = 0;
637 1232
638 while (buffer_segment) { 1233 while (buffer_segment) {
639 DCHECK(buffer_segment->buf); 1234 DCHECK(buffer_segment->buf);
640 1235
641 if (buffer_segment->size > target_size) { 1236 if (buffer_segment->size > target_size) {
642 DVLOG(1) << "Insufficient output buffer size"; 1237 DVLOG(1) << "Insufficient output buffer size";
643 break; 1238 break;
644 } 1239 }
645 1240
646 memcpy(target_ptr, buffer_segment->buf, buffer_segment->size); 1241 memcpy(target_ptr, buffer_segment->buf, buffer_segment->size);
647 1242
648 target_ptr += buffer_segment->size; 1243 target_ptr += buffer_segment->size;
649 *coded_data_size += buffer_segment->size; 1244 *coded_data_size += buffer_segment->size;
650 target_size -= buffer_segment->size; 1245 target_size -= buffer_segment->size;
651 1246
652 buffer_segment = 1247 buffer_segment =
653 reinterpret_cast<VACodedBufferSegment*>(buffer_segment->next); 1248 reinterpret_cast<VACodedBufferSegment*>(buffer_segment->next);
654 } 1249 }
655 } 1250 }
656 1251
657 va_res = vaUnmapBuffer(va_display_, buffer_id); 1252 va_res = vaUnmapBuffer(backend_->GetDisplay(), buffer_id);
658 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); 1253 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
659 1254
660 va_res = vaDestroyBuffer(va_display_, buffer_id); 1255 va_res = vaDestroyBuffer(backend_->GetDisplay(), buffer_id);
661 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); 1256 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
662 1257
663 DCHECK(coded_buffers_.erase(buffer_id)); 1258 DCHECK(coded_buffers_.erase(buffer_id));
664 1259
665 return buffer_segment == NULL; 1260 return buffer_segment == NULL;
666 } 1261 }
667 1262
668 // static 1263 // static
669 bool VaapiWrapper::PostSandboxInitialization() { 1264 bool VaapiWrapper::PostSandboxInitialization() {
670 StubPathMap paths; 1265 StubPathMap paths;
671 paths[kModuleVa].push_back(kVaLib); 1266
1267 paths[kModuleVa].push_back("libva.so.1");
1268
1269 #ifdef USE_X11
1270 paths[kModuleVa_x11].push_back("libva-x11.so.1");
1271 #else
1272 paths[kModuleVa_ozone].push_back("libva-drm.so.1");
1273 #endif
672 1274
673 return InitializeStubs(paths); 1275 return InitializeStubs(paths);
674 } 1276 }
675 1277
676 } // namespace content 1278 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698