Index: content/common/gpu/media/vaapi_video_decode_accelerator_drm.cc |
diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator_drm.cc |
similarity index 88% |
copy from content/common/gpu/media/vaapi_video_decode_accelerator.cc |
copy to content/common/gpu/media/vaapi_video_decode_accelerator_drm.cc |
index afcfc8a3b0632f2d316fe393c44595f04a1ef714..6c86d2ca426a1c0b9cb7d26e3c328d0dcd3e77b2 100644 |
--- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc |
+++ b/content/common/gpu/media/vaapi_video_decode_accelerator_drm.cc |
@@ -2,6 +2,9 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include <stddef.h> |
+#include <gbm.h> |
+ |
#include "base/bind.h" |
#include "base/debug/trace_event.h" |
#include "base/logging.h" |
@@ -10,11 +13,11 @@ |
#include "base/strings/string_util.h" |
#include "base/synchronization/waitable_event.h" |
#include "base/threading/non_thread_safe.h" |
-#include "content/common/gpu/gpu_channel.h" |
-#include "content/common/gpu/media/vaapi_video_decode_accelerator.h" |
+#include "content/common/gpu/media/vaapi_video_decode_accelerator_drm.h" |
scherkus (not reviewing)
2014/07/29 17:48:54
looks like this .cc file has incorrect include ord
vignatti (out of this project)
2014/07/30 21:51:30
right, I fixed. The problem happened because I've
|
#include "media/base/bind_to_current_loop.h" |
#include "media/video/picture.h" |
#include "ui/gl/gl_bindings.h" |
+#include "ui/gl/gl_surface_egl.h" |
#include "ui/gl/scoped_binders.h" |
static void ReportToUMA( |
@@ -74,8 +77,8 @@ class VaapiVideoDecodeAccelerator::TFPPicture : public base::NonThreadSafe { |
static linked_ptr<TFPPicture> Create( |
const base::Callback<bool(void)>& make_context_current, |
- const GLXFBConfig& fb_config, |
- Display* x_display, |
+ int fd, |
+ VaapiWrapper* va_wrapper, |
int32 picture_buffer_id, |
uint32 texture_id, |
gfx::Size size); |
@@ -88,129 +91,111 @@ class VaapiVideoDecodeAccelerator::TFPPicture : public base::NonThreadSafe { |
return size_; |
} |
- int x_pixmap() { |
- return x_pixmap_; |
- } |
- |
- // Bind texture to pixmap. Needs to be called every frame. |
- bool Bind(); |
+ // Upload vaimage data to texture. Needs to be called every frame. |
+ bool Upload(VASurfaceID id); |
private: |
TFPPicture(const base::Callback<bool(void)>& make_context_current, |
- Display* x_display, |
+ int fd, |
+ VaapiWrapper* va_wrapper, |
int32 picture_buffer_id, |
uint32 texture_id, |
gfx::Size size); |
- bool Initialize(const GLXFBConfig& fb_config); |
+ bool Initialize(); |
base::Callback<bool(void)> make_context_current_; |
- Display* x_display_; |
+ int fd_; |
+ VaapiWrapper* va_wrapper_; |
// Output id for the client. |
int32 picture_buffer_id_; |
uint32 texture_id_; |
gfx::Size size_; |
- |
- // Pixmaps bound to this texture. |
- Pixmap x_pixmap_; |
- GLXPixmap glx_pixmap_; |
+ VAImage va_image_; |
DISALLOW_COPY_AND_ASSIGN(TFPPicture); |
}; |
VaapiVideoDecodeAccelerator::TFPPicture::TFPPicture( |
const base::Callback<bool(void)>& make_context_current, |
- Display* x_display, |
+ int fd, |
+ VaapiWrapper* va_wrapper, |
int32 picture_buffer_id, |
uint32 texture_id, |
gfx::Size size) |
: make_context_current_(make_context_current), |
- x_display_(x_display), |
+ fd_(fd), |
+ va_wrapper_(va_wrapper), |
picture_buffer_id_(picture_buffer_id), |
texture_id_(texture_id), |
- size_(size), |
- x_pixmap_(0), |
- glx_pixmap_(0) { |
+ size_(size) { |
DCHECK(!make_context_current_.is_null()); |
}; |
linked_ptr<VaapiVideoDecodeAccelerator::TFPPicture> |
VaapiVideoDecodeAccelerator::TFPPicture::Create( |
const base::Callback<bool(void)>& make_context_current, |
- const GLXFBConfig& fb_config, |
- Display* x_display, |
+ int fd, |
+ VaapiWrapper* va_wrapper, |
int32 picture_buffer_id, |
uint32 texture_id, |
gfx::Size size) { |
linked_ptr<TFPPicture> tfp_picture( |
- new TFPPicture(make_context_current, x_display, picture_buffer_id, |
+ new TFPPicture(make_context_current, fd, va_wrapper, picture_buffer_id, |
texture_id, size)); |
- if (!tfp_picture->Initialize(fb_config)) |
+ if (!tfp_picture->Initialize()) |
tfp_picture.reset(); |
return tfp_picture; |
} |
-bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize( |
- const GLXFBConfig& fb_config) { |
+bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize() { |
DCHECK(CalledOnValidThread()); |
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"; |
+ if (!va_wrapper_->CreateRGBImage(size_, &va_image_)) { |
+ DVLOG(1) << "Failed to create VAImage"; |
return false; |
} |
- |
return true; |
} |
VaapiVideoDecodeAccelerator::TFPPicture::~TFPPicture() { |
DCHECK(CalledOnValidThread()); |
- // Unbind surface from texture and deallocate resources. |
- if (glx_pixmap_ && make_context_current_.Run()) { |
- glXReleaseTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT); |
- glXDestroyPixmap(x_display_, glx_pixmap_); |
+ if (va_wrapper_) { |
scherkus (not reviewing)
2014/07/29 17:48:54
nit: a lot of this existing code seems to use no {
vignatti (out of this project)
2014/07/30 21:51:30
Done.
|
+ va_wrapper_->DestroyImage(&va_image_); |
} |
- |
- if (x_pixmap_) |
- XFreePixmap(x_display_, x_pixmap_); |
- XSync(x_display_, False); // Needed to work around buggy vdpau-driver. |
} |
-bool VaapiVideoDecodeAccelerator::TFPPicture::Bind() { |
+bool VaapiVideoDecodeAccelerator::TFPPicture::Upload(VASurfaceID surface) { |
DCHECK(CalledOnValidThread()); |
- DCHECK(x_pixmap_); |
- DCHECK(glx_pixmap_); |
if (!make_context_current_.Run()) |
return false; |
+ if (!va_wrapper_->PutSurfaceIntoImage(surface, &va_image_)) { |
+ DVLOG(1) << "Failed to put va surface to image"; |
+ return false; |
+ } |
+ |
+ void* buffer = NULL; |
+ if (!va_wrapper_->MapImage(&va_image_, &buffer)) { |
+ DVLOG(1) << "Failed to map VAImage"; |
+ return false; |
+ } |
+ |
gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, texture_id_); |
- glXBindTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL); |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.width(), size_.height(), |
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); |
+ |
+ va_wrapper_->UnmapImage(&va_image_); |
return true; |
} |
@@ -227,9 +212,8 @@ VaapiVideoDecodeAccelerator::TFPPicture* |
} |
VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator( |
- Display* x_display, |
const base::Callback<bool(void)>& make_context_current) |
- : x_display_(x_display), |
+ : fd_(0), |
make_context_current_(make_context_current), |
state_(kUninitialized), |
input_ready_(&lock_), |
@@ -249,35 +233,7 @@ VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator( |
VaapiVideoDecodeAccelerator::~VaapiVideoDecodeAccelerator() { |
DCHECK_EQ(message_loop_, base::MessageLoop::current()); |
-} |
- |
-class XFreeDeleter { |
- public: |
- void operator()(void* x) const { |
- ::XFree(x); |
- } |
-}; |
- |
-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<GLXFBConfig, XFreeDeleter> glx_fb_configs( |
- glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr, |
- &num_fbconfigs)); |
- if (!glx_fb_configs) |
- return false; |
- if (!num_fbconfigs) |
- return false; |
- |
- fb_config_ = glx_fb_configs.get()[0]; |
- return true; |
+ fd_ = 0; |
scherkus (not reviewing)
2014/07/29 17:48:54
is this really necessary? if we're protecting agai
vignatti (out of this project)
2014/07/30 21:51:30
fd_ was initialized in the constructor and for saf
|
} |
bool VaapiVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, |
@@ -294,15 +250,19 @@ bool VaapiVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, |
if (!make_context_current_.Run()) |
return false; |
- if (!InitializeFBConfig()) { |
- DVLOG(1) << "Could not get a usable FBConfig"; |
+ gbm_device* device = NULL; |
+ device = reinterpret_cast<gbm_device*>( |
+ gfx::GetPlatformDefaultEGLNativeDisplay()); |
+ fd_ = gbm_device_get_fd(device); |
+ if (!fd_) { |
+ DVLOG(1) << "Could not get a usable DRM device"; |
return false; |
} |
vaapi_wrapper_ = VaapiWrapper::Create( |
VaapiWrapper::kDecode, |
profile, |
- x_display_, |
+ fd_, |
base::Bind(&ReportToUMA, content::VaapiH264Decoder::VAAPI_ERROR)); |
if (!vaapi_wrapper_.get()) { |
@@ -356,14 +316,8 @@ void VaapiVideoDecodeAccelerator::OutputPicture( |
DVLOG(3) << "Outputting VASurface " << va_surface->id() |
<< " into pixmap bound to picture buffer id " << output_id; |
- RETURN_AND_NOTIFY_ON_FAILURE(tfp_picture->Bind(), |
- "Failed binding texture to pixmap", |
- PLATFORM_FAILURE, ); |
- |
RETURN_AND_NOTIFY_ON_FAILURE( |
- vaapi_wrapper_->PutSurfaceIntoPixmap(va_surface->id(), |
- tfp_picture->x_pixmap(), |
- tfp_picture->size()), |
+ tfp_picture->Upload(va_surface->id()), |
"Failed putting surface into pixmap", PLATFORM_FAILURE, ); |
// Notify the client a picture is ready to be displayed. |
@@ -704,7 +658,7 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers( |
<< " VASurfaceID: " << va_surface_ids[i]; |
linked_ptr<TFPPicture> tfp_picture( |
- TFPPicture::Create(make_context_current_, fb_config_, x_display_, |
+ TFPPicture::Create(make_context_current_, fd_, vaapi_wrapper_.get(), |
buffers[i].id(), buffers[i].texture_id(), |
requested_pic_size_)); |