diff options
Diffstat (limited to 'content/common/gpu/media/vaapi_drm_picture.cc')
-rw-r--r-- | content/common/gpu/media/vaapi_drm_picture.cc | 119 |
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_; } |