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> |
| 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 { |
| 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 { |
| 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); |
| 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 |