summaryrefslogtreecommitdiff
path: root/chromium/media/gpu/vaapi/vaapi_wrapper.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/gpu/vaapi/vaapi_wrapper.cc')
-rw-r--r--chromium/media/gpu/vaapi/vaapi_wrapper.cc409
1 files changed, 265 insertions, 144 deletions
diff --git a/chromium/media/gpu/vaapi/vaapi_wrapper.cc b/chromium/media/gpu/vaapi/vaapi_wrapper.cc
index cdbd4fb2c73..dc1b731ea25 100644
--- a/chromium/media/gpu/vaapi/vaapi_wrapper.cc
+++ b/chromium/media/gpu/vaapi/vaapi_wrapper.cc
@@ -5,6 +5,7 @@
#include "media/gpu/vaapi/vaapi_wrapper.h"
#include <dlfcn.h>
+#include <drm_fourcc.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
@@ -42,6 +43,7 @@
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "media/base/media_switches.h"
+#include "media/base/video_codecs.h"
#include "media/base/video_frame.h"
#include "media/base/video_types.h"
#include "media/gpu/macros.h"
@@ -53,6 +55,7 @@
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/linux/drm_util_linux.h"
#include "ui/gfx/linux/native_pixmap_dmabuf.h"
#include "ui/gfx/native_pixmap.h"
#include "ui/gfx/native_pixmap_handle.h"
@@ -258,6 +261,152 @@ bool UseGlobalVaapiLock(media::VAImplementation implementation_type) {
base::FeatureList::IsEnabled(media::kGlobalVaapiLock);
}
+bool FillVADRMPRIMESurfaceDescriptor(const gfx::NativePixmap& pixmap,
+ VADRMPRIMESurfaceDescriptor& descriptor) {
+ memset(&descriptor, 0, sizeof(VADRMPRIMESurfaceDescriptor));
+
+ const gfx::BufferFormat buffer_format = pixmap.GetBufferFormat();
+ const uint32_t va_fourcc = BufferFormatToVAFourCC(buffer_format);
+ DCHECK(va_fourcc);
+
+ const gfx::Size size = pixmap.GetBufferSize();
+ const size_t num_planes = pixmap.GetNumberOfPlanes();
+ const int drm_fourcc = ui::GetFourCCFormatFromBufferFormat(buffer_format);
+ if (drm_fourcc == DRM_FORMAT_INVALID) {
+ LOG(ERROR) << "Failed to get the DRM format from the buffer format";
+ return false;
+ }
+ if (num_planes > std::size(descriptor.objects)) {
+ LOG(ERROR) << "Too many planes in the NativePixmap; got " << num_planes
+ << " but the maximum number is "
+ << std::size(descriptor.objects);
+ return false;
+ }
+ static_assert(std::size(VADRMPRIMESurfaceDescriptor{}.layers) ==
+ std::size(VADRMPRIMESurfaceDescriptor{}.objects));
+ static_assert(
+ std::size(VADRMPRIMESurfaceDescriptor{}.layers[0].object_index) ==
+ std::size(VADRMPRIMESurfaceDescriptor{}.objects));
+ static_assert(std::size(VADRMPRIMESurfaceDescriptor{}.layers[0].offset) ==
+ std::size(VADRMPRIMESurfaceDescriptor{}.objects));
+ static_assert(std::size(VADRMPRIMESurfaceDescriptor{}.layers[0].pitch) ==
+ std::size(VADRMPRIMESurfaceDescriptor{}.objects));
+
+ descriptor.fourcc = va_fourcc;
+ descriptor.width = base::checked_cast<uint32_t>(size.width());
+ descriptor.height = base::checked_cast<uint32_t>(size.height());
+
+ // We can pass the planes as separate layers or all in one layer. The choice
+ // of doing the latter was arbitrary.
+ descriptor.num_layers = 1u;
+ descriptor.layers[0].drm_format = base::checked_cast<uint32_t>(drm_fourcc);
+ descriptor.layers[0].num_planes = base::checked_cast<uint32_t>(num_planes);
+
+ descriptor.num_objects = base::checked_cast<uint32_t>(num_planes);
+ for (size_t i = 0u; i < num_planes; i++) {
+ const int dma_buf_fd = pixmap.GetDmaBufFd(i);
+ if (dma_buf_fd < 0) {
+ LOG(ERROR) << "Failed to get dmabuf from an Ozone NativePixmap";
+ return false;
+ }
+ const off_t data_size = lseek(dma_buf_fd, /*offset=*/0, SEEK_END);
+ if (data_size == static_cast<off_t>(-1)) {
+ PLOG(ERROR) << "Failed to get the size of the dma-buf";
+ return false;
+ }
+ if (lseek(dma_buf_fd, /*offset=*/0, SEEK_SET) == static_cast<off_t>(-1)) {
+ PLOG(ERROR) << "Failed to reset the file offset of the dma-buf";
+ return false;
+ }
+
+ descriptor.objects[i].fd = dma_buf_fd;
+ descriptor.objects[i].size = base::checked_cast<uint32_t>(data_size);
+ descriptor.objects[i].drm_format_modifier =
+ pixmap.GetBufferFormatModifier();
+
+ descriptor.layers[0].object_index[i] = base::checked_cast<uint32_t>(i);
+ if (!base::IsValueInRangeForNumericType<uint32_t>(
+ pixmap.GetDmaBufOffset(i))) {
+ LOG(ERROR) << "The offset for plane " << i << " is out-of-range";
+ return false;
+ }
+ descriptor.layers[0].offset[i] =
+ base::checked_cast<uint32_t>(pixmap.GetDmaBufOffset(i));
+ descriptor.layers[0].pitch[i] = pixmap.GetDmaBufPitch(i);
+ }
+
+ return true;
+}
+
+struct VASurfaceAttribExternalBuffersAndFD {
+ VASurfaceAttribExternalBuffers va_attrib_extbuf;
+ uintptr_t fd;
+};
+
+bool FillVASurfaceAttribExternalBuffers(
+ const gfx::NativePixmap& pixmap,
+ VASurfaceAttribExternalBuffersAndFD& va_attrib_extbuf_and_fd) {
+ VASurfaceAttribExternalBuffers& va_attrib_extbuf =
+ va_attrib_extbuf_and_fd.va_attrib_extbuf;
+ memset(&va_attrib_extbuf_and_fd, 0,
+ sizeof(VASurfaceAttribExternalBuffersAndFD));
+
+ const uint32_t va_fourcc = BufferFormatToVAFourCC(pixmap.GetBufferFormat());
+ DCHECK(va_fourcc);
+
+ const gfx::Size size = pixmap.GetBufferSize();
+ const size_t num_planes = pixmap.GetNumberOfPlanes();
+
+ va_attrib_extbuf.pixel_format = va_fourcc;
+ va_attrib_extbuf.width = base::checked_cast<uint32_t>(size.width());
+ va_attrib_extbuf.height = base::checked_cast<uint32_t>(size.height());
+
+ static_assert(std::size(VASurfaceAttribExternalBuffers{}.pitches) ==
+ std::size(VASurfaceAttribExternalBuffers{}.offsets));
+ if (num_planes > std::size(va_attrib_extbuf.pitches)) {
+ LOG(ERROR) << "Too many planes in the NativePixmap; got " << num_planes
+ << " but the maximum number is "
+ << std::size(va_attrib_extbuf.pitches);
+ return false;
+ }
+ for (size_t i = 0; i < num_planes; ++i) {
+ va_attrib_extbuf.pitches[i] = pixmap.GetDmaBufPitch(i);
+ va_attrib_extbuf.offsets[i] =
+ base::checked_cast<uint32_t>(pixmap.GetDmaBufOffset(i));
+ DVLOG(4) << "plane " << i << ": pitch: " << va_attrib_extbuf.pitches[i]
+ << " offset: " << va_attrib_extbuf.offsets[i];
+ }
+ va_attrib_extbuf.num_planes = base::checked_cast<uint32_t>(num_planes);
+
+ const int dma_buf_fd = pixmap.GetDmaBufFd(0);
+ if (dma_buf_fd < 0) {
+ LOG(ERROR) << "Failed to get dmabuf from an Ozone NativePixmap";
+ return false;
+ }
+ const off_t data_size = lseek(dma_buf_fd, /*offset=*/0, SEEK_END);
+ if (data_size == static_cast<off_t>(-1)) {
+ PLOG(ERROR) << "Failed to get the size of the dma-buf";
+ return false;
+ }
+ if (lseek(dma_buf_fd, /*offset=*/0, SEEK_SET) == static_cast<off_t>(-1)) {
+ PLOG(ERROR) << "Failed to reset the file offset of the dma-buf";
+ return false;
+ }
+ // If the data size doesn't fit in a uint32_t, we probably have bigger
+ // problems.
+ va_attrib_extbuf.data_size = base::checked_cast<uint32_t>(data_size);
+
+ // We only have to pass the first file descriptor to a driver. A VA-API driver
+ // shall create a VASurface from the single fd correctly.
+ va_attrib_extbuf_and_fd.fd = base::checked_cast<uintptr_t>(dma_buf_fd);
+ va_attrib_extbuf.buffers = &va_attrib_extbuf_and_fd.fd;
+ va_attrib_extbuf.num_buffers = 1u;
+
+ DCHECK_EQ(va_attrib_extbuf.flags, 0u);
+ DCHECK_EQ(va_attrib_extbuf.private_data, nullptr);
+ return true;
+}
+
} // namespace
namespace media {
@@ -448,6 +597,7 @@ const ProfileCodecMap& GetProfileCodecMap() {
// {AV1PROFILE_PROFILE_HIGH, VAProfileAV1Profile1},
#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
{HEVCPROFILE_MAIN, VAProfileHEVCMain},
+ {HEVCPROFILE_MAIN_STILL_PICTURE, VAProfileHEVCMain},
{HEVCPROFILE_MAIN10, VAProfileHEVCMain10},
#endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
});
@@ -963,6 +1113,10 @@ class VASupportedProfiles {
// Determines if |mode| supports |va_profile| (and |va_entrypoint| if defined
// and valid). If so, returns a const pointer to its ProfileInfo, otherwise
// returns nullptr.
+ // TODO(hiroh): If VAEntrypoint is kVAEntrypointInvalid, the default entry
+ // point acquired by GetDefaultVaEntryPoint() is used. If the default entry
+ // point is not supported, the earlier supported entrypoint in
+ // |kAllowedEntryPopints| is used.
const ProfileInfo* IsProfileSupported(
VaapiWrapper::CodecMode mode,
VAProfile va_profile,
@@ -1433,6 +1587,24 @@ bool IsLowPowerEncSupported(VAProfile va_profile) {
return false;
}
+bool IsVBREncodingSupported(VAProfile va_profile) {
+ if (!base::FeatureList::IsEnabled(kChromeOSHWVBREncoding))
+ return false;
+
+ auto mode = VaapiWrapper::CodecMode::kCodecModeMax;
+ switch (va_profile) {
+ case VAProfileH264ConstrainedBaseline:
+ case VAProfileH264Main:
+ case VAProfileH264High:
+ mode = VaapiWrapper::CodecMode::kEncodeVariableBitrate;
+ break;
+ default:
+ return false;
+ }
+
+ return VASupportedProfiles::Get().IsProfileSupported(mode, va_profile);
+}
+
} // namespace
NativePixmapAndSizeInfo::NativePixmapAndSizeInfo() = default;
@@ -1550,8 +1722,13 @@ VaapiWrapper::GetSupportedEncodeProfiles() {
constexpr int kMaxEncoderFramerate = 30;
profile.max_framerate_numerator = kMaxEncoderFramerate;
profile.max_framerate_denominator = 1;
- // TODO(b/193680666): remove hard-coding when VBR is supported
profile.rate_control_modes = media::VideoEncodeAccelerator::kConstantMode;
+ // This code assumes that the resolutions are the same between CBR and VBR.
+ // This is checked in a test in vaapi_unittest.cc: VbrAndCbrResolutionsMatch
+ if (IsVBREncodingSupported(va_profile)) {
+ profile.rate_control_modes |=
+ media::VideoEncodeAccelerator::kVariableMode;
+ }
profile.scalability_modes =
GetSupportedScalabilityModes(media_profile, va_profile);
profiles.push_back(profile);
@@ -1616,26 +1793,18 @@ bool VaapiWrapper::IsDecodingSupportedForInternalFormat(
}
// static
-bool VaapiWrapper::GetDecodeMinResolution(VAProfile va_profile,
- gfx::Size* min_size) {
+bool VaapiWrapper::GetSupportedResolutions(VAProfile va_profile,
+ CodecMode codec_mode,
+ gfx::Size& min_size,
+ gfx::Size& max_size) {
const VASupportedProfiles::ProfileInfo* profile_info =
- VASupportedProfiles::Get().IsProfileSupported(kDecode, va_profile);
- if (!profile_info)
+ VASupportedProfiles::Get().IsProfileSupported(codec_mode, va_profile);
+ if (!profile_info || profile_info->max_resolution.IsEmpty())
return false;
- *min_size = gfx::Size(std::max(1, profile_info->min_resolution.width()),
- std::max(1, profile_info->min_resolution.height()));
- return true;
-}
-// static
-bool VaapiWrapper::GetDecodeMaxResolution(VAProfile va_profile,
- gfx::Size* max_size) {
- const VASupportedProfiles::ProfileInfo* profile_info =
- VASupportedProfiles::Get().IsProfileSupported(kDecode, va_profile);
- if (!profile_info)
- return false;
-
- *max_size = profile_info->max_resolution;
+ min_size = gfx::Size(std::max(1, profile_info->min_resolution.width()),
+ std::max(1, profile_info->min_resolution.height()));
+ max_size = profile_info->max_resolution;
return true;
}
@@ -1921,7 +2090,7 @@ bool VaapiWrapper::CreateProtectedSession(
const VAProfile va_profile = VAProfileProtected;
const VAEntrypoint entrypoint = GetDefaultVaEntryPoint(mode_, va_profile);
{
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
std::vector<VAConfigAttrib> required_attribs;
if (!GetRequiredAttribs(va_lock_, va_display_, mode_, va_profile,
entrypoint, &required_attribs)) {
@@ -1958,7 +2127,7 @@ bool VaapiWrapper::CreateProtectedSession(
std::unique_ptr<ScopedVABuffer> hw_update = CreateVABuffer(
VAProtectedSessionExecuteBufferType, sizeof(hw_update_buf));
{
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
constexpr size_t kHwIdentifierMaxSize = 64;
memset(&hw_update_buf, 0, sizeof(hw_update_buf));
hw_update_buf.function_id = VA_TEE_EXEC_TEE_FUNCID_HW_UPDATE;
@@ -2032,7 +2201,7 @@ bool VaapiWrapper::IsProtectedSessionDead(
tee_exec_buf.output.data_size = sizeof(alive);
tee_exec_buf.output.data = &alive;
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
VABufferID buf_id;
VAStatus va_res = vaCreateBuffer(
va_display_, va_protected_session_id, VAProtectedSessionExecuteBufferType,
@@ -2065,7 +2234,7 @@ void VaapiWrapper::DestroyProtectedSession() {
#if BUILDFLAG(IS_CHROMEOS_ASH)
if (va_protected_session_id_ == VA_INVALID_ID)
return;
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
VAStatus va_res =
vaDestroyProtectedSession(va_display_, va_protected_session_id_);
VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroyProtectedSession);
@@ -2088,7 +2257,7 @@ bool VaapiWrapper::CreateContext(const gfx::Size& size) {
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
DVLOG(2) << "Creating context";
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
// vaCreateContext() doesn't really need an array of VASurfaceIDs (see
// https://lists.01.org/pipermail/intel-vaapi-media/2017-July/000052.html and
@@ -2147,65 +2316,34 @@ scoped_refptr<VASurface> VaapiWrapper::CreateVASurfaceForPixmap(
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
const gfx::BufferFormat buffer_format = pixmap->GetBufferFormat();
-
- const uint32_t va_fourcc = BufferFormatToVAFourCC(buffer_format);
- if (!va_fourcc) {
+ if (!BufferFormatToVAFourCC(buffer_format)) {
LOG(ERROR) << "Failed to get the VA fourcc from the buffer format";
return nullptr;
}
- const size_t num_planes = pixmap->GetNumberOfPlanes();
-
- // Create a VASurface for a NativePixmap by importing the underlying dmabufs.
- const gfx::Size size = pixmap->GetBufferSize();
- VASurfaceAttribExternalBuffers va_attrib_extbuf{};
- va_attrib_extbuf.pixel_format = va_fourcc;
- va_attrib_extbuf.width = base::checked_cast<uint32_t>(size.width());
- va_attrib_extbuf.height = base::checked_cast<uint32_t>(size.height());
-
- static_assert(std::size(va_attrib_extbuf.pitches) ==
- std::size(va_attrib_extbuf.offsets));
- if (num_planes > std::size(va_attrib_extbuf.pitches)) {
- LOG(ERROR) << "Too many planes in the NativePixmap; got " << num_planes
- << " but the maximum number is "
- << std::size(va_attrib_extbuf.pitches);
- return nullptr;
- }
- for (size_t i = 0; i < num_planes; ++i) {
- va_attrib_extbuf.pitches[i] = pixmap->GetDmaBufPitch(i);
- va_attrib_extbuf.offsets[i] =
- base::checked_cast<uint32_t>(pixmap->GetDmaBufOffset(i));
- DVLOG(4) << "plane " << i << ": pitch: " << va_attrib_extbuf.pitches[i]
- << " offset: " << va_attrib_extbuf.offsets[i];
- }
- va_attrib_extbuf.num_planes = base::checked_cast<uint32_t>(num_planes);
+ // TODO(b/233894465): use the DRM_PRIME_2 API with the Mesa Gallium driver
+ // when AMD supports it.
+ // TODO(b/233924862): use the DRM_PRIME_2 API with protected content.
+ // TODO(b/233929647): use the DRM_PRIME_2 API with the i965 driver.
+ // TODO(b/236746283): remove the kNoModifier check once the modifier is
+ // plumbed for JPEG decoding and encoding.
+ const bool use_drm_prime_2 =
+ GetImplementationType() == VAImplementation::kIntelIHD &&
+ !protected_content &&
+ pixmap->GetBufferFormatModifier() != gfx::NativePixmapHandle::kNoModifier;
+
+ union {
+ VADRMPRIMESurfaceDescriptor descriptor;
+ VASurfaceAttribExternalBuffersAndFD va_attrib_extbuf_and_fd;
+ };
- const int dma_buf_fd = pixmap->GetDmaBufFd(0);
- if (dma_buf_fd < 0) {
- LOG(ERROR) << "Failed to get dmabuf from an Ozone NativePixmap";
- return nullptr;
- }
- const off_t data_size = lseek(dma_buf_fd, /*offset=*/0, SEEK_END);
- if (data_size == static_cast<off_t>(-1)) {
- PLOG(ERROR) << "Failed to get the size of the dma-buf";
- return nullptr;
- }
- if (lseek(dma_buf_fd, /*offset=*/0, SEEK_SET) == static_cast<off_t>(-1)) {
- PLOG(ERROR) << "Failed to reset the file offset of the dma-buf";
- return nullptr;
+ if (use_drm_prime_2) {
+ if (!FillVADRMPRIMESurfaceDescriptor(*pixmap, descriptor))
+ return nullptr;
+ } else {
+ if (!FillVASurfaceAttribExternalBuffers(*pixmap, va_attrib_extbuf_and_fd))
+ return nullptr;
}
- // If the data size doesn't fit in a uint32_t, we probably have bigger
- // problems.
- va_attrib_extbuf.data_size = base::checked_cast<uint32_t>(data_size);
-
- // We only have to pass the first file descriptor to a driver. A VA-API driver
- // shall create a VASurface from the single fd correctly.
- uintptr_t fd = base::checked_cast<uintptr_t>(dma_buf_fd);
- va_attrib_extbuf.buffers = &fd;
- va_attrib_extbuf.num_buffers = 1u;
-
- DCHECK_EQ(va_attrib_extbuf.flags, 0u);
- DCHECK_EQ(va_attrib_extbuf.private_data, nullptr);
unsigned int va_format =
base::strict_cast<unsigned int>(BufferFormatToVARTFormat(buffer_format));
@@ -2215,10 +2353,12 @@ scoped_refptr<VASurface> VaapiWrapper::CreateVASurfaceForPixmap(
}
if (protected_content) {
- if (GetImplementationType() == VAImplementation::kMesaGallium)
+ if (GetImplementationType() == VAImplementation::kMesaGallium) {
va_format |= VA_RT_FORMAT_PROTECTED;
- else
- va_attrib_extbuf.flags = VA_SURFACE_EXTBUF_DESC_PROTECTED;
+ } else {
+ va_attrib_extbuf_and_fd.va_attrib_extbuf.flags =
+ VA_SURFACE_EXTBUF_DESC_PROTECTED;
+ }
}
std::vector<VASurfaceAttrib> va_attribs(2);
@@ -2226,16 +2366,21 @@ scoped_refptr<VASurface> VaapiWrapper::CreateVASurfaceForPixmap(
va_attribs[0].type = VASurfaceAttribMemoryType;
va_attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
va_attribs[0].value.type = VAGenericValueTypeInteger;
- va_attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
+ va_attribs[0].value.value.i = use_drm_prime_2
+ ? VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2
+ : VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
va_attribs[1].type = VASurfaceAttribExternalBufferDescriptor;
va_attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
va_attribs[1].value.type = VAGenericValueTypePointer;
- va_attribs[1].value.value.p = &va_attrib_extbuf;
+ va_attribs[1].value.value.p = use_drm_prime_2
+ ? static_cast<void*>(&descriptor)
+ : &va_attrib_extbuf_and_fd.va_attrib_extbuf;
+ const gfx::Size size = pixmap->GetBufferSize();
VASurfaceID va_surface_id = VA_INVALID_ID;
{
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
VAStatus va_res = vaCreateSurfaces(
va_display_, va_format, base::checked_cast<unsigned int>(size.width()),
base::checked_cast<unsigned int>(size.height()), &va_surface_id, 1,
@@ -2285,7 +2430,7 @@ scoped_refptr<VASurface> VaapiWrapper::CreateVASurfaceForUserPtr(
VASurfaceID va_surface_id = VA_INVALID_ID;
const unsigned int va_format = VA_RT_FORMAT_RGBP;
{
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
VAStatus va_res = vaCreateSurfaces(
va_display_, va_format, base::checked_cast<unsigned int>(size.width()),
base::checked_cast<unsigned int>(size.height()), &va_surface_id, 1,
@@ -2321,7 +2466,7 @@ VaapiWrapper::ExportVASurfaceAsNativePixmapDmaBufUnwrapped(
DCHECK(!va_surface_size.IsEmpty());
VADRMPRIMESurfaceDescriptor descriptor;
{
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVASyncSurface, nullptr);
va_res = vaExportSurfaceHandle(
@@ -2442,7 +2587,7 @@ bool VaapiWrapper::SyncSurface(VASurfaceID va_surface_id) {
sequence_checker_.CalledOnValidSequence());
DCHECK_NE(va_surface_id, VA_INVALID_ID);
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVASyncSurface, false);
@@ -2455,7 +2600,7 @@ bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type,
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
TRACE_EVENT0("media,gpu", "VaapiWrapper::SubmitBuffer");
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
return SubmitBuffer_Locked({va_buffer_type, size, data});
}
@@ -2464,7 +2609,7 @@ bool VaapiWrapper::SubmitBuffers(
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
TRACE_EVENT0("media,gpu", "VaapiWrapper::SubmitBuffers");
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
for (const VABufferDescriptor& va_buffer : va_buffers) {
if (!SubmitBuffer_Locked(va_buffer))
return false;
@@ -2476,7 +2621,7 @@ void VaapiWrapper::DestroyPendingBuffers() {
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
TRACE_EVENT0("media,gpu", "VaapiWrapper::DestroyPendingBuffers");
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
DestroyPendingBuffers_Locked();
}
@@ -2495,7 +2640,7 @@ void VaapiWrapper::DestroyPendingBuffers_Locked() {
bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) {
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
bool result = Execute_Locked(va_surface_id, pending_va_buffers_);
DestroyPendingBuffers_Locked();
return result;
@@ -2509,7 +2654,7 @@ bool VaapiWrapper::MapAndCopyAndExecute(
DCHECK_NE(va_surface_id, VA_INVALID_SURFACE);
TRACE_EVENT0("media,gpu", "VaapiWrapper::MapAndCopyAndExecute");
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
std::vector<VABufferID> va_buffer_ids;
for (const auto& va_buffer : va_buffers) {
@@ -2532,7 +2677,7 @@ bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id,
gfx::Size dest_size) {
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVASyncSurface, false);
@@ -2555,7 +2700,7 @@ std::unique_ptr<ScopedVAImage> VaapiWrapper::CreateVaImage(
sequence_checker_.CalledOnValidSequence());
std::unique_ptr<ScopedVAImage> scoped_image;
{
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVASyncSurface, nullptr);
@@ -2572,7 +2717,7 @@ bool VaapiWrapper::UploadVideoFrameToSurface(const VideoFrame& frame,
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
TRACE_EVENT0("media,gpu", "VaapiWrapper::UploadVideoFrameToSurface");
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
TRACE_EVENT0("media,gpu", "VaapiWrapper::UploadVideoFrameToSurfaceLocked");
if (frame.visible_rect().origin() != gfx::Point(0, 0)) {
@@ -2634,42 +2779,18 @@ bool VaapiWrapper::UploadVideoFrameToSurface(const VideoFrame& frame,
std::unique_ptr<base::AutoUnlock> auto_unlock;
if (va_lock_)
auto_unlock = std::make_unique<base::AutoUnlock>(*va_lock_);
- switch (frame.format()) {
- case PIXEL_FORMAT_I420:
- ret = libyuv::I420ToNV12(
- frame.data(VideoFrame::kYPlane), frame.stride(VideoFrame::kYPlane),
- frame.data(VideoFrame::kUPlane), frame.stride(VideoFrame::kUPlane),
- frame.data(VideoFrame::kVPlane), frame.stride(VideoFrame::kVPlane),
- image_ptr + image.offsets[0], image.pitches[0],
- image_ptr + image.offsets[1], image.pitches[1],
- visible_size.width(), visible_size.height());
- break;
- case PIXEL_FORMAT_NV12: {
- int uv_width = visible_size.width();
- if (visible_size.width() % 2 != 0 &&
- !base::CheckAdd<int>(visible_size.width(), 1)
- .AssignIfValid(&uv_width)) {
- return false;
- }
-
- int uv_height = 0;
- if (!(base::CheckAdd<int>(visible_size.height(), 1) / 2)
- .AssignIfValid(&uv_height)) {
- return false;
- }
-
- libyuv::CopyPlane(frame.data(VideoFrame::kYPlane),
- frame.stride(VideoFrame::kYPlane),
- image_ptr + image.offsets[0], image.pitches[0],
- visible_size.width(), visible_size.height());
- libyuv::CopyPlane(frame.data(VideoFrame::kUVPlane),
- frame.stride(VideoFrame::kUVPlane),
- image_ptr + image.offsets[1], image.pitches[1],
- uv_width, uv_height);
- } break;
- default:
- LOG(ERROR) << "Unsupported pixel format: " << frame.format();
- return false;
+ if (frame.format() == PIXEL_FORMAT_I420) {
+ ret = libyuv::I420ToNV12(
+ frame.data(VideoFrame::kYPlane), frame.stride(VideoFrame::kYPlane),
+ frame.data(VideoFrame::kUPlane), frame.stride(VideoFrame::kUPlane),
+ frame.data(VideoFrame::kVPlane), frame.stride(VideoFrame::kVPlane),
+ image_ptr + image.offsets[0], image.pitches[0],
+ image_ptr + image.offsets[1], image.pitches[1], visible_size.width(),
+ visible_size.height());
+ } else {
+ LOG(ERROR) << "Unsupported pixel format: "
+ << VideoPixelFormatToString(frame.format());
+ return false;
}
}
if (needs_va_put_image) {
@@ -2686,7 +2807,7 @@ std::unique_ptr<ScopedVABuffer> VaapiWrapper::CreateVABuffer(VABufferType type,
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
TRACE_EVENT0("media,gpu", "VaapiWrapper::CreateVABuffer");
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
TRACE_EVENT2("media,gpu", "VaapiWrapper::CreateVABufferLocked", "type", type,
"size", size);
#if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -2707,7 +2828,7 @@ uint64_t VaapiWrapper::GetEncodedChunkSize(VABufferID buffer_id,
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
TRACE_EVENT0("media,gpu", "VaapiWrapper::GetEncodedChunkSize");
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
TRACE_EVENT0("media,gpu", "VaapiWrapper::GetEncodedChunkSizeLocked");
// vaSyncSurface() is not necessary on Intel platforms as long as there is a
@@ -2745,7 +2866,7 @@ bool VaapiWrapper::DownloadFromVABuffer(
sequence_checker_.CalledOnValidSequence());
DCHECK(target_ptr);
TRACE_EVENT0("media,gpu", "VaapiWrapper::DownloadFromVABuffer");
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
TRACE_EVENT0("media,gpu", "VaapiWrapper::DownloadFromVABufferLocked");
// vaSyncSurface() is not necessary on Intel platforms as long as there is a
@@ -2803,7 +2924,7 @@ bool VaapiWrapper::GetVAEncMaxNumOfRefFrames(VideoCodecProfile profile,
VAConfigAttrib attrib;
attrib.type = VAConfigAttribEncMaxRefFrames;
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
VAStatus va_res = vaGetConfigAttributes(va_display_, va_profile,
va_entrypoint_, &attrib, 1);
VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAGetConfigAttributes, false);
@@ -2822,7 +2943,7 @@ bool VaapiWrapper::GetSupportedPackedHeaders(VideoCodecProfile profile,
ProfileToVAProfile(profile, CodecMode::kEncodeConstantBitrate);
VAConfigAttrib attrib{};
attrib.type = VAConfigAttribEncPackedHeaders;
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
const VAStatus va_res = vaGetConfigAttributes(va_display_, va_profile,
va_entrypoint_, &attrib, 1);
VA_SUCCESS_OR_RETURN(va_res, VaapiFunctions::kVAGetConfigAttributes, false);
@@ -2836,7 +2957,7 @@ bool VaapiWrapper::GetSupportedPackedHeaders(VideoCodecProfile profile,
bool VaapiWrapper::IsRotationSupported() {
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
VAProcPipelineCaps pipeline_caps;
memset(&pipeline_caps, 0, sizeof(pipeline_caps));
VAStatus va_res = vaQueryVideoProcPipelineCaps(va_display_, va_context_id_,
@@ -2864,7 +2985,7 @@ bool VaapiWrapper::BlitSurface(const VASurface& va_surface_src,
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
DCHECK_EQ(mode_, kVideoProcess);
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
// Create a buffer for VPP if it has not been created.
if (!va_buffer_for_vpp_) {
@@ -3045,7 +3166,7 @@ bool VaapiWrapper::Initialize(VAProfile va_profile,
const VAEntrypoint entrypoint = GetDefaultVaEntryPoint(mode_, va_profile);
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
std::vector<VAConfigAttrib> required_attribs;
if (!GetRequiredAttribs(va_lock_, va_display_, mode_, va_profile, entrypoint,
&required_attribs)) {
@@ -3081,7 +3202,7 @@ void VaapiWrapper::Deinitialize() {
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
{
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
#if BUILDFLAG(IS_CHROMEOS_ASH)
if (va_protected_session_id_ != VA_INVALID_ID) {
VAStatus va_res =
@@ -3122,7 +3243,7 @@ bool VaapiWrapper::VaInitialize(
}
{
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
va_display_ = VADisplayState::Get()->va_display();
DCHECK(va_display_) << "VADisplayState hasn't been properly Initialize()d";
}
@@ -3132,7 +3253,7 @@ bool VaapiWrapper::VaInitialize(
void VaapiWrapper::DestroyContext() {
CHECK(!enforce_sequence_affinity_ ||
sequence_checker_.CalledOnValidSequence());
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
DVLOG(2) << "Destroying context";
if (va_context_id_ != VA_INVALID_ID) {
@@ -3180,7 +3301,7 @@ bool VaapiWrapper::CreateSurfaces(
VAStatus va_res;
{
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
va_res = vaCreateSurfaces(
va_display_, va_format, base::checked_cast<unsigned int>(size.width()),
base::checked_cast<unsigned int>(size.height()), va_surfaces->data(),
@@ -3227,7 +3348,7 @@ VaapiWrapper::CreateScopedVASurfaces(
attribs[1].value.type = VAGenericValueTypeInteger;
attribs[1].value.value.i = base::checked_cast<int32_t>(*va_fourcc);
}
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
std::vector<VASurfaceID> va_surface_ids(num_surfaces, VA_INVALID_ID);
const VAStatus va_res = vaCreateSurfaces(
va_display_, va_rt_format, base::checked_cast<unsigned int>(size.width()),
@@ -3263,7 +3384,7 @@ void VaapiWrapper::DestroySurfaces(std::vector<VASurfaceID> va_surfaces) {
if (va_surfaces.empty())
return;
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
const VAStatus va_res =
vaDestroySurfaces(va_display_, va_surfaces.data(), va_surfaces.size());
VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroySurfaces);
@@ -3275,7 +3396,7 @@ void VaapiWrapper::DestroySurface(VASurfaceID va_surface_id) {
if (va_surface_id == VA_INVALID_SURFACE)
return;
DVLOG(3) << __func__ << " " << va_surface_id;
- base::AutoLockMaybe auto_lock(va_lock_);
+ base::AutoLockMaybe auto_lock(va_lock_.get());
const VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_id, 1);
VA_LOG_ON_ERROR(va_res, VaapiFunctions::kVADestroySurfaces);
}