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 "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 |