summaryrefslogtreecommitdiffstats
path: root/content/common/gpu/media/vaapi_drm_picture.cc
diff options
context:
space:
mode:
Diffstat (limited to 'content/common/gpu/media/vaapi_drm_picture.cc')
-rw-r--r--content/common/gpu/media/vaapi_drm_picture.cc119
1 files changed, 93 insertions, 26 deletions
diff --git a/content/common/gpu/media/vaapi_drm_picture.cc b/content/common/gpu/media/vaapi_drm_picture.cc
index bf694d2..66e4328 100644
--- a/content/common/gpu/media/vaapi_drm_picture.cc
+++ b/content/common/gpu/media/vaapi_drm_picture.cc
@@ -28,7 +28,8 @@ VaapiDrmPicture::VaapiDrmPicture(
const gfx::Size& size)
: VaapiPicture(picture_buffer_id, texture_id, size),
vaapi_wrapper_(vaapi_wrapper),
- make_context_current_(make_context_current) {
+ make_context_current_(make_context_current),
+ weak_this_factory_(this) {
}
VaapiDrmPicture::~VaapiDrmPicture() {
@@ -40,37 +41,24 @@ VaapiDrmPicture::~VaapiDrmPicture() {
}
}
-bool VaapiDrmPicture::Initialize() {
- // We want to create a VASurface and an EGLImage out of the same
- // memory buffer, so we can output decoded pictures to it using
- // VAAPI and also use it to paint with GL.
- ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance();
- ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone();
-
- // Create a buffer from Ozone.
- pixmap_ = factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, size(),
- ui::SurfaceFactoryOzone::BGRA_8888,
- ui::SurfaceFactoryOzone::SCANOUT);
- if (!pixmap_) {
- LOG(ERROR) << "Failed creating an Ozone NativePixmap";
- return false;
- }
-
+scoped_refptr<VASurface> VaapiDrmPicture::CreateVASurfaceForPixmap(
+ scoped_refptr<ui::NativePixmap> pixmap,
+ gfx::Size pixmap_size) {
// Get the dmabuf of the created buffer.
- int dmabuf_fd = pixmap_->GetDmaBufFd();
+ int dmabuf_fd = pixmap->GetDmaBufFd();
if (dmabuf_fd < 0) {
LOG(ERROR) << "Failed to get dmabuf from an Ozone NativePixmap";
- return false;
+ return nullptr;
}
- int dmabuf_pitch = pixmap_->GetDmaBufPitch();
+ int dmabuf_pitch = pixmap->GetDmaBufPitch();
// Create a VASurface out of the created buffer using the dmabuf.
VASurfaceAttribExternalBuffers va_attrib_extbuf;
memset(&va_attrib_extbuf, 0, sizeof(va_attrib_extbuf));
va_attrib_extbuf.pixel_format = VA_FOURCC_BGRX;
- va_attrib_extbuf.width = size().width();
- va_attrib_extbuf.height = size().height();
- va_attrib_extbuf.data_size = size().height() * dmabuf_pitch;
+ va_attrib_extbuf.width = pixmap_size.width();
+ va_attrib_extbuf.height = pixmap_size.height();
+ va_attrib_extbuf.data_size = pixmap_size.height() * dmabuf_pitch;
va_attrib_extbuf.num_planes = 1;
va_attrib_extbuf.pitches[0] = dmabuf_pitch;
va_attrib_extbuf.offsets[0] = 0;
@@ -92,13 +80,49 @@ bool VaapiDrmPicture::Initialize() {
va_attribs[1].value.type = VAGenericValueTypePointer;
va_attribs[1].value.value.p = &va_attrib_extbuf;
- va_surface_ = vaapi_wrapper_->CreateUnownedSurface(VA_RT_FORMAT_RGB32, size(),
- va_attribs);
- if (!va_surface_) {
+ scoped_refptr<VASurface> va_surface = vaapi_wrapper_->CreateUnownedSurface(
+ VA_RT_FORMAT_RGB32, pixmap_size, va_attribs);
+ if (!va_surface) {
LOG(ERROR) << "Failed to create VASurface for an Ozone NativePixmap";
+ return nullptr;
+ }
+
+ return va_surface;
+}
+
+scoped_refptr<ui::NativePixmap> VaapiDrmPicture::CreateNativePixmap(
+ gfx::Size size) {
+ ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance();
+ ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone();
+
+ // Create a buffer from Ozone.
+ return factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, size,
+ ui::SurfaceFactoryOzone::BGRA_8888,
+ ui::SurfaceFactoryOzone::SCANOUT);
+}
+
+bool VaapiDrmPicture::Initialize() {
+ // We want to create a VASurface and an EGLImage out of the same
+ // memory buffer, so we can output decoded pictures to it using
+ // VAAPI and also use it to paint with GL.
+ pixmap_ = CreateNativePixmap(size());
+ if (!pixmap_) {
+ LOG(ERROR) << "Failed creating an Ozone NativePixmap";
+ return false;
+ }
+
+ va_surface_ = CreateVASurfaceForPixmap(pixmap_, size());
+ if (!va_surface_) {
+ LOG(ERROR) << "Failed creating VASurface for NativePixmap";
return false;
}
+ // Weak pointers can only bind to methods without return values,
+ // hence we cannot bind ScalePixmap here. Instead we use a
+ // static function to solve this problem.
+ pixmap_->SetScalingCallback(base::Bind(&VaapiDrmPicture::CallScalePixmap,
+ weak_this_factory_.GetWeakPtr()));
+
if (!make_context_current_.Run())
return false;
@@ -124,6 +148,49 @@ bool VaapiDrmPicture::DownloadFromSurface(
va_surface_->id(), va_surface_->size());
}
+// static
+scoped_refptr<ui::NativePixmap> VaapiDrmPicture::CallScalePixmap(
+ base::WeakPtr<VaapiDrmPicture> weak_ptr,
+ gfx::Size new_size) {
+ if (!weak_ptr.get()) {
+ LOG(ERROR) << "Failed scaling NativePixmap as scaling "
+ "unit(VaapiDrmPicture) is deleted";
+ return nullptr;
+ }
+ return weak_ptr->ScalePixmap(new_size);
+}
+
+scoped_refptr<ui::NativePixmap> VaapiDrmPicture::ScalePixmap(
+ gfx::Size new_size) {
+ if (!scaled_va_surface_.get() || scaled_va_surface_->size() != new_size) {
+ scaled_pixmap_ = CreateNativePixmap(new_size);
+ if (!scaled_pixmap_) {
+ LOG(ERROR) << "Failed creating an Ozone NativePixmap for scaling";
+ scaled_va_surface_ = nullptr;
+ return nullptr;
+ }
+ scaled_va_surface_ = CreateVASurfaceForPixmap(scaled_pixmap_, new_size);
+ if (!scaled_va_surface_) {
+ LOG(ERROR) << "Failed creating VA Surface for pixmap";
+ scaled_pixmap_ = nullptr;
+ return nullptr;
+ }
+ }
+
+ DCHECK(scaled_pixmap_);
+ bool vpp_result = vaapi_wrapper_->BlitSurface(
+ va_surface_->id(), va_surface_->size(), scaled_va_surface_->id(),
+ scaled_va_surface_->size());
+ if (!vpp_result) {
+ LOG(ERROR) << "Failed scaling NativePixmap";
+ scaled_pixmap_ = nullptr;
+ scaled_va_surface_ = nullptr;
+ return nullptr;
+ }
+
+ return scaled_pixmap_;
+}
+
scoped_refptr<gfx::GLImage> VaapiDrmPicture::GetImageToBind() {
return gl_image_;
}