Index: content/common/gpu/media/vaapi_drm_picture.cc |
diff --git a/content/common/gpu/media/vaapi_drm_picture.cc b/content/common/gpu/media/vaapi_drm_picture.cc |
index d344a1b5138a97c986e13709283e2bce9fb1e18b..dfa4124eaa5ca53fda215d95bd90b63a01ee7111 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() { |