Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Unified Diff: content/common/gpu/media/vaapi_wrapper.cc

Issue 1882373004: Migrate content/common/gpu/media code to media/gpu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix several more bot-identified build issues Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/common/gpu/media/vaapi_wrapper.cc
diff --git a/content/common/gpu/media/vaapi_wrapper.cc b/content/common/gpu/media/vaapi_wrapper.cc
deleted file mode 100644
index ab4e176e4ec0e869448e192728bcce4a80257d46..0000000000000000000000000000000000000000
--- a/content/common/gpu/media/vaapi_wrapper.cc
+++ /dev/null
@@ -1,1274 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/common/gpu/media/vaapi_wrapper.h"
-
-#include <dlfcn.h>
-#include <string.h>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/sys_info.h"
-#include "build/build_config.h"
-// Auto-generated for dlopen libva libraries
-#include "content/common/gpu/media/va_stubs.h"
-#include "content/common/gpu/media/vaapi_picture.h"
-#include "third_party/libyuv/include/libyuv.h"
-#include "ui/gl/gl_bindings.h"
-#if defined(USE_X11)
-#include "ui/gfx/x/x11_types.h"
-#elif defined(USE_OZONE)
-#include "third_party/libva/va/drm/va_drm.h"
-#include "third_party/libva/va/va_drmcommon.h"
-#include "ui/ozone/public/ozone_platform.h"
-#include "ui/ozone/public/surface_factory_ozone.h"
-#endif // USE_X11
-
-using content_common_gpu_media::kModuleVa;
-#if defined(USE_X11)
-using content_common_gpu_media::kModuleVa_x11;
-#elif defined(USE_OZONE)
-using content_common_gpu_media::kModuleVa_drm;
-#endif // USE_X11
-using content_common_gpu_media::InitializeStubs;
-using content_common_gpu_media::StubPathMap;
-
-#define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \
- do { \
- LOG(ERROR) << err_msg \
- << " VA error: " << vaErrorStr(va_error); \
- report_error_to_uma_cb_.Run(); \
- } while (0)
-
-#define VA_LOG_ON_ERROR(va_error, err_msg) \
- do { \
- if ((va_error) != VA_STATUS_SUCCESS) \
- LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \
- } while (0)
-
-#define VA_SUCCESS_OR_RETURN(va_error, err_msg, ret) \
- do { \
- if ((va_error) != VA_STATUS_SUCCESS) { \
- LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \
- return (ret); \
- } \
- } while (0)
-
-#if defined(USE_OZONE)
-namespace {
-
-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
-#endif
-
-namespace content {
-
-// Maximum framerate of encoded profile. This value is an arbitary limit
-// and not taken from HW documentation.
-const int kMaxEncoderFramerate = 30;
-
-base::LazyInstance<VaapiWrapper::VADisplayState>
- VaapiWrapper::va_display_state_ = LAZY_INSTANCE_INITIALIZER;
-
-base::LazyInstance<VaapiWrapper::LazyProfileInfos>
- VaapiWrapper::profile_infos_ = LAZY_INSTANCE_INITIALIZER;
-
-// Config attributes common for both encode and decode.
-static const VAConfigAttrib kCommonVAConfigAttribs[] = {
- {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420},
-};
-
-// Attributes required for encode.
-static const VAConfigAttrib kEncodeVAConfigAttribs[] = {
- {VAConfigAttribRateControl, VA_RC_CBR},
- {VAConfigAttribEncPackedHeaders,
- VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE},
-};
-
-struct ProfileMap {
- media::VideoCodecProfile profile;
- VAProfile va_profile;
-};
-
-// A map between VideoCodecProfile and VAProfile.
-static const ProfileMap kProfileMap[] = {
- {media::H264PROFILE_BASELINE, VAProfileH264Baseline},
- {media::H264PROFILE_MAIN, VAProfileH264Main},
- // TODO(posciak): See if we can/want support other variants of
- // media::H264PROFILE_HIGH*.
- {media::H264PROFILE_HIGH, VAProfileH264High},
- {media::VP8PROFILE_ANY, VAProfileVP8Version0_3},
- // TODO(servolk): Need to add VP9 profiles 1,2,3 here after rolling
- // third_party/libva to 1.7. crbug.com/598118
- {media::VP9PROFILE_PROFILE0, VAProfileVP9Profile0},
-};
-
-static std::vector<VAConfigAttrib> GetRequiredAttribs(
- VaapiWrapper::CodecMode mode) {
- std::vector<VAConfigAttrib> required_attribs;
- required_attribs.insert(
- required_attribs.end(),
- kCommonVAConfigAttribs,
- kCommonVAConfigAttribs + arraysize(kCommonVAConfigAttribs));
- if (mode == VaapiWrapper::kEncode) {
- required_attribs.insert(
- required_attribs.end(),
- kEncodeVAConfigAttribs,
- kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs));
- }
- return required_attribs;
-}
-
-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),
- format_(format),
- release_cb_(release_cb) {
- DCHECK(!release_cb_.is_null());
-}
-
-VASurface::~VASurface() {
- release_cb_.Run(va_surface_id_);
-}
-
-VaapiWrapper::VaapiWrapper()
- : 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),
- va_vpp_context_id_(VA_INVALID_ID),
- va_vpp_buffer_id_(VA_INVALID_ID) {
- va_lock_ = va_display_state_.Get().va_lock();
-}
-
-VaapiWrapper::~VaapiWrapper() {
- DestroyPendingBuffers();
- DestroyCodedBuffers();
- DestroySurfaces();
- DeinitializeVpp();
- Deinitialize();
-}
-
-// static
-scoped_refptr<VaapiWrapper> VaapiWrapper::Create(
- CodecMode mode,
- VAProfile va_profile,
- const base::Closure& report_error_to_uma_cb) {
- if (!profile_infos_.Get().IsProfileSupported(mode, va_profile)) {
- DVLOG(1) << "Unsupported va_profile: " << va_profile;
- return nullptr;
- }
-
- scoped_refptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
- if (vaapi_wrapper->VaInitialize(report_error_to_uma_cb)) {
- if (vaapi_wrapper->Initialize(mode, va_profile))
- return vaapi_wrapper;
- }
- LOG(ERROR) << "Failed to create VaapiWrapper for va_profile: " << va_profile;
- return nullptr;
-}
-
-// static
-scoped_refptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec(
- CodecMode mode,
- media::VideoCodecProfile profile,
- const base::Closure& report_error_to_uma_cb) {
- VAProfile va_profile = ProfileToVAProfile(profile, mode);
- scoped_refptr<VaapiWrapper> vaapi_wrapper =
- Create(mode, va_profile, report_error_to_uma_cb);
- return vaapi_wrapper;
-}
-
-// static
-media::VideoEncodeAccelerator::SupportedProfiles
-VaapiWrapper::GetSupportedEncodeProfiles() {
- media::VideoEncodeAccelerator::SupportedProfiles profiles;
- std::vector<ProfileInfo> encode_profile_infos =
- profile_infos_.Get().GetSupportedProfileInfosForCodecMode(kEncode);
-
- for (size_t i = 0; i < arraysize(kProfileMap); ++i) {
- VAProfile va_profile = ProfileToVAProfile(kProfileMap[i].profile, kEncode);
- if (va_profile == VAProfileNone)
- continue;
- for (const auto& profile_info : encode_profile_infos) {
- if (profile_info.va_profile == va_profile) {
- media::VideoEncodeAccelerator::SupportedProfile profile;
- profile.profile = kProfileMap[i].profile;
- profile.max_resolution = profile_info.max_resolution;
- profile.max_framerate_numerator = kMaxEncoderFramerate;
- profile.max_framerate_denominator = 1;
- profiles.push_back(profile);
- break;
- }
- }
- }
- return profiles;
-}
-
-// static
-media::VideoDecodeAccelerator::SupportedProfiles
-VaapiWrapper::GetSupportedDecodeProfiles() {
- media::VideoDecodeAccelerator::SupportedProfiles profiles;
- std::vector<ProfileInfo> decode_profile_infos =
- profile_infos_.Get().GetSupportedProfileInfosForCodecMode(kDecode);
-
- for (size_t i = 0; i < arraysize(kProfileMap); ++i) {
- VAProfile va_profile = ProfileToVAProfile(kProfileMap[i].profile, kDecode);
- if (va_profile == VAProfileNone)
- continue;
- for (const auto& profile_info : decode_profile_infos) {
- if (profile_info.va_profile == va_profile) {
- media::VideoDecodeAccelerator::SupportedProfile profile;
- profile.profile = kProfileMap[i].profile;
- profile.max_resolution = profile_info.max_resolution;
- profile.min_resolution.SetSize(16, 16);
- profiles.push_back(profile);
- break;
- }
- }
- }
- return profiles;
-}
-
-// static
-bool VaapiWrapper::IsJpegDecodeSupported() {
- return profile_infos_.Get().IsProfileSupported(kDecode,
- VAProfileJPEGBaseline);
-}
-
-void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
- base::AutoLock auto_lock(*va_lock_);
- VADisplayAttribute item = {VADisplayAttribRenderMode,
- 1, // At least support '_LOCAL_OVERLAY'.
- -1, // The maximum possible support 'ALL'.
- VA_RENDER_MODE_LOCAL_GPU,
- VA_DISPLAY_ATTRIB_SETTABLE};
-
- VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1);
- if (va_res != VA_STATUS_SUCCESS)
- DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default.";
-}
-
-// static
-VAProfile VaapiWrapper::ProfileToVAProfile(
- media::VideoCodecProfile profile, CodecMode mode) {
- VAProfile va_profile = VAProfileNone;
- for (size_t i = 0; i < arraysize(kProfileMap); ++i) {
- if (kProfileMap[i].profile == profile) {
- va_profile = kProfileMap[i].va_profile;
- break;
- }
- }
- if (!profile_infos_.Get().IsProfileSupported(mode, va_profile) &&
- va_profile == VAProfileH264Baseline) {
- // crbug.com/345569: media::ProfileIDToVideoCodecProfile() currently strips
- // the information whether the profile is constrained or not, so we have no
- // way to know here. Try for baseline first, but if it is not supported,
- // try constrained baseline and hope this is what it actually is
- // (which in practice is true for a great majority of cases).
- if (profile_infos_.Get().IsProfileSupported(
- mode, VAProfileH264ConstrainedBaseline)) {
- va_profile = VAProfileH264ConstrainedBaseline;
- DVLOG(1) << "Fall back to constrained baseline profile.";
- }
- }
- return va_profile;
-}
-
-std::vector<VaapiWrapper::ProfileInfo>
-VaapiWrapper::GetSupportedProfileInfosForCodecModeInternal(CodecMode mode) {
- std::vector<ProfileInfo> supported_profile_infos;
- std::vector<VAProfile> va_profiles;
- if (!GetSupportedVaProfiles(&va_profiles))
- return supported_profile_infos;
-
- std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode);
- VAEntrypoint entrypoint =
- (mode == kEncode ? VAEntrypointEncSlice: VAEntrypointVLD);
-
- base::AutoLock auto_lock(*va_lock_);
- for (const auto& va_profile : va_profiles) {
- if (!IsEntrypointSupported_Locked(va_profile, entrypoint))
- continue;
- if (!AreAttribsSupported_Locked(va_profile, entrypoint, required_attribs))
- continue;
- ProfileInfo profile_info;
- if (!GetMaxResolution_Locked(va_profile,
- entrypoint,
- required_attribs,
- &profile_info.max_resolution)) {
- LOG(ERROR) << "GetMaxResolution failed for va_profile " << va_profile
- << " and entrypoint " << entrypoint;
- continue;
- }
- profile_info.va_profile = va_profile;
- supported_profile_infos.push_back(profile_info);
- }
- return supported_profile_infos;
-}
-
-bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) {
- static bool vaapi_functions_initialized = PostSandboxInitialization();
- if (!vaapi_functions_initialized) {
- bool running_on_chromeos = false;
-#if defined(OS_CHROMEOS)
- // When chrome runs on linux with chromeos=1, do not log error message
- // without VAAPI libraries.
- running_on_chromeos = base::SysInfo::IsRunningOnChromeOS();
-#endif
- static const char kErrorMsg[] = "Failed to initialize VAAPI libs";
- if (running_on_chromeos)
- LOG(ERROR) << kErrorMsg;
- else
- DVLOG(1) << kErrorMsg;
- return false;
- }
-
- report_error_to_uma_cb_ = report_error_to_uma_cb;
-
- base::AutoLock auto_lock(*va_lock_);
-
- VADisplayState* va_display_state = &va_display_state_.Get();
- if (!va_display_state) {
- LOG(ERROR) << "Failed to allocate VA display state";
- return false;
- }
-
- if (!va_display_state->Initialize())
- return false;
-
- va_display_ = va_display_state->va_display();
- return true;
-}
-
-bool VaapiWrapper::GetSupportedVaProfiles(std::vector<VAProfile>* profiles) {
- base::AutoLock auto_lock(*va_lock_);
- // Query the driver for supported profiles.
- int max_profiles = vaMaxNumProfiles(va_display_);
- std::vector<VAProfile> supported_profiles(
- base::checked_cast<size_t>(max_profiles));
-
- int num_supported_profiles;
- VAStatus va_res = vaQueryConfigProfiles(
- va_display_, &supported_profiles[0], &num_supported_profiles);
- VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false);
- if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) {
- LOG(ERROR) << "vaQueryConfigProfiles returned: " << num_supported_profiles;
- return false;
- }
-
- supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles));
- *profiles = supported_profiles;
- return true;
-}
-
-bool VaapiWrapper::IsEntrypointSupported_Locked(VAProfile va_profile,
- VAEntrypoint entrypoint) {
- va_lock_->AssertAcquired();
- // Query the driver for supported entrypoints.
- int max_entrypoints = vaMaxNumEntrypoints(va_display_);
- std::vector<VAEntrypoint> supported_entrypoints(
- base::checked_cast<size_t>(max_entrypoints));
-
- int num_supported_entrypoints;
- VAStatus va_res = vaQueryConfigEntrypoints(va_display_,
- va_profile,
- &supported_entrypoints[0],
- &num_supported_entrypoints);
- VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false);
- if (num_supported_entrypoints < 0 ||
- num_supported_entrypoints > max_entrypoints) {
- LOG(ERROR) << "vaQueryConfigEntrypoints returned: "
- << num_supported_entrypoints;
- return false;
- }
-
- if (std::find(supported_entrypoints.begin(),
- supported_entrypoints.end(),
- entrypoint) == supported_entrypoints.end()) {
- DVLOG(1) << "Unsupported entrypoint";
- return false;
- }
- return true;
-}
-
-bool VaapiWrapper::AreAttribsSupported_Locked(
- VAProfile va_profile,
- VAEntrypoint entrypoint,
- const std::vector<VAConfigAttrib>& required_attribs) {
- va_lock_->AssertAcquired();
- // Query the driver for required attributes.
- std::vector<VAConfigAttrib> attribs = required_attribs;
- for (size_t i = 0; i < required_attribs.size(); ++i)
- attribs[i].value = 0;
-
- VAStatus va_res = vaGetConfigAttributes(
- va_display_, va_profile, entrypoint, &attribs[0], attribs.size());
- VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false);
-
- for (size_t i = 0; i < required_attribs.size(); ++i) {
- if (attribs[i].type != required_attribs[i].type ||
- (attribs[i].value & required_attribs[i].value) !=
- required_attribs[i].value) {
- DVLOG(1) << "Unsupported value " << required_attribs[i].value
- << " for attribute type " << required_attribs[i].type;
- return false;
- }
- }
- return true;
-}
-
-bool VaapiWrapper::GetMaxResolution_Locked(
- VAProfile va_profile,
- VAEntrypoint entrypoint,
- std::vector<VAConfigAttrib>& required_attribs,
- gfx::Size* resolution) {
- va_lock_->AssertAcquired();
- VAConfigID va_config_id;
- VAStatus va_res = vaCreateConfig(
- va_display_,
- va_profile,
- entrypoint,
- &required_attribs[0],
- required_attribs.size(),
- &va_config_id);
- VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false);
-
- // Calls vaQuerySurfaceAttributes twice. The first time is to get the number
- // of attributes to prepare the space and the second time is to get all
- // attributes.
- unsigned int num_attribs;
- va_res = vaQuerySurfaceAttributes(
- va_display_, va_config_id, nullptr, &num_attribs);
- VA_SUCCESS_OR_RETURN(va_res, "vaQuerySurfaceAttributes failed", false);
- if (!num_attribs)
- return false;
-
- std::vector<VASurfaceAttrib> attrib_list(
- base::checked_cast<size_t>(num_attribs));
-
- va_res = vaQuerySurfaceAttributes(
- va_display_, va_config_id, &attrib_list[0], &num_attribs);
- VA_SUCCESS_OR_RETURN(va_res, "vaQuerySurfaceAttributes failed", false);
-
- resolution->SetSize(0, 0);
- for (const auto& attrib : attrib_list) {
- if (attrib.type == VASurfaceAttribMaxWidth)
- resolution->set_width(attrib.value.value.i);
- else if (attrib.type == VASurfaceAttribMaxHeight)
- resolution->set_height(attrib.value.value.i);
- }
- if (resolution->IsEmpty()) {
- LOG(ERROR) << "Codec resolution " << resolution->ToString()
- << " cannot be zero.";
- return false;
- }
- return true;
-}
-
-bool VaapiWrapper::Initialize(CodecMode mode, VAProfile va_profile) {
- TryToSetVADisplayAttributeToLocalGPU();
-
- VAEntrypoint entrypoint =
- (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD);
- std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode);
- base::AutoLock auto_lock(*va_lock_);
- VAStatus va_res = vaCreateConfig(va_display_,
- va_profile,
- entrypoint,
- &required_attribs[0],
- required_attribs.size(),
- &va_config_id_);
- VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false);
-
- return true;
-}
-
-void VaapiWrapper::Deinitialize() {
- base::AutoLock auto_lock(*va_lock_);
-
- if (va_config_id_ != VA_INVALID_ID) {
- VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_);
- VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed");
- }
-
- VADisplayState* va_display_state = &va_display_state_.Get();
- if (va_display_state) {
- VAStatus va_res = VA_STATUS_SUCCESS;
- va_display_state->Deinitialize(&va_res);
- VA_LOG_ON_ERROR(va_res, "vaTerminate failed");
- }
-
- va_config_id_ = VA_INVALID_ID;
- va_display_ = NULL;
-}
-
-bool VaapiWrapper::CreateSurfaces(unsigned int va_format,
- const gfx::Size& size,
- size_t num_surfaces,
- std::vector<VASurfaceID>* va_surfaces) {
- base::AutoLock auto_lock(*va_lock_);
- DVLOG(2) << "Creating " << num_surfaces << " surfaces";
-
- 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.
- VAStatus va_res =
- vaCreateSurfaces(va_display_, va_format, size.width(), size.height(),
- &va_surface_ids_[0], va_surface_ids_.size(), NULL, 0);
-
- VA_LOG_ON_ERROR(va_res, "vaCreateSurfaces failed");
- if (va_res != VA_STATUS_SUCCESS) {
- va_surface_ids_.clear();
- return false;
- }
-
- // And create a context associated with them.
- va_res = vaCreateContext(va_display_, va_config_id_,
- size.width(), size.height(), VA_PROGRESSIVE,
- &va_surface_ids_[0], va_surface_ids_.size(),
- &va_context_id_);
-
- VA_LOG_ON_ERROR(va_res, "vaCreateContext failed");
- if (va_res != VA_STATUS_SUCCESS) {
- DestroySurfaces();
- return false;
- }
-
- *va_surfaces = va_surface_ids_;
- va_surface_format_ = va_format;
- return true;
-}
-
-void VaapiWrapper::DestroySurfaces() {
- base::AutoLock auto_lock(*va_lock_);
- DVLOG(2) << "Destroying " << va_surface_ids_.size() << " surfaces";
-
- if (va_context_id_ != VA_INVALID_ID) {
- VAStatus va_res = vaDestroyContext(va_display_, va_context_id_);
- VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed");
- }
-
- if (!va_surface_ids_.empty()) {
- VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0],
- va_surface_ids_.size());
- VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed");
- }
-
- va_surface_ids_.clear();
- va_context_id_ = VA_INVALID_ID;
- va_surface_format_ = 0;
-}
-
-scoped_refptr<VASurface> VaapiWrapper::CreateUnownedSurface(
- unsigned int va_format,
- const gfx::Size& size,
- const std::vector<VASurfaceAttrib>& va_attribs) {
- base::AutoLock auto_lock(*va_lock_);
-
- std::vector<VASurfaceAttrib> attribs(va_attribs);
- VASurfaceID va_surface_id;
- VAStatus va_res =
- vaCreateSurfaces(va_display_, va_format, size.width(), size.height(),
- &va_surface_id, 1, &attribs[0], attribs.size());
-
- scoped_refptr<VASurface> va_surface;
- VA_SUCCESS_OR_RETURN(va_res, "Failed to create unowned VASurface",
- va_surface);
-
- // This is safe to use Unretained() here, because the VDA takes care
- // of the destruction order. All the surfaces will be destroyed
- // before VaapiWrapper.
- va_surface = new VASurface(
- va_surface_id, size, va_format,
- base::Bind(&VaapiWrapper::DestroyUnownedSurface, base::Unretained(this)));
-
- return va_surface;
-}
-
-#if defined(USE_OZONE)
-scoped_refptr<VASurface> VaapiWrapper::CreateVASurfaceForPixmap(
- const scoped_refptr<ui::NativePixmap>& pixmap) {
- // Get the dmabuf of the created buffer.
- int dmabuf_fd = pixmap->GetDmaBufFd();
- if (dmabuf_fd < 0) {
- LOG(ERROR) << "Failed to get dmabuf from an Ozone NativePixmap";
- return nullptr;
- }
- int dmabuf_pitch = pixmap->GetDmaBufPitch();
- gfx::Size pixmap_size = pixmap->GetBufferSize();
-
- // 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 =
- 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;
- va_attrib_extbuf.num_planes = 1;
- va_attrib_extbuf.pitches[0] = dmabuf_pitch;
- va_attrib_extbuf.offsets[0] = 0;
- va_attrib_extbuf.buffers = reinterpret_cast<unsigned long*>(&dmabuf_fd);
- va_attrib_extbuf.num_buffers = 1;
- va_attrib_extbuf.flags = 0;
- va_attrib_extbuf.private_data = NULL;
-
- std::vector<VASurfaceAttrib> va_attribs;
- va_attribs.resize(2);
-
- 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[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;
-
- scoped_refptr<VASurface> va_surface =
- CreateUnownedSurface(BufferFormatToVARTFormat(pixmap->GetBufferFormat()),
- pixmap_size, va_attribs);
- if (!va_surface) {
- LOG(ERROR) << "Failed to create VASurface for an Ozone NativePixmap";
- return nullptr;
- }
-
- return va_surface;
-}
-
-bool VaapiWrapper::ProcessPixmap(
- const scoped_refptr<ui::NativePixmap>& source_pixmap,
- scoped_refptr<ui::NativePixmap> target_pixmap) {
- scoped_refptr<VASurface> va_surface = CreateVASurfaceForPixmap(source_pixmap);
- if (!va_surface) {
- LOG(ERROR) << "Failed creating VA Surface for source_pixmap";
- return false;
- }
-
- scoped_refptr<VASurface> processed_va_surface =
- CreateVASurfaceForPixmap(target_pixmap);
- if (!processed_va_surface) {
- LOG(ERROR) << "Failed creating processed VA Surface for pixmap";
- return false;
- }
-
- if (!BlitSurface(va_surface, processed_va_surface)) {
- LOG(ERROR) << "Failed scaling NativePixmap";
- return false;
- }
-
- return true;
-}
-
-#endif
-
-void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface_id) {
- base::AutoLock auto_lock(*va_lock_);
-
- VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_id, 1);
- VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on surface failed");
-}
-
-bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type,
- size_t size,
- void* buffer) {
- base::AutoLock auto_lock(*va_lock_);
-
- VABufferID buffer_id;
- VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_,
- va_buffer_type, size,
- 1, buffer, &buffer_id);
- VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false);
-
- switch (va_buffer_type) {
- case VASliceParameterBufferType:
- case VASliceDataBufferType:
- case VAEncSliceParameterBufferType:
- pending_slice_bufs_.push_back(buffer_id);
- break;
-
- default:
- pending_va_bufs_.push_back(buffer_id);
- break;
- }
-
- return true;
-}
-
-bool VaapiWrapper::SubmitVAEncMiscParamBuffer(
- VAEncMiscParameterType misc_param_type,
- size_t size,
- void* buffer) {
- base::AutoLock auto_lock(*va_lock_);
-
- VABufferID buffer_id;
- VAStatus va_res = vaCreateBuffer(va_display_,
- va_context_id_,
- VAEncMiscParameterBufferType,
- sizeof(VAEncMiscParameterBuffer) + size,
- 1,
- NULL,
- &buffer_id);
- VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false);
-
- void* data_ptr = NULL;
- va_res = vaMapBuffer(va_display_, buffer_id, &data_ptr);
- VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed");
- if (va_res != VA_STATUS_SUCCESS) {
- vaDestroyBuffer(va_display_, buffer_id);
- return false;
- }
-
- DCHECK(data_ptr);
-
- VAEncMiscParameterBuffer* misc_param =
- reinterpret_cast<VAEncMiscParameterBuffer*>(data_ptr);
- misc_param->type = misc_param_type;
- memcpy(misc_param->data, buffer, size);
- va_res = vaUnmapBuffer(va_display_, buffer_id);
- VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
-
- pending_va_bufs_.push_back(buffer_id);
- return true;
-}
-
-void VaapiWrapper::DestroyPendingBuffers() {
- base::AutoLock auto_lock(*va_lock_);
-
- for (const auto& pending_va_buf : pending_va_bufs_) {
- VAStatus va_res = vaDestroyBuffer(va_display_, pending_va_buf);
- VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
- }
-
- for (const auto& pending_slice_buf : pending_slice_bufs_) {
- VAStatus va_res = vaDestroyBuffer(va_display_, pending_slice_buf);
- VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
- }
-
- pending_va_bufs_.clear();
- pending_slice_bufs_.clear();
-}
-
-bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) {
- base::AutoLock auto_lock(*va_lock_);
- VAStatus va_res = vaCreateBuffer(va_display_,
- va_context_id_,
- VAEncCodedBufferType,
- size,
- 1,
- NULL,
- buffer_id);
- VA_SUCCESS_OR_RETURN(va_res, "Failed to create a coded buffer", false);
-
- const auto is_new_entry = coded_buffers_.insert(*buffer_id).second;
- DCHECK(is_new_entry);
- return true;
-}
-
-void VaapiWrapper::DestroyCodedBuffers() {
- base::AutoLock auto_lock(*va_lock_);
-
- for (std::set<VABufferID>::const_iterator iter = coded_buffers_.begin();
- iter != coded_buffers_.end();
- ++iter) {
- VAStatus va_res = vaDestroyBuffer(va_display_, *iter);
- VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
- }
-
- coded_buffers_.clear();
-}
-
-bool VaapiWrapper::Execute(VASurfaceID va_surface_id) {
- base::AutoLock auto_lock(*va_lock_);
-
- DVLOG(4) << "Pending VA bufs to commit: " << pending_va_bufs_.size();
- DVLOG(4) << "Pending slice bufs to commit: " << pending_slice_bufs_.size();
- DVLOG(4) << "Target VA surface " << va_surface_id;
-
- // Get ready to execute for given surface.
- VAStatus va_res = vaBeginPicture(va_display_, va_context_id_,
- va_surface_id);
- VA_SUCCESS_OR_RETURN(va_res, "vaBeginPicture failed", false);
-
- if (pending_va_bufs_.size() > 0) {
- // Commit parameter and slice buffers.
- va_res = vaRenderPicture(va_display_,
- va_context_id_,
- &pending_va_bufs_[0],
- pending_va_bufs_.size());
- VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for va_bufs failed", false);
- }
-
- if (pending_slice_bufs_.size() > 0) {
- va_res = vaRenderPicture(va_display_,
- va_context_id_,
- &pending_slice_bufs_[0],
- pending_slice_bufs_.size());
- VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for slices failed", false);
- }
-
- // Instruct HW codec to start processing committed buffers.
- // Does not block and the job is not finished after this returns.
- va_res = vaEndPicture(va_display_, va_context_id_);
- VA_SUCCESS_OR_RETURN(va_res, "vaEndPicture failed", false);
-
- return true;
-}
-
-bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) {
- bool result = Execute(va_surface_id);
- DestroyPendingBuffers();
- return result;
-}
-
-#if defined(USE_X11)
-bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id,
- Pixmap x_pixmap,
- gfx::Size dest_size) {
- base::AutoLock auto_lock(*va_lock_);
-
- VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
- VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
-
- // Put the data into an X Pixmap.
- va_res = vaPutSurface(va_display_,
- va_surface_id,
- x_pixmap,
- 0, 0, dest_size.width(), dest_size.height(),
- 0, 0, dest_size.width(), dest_size.height(),
- NULL, 0, 0);
- VA_SUCCESS_OR_RETURN(va_res, "Failed putting surface to pixmap", false);
- return true;
-}
-#endif // USE_X11
-
-bool VaapiWrapper::GetDerivedVaImage(VASurfaceID va_surface_id,
- VAImage* image,
- void** mem) {
- base::AutoLock auto_lock(*va_lock_);
-
- VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
- VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
-
- // Derive a VAImage from the VASurface
- va_res = vaDeriveImage(va_display_, va_surface_id, image);
- VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed");
- if (va_res != VA_STATUS_SUCCESS)
- return false;
-
- // Map the VAImage into memory
- va_res = vaMapBuffer(va_display_, image->buf, mem);
- VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed");
- if (va_res == VA_STATUS_SUCCESS)
- return true;
-
- va_res = vaDestroyImage(va_display_, image->image_id);
- VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed");
-
- return false;
-}
-
-bool VaapiWrapper::GetVaImage(VASurfaceID va_surface_id,
- VAImageFormat* format,
- const gfx::Size& size,
- VAImage* image,
- void** mem) {
- base::AutoLock auto_lock(*va_lock_);
-
- VAStatus va_res = vaSyncSurface(va_display_, va_surface_id);
- VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
-
- va_res =
- vaCreateImage(va_display_, format, size.width(), size.height(), image);
- VA_SUCCESS_OR_RETURN(va_res, "vaCreateImage failed", false);
-
- va_res = vaGetImage(va_display_, va_surface_id, 0, 0, size.width(),
- size.height(), image->image_id);
- VA_LOG_ON_ERROR(va_res, "vaGetImage failed");
-
- if (va_res == VA_STATUS_SUCCESS) {
- // Map the VAImage into memory
- va_res = vaMapBuffer(va_display_, image->buf, mem);
- VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed");
- }
-
- if (va_res != VA_STATUS_SUCCESS) {
- va_res = vaDestroyImage(va_display_, image->image_id);
- VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed");
- return false;
- }
-
- return true;
-}
-
-void VaapiWrapper::ReturnVaImage(VAImage* image) {
- base::AutoLock auto_lock(*va_lock_);
-
- VAStatus va_res = vaUnmapBuffer(va_display_, image->buf);
- VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
-
- va_res = vaDestroyImage(va_display_, image->image_id);
- VA_LOG_ON_ERROR(va_res, "vaDestroyImage failed");
-}
-
-static void DestroyVAImage(VADisplay va_display, VAImage image) {
- if (image.image_id != VA_INVALID_ID)
- vaDestroyImage(va_display, image.image_id);
-}
-
-bool VaapiWrapper::UploadVideoFrameToSurface(
- const scoped_refptr<media::VideoFrame>& frame,
- VASurfaceID va_surface_id) {
- base::AutoLock auto_lock(*va_lock_);
-
- VAImage image;
- VAStatus va_res = vaDeriveImage(va_display_, va_surface_id, &image);
- VA_SUCCESS_OR_RETURN(va_res, "vaDeriveImage failed", false);
- base::ScopedClosureRunner vaimage_deleter(
- base::Bind(&DestroyVAImage, va_display_, image));
-
- if (image.format.fourcc != VA_FOURCC_NV12) {
- LOG(ERROR) << "Unsupported image format: " << image.format.fourcc;
- return false;
- }
-
- if (gfx::Rect(image.width, image.height) < gfx::Rect(frame->coded_size())) {
- LOG(ERROR) << "Buffer too small to fit the frame.";
- return false;
- }
-
- void* image_ptr = NULL;
- va_res = vaMapBuffer(va_display_, image.buf, &image_ptr);
- VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false);
- DCHECK(image_ptr);
-
- int ret = 0;
- {
- base::AutoUnlock auto_unlock(*va_lock_);
- ret = libyuv::I420ToNV12(
- frame->data(media::VideoFrame::kYPlane),
- frame->stride(media::VideoFrame::kYPlane),
- frame->data(media::VideoFrame::kUPlane),
- frame->stride(media::VideoFrame::kUPlane),
- frame->data(media::VideoFrame::kVPlane),
- frame->stride(media::VideoFrame::kVPlane),
- static_cast<uint8_t*>(image_ptr) + image.offsets[0], image.pitches[0],
- static_cast<uint8_t*>(image_ptr) + image.offsets[1], image.pitches[1],
- image.width, image.height);
- }
-
- va_res = vaUnmapBuffer(va_display_, image.buf);
- VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
-
- return ret == 0;
-}
-
-bool VaapiWrapper::DownloadAndDestroyCodedBuffer(VABufferID buffer_id,
- VASurfaceID sync_surface_id,
- uint8_t* target_ptr,
- size_t target_size,
- size_t* coded_data_size) {
- base::AutoLock auto_lock(*va_lock_);
-
- VAStatus va_res = vaSyncSurface(va_display_, sync_surface_id);
- VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false);
-
- VACodedBufferSegment* buffer_segment = NULL;
- va_res = vaMapBuffer(
- va_display_, buffer_id, reinterpret_cast<void**>(&buffer_segment));
- VA_SUCCESS_OR_RETURN(va_res, "vaMapBuffer failed", false);
- DCHECK(target_ptr);
-
- {
- base::AutoUnlock auto_unlock(*va_lock_);
- *coded_data_size = 0;
-
- while (buffer_segment) {
- DCHECK(buffer_segment->buf);
-
- if (buffer_segment->size > target_size) {
- LOG(ERROR) << "Insufficient output buffer size";
- break;
- }
-
- memcpy(target_ptr, buffer_segment->buf, buffer_segment->size);
-
- target_ptr += buffer_segment->size;
- *coded_data_size += buffer_segment->size;
- target_size -= buffer_segment->size;
-
- buffer_segment =
- reinterpret_cast<VACodedBufferSegment*>(buffer_segment->next);
- }
- }
-
- va_res = vaUnmapBuffer(va_display_, buffer_id);
- VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
-
- va_res = vaDestroyBuffer(va_display_, buffer_id);
- VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
-
- const auto was_found = coded_buffers_.erase(buffer_id);
- DCHECK(was_found);
-
- return buffer_segment == NULL;
-}
-
-bool VaapiWrapper::BlitSurface(
- const scoped_refptr<VASurface>& va_surface_src,
- const scoped_refptr<VASurface>& va_surface_dest) {
- base::AutoLock auto_lock(*va_lock_);
-
- // Initialize the post processing engine if not already done.
- if (va_vpp_buffer_id_ == VA_INVALID_ID) {
- if (!InitializeVpp_Locked())
- return false;
- }
-
- VAProcPipelineParameterBuffer* pipeline_param;
- VA_SUCCESS_OR_RETURN(vaMapBuffer(va_display_, va_vpp_buffer_id_,
- reinterpret_cast<void**>(&pipeline_param)),
- "Couldn't map vpp buffer", false);
-
- memset(pipeline_param, 0, sizeof *pipeline_param);
- const gfx::Size src_size = va_surface_src->size();
- const gfx::Size dest_size = va_surface_dest->size();
-
- VARectangle input_region;
- input_region.x = input_region.y = 0;
- input_region.width = src_size.width();
- input_region.height = src_size.height();
- pipeline_param->surface_region = &input_region;
- pipeline_param->surface = va_surface_src->id();
- pipeline_param->surface_color_standard = VAProcColorStandardNone;
-
- VARectangle output_region;
- output_region.x = output_region.y = 0;
- output_region.width = dest_size.width();
- output_region.height = dest_size.height();
- pipeline_param->output_region = &output_region;
- pipeline_param->output_background_color = 0xff000000;
- pipeline_param->output_color_standard = VAProcColorStandardNone;
- pipeline_param->filter_flags = VA_FILTER_SCALING_HQ;
-
- VA_SUCCESS_OR_RETURN(vaUnmapBuffer(va_display_, va_vpp_buffer_id_),
- "Couldn't unmap vpp buffer", false);
-
- VA_SUCCESS_OR_RETURN(
- vaBeginPicture(va_display_, va_vpp_context_id_, va_surface_dest->id()),
- "Couldn't begin picture", false);
-
- VA_SUCCESS_OR_RETURN(
- vaRenderPicture(va_display_, va_vpp_context_id_, &va_vpp_buffer_id_, 1),
- "Couldn't render picture", false);
-
- VA_SUCCESS_OR_RETURN(vaEndPicture(va_display_, va_vpp_context_id_),
- "Couldn't end picture", false);
-
- return true;
-}
-
-bool VaapiWrapper::InitializeVpp_Locked() {
- va_lock_->AssertAcquired();
-
- VA_SUCCESS_OR_RETURN(
- vaCreateConfig(va_display_, VAProfileNone, VAEntrypointVideoProc, NULL, 0,
- &va_vpp_config_id_),
- "Couldn't create config", false);
-
- // The size of the picture for the context is irrelevant in the case
- // of the VPP, just passing 1x1.
- VA_SUCCESS_OR_RETURN(vaCreateContext(va_display_, va_vpp_config_id_, 1, 1, 0,
- NULL, 0, &va_vpp_context_id_),
- "Couldn't create context", false);
-
- VA_SUCCESS_OR_RETURN(vaCreateBuffer(va_display_, va_vpp_context_id_,
- VAProcPipelineParameterBufferType,
- sizeof(VAProcPipelineParameterBuffer), 1,
- NULL, &va_vpp_buffer_id_),
- "Couldn't create buffer", false);
-
- return true;
-}
-
-void VaapiWrapper::DeinitializeVpp() {
- base::AutoLock auto_lock(*va_lock_);
-
- if (va_vpp_buffer_id_ != VA_INVALID_ID) {
- vaDestroyBuffer(va_display_, va_vpp_buffer_id_);
- va_vpp_buffer_id_ = VA_INVALID_ID;
- }
- if (va_vpp_context_id_ != VA_INVALID_ID) {
- vaDestroyContext(va_display_, va_vpp_context_id_);
- va_vpp_context_id_ = VA_INVALID_ID;
- }
- if (va_vpp_config_id_ != VA_INVALID_ID) {
- vaDestroyConfig(va_display_, va_vpp_config_id_);
- va_vpp_config_id_ = VA_INVALID_ID;
- }
-}
-
-// static
-void VaapiWrapper::PreSandboxInitialization() {
-#if defined(USE_OZONE)
- const char kDriRenderNode0Path[] = "/dev/dri/renderD128";
- base::File drm_file = base::File(
- base::FilePath::FromUTF8Unsafe(kDriRenderNode0Path),
- base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE);
- if (drm_file.IsValid())
- va_display_state_.Get().SetDrmFd(drm_file.GetPlatformFile());
-#endif
-}
-
-// static
-bool VaapiWrapper::PostSandboxInitialization() {
- StubPathMap paths;
-
- paths[kModuleVa].push_back("libva.so.1");
-
-#if defined(USE_X11)
- paths[kModuleVa_x11].push_back("libva-x11.so.1");
-#elif defined(USE_OZONE)
- paths[kModuleVa_drm].push_back("libva-drm.so.1");
-#endif
-
- return InitializeStubs(paths);
-}
-
-VaapiWrapper::LazyProfileInfos::LazyProfileInfos() {
- static_assert(arraysize(supported_profiles_) == kCodecModeMax,
- "The array size of supported profile is incorrect.");
- scoped_refptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
- if (!vaapi_wrapper->VaInitialize(base::Bind(&base::DoNothing)))
- return;
- for (size_t i = 0; i < kCodecModeMax; ++i) {
- supported_profiles_[i] =
- vaapi_wrapper->GetSupportedProfileInfosForCodecModeInternal(
- static_cast<CodecMode>(i));
- }
-}
-
-VaapiWrapper::LazyProfileInfos::~LazyProfileInfos() {
-}
-
-std::vector<VaapiWrapper::ProfileInfo>
-VaapiWrapper::LazyProfileInfos::GetSupportedProfileInfosForCodecMode(
- CodecMode mode) {
- return supported_profiles_[mode];
-}
-
-bool VaapiWrapper::LazyProfileInfos::IsProfileSupported(
- CodecMode mode, VAProfile va_profile) {
- for (const auto& profile : supported_profiles_[mode]) {
- if (profile.va_profile == va_profile)
- return true;
- }
- return false;
-}
-
-VaapiWrapper::VADisplayState::VADisplayState()
- : refcount_(0),
- va_display_(nullptr),
- major_version_(-1),
- minor_version_(-1),
- va_initialized_(false) {}
-
-VaapiWrapper::VADisplayState::~VADisplayState() {}
-
-bool VaapiWrapper::VADisplayState::Initialize() {
- va_lock_.AssertAcquired();
- if (refcount_++ == 0) {
-#if defined(USE_X11)
- va_display_ = vaGetDisplay(gfx::GetXDisplay());
-#elif defined(USE_OZONE)
- va_display_ = vaGetDisplayDRM(drm_fd_.get());
-#endif // USE_X11
-
- if (!vaDisplayIsValid(va_display_)) {
- LOG(ERROR) << "Could not get a valid VA display";
- return false;
- }
-
- VAStatus va_res =
- vaInitialize(va_display_, &major_version_, &minor_version_);
- if (va_res != VA_STATUS_SUCCESS) {
- LOG(WARNING) << "vaInitialize failed: " << vaErrorStr(va_res);
- return false;
- }
-
- va_initialized_ = true;
- DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_;
- }
-
- if (VAAPIVersionLessThan(0, 34)) {
- LOG(ERROR) << "VAAPI version < 0.34 is not supported.";
- return false;
- }
- return true;
-}
-
-void VaapiWrapper::VADisplayState::Deinitialize(VAStatus* status) {
- va_lock_.AssertAcquired();
- if (--refcount_ > 0)
- return;
-
- // Must check if vaInitialize completed successfully, to work around a bug in
- // libva. The bug was fixed upstream:
- // http://lists.freedesktop.org/archives/libva/2013-July/001807.html
- // TODO(mgiuca): Remove this check, and the |va_initialized_| variable, once
- // the fix has rolled out sufficiently.
- if (va_initialized_ && va_display_) {
- *status = vaTerminate(va_display_);
- }
- va_initialized_ = false;
- va_display_ = nullptr;
-}
-
-#if defined(USE_OZONE)
-void VaapiWrapper::VADisplayState::SetDrmFd(base::PlatformFile fd) {
- drm_fd_.reset(HANDLE_EINTR(dup(fd)));
-}
-#endif // USE_OZONE
-
-bool VaapiWrapper::VADisplayState::VAAPIVersionLessThan(int major, int minor) {
- return (major_version_ < major) ||
- (major_version_ == major && minor_version_ < minor);
-}
-
-} // namespace content

Powered by Google App Engine
This is Rietveld 408576698