diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc | 2 | ||||
-rw-r--r-- | content/common/gpu/media/va_surface.h | 3 | ||||
-rw-r--r-- | content/common/gpu/media/vaapi_drm_picture.cc | 97 | ||||
-rw-r--r-- | content/common/gpu/media/vaapi_drm_picture.h | 27 | ||||
-rw-r--r-- | content/common/gpu/media/vaapi_video_decode_accelerator.cc | 6 | ||||
-rw-r--r-- | content/common/gpu/media/vaapi_video_encode_accelerator.cc | 6 | ||||
-rw-r--r-- | content/common/gpu/media/vaapi_wrapper.cc | 14 | ||||
-rw-r--r-- | content/common/gpu/media/vaapi_wrapper.h | 6 |
8 files changed, 112 insertions, 49 deletions
diff --git a/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc index 69fdd30..19106cb 100644 --- a/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc +++ b/content/common/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.cc @@ -129,7 +129,7 @@ GpuMemoryBufferFactoryOzoneNativePixmap::CreateImageForGpuMemoryBuffer( scoped_refptr<gfx::GLImageOzoneNativePixmap> image( new gfx::GLImageOzoneNativePixmap(size, internalformat)); - if (!image->Initialize(pixmap.get(), format)) { + if (!image->Initialize(pixmap.get())) { LOG(ERROR) << "Failed to create GLImage"; return nullptr; } diff --git a/content/common/gpu/media/va_surface.h b/content/common/gpu/media/va_surface.h index c76c11f..8901fa6 100644 --- a/content/common/gpu/media/va_surface.h +++ b/content/common/gpu/media/va_surface.h @@ -90,6 +90,7 @@ class CONTENT_EXPORT VASurface : public base::RefCountedThreadSafe<VASurface> { VASurface(VASurfaceID va_surface_id, const gfx::Size& size, + unsigned int format, const ReleaseCB& release_cb); VASurfaceID id() { @@ -97,6 +98,7 @@ class CONTENT_EXPORT VASurface : public base::RefCountedThreadSafe<VASurface> { } const gfx::Size& size() const { return size_; } + unsigned int format() const { return format_; } private: friend class base::RefCountedThreadSafe<VASurface>; @@ -104,6 +106,7 @@ class CONTENT_EXPORT VASurface : public base::RefCountedThreadSafe<VASurface> { const VASurfaceID va_surface_id_; gfx::Size size_; + unsigned int format_; ReleaseCB release_cb_; DISALLOW_COPY_AND_ASSIGN(VASurface); diff --git a/content/common/gpu/media/vaapi_drm_picture.cc b/content/common/gpu/media/vaapi_drm_picture.cc index d344a1b..dfa4124 100644 --- a/content/common/gpu/media/vaapi_drm_picture.cc +++ b/content/common/gpu/media/vaapi_drm_picture.cc @@ -17,6 +17,37 @@ #include "ui/ozone/public/ozone_platform.h" #include "ui/ozone/public/surface_factory_ozone.h" +namespace { +// We decode video into YUV420, but for usage with GLImages we have to convert +// to BGRX_8888. +const gfx::BufferFormat kPictureForGLImageFormat = gfx::BufferFormat::BGRX_8888; + +uint32_t BufferFormatToVAFourCC(gfx::BufferFormat fmt) { + switch (fmt) { + case gfx::BufferFormat::BGRX_8888: + return VA_FOURCC_BGRX; + case gfx::BufferFormat::UYVY_422: + return VA_FOURCC_UYVY; + default: + NOTREACHED(); + return 0; + } +} + +uint32_t BufferFormatToVARTFormat(gfx::BufferFormat fmt) { + switch (fmt) { + case gfx::BufferFormat::UYVY_422: + return VA_RT_FORMAT_YUV422; + case gfx::BufferFormat::BGRX_8888: + return VA_RT_FORMAT_RGB32; + default: + NOTREACHED(); + return 0; + } +} + +} // namespace + namespace content { VaapiDrmPicture::VaapiDrmPicture( @@ -54,7 +85,8 @@ scoped_refptr<VASurface> VaapiDrmPicture::CreateVASurfaceForPixmap( // 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.pixel_format = + BufferFormatToVAFourCC(pixmap->GetBufferFormat()); va_attrib_extbuf.width = pixmap_size.width(); va_attrib_extbuf.height = pixmap_size.height(); va_attrib_extbuf.data_size = pixmap_size.height() * dmabuf_pitch; @@ -80,7 +112,8 @@ scoped_refptr<VASurface> VaapiDrmPicture::CreateVASurfaceForPixmap( va_attribs[1].value.value.p = &va_attrib_extbuf; scoped_refptr<VASurface> va_surface = vaapi_wrapper_->CreateUnownedSurface( - VA_RT_FORMAT_RGB32, pixmap_size, va_attribs); + BufferFormatToVARTFormat(pixmap->GetBufferFormat()), pixmap_size, + va_attribs); if (!va_surface) { LOG(ERROR) << "Failed to create VASurface for an Ozone NativePixmap"; return nullptr; @@ -90,13 +123,13 @@ scoped_refptr<VASurface> VaapiDrmPicture::CreateVASurfaceForPixmap( } scoped_refptr<ui::NativePixmap> VaapiDrmPicture::CreateNativePixmap( - gfx::Size size) { + gfx::Size size, + gfx::BufferFormat format) { ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone(); // Create a buffer from Ozone. - return factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, size, - gfx::BufferFormat::BGRX_8888, + return factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, size, format, gfx::BufferUsage::SCANOUT); } @@ -104,7 +137,7 @@ 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()); + pixmap_ = CreateNativePixmap(size(), kPictureForGLImageFormat); if (!pixmap_) { LOG(ERROR) << "Failed creating an Ozone NativePixmap"; return false; @@ -117,10 +150,10 @@ bool VaapiDrmPicture::Initialize() { } // Weak pointers can only bind to methods without return values, - // hence we cannot bind ScalePixmap here. Instead we use a + // hence we cannot bind ProcessPixmap here. Instead we use a // static function to solve this problem. - pixmap_->SetScalingCallback(base::Bind(&VaapiDrmPicture::CallScalePixmap, - weak_this_factory_.GetWeakPtr())); + pixmap_->SetProcessingCallback(base::Bind(&VaapiDrmPicture::CallProcessPixmap, + weak_this_factory_.GetWeakPtr())); if (!make_context_current_.Run()) return false; @@ -129,7 +162,7 @@ bool VaapiDrmPicture::Initialize() { texture_id()); scoped_refptr<gfx::GLImageOzoneNativePixmap> image( new gfx::GLImageOzoneNativePixmap(size(), GL_BGRA_EXT)); - if (!image->Initialize(pixmap_.get(), gfx::BufferFormat::BGRX_8888)) { + if (!image->Initialize(pixmap_.get())) { LOG(ERROR) << "Failed to create GLImage"; return false; } @@ -148,45 +181,51 @@ bool VaapiDrmPicture::DownloadFromSurface( } // static -scoped_refptr<ui::NativePixmap> VaapiDrmPicture::CallScalePixmap( +scoped_refptr<ui::NativePixmap> VaapiDrmPicture::CallProcessPixmap( base::WeakPtr<VaapiDrmPicture> weak_ptr, - gfx::Size new_size) { + gfx::Size target_size, + gfx::BufferFormat target_format) { if (!weak_ptr.get()) { - LOG(ERROR) << "Failed scaling NativePixmap as scaling " + LOG(ERROR) << "Failed processing NativePixmap as processing " "unit(VaapiDrmPicture) is deleted"; return nullptr; } - return weak_ptr->ScalePixmap(new_size); + return weak_ptr->ProcessPixmap(target_size, target_format); } -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; +scoped_refptr<ui::NativePixmap> VaapiDrmPicture::ProcessPixmap( + gfx::Size target_size, + gfx::BufferFormat target_format) { + if (!processed_va_surface_.get() || + processed_va_surface_->size() != target_size || + processed_va_surface_->format() != + BufferFormatToVARTFormat(target_format)) { + processed_pixmap_ = CreateNativePixmap(target_size, target_format); + if (!processed_pixmap_) { + LOG(ERROR) << "Failed creating an Ozone NativePixmap for processing"; + processed_va_surface_ = nullptr; return nullptr; } - scaled_va_surface_ = CreateVASurfaceForPixmap(scaled_pixmap_, new_size); - if (!scaled_va_surface_) { + processed_va_surface_ = + CreateVASurfaceForPixmap(processed_pixmap_, target_size); + if (!processed_va_surface_) { LOG(ERROR) << "Failed creating VA Surface for pixmap"; - scaled_pixmap_ = nullptr; + processed_pixmap_ = nullptr; return nullptr; } } - DCHECK(scaled_pixmap_); + DCHECK(processed_pixmap_); bool vpp_result = - vaapi_wrapper_->BlitSurface(va_surface_, scaled_va_surface_); + vaapi_wrapper_->BlitSurface(va_surface_, processed_va_surface_); if (!vpp_result) { LOG(ERROR) << "Failed scaling NativePixmap"; - scaled_pixmap_ = nullptr; - scaled_va_surface_ = nullptr; + processed_pixmap_ = nullptr; + processed_va_surface_ = nullptr; return nullptr; } - return scaled_pixmap_; + return processed_pixmap_; } scoped_refptr<gl::GLImage> VaapiDrmPicture::GetImageToBind() { diff --git a/content/common/gpu/media/vaapi_drm_picture.h b/content/common/gpu/media/vaapi_drm_picture.h index 4ea787f..e480c8c 100644 --- a/content/common/gpu/media/vaapi_drm_picture.h +++ b/content/common/gpu/media/vaapi_drm_picture.h @@ -13,6 +13,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "content/common/gpu/media/vaapi_picture.h" +#include "ui/gfx/buffer_types.h" #include "ui/gfx/geometry/size.h" namespace gl { @@ -47,17 +48,21 @@ class VaapiDrmPicture : public VaapiPicture { bool AllowOverlay() const override; private: - // Calls ScalePixmap() if weak_ptr is not NULL. - static scoped_refptr<ui::NativePixmap> CallScalePixmap( + // Calls ProcessPixmap() if weak_ptr is not NULL. + static scoped_refptr<ui::NativePixmap> CallProcessPixmap( base::WeakPtr<VaapiDrmPicture> weak_ptr, - gfx::Size new_size); - // Use VPP to scale underlying pixmap_ to |new_size| and return the - // scaling result with a new pixmap. - scoped_refptr<ui::NativePixmap> ScalePixmap(gfx::Size new_size); + gfx::Size target_size, + gfx::BufferFormat target_format); + // Use VPP to process underlying pixmap_, scaling to |target_size| and + // converting to |target_format|. + scoped_refptr<ui::NativePixmap> ProcessPixmap( + gfx::Size target_size, + gfx::BufferFormat target_format); scoped_refptr<VASurface> CreateVASurfaceForPixmap( scoped_refptr<ui::NativePixmap> pixmap, gfx::Size pixmap_size); - scoped_refptr<ui::NativePixmap> CreateNativePixmap(gfx::Size size); + scoped_refptr<ui::NativePixmap> CreateNativePixmap(gfx::Size size, + gfx::BufferFormat format); VaapiWrapper* vaapi_wrapper_; // Not owned. base::Callback<bool(void)> make_context_current_; @@ -65,8 +70,8 @@ class VaapiDrmPicture : public VaapiPicture { // Ozone buffer, the storage of the EGLImage and the VASurface. scoped_refptr<ui::NativePixmap> pixmap_; - // Ozone buffer, the storage of the scaled buffer for overlay. - scoped_refptr<ui::NativePixmap> scaled_pixmap_; + // Ozone buffer, the storage of the processed buffer for overlay. + scoped_refptr<ui::NativePixmap> processed_pixmap_; // EGLImage bound to the GL textures used by the VDA client. scoped_refptr<gl::GLImage> gl_image_; @@ -74,8 +79,8 @@ class VaapiDrmPicture : public VaapiPicture { // VASurface used to transfer from the decoder's pixel format. scoped_refptr<VASurface> va_surface_; - // VaSurface used to apply scaling. - scoped_refptr<VASurface> scaled_va_surface_; + // VaSurface used to apply processing. + scoped_refptr<VASurface> processed_va_surface_; // The WeakPtrFactory for VaapiDrmPicture. base::WeakPtrFactory<VaapiDrmPicture> weak_this_factory_; diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator.cc index 704f7f2..97823a7 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.cc @@ -999,9 +999,9 @@ VaapiVideoDecodeAccelerator::CreateSurface() { return nullptr; DCHECK(!awaiting_va_surfaces_recycle_); - scoped_refptr<VASurface> va_surface( - new VASurface(available_va_surfaces_.front(), requested_pic_size_, - va_surface_release_cb_)); + scoped_refptr<VASurface> va_surface(new VASurface( + available_va_surfaces_.front(), requested_pic_size_, + vaapi_wrapper_->va_surface_format(), va_surface_release_cb_)); available_va_surfaces_.pop_front(); scoped_refptr<VaapiDecodeSurface> dec_surface = diff --git a/content/common/gpu/media/vaapi_video_encode_accelerator.cc b/content/common/gpu/media/vaapi_video_encode_accelerator.cc index 9c078b2..495f2f1 100644 --- a/content/common/gpu/media/vaapi_video_encode_accelerator.cc +++ b/content/common/gpu/media/vaapi_video_encode_accelerator.cc @@ -584,11 +584,13 @@ bool VaapiVideoEncodeAccelerator::PrepareNextJob() { } current_encode_job_->input_surface = new VASurface( - available_va_surface_ids_.back(), coded_size_, va_surface_release_cb_); + available_va_surface_ids_.back(), coded_size_, + vaapi_wrapper_->va_surface_format(), va_surface_release_cb_); available_va_surface_ids_.pop_back(); current_encode_job_->recon_surface = new VASurface( - available_va_surface_ids_.back(), coded_size_, va_surface_release_cb_); + available_va_surface_ids_.back(), coded_size_, + vaapi_wrapper_->va_surface_format(), va_surface_release_cb_); available_va_surface_ids_.pop_back(); // Reference surfaces are needed until the job is done, but they get diff --git a/content/common/gpu/media/vaapi_wrapper.cc b/content/common/gpu/media/vaapi_wrapper.cc index 4f073d3..4240f94 100644 --- a/content/common/gpu/media/vaapi_wrapper.cc +++ b/content/common/gpu/media/vaapi_wrapper.cc @@ -114,8 +114,12 @@ static std::vector<VAConfigAttrib> GetRequiredAttribs( VASurface::VASurface(VASurfaceID va_surface_id, const gfx::Size& size, + unsigned int format, const ReleaseCB& release_cb) - : va_surface_id_(va_surface_id), size_(size), release_cb_(release_cb) { + : va_surface_id_(va_surface_id), + size_(size), + format_(format), + release_cb_(release_cb) { DCHECK(!release_cb_.is_null()); } @@ -124,7 +128,8 @@ VASurface::~VASurface() { } VaapiWrapper::VaapiWrapper() - : va_display_(NULL), + : va_surface_format_(0), + va_display_(NULL), va_config_id_(VA_INVALID_ID), va_context_id_(VA_INVALID_ID), va_vpp_config_id_(VA_INVALID_ID), @@ -511,6 +516,7 @@ bool VaapiWrapper::CreateSurfaces(unsigned int va_format, DCHECK(va_surfaces->empty()); DCHECK(va_surface_ids_.empty()); + DCHECK_EQ(va_surface_format_, 0u); va_surface_ids_.resize(num_surfaces); // Allocate surfaces in driver. @@ -537,6 +543,7 @@ bool VaapiWrapper::CreateSurfaces(unsigned int va_format, } *va_surfaces = va_surface_ids_; + va_surface_format_ = va_format; return true; } @@ -557,6 +564,7 @@ void VaapiWrapper::DestroySurfaces() { va_surface_ids_.clear(); va_context_id_ = VA_INVALID_ID; + va_surface_format_ = 0; } scoped_refptr<VASurface> VaapiWrapper::CreateUnownedSurface( @@ -579,7 +587,7 @@ scoped_refptr<VASurface> VaapiWrapper::CreateUnownedSurface( // of the destruction order. All the surfaces will be destroyed // before VaapiWrapper. va_surface = new VASurface( - va_surface_id, size, + va_surface_id, size, va_format, base::Bind(&VaapiWrapper::DestroyUnownedSurface, base::Unretained(this))); return va_surface; diff --git a/content/common/gpu/media/vaapi_wrapper.h b/content/common/gpu/media/vaapi_wrapper.h index 49e9f04..036bee4 100644 --- a/content/common/gpu/media/vaapi_wrapper.h +++ b/content/common/gpu/media/vaapi_wrapper.h @@ -195,6 +195,9 @@ class CONTENT_EXPORT VaapiWrapper { // Initialize static data before sandbox is enabled. static void PreSandboxInitialization(); + // Get the created surfaces format. + unsigned int va_surface_format() const { return va_surface_format_; } + private: struct ProfileInfo { VAProfile va_profile; @@ -325,6 +328,9 @@ class CONTENT_EXPORT VaapiWrapper { // Allocated ids for VASurfaces. std::vector<VASurfaceID> va_surface_ids_; + // VA format of surfaces with va_surface_ids_. + unsigned int va_surface_format_; + // Singleton instance of VADisplayState. static base::LazyInstance<VADisplayState> va_display_state_; |