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

Side by Side Diff: content/common/gpu/media/vaapi_wrapper.cc

Issue 1432963003: [Ozone] Extends the lifetime of VaapiWrapper (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/gpu/media/vaapi_wrapper.h" 5 #include "content/common/gpu/media/vaapi_wrapper.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/numerics/safe_conversions.h" 13 #include "base/numerics/safe_conversions.h"
14 #include "base/sys_info.h" 14 #include "base/sys_info.h"
15 // Auto-generated for dlopen libva libraries 15 // Auto-generated for dlopen libva libraries
16 #include "content/common/gpu/media/va_stubs.h" 16 #include "content/common/gpu/media/va_stubs.h"
17 #include "content/common/gpu/media/vaapi_picture.h" 17 #include "content/common/gpu/media/vaapi_picture.h"
18 #include "content/public/common/content_switches.h" 18 #include "content/public/common/content_switches.h"
19 #include "third_party/libyuv/include/libyuv.h" 19 #include "third_party/libyuv/include/libyuv.h"
20 #include "ui/gl/gl_bindings.h" 20 #include "ui/gl/gl_bindings.h"
21 #if defined(USE_X11) 21 #if defined(USE_X11)
22 #include "ui/gfx/x/x11_types.h" 22 #include "ui/gfx/x/x11_types.h"
23 #elif defined(USE_OZONE) 23 #elif defined(USE_OZONE)
24 #include "third_party/libva/va/drm/va_drm.h" 24 #include "third_party/libva/va/drm/va_drm.h"
25 #include "third_party/libva/va/va_drmcommon.h"
25 #include "ui/ozone/public/ozone_platform.h" 26 #include "ui/ozone/public/ozone_platform.h"
26 #include "ui/ozone/public/surface_factory_ozone.h" 27 #include "ui/ozone/public/surface_factory_ozone.h"
27 #endif // USE_X11 28 #endif // USE_X11
28 29
29 using content_common_gpu_media::kModuleVa; 30 using content_common_gpu_media::kModuleVa;
30 #if defined(USE_X11) 31 #if defined(USE_X11)
31 using content_common_gpu_media::kModuleVa_x11; 32 using content_common_gpu_media::kModuleVa_x11;
32 #elif defined(USE_OZONE) 33 #elif defined(USE_OZONE)
33 using content_common_gpu_media::kModuleVa_drm; 34 using content_common_gpu_media::kModuleVa_drm;
34 #endif // USE_X11 35 #endif // USE_X11
(...skipping 14 matching lines...) Expand all
49 } while (0) 50 } while (0)
50 51
51 #define VA_SUCCESS_OR_RETURN(va_error, err_msg, ret) \ 52 #define VA_SUCCESS_OR_RETURN(va_error, err_msg, ret) \
52 do { \ 53 do { \
53 if ((va_error) != VA_STATUS_SUCCESS) { \ 54 if ((va_error) != VA_STATUS_SUCCESS) { \
54 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ 55 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \
55 return (ret); \ 56 return (ret); \
56 } \ 57 } \
57 } while (0) 58 } while (0)
58 59
60 namespace {
61
62 uint32_t BufferFormatToVAFourCC(gfx::BufferFormat fmt) {
63 switch (fmt) {
64 case gfx::BufferFormat::BGRX_8888:
65 return VA_FOURCC_BGRX;
66 case gfx::BufferFormat::UYVY_422:
67 return VA_FOURCC_UYVY;
68 default:
69 NOTREACHED();
70 return 0;
71 }
72 }
73
74 uint32_t BufferFormatToVARTFormat(gfx::BufferFormat fmt) {
75 switch (fmt) {
76 case gfx::BufferFormat::UYVY_422:
77 return VA_RT_FORMAT_YUV422;
78 case gfx::BufferFormat::BGRX_8888:
79 return VA_RT_FORMAT_RGB32;
80 default:
81 NOTREACHED();
82 return 0;
83 }
84 }
85
86 } // namespace
87
59 namespace content { 88 namespace content {
60 89
61 // Maximum framerate of encoded profile. This value is an arbitary limit 90 // Maximum framerate of encoded profile. This value is an arbitary limit
62 // and not taken from HW documentation. 91 // and not taken from HW documentation.
63 const int kMaxEncoderFramerate = 30; 92 const int kMaxEncoderFramerate = 30;
64 93
65 base::LazyInstance<VaapiWrapper::VADisplayState> 94 base::LazyInstance<VaapiWrapper::VADisplayState>
66 VaapiWrapper::va_display_state_ = LAZY_INSTANCE_INITIALIZER; 95 VaapiWrapper::va_display_state_ = LAZY_INSTANCE_INITIALIZER;
67 96
68 base::LazyInstance<VaapiWrapper::LazyProfileInfos> 97 base::LazyInstance<VaapiWrapper::LazyProfileInfos>
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 169
141 VaapiWrapper::~VaapiWrapper() { 170 VaapiWrapper::~VaapiWrapper() {
142 DestroyPendingBuffers(); 171 DestroyPendingBuffers();
143 DestroyCodedBuffers(); 172 DestroyCodedBuffers();
144 DestroySurfaces(); 173 DestroySurfaces();
145 DeinitializeVpp(); 174 DeinitializeVpp();
146 Deinitialize(); 175 Deinitialize();
147 } 176 }
148 177
149 // static 178 // static
150 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( 179 scoped_refptr<VaapiWrapper> VaapiWrapper::Create(
151 CodecMode mode, 180 CodecMode mode,
152 VAProfile va_profile, 181 VAProfile va_profile,
153 const base::Closure& report_error_to_uma_cb) { 182 const base::Closure& report_error_to_uma_cb) {
154 if (!profile_infos_.Get().IsProfileSupported(mode, va_profile)) { 183 if (!profile_infos_.Get().IsProfileSupported(mode, va_profile)) {
155 DVLOG(1) << "Unsupported va_profile: " << va_profile; 184 DVLOG(1) << "Unsupported va_profile: " << va_profile;
156 return nullptr; 185 return nullptr;
157 } 186 }
158 187
159 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); 188 scoped_refptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
160 if (vaapi_wrapper->VaInitialize(report_error_to_uma_cb)) { 189 if (vaapi_wrapper->VaInitialize(report_error_to_uma_cb)) {
161 if (vaapi_wrapper->Initialize(mode, va_profile)) 190 if (vaapi_wrapper->Initialize(mode, va_profile))
162 return vaapi_wrapper.Pass(); 191 return vaapi_wrapper;
163 } 192 }
164 LOG(ERROR) << "Failed to create VaapiWrapper for va_profile: " << va_profile; 193 LOG(ERROR) << "Failed to create VaapiWrapper for va_profile: " << va_profile;
165 return nullptr; 194 return nullptr;
166 } 195 }
167 196
168 // static 197 // static
169 scoped_ptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec( 198 scoped_refptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec(
170 CodecMode mode, 199 CodecMode mode,
171 media::VideoCodecProfile profile, 200 media::VideoCodecProfile profile,
172 const base::Closure& report_error_to_uma_cb) { 201 const base::Closure& report_error_to_uma_cb) {
173 VAProfile va_profile = ProfileToVAProfile(profile, mode); 202 VAProfile va_profile = ProfileToVAProfile(profile, mode);
174 scoped_ptr<VaapiWrapper> vaapi_wrapper = 203 scoped_refptr<VaapiWrapper> vaapi_wrapper =
175 Create(mode, va_profile, report_error_to_uma_cb); 204 Create(mode, va_profile, report_error_to_uma_cb);
176 return vaapi_wrapper.Pass(); 205 return vaapi_wrapper;
177 } 206 }
178 207
179 // static 208 // static
180 media::VideoEncodeAccelerator::SupportedProfiles 209 media::VideoEncodeAccelerator::SupportedProfiles
181 VaapiWrapper::GetSupportedEncodeProfiles() { 210 VaapiWrapper::GetSupportedEncodeProfiles() {
182 media::VideoEncodeAccelerator::SupportedProfiles profiles; 211 media::VideoEncodeAccelerator::SupportedProfiles profiles;
183 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); 212 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
184 if (cmd_line->HasSwitch(switches::kDisableVaapiAcceleratedVideoEncode)) 213 if (cmd_line->HasSwitch(switches::kDisableVaapiAcceleratedVideoEncode))
185 return profiles; 214 return profiles;
186 215
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 // (which in practice is true for a great majority of cases). 298 // (which in practice is true for a great majority of cases).
270 if (profile_infos_.Get().IsProfileSupported( 299 if (profile_infos_.Get().IsProfileSupported(
271 mode, VAProfileH264ConstrainedBaseline)) { 300 mode, VAProfileH264ConstrainedBaseline)) {
272 va_profile = VAProfileH264ConstrainedBaseline; 301 va_profile = VAProfileH264ConstrainedBaseline;
273 DVLOG(1) << "Fall back to constrained baseline profile."; 302 DVLOG(1) << "Fall back to constrained baseline profile.";
274 } 303 }
275 } 304 }
276 return va_profile; 305 return va_profile;
277 } 306 }
278 307
308 scoped_refptr<ui::NativePixmap> VaapiWrapper::ProcessPixmap(
309 const scoped_refptr<ui::NativePixmap>& source_pixmap,
310 const gfx::Size& target_size,
311 gfx::BufferFormat target_format) {
312 scoped_refptr<VASurface> va_surface =
313 CreateVASurfaceForPixmap(source_pixmap, source_pixmap->size());
kalyank 2015/11/23 17:51:07 Now, we create va surface of original pixmap, only
william.xie1 2015/11/24 06:19:39 Dear Kalyan, I measured the cost, it is quit light
kalyank 2015/11/24 23:00:24 MiniGBM doesn't use dri infrastructure internally
314 if (!va_surface) {
315 LOG(ERROR) << "Failed creating VA Surface for source_pixmap";
316 return nullptr;
317 }
318
319 scoped_refptr<ui::NativePixmap> processed_pixmap =
320 CreateNativePixmap(target_size, target_format);
321 if (!processed_pixmap) {
322 LOG(ERROR) << "Failed creating an Ozone NativePixmap for processing";
323 return nullptr;
324 }
325
326 scoped_refptr<VASurface> processed_va_surface =
327 CreateVASurfaceForPixmap(processed_pixmap, target_size);
328 if (!processed_va_surface) {
329 LOG(ERROR) << "Failed creating processed VA Surface for pixmap";
330 return nullptr;
331 }
332
333 DCHECK(processed_pixmap);
334 if (!BlitSurface(va_surface, processed_va_surface)) {
335 LOG(ERROR) << "Failed scaling NativePixmap";
336 return nullptr;
337 }
338
339 return processed_pixmap;
340 }
341
342 scoped_refptr<ui::NativePixmap> VaapiWrapper::CreateNativePixmap(
343 gfx::Size size,
344 gfx::BufferFormat format) {
345 ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance();
346 ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone();
347
348 // Create a buffer from Ozone.
349 return factory->CreateNativePixmap(gfx::kNullAcceleratedWidget, size, format,
350 gfx::BufferUsage::SCANOUT);
351 }
352
279 std::vector<VaapiWrapper::ProfileInfo> 353 std::vector<VaapiWrapper::ProfileInfo>
280 VaapiWrapper::GetSupportedProfileInfosForCodecModeInternal(CodecMode mode) { 354 VaapiWrapper::GetSupportedProfileInfosForCodecModeInternal(CodecMode mode) {
281 std::vector<ProfileInfo> supported_profile_infos; 355 std::vector<ProfileInfo> supported_profile_infos;
282 std::vector<VAProfile> va_profiles; 356 std::vector<VAProfile> va_profiles;
283 if (!GetSupportedVaProfiles(&va_profiles)) 357 if (!GetSupportedVaProfiles(&va_profiles))
284 return supported_profile_infos; 358 return supported_profile_infos;
285 359
286 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode); 360 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode);
287 VAEntrypoint entrypoint = 361 VAEntrypoint entrypoint =
288 (mode == kEncode ? VAEntrypointEncSlice: VAEntrypointVLD); 362 (mode == kEncode ? VAEntrypointEncSlice: VAEntrypointVLD);
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 // This is safe to use Unretained() here, because the VDA takes care 660 // This is safe to use Unretained() here, because the VDA takes care
587 // of the destruction order. All the surfaces will be destroyed 661 // of the destruction order. All the surfaces will be destroyed
588 // before VaapiWrapper. 662 // before VaapiWrapper.
589 va_surface = new VASurface( 663 va_surface = new VASurface(
590 va_surface_id, size, va_format, 664 va_surface_id, size, va_format,
591 base::Bind(&VaapiWrapper::DestroyUnownedSurface, base::Unretained(this))); 665 base::Bind(&VaapiWrapper::DestroyUnownedSurface, base::Unretained(this)));
592 666
593 return va_surface; 667 return va_surface;
594 } 668 }
595 669
670 scoped_refptr<VASurface> VaapiWrapper::CreateVASurfaceForPixmap(
671 const scoped_refptr<ui::NativePixmap>& pixmap,
672 const gfx::Size& pixmap_size) {
673 // Get the dmabuf of the created buffer.
674 int dmabuf_fd = pixmap->GetDmaBufFd();
675 if (dmabuf_fd < 0) {
676 LOG(ERROR) << "Failed to get dmabuf from an Ozone NativePixmap";
677 return nullptr;
678 }
679 int dmabuf_pitch = pixmap->GetDmaBufPitch();
680
681 // Create a VASurface out of the created buffer using the dmabuf.
682 VASurfaceAttribExternalBuffers va_attrib_extbuf;
683 memset(&va_attrib_extbuf, 0, sizeof(va_attrib_extbuf));
684 va_attrib_extbuf.pixel_format =
685 BufferFormatToVAFourCC(pixmap->GetBufferFormat());
686 va_attrib_extbuf.width = pixmap_size.width();
687 va_attrib_extbuf.height = pixmap_size.height();
688 va_attrib_extbuf.data_size = pixmap_size.height() * dmabuf_pitch;
689 va_attrib_extbuf.num_planes = 1;
690 va_attrib_extbuf.pitches[0] = dmabuf_pitch;
691 va_attrib_extbuf.offsets[0] = 0;
692 va_attrib_extbuf.buffers = reinterpret_cast<unsigned long*>(&dmabuf_fd);
693 va_attrib_extbuf.num_buffers = 1;
694 va_attrib_extbuf.flags = 0;
695 va_attrib_extbuf.private_data = NULL;
696
697 std::vector<VASurfaceAttrib> va_attribs;
698 va_attribs.resize(2);
699
700 va_attribs[0].type = VASurfaceAttribMemoryType;
701 va_attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
702 va_attribs[0].value.type = VAGenericValueTypeInteger;
703 va_attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
704
705 va_attribs[1].type = VASurfaceAttribExternalBufferDescriptor;
706 va_attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
707 va_attribs[1].value.type = VAGenericValueTypePointer;
708 va_attribs[1].value.value.p = &va_attrib_extbuf;
709
710 scoped_refptr<VASurface> va_surface =
711 CreateUnownedSurface(BufferFormatToVARTFormat(pixmap->GetBufferFormat()),
712 pixmap_size, va_attribs);
713 if (!va_surface) {
714 LOG(ERROR) << "Failed to create VASurface for an Ozone NativePixmap";
715 return nullptr;
716 }
717
718 return va_surface;
719 }
720
596 void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface_id) { 721 void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface_id) {
597 base::AutoLock auto_lock(*va_lock_); 722 base::AutoLock auto_lock(*va_lock_);
598 723
599 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_id, 1); 724 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_id, 1);
600 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on surface failed"); 725 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on surface failed");
601 } 726 }
602 727
603 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, 728 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type,
604 size_t size, 729 size_t size,
605 void* buffer) { 730 void* buffer) {
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 #elif defined(USE_OZONE) 1189 #elif defined(USE_OZONE)
1065 paths[kModuleVa_drm].push_back("libva-drm.so.1"); 1190 paths[kModuleVa_drm].push_back("libva-drm.so.1");
1066 #endif 1191 #endif
1067 1192
1068 return InitializeStubs(paths); 1193 return InitializeStubs(paths);
1069 } 1194 }
1070 1195
1071 VaapiWrapper::LazyProfileInfos::LazyProfileInfos() { 1196 VaapiWrapper::LazyProfileInfos::LazyProfileInfos() {
1072 static_assert(arraysize(supported_profiles_) == kCodecModeMax, 1197 static_assert(arraysize(supported_profiles_) == kCodecModeMax,
1073 "The array size of supported profile is incorrect."); 1198 "The array size of supported profile is incorrect.");
1074 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); 1199 scoped_refptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
1075 if (!vaapi_wrapper->VaInitialize(base::Bind(&base::DoNothing))) 1200 if (!vaapi_wrapper->VaInitialize(base::Bind(&base::DoNothing)))
1076 return; 1201 return;
1077 for (size_t i = 0; i < kCodecModeMax; ++i) { 1202 for (size_t i = 0; i < kCodecModeMax; ++i) {
1078 supported_profiles_[i] = 1203 supported_profiles_[i] =
1079 vaapi_wrapper->GetSupportedProfileInfosForCodecModeInternal( 1204 vaapi_wrapper->GetSupportedProfileInfosForCodecModeInternal(
1080 static_cast<CodecMode>(i)); 1205 static_cast<CodecMode>(i));
1081 } 1206 }
1082 } 1207 }
1083 1208
1084 VaapiWrapper::LazyProfileInfos::~LazyProfileInfos() { 1209 VaapiWrapper::LazyProfileInfos::~LazyProfileInfos() {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 drm_fd_.reset(HANDLE_EINTR(dup(fd))); 1284 drm_fd_.reset(HANDLE_EINTR(dup(fd)));
1160 } 1285 }
1161 #endif // USE_OZONE 1286 #endif // USE_OZONE
1162 1287
1163 bool VaapiWrapper::VADisplayState::VAAPIVersionLessThan(int major, int minor) { 1288 bool VaapiWrapper::VADisplayState::VAAPIVersionLessThan(int major, int minor) {
1164 return (major_version_ < major) || 1289 return (major_version_ < major) ||
1165 (major_version_ == major && minor_version_ < minor); 1290 (major_version_ == major && minor_version_ < minor);
1166 } 1291 }
1167 1292
1168 } // namespace content 1293 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698