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" | |
6 | |
5 #include <dlfcn.h> | 7 #include <dlfcn.h> |
6 | 8 |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/logging.h" | 10 #include "base/logging.h" |
9 #include "content/common/gpu/media/vaapi_wrapper.h" | 11 #include "common/gpu/media/va_stubs.h" |
12 | |
13 using common_gpu_media::kModuleVa; | |
14 using common_gpu_media::InitializeStubs; | |
15 using common_gpu_media::StubPathMap; | |
16 | |
17 // libva-x11 depend on libva, so dlopen libva-x11 is enough | |
18 static const base::FilePath::CharType kVaLib[] = | |
19 FILE_PATH_LITERAL("libva-x11.so.1"); | |
10 | 20 |
11 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ | 21 #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ |
12 do { \ | 22 do { \ |
13 DVLOG(1) << err_msg \ | 23 DVLOG(1) << err_msg \ |
14 << " VA error: " << VAAPI_ErrorStr(va_error); \ | 24 << " VA error: " << vaErrorStr(va_error); \ |
15 report_error_to_uma_cb_.Run(); \ | 25 report_error_to_uma_cb_.Run(); \ |
16 } while (0) | 26 } while (0) |
17 | 27 |
18 #define VA_LOG_ON_ERROR(va_error, err_msg) \ | 28 #define VA_LOG_ON_ERROR(va_error, err_msg) \ |
19 do { \ | 29 do { \ |
20 if ((va_error) != VA_STATUS_SUCCESS) \ | 30 if ((va_error) != VA_STATUS_SUCCESS) \ |
21 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ | 31 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ |
22 } while (0) | 32 } while (0) |
23 | 33 |
24 #define VA_SUCCESS_OR_RETURN(va_error, err_msg, ret) \ | 34 #define VA_SUCCESS_OR_RETURN(va_error, err_msg, ret) \ |
25 do { \ | 35 do { \ |
26 if ((va_error) != VA_STATUS_SUCCESS) { \ | 36 if ((va_error) != VA_STATUS_SUCCESS) { \ |
27 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ | 37 LOG_VA_ERROR_AND_REPORT(va_error, err_msg); \ |
28 return (ret); \ | 38 return (ret); \ |
29 } \ | 39 } \ |
30 } while (0) | 40 } while (0) |
31 | 41 |
32 namespace content { | 42 namespace content { |
33 | 43 |
34 static void *vaapi_handle = NULL; | |
35 static void *vaapi_x11_handle = NULL; | |
36 | |
37 typedef VAStatus (*VaapiBeginPicture)(VADisplay dpy, | |
38 VAContextID context, | |
39 VASurfaceID render_target); | |
40 typedef VAStatus (*VaapiCreateBuffer)(VADisplay dpy, | |
41 VAContextID context, | |
42 VABufferType type, | |
43 unsigned int size, | |
44 unsigned int num_elements, | |
45 void *data, | |
46 VABufferID *buf_id); | |
47 typedef VAStatus (*VaapiCreateConfig)(VADisplay dpy, | |
48 VAProfile profile, | |
49 VAEntrypoint entrypoint, | |
50 VAConfigAttrib *attrib_list, | |
51 int num_attribs, | |
52 VAConfigID *config_id); | |
53 typedef VAStatus (*VaapiCreateContext)(VADisplay dpy, | |
54 VAConfigID config_id, | |
55 int picture_width, | |
56 int picture_height, | |
57 int flag, | |
58 VASurfaceID *render_targets, | |
59 int num_render_targets, | |
60 VAContextID *context); | |
61 // In VAAPI version < 0.34, vaCreateSurface has 6 parameters, but in VAAPI | 44 // In VAAPI version < 0.34, vaCreateSurface has 6 parameters, but in VAAPI |
62 // version >= 0.34, vaCreateSurface has 8 parameters. | 45 // version >= 0.34, vaCreateSurface has 8 parameters. |
63 // TODO(chihchung): Remove the old path once ChromeOS updates to 1.2.1. | 46 // TODO(chihchung): Remove the old path once ChromeOS updates to 1.2.1. |
Pawel Osciak
2014/02/25 10:34:01
We can do this already. We are at 1.2.1/0.34.
| |
64 typedef void *VaapiCreateSurfaces; | 47 static void* vaapi_handle = NULL; |
48 | |
49 typedef void* VaapiCreateSurfaces; | |
65 typedef VAStatus (*VaapiCreateSurfaces6)(VADisplay dpy, | 50 typedef VAStatus (*VaapiCreateSurfaces6)(VADisplay dpy, |
66 int width, | 51 int width, |
67 int height, | 52 int height, |
68 int format, | 53 int format, |
69 int num_surfaces, | 54 int num_surfaces, |
70 VASurfaceID *surfaces); | 55 VASurfaceID* surfaces); |
71 typedef VAStatus (*VaapiCreateSurfaces8)(VADisplay dpy, | 56 typedef VAStatus (*VaapiCreateSurfaces8)(VADisplay dpy, |
72 unsigned int format, | 57 unsigned int format, |
73 unsigned int width, | 58 unsigned int width, |
74 unsigned int height, | 59 unsigned int height, |
75 VASurfaceID *surfaces, | 60 VASurfaceID* surfaces, |
76 unsigned int num_surfaces, | 61 unsigned int num_surfaces, |
77 VASurfaceAttrib *attrib_list, | 62 VASurfaceAttrib* attrib_list, |
78 unsigned int num_attribs); | 63 unsigned int num_attribs); |
79 typedef VAStatus (*VaapiDeriveImage)(VADisplay dpy, | |
80 VASurfaceID surface, | |
81 VAImage* image); | |
82 typedef VAStatus (*VaapiDestroyBuffer)(VADisplay dpy, VABufferID buffer_id); | |
83 typedef VAStatus (*VaapiDestroyConfig)(VADisplay dpy, VAConfigID config_id); | |
84 typedef VAStatus (*VaapiDestroyContext)(VADisplay dpy, VAContextID context); | |
85 typedef VAStatus (*VaapiDestroyImage)(VADisplay dpy, VAImageID image); | |
86 typedef VAStatus (*VaapiDestroySurfaces)(VADisplay dpy, | |
87 VASurfaceID *surfaces, | |
88 int num_surfaces); | |
89 typedef int (*VaapiDisplayIsValid)(VADisplay dpy); | |
90 typedef VAStatus (*VaapiEndPicture)(VADisplay dpy, VAContextID context); | |
91 typedef const char* (*VaapiErrorStr)(VAStatus error_status); | |
92 typedef VAStatus (*VaapiGetConfigAttributes)(VADisplay dpy, | |
93 VAProfile profile, | |
94 VAEntrypoint entrypoint, | |
95 VAConfigAttrib *attrib_list, | |
96 int num_attribs); | |
97 typedef VADisplay (*VaapiGetDisplay)(Display *dpy); | |
98 typedef VAStatus (*VaapiInitialize)(VADisplay dpy, | |
99 int *major_version, | |
100 int *minor_version); | |
101 typedef VAStatus (*VaapiMapBuffer)(VADisplay dpy, | |
102 VABufferID buf_id, | |
103 void** pbuf); | |
104 typedef VAStatus (*VaapiPutSurface)(VADisplay dpy, | |
105 VASurfaceID surface, | |
106 Drawable draw, | |
107 short srcx, | |
108 short srcy, | |
109 unsigned short srcw, | |
110 unsigned short srch, | |
111 short destx, | |
112 short desty, | |
113 unsigned short destw, | |
114 unsigned short desth, | |
115 VARectangle *cliprects, | |
116 unsigned int number_cliprects, | |
117 unsigned int flags); | |
118 typedef VAStatus (*VaapiRenderPicture)(VADisplay dpy, | |
119 VAContextID context, | |
120 VABufferID *buffers, | |
121 int num_buffers); | |
122 typedef VAStatus (*VaapiSetDisplayAttributes)(VADisplay dpy, | |
123 VADisplayAttribute *type, | |
124 int num_attributes); | |
125 typedef VAStatus (*VaapiSyncSurface)(VADisplay dpy, VASurfaceID render_target); | |
126 typedef VAStatus (*VaapiTerminate)(VADisplay dpy); | |
127 typedef VAStatus (*VaapiUnmapBuffer)(VADisplay dpy, VABufferID buf_id); | |
128 | 64 |
129 #define VAAPI_SYM(name, handle) Vaapi##name VAAPI_##name = NULL | 65 #define VAAPI_SYM(name, handle) Vaapi##name VAAPI_##name = NULL |
130 | |
131 VAAPI_SYM(BeginPicture, vaapi_handle); | |
132 VAAPI_SYM(CreateBuffer, vaapi_handle); | |
133 VAAPI_SYM(CreateConfig, vaapi_handle); | |
134 VAAPI_SYM(CreateContext, vaapi_handle); | |
135 VAAPI_SYM(CreateSurfaces, vaapi_handle); | 66 VAAPI_SYM(CreateSurfaces, vaapi_handle); |
136 VAAPI_SYM(DeriveImage, vaapi_handle); | |
137 VAAPI_SYM(DestroyBuffer, vaapi_handle); | |
138 VAAPI_SYM(DestroyConfig, vaapi_handle); | |
139 VAAPI_SYM(DestroyContext, vaapi_handle); | |
140 VAAPI_SYM(DestroyImage, vaapi_handle); | |
141 VAAPI_SYM(DestroySurfaces, vaapi_handle); | |
142 VAAPI_SYM(DisplayIsValid, vaapi_handle); | |
143 VAAPI_SYM(EndPicture, vaapi_handle); | |
144 VAAPI_SYM(ErrorStr, vaapi_handle); | |
145 VAAPI_SYM(GetConfigAttributes, vaapi_handle); | |
146 VAAPI_SYM(GetDisplay, vaapi_x11_handle); | |
147 VAAPI_SYM(Initialize, vaapi_handle); | |
148 VAAPI_SYM(MapBuffer, vaapi_handle); | |
149 VAAPI_SYM(PutSurface, vaapi_x11_handle); | |
150 VAAPI_SYM(RenderPicture, vaapi_handle); | |
151 VAAPI_SYM(SetDisplayAttributes, vaapi_handle); | |
152 VAAPI_SYM(SyncSurface, vaapi_x11_handle); | |
153 VAAPI_SYM(Terminate, vaapi_handle); | |
154 VAAPI_SYM(UnmapBuffer, vaapi_handle); | |
155 | |
156 #undef VAAPI_SYM | 67 #undef VAAPI_SYM |
157 | 68 |
158 // Maps Profile enum values to VaProfile values. | 69 // Maps Profile enum values to VaProfile values. |
159 static bool ProfileToVAProfile(media::VideoCodecProfile profile, | 70 static bool ProfileToVAProfile(media::VideoCodecProfile profile, |
160 VAProfile* va_profile) { | 71 VAProfile* va_profile) { |
161 switch (profile) { | 72 switch (profile) { |
162 case media::H264PROFILE_BASELINE: | 73 case media::H264PROFILE_BASELINE: |
163 *va_profile = VAProfileH264Baseline; | 74 *va_profile = VAProfileH264Baseline; |
164 break; | 75 break; |
165 case media::H264PROFILE_MAIN: | 76 case media::H264PROFILE_MAIN: |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
210 return vaapi_wrapper.Pass(); | 121 return vaapi_wrapper.Pass(); |
211 } | 122 } |
212 | 123 |
213 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { | 124 void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { |
214 VADisplayAttribute item = {VADisplayAttribRenderMode, | 125 VADisplayAttribute item = {VADisplayAttribRenderMode, |
215 1, // At least support '_LOCAL_OVERLAY'. | 126 1, // At least support '_LOCAL_OVERLAY'. |
216 -1, // The maximum possible support 'ALL'. | 127 -1, // The maximum possible support 'ALL'. |
217 VA_RENDER_MODE_LOCAL_GPU, | 128 VA_RENDER_MODE_LOCAL_GPU, |
218 VA_DISPLAY_ATTRIB_SETTABLE}; | 129 VA_DISPLAY_ATTRIB_SETTABLE}; |
219 | 130 |
220 VAStatus va_res = VAAPI_SetDisplayAttributes(va_display_, &item, 1); | 131 VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); |
221 if (va_res != VA_STATUS_SUCCESS) | 132 if (va_res != VA_STATUS_SUCCESS) |
222 DVLOG(2) << "VAAPI_SetDisplayAttributes unsupported, ignoring by default."; | 133 DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; |
223 } | 134 } |
224 | 135 |
225 bool VaapiWrapper::Initialize(media::VideoCodecProfile profile, | 136 bool VaapiWrapper::Initialize(media::VideoCodecProfile profile, |
226 Display* x_display, | 137 Display* x_display, |
227 const base::Closure& report_error_to_uma_cb) { | 138 const base::Closure& report_error_to_uma_cb) { |
228 static bool vaapi_functions_initialized = PostSandboxInitialization(); | 139 static bool vaapi_functions_initialized = PostSandboxInitialization(); |
229 if (!vaapi_functions_initialized) { | 140 if (!vaapi_functions_initialized) { |
230 DVLOG(1) << "Failed to initialize VAAPI libs"; | 141 DVLOG(1) << "Failed to initialize VAAPI libs"; |
231 return false; | 142 return false; |
232 } | 143 } |
233 | 144 |
234 report_error_to_uma_cb_ = report_error_to_uma_cb; | 145 report_error_to_uma_cb_ = report_error_to_uma_cb; |
235 | 146 |
236 base::AutoLock auto_lock(va_lock_); | 147 base::AutoLock auto_lock(va_lock_); |
237 | 148 |
238 VAProfile va_profile; | 149 VAProfile va_profile; |
239 if (!ProfileToVAProfile(profile, &va_profile)) { | 150 if (!ProfileToVAProfile(profile, &va_profile)) { |
240 DVLOG(1) << "Unsupported profile"; | 151 DVLOG(1) << "Unsupported profile"; |
241 return false; | 152 return false; |
242 } | 153 } |
243 | 154 |
244 va_display_ = VAAPI_GetDisplay(x_display); | 155 va_display_ = vaGetDisplay(x_display); |
245 if (!VAAPI_DisplayIsValid(va_display_)) { | 156 if (!vaDisplayIsValid(va_display_)) { |
246 DVLOG(1) << "Could not get a valid VA display"; | 157 DVLOG(1) << "Could not get a valid VA display"; |
247 return false; | 158 return false; |
248 } | 159 } |
249 | 160 |
250 VAStatus va_res; | 161 VAStatus va_res; |
251 va_res = VAAPI_Initialize(va_display_, &major_version_, &minor_version_); | 162 va_res = vaInitialize(va_display_, &major_version_, &minor_version_); |
252 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); | 163 VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); |
253 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; | 164 DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; |
254 | 165 |
255 VAConfigAttrib attrib = {VAConfigAttribRTFormat, 0}; | 166 VAConfigAttrib attrib = {VAConfigAttribRTFormat, 0}; |
256 | 167 |
257 const VAEntrypoint kEntrypoint = VAEntrypointVLD; | 168 const VAEntrypoint kEntrypoint = VAEntrypointVLD; |
258 va_res = VAAPI_GetConfigAttributes(va_display_, va_profile, kEntrypoint, | 169 va_res = vaGetConfigAttributes(va_display_, va_profile, kEntrypoint, |
259 &attrib, 1); | 170 &attrib, 1); |
260 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false); | 171 VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false); |
261 | 172 |
262 if (!(attrib.value & VA_RT_FORMAT_YUV420)) { | 173 if (!(attrib.value & VA_RT_FORMAT_YUV420)) { |
263 DVLOG(1) << "YUV420 not supported by this VAAPI implementation"; | 174 DVLOG(1) << "YUV420 not supported by this VAAPI implementation"; |
264 return false; | 175 return false; |
265 } | 176 } |
266 | 177 |
267 TryToSetVADisplayAttributeToLocalGPU(); | 178 TryToSetVADisplayAttributeToLocalGPU(); |
268 | 179 |
269 va_res = VAAPI_CreateConfig(va_display_, va_profile, kEntrypoint, | 180 va_res = vaCreateConfig(va_display_, va_profile, kEntrypoint, |
270 &attrib, 1, &va_config_id_); | 181 &attrib, 1, &va_config_id_); |
271 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false); | 182 VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false); |
272 | 183 |
273 return true; | 184 return true; |
274 } | 185 } |
275 | 186 |
276 void VaapiWrapper::Deinitialize() { | 187 void VaapiWrapper::Deinitialize() { |
277 base::AutoLock auto_lock(va_lock_); | 188 base::AutoLock auto_lock(va_lock_); |
278 | 189 |
279 if (va_config_id_ != VA_INVALID_ID) { | 190 if (va_config_id_ != VA_INVALID_ID) { |
280 VAStatus va_res = VAAPI_DestroyConfig(va_display_, va_config_id_); | 191 VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_); |
281 VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed"); | 192 VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed"); |
282 } | 193 } |
283 | 194 |
284 if (va_display_) { | 195 if (va_display_) { |
285 VAStatus va_res = VAAPI_Terminate(va_display_); | 196 VAStatus va_res = vaTerminate(va_display_); |
286 VA_LOG_ON_ERROR(va_res, "vaTerminate failed"); | 197 VA_LOG_ON_ERROR(va_res, "vaTerminate failed"); |
287 } | 198 } |
288 | 199 |
289 va_config_id_ = VA_INVALID_ID; | 200 va_config_id_ = VA_INVALID_ID; |
290 va_display_ = NULL; | 201 va_display_ = NULL; |
291 } | 202 } |
292 | 203 |
293 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { | 204 bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { |
294 return (major_version_ < major) || | 205 return (major_version_ < major) || |
295 (major_version_ == major && minor_version_ < minor); | 206 (major_version_ == major && minor_version_ < minor); |
296 } | 207 } |
297 | 208 |
298 bool VaapiWrapper::CreateSurfaces(gfx::Size size, | 209 bool VaapiWrapper::CreateSurfaces(gfx::Size size, |
299 size_t num_surfaces, | 210 size_t num_surfaces, |
300 std::vector<VASurfaceID>* va_surfaces) { | 211 std::vector<VASurfaceID>* va_surfaces) { |
301 base::AutoLock auto_lock(va_lock_); | 212 base::AutoLock auto_lock(va_lock_); |
302 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; | 213 DVLOG(2) << "Creating " << num_surfaces << " surfaces"; |
303 | 214 |
304 DCHECK(va_surfaces->empty()); | 215 DCHECK(va_surfaces->empty()); |
305 DCHECK(va_surface_ids_.empty()); | 216 DCHECK(va_surface_ids_.empty()); |
306 va_surface_ids_.resize(num_surfaces); | 217 va_surface_ids_.resize(num_surfaces); |
307 | 218 |
308 // Allocate surfaces in driver. | 219 // Allocate surfaces in driver. |
309 VAStatus va_res; | 220 VAStatus va_res; |
310 if (VAAPIVersionLessThan(0, 34)) { | 221 if (VAAPIVersionLessThan(0, 34)) { |
(...skipping 13 matching lines...) Expand all Loading... | |
324 NULL, 0); | 235 NULL, 0); |
325 } | 236 } |
326 | 237 |
327 VA_LOG_ON_ERROR(va_res, "vaCreateSurfaces failed"); | 238 VA_LOG_ON_ERROR(va_res, "vaCreateSurfaces failed"); |
328 if (va_res != VA_STATUS_SUCCESS) { | 239 if (va_res != VA_STATUS_SUCCESS) { |
329 va_surface_ids_.clear(); | 240 va_surface_ids_.clear(); |
330 return false; | 241 return false; |
331 } | 242 } |
332 | 243 |
333 // And create a context associated with them. | 244 // And create a context associated with them. |
334 va_res = VAAPI_CreateContext(va_display_, va_config_id_, | 245 va_res = vaCreateContext(va_display_, va_config_id_, |
335 size.width(), size.height(), VA_PROGRESSIVE, | 246 size.width(), size.height(), VA_PROGRESSIVE, |
336 &va_surface_ids_[0], va_surface_ids_.size(), | 247 &va_surface_ids_[0], va_surface_ids_.size(), |
337 &va_context_id_); | 248 &va_context_id_); |
338 | 249 |
339 VA_LOG_ON_ERROR(va_res, "vaCreateContext failed"); | 250 VA_LOG_ON_ERROR(va_res, "vaCreateContext failed"); |
340 if (va_res != VA_STATUS_SUCCESS) { | 251 if (va_res != VA_STATUS_SUCCESS) { |
341 DestroySurfaces(); | 252 DestroySurfaces(); |
342 return false; | 253 return false; |
343 } | 254 } |
344 | 255 |
345 *va_surfaces = va_surface_ids_; | 256 *va_surfaces = va_surface_ids_; |
346 return true; | 257 return true; |
347 } | 258 } |
348 | 259 |
349 void VaapiWrapper::DestroySurfaces() { | 260 void VaapiWrapper::DestroySurfaces() { |
350 base::AutoLock auto_lock(va_lock_); | 261 base::AutoLock auto_lock(va_lock_); |
351 DVLOG(2) << "Destroying " << va_surface_ids_.size() << " surfaces"; | 262 DVLOG(2) << "Destroying " << va_surface_ids_.size() << " surfaces"; |
352 | 263 |
353 if (va_context_id_ != VA_INVALID_ID) { | 264 if (va_context_id_ != VA_INVALID_ID) { |
354 VAStatus va_res = VAAPI_DestroyContext(va_display_, va_context_id_); | 265 VAStatus va_res = vaDestroyContext(va_display_, va_context_id_); |
355 VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed"); | 266 VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed"); |
356 } | 267 } |
357 | 268 |
358 if (!va_surface_ids_.empty()) { | 269 if (!va_surface_ids_.empty()) { |
359 VAStatus va_res = VAAPI_DestroySurfaces(va_display_, &va_surface_ids_[0], | 270 VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], |
360 va_surface_ids_.size()); | 271 va_surface_ids_.size()); |
361 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); | 272 VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); |
362 } | 273 } |
363 | 274 |
364 va_surface_ids_.clear(); | 275 va_surface_ids_.clear(); |
365 va_context_id_ = VA_INVALID_ID; | 276 va_context_id_ = VA_INVALID_ID; |
366 } | 277 } |
367 | 278 |
368 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, | 279 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, |
369 size_t size, | 280 size_t size, |
370 void* buffer) { | 281 void* buffer) { |
371 base::AutoLock auto_lock(va_lock_); | 282 base::AutoLock auto_lock(va_lock_); |
372 | 283 |
373 VABufferID buffer_id; | 284 VABufferID buffer_id; |
374 VAStatus va_res = VAAPI_CreateBuffer(va_display_, va_context_id_, | 285 VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, |
375 va_buffer_type, size, | 286 va_buffer_type, size, |
376 1, buffer, &buffer_id); | 287 1, buffer, &buffer_id); |
377 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); | 288 VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); |
378 | 289 |
379 switch (va_buffer_type) { | 290 switch (va_buffer_type) { |
380 case VASliceParameterBufferType: | 291 case VASliceParameterBufferType: |
381 case VASliceDataBufferType: | 292 case VASliceDataBufferType: |
382 pending_slice_bufs_.push_back(buffer_id); | 293 pending_slice_bufs_.push_back(buffer_id); |
383 break; | 294 break; |
384 | 295 |
385 default: | 296 default: |
386 pending_va_bufs_.push_back(buffer_id); | 297 pending_va_bufs_.push_back(buffer_id); |
387 break; | 298 break; |
388 } | 299 } |
389 | 300 |
390 return true; | 301 return true; |
391 } | 302 } |
392 | 303 |
393 void VaapiWrapper::DestroyPendingBuffers() { | 304 void VaapiWrapper::DestroyPendingBuffers() { |
394 base::AutoLock auto_lock(va_lock_); | 305 base::AutoLock auto_lock(va_lock_); |
395 | 306 |
396 for (size_t i = 0; i < pending_va_bufs_.size(); ++i) { | 307 for (size_t i = 0; i < pending_va_bufs_.size(); ++i) { |
397 VAStatus va_res = VAAPI_DestroyBuffer(va_display_, pending_va_bufs_[i]); | 308 VAStatus va_res = vaDestroyBuffer(va_display_, pending_va_bufs_[i]); |
398 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); | 309 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
399 } | 310 } |
400 | 311 |
401 for (size_t i = 0; i < pending_slice_bufs_.size(); ++i) { | 312 for (size_t i = 0; i < pending_slice_bufs_.size(); ++i) { |
402 VAStatus va_res = VAAPI_DestroyBuffer(va_display_, pending_slice_bufs_[i]); | 313 VAStatus va_res = vaDestroyBuffer(va_display_, pending_slice_bufs_[i]); |
403 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); | 314 VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
404 } | 315 } |
405 | 316 |
406 pending_va_bufs_.clear(); | 317 pending_va_bufs_.clear(); |
407 pending_slice_bufs_.clear(); | 318 pending_slice_bufs_.clear(); |
408 } | 319 } |
409 | 320 |
410 bool VaapiWrapper::SubmitDecode(VASurfaceID va_surface_id) { | 321 bool VaapiWrapper::SubmitDecode(VASurfaceID va_surface_id) { |
411 base::AutoLock auto_lock(va_lock_); | 322 base::AutoLock auto_lock(va_lock_); |
412 | 323 |
413 DVLOG(4) << "Pending VA bufs to commit: " << pending_va_bufs_.size(); | 324 DVLOG(4) << "Pending VA bufs to commit: " << pending_va_bufs_.size(); |
414 DVLOG(4) << "Pending slice bufs to commit: " << pending_slice_bufs_.size(); | 325 DVLOG(4) << "Pending slice bufs to commit: " << pending_slice_bufs_.size(); |
415 DVLOG(4) << "Decoding into VA surface " << va_surface_id; | 326 DVLOG(4) << "Decoding into VA surface " << va_surface_id; |
416 | 327 |
417 // Get ready to decode into surface. | 328 // Get ready to decode into surface. |
418 VAStatus va_res = VAAPI_BeginPicture(va_display_, va_context_id_, | 329 VAStatus va_res = vaBeginPicture(va_display_, va_context_id_, |
419 va_surface_id); | 330 va_surface_id); |
420 VA_SUCCESS_OR_RETURN(va_res, "vaBeginPicture failed", false); | 331 VA_SUCCESS_OR_RETURN(va_res, "vaBeginPicture failed", false); |
421 | 332 |
422 // Commit parameter and slice buffers. | 333 // Commit parameter and slice buffers. |
423 va_res = VAAPI_RenderPicture(va_display_, va_context_id_, | 334 va_res = vaRenderPicture(va_display_, va_context_id_, |
424 &pending_va_bufs_[0], pending_va_bufs_.size()); | 335 &pending_va_bufs_[0], pending_va_bufs_.size()); |
425 VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for va_bufs failed", false); | 336 VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for va_bufs failed", false); |
426 | 337 |
427 va_res = VAAPI_RenderPicture(va_display_, va_context_id_, | 338 va_res = vaRenderPicture(va_display_, va_context_id_, |
428 &pending_slice_bufs_[0], | 339 &pending_slice_bufs_[0], |
429 pending_slice_bufs_.size()); | 340 pending_slice_bufs_.size()); |
430 VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for slices failed", false); | 341 VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for slices failed", false); |
431 | 342 |
432 // Instruct HW decoder to start processing committed buffers (decode this | 343 // Instruct HW decoder to start processing committed buffers (decode this |
433 // picture). This does not block until the end of decode. | 344 // picture). This does not block until the end of decode. |
434 va_res = VAAPI_EndPicture(va_display_, va_context_id_); | 345 va_res = vaEndPicture(va_display_, va_context_id_); |
435 VA_SUCCESS_OR_RETURN(va_res, "vaEndPicture failed", false); | 346 VA_SUCCESS_OR_RETURN(va_res, "vaEndPicture failed", false); |
436 | 347 |
437 return true; | 348 return true; |
438 } | 349 } |
439 | 350 |
440 bool VaapiWrapper::DecodeAndDestroyPendingBuffers(VASurfaceID va_surface_id) { | 351 bool VaapiWrapper::DecodeAndDestroyPendingBuffers(VASurfaceID va_surface_id) { |
441 bool result = SubmitDecode(va_surface_id); | 352 bool result = SubmitDecode(va_surface_id); |
442 DestroyPendingBuffers(); | 353 DestroyPendingBuffers(); |
443 return result; | 354 return result; |
444 } | 355 } |
445 | 356 |
446 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, | 357 bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, |
447 Pixmap x_pixmap, | 358 Pixmap x_pixmap, |
448 gfx::Size dest_size) { | 359 gfx::Size dest_size) { |
449 base::AutoLock auto_lock(va_lock_); | 360 base::AutoLock auto_lock(va_lock_); |
450 | 361 |
451 VAStatus va_res = VAAPI_SyncSurface(va_display_, va_surface_id); | 362 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
452 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 363 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
453 | 364 |
454 // Put the data into an X Pixmap. | 365 // Put the data into an X Pixmap. |
455 va_res = VAAPI_PutSurface(va_display_, | 366 va_res = vaPutSurface(va_display_, |
456 va_surface_id, | 367 va_surface_id, |
457 x_pixmap, | 368 x_pixmap, |
458 0, 0, dest_size.width(), dest_size.height(), | 369 0, 0, dest_size.width(), dest_size.height(), |
459 0, 0, dest_size.width(), dest_size.height(), | 370 0, 0, dest_size.width(), dest_size.height(), |
460 NULL, 0, 0); | 371 NULL, 0, 0); |
461 VA_SUCCESS_OR_RETURN(va_res, "Failed putting decode surface to pixmap", | 372 VA_SUCCESS_OR_RETURN(va_res, "Failed putting decode surface to pixmap", |
462 false); | 373 false); |
463 return true; | 374 return true; |
464 } | 375 } |
465 | 376 |
466 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, | 377 bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, |
467 VAImage* image, | 378 VAImage* image, |
468 void** mem) { | 379 void** mem) { |
469 base::AutoLock auto_lock(va_lock_); | 380 base::AutoLock auto_lock(va_lock_); |
470 | 381 |
471 VAStatus va_res = VAAPI_SyncSurface(va_display_, va_surface_id); | 382 VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
472 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | 383 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
473 | 384 |
474 // Derive a VAImage from the VASurface | 385 // Derive a VAImage from the VASurface |
475 va_res = VAAPI_DeriveImage(va_display_, va_surface_id, image); | 386 va_res = vaDeriveImage(va_display_, va_surface_id, image); |
476 VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed"); | 387 VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed"); |
477 if (va_res != VA_STATUS_SUCCESS) | 388 if (va_res != VA_STATUS_SUCCESS) |
478 return false; | 389 return false; |
479 | 390 |
480 // Map the VAImage into memory | 391 // Map the VAImage into memory |
481 va_res = VAAPI_MapBuffer(va_display_, image->buf, mem); | 392 va_res = vaMapBuffer(va_display_, image->buf, mem); |
482 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); | 393 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); |
483 if (va_res == VA_STATUS_SUCCESS) | 394 if (va_res == VA_STATUS_SUCCESS) |
484 return true; | 395 return true; |
485 | 396 |
486 VAAPI_DestroyImage(va_display_, image->image_id); | 397 vaDestroyImage(va_display_, image->image_id); |
487 return false; | 398 return false; |
488 } | 399 } |
489 | 400 |
490 void VaapiWrapper::ReturnVaImageForTesting(VAImage* image) { | 401 void VaapiWrapper::ReturnVaImageForTesting(VAImage* image) { |
491 base::AutoLock auto_lock(va_lock_); | 402 base::AutoLock auto_lock(va_lock_); |
492 | 403 |
493 VAAPI_UnmapBuffer(va_display_, image->buf); | 404 vaUnmapBuffer(va_display_, image->buf); |
494 VAAPI_DestroyImage(va_display_, image->image_id); | 405 vaDestroyImage(va_display_, image->image_id); |
495 } | 406 } |
496 | 407 |
497 // static | 408 // static |
498 bool VaapiWrapper::PostSandboxInitialization() { | 409 bool VaapiWrapper::PostSandboxInitialization() { |
499 vaapi_handle = dlopen("libva.so.1", RTLD_NOW); | 410 vaapi_handle = dlopen("libva.so.1", RTLD_NOW); |
500 vaapi_x11_handle = dlopen("libva-x11.so.1", RTLD_NOW); | 411 if (!vaapi_handle) |
412 return false; | |
501 | 413 |
502 if (!vaapi_handle || !vaapi_x11_handle) | 414 // TODO(halton): Abondon dlsym for vaCreateSurfaces when support for |
503 return false; | 415 // VAAPI < 0.34 is not needed. |
504 #define VAAPI_DLSYM_OR_RETURN_ON_ERROR(name, handle) \ | 416 #define VAAPI_DLSYM_OR_RETURN_BOOL_ON_ERROR(name, handle) \ |
505 do { \ | 417 do { \ |
506 VAAPI_##name = reinterpret_cast<Vaapi##name>(dlsym((handle), "va"#name)); \ | 418 VAAPI_##name = reinterpret_cast<Vaapi##name>(dlsym((handle), "va"#name)); \ |
507 if (VAAPI_##name == NULL) { \ | 419 if (VAAPI_##name == NULL) { \ |
508 DVLOG(1) << "Failed to dlsym va"#name; \ | 420 DVLOG(1) << "Failed to dlsym va"#name; \ |
509 return false; \ | 421 return false; \ |
510 } \ | 422 } \ |
511 } while (0) | 423 } while (0) |
512 | 424 |
513 VAAPI_DLSYM_OR_RETURN_ON_ERROR(BeginPicture, vaapi_handle); | 425 VAAPI_DLSYM_OR_RETURN_BOOL_ON_ERROR(CreateSurfaces, vaapi_handle); |
514 VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateBuffer, vaapi_handle); | |
515 VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateConfig, vaapi_handle); | |
516 VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateContext, vaapi_handle); | |
517 VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateSurfaces, vaapi_handle); | |
518 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DeriveImage, vaapi_handle); | |
519 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyBuffer, vaapi_handle); | |
520 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyConfig, vaapi_handle); | |
521 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyContext, vaapi_handle); | |
522 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyImage, vaapi_handle); | |
523 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroySurfaces, vaapi_handle); | |
524 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DisplayIsValid, vaapi_handle); | |
525 VAAPI_DLSYM_OR_RETURN_ON_ERROR(EndPicture, vaapi_handle); | |
526 VAAPI_DLSYM_OR_RETURN_ON_ERROR(ErrorStr, vaapi_handle); | |
527 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetConfigAttributes, vaapi_handle); | |
528 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetDisplay, vaapi_x11_handle); | |
529 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Initialize, vaapi_handle); | |
530 VAAPI_DLSYM_OR_RETURN_ON_ERROR(MapBuffer, vaapi_handle); | |
531 VAAPI_DLSYM_OR_RETURN_ON_ERROR(PutSurface, vaapi_x11_handle); | |
532 VAAPI_DLSYM_OR_RETURN_ON_ERROR(RenderPicture, vaapi_handle); | |
533 VAAPI_DLSYM_OR_RETURN_ON_ERROR(SetDisplayAttributes, vaapi_handle); | |
534 VAAPI_DLSYM_OR_RETURN_ON_ERROR(SyncSurface, vaapi_handle); | |
535 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Terminate, vaapi_handle); | |
536 VAAPI_DLSYM_OR_RETURN_ON_ERROR(UnmapBuffer, vaapi_handle); | |
537 #undef VAAPI_DLSYM | |
538 | 426 |
539 return true; | 427 #undef VAAPI_DLSYM_OR_RETURN_ON_ERROR |
428 | |
429 StubPathMap paths; | |
430 paths[kModuleVa].push_back(kVaLib); | |
431 | |
432 return InitializeStubs(paths); | |
540 } | 433 } |
541 | 434 |
542 } // namespace content | 435 } // namespace content |
OLD | NEW |