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

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: 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
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 static std::vector<VAConfigAttrib> GetRequiredAttribs(
61 VaapiWrapper::CodecMode mode) {
62 std::vector<VAConfigAttrib> required_attribs;
63 required_attribs.insert(
64 required_attribs.end(),
65 kCommonVAConfigAttribs,
66 kCommonVAConfigAttribs + arraysize(kCommonVAConfigAttribs));
67 if (mode == VaapiWrapper::kEncode) {
68 required_attribs.insert(
69 required_attribs.end(),
70 kEncodeVAConfigAttribs,
71 kEncodeVAConfigAttribs + arraysize(kEncodeVAConfigAttribs));
72 }
73 return required_attribs;
74 }
75
60 // Maps Profile enum values to VaProfile values. 76 // Maps Profile enum values to VaProfile values.
61 static VAProfile ProfileToVAProfile( 77 static VAProfile ProfileToVAProfile(
62 media::VideoCodecProfile profile, 78 media::VideoCodecProfile profile,
63 const std::vector<VAProfile>& supported_profiles) { 79 const std::vector<VAProfile>& supported_profiles) {
64 80
65 VAProfile va_profile = VAProfileNone; 81 VAProfile va_profile = VAProfileNone;
66 82
67 switch (profile) { 83 switch (profile) {
68 case media::H264PROFILE_BASELINE: 84 case media::H264PROFILE_BASELINE:
69 va_profile = VAProfileH264Baseline; 85 va_profile = VAProfileH264Baseline;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 const base::Closure& report_error_to_uma_cb) { 148 const base::Closure& report_error_to_uma_cb) {
133 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper()); 149 scoped_ptr<VaapiWrapper> vaapi_wrapper(new VaapiWrapper());
134 150
135 if (!vaapi_wrapper->Initialize( 151 if (!vaapi_wrapper->Initialize(
136 mode, profile, x_display, report_error_to_uma_cb)) 152 mode, profile, x_display, report_error_to_uma_cb))
137 vaapi_wrapper.reset(); 153 vaapi_wrapper.reset();
138 154
139 return vaapi_wrapper.Pass(); 155 return vaapi_wrapper.Pass();
140 } 156 }
141 157
158 std::vector<media::VideoCodecProfile> VaapiWrapper::GetSupportedProfiles(
159 Display* x_display,
160 const base::Closure& report_error_to_uma_cb) {
161 std::vector<media::VideoCodecProfile> supported_profiles;
162 media::VideoCodecProfile profiles[3] = {media::H264PROFILE_BASELINE,
Pawel Osciak 2014/09/26 07:15:12 Ideally we'd like to use all va_profiles and use s
wuchengli 2014/09/26 09:02:28 GetSupportedProfiles is called when GPU process st
163 media::H264PROFILE_MAIN,
164 media::H264PROFILE_HIGH};
165
166 scoped_ptr<VaapiWrapper> wrapper(new VaapiWrapper());
167 std::vector<VAProfile> va_profiles;
168 if (!wrapper->VaInitialize(x_display, report_error_to_uma_cb)) {
169 return supported_profiles;
170 }
171 if (!wrapper->GetSupportedVaProfiles(&va_profiles))
172 return supported_profiles;
173 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(kEncode);
174 for (size_t i = 0; i < arraysize(profiles); i++) {
175 VAProfile va_profile = ProfileToVAProfile(profiles[i], va_profiles);
Pawel Osciak 2014/09/26 07:15:12 We have this chunk of code duplicated here and in
wuchengli 2014/09/26 09:02:28 Done. vaCreateConfig needs VA profile, entrypoint
176 if (va_profile != VAProfileNone &&
177 wrapper->IsEntrypointSupported(va_profile, VAEntrypointEncSlice) &&
178 wrapper->IsAttribSupported(
179 va_profile, VAEntrypointEncSlice, required_attribs)) {
180 supported_profiles.push_back(profiles[i]);
181 }
182 }
183 return supported_profiles;
184 }
185
142 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { 186 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
143 VADisplayAttribute item = {VADisplayAttribRenderMode, 187 VADisplayAttribute item = {VADisplayAttribRenderMode,
144 1, // At least support '_LOCAL_OVERLAY'. 188 1, // At least support '_LOCAL_OVERLAY'.
145 -1, // The maximum possible support 'ALL'. 189 -1, // The maximum possible support 'ALL'.
146 VA_RENDER_MODE_LOCAL_GPU, 190 VA_RENDER_MODE_LOCAL_GPU,
147 VA_DISPLAY_ATTRIB_SETTABLE}; 191 VA_DISPLAY_ATTRIB_SETTABLE};
148 192
149 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); 193 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1);
150 if (va_res != VA_STATUS_SUCCESS) 194 if (va_res != VA_STATUS_SUCCESS)
151 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; 195 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default.";
152 } 196 }
153 197
154 bool VaapiWrapper::Initialize(CodecMode mode, 198 bool VaapiWrapper::VaInitialize(Display* x_display,
155 media::VideoCodecProfile profile, 199 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(); 200 static bool vaapi_functions_initialized = PostSandboxInitialization();
159 if (!vaapi_functions_initialized) { 201 if (!vaapi_functions_initialized) {
160 DVLOG(1) << "Failed to initialize VAAPI libs"; 202 DVLOG(1) << "Failed to initialize VAAPI libs";
161 return false; 203 return false;
162 } 204 }
163 205
164 report_error_to_uma_cb_ = report_error_to_uma_cb; 206 report_error_to_uma_cb_ = report_error_to_uma_cb;
165 207
166 base::AutoLock auto_lock(va_lock_); 208 base::AutoLock auto_lock(va_lock_);
167 209
168 va_display_ = vaGetDisplay(x_display); 210 va_display_ = vaGetDisplay(x_display);
169 if (!vaDisplayIsValid(va_display_)) { 211 if (!vaDisplayIsValid(va_display_)) {
170 DVLOG(1) << "Could not get a valid VA display"; 212 DVLOG(1) << "Could not get a valid VA display";
171 return false; 213 return false;
172 } 214 }
173 215
174 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_); 216 VAStatus va_res = vaInitialize(va_display_, &major_version_, &minor_version_);
175 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); 217 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false);
176 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; 218 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_;
177 219
178 if (VAAPIVersionLessThan(0, 34)) { 220 if (VAAPIVersionLessThan(0, 34)) {
179 DVLOG(1) << "VAAPI version < 0.34 is not supported."; 221 DVLOG(1) << "VAAPI version < 0.34 is not supported.";
180 return false; 222 return false;
181 } 223 }
224 return true;
225 }
182 226
227 bool VaapiWrapper::GetSupportedVaProfiles(std::vector<VAProfile>* profiles) {
228 base::AutoLock auto_lock(va_lock_);
183 // Query the driver for supported profiles. 229 // Query the driver for supported profiles.
184 int max_profiles = vaMaxNumProfiles(va_display_); 230 int max_profiles = vaMaxNumProfiles(va_display_);
185 std::vector<VAProfile> supported_profiles( 231 std::vector<VAProfile> supported_profiles(
186 base::checked_cast<size_t>(max_profiles)); 232 base::checked_cast<size_t>(max_profiles));
187 233
188 int num_supported_profiles; 234 int num_supported_profiles;
189 va_res = vaQueryConfigProfiles( 235 VAStatus va_res = vaQueryConfigProfiles(
190 va_display_, &supported_profiles[0], &num_supported_profiles); 236 va_display_, &supported_profiles[0], &num_supported_profiles);
191 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false); 237 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigProfiles failed", false);
192 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) { 238 if (num_supported_profiles < 0 || num_supported_profiles > max_profiles) {
193 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles; 239 DVLOG(1) << "vaQueryConfigProfiles returned: " << num_supported_profiles;
194 return false; 240 return false;
195 } 241 }
196 242
197 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles)); 243 supported_profiles.resize(base::checked_cast<size_t>(num_supported_profiles));
244 *profiles = supported_profiles;
245 return true;
246 }
198 247
199 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles); 248 bool VaapiWrapper::IsEntrypointSupported(VAProfile va_profile,
200 if (va_profile == VAProfileNone) { 249 VAEntrypoint entrypoint) {
201 DVLOG(1) << "Unsupported profile"; 250 base::AutoLock auto_lock(va_lock_);
202 return false;
203 }
204
205 // Query the driver for supported entrypoints. 251 // Query the driver for supported entrypoints.
206 int max_entrypoints = vaMaxNumEntrypoints(va_display_); 252 int max_entrypoints = vaMaxNumEntrypoints(va_display_);
207 std::vector<VAEntrypoint> supported_entrypoints( 253 std::vector<VAEntrypoint> supported_entrypoints(
208 base::checked_cast<size_t>(max_entrypoints)); 254 base::checked_cast<size_t>(max_entrypoints));
209 255
210 int num_supported_entrypoints; 256 int num_supported_entrypoints;
211 va_res = vaQueryConfigEntrypoints(va_display_, 257 VAStatus va_res = vaQueryConfigEntrypoints(va_display_,
212 va_profile, 258 va_profile,
213 &supported_entrypoints[0], 259 &supported_entrypoints[0],
214 &num_supported_entrypoints); 260 &num_supported_entrypoints);
215 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false); 261 VA_SUCCESS_OR_RETURN(va_res, "vaQueryConfigEntrypoints failed", false);
216 if (num_supported_entrypoints < 0 || 262 if (num_supported_entrypoints < 0 ||
217 num_supported_entrypoints > max_entrypoints) { 263 num_supported_entrypoints > max_entrypoints) {
218 DVLOG(1) << "vaQueryConfigEntrypoints returned: " 264 DVLOG(1) << "vaQueryConfigEntrypoints returned: "
219 << num_supported_entrypoints; 265 << num_supported_entrypoints;
220 return false; 266 return false;
221 } 267 }
222 268
223 VAEntrypoint entrypoint =
224 (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD);
225
226 if (std::find(supported_entrypoints.begin(), 269 if (std::find(supported_entrypoints.begin(),
227 supported_entrypoints.end(), 270 supported_entrypoints.end(),
228 entrypoint) == supported_entrypoints.end()) { 271 entrypoint) == supported_entrypoints.end()) {
229 DVLOG(1) << "Unsupported entrypoint"; 272 DVLOG(1) << "Unsupported entrypoint";
230 return false; 273 return false;
231 } 274 }
275 return true;
276 }
232 277
278 bool VaapiWrapper::IsAttribSupported(
279 VAProfile va_profile,
280 VAEntrypoint entrypoint,
281 const std::vector<VAConfigAttrib>& required_attribs) {
282 base::AutoLock auto_lock(va_lock_);
233 // Query the driver for required attributes. 283 // 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; 284 std::vector<VAConfigAttrib> attribs = required_attribs;
247 for (size_t i = 0; i < required_attribs.size(); ++i) 285 for (size_t i = 0; i < required_attribs.size(); ++i)
248 attribs[i].value = 0; 286 attribs[i].value = 0;
249 287
250 va_res = vaGetConfigAttributes( 288 VAStatus va_res = vaGetConfigAttributes(
251 va_display_, va_profile, entrypoint, &attribs[0], attribs.size()); 289 va_display_, va_profile, entrypoint, &attribs[0], attribs.size());
252 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false); 290 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false);
253 291
254 for (size_t i = 0; i < required_attribs.size(); ++i) { 292 for (size_t i = 0; i < required_attribs.size(); ++i) {
255 if (attribs[i].type != required_attribs[i].type || 293 if (attribs[i].type != required_attribs[i].type ||
256 (attribs[i].value & required_attribs[i].value) != 294 (attribs[i].value & required_attribs[i].value) !=
257 required_attribs[i].value) { 295 required_attribs[i].value) {
258 DVLOG(1) << "Unsupported value " << required_attribs[i].value 296 DVLOG(1) << "Unsupported value " << required_attribs[i].value
259 << " for attribute type " << required_attribs[i].type; 297 << " for attribute type " << required_attribs[i].type;
260 return false; 298 return false;
261 } 299 }
262 } 300 }
301 return true;
302 }
303
304 bool VaapiWrapper::Initialize(CodecMode mode,
305 media::VideoCodecProfile profile,
306 Display* x_display,
307 const base::Closure& report_error_to_uma_cb) {
308 if (!VaInitialize(x_display, report_error_to_uma_cb))
309 return false;
310 std::vector<VAProfile> supported_profiles;
311 if (!GetSupportedVaProfiles(&supported_profiles))
312 return false;
313 VAProfile va_profile = ProfileToVAProfile(profile, supported_profiles);
314 if (va_profile == VAProfileNone) {
315 DVLOG(1) << "Unsupported profile";
316 return false;
317 }
318 VAEntrypoint entrypoint =
319 (mode == kEncode ? VAEntrypointEncSlice : VAEntrypointVLD);
320 if (!IsEntrypointSupported(va_profile, entrypoint))
321 return false;
322 std::vector<VAConfigAttrib> required_attribs = GetRequiredAttribs(mode);
323 if (!IsAttribSupported(va_profile, entrypoint, required_attribs))
324 return false;
263 325
264 TryToSetVADisplayAttributeToLocalGPU(); 326 TryToSetVADisplayAttributeToLocalGPU();
265 327
266 va_res = vaCreateConfig(va_display_, 328 VAStatus va_res = vaCreateConfig(va_display_,
kcwu 2014/09/26 07:50:45 va_lock_ for this?
wuchengli 2014/09/26 09:02:28 Done. Thanks for catching this.
267 va_profile, 329 va_profile,
268 entrypoint, 330 entrypoint,
269 &required_attribs[0], 331 &required_attribs[0],
270 required_attribs.size(), 332 required_attribs.size(),
271 &va_config_id_); 333 &va_config_id_);
272 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false); 334 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false);
273 335
274 return true; 336 return true;
275 } 337 }
276 338
277 void VaapiWrapper::Deinitialize() { 339 void VaapiWrapper::Deinitialize() {
278 base::AutoLock auto_lock(va_lock_); 340 base::AutoLock auto_lock(va_lock_);
279 341
280 if (va_config_id_ != VA_INVALID_ID) { 342 if (va_config_id_ != VA_INVALID_ID) {
281 VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_); 343 VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_);
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 729
668 // static 730 // static
669 bool VaapiWrapper::PostSandboxInitialization() { 731 bool VaapiWrapper::PostSandboxInitialization() {
670 StubPathMap paths; 732 StubPathMap paths;
671 paths[kModuleVa].push_back(kVaLib); 733 paths[kModuleVa].push_back(kVaLib);
672 734
673 return InitializeStubs(paths); 735 return InitializeStubs(paths);
674 } 736 }
675 737
676 } // namespace content 738 } // namespace content
OLDNEW
« content/common/gpu/media/vaapi_wrapper.h ('K') | « 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