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

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

Issue 240113009: Enable HW VAVDA by libva-wayland backend. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 8 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_wayland.cc
diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator_wayland.cc
similarity index 83%
copy from content/common/gpu/media/vaapi_video_decode_accelerator.cc
copy to content/common/gpu/media/vaapi_video_decode_accelerator_wayland.cc
index 4b2c49e7d19702bd6ec446bb937dedc8063d02d7..6e9fb84609bb732db4fee597216796ca0d877ae9 100644
--- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc
+++ b/content/common/gpu/media/vaapi_video_decode_accelerator_wayland.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2014 and intel copyright. All rights reserved.
Ami GONE FROM CHROMIUM 2014/04/18 22:40:25 Copyright rests with The Chromium Authors, not wit
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,6 @@
#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"
#include "ui/gl/scoped_binders.h"
static void ReportToUMA(
@@ -61,21 +60,21 @@ void VaapiVideoDecodeAccelerator::NotifyError(Error error) {
}
}
-// TFPPicture allocates X Pixmaps and binds them to textures passed
+// TFPPicture allocates VAImage and binds them to textures passed
// in PictureBuffers from clients to them. TFPPictures are created as
// a consequence of receiving a set of PictureBuffers from clients and released
// at the end of decode (or when a new set of PictureBuffers is required).
//
// TFPPictures are used for output, contents of VASurfaces passed from decoder
-// are put into the associated pixmap memory and sent to client.
+// are put into the associated vaimage memory and upload to client.
class VaapiVideoDecodeAccelerator::TFPPicture : public base::NonThreadSafe {
public:
~TFPPicture();
static linked_ptr<TFPPicture> Create(
- const base::Callback<bool(void)>& make_context_current,
- const GLXFBConfig& fb_config,
- Display* x_display,
+ const base::Callback<bool(void)>& make_context_current, //NOLINT
+ wl_display* wl_display,
+ VaapiWrapper* va_wrapper,
int32 picture_buffer_id,
uint32 texture_id,
gfx::Size size);
@@ -88,101 +87,75 @@ 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,
+ TFPPicture(const base::Callback<bool(void)>& make_context_current, //NOLINT
+ wl_display* wl_display,
+ 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_;
+ base::Callback<bool(void)> make_context_current_; //NOLINT
- Display* x_display_;
+ wl_display* wl_display_;
+ 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,
+ const base::Callback<bool(void)>& make_context_current, //NOLINT
+ wl_display* wl_display,
+ VaapiWrapper* va_wrapper,
int32 picture_buffer_id,
uint32 texture_id,
gfx::Size size)
: make_context_current_(make_context_current),
- x_display_(x_display),
+ wl_display_(wl_display),
+ 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,
+ const base::Callback<bool(void)>& make_context_current, //NOLINT
+ wl_display* wl_display,
+ 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,
- texture_id, size));
+ new TFPPicture(make_context_current, wl_display, 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;
}
@@ -191,26 +164,36 @@ bool VaapiVideoDecodeAccelerator::TFPPicture::Initialize(
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 (x_pixmap_)
- XFreePixmap(x_display_, x_pixmap_);
- XSync(x_display_, False); // Needed to work around buggy vdpau-driver.
+ if (va_wrapper_) {
+ va_wrapper_->DestroyImage(&va_image_);
+ }
}
-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,59 +210,66 @@ VaapiVideoDecodeAccelerator::TFPPicture*
}
VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator(
- Display* x_display,
- const base::Callback<bool(void)>& make_context_current)
- : x_display_(x_display),
+ const base::Callback<bool(void)>& make_context_current) //NOLINT
+ : wl_display_(NULL),
make_context_current_(make_context_current),
state_(kUninitialized),
input_ready_(&lock_),
surfaces_available_(&lock_),
message_loop_(base::MessageLoop::current()),
+ weak_this_(base::AsWeakPtr(this)),
+ va_surface_release_cb_(media::BindToCurrentLoop(base::Bind(
+ &VaapiVideoDecodeAccelerator::RecycleVASurfaceID, weak_this_))),
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),
- weak_this_factory_(this) {
- weak_this_ = weak_this_factory_.GetWeakPtr();
- va_surface_release_cb_ = media::BindToCurrentLoop(
- base::Bind(&VaapiVideoDecodeAccelerator::RecycleVASurfaceID, weak_this_));
+ requested_num_pics_(0) {
}
VaapiVideoDecodeAccelerator::~VaapiVideoDecodeAccelerator() {
DCHECK_EQ(message_loop_, base::MessageLoop::current());
+ if (wl_display_) {
+ wl_display_flush(wl_display_);
+ wl_display_disconnect(wl_display_);
+ wl_display_ = NULL;
+ }
}
-class XFreeDeleter {
- public:
- void operator()(void* x) const {
- ::XFree(x);
+typedef struct wayland_display {
+ wl_display* display;
+ wl_compositor* compositor;
+ wl_shell* shell;
+ wl_registry* registry;
+ int event_fd;
+} wayland_display;
+
+static void registry_handle_global(
+ void* data,
+ wl_registry* registry,
+ uint32_t id,
+ const char* interface,
+ uint32_t version) {
+ wayland_display* display_handle =
+ reinterpret_cast<wayland_display *>(data);
+
+ if (strcmp(interface, "wl_compositor") == 0) {
+ display_handle->compositor =
+ reinterpret_cast<wl_compositor *>(wl_registry_bind(
+ registry, id, &wl_compositor_interface, 1));
+ } else if (strcmp(interface, "wl_shell") == 0) {
+ display_handle->shell =
+ reinterpret_cast<wl_shell *>(wl_registry_bind(
+ registry, id, &wl_shell_interface, 1));
}
-};
-
-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;
}
+static const struct wl_registry_listener registry_listener = {
+ registry_handle_global,
+ NULL,
+};
+
bool VaapiVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
Client* client) {
DCHECK_EQ(message_loop_, base::MessageLoop::current());
@@ -294,13 +284,19 @@ bool VaapiVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
if (!make_context_current_.Run())
return false;
- if (!InitializeFBConfig()) {
- DVLOG(1) << "Could not get a usable FBConfig";
+ wayland_display d;
+
+ d.display = wl_display_connect(NULL);
+ if (!d.display)
return false;
- }
+ wl_display_set_user_data(d.display, &d);
+ d.registry = wl_display_get_registry(d.display);
+ wl_registry_add_listener(d.registry, &registry_listener, &d);
+ wl_display_dispatch(d.display);
+ wl_display_ = d.display;
vaapi_wrapper_ = VaapiWrapper::Create(
- profile, x_display_,
+ profile, wl_display_,
base::Bind(&ReportToUMA, content::VaapiH264Decoder::VAAPI_ERROR));
if (!vaapi_wrapper_.get()) {
@@ -319,6 +315,10 @@ bool VaapiVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
decoder_thread_proxy_ = decoder_thread_.message_loop_proxy();
state_ = kIdle;
+
+ message_loop_->PostTask(FROM_HERE, base::Bind(
+ &Client::NotifyInitializeDone, client_));
+
return true;
}
@@ -354,15 +354,9 @@ 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()),
- "Failed putting surface into pixmap", PLATFORM_FAILURE, );
+ RETURN_AND_NOTIFY_ON_FAILURE(tfp_picture->Upload(va_surface->id()),
+ "Failed to upload VASurface to texture",
+ PLATFORM_FAILURE, ); //NOLINT
// Notify the client a picture is ready to be displayed.
++num_frames_at_client_;
@@ -403,12 +397,12 @@ void VaapiVideoDecodeAccelerator::MapAndQueueNewInputBuffer(
bitstream_buffer.id());
DVLOG(4) << "Mapping new input buffer id: " << bitstream_buffer.id()
- << " size: " << (int)bitstream_buffer.size();
+ << " size: " << static_cast<int>(bitstream_buffer.size());
scoped_ptr<base::SharedMemory> shm(
new base::SharedMemory(bitstream_buffer.handle(), true));
RETURN_AND_NOTIFY_ON_FAILURE(shm->Map(bitstream_buffer.size()),
- "Failed to map input buffer", UNREADABLE_INPUT,);
+ "Failed to map input buffer", UNREADABLE_INPUT,); //NOLINT
base::AutoLock auto_lock(lock_);
@@ -492,7 +486,7 @@ 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();
}
@@ -560,7 +554,7 @@ void VaapiVideoDecodeAccelerator::DecodeTask() {
case VaapiH264Decoder::kDecodeError:
RETURN_AND_NOTIFY_ON_FAILURE(false, "Error decoding stream",
- PLATFORM_FAILURE, );
+ PLATFORM_FAILURE,); //NOLINT
return;
}
}
@@ -658,7 +652,7 @@ void VaapiVideoDecodeAccelerator::Decode(
default:
RETURN_AND_NOTIFY_ON_FAILURE(false,
"Decode request from client in invalid state: " << state_,
- PLATFORM_FAILURE, );
+ PLATFORM_FAILURE,); //NOLINT
break;
}
}
@@ -684,8 +678,8 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers(
RETURN_AND_NOTIFY_ON_FAILURE(
buffers.size() == requested_num_pics_,
- "Got an invalid number of picture buffers. (Got " << buffers.size()
- << ", requested " << requested_num_pics_ << ")", INVALID_ARGUMENT, );
+ "Got an invalid buffers. (Got " << buffers.size() << ", requested "
+ << requested_num_pics_ << ")", INVALID_ARGUMENT,); //NOLINT
DCHECK(requested_pic_size_ == buffers[0].size());
std::vector<VASurfaceID> va_surface_ids;
@@ -693,7 +687,7 @@ void VaapiVideoDecodeAccelerator::AssignPictureBuffers(
vaapi_wrapper_->CreateSurfaces(requested_pic_size_,
buffers.size(),
&va_surface_ids),
- "Failed creating VA Surfaces", PLATFORM_FAILURE, );
+ "Failed creating VA Surfaces", PLATFORM_FAILURE,); //NOLINT
DCHECK_EQ(va_surface_ids.size(), buffers.size());
for (size_t i = 0; i < buffers.size(); ++i) {
@@ -702,13 +696,13 @@ 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(),
- requested_pic_size_));
+ TFPPicture::Create(make_context_current_, wl_display_,
+ vaapi_wrapper_.get(), 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, );
+ PLATFORM_FAILURE,); //NOLINT
bool inserted = tfp_pictures_.insert(std::make_pair(
buffers[i].id(), tfp_picture)).second;
@@ -744,7 +738,7 @@ void VaapiVideoDecodeAccelerator::FlushTask() {
// client to output them.
bool res = decoder_->Flush();
RETURN_AND_NOTIFY_ON_FAILURE(res, "Failed flushing the decoder.",
- PLATFORM_FAILURE, );
+ PLATFORM_FAILURE,); //NOLINT
// Put the decoder in idle state, ready to resume.
decoder_->Reset();
@@ -893,7 +887,6 @@ void VaapiVideoDecodeAccelerator::Cleanup() {
state_ = kDestroying;
client_ptr_factory_.reset();
- weak_this_factory_.InvalidateWeakPtrs();
{
base::AutoUnlock auto_unlock(lock_);

Powered by Google App Engine
This is Rietveld 408576698