OLD | NEW |
---|---|
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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
140 | 141 |
141 VaapiWrapper::~VaapiWrapper() { | 142 VaapiWrapper::~VaapiWrapper() { |
142 DestroyPendingBuffers(); | 143 DestroyPendingBuffers(); |
143 DestroyCodedBuffers(); | 144 DestroyCodedBuffers(); |
144 DestroySurfaces(); | 145 DestroySurfaces(); |
145 DeinitializeVpp(); | 146 DeinitializeVpp(); |
146 Deinitialize(); | 147 Deinitialize(); |
147 } | 148 } |
148 | 149 |
149 // static | 150 // static |
150 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( | 151 scoped_refptr<VaapiWrapper> VaapiWrapper::Create( |
151 CodecMode mode, | 152 CodecMode mode, |
152 VAProfile va_profile, | 153 VAProfile va_profile, |
153 const base::Closure& report_error_to_uma_cb) { | 154 const base::Closure& report_error_to_uma_cb) { |
154 if (!profile_infos_.Get().IsProfileSupported(mode, va_profile)) { | 155 if (!profile_infos_.Get().IsProfileSupported(mode, va_profile)) { |
155 DVLOG(1) << "Unsupported va_profile: " << va_profile; | 156 DVLOG(1) << "Unsupported va_profile: " << va_profile; |
156 return nullptr; | 157 return nullptr; |
157 } | 158 } |
158 | 159 |
159 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); | 160 scoped_refptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); |
160 if (vaapi_wrapper->VaInitialize(report_error_to_uma_cb)) { | 161 if (vaapi_wrapper->VaInitialize(report_error_to_uma_cb)) { |
161 if (vaapi_wrapper->Initialize(mode, va_profile)) | 162 if (vaapi_wrapper->Initialize(mode, va_profile)) |
162 return vaapi_wrapper.Pass(); | 163 return vaapi_wrapper.Pass(); |
Pawel Osciak
2015/11/20 10:09:18
Pass() should not be needed, here and below.
william.xie1
2015/11/23 03:33:58
Done.
| |
163 } | 164 } |
164 LOG(ERROR) << "Failed to create VaapiWrapper for va_profile: " << va_profile; | 165 LOG(ERROR) << "Failed to create VaapiWrapper for va_profile: " << va_profile; |
165 return nullptr; | 166 return nullptr; |
166 } | 167 } |
167 | 168 |
168 // static | 169 // static |
169 scoped_ptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec( | 170 scoped_refptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec( |
170 CodecMode mode, | 171 CodecMode mode, |
171 media::VideoCodecProfile profile, | 172 media::VideoCodecProfile profile, |
172 const base::Closure& report_error_to_uma_cb) { | 173 const base::Closure& report_error_to_uma_cb) { |
173 VAProfile va_profile = ProfileToVAProfile(profile, mode); | 174 VAProfile va_profile = ProfileToVAProfile(profile, mode); |
174 scoped_ptr<VaapiWrapper> vaapi_wrapper = | 175 scoped_refptr<VaapiWrapper> vaapi_wrapper = |
175 Create(mode, va_profile, report_error_to_uma_cb); | 176 Create(mode, va_profile, report_error_to_uma_cb); |
176 return vaapi_wrapper.Pass(); | 177 return vaapi_wrapper.Pass(); |
177 } | 178 } |
178 | 179 |
179 // static | 180 // static |
180 media::VideoEncodeAccelerator::SupportedProfiles | 181 media::VideoEncodeAccelerator::SupportedProfiles |
181 VaapiWrapper::GetSupportedEncodeProfiles() { | 182 VaapiWrapper::GetSupportedEncodeProfiles() { |
182 media::VideoEncodeAccelerator::SupportedProfiles profiles; | 183 media::VideoEncodeAccelerator::SupportedProfiles profiles; |
183 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); | 184 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
184 if (cmd_line->HasSwitch(switches::kDisableVaapiAcceleratedVideoEncode)) | 185 if (cmd_line->HasSwitch(switches::kDisableVaapiAcceleratedVideoEncode)) |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
269 // (which in practice is true for a great majority of cases). | 270 // (which in practice is true for a great majority of cases). |
270 if (profile_infos_.Get().IsProfileSupported( | 271 if (profile_infos_.Get().IsProfileSupported( |
271 mode, VAProfileH264ConstrainedBaseline)) { | 272 mode, VAProfileH264ConstrainedBaseline)) { |
272 va_profile = VAProfileH264ConstrainedBaseline; | 273 va_profile = VAProfileH264ConstrainedBaseline; |
273 DVLOG(1) << "Fall back to constrained baseline profile."; | 274 DVLOG(1) << "Fall back to constrained baseline profile."; |
274 } | 275 } |
275 } | 276 } |
276 return va_profile; | 277 return va_profile; |
277 } | 278 } |
278 | 279 |
280 // static | |
281 uint32_t VaapiWrapper::BufferFormatToVAFourCC(gfx::BufferFormat fmt) { | |
282 switch (fmt) { | |
283 case gfx::BufferFormat::BGRX_8888: | |
284 return VA_FOURCC_BGRX; | |
285 case gfx::BufferFormat::UYVY_422: | |
286 return VA_FOURCC_UYVY; | |
287 default: | |
288 NOTREACHED(); | |
289 return 0; | |
290 } | |
291 } | |
292 | |
293 // static | |
294 uint32_t VaapiWrapper::BufferFormatToVARTFormat(gfx::BufferFormat fmt) { | |
295 switch (fmt) { | |
296 case gfx::BufferFormat::UYVY_422: | |
297 return VA_RT_FORMAT_YUV422; | |
298 case gfx::BufferFormat::BGRX_8888: | |
299 return VA_RT_FORMAT_RGB32; | |
300 default: | |
301 NOTREACHED(); | |
302 return 0; | |
303 } | |
304 } | |
305 | |
279 std::vector<VaapiWrapper::ProfileInfo> | 306 std::vector<VaapiWrapper::ProfileInfo> |
280 VaapiWrapper::GetSupportedProfileInfosForCodecModeInternal(CodecMode mode) { | 307 VaapiWrapper::GetSupportedProfileInfosForCodecModeInternal(CodecMode mode) { |
281 std::vector<ProfileInfo> supported_profile_infos; | 308 std::vector<ProfileInfo> supported_profile_infos; |
282 std::vector<VAProfile> va_profiles; | 309 std::vector<VAProfile> va_profiles; |
283 if (!GetSupportedVaProfiles(&va_profiles)) | 310 if (!GetSupportedVaProfiles(&va_profiles)) |
284 return supported_profile_infos; | 311 return supported_profile_infos; |
285 | 312 |
286 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode); | 313 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode); |
287 VAEntrypoint entrypoint = | 314 VAEntrypoint entrypoint = |
288 (mode == kEncode ? VAEntrypointEncSlice: VAEntrypointVLD); | 315 (mode == kEncode ? VAEntrypointEncSlice: VAEntrypointVLD); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
586 // This is safe to use Unretained() here, because the VDA takes care | 613 // This is safe to use Unretained() here, because the VDA takes care |
587 // of the destruction order. All the surfaces will be destroyed | 614 // of the destruction order. All the surfaces will be destroyed |
588 // before VaapiWrapper. | 615 // before VaapiWrapper. |
589 va_surface = new VASurface( | 616 va_surface = new VASurface( |
590 va_surface_id, size, va_format, | 617 va_surface_id, size, va_format, |
591 base::Bind(&VaapiWrapper::DestroyUnownedSurface, base::Unretained(this))); | 618 base::Bind(&VaapiWrapper::DestroyUnownedSurface, base::Unretained(this))); |
592 | 619 |
593 return va_surface; | 620 return va_surface; |
594 } | 621 } |
595 | 622 |
623 scoped_refptr<VASurface> VaapiWrapper::CreateVASurfaceForPixmap( | |
624 scoped_refptr<ui::NativePixmap> pixmap, | |
625 gfx::Size pixmap_size) { | |
626 // Get the dmabuf of the created buffer. | |
627 int dmabuf_fd = pixmap->GetDmaBufFd(); | |
628 if (dmabuf_fd < 0) { | |
629 LOG(ERROR) << "Failed to get dmabuf from an Ozone NativePixmap"; | |
630 return nullptr; | |
631 } | |
632 int dmabuf_pitch = pixmap->GetDmaBufPitch(); | |
633 | |
634 // Create a VASurface out of the created buffer using the dmabuf. | |
635 VASurfaceAttribExternalBuffers va_attrib_extbuf; | |
636 memset(&va_attrib_extbuf, 0, sizeof(va_attrib_extbuf)); | |
637 va_attrib_extbuf.pixel_format = | |
638 BufferFormatToVAFourCC(pixmap->GetBufferFormat()); | |
639 va_attrib_extbuf.width = pixmap_size.width(); | |
640 va_attrib_extbuf.height = pixmap_size.height(); | |
641 va_attrib_extbuf.data_size = pixmap_size.height() * dmabuf_pitch; | |
642 va_attrib_extbuf.num_planes = 1; | |
643 va_attrib_extbuf.pitches[0] = dmabuf_pitch; | |
644 va_attrib_extbuf.offsets[0] = 0; | |
645 va_attrib_extbuf.buffers = reinterpret_cast<unsigned long*>(&dmabuf_fd); | |
646 va_attrib_extbuf.num_buffers = 1; | |
647 va_attrib_extbuf.flags = 0; | |
648 va_attrib_extbuf.private_data = NULL; | |
649 | |
650 std::vector<VASurfaceAttrib> va_attribs; | |
651 va_attribs.resize(2); | |
652 | |
653 va_attribs[0].type = VASurfaceAttribMemoryType; | |
654 va_attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE; | |
655 va_attribs[0].value.type = VAGenericValueTypeInteger; | |
656 va_attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; | |
657 | |
658 va_attribs[1].type = VASurfaceAttribExternalBufferDescriptor; | |
659 va_attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE; | |
660 va_attribs[1].value.type = VAGenericValueTypePointer; | |
661 va_attribs[1].value.value.p = &va_attrib_extbuf; | |
662 | |
663 scoped_refptr<VASurface> va_surface = | |
664 CreateUnownedSurface(BufferFormatToVARTFormat(pixmap->GetBufferFormat()), | |
665 pixmap_size, va_attribs); | |
666 if (!va_surface) { | |
667 LOG(ERROR) << "Failed to create VASurface for an Ozone NativePixmap"; | |
668 return nullptr; | |
669 } | |
670 | |
671 return va_surface; | |
672 } | |
673 | |
596 void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface_id) { | 674 void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface_id) { |
597 base::AutoLock auto_lock(*va_lock_); | 675 base::AutoLock auto_lock(*va_lock_); |
598 | 676 |
599 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_id, 1); | 677 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_id, 1); |
600 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on surface failed"); | 678 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on surface failed"); |
601 } | 679 } |
602 | 680 |
603 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, | 681 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, |
604 size_t size, | 682 size_t size, |
605 void* buffer) { | 683 void* buffer) { |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1064 #elif defined(USE_OZONE) | 1142 #elif defined(USE_OZONE) |
1065 paths[kModuleVa_drm].push_back("libva-drm.so.1"); | 1143 paths[kModuleVa_drm].push_back("libva-drm.so.1"); |
1066 #endif | 1144 #endif |
1067 | 1145 |
1068 return InitializeStubs(paths); | 1146 return InitializeStubs(paths); |
1069 } | 1147 } |
1070 | 1148 |
1071 VaapiWrapper::LazyProfileInfos::LazyProfileInfos() { | 1149 VaapiWrapper::LazyProfileInfos::LazyProfileInfos() { |
1072 static_assert(arraysize(supported_profiles_) == kCodecModeMax, | 1150 static_assert(arraysize(supported_profiles_) == kCodecModeMax, |
1073 "The array size of supported profile is incorrect."); | 1151 "The array size of supported profile is incorrect."); |
1074 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); | 1152 scoped_refptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); |
1075 if (!vaapi_wrapper->VaInitialize(base::Bind(&base::DoNothing))) | 1153 if (!vaapi_wrapper->VaInitialize(base::Bind(&base::DoNothing))) |
1076 return; | 1154 return; |
1077 for (size_t i = 0; i < kCodecModeMax; ++i) { | 1155 for (size_t i = 0; i < kCodecModeMax; ++i) { |
1078 supported_profiles_[i] = | 1156 supported_profiles_[i] = |
1079 vaapi_wrapper->GetSupportedProfileInfosForCodecModeInternal( | 1157 vaapi_wrapper->GetSupportedProfileInfosForCodecModeInternal( |
1080 static_cast<CodecMode>(i)); | 1158 static_cast<CodecMode>(i)); |
1081 } | 1159 } |
1082 } | 1160 } |
1083 | 1161 |
1084 VaapiWrapper::LazyProfileInfos::~LazyProfileInfos() { | 1162 VaapiWrapper::LazyProfileInfos::~LazyProfileInfos() { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1159 drm_fd_.reset(HANDLE_EINTR(dup(fd))); | 1237 drm_fd_.reset(HANDLE_EINTR(dup(fd))); |
1160 } | 1238 } |
1161 #endif // USE_OZONE | 1239 #endif // USE_OZONE |
1162 | 1240 |
1163 bool VaapiWrapper::VADisplayState::VAAPIVersionLessThan(int major, int minor) { | 1241 bool VaapiWrapper::VADisplayState::VAAPIVersionLessThan(int major, int minor) { |
1164 return (major_version_ < major) || | 1242 return (major_version_ < major) || |
1165 (major_version_ == major && minor_version_ < minor); | 1243 (major_version_ == major && minor_version_ < minor); |
1166 } | 1244 } |
1167 | 1245 |
1168 } // namespace content | 1246 } // namespace content |
OLD | NEW |