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

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

Issue 43283002: Enable GLX/EGL backend switching while run HW video decode with libva. (Closed) Base URL: https://git.chromium.org/chromium/src.git@master
Patch Set: Refined based on Fischman's comments. Created 7 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_video_decode_accelerator.cc
diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator.cc
index cd18574a8d8142d65f6fb5485444a60218d62a25..5b145f2867bbacc46662bd2f4a17c2cb403434cc 100644
--- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc
+++ b/content/common/gpu/media/vaapi_video_decode_accelerator.cc
@@ -80,6 +80,13 @@ class VaapiVideoDecodeAccelerator::TFPPicture {
uint32 texture_id,
gfx::Size size);
+ static linked_ptr<TFPPicture> Create(
+ const base::Callback<bool(void)>& make_context_current,
+ const EGLDisplay egl_display,
+ Display* x_display,
+ int32 picture_buffer_id,
+ uint32 texture_id,
+ gfx::Size size);
int32 picture_buffer_id() {
return picture_buffer_id_;
}
@@ -101,12 +108,20 @@ class VaapiVideoDecodeAccelerator::TFPPicture {
private:
TFPPicture(const base::Callback<bool(void)>& make_context_current,
+ GLXFBConfig& fb_config,
+ Display* x_display,
+ int32 picture_buffer_id,
+ uint32 texture_id,
+ gfx::Size size);
+ TFPPicture(const base::Callback<bool(void)>& make_context_current,
+ EGLDisplay egl_display,
Display* x_display,
int32 picture_buffer_id,
uint32 texture_id,
gfx::Size size);
bool Initialize(const GLXFBConfig& fb_config);
+ bool Initialize(const EGLDisplay egl_display);
base::Callback<bool(void)> make_context_current_;
@@ -120,13 +135,33 @@ class VaapiVideoDecodeAccelerator::TFPPicture {
// Pixmaps bound to this texture.
Pixmap x_pixmap_;
+ EGLDisplay egl_display_;
+ EGLImageKHR egl_image_;
GLXPixmap glx_pixmap_;
DISALLOW_COPY_AND_ASSIGN(TFPPicture);
};
+VaapiVideoDecodeAccelerator::TFPPicture::TFPPicture(
+ const base::Callback<bool(void)>& make_context_current,
+ GLXFBConfig& fb_config,
+ Display* x_display,
+ int32 picture_buffer_id,
+ uint32 texture_id,
+ gfx::Size size)
+ : make_context_current_(make_context_current),
+ x_display_(x_display),
+ picture_buffer_id_(picture_buffer_id),
+ texture_id_(texture_id),
+ size_(size),
+ x_pixmap_(0),
+ egl_image_(0),
+ glx_pixmap_(0) {
+ DCHECK(!make_context_current_.is_null());
+};
VaapiVideoDecodeAccelerator::TFPPicture::TFPPicture(
const base::Callback<bool(void)>& make_context_current,
+ EGLDisplay egl_display,
Display* x_display,
int32 picture_buffer_id,
uint32 texture_id,
@@ -137,6 +172,8 @@ VaapiVideoDecodeAccelerator::TFPPicture::TFPPicture(
texture_id_(texture_id),
size_(size),
x_pixmap_(0),
+ egl_display_(egl_display),
+ egl_image_(0),
glx_pixmap_(0) {
DCHECK(!make_context_current_.is_null());
};
@@ -151,8 +188,8 @@ VaapiVideoDecodeAccelerator::TFPPicture::Create(
gfx::Size size) {
linked_ptr<TFPPicture> tfp_picture(
- new TFPPicture(make_context_current, x_display, picture_buffer_id,
- texture_id, size));
+ new TFPPicture(make_context_current, fb_config, x_display,
+ picture_buffer_id, texture_id, size));
if (!tfp_picture->Initialize(fb_config))
tfp_picture.reset();
@@ -160,6 +197,24 @@ VaapiVideoDecodeAccelerator::TFPPicture::Create(
return tfp_picture;
}
+linked_ptr<VaapiVideoDecodeAccelerator::TFPPicture>
+VaapiVideoDecodeAccelerator::TFPPicture::Create(
+ const base::Callback<bool(void)>& make_context_current,
+ const EGLDisplay egl_display,
+ Display* x_display,
+ int32 picture_buffer_id,
+ uint32 texture_id,
+ gfx::Size size) {
+
+ linked_ptr<TFPPicture> tfp_picture(
+ new TFPPicture(make_context_current, egl_display, x_display,
+ picture_buffer_id, texture_id, size));
+
+ if (!tfp_picture->Initialize(egl_display))
+ tfp_picture.reset();
+
+ return tfp_picture;
+}
bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize(
const GLXFBConfig& fb_config) {
// Check for NULL prevents unittests from crashing on nonexistent ChildThread.
@@ -196,6 +251,41 @@ bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize(
return true;
}
+bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize(
+ EGLDisplay egl_display) {
+ // Check for NULL prevents unittests from crashing on nonexistent ChildThread.
+ DCHECK(ChildThread::current() == NULL ||
+ ChildThread::current()->message_loop() == base::MessageLoop::current());
+
+ 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;
+ }
+
+ egl_display_ = egl_display;
+ EGLint image_attrs[] = { EGL_IMAGE_PRESERVED_KHR, 1 , EGL_NONE };
+
+ egl_image_ = eglCreateImageKHR(egl_display_,
+ EGL_NO_CONTEXT,
+ EGL_NATIVE_PIXMAP_KHR,
+ (EGLClientBuffer)x_pixmap_,
+ image_attrs);
+ if (!egl_image_) {
+ DVLOG(1) << "Failed creating a EGLImage from Pixmap for KHR";
+ return false;
+ }
+
+ return true;
+}
VaapiVideoDecodeAccelerator::TFPPicture::~TFPPicture() {
// Check for NULL prevents unittests from crashing on nonexistent ChildThread.
DCHECK(ChildThread::current() == NULL ||
@@ -207,6 +297,10 @@ VaapiVideoDecodeAccelerator::TFPPicture::~TFPPicture() {
glXDestroyPixmap(x_display_, glx_pixmap_);
}
+ if (egl_image_ && make_context_current_.Run()) {
+ eglDestroyImageKHR(egl_display_, egl_image_);
+ }
+
if (x_pixmap_)
XFreePixmap(x_display_, x_pixmap_);
XSync(x_display_, False); // Needed to work around buggy vdpau-driver.
@@ -214,7 +308,7 @@ VaapiVideoDecodeAccelerator::TFPPicture::~TFPPicture() {
bool VaapiVideoDecodeAccelerator::TFPPicture::Bind() {
DCHECK(x_pixmap_);
- DCHECK(glx_pixmap_);
+
// Check for NULL prevents unittests from crashing on nonexistent ChildThread.
DCHECK(ChildThread::current() == NULL ||
ChildThread::current()->message_loop() == base::MessageLoop::current());
@@ -223,8 +317,13 @@ bool VaapiVideoDecodeAccelerator::TFPPicture::Bind() {
return false;
gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_);
- glXBindTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL);
-
+ if(glx_pixmap_) {
+ glXBindTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL);
+ } else if(egl_image_) {
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, egl_image_);
+ } else {
+ return false;
+ }
return true;
}
@@ -244,6 +343,7 @@ VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator(
Client* client,
const base::Callback<bool(void)>& make_context_current)
: x_display_(x_display),
+ egl_context_(0),
glx_context_(glx_context),
make_context_current_(make_context_current),
state_(kUninitialized),
@@ -262,6 +362,30 @@ VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator(
DCHECK(client);
}
+VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator(
+ EGLDisplay egl_display, EGLContext egl_context,
+ Client* client,
+ const base::Callback<bool(void)>& make_context_current)
+ : x_display_(0),
+ egl_display_(egl_display),
+ egl_context_(egl_context),
+ glx_context_(0),
+ make_context_current_(make_context_current),
+ state_(kUninitialized),
+ input_ready_(&lock_),
+ surfaces_available_(&lock_),
+ message_loop_(base::MessageLoop::current()),
+ weak_this_(base::AsWeakPtr(this)),
+ client_ptr_factory_(client),
+ client_(client_ptr_factory_.GetWeakPtr()),
+ decoder_thread_("VaapiDecoderThread"),
+ num_frames_at_client_(0),
+ num_stream_bufs_at_decoder_(0),
+ finish_flush_pending_(false),
+ awaiting_va_surfaces_recycle_(false),
+ requested_num_pics_(0) {
+ DCHECK(client);
+}
VaapiVideoDecodeAccelerator::~VaapiVideoDecodeAccelerator() {
DCHECK_EQ(message_loop_, base::MessageLoop::current());
}
@@ -274,24 +398,31 @@ class ScopedPtrXFree {
};
bool VaapiVideoDecodeAccelerator::InitializeFBConfig() {
- 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_malloc<GLXFBConfig, ScopedPtrXFree> glx_fb_configs(
+ if(glx_context_) {
+ 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_malloc<GLXFBConfig, ScopedPtrXFree> glx_fb_configs(
glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr,
&num_fbconfigs));
- if (!glx_fb_configs)
- return false;
- if (!num_fbconfigs)
+ if (!glx_fb_configs)
+ return false;
+ if (!num_fbconfigs)
+ return false;
+
+ fb_config_ = glx_fb_configs.get()[0];
+ } else if(egl_context_) {
+ x_display_ = base::MessagePumpForUI::GetDefaultXDisplay();
+ } else {
return false;
+ }
- fb_config_ = glx_fb_configs.get()[0];
return true;
}
@@ -716,19 +847,33 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers(
DVLOG(2) << "Assigning picture id: " << buffers[i].id()
<< " to texture id: " << buffers[i].texture_id()
<< " VASurfaceID: " << va_surface_ids[i];
+ if(glx_context_) {
+ linked_ptr<TFPPicture> tfp_picture(
+ TFPPicture::Create(make_context_current_, fb_config_, x_display_,
+ buffers[i].id(), buffers[i].texture_id(),
+ requested_pic_size_));
+
+ RETURN_AND_NOTIFY_ON_FAILURE(
+ tfp_picture.get(), "Failed assigning picture buffer to a texture.",
+ PLATFORM_FAILURE, );
- linked_ptr<TFPPicture> tfp_picture(
- TFPPicture::Create(make_context_current_, fb_config_, x_display_,
- buffers[i].id(), buffers[i].texture_id(),
- requested_pic_size_));
-
- RETURN_AND_NOTIFY_ON_FAILURE(
- tfp_picture.get(), "Failed assigning picture buffer to a texture.",
- PLATFORM_FAILURE, );
+ bool inserted = tfp_pictures_.insert(std::make_pair(
+ buffers[i].id(), tfp_picture)).second;
+ DCHECK(inserted);
+ } else if(egl_context_) {
+ linked_ptr<TFPPicture> tfp_picture(
+ TFPPicture::Create(make_context_current_, egl_display_, x_display_,
+ buffers[i].id(), buffers[i].texture_id(),
+ requested_pic_size_));
+
+ RETURN_AND_NOTIFY_ON_FAILURE(
+ tfp_picture.get(), "Failed assigning picture buffer to a texture.",
+ PLATFORM_FAILURE, );
- bool inserted = tfp_pictures_.insert(std::make_pair(
- buffers[i].id(), tfp_picture)).second;
- DCHECK(inserted);
+ bool inserted = tfp_pictures_.insert(std::make_pair(
+ buffers[i].id(), tfp_picture)).second;
+ DCHECK(inserted);
+ }
output_buffers_.push(buffers[i].id());
available_va_surfaces_.push_back(va_surface_ids[i]);

Powered by Google App Engine
This is Rietveld 408576698