OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/common/gpu/media/vaapi_picture_provider.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/callback.h" | |
9 #include "ui/gl/gl_bindings.h" | |
10 #include "ui/gl/gl_image.h" | |
11 #if defined(USE_X11) | |
12 #include "third_party/libva/va/va_x11.h" | |
13 #include "ui/gl/gl_context_glx.h" | |
14 #else | |
15 #include <gbm.h> | |
spang
2014/09/05 20:45:46
Remove gbm #include.
| |
16 #include "third_party/libva/va/drm/va_drm.h" | |
17 #include "third_party/libva/va/va_drmcommon.h" | |
18 #include "ui/gl/gl_image_egl.h" | |
19 #include "ui/ozone/public/native_pixmap.h" | |
20 #include "ui/ozone/public/ozone_platform.h" | |
21 #include "ui/ozone/public/surface_factory_ozone.h" | |
22 #include <va/va_vpp.h> | |
23 #endif // USE_X11 | |
24 #include "ui/gl/scoped_binders.h" | |
25 | |
26 #define LOG_VA_ERROR_AND_RETURN(input, err_msg, output_code) \ | |
27 do { \ | |
28 VAStatus va_status = input; \ | |
29 if (va_status != VA_STATUS_SUCCESS) { \ | |
30 DVLOG(1) << err_msg << " : " << va_status; \ | |
31 output_code; \ | |
32 return false; \ | |
33 } \ | |
34 } while (0) | |
35 | |
36 namespace content { | |
37 | |
38 namespace { | |
39 | |
40 #if defined(USE_X11) | |
41 | |
42 class TFPPicture; | |
43 | |
44 class X11VaapiPictureProvider : public VaapiPictureProvider { | |
45 public: | |
46 X11VaapiPictureProvider( | |
47 VADisplay va_display, | |
48 gfx::GLContextGLX* glx_context, | |
49 const base::Callback<bool(void)> make_context_current); | |
50 virtual ~X11VaapiPictureProvider(); | |
51 | |
52 virtual scoped_ptr<VaapiPictureProvider::Picture> CreatePicture( | |
53 int32 picture_buffer_id, | |
54 uint32 texture_id, | |
55 const gfx::Size& size) OVERRIDE; | |
56 | |
57 void DestroyPicture(TFPPicture* tfp_picture); | |
58 | |
59 virtual bool PutSurfaceIntoPicture( | |
60 VASurfaceID va_surface_id, | |
61 VaapiPictureProvider::Picture* picture) OVERRIDE; | |
62 | |
63 virtual bool Initialize() OVERRIDE; | |
64 | |
65 private: | |
66 | |
67 bool BindPicture(TFPPicture* picture); | |
68 | |
69 gfx::GLContextGLX* glx_context_; | |
70 base::Callback<bool(void)> make_context_current_; | |
71 | |
72 Display* x_display_; | |
73 GLXFBConfig fb_config_; | |
74 | |
75 VADisplay va_display_; | |
76 }; | |
77 | |
78 class TFPPicture : public VaapiPictureProvider::Picture { | |
79 public: | |
80 TFPPicture(X11VaapiPictureProvider* provider, | |
81 int32 picture_buffer_id, | |
82 uint32 texture_id, | |
83 const gfx::Size& size, | |
84 Pixmap x_pixmap, | |
85 GLXPixmap glx_pixmap) | |
86 : Picture(picture_buffer_id, texture_id, size), | |
87 provider_(provider), | |
88 x_pixmap_(x_pixmap), | |
89 glx_pixmap_(glx_pixmap) {} | |
90 virtual ~TFPPicture() { provider_->DestroyPicture(this); } | |
91 | |
92 Pixmap x_pixmap() const { return x_pixmap_; } | |
93 GLXPixmap glx_pixmap() const { return glx_pixmap_; } | |
94 | |
95 private: | |
96 X11VaapiPictureProvider* provider_; | |
97 Pixmap x_pixmap_; | |
98 GLXPixmap glx_pixmap_; | |
99 }; | |
100 | |
101 class XFreeDeleter { | |
102 public: | |
103 void operator()(void* x) const { ::XFree(x); } | |
104 }; | |
105 | |
106 X11VaapiPictureProvider::X11VaapiPictureProvider( | |
107 VADisplay va_display, | |
108 gfx::GLContextGLX* glx_context, | |
109 const base::Callback<bool(void)> make_context_current) | |
110 : glx_context_(glx_context), | |
111 make_context_current_(make_context_current), | |
112 x_display_(glx_context_->display()), | |
113 va_display_(va_display) { | |
114 } | |
115 | |
116 X11VaapiPictureProvider::~X11VaapiPictureProvider() { | |
117 } | |
118 | |
119 scoped_ptr<VaapiPictureProvider::Picture> | |
120 X11VaapiPictureProvider::CreatePicture(int32 picture_buffer_id, | |
121 uint32 texture_id, | |
122 const gfx::Size& size) { | |
123 scoped_ptr<VaapiPictureProvider::Picture> picture; | |
124 | |
125 if (!make_context_current_.Run()) | |
126 return picture.Pass(); | |
127 | |
128 XWindowAttributes win_attr; | |
129 int screen = DefaultScreen(x_display_); | |
130 XGetWindowAttributes(x_display_, RootWindow(x_display_, screen), &win_attr); | |
131 // TODO(posciak): pass the depth required by libva, not the RootWindow's | |
132 // depth | |
133 Pixmap x_pixmap = XCreatePixmap(x_display_, | |
134 RootWindow(x_display_, screen), | |
135 size.width(), | |
136 size.height(), | |
137 win_attr.depth); | |
138 if (!x_pixmap) { | |
139 DVLOG(1) << "Failed creating an X Pixmap for TFP"; | |
140 return picture.Pass(); | |
141 } | |
142 | |
143 static const int pixmap_attr[] = { | |
144 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_TEXTURE_FORMAT_EXT, | |
145 GLX_TEXTURE_FORMAT_RGB_EXT, GL_NONE, | |
146 }; | |
147 | |
148 GLXPixmap glx_pixmap = | |
149 glXCreatePixmap(x_display_, fb_config_, x_pixmap, pixmap_attr); | |
150 if (!glx_pixmap) { | |
151 // x_pixmap_ will be freed in the destructor. | |
152 DVLOG(1) << "Failed creating a GLX Pixmap for TFP"; | |
153 XFreePixmap(x_display_, x_pixmap); | |
154 return picture.Pass(); | |
155 } | |
156 | |
157 picture.reset(new TFPPicture(this, | |
158 picture_buffer_id, | |
159 texture_id, | |
160 size, | |
161 x_pixmap, | |
162 glx_pixmap)); | |
163 | |
164 return picture.Pass(); | |
165 } | |
166 | |
167 void X11VaapiPictureProvider::DestroyPicture(TFPPicture* tfp_picture) { | |
168 // Unbind surface from texture and deallocate resources. | |
169 if (tfp_picture->glx_pixmap() && make_context_current_.Run()) { | |
170 glXReleaseTexImageEXT(x_display_, | |
171 tfp_picture->glx_pixmap(), | |
172 GLX_FRONT_LEFT_EXT); | |
173 glXDestroyPixmap(x_display_, tfp_picture->glx_pixmap()); | |
174 } | |
175 | |
176 if (tfp_picture->x_pixmap()) | |
177 XFreePixmap(x_display_, tfp_picture->x_pixmap()); | |
178 XSync(x_display_, False); // Needed to work around buggy vdpau-driver. | |
179 } | |
180 | |
181 bool X11VaapiPictureProvider::PutSurfaceIntoPicture( | |
182 VASurfaceID va_surface_id, | |
183 VaapiPictureProvider::Picture* picture) { | |
184 TFPPicture* tfp_picture = static_cast<TFPPicture*>(picture); | |
185 const gfx::Size& size = tfp_picture->size(); | |
186 | |
187 if (!BindPicture(tfp_picture)) | |
188 return false; | |
189 | |
190 LOG_VA_ERROR_AND_RETURN(vaPutSurface(va_display_, | |
191 va_surface_id, | |
192 tfp_picture->x_pixmap(), | |
193 0, 0, | |
194 size.width(), | |
195 size.height(), | |
196 0, 0, | |
197 size.width(), | |
198 size.height(), | |
199 NULL, | |
200 0, 0), | |
201 "Couldn't put surface into picture",); | |
202 return true; | |
203 } | |
204 | |
205 bool X11VaapiPictureProvider::Initialize(){ | |
206 if (!make_context_current_.Run()) { | |
207 DVLOG(1) << "Couldn't make context current"; | |
208 return false; | |
209 } | |
210 | |
211 const int fbconfig_attr[] = { | |
212 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, | |
213 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, | |
214 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE, | |
215 GLX_Y_INVERTED_EXT, GL_TRUE, | |
216 GL_NONE, | |
217 }; | |
218 | |
219 int num_fbconfigs; | |
220 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs(glXChooseFBConfig( | |
221 x_display_, DefaultScreen(x_display_), fbconfig_attr, &num_fbconfigs)); | |
222 | |
223 if (!glx_fb_configs) { | |
224 DVLOG(1) << "Couldn't get glx configs"; | |
225 return false; | |
226 } | |
227 if (!num_fbconfigs) { | |
228 DVLOG(1) << "Couldn't get at least a glx config"; | |
229 return false; | |
230 } | |
231 | |
232 fb_config_ = glx_fb_configs.get()[0]; | |
233 return true; | |
234 } | |
235 | |
236 bool X11VaapiPictureProvider::BindPicture(TFPPicture* tfp_picture) { | |
237 if (!make_context_current_.Run()) { | |
238 DVLOG(1) << "Failed making gl context current"; | |
239 return false; | |
240 } | |
241 | |
242 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, | |
243 tfp_picture->texture_id()); | |
244 glXBindTexImageEXT(x_display_, tfp_picture->glx_pixmap(), | |
245 GLX_FRONT_LEFT_EXT, NULL); | |
246 | |
247 return true; | |
248 } | |
249 | |
250 #else | |
251 | |
252 class GbmPicture; | |
253 | |
254 class GbmVaapiPictureProvider : public VaapiPictureProvider { | |
spang
2014/09/05 20:45:46
s/Gbm/Drm/
| |
255 public: | |
256 GbmVaapiPictureProvider( | |
257 VADisplay va_display, | |
258 const base::Callback<bool(void)> make_context_current); | |
259 virtual ~GbmVaapiPictureProvider(); | |
260 | |
261 virtual scoped_ptr<VaapiPictureProvider::Picture> CreatePicture( | |
262 int32 picture_buffer_id, | |
263 uint32 texture_id, | |
264 const gfx::Size& size) OVERRIDE; | |
265 | |
266 void DestroyPicture(GbmPicture* gbm_picture); | |
267 | |
268 virtual bool PutSurfaceIntoPicture( | |
269 VASurfaceID va_surface_id, | |
270 VaapiPictureProvider::Picture* picture) OVERRIDE; | |
271 | |
272 virtual bool SetCodedSurfacesSize(const gfx::Size& size) OVERRIDE; | |
273 | |
274 virtual bool Initialize() OVERRIDE; | |
275 | |
276 private: | |
277 bool InitializeVpp(const gfx::Size& size); | |
278 | |
279 bool IsVppInitialized(); | |
280 | |
281 void DeinitializeVpp(); | |
282 | |
283 base::Callback<bool(void)> make_context_current_; | |
284 | |
285 VADisplay va_display_; | |
286 | |
287 VAConfigID vpp_config_; | |
288 VAContextID vpp_context_; | |
289 VABufferID vpp_buffer_; | |
290 | |
291 gfx::Size coded_picture_size_; | |
292 }; | |
293 | |
294 class GbmPicture : public VaapiPictureProvider::Picture { | |
spang
2014/09/05 20:45:46
s/Gbm/Drm/
| |
295 public: | |
296 GbmPicture(GbmVaapiPictureProvider* provider, | |
297 int32 picture_buffer_id, | |
298 uint32 texture_id, | |
299 const gfx::Size& size, | |
300 VASurfaceID va_surface, | |
301 scoped_refptr<ui::NativePixmap> pixmap, | |
302 scoped_refptr<gfx::GLImage> gl_image) | |
303 : Picture(picture_buffer_id, texture_id, size), | |
304 provider_(provider), | |
305 va_surface_(va_surface), | |
306 pixmap_(pixmap), | |
307 gl_image_(gl_image) {} | |
308 virtual ~GbmPicture() { | |
309 provider_->DestroyPicture(this); | |
310 } | |
311 | |
312 scoped_refptr<gfx::GLImage> gl_image() const { return gl_image_; } | |
313 VASurfaceID va_surface() const { return va_surface_; } | |
314 | |
315 private: | |
316 GbmVaapiPictureProvider* provider_; | |
317 VASurfaceID va_surface_; | |
318 scoped_refptr<ui::NativePixmap> pixmap_; | |
319 scoped_refptr<gfx::GLImage> gl_image_; | |
320 }; | |
321 | |
322 GbmVaapiPictureProvider::GbmVaapiPictureProvider( | |
323 VADisplay va_display, | |
324 const base::Callback<bool(void)> make_context_current) | |
325 : make_context_current_(make_context_current), | |
326 va_display_(va_display), | |
327 vpp_config_(VA_INVALID_ID), | |
328 vpp_context_(VA_INVALID_ID), | |
329 vpp_buffer_(VA_INVALID_ID) { | |
330 } | |
331 | |
332 GbmVaapiPictureProvider::~GbmVaapiPictureProvider() { | |
333 DeinitializeVpp(); | |
334 } | |
335 | |
336 scoped_ptr<VaapiPictureProvider::Picture> | |
337 GbmVaapiPictureProvider::CreatePicture(int32 picture_buffer_id, | |
338 uint32 texture_id, | |
339 const gfx::Size& size) { | |
340 VASurfaceAttrib va_attribs[2]; | |
341 VASurfaceAttribExternalBuffers va_attrib_extbuf; | |
342 | |
343 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); | |
344 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); | |
345 | |
346 scoped_refptr<ui::NativePixmap> pixmap = | |
347 factory->CreateNativePixmap(size, ui::SurfaceFactoryOzone::RGBA_8888); | |
348 struct gbm_bo* bo = static_cast<struct gbm_bo*>(pixmap->GetEGLClientBuffer()); | |
349 unsigned long buffer_fd = pixmap->GetDmaBufFd(); | |
350 VASurfaceID va_surface; | |
351 | |
352 va_attrib_extbuf.pixel_format = VA_FOURCC_BGRX; | |
353 va_attrib_extbuf.width = size.width(); | |
354 va_attrib_extbuf.height = size.height(); | |
355 va_attrib_extbuf.data_size = size.height() * gbm_bo_get_stride (bo); | |
spang
2014/09/05 20:45:46
Move these gbm calls into GbmPixmap & add a virtua
| |
356 va_attrib_extbuf.num_planes = 1; | |
357 va_attrib_extbuf.pitches[0] = gbm_bo_get_stride (bo); | |
358 va_attrib_extbuf.offsets[0] = 0; | |
359 va_attrib_extbuf.buffers = &buffer_fd; | |
360 va_attrib_extbuf.num_buffers = 1; | |
361 va_attrib_extbuf.flags = 0; | |
362 va_attrib_extbuf.private_data = NULL; | |
363 | |
364 va_attribs[0].type = VASurfaceAttribMemoryType; | |
365 va_attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE; | |
366 va_attribs[0].value.type = VAGenericValueTypeInteger; | |
367 va_attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; | |
368 | |
369 va_attribs[1].type = VASurfaceAttribExternalBufferDescriptor; | |
370 va_attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE; | |
371 va_attribs[1].value.type = VAGenericValueTypePointer; | |
372 va_attribs[1].value.value.p = &va_attrib_extbuf; | |
373 | |
374 VAStatus status = vaCreateSurfaces(va_display_, | |
375 VA_RT_FORMAT_RGB32, | |
376 size.width(), | |
377 size.height(), | |
378 &va_surface, | |
379 1, | |
380 va_attribs, | |
381 arraysize(va_attribs)); | |
382 | |
383 scoped_ptr<Picture> picture; | |
384 | |
385 if (status == VA_STATUS_SUCCESS) { | |
386 if (!make_context_current_.Run()) | |
387 return picture.Pass(); | |
388 | |
389 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; | |
390 scoped_refptr<gfx::GLImageEGL> gl_image(new gfx::GLImageEGL(size)); | |
391 gl_image->Initialize( | |
392 EGL_NATIVE_PIXMAP_KHR, | |
393 pixmap->GetEGLClientBuffer(), | |
394 attrs); | |
395 | |
396 | |
397 if (static_cast<int>(glGetError()) != GL_NO_ERROR) | |
398 return picture.Pass(); | |
399 | |
400 picture.reset(new GbmPicture(this, | |
401 picture_buffer_id, | |
402 texture_id, | |
403 size, | |
404 va_surface, | |
405 pixmap, | |
406 gl_image)); | |
407 } | |
408 | |
409 return picture.Pass(); | |
410 } | |
411 | |
412 void GbmVaapiPictureProvider::DestroyPicture(GbmPicture* gbm_picture) { | |
413 VASurfaceID va_surface = gbm_picture->va_surface(); | |
414 | |
415 if (!make_context_current_.Run()) | |
416 return; | |
417 | |
418 // ReleaseTexImage on a GLImageEGL does nothing, do deassociate | |
419 // the renderer texture from the image, just set the storage of | |
420 // that texture to NULL | |
421 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, | |
422 gbm_picture->texture_id()); | |
423 glTexImage2D(GL_TEXTURE_2D, | |
424 0, | |
425 GL_RGBA, | |
426 gbm_picture->size().width(), | |
427 gbm_picture->size().height(), | |
428 0, | |
429 GL_RGBA, | |
430 GL_UNSIGNED_BYTE, | |
431 NULL); | |
432 | |
433 gbm_picture->gl_image()->Destroy(true); | |
434 | |
435 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | |
436 | |
437 vaDestroySurfaces(va_display_, &va_surface, 1); | |
438 } | |
439 | |
440 bool GbmVaapiPictureProvider::PutSurfaceIntoPicture( | |
441 VASurfaceID va_surface_id, | |
442 VaapiPictureProvider::Picture* picture) { | |
443 GbmPicture* gbm_picture = static_cast<GbmPicture*>(picture); | |
444 VAProcPipelineParameterBuffer* pipeline_param; | |
445 VARectangle input_region, output_region; | |
446 | |
447 DCHECK(IsVppInitialized()); | |
448 | |
449 LOG_VA_ERROR_AND_RETURN(vaMapBuffer(va_display_, | |
450 vpp_buffer_, | |
451 (void**)&pipeline_param), | |
452 "Couldn't map buffer",); | |
453 | |
454 memset(pipeline_param, 0, sizeof *pipeline_param); | |
455 | |
456 input_region.x = input_region.y = 0; | |
457 input_region.width = coded_picture_size_.width(); | |
458 input_region.height = coded_picture_size_.height(); | |
459 pipeline_param->surface_region = &input_region; | |
460 pipeline_param->surface = va_surface_id; | |
461 pipeline_param->surface_color_standard = VAProcColorStandardNone; | |
462 | |
463 output_region.x = output_region.y = 0; | |
464 output_region.width = gbm_picture->size().width(); | |
465 output_region.height = gbm_picture->size().height(); | |
466 pipeline_param->output_region = &output_region; | |
467 pipeline_param->output_background_color = 0xff000000; | |
468 pipeline_param->output_color_standard = VAProcColorStandardNone; | |
469 | |
470 LOG_VA_ERROR_AND_RETURN(vaUnmapBuffer(va_display_, vpp_buffer_), | |
471 "Couldn't unmap buffer",); | |
472 | |
473 LOG_VA_ERROR_AND_RETURN(vaBeginPicture(va_display_, | |
474 vpp_context_, | |
475 gbm_picture->va_surface()), | |
476 "Couldn't begin picture",); | |
477 | |
478 LOG_VA_ERROR_AND_RETURN(vaRenderPicture(va_display_, | |
479 vpp_context_, | |
480 &vpp_buffer_, 1), | |
481 "Couldn't render picture",); | |
482 | |
483 LOG_VA_ERROR_AND_RETURN(vaEndPicture(va_display_, vpp_context_), | |
484 "Couldn't end picture", ); | |
485 | |
486 if (!make_context_current_.Run()) | |
487 return VA_STATUS_ERROR_OPERATION_FAILED; | |
488 | |
489 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, | |
490 gbm_picture->texture_id()); | |
491 gbm_picture->gl_image()->BindTexImage(GL_TEXTURE_2D); | |
492 | |
493 if (static_cast<int>(glGetError()) != GL_NO_ERROR) | |
494 return false; | |
495 | |
496 return true; | |
497 } | |
498 | |
499 bool GbmVaapiPictureProvider::SetCodedSurfacesSize(const gfx::Size& size) { | |
500 DeinitializeVpp(); | |
501 return InitializeVpp(size); | |
502 } | |
503 | |
504 | |
505 bool GbmVaapiPictureProvider::Initialize() { | |
506 return true; | |
507 } | |
508 | |
509 bool GbmVaapiPictureProvider::InitializeVpp(const gfx::Size& size) { | |
510 LOG_VA_ERROR_AND_RETURN(vaCreateConfig(va_display_, | |
511 VAProfileNone, | |
512 VAEntrypointVideoProc, | |
513 NULL, | |
514 0, | |
515 &vpp_config_), | |
516 "Couldn't create config",); | |
517 | |
518 LOG_VA_ERROR_AND_RETURN(vaCreateContext(va_display_, | |
519 vpp_config_, | |
520 size.width(), | |
521 size.height(), | |
522 0, | |
523 NULL, | |
524 0, | |
525 &vpp_context_), | |
526 "Couldn't create context", | |
527 DeinitializeVpp()); | |
528 | |
529 LOG_VA_ERROR_AND_RETURN(vaCreateBuffer(va_display_, | |
530 vpp_context_, | |
531 VAProcPipelineParameterBufferType, | |
532 sizeof(VAProcPipelineParameterBuffer), | |
533 1, | |
534 NULL, | |
535 &vpp_buffer_), | |
536 "Couldn't create buffer", | |
537 DeinitializeVpp()); | |
538 | |
539 coded_picture_size_ = size; | |
540 | |
541 return true; | |
542 } | |
543 | |
544 bool GbmVaapiPictureProvider::IsVppInitialized() { | |
545 return vpp_buffer_ != VA_INVALID_ID; | |
546 } | |
547 | |
548 void GbmVaapiPictureProvider::DeinitializeVpp() { | |
549 if (vpp_buffer_ != VA_INVALID_ID) { | |
550 vaDestroyBuffer(va_display_, vpp_buffer_); | |
551 vpp_buffer_ = VA_INVALID_ID; | |
552 } | |
553 if (vpp_context_ != VA_INVALID_ID) { | |
554 vaDestroyContext(va_display_, vpp_context_); | |
555 vpp_context_ = VA_INVALID_ID; | |
556 } | |
557 if (vpp_config_ != VA_INVALID_ID) { | |
558 vaDestroyConfig(va_display_, vpp_config_); | |
559 vpp_config_ = VA_INVALID_ID; | |
560 } | |
561 } | |
562 | |
563 #endif // USE_X11 | |
564 | |
565 } // namespace | |
566 | |
567 | |
568 scoped_ptr<VaapiPictureProvider> VaapiPictureProvider::Create( | |
569 VADisplay va_display, | |
570 gfx::GLContext* gl_context, | |
571 const base::Callback<bool(void)> make_context_current) { | |
572 scoped_ptr<VaapiPictureProvider> backend; | |
573 | |
574 #if defined(USE_X11) | |
575 backend.reset(new X11VaapiPictureProvider( | |
576 va_display, | |
577 static_cast<gfx::GLContextGLX*>(gl_context), | |
578 make_context_current)); | |
579 #else | |
580 backend.reset(new GbmVaapiPictureProvider(va_display, | |
581 make_context_current)); | |
582 #endif // USE_X11 | |
583 | |
584 if (!backend->Initialize()) | |
585 backend.reset(); | |
586 | |
587 return backend.Pass(); | |
588 } | |
589 | |
590 } // namespace content | |
OLD | NEW |