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

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

Issue 603153002: vaapi: detect supported profiles in runtime. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix a comment Created 6 years, 2 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"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420}, 50 {VAConfigAttribRTFormat, VA_RT_FORMAT_YUV420},
51 }; 51 };
52 52
53 // Attributes required for encode. 53 // Attributes required for encode.
54 static const VAConfigAttrib kEncodeVAConfigAttribs[] = { 54 static const VAConfigAttrib kEncodeVAConfigAttribs[] = {
55 {VAConfigAttribRateControl, VA_RC_CBR}, 55 {VAConfigAttribRateControl, VA_RC_CBR},
56 {VAConfigAttribEncPackedHeaders, 56 {VAConfigAttribEncPackedHeaders,
57 VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE}, 57 VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE},
58 }; 58 };
59 59
60 struct ProfileMap {
61 media::VideoCodecProfile profile;
62 VAProfile va_profile;
63 };
64
65 // A map between VideoCodecProfile and VAProfile.
66 static const ProfileMap kProfileMap[] = {
67 {media::H264PROFILE_BASELINE, VAProfileH264Baseline},
68 {media::H264PROFILE_MAIN, VAProfileH264Main},
69 // TODO(posciak): See if we can/want support other variants of
70 // media::H264PROFILE_HIGH*.
71 {media::H264PROFILE_HIGH, VAProfileH264High}};
kcwu 2014/09/26 10:06:14 how about }; in next line
72
73 static std::vector<VAConfigAttrib> GetRequiredAttribs(
74 VaapiWrapper::CodecMode mode) {
75 std::vector<VAConfigAttrib> required_attribs;
76 required_attribs.insert(
77 required_attribs.end(),
78 kCommonVAConfigAttribs,
79 kCommonVAConfigAttribs + arraysize(kCommonVAConfigAttribs));
80 if (mode == VaapiWrapper::kEncode) {
81 required_attribs.insert(
82 required_attribs.end(),
83 kEncodeVAConfigAttribs,
84 kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs));
85 }
86 return required_attribs;
87 }
88
60 // Maps Profile enum values to VaProfile values. 89 // Maps Profile enum values to VaProfile values.
61 static VAProfile ProfileToVAProfile( 90 static VAProfile ProfileToVAProfile(
62 media::VideoCodecProfile profile, 91 media::VideoCodecProfile profile,
63 const std::vector<VAProfile>& supported_profiles) { 92 const std::vector<VAProfile>& supported_profiles) {
64 93
65 VAProfile va_profile = VAProfileNone; 94 VAProfile va_profile = VAProfileNone;
66 95 for (size_t i = 0; i < arraysize(kProfileMap); i++) {
67 switch (profile) { 96 if (kProfileMap[i].profile == profile) {
68 case media::H264PROFILE_BASELINE: 97 va_profile = kProfileMap[i].va_profile;
69 va_profile = VAProfileH264Baseline;
70 break; 98 break;
71 case media::H264PROFILE_MAIN: 99 }
72 va_profile = VAProfileH264Main;
73 break;
74 // TODO(posciak): See if we can/want support other variants
75 // of media::H264PROFILE_HIGH*.
76 case media::H264PROFILE_HIGH:
77 va_profile = VAProfileH264High;
78 break;
79 default:
80 break;
81 } 100 }
82 101
83 bool supported = std::find(supported_profiles.begin(), 102 bool supported = std::find(supported_profiles.begin(),
84 supported_profiles.end(), 103 supported_profiles.end(),
85 va_profile) != supported_profiles.end(); 104 va_profile) != supported_profiles.end();
86 105
87 if (!supported && va_profile == VAProfileH264Baseline) { 106 if (!supported && va_profile == VAProfileH264Baseline) {
88 // crbug.com/345569: media::ProfileIDToVideoCodecProfile() currently strips 107 // crbug.com/345569: media::ProfileIDToVideoCodecProfile() currently strips
89 // the information whether the profile is constrained or not, so we have no 108 // the information whether the profile is constrained or not, so we have no
90 // way to know here. Try for baseline first, but if it is not supported, 109 // way to know here. Try for baseline first, but if it is not supported,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 const base::Closure& report_error_to_uma_cb) { 151 const base::Closure& report_error_to_uma_cb) {
133 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); 152 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
134 153
135 if (!vaapi_wrapper->Initialize( 154 if (!vaapi_wrapper->Initialize(
136 mode, profile, x_display, report_error_to_uma_cb)) 155 mode, profile, x_display, report_error_to_uma_cb))
137 vaapi_wrapper.reset(); 156 vaapi_wrapper.reset();
138 157
139 return vaapi_wrapper.Pass(); 158 return vaapi_wrapper.Pass();
140 } 159 }
141 160
161 std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedEncodeProfiles(
162 Display* x_display,
163 const base::Closure& report_error_to_uma_cb) {
164 std::vector<media::VideoCodecProfile> supported_profiles;
165
166 scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper());
167 if (!wrapper->VaInitialize(x_display, report_error_to_uma_cb)) {
168 return supported_profiles;
169 }
170
171 std::vector<VAProfile> va_profiles;
172 if (!wrapper->GetSupportedVaProfiles(&va_profiles))
173 return supported_profiles;
174
175 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode);
176 for (size_t i = 0; i < arraysize(kProfileMap); i++) {
177 VAProfile va_profile = VAProfileNone;
178 if (wrapper->IsProfileSupported(kProfileMap[i].profile,
179 va_profiles,
180 VAEntrypointEncSlice,
181 required_attribs,
182 &va_profile)) {
183 supported_profiles.push_back(kProfileMap[i].profile);
184 }
185 }
186 return supported_profiles;
187 }
188
142 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { 189 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
143 VADisplayAttribute item = {VADisplayAttribRenderMode, 190 VADisplayAttribute item = {VADisplayAttribRenderMode,
144 1, // At least support '_LOCAL_OVERLAY'. 191 1, // At least support '_LOCAL_OVERLAY'.
145 -1, // The maximum possible support 'ALL'. 192 -1, // The maximum possible support 'ALL'.
146 VA_RENDER_MODE_LOCAL_GPU, 193 VA_RENDER_MODE_LOCAL_GPU,
147 VA_DISPLAY_ATTRIB_SETTABLE}; 194 VA_DISPLAY_ATTRIB_SETTABLE};
148 195
149 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); 196 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1);
150 if (va_res != VA_STATUS_SUCCESS) 197 if (va_res != VA_STATUS_SUCCESS)
151 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; 198 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default.";
152 } 199 }
153 200
154 bool VaapiWrapper::Initialize(CodecMode mode, 201 bool VaapiWrapper::VaInitialize(Display* x_display,
155 media::VideoCodecProfile profile, 202 const base::Closure& report_error_to_uma_cb) {
156 Display* x_display,
157 const base::Closure& report_error_to_uma_cb) {
158 static bool vaapi_functions_initialized = PostSandboxInitialization(); 203 static bool vaapi_functions_initialized = PostSandboxInitialization();
159 if (!vaapi_functions_initialized) { 204 if (!vaapi_functions_initialized) {
160 DVLOG(1) << "Failed to initialize VAAPI libs"; 205 DVLOG(1) << "Failed to initialize VAAPI libs";
161 return false; 206 return false;
162 } 207 }
163 208
164 report_error_to_uma_cb_ = report_error_to_uma_cb; 209 report_error_to_uma_cb_ = report_error_to_uma_cb;
165 210
166 base::AutoLock auto_lock(va_lock_); 211 base::AutoLock auto_lock(va_lock_);
167 212
168 va_display_ = vaGetDisplay(x_display); 213 va_display_ = vaGetDisplay(x_display);
169 if (!vaDisplayIsValid(va_display_)) { 214 if (!vaDisplayIsValid(va_display_)) {
170 DVLOG(1) << "Could not get a valid VA display"; 215 DVLOG(1) << "Could not get a valid VA display";
171 return false; 216 return false;
172 } 217 }
173 218
174 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); 219 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_);
175 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); 220 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false);
176 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; 221 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_;
177 222
178 if (VAAPIVersionLessThan(0, 34)) { 223 if (VAAPIVersionLessThan(0, 34)) {
179 DVLOG(1) << "VAAPI version < 0.34 is not supported."; 224 DVLOG(1) << "VAAPI version < 0.34 is not supported.";
180 return false; 225 return false;
181 } 226 }
227 return true;
228 }
182 229
230 bool VaapiWrapper::GetSupportedVaProfiles(std::vector<VAProfile>* profiles) {
231 base::AutoLock auto_lock(va_lock_);
183 // Query the driver for supported profiles. 232 // Query the driver for supported profiles.
184 int max_profiles = vaMaxNumProfiles(va_display_); 233 int max_profiles = vaMaxNumProfiles(va_display_);
185 std::vector<VAProfile> supported_profiles( 234 std::vector<VAProfile> supported_profiles(
186 base::checked_cast<size_t>(max_profiles)); 235 base::checked_cast<size_t>(max_profiles));
187 236
188 int num_supported_profiles; 237 int num_supported_profiles;
189 va_res = vaQueryConfigProfiles( 238 VAStatus va_res = vaQueryConfigProfiles(
190 va_display_, &supported_profiles[0], &num_supported_profiles); 239 va_display_, &supported_profiles[0], &num_supported_profiles);
191 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); 240 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false);
192 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { 241 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) {
193 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles; 242 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles;
194 return false; 243 return false;
195 } 244 }
196 245
197 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); 246 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles));
247 *profiles = supported_profiles;
248 return true;
249 }
198 250
199 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles); 251 bool VaapiWrapper::IsProfileSupported(
200 if (va_profile == VAProfileNone) { 252 media::VideoCodecProfile profile,
253 const std::vector<VAProfile>& supported_profiles,
254 VAEntrypoint entrypoint,
255 const std::vector<VAConfigAttrib>& required_attribs,
256 VAProfile* va_profile) {
257 *va_profile = ProfileToVAProfile(profile, supported_profiles);
258 if (*va_profile == VAProfileNone) {
201 DVLOG(1) << "Unsupported profile"; 259 DVLOG(1) << "Unsupported profile";
202 return false; 260 return false;
203 } 261 }
204 262
263 base::AutoLock auto_lock(va_lock_);
205 // Query the driver for supported entrypoints. 264 // Query the driver for supported entrypoints.
206 int max_entrypoints = vaMaxNumEntrypoints(va_display_); 265 int max_entrypoints = vaMaxNumEntrypoints(va_display_);
207 std::vector<VAEntrypoint> supported_entrypoints( 266 std::vector<VAEntrypoint> supported_entrypoints(
208 base::checked_cast<size_t>(max_entrypoints)); 267 base::checked_cast<size_t>(max_entrypoints));
209 268
210 int num_supported_entrypoints; 269 int num_supported_entrypoints;
211 va_res = vaQueryConfigEntrypoints(va_display_, 270 VAStatus va_res = vaQueryConfigEntrypoints(va_display_,
212 va_profile, 271 *va_profile,
213 &supported_entrypoints[0], 272 &supported_entrypoints[0],
214 &num_supported_entrypoints); 273 &num_supported_entrypoints);
215 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false); 274 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false);
216 if (num_supported_entrypoints < 0 || 275 if (num_supported_entrypoints < 0 ||
217 num_supported_entrypoints > max_entrypoints) { 276 num_supported_entrypoints > max_entrypoints) {
218 DVLOG(1) << "vaQueryConfigEntrypoints returned: " 277 DVLOG(1) << "vaQueryConfigEntrypoints returned: "
219 << num_supported_entrypoints; 278 << num_supported_entrypoints;
220 return false; 279 return false;
221 } 280 }
222 281
223 VAEntrypoint entrypoint =
224 (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD);
225
226 if (std::find(supported_entrypoints.begin(), 282 if (std::find(supported_entrypoints.begin(),
227 supported_entrypoints.end(), 283 supported_entrypoints.end(),
228 entrypoint) == supported_entrypoints.end()) { 284 entrypoint) == supported_entrypoints.end()) {
229 DVLOG(1) << "Unsupported entrypoint"; 285 DVLOG(1) << "Unsupported entrypoint";
230 return false; 286 return false;
231 } 287 }
232 288
233 // Query the driver for required attributes. 289 // Query the driver for required attributes.
234 std::vector<VAConfigAttrib> required_attribs;
235 required_attribs.insert(
236 required_attribs.end(),
237 kCommonVAConfigAttribs,
238 kCommonVAConfigAttribs + arraysize(kCommonVAConfigAttribs));
239 if (mode == kEncode) {
240 required_attribs.insert(
241 required_attribs.end(),
242 kEncodeVAConfigAttribs,
243 kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs));
244 }
245
246 std::vector<VAConfigAttrib> attribs = required_attribs; 290 std::vector<VAConfigAttrib> attribs = required_attribs;
247 for (size_t i = 0; i < required_attribs.size(); ++i) 291 for (size_t i = 0; i < required_attribs.size(); ++i)
248 attribs[i].value = 0; 292 attribs[i].value = 0;
249 293
250 va_res = vaGetConfigAttributes( 294 va_res = vaGetConfigAttributes(
251 va_display_, va_profile, entrypoint, &attribs[0], attribs.size()); 295 va_display_, *va_profile, entrypoint, &attribs[0], attribs.size());
252 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false); 296 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false);
253 297
254 for (size_t i = 0; i < required_attribs.size(); ++i) { 298 for (size_t i = 0; i < required_attribs.size(); ++i) {
255 if (attribs[i].type != required_attribs[i].type || 299 if (attribs[i].type != required_attribs[i].type ||
256 (attribs[i].value & required_attribs[i].value) != 300 (attribs[i].value & required_attribs[i].value) !=
257 required_attribs[i].value) { 301 required_attribs[i].value) {
258 DVLOG(1) << "Unsupported value " << required_attribs[i].value 302 DVLOG(1) << "Unsupported value " << required_attribs[i].value
259 << " for attribute type " << required_attribs[i].type; 303 << " for attribute type " << required_attribs[i].type;
260 return false; 304 return false;
261 } 305 }
262 } 306 }
307 return true;
308 }
263 309
310 bool VaapiWrapper::Initialize(CodecMode mode,
311 media::VideoCodecProfile profile,
312 Display* x_display,
313 const base::Closure& report_error_to_uma_cb) {
314 if (!VaInitialize(x_display, report_error_to_uma_cb))
315 return false;
316 std::vector<VAProfile> supported_va_profiles;
317 if (!GetSupportedVaProfiles(&supported_va_profiles))
318 return false;
319 VAEntrypoint entrypoint =
320 (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD);
321 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode);
322 VAProfile va_profile = VAProfileNone;
323 if (!IsProfileSupported(profile,
324 supported_va_profiles,
325 entrypoint,
326 required_attribs,
327 &va_profile)) {
328 return false;
329 }
330
331 base::AutoLock auto_lock(va_lock_);
264 TryToSetVADisplayAttributeToLocalGPU(); 332 TryToSetVADisplayAttributeToLocalGPU();
265 333
266 va_res = vaCreateConfig(va_display_, 334 VAStatus va_res = vaCreateConfig(va_display_,
267 va_profile, 335 va_profile,
268 entrypoint, 336 entrypoint,
269 &required_attribs[0], 337 &required_attribs[0],
270 required_attribs.size(), 338 required_attribs.size(),
271 &va_config_id_); 339 &va_config_id_);
272 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false); 340 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false);
273 341
274 return true; 342 return true;
275 } 343 }
276 344
277 void VaapiWrapper::Deinitialize() { 345 void VaapiWrapper::Deinitialize() {
278 base::AutoLock auto_lock(va_lock_); 346 base::AutoLock auto_lock(va_lock_);
279 347
280 if (va_config_id_ != VA_INVALID_ID) { 348 if (va_config_id_ != VA_INVALID_ID) {
281 VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_); 349 VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_);
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 735
668 // static 736 // static
669 bool VaapiWrapper::PostSandboxInitialization() { 737 bool VaapiWrapper::PostSandboxInitialization() {
670 StubPathMap paths; 738 StubPathMap paths;
671 paths[kModuleVa].push_back(kVaLib); 739 paths[kModuleVa].push_back(kVaLib);
672 740
673 return InitializeStubs(paths); 741 return InitializeStubs(paths);
674 } 742 }
675 743
676 } // namespace content 744 } // 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