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

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

Issue 385793002: content: Add support for Video Decode Acceleration on GBM (Closed) Base URL: 038ca4ab40c387bf3bc1541d56578bc522df9f41
Patch Set: merge changes into one single vaapi_video_decode_accelerator Created 6 years, 5 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
« no previous file with comments | « content/common/gpu/media/vaapi_video_decode_accelerator.h ('k') | content/common/gpu/media/vaapi_wrapper.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 afcfc8a3b0632f2d316fe393c44595f04a1ef714..e8aa207142e913dc52df14aa4290842dfc2c8e79 100644
--- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc
+++ b/content/common/gpu/media/vaapi_video_decode_accelerator.cc
@@ -2,6 +2,12 @@
// 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_video_decode_accelerator.h"
+
+#if !defined(USE_X11)
+#include <gbm.h>
+#endif
+
#include "base/bind.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
@@ -11,10 +17,12 @@
#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 "media/base/bind_to_current_loop.h"
#include "media/video/picture.h"
#include "ui/gl/gl_bindings.h"
+#if !defined(USE_X11)
+#include "ui/gl/gl_surface_egl.h"
+#endif
#include "ui/gl/scoped_binders.h"
static void ReportToUMA(
@@ -74,8 +82,13 @@ class VaapiVideoDecodeAccelerator::TFPPicture : public base::NonThreadSafe {
static linked_ptr<TFPPicture> Create(
const base::Callback<bool(void)>& make_context_current,
+#if defined(USE_X11)
const GLXFBConfig& fb_config,
Display* x_display,
+#else
+ int fd,
+ VaapiWrapper* va_wrapper,
+#endif
int32 picture_buffer_id,
uint32 texture_id,
gfx::Size size);
@@ -87,81 +100,129 @@ class VaapiVideoDecodeAccelerator::TFPPicture : public base::NonThreadSafe {
gfx::Size size() {
return size_;
}
-
+#if defined(USE_X11)
int x_pixmap() {
return x_pixmap_;
}
// Bind texture to pixmap. Needs to be called every frame.
bool Bind();
+#else
+ // Upload vaimage data to texture. Needs to be called every frame.
+ bool Upload(VASurfaceID id);
+#endif
private:
TFPPicture(const base::Callback<bool(void)>& make_context_current,
+#if defined(USE_X11)
Display* x_display,
+#else
+ int fd,
+ VaapiWrapper* va_wrapper,
+#endif
int32 picture_buffer_id,
uint32 texture_id,
gfx::Size size);
+#if defined(USE_X11)
bool Initialize(const GLXFBConfig& fb_config);
base::Callback<bool(void)> make_context_current_;
Display* x_display_;
+#else
+ bool Initialize();
+
+ base::Callback<bool(void)> make_context_current_;
+
+ VaapiWrapper* va_wrapper_;
+#endif
// Output id for the client.
int32 picture_buffer_id_;
uint32 texture_id_;
gfx::Size size_;
-
+#if defined(USE_X11)
// Pixmaps bound to this texture.
Pixmap x_pixmap_;
GLXPixmap glx_pixmap_;
-
+#else
+ VAImage va_image_;
+#endif
DISALLOW_COPY_AND_ASSIGN(TFPPicture);
};
VaapiVideoDecodeAccelerator::TFPPicture::TFPPicture(
const base::Callback<bool(void)>& make_context_current,
+#if defined(USE_X11)
Display* x_display,
+#else
+ int fd,
+ VaapiWrapper* va_wrapper,
+#endif
int32 picture_buffer_id,
uint32 texture_id,
gfx::Size size)
: make_context_current_(make_context_current),
+#if defined(USE_X11)
x_display_(x_display),
+ x_pixmap_(0),
+ glx_pixmap_(0),
+#else
+ va_wrapper_(va_wrapper),
+#endif
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,
+#if defined(USE_X11)
const GLXFBConfig& fb_config,
Display* x_display,
+#else
+ int fd,
+ VaapiWrapper* va_wrapper,
+#endif
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,
- texture_id, size));
-
+ new TFPPicture(make_context_current,
+#if defined(USE_X11)
+ x_display,
+#else
+ fd,
+ va_wrapper,
+#endif
+ picture_buffer_id,
+ texture_id,
+ size));
+#if defined(USE_X11)
if (!tfp_picture->Initialize(fb_config))
+#else
+ if (!tfp_picture->Initialize())
+#endif
tfp_picture.reset();
return tfp_picture;
}
+#if defined(USE_X11)
bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize(
const GLXFBConfig& fb_config) {
+#else
+bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize() {
+#endif
DCHECK(CalledOnValidThread());
if (!make_context_current_.Run())
return false;
-
+#if defined(USE_X11)
XWindowAttributes win_attr;
int screen = DefaultScreen(x_display_);
XGetWindowAttributes(x_display_, RootWindow(x_display_, screen), &win_attr);
@@ -185,12 +246,18 @@ bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize(
DVLOG(1) << "Failed creating a GLX Pixmap for TFP";
return false;
}
-
+#else
+ if (!va_wrapper_->CreateRGBImage(size_, &va_image_)) {
+ DVLOG(1) << "Failed to create VAImage";
+ return false;
+ }
+#endif
return true;
}
VaapiVideoDecodeAccelerator::TFPPicture::~TFPPicture() {
DCHECK(CalledOnValidThread());
+#if defined(USE_X11)
// Unbind surface from texture and deallocate resources.
if (glx_pixmap_ && make_context_current_.Run()) {
glXReleaseTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT);
@@ -200,8 +267,13 @@ VaapiVideoDecodeAccelerator::TFPPicture::~TFPPicture() {
if (x_pixmap_)
XFreePixmap(x_display_, x_pixmap_);
XSync(x_display_, False); // Needed to work around buggy vdpau-driver.
+#else
+ if (va_wrapper_)
+ va_wrapper_->DestroyImage(&va_image_);
+#endif
}
+#if defined(USE_X11)
bool VaapiVideoDecodeAccelerator::TFPPicture::Bind() {
DCHECK(CalledOnValidThread());
DCHECK(x_pixmap_);
@@ -214,6 +286,35 @@ bool VaapiVideoDecodeAccelerator::TFPPicture::Bind() {
return true;
}
+#else
+bool VaapiVideoDecodeAccelerator::TFPPicture::Upload(VASurfaceID surface) {
+ DCHECK(CalledOnValidThread());
+ 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_);
+ 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);
marcheu 2014/08/07 01:26:25 This is a synchronous, CPU-side copy. This copy do
vignatti (out of this project) 2014/08/12 08:19:02 FYI point taken. We are working on that.
+
+ va_wrapper_->UnmapImage(&va_image_);
+
+ return true;
+}
+#endif
VaapiVideoDecodeAccelerator::TFPPicture*
VaapiVideoDecodeAccelerator::TFPPictureById(int32 picture_buffer_id) {
@@ -227,9 +328,15 @@ VaapiVideoDecodeAccelerator::TFPPicture*
}
VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator(
+#if defined(USE_X11)
Display* x_display,
+#endif
const base::Callback<bool(void)>& make_context_current)
+#if defined(USE_X11)
: x_display_(x_display),
+#else
+ : fd_(0),
+#endif
make_context_current_(make_context_current),
state_(kUninitialized),
input_ready_(&lock_),
@@ -249,8 +356,12 @@ VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator(
VaapiVideoDecodeAccelerator::~VaapiVideoDecodeAccelerator() {
DCHECK_EQ(message_loop_, base::MessageLoop::current());
+#if !defined(USE_X11)
+ fd_ = 0;
+#endif
}
+#if defined(USE_X11)
class XFreeDeleter {
public:
void operator()(void* x) const {
@@ -279,6 +390,7 @@ bool VaapiVideoDecodeAccelerator::InitializeFBConfig() {
fb_config_ = glx_fb_configs.get()[0];
return true;
}
+#endif
bool VaapiVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
Client* client) {
@@ -294,15 +406,30 @@ bool VaapiVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
if (!make_context_current_.Run())
return false;
+#if defined(USE_X11)
if (!InitializeFBConfig()) {
DVLOG(1) << "Could not get a usable FBConfig";
return false;
}
+#else
+ 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;
+ }
+#endif
vaapi_wrapper_ = VaapiWrapper::Create(
VaapiWrapper::kDecode,
profile,
+#if defined(USE_X11)
x_display_,
+#else
+ fd_,
+#endif
base::Bind(&ReportToUMA, content::VaapiH264Decoder::VAAPI_ERROR));
if (!vaapi_wrapper_.get()) {
@@ -355,7 +482,7 @@ void VaapiVideoDecodeAccelerator::OutputPicture(
DVLOG(3) << "Outputting VASurface " << va_surface->id()
<< " into pixmap bound to picture buffer id " << output_id;
-
+#if defined(USE_X11)
RETURN_AND_NOTIFY_ON_FAILURE(tfp_picture->Bind(),
"Failed binding texture to pixmap",
PLATFORM_FAILURE, );
@@ -365,7 +492,11 @@ void VaapiVideoDecodeAccelerator::OutputPicture(
tfp_picture->x_pixmap(),
tfp_picture->size()),
"Failed putting surface into pixmap", PLATFORM_FAILURE, );
-
+#else
+ RETURN_AND_NOTIFY_ON_FAILURE(
+ tfp_picture->Upload(va_surface->id()),
+ "Failed putting surface into pixmap", PLATFORM_FAILURE, );
+#endif
// Notify the client a picture is ready to be displayed.
++num_frames_at_client_;
TRACE_COUNTER1("Video Decoder", "Textures at client", num_frames_at_client_);
@@ -437,9 +568,8 @@ bool VaapiVideoDecodeAccelerator::GetInputBuffer_Locked() {
// Will only wait if it is expected that in current state new buffers will
// be queued from the client via Decode(). The state can change during wait.
- while (input_buffers_.empty() && (state_ == kDecoding || state_ == kIdle)) {
+ while (input_buffers_.empty() && (state_ == kDecoding || state_ == kIdle))
input_ready_.Wait();
- }
// We could have got woken up in a different state or never got to sleep
// due to current state; check for that.
@@ -494,9 +624,8 @@ bool VaapiVideoDecodeAccelerator::FeedDecoderWithOutputSurfaces_Locked() {
DCHECK(decoder_thread_proxy_->BelongsToCurrentThread());
while (available_va_surfaces_.empty() &&
- (state_ == kDecoding || state_ == kFlushing || state_ == kIdle)) {
+ (state_ == kDecoding || state_ == kFlushing || state_ == kIdle))
surfaces_available_.Wait();
- }
if (state_ != kDecoding && state_ != kFlushing && state_ != kIdle)
return false;
@@ -704,8 +833,16 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers(
<< " VASurfaceID: " << va_surface_ids[i];
linked_ptr<TFPPicture> tfp_picture(
- TFPPicture::Create(make_context_current_, fb_config_, x_display_,
- buffers[i].id(), buffers[i].texture_id(),
+ TFPPicture::Create(make_context_current_,
+#if defined(USE_X11)
+ fb_config_,
+ x_display_,
+#else
+ fd_,
+ vaapi_wrapper_.get(),
+#endif
+ buffers[i].id(),
+ buffers[i].texture_id(),
requested_pic_size_));
RETURN_AND_NOTIFY_ON_FAILURE(
« no previous file with comments | « content/common/gpu/media/vaapi_video_decode_accelerator.h ('k') | content/common/gpu/media/vaapi_wrapper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698