Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1156)

Unified Diff: content/common/gpu/media/vaapi_picture_provider_x11.cc

Issue 490233002: VaapiVideoAccelerator: make Vaapi accelerator work with ozone (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Missing modifications in video accelerators Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/common/gpu/media/vaapi_picture_provider_x11.cc
diff --git a/content/common/gpu/media/vaapi_picture_provider_x11.cc b/content/common/gpu/media/vaapi_picture_provider_x11.cc
new file mode 100644
index 0000000000000000000000000000000000000000..baff46bcab0bc2d3418c5630a0b3adff83528afc
--- /dev/null
+++ b/content/common/gpu/media/vaapi_picture_provider_x11.cc
@@ -0,0 +1,194 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/gpu/media/vaapi_picture_provider_x11.h"
+#include "third_party/libva/va/va_x11.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_context_glx.h"
+#include "ui/gl/gl_image.h"
+#include "ui/gl/scoped_binders.h"
+
+namespace content {
+
+#define LOG_VA_ERROR_AND_RETURN(input, err_msg) \
+ do { \
+ VAStatus va_status = input; \
+ if (va_status != VA_STATUS_SUCCESS) { \
+ DVLOG(1) << err_msg << " : " << vaErrorStr(va_status); \
+ return false; \
+ } \
+ } while (0)
+
+class TFPPicture : public VaapiPictureProvider::Picture {
+ public:
+ TFPPicture(VADisplay va_display,
+ gfx::GLContextGLX* glx_context,
+ const base::Callback<bool(void)> make_context_current,
+ int32 picture_buffer_id,
+ uint32 texture_id,
+ const gfx::Size& size)
+ : Picture(picture_buffer_id, texture_id, size),
+ va_display_(va_display),
+ glx_context_(glx_context),
+ make_context_current_(make_context_current),
+ x_display_(glx_context_->display()) {}
+
+ virtual ~TFPPicture() {
+ if (glx_pixmap_ && make_context_current_.Run()) {
+ glXReleaseTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT);
+ glXDestroyPixmap(x_display_, glx_pixmap_);
+ }
+
+ if (x_pixmap_)
+ XFreePixmap(x_display_, x_pixmap_);
+ XSync(x_display_, False); // Needed to work around buggy vdpau-driver.
+ }
+
+ bool Initialize(GLXFBConfig& fb_config) {
+ if (!make_context_current_.Run())
+ return false;
+
+ XWindowAttributes win_attr;
+ int screen = DefaultScreen(x_display_);
+ XGetWindowAttributes(x_display_, RootWindow(x_display_, screen), &win_attr);
+ // TODO(posciak): pass the depth required by libva, not the RootWindow's
+ // depth
+ x_pixmap_ = XCreatePixmap(x_display_,
+ RootWindow(x_display_, screen),
+ size().width(),
+ size().height(),
+ win_attr.depth);
+ if (!x_pixmap_) {
+ DVLOG(1) << "Failed creating an X Pixmap for TFP";
+ return false;
+ }
+
+ static const int pixmap_attr[] = {
+ GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_TEXTURE_FORMAT_EXT,
+ GLX_TEXTURE_FORMAT_RGB_EXT, GL_NONE,
+ };
+
+ glx_pixmap_ =
+ glXCreatePixmap(x_display_, fb_config, x_pixmap_, pixmap_attr);
+ if (!glx_pixmap_) {
+ // x_pixmap_ will be freed in the destructor.
+ DVLOG(1) << "Failed creating a GLX Pixmap for TFP";
+ return false;
+ }
+
+ return true;
+ }
+
+ bool PutSurface(VASurfaceID va_surface_id) OVERRIDE {
+ if (!make_context_current_.Run()) {
+ DVLOG(1) << "Failed making gl context current";
+ return false;
+ }
+
+ gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id());
+ glXBindTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL);
+ if (glGetError() != GL_NO_ERROR)
+ return false;
+
+ LOG_VA_ERROR_AND_RETURN(vaPutSurface(va_display_,
Pawel Osciak 2014/10/08 08:17:22 Could we please keep using the VaapiWrapper instan
llandwerlin-old 2014/10/08 09:31:18 Acknowledged.
+ va_surface_id,
+ x_pixmap_,
+ 0,
+ 0,
+ size().width(),
+ size().height(),
+ 0,
+ 0,
+ size().width(),
+ size().height(),
+ NULL,
+ 0,
+ 0),
+ "Couldn't put surface into picture");
+ return true;
+ }
+
+ private:
+ VADisplay va_display_;
+
+ gfx::GLContextGLX* glx_context_;
+ base::Callback<bool(void)> make_context_current_;
+ Display* x_display_;
+
+ Pixmap x_pixmap_;
+ GLXPixmap glx_pixmap_;
+};
+
+class XFreeDeleter {
+ public:
+ void operator()(void* x) const { ::XFree(x); }
+};
+
+X11VaapiPictureProvider::X11VaapiPictureProvider(
+ VADisplay va_display,
+ gfx::GLContextGLX* glx_context,
+ const base::Callback<bool(void)> make_context_current)
+ : glx_context_(glx_context),
+ make_context_current_(make_context_current),
+ x_display_(glx_context_->display()),
+ va_display_(va_display) {
+}
+
+X11VaapiPictureProvider::~X11VaapiPictureProvider() {
+}
+
+scoped_ptr<VaapiPictureProvider::Picture>
+X11VaapiPictureProvider::CreatePicture(int32 picture_buffer_id,
+ uint32 texture_id,
+ const gfx::Size& size) {
+ TFPPicture* tfp_picture = new TFPPicture(va_display_,
+ glx_context_,
+ make_context_current_,
+ picture_buffer_id,
+ texture_id,
+ size);
+ scoped_ptr<VaapiPictureProvider::Picture> picture(tfp_picture);
+
+ if (!tfp_picture->Initialize(fb_config_))
+ picture.reset();
+
+ return picture.Pass();
+}
+
+bool X11VaapiPictureProvider::SetCodedSurfacesSize(const gfx::Size& size) {
+ return true;
+}
+
+bool X11VaapiPictureProvider::Initialize() {
+ if (!make_context_current_.Run()) {
+ DVLOG(1) << "Couldn't make context current";
+ return false;
+ }
+
+ const int fbconfig_attr[] = {
+ GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
+ GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
+ GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE,
+ GLX_Y_INVERTED_EXT, GL_TRUE,
+ GL_NONE,
+ };
+
+ int num_fbconfigs;
+ scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs(glXChooseFBConfig(
+ x_display_, DefaultScreen(x_display_), fbconfig_attr, &num_fbconfigs));
+
+ if (!glx_fb_configs) {
+ DVLOG(1) << "Couldn't get glx configs";
+ return false;
+ }
+ if (!num_fbconfigs) {
+ DVLOG(1) << "Couldn't get at least a glx config";
+ return false;
+ }
+
+ fb_config_ = glx_fb_configs.get()[0];
+ return true;
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698