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