Chromium Code Reviews| 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 |