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

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

Issue 872623002: VaapiVEA: Get maximum resolution from libva (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address all review comments Created 5 years, 9 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 unified diff | Download patch
« no previous file with comments | « content/common/gpu/media/vaapi_wrapper.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/logging.h" 12 #include "base/logging.h"
12 #include "base/numerics/safe_conversions.h" 13 #include "base/numerics/safe_conversions.h"
13 #include "base/sys_info.h" 14 #include "base/sys_info.h"
14 // Auto-generated for dlopen libva libraries 15 // Auto-generated for dlopen libva libraries
15 #include "content/common/gpu/media/va_stubs.h" 16 #include "content/common/gpu/media/va_stubs.h"
16 #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"
17 #include "third_party/libyuv/include/libyuv.h" 19 #include "third_party/libyuv/include/libyuv.h"
18 #include "ui/gl/gl_bindings.h" 20 #include "ui/gl/gl_bindings.h"
19 #if defined(USE_X11) 21 #if defined(USE_X11)
20 #include "ui/gfx/x/x11_types.h" 22 #include "ui/gfx/x/x11_types.h"
21 #elif defined(USE_OZONE) 23 #elif defined(USE_OZONE)
22 #include "third_party/libva/va/drm/va_drm.h" 24 #include "third_party/libva/va/drm/va_drm.h"
23 #include "ui/ozone/public/ozone_platform.h" 25 #include "ui/ozone/public/ozone_platform.h"
24 #include "ui/ozone/public/surface_factory_ozone.h" 26 #include "ui/ozone/public/surface_factory_ozone.h"
25 #endif // USE_X11 27 #endif // USE_X11
26 28
(...skipping 22 matching lines...) Expand all
49 #define VA_SUCCESS_OR_RETURN(va_error, err_msg, ret) \ 51 #define VA_SUCCESS_OR_RETURN(va_error, err_msg, ret) \
50 do { \ 52 do { \
51 if ((va_error) != VA_STATUS_SUCCESS) { \ 53 if ((va_error) != VA_STATUS_SUCCESS) { \
52 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ 54 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \
53 return (ret); \ 55 return (ret); \
54 } \ 56 } \
55 } while (0) 57 } while (0)
56 58
57 namespace content { 59 namespace content {
58 60
61 // Maximum framerate of encoded profile. This value is an arbitary limit
62 // and not taken from HW documentation.
63 const int kMaxEncoderFramerate = 30;
64
65 base::LazyInstance<VaapiWrapper::LazyProfileInfos>
66 VaapiWrapper::profile_infos_ = LAZY_INSTANCE_INITIALIZER;
67
59 // Config attributes common for both encode and decode. 68 // Config attributes common for both encode and decode.
60 static const VAConfigAttrib kCommonVAConfigAttribs[] = { 69 static const VAConfigAttrib kCommonVAConfigAttribs[] = {
61 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420}, 70 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420},
62 }; 71 };
63 72
64 // Attributes required for encode. 73 // Attributes required for encode.
65 static const VAConfigAttrib kEncodeVAConfigAttribs[] = { 74 static const VAConfigAttrib kEncodeVAConfigAttribs[] = {
66 {VAConfigAttribRateControl, VA_RC_CBR}, 75 {VAConfigAttribRateControl, VA_RC_CBR},
67 {VAConfigAttribEncPackedHeaders, 76 {VAConfigAttribEncPackedHeaders,
68 VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE}, 77 VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE},
(...skipping 22 matching lines...) Expand all
91 kCommonVAConfigAttribs + arraysize(kCommonVAConfigAttribs)); 100 kCommonVAConfigAttribs + arraysize(kCommonVAConfigAttribs));
92 if (mode == VaapiWrapper::kEncode) { 101 if (mode == VaapiWrapper::kEncode) {
93 required_attribs.insert( 102 required_attribs.insert(
94 required_attribs.end(), 103 required_attribs.end(),
95 kEncodeVAConfigAttribs, 104 kEncodeVAConfigAttribs,
96 kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs)); 105 kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs));
97 } 106 }
98 return required_attribs; 107 return required_attribs;
99 } 108 }
100 109
101 // Maps Profile enum values to VaProfile values.
102 static VAProfile ProfileToVAProfile(
103 media::VideoCodecProfile profile,
104 const std::vector<VAProfile>& supported_profiles) {
105
106 VAProfile va_profile = VAProfileNone;
107 for (size_t i = 0; i < arraysize(kProfileMap); i++) {
108 if (kProfileMap[i].profile == profile) {
109 va_profile = kProfileMap[i].va_profile;
110 break;
111 }
112 }
113
114 bool supported = std::find(supported_profiles.begin(),
115 supported_profiles.end(),
116 va_profile) != supported_profiles.end();
117
118 if (!supported && va_profile == VAProfileH264Baseline) {
119 // crbug.com/345569: media::ProfileIDToVideoCodecProfile() currently strips
120 // the information whether the profile is constrained or not, so we have no
121 // way to know here. Try for baseline first, but if it is not supported,
122 // try constrained baseline and hope this is what it actually is
123 // (which in practice is true for a great majority of cases).
124 if (std::find(supported_profiles.begin(),
125 supported_profiles.end(),
126 VAProfileH264ConstrainedBaseline) !=
127 supported_profiles.end()) {
128 va_profile = VAProfileH264ConstrainedBaseline;
129 DVLOG(1) << "Falling back to constrained baseline profile.";
130 }
131 }
132
133 return va_profile;
134 }
135
136 VASurface::VASurface(VASurfaceID va_surface_id, 110 VASurface::VASurface(VASurfaceID va_surface_id,
137 const gfx::Size& size, 111 const gfx::Size& size,
138 const ReleaseCB& release_cb) 112 const ReleaseCB& release_cb)
139 : va_surface_id_(va_surface_id), size_(size), release_cb_(release_cb) { 113 : va_surface_id_(va_surface_id), size_(size), release_cb_(release_cb) {
140 DCHECK(!release_cb_.is_null()); 114 DCHECK(!release_cb_.is_null());
141 } 115 }
142 116
143 VASurface::~VASurface() { 117 VASurface::~VASurface() {
144 release_cb_.Run(va_surface_id_); 118 release_cb_.Run(va_surface_id_);
145 } 119 }
146 120
147 VaapiWrapper::VaapiWrapper() 121 VaapiWrapper::VaapiWrapper()
148 : va_display_(NULL), 122 : va_display_(NULL),
149 va_config_id_(VA_INVALID_ID), 123 va_config_id_(VA_INVALID_ID),
150 va_context_id_(VA_INVALID_ID), 124 va_context_id_(VA_INVALID_ID),
151 va_initialized_(false), 125 va_initialized_(false),
152 va_vpp_config_id_(VA_INVALID_ID), 126 va_vpp_config_id_(VA_INVALID_ID),
153 va_vpp_context_id_(VA_INVALID_ID), 127 va_vpp_context_id_(VA_INVALID_ID),
154 va_vpp_buffer_id_(VA_INVALID_ID) { 128 va_vpp_buffer_id_(VA_INVALID_ID) {
155 } 129 }
156 130
157 VaapiWrapper::~VaapiWrapper() { 131 VaapiWrapper::~VaapiWrapper() {
158 DestroyPendingBuffers(); 132 DestroyPendingBuffers();
159 DestroyCodedBuffers(); 133 DestroyCodedBuffers();
160 DestroySurfaces(); 134 DestroySurfaces();
161 DeinitializeVpp(); 135 DeinitializeVpp();
162 Deinitialize(); 136 Deinitialize();
163 } 137 }
164 138
139 // static
165 scoped_ptr<VaapiWrapper> VaapiWrapper::Create( 140 scoped_ptr<VaapiWrapper> VaapiWrapper::Create(
166 CodecMode mode, 141 CodecMode mode,
167 VAProfile va_profile, 142 VAProfile va_profile,
168 const base::Closure& report_error_to_uma_cb) { 143 const base::Closure& report_error_to_uma_cb) {
169 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); 144 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
170 145
171 if (!vaapi_wrapper->VaInitialize(report_error_to_uma_cb)) 146 if (!vaapi_wrapper->VaInitialize(report_error_to_uma_cb))
172 return nullptr; 147 return nullptr;
148
173 if (!vaapi_wrapper->Initialize(mode, va_profile)) 149 if (!vaapi_wrapper->Initialize(mode, va_profile))
174 return nullptr; 150 return nullptr;
175 151
176 return vaapi_wrapper.Pass(); 152 return vaapi_wrapper.Pass();
177 } 153 }
178 154
155 // static
179 scoped_ptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec( 156 scoped_ptr<VaapiWrapper> VaapiWrapper::CreateForVideoCodec(
180 CodecMode mode, 157 CodecMode mode,
181 media::VideoCodecProfile profile, 158 media::VideoCodecProfile profile,
182 const base::Closure& report_error_to_uma_cb) { 159 const base::Closure& report_error_to_uma_cb) {
183 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); 160 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
184 161
185 if (!vaapi_wrapper->VaInitialize(report_error_to_uma_cb)) 162 if (!vaapi_wrapper->VaInitialize(report_error_to_uma_cb))
186 return nullptr; 163 return nullptr;
187 164
188 std::vector<VAProfile> supported_va_profiles; 165 VAProfile va_profile = ProfileToVAProfile(profile, mode);
189 if (!vaapi_wrapper->GetSupportedVaProfiles(&supported_va_profiles))
190 return nullptr;
191
192 VAProfile va_profile = ProfileToVAProfile(profile, supported_va_profiles);
193 if (!vaapi_wrapper->Initialize(mode, va_profile)) 166 if (!vaapi_wrapper->Initialize(mode, va_profile))
194 return nullptr; 167 return nullptr;
195 168
196 return vaapi_wrapper.Pass(); 169 return vaapi_wrapper.Pass();
197 } 170 }
198 171
199 std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles( 172 // static
200 const base::Closure& report_error_to_uma_cb) { 173 std::vector<media::VideoEncodeAccelerator::SupportedProfile>
201 std::vector<media::VideoCodecProfile> supported_profiles; 174 VaapiWrapper::GetSupportedEncodeProfiles() {
175 std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles;
176 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
177 if (cmd_line->HasSwitch(switches::kDisableVaapiAcceleratedVideoEncode))
178 return profiles;
202 179
203 scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper()); 180 std::vector<ProfileInfo> encode_profile_infos =
204 if (!wrapper->VaInitialize(report_error_to_uma_cb)) { 181 profile_infos_.Get().GetSupportedProfileInfosForCodecMode(kEncode);
205 return supported_profiles;
206 }
207 182
208 std::vector<VAProfile> va_profiles; 183 for (size_t i = 0; i < arraysize(kProfileMap); ++i) {
209 if (!wrapper->GetSupportedVaProfiles(&va_profiles)) 184 VAProfile va_profile = ProfileToVAProfile(kProfileMap[i].profile, kEncode);
210 return supported_profiles; 185 if (va_profile == VAProfileNone)
211 186 continue;
212 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode); 187 for (const auto& profile_info : encode_profile_infos) {
213 for (size_t i = 0; i < arraysize(kProfileMap); i++) { 188 if (profile_info.va_profile == va_profile) {
214 VAProfile va_profile = 189 media::VideoEncodeAccelerator::SupportedProfile profile;
215 ProfileToVAProfile(kProfileMap[i].profile, va_profiles); 190 profile.profile = kProfileMap[i].profile;
216 if (va_profile != VAProfileNone && 191 profile.max_resolution = profile_info.max_resolution;
217 wrapper->IsEntrypointSupported(va_profile, VAEntrypointEncSlice) && 192 profile.max_framerate_numerator = kMaxEncoderFramerate;
218 wrapper->AreAttribsSupported( 193 profile.max_framerate_denominator = 1;
219 va_profile, VAEntrypointEncSlice, required_attribs)) { 194 profiles.push_back(profile);
220 supported_profiles.push_back(kProfileMap[i].profile); 195 break;
196 }
221 } 197 }
222 } 198 }
223 return supported_profiles; 199 return profiles;
200 }
201
202 // static
203 std::vector<VaapiWrapper::ProfileInfo>
204 VaapiWrapper::GetSupportedProfileInfosForCodecMode(CodecMode mode) {
205 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
206 if (!vaapi_wrapper->VaInitialize(base::Bind(&base::DoNothing)))
207 return std::vector<ProfileInfo>();
208 return vaapi_wrapper->GetSupportedProfileInfosForCodecModeInternal(mode);
224 } 209 }
225 210
226 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { 211 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
227 base::AutoLock auto_lock(va_lock_); 212 base::AutoLock auto_lock(va_lock_);
228 VADisplayAttribute item = {VADisplayAttribRenderMode, 213 VADisplayAttribute item = {VADisplayAttribRenderMode,
229 1, // At least support '_LOCAL_OVERLAY'. 214 1, // At least support '_LOCAL_OVERLAY'.
230 -1, // The maximum possible support 'ALL'. 215 -1, // The maximum possible support 'ALL'.
231 VA_RENDER_MODE_LOCAL_GPU, 216 VA_RENDER_MODE_LOCAL_GPU,
232 VA_DISPLAY_ATTRIB_SETTABLE}; 217 VA_DISPLAY_ATTRIB_SETTABLE};
233 218
234 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); 219 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1);
235 if (va_res != VA_STATUS_SUCCESS) 220 if (va_res != VA_STATUS_SUCCESS)
236 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; 221 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default.";
237 } 222 }
238 223
224 // static
225 VAProfile VaapiWrapper::ProfileToVAProfile(
226 media::VideoCodecProfile profile, CodecMode mode) {
227 VAProfile va_profile = VAProfileNone;
228 for (size_t i = 0; i < arraysize(kProfileMap); ++i) {
229 if (kProfileMap[i].profile == profile) {
230 va_profile = kProfileMap[i].va_profile;
231 break;
232 }
233 }
234 if (!profile_infos_.Get().IsProfileSupported(mode, va_profile) &&
235 va_profile == VAProfileH264Baseline) {
236 // crbug.com/345569: media::ProfileIDToVideoCodecProfile() currently strips
237 // the information whether the profile is constrained or not, so we have no
238 // way to know here. Try for baseline first, but if it is not supported,
239 // try constrained baseline and hope this is what it actually is
240 // (which in practice is true for a great majority of cases).
241 if (profile_infos_.Get().IsProfileSupported(
242 mode, VAProfileH264ConstrainedBaseline)) {
243 va_profile = VAProfileH264ConstrainedBaseline;
244 DVLOG(1) << "Fall back to constrained baseline profile.";
245 }
246 }
247 return va_profile;
248 }
249
250 std::vector<VaapiWrapper::ProfileInfo>
251 VaapiWrapper::GetSupportedProfileInfosForCodecModeInternal(CodecMode mode) {
252 std::vector<ProfileInfo> supported_profile_infos;
253 std::vector<VAProfile> va_profiles;
254 if (!GetSupportedVaProfiles(&va_profiles))
255 return supported_profile_infos;
256
257 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode);
258 VAEntrypoint entrypoint =
259 (mode == kEncode ? VAEntrypointEncSlice: VAEntrypointVLD);
260
261 base::AutoLock auto_lock(va_lock_);
262 for (const auto& va_profile : va_profiles) {
263 if (!IsEntrypointSupported_Locked(va_profile, entrypoint))
264 continue;
265 if (!AreAttribsSupported_Locked(va_profile, entrypoint, required_attribs))
266 continue;
267 VAConfigID config_id;
268 VAStatus va_res = vaCreateConfig(
wuchengli 2015/03/09 05:17:30 Pawel and I discussed. vaCreateConfig should be mo
henryhsu 2015/03/09 09:21:53 Done.
269 va_display_,
270 va_profile,
271 entrypoint,
272 &required_attribs[0],
273 required_attribs.size(),
274 &config_id);
275 if (va_res != VA_STATUS_SUCCESS) {
276 LOG_VA_ERROR_AND_REPORT(va_res, "vaCreateConfig failed");
277 continue;
278 }
279 ProfileInfo profile_info;
280 if (!GetMaxResolutionForVAConfigID(
281 config_id, &profile_info.max_resolution)) {
282 LOG(ERROR) << "GetMaxResolution failed by va_profile " << va_profile;
283 continue;
284 }
285 profile_info.va_profile = va_profile;
286 supported_profile_infos.push_back(profile_info);
287 }
288 return supported_profile_infos;
289 }
290
239 bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) { 291 bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) {
240 static bool vaapi_functions_initialized = PostSandboxInitialization(); 292 static bool vaapi_functions_initialized = PostSandboxInitialization();
241 if (!vaapi_functions_initialized) { 293 if (!vaapi_functions_initialized) {
242 bool running_on_chromeos = false; 294 bool running_on_chromeos = false;
243 #if defined(OS_CHROMEOS) 295 #if defined(OS_CHROMEOS)
244 // When chrome runs on linux with chromeos=1, do not log error message 296 // When chrome runs on linux with chromeos=1, do not log error message
245 // without VAAPI libraries. 297 // without VAAPI libraries.
246 running_on_chromeos = base::SysInfo::IsRunningOnChromeOS(); 298 running_on_chromeos = base::SysInfo::IsRunningOnChromeOS();
247 #endif 299 #endif
248 static const char kErrorMsg[] = "Failed to initialize VAAPI libs"; 300 static const char kErrorMsg[] = "Failed to initialize VAAPI libs";
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { 349 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) {
298 LOG(ERROR) << "vaQueryConfigProfiles returned: " << num_supported_profiles; 350 LOG(ERROR) << "vaQueryConfigProfiles returned: " << num_supported_profiles;
299 return false; 351 return false;
300 } 352 }
301 353
302 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); 354 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles));
303 *profiles = supported_profiles; 355 *profiles = supported_profiles;
304 return true; 356 return true;
305 } 357 }
306 358
307 bool VaapiWrapper::IsEntrypointSupported(VAProfile va_profile, 359 bool VaapiWrapper::IsEntrypointSupported_Locked(VAProfile va_profile,
308 VAEntrypoint entrypoint) { 360 VAEntrypoint entrypoint) {
309 base::AutoLock auto_lock(va_lock_); 361 va_lock_.AssertAcquired();
310 // Query the driver for supported entrypoints. 362 // Query the driver for supported entrypoints.
311 int max_entrypoints = vaMaxNumEntrypoints(va_display_); 363 int max_entrypoints = vaMaxNumEntrypoints(va_display_);
312 std::vector<VAEntrypoint> supported_entrypoints( 364 std::vector<VAEntrypoint> supported_entrypoints(
313 base::checked_cast<size_t>(max_entrypoints)); 365 base::checked_cast<size_t>(max_entrypoints));
314 366
315 int num_supported_entrypoints; 367 int num_supported_entrypoints;
316 VAStatus va_res = vaQueryConfigEntrypoints(va_display_, 368 VAStatus va_res = vaQueryConfigEntrypoints(va_display_,
317 va_profile, 369 va_profile,
318 &supported_entrypoints[0], 370 &supported_entrypoints[0],
319 &num_supported_entrypoints); 371 &num_supported_entrypoints);
320 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false); 372 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false);
321 if (num_supported_entrypoints < 0 || 373 if (num_supported_entrypoints < 0 ||
322 num_supported_entrypoints > max_entrypoints) { 374 num_supported_entrypoints > max_entrypoints) {
323 LOG(ERROR) << "vaQueryConfigEntrypoints returned: " 375 LOG(ERROR) << "vaQueryConfigEntrypoints returned: "
324 << num_supported_entrypoints; 376 << num_supported_entrypoints;
325 return false; 377 return false;
326 } 378 }
327 379
328 if (std::find(supported_entrypoints.begin(), 380 if (std::find(supported_entrypoints.begin(),
329 supported_entrypoints.end(), 381 supported_entrypoints.end(),
330 entrypoint) == supported_entrypoints.end()) { 382 entrypoint) == supported_entrypoints.end()) {
331 DVLOG(1) << "Unsupported entrypoint"; 383 DVLOG(1) << "Unsupported entrypoint";
332 return false; 384 return false;
333 } 385 }
334 return true; 386 return true;
335 } 387 }
336 388
337 bool VaapiWrapper::AreAttribsSupported( 389 bool VaapiWrapper::AreAttribsSupported_Locked(
338 VAProfile va_profile, 390 VAProfile va_profile,
339 VAEntrypoint entrypoint, 391 VAEntrypoint entrypoint,
340 const std::vector<VAConfigAttrib>& required_attribs) { 392 const std::vector<VAConfigAttrib>& required_attribs) {
341 base::AutoLock auto_lock(va_lock_); 393 va_lock_.AssertAcquired();
342 // Query the driver for required attributes. 394 // Query the driver for required attributes.
343 std::vector<VAConfigAttrib> attribs = required_attribs; 395 std::vector<VAConfigAttrib> attribs = required_attribs;
344 for (size_t i = 0; i < required_attribs.size(); ++i) 396 for (size_t i = 0; i < required_attribs.size(); ++i)
345 attribs[i].value = 0; 397 attribs[i].value = 0;
346 398
347 VAStatus va_res = vaGetConfigAttributes( 399 VAStatus va_res = vaGetConfigAttributes(
348 va_display_, va_profile, entrypoint, &attribs[0], attribs.size()); 400 va_display_, va_profile, entrypoint, &attribs[0], attribs.size());
349 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false); 401 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false);
350 402
351 for (size_t i = 0; i < required_attribs.size(); ++i) { 403 for (size_t i = 0; i < required_attribs.size(); ++i) {
352 if (attribs[i].type != required_attribs[i].type || 404 if (attribs[i].type != required_attribs[i].type ||
353 (attribs[i].value & required_attribs[i].value) != 405 (attribs[i].value & required_attribs[i].value) !=
354 required_attribs[i].value) { 406 required_attribs[i].value) {
355 DVLOG(1) << "Unsupported value " << required_attribs[i].value 407 DVLOG(1) << "Unsupported value " << required_attribs[i].value
356 << " for attribute type " << required_attribs[i].type; 408 << " for attribute type " << required_attribs[i].type;
357 return false; 409 return false;
358 } 410 }
359 } 411 }
360 return true; 412 return true;
361 } 413 }
362 414
415 bool VaapiWrapper::GetMaxResolutionForVAConfigID(VAConfigID va_config_id,
416 gfx::Size* resolution) {
417 va_lock_.AssertAcquired();
418 unsigned int num_attribs;
419
420 // Calls vaQuerySurfaceAttributes twice. The first time is to get the number
421 // of attributes to prepare the space and the second time is to get all
422 // attributes.
423 VAStatus va_res;
424 va_res = vaQuerySurfaceAttributes(
425 va_display_, va_config_id, nullptr, &num_attribs);
426 VA_SUCCESS_OR_RETURN(va_res, "vaQuerySurfaceAttributes failed", false);
427 if (!num_attribs)
428 return false;
429
430 std::vector<VASurfaceAttrib> attrib_list(
431 base::checked_cast<size_t>(num_attribs));
432
433 va_res = vaQuerySurfaceAttributes(
434 va_display_, va_config_id, &attrib_list[0], &num_attribs);
435 VA_SUCCESS_OR_RETURN(va_res, "vaQuerySurfaceAttributes failed", false);
436
437 resolution->SetSize(0, 0);
438 for (const auto& attrib : attrib_list) {
439 if (attrib.type == VASurfaceAttribMaxWidth)
440 resolution->set_width(attrib.value.value.i);
441 else if (attrib.type == VASurfaceAttribMaxHeight)
442 resolution->set_height(attrib.value.value.i);
443 }
444 if (resolution->IsEmpty()) {
445 LOG(ERROR) << "Codec resolution " << resolution->ToString()
446 << " cannot be zero.";
447 return false;
448 }
449 return true;
450 }
451
363 bool VaapiWrapper::Initialize(CodecMode mode, VAProfile va_profile) { 452 bool VaapiWrapper::Initialize(CodecMode mode, VAProfile va_profile) {
364 if (va_profile == VAProfileNone) { 453 if (!profile_infos_.Get().IsProfileSupported(mode, va_profile)) {
365 DVLOG(1) << "Unsupported profile"; 454 DVLOG(1) << "Unsupported va profile: " << va_profile;
366 return false; 455 return false;
367 } 456 }
368 VAEntrypoint entrypoint =
369 (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD);
370 if (!IsEntrypointSupported(va_profile, entrypoint))
371 return false;
372 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode);
373 if (!AreAttribsSupported(va_profile, entrypoint, required_attribs))
374 return false;
375 457
376 TryToSetVADisplayAttributeToLocalGPU(); 458 TryToSetVADisplayAttributeToLocalGPU();
377 459
460 VAEntrypoint entrypoint =
461 (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD);
462 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode);
378 base::AutoLock auto_lock(va_lock_); 463 base::AutoLock auto_lock(va_lock_);
379 VAStatus va_res = vaCreateConfig(va_display_, 464 VAStatus va_res = vaCreateConfig(va_display_,
380 va_profile, 465 va_profile,
381 entrypoint, 466 entrypoint,
382 &required_attribs[0], 467 &required_attribs[0],
383 required_attribs.size(), 468 required_attribs.size(),
384 &va_config_id_); 469 &va_config_id_);
385 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false); 470 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false);
386 471
387 return true; 472 return true;
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 va_res = vaUnmapBuffer(va_display_, buffer_id); 651 va_res = vaUnmapBuffer(va_display_, buffer_id);
567 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed"); 652 VA_LOG_ON_ERROR(va_res, "vaUnmapBuffer failed");
568 653
569 pending_va_bufs_.push_back(buffer_id); 654 pending_va_bufs_.push_back(buffer_id);
570 return true; 655 return true;
571 } 656 }
572 657
573 void VaapiWrapper::DestroyPendingBuffers() { 658 void VaapiWrapper::DestroyPendingBuffers() {
574 base::AutoLock auto_lock(va_lock_); 659 base::AutoLock auto_lock(va_lock_);
575 660
576 for (size_t i = 0; i < pending_va_bufs_.size(); ++i) { 661 for (const auto& pending_va_buf : pending_va_bufs_) {
577 VAStatus va_res = vaDestroyBuffer(va_display_, pending_va_bufs_[i]); 662 VAStatus va_res = vaDestroyBuffer(va_display_, pending_va_buf);
578 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); 663 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
579 } 664 }
580 665
581 for (size_t i = 0; i < pending_slice_bufs_.size(); ++i) { 666 for (const auto& pending_slice_buf : pending_slice_bufs_) {
582 VAStatus va_res = vaDestroyBuffer(va_display_, pending_slice_bufs_[i]); 667 VAStatus va_res = vaDestroyBuffer(va_display_, pending_slice_buf);
583 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); 668 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
584 } 669 }
585 670
586 pending_va_bufs_.clear(); 671 pending_va_bufs_.clear();
587 pending_slice_bufs_.clear(); 672 pending_slice_bufs_.clear();
588 } 673 }
589 674
590 bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) { 675 bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) {
591 base::AutoLock auto_lock(va_lock_); 676 base::AutoLock auto_lock(va_lock_);
592 VAStatus va_res = vaCreateBuffer(va_display_, 677 VAStatus va_res = vaCreateBuffer(va_display_,
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 1037
953 #if defined(USE_X11) 1038 #if defined(USE_X11)
954 paths[kModuleVa_x11].push_back("libva-x11.so.1"); 1039 paths[kModuleVa_x11].push_back("libva-x11.so.1");
955 #elif defined(USE_OZONE) 1040 #elif defined(USE_OZONE)
956 paths[kModuleVa_drm].push_back("libva-drm.so.1"); 1041 paths[kModuleVa_drm].push_back("libva-drm.so.1");
957 #endif 1042 #endif
958 1043
959 return InitializeStubs(paths); 1044 return InitializeStubs(paths);
960 } 1045 }
961 1046
1047 VaapiWrapper::LazyProfileInfos::LazyProfileInfos() {
1048 static_assert(arraysize(supported_profiles_) == kCodecModeMax,
1049 "The array size of supported profile is incorrect.");
1050 for (size_t i = 0; i < kCodecModeMax; ++i) {
1051 supported_profiles_[i] =
1052 VaapiWrapper::GetSupportedProfileInfosForCodecMode(
1053 static_cast<CodecMode>(i));
1054 }
1055 }
1056
1057 VaapiWrapper::LazyProfileInfos::~LazyProfileInfos() {
1058 }
1059
1060 std::vector<VaapiWrapper::ProfileInfo>
1061 VaapiWrapper::LazyProfileInfos::GetSupportedProfileInfosForCodecMode(
1062 CodecMode mode) {
1063 return supported_profiles_[mode];
1064 }
1065
1066 bool VaapiWrapper::LazyProfileInfos::IsProfileSupported(
1067 CodecMode mode, VAProfile va_profile) {
1068 for (const auto& profile : supported_profiles_[mode]) {
1069 if (profile.va_profile == va_profile)
1070 return true;
1071 }
1072 return false;
1073 }
1074
962 } // namespace content 1075 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/vaapi_wrapper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698