Chromium Code Reviews| Index: content/common/gpu/media/vaapi_wrapper.cc |
| diff --git a/content/common/gpu/media/vaapi_wrapper.cc b/content/common/gpu/media/vaapi_wrapper.cc |
| index 290dec8186e3604a226168d17295c98671d57fed..7bad0c5b91e5f1c423d551948d6f3209c6c6c113 100644 |
| --- a/content/common/gpu/media/vaapi_wrapper.cc |
| +++ b/content/common/gpu/media/vaapi_wrapper.cc |
| @@ -2,16 +2,26 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| +#include "content/common/gpu/media/vaapi_wrapper.h" |
| + |
| #include <dlfcn.h> |
| #include "base/bind.h" |
| #include "base/logging.h" |
| -#include "content/common/gpu/media/vaapi_wrapper.h" |
| +#include "common/gpu/media/va_stubs.h" |
| + |
| +using common_gpu_media::kModuleVa; |
| +using common_gpu_media::InitializeStubs; |
| +using common_gpu_media::StubPathMap; |
| + |
| +// libva-x11 depend on libva, so dlopen libva-x11 is enough |
| +static const base::FilePath::CharType kVaLib[] = |
| + FILE_PATH_LITERAL("libva-x11.so.1"); |
| #define LOG_VA_ERROR_AND_REPORT(va_error, err_msg) \ |
| do { \ |
| DVLOG(1) << err_msg \ |
| - << " VA error: " << VAAPI_ErrorStr(va_error); \ |
| + << " VA error: " << vaErrorStr(va_error); \ |
| report_error_to_uma_cb_.Run(); \ |
| } while (0) |
| @@ -31,128 +41,29 @@ |
| namespace content { |
| -static void *vaapi_handle = NULL; |
| -static void *vaapi_x11_handle = NULL; |
| - |
| -typedef VAStatus (*VaapiBeginPicture)(VADisplay dpy, |
| - VAContextID context, |
| - VASurfaceID render_target); |
| -typedef VAStatus (*VaapiCreateBuffer)(VADisplay dpy, |
| - VAContextID context, |
| - VABufferType type, |
| - unsigned int size, |
| - unsigned int num_elements, |
| - void *data, |
| - VABufferID *buf_id); |
| -typedef VAStatus (*VaapiCreateConfig)(VADisplay dpy, |
| - VAProfile profile, |
| - VAEntrypoint entrypoint, |
| - VAConfigAttrib *attrib_list, |
| - int num_attribs, |
| - VAConfigID *config_id); |
| -typedef VAStatus (*VaapiCreateContext)(VADisplay dpy, |
| - VAConfigID config_id, |
| - int picture_width, |
| - int picture_height, |
| - int flag, |
| - VASurfaceID *render_targets, |
| - int num_render_targets, |
| - VAContextID *context); |
| // In VAAPI version < 0.34, vaCreateSurface has 6 parameters, but in VAAPI |
| // version >= 0.34, vaCreateSurface has 8 parameters. |
| // 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.
|
| -typedef void *VaapiCreateSurfaces; |
| +static void* vaapi_handle = NULL; |
| + |
| +typedef void* VaapiCreateSurfaces; |
| typedef VAStatus (*VaapiCreateSurfaces6)(VADisplay dpy, |
| int width, |
| int height, |
| int format, |
| int num_surfaces, |
| - VASurfaceID *surfaces); |
| + VASurfaceID* surfaces); |
| typedef VAStatus (*VaapiCreateSurfaces8)(VADisplay dpy, |
| unsigned int format, |
| unsigned int width, |
| unsigned int height, |
| - VASurfaceID *surfaces, |
| + VASurfaceID* surfaces, |
| unsigned int num_surfaces, |
| - VASurfaceAttrib *attrib_list, |
| + VASurfaceAttrib* attrib_list, |
| unsigned int num_attribs); |
| -typedef VAStatus (*VaapiDeriveImage)(VADisplay dpy, |
| - VASurfaceID surface, |
| - VAImage* image); |
| -typedef VAStatus (*VaapiDestroyBuffer)(VADisplay dpy, VABufferID buffer_id); |
| -typedef VAStatus (*VaapiDestroyConfig)(VADisplay dpy, VAConfigID config_id); |
| -typedef VAStatus (*VaapiDestroyContext)(VADisplay dpy, VAContextID context); |
| -typedef VAStatus (*VaapiDestroyImage)(VADisplay dpy, VAImageID image); |
| -typedef VAStatus (*VaapiDestroySurfaces)(VADisplay dpy, |
| - VASurfaceID *surfaces, |
| - int num_surfaces); |
| -typedef int (*VaapiDisplayIsValid)(VADisplay dpy); |
| -typedef VAStatus (*VaapiEndPicture)(VADisplay dpy, VAContextID context); |
| -typedef const char* (*VaapiErrorStr)(VAStatus error_status); |
| -typedef VAStatus (*VaapiGetConfigAttributes)(VADisplay dpy, |
| - VAProfile profile, |
| - VAEntrypoint entrypoint, |
| - VAConfigAttrib *attrib_list, |
| - int num_attribs); |
| -typedef VADisplay (*VaapiGetDisplay)(Display *dpy); |
| -typedef VAStatus (*VaapiInitialize)(VADisplay dpy, |
| - int *major_version, |
| - int *minor_version); |
| -typedef VAStatus (*VaapiMapBuffer)(VADisplay dpy, |
| - VABufferID buf_id, |
| - void** pbuf); |
| -typedef VAStatus (*VaapiPutSurface)(VADisplay dpy, |
| - VASurfaceID surface, |
| - Drawable draw, |
| - short srcx, |
| - short srcy, |
| - unsigned short srcw, |
| - unsigned short srch, |
| - short destx, |
| - short desty, |
| - unsigned short destw, |
| - unsigned short desth, |
| - VARectangle *cliprects, |
| - unsigned int number_cliprects, |
| - unsigned int flags); |
| -typedef VAStatus (*VaapiRenderPicture)(VADisplay dpy, |
| - VAContextID context, |
| - VABufferID *buffers, |
| - int num_buffers); |
| -typedef VAStatus (*VaapiSetDisplayAttributes)(VADisplay dpy, |
| - VADisplayAttribute *type, |
| - int num_attributes); |
| -typedef VAStatus (*VaapiSyncSurface)(VADisplay dpy, VASurfaceID render_target); |
| -typedef VAStatus (*VaapiTerminate)(VADisplay dpy); |
| -typedef VAStatus (*VaapiUnmapBuffer)(VADisplay dpy, VABufferID buf_id); |
| #define VAAPI_SYM(name, handle) Vaapi##name VAAPI_##name = NULL |
| - |
| -VAAPI_SYM(BeginPicture, vaapi_handle); |
| -VAAPI_SYM(CreateBuffer, vaapi_handle); |
| -VAAPI_SYM(CreateConfig, vaapi_handle); |
| -VAAPI_SYM(CreateContext, vaapi_handle); |
| VAAPI_SYM(CreateSurfaces, vaapi_handle); |
| -VAAPI_SYM(DeriveImage, vaapi_handle); |
| -VAAPI_SYM(DestroyBuffer, vaapi_handle); |
| -VAAPI_SYM(DestroyConfig, vaapi_handle); |
| -VAAPI_SYM(DestroyContext, vaapi_handle); |
| -VAAPI_SYM(DestroyImage, vaapi_handle); |
| -VAAPI_SYM(DestroySurfaces, vaapi_handle); |
| -VAAPI_SYM(DisplayIsValid, vaapi_handle); |
| -VAAPI_SYM(EndPicture, vaapi_handle); |
| -VAAPI_SYM(ErrorStr, vaapi_handle); |
| -VAAPI_SYM(GetConfigAttributes, vaapi_handle); |
| -VAAPI_SYM(GetDisplay, vaapi_x11_handle); |
| -VAAPI_SYM(Initialize, vaapi_handle); |
| -VAAPI_SYM(MapBuffer, vaapi_handle); |
| -VAAPI_SYM(PutSurface, vaapi_x11_handle); |
| -VAAPI_SYM(RenderPicture, vaapi_handle); |
| -VAAPI_SYM(SetDisplayAttributes, vaapi_handle); |
| -VAAPI_SYM(SyncSurface, vaapi_x11_handle); |
| -VAAPI_SYM(Terminate, vaapi_handle); |
| -VAAPI_SYM(UnmapBuffer, vaapi_handle); |
| - |
| #undef VAAPI_SYM |
| // Maps Profile enum values to VaProfile values. |
| @@ -217,9 +128,9 @@ void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() { |
| VA_RENDER_MODE_LOCAL_GPU, |
| VA_DISPLAY_ATTRIB_SETTABLE}; |
| - VAStatus va_res = VAAPI_SetDisplayAttributes(va_display_, &item, 1); |
| + VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1); |
| if (va_res != VA_STATUS_SUCCESS) |
| - DVLOG(2) << "VAAPI_SetDisplayAttributes unsupported, ignoring by default."; |
| + DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default."; |
| } |
| bool VaapiWrapper::Initialize(media::VideoCodecProfile profile, |
| @@ -241,22 +152,22 @@ bool VaapiWrapper::Initialize(media::VideoCodecProfile profile, |
| return false; |
| } |
| - va_display_ = VAAPI_GetDisplay(x_display); |
| - if (!VAAPI_DisplayIsValid(va_display_)) { |
| + va_display_ = vaGetDisplay(x_display); |
| + if (!vaDisplayIsValid(va_display_)) { |
| DVLOG(1) << "Could not get a valid VA display"; |
| return false; |
| } |
| VAStatus va_res; |
| - va_res = VAAPI_Initialize(va_display_, &major_version_, &minor_version_); |
| + va_res = vaInitialize(va_display_, &major_version_, &minor_version_); |
| VA_SUCCESS_OR_RETURN(va_res, "vaInitialize failed", false); |
| DVLOG(1) << "VAAPI version: " << major_version_ << "." << minor_version_; |
| VAConfigAttrib attrib = {VAConfigAttribRTFormat, 0}; |
| const VAEntrypoint kEntrypoint = VAEntrypointVLD; |
| - va_res = VAAPI_GetConfigAttributes(va_display_, va_profile, kEntrypoint, |
| - &attrib, 1); |
| + va_res = vaGetConfigAttributes(va_display_, va_profile, kEntrypoint, |
| + &attrib, 1); |
| VA_SUCCESS_OR_RETURN(va_res, "vaGetConfigAttributes failed", false); |
| if (!(attrib.value & VA_RT_FORMAT_YUV420)) { |
| @@ -266,8 +177,8 @@ bool VaapiWrapper::Initialize(media::VideoCodecProfile profile, |
| TryToSetVADisplayAttributeToLocalGPU(); |
| - va_res = VAAPI_CreateConfig(va_display_, va_profile, kEntrypoint, |
| - &attrib, 1, &va_config_id_); |
| + va_res = vaCreateConfig(va_display_, va_profile, kEntrypoint, |
| + &attrib, 1, &va_config_id_); |
| VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false); |
| return true; |
| @@ -277,12 +188,12 @@ void VaapiWrapper::Deinitialize() { |
| base::AutoLock auto_lock(va_lock_); |
| if (va_config_id_ != VA_INVALID_ID) { |
| - VAStatus va_res = VAAPI_DestroyConfig(va_display_, va_config_id_); |
| + VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_); |
| VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed"); |
| } |
| if (va_display_) { |
| - VAStatus va_res = VAAPI_Terminate(va_display_); |
| + VAStatus va_res = vaTerminate(va_display_); |
| VA_LOG_ON_ERROR(va_res, "vaTerminate failed"); |
| } |
| @@ -297,7 +208,7 @@ bool VaapiWrapper::VAAPIVersionLessThan(int major, int minor) { |
| bool VaapiWrapper::CreateSurfaces(gfx::Size size, |
| size_t num_surfaces, |
| - std::vector<VASurfaceID>* va_surfaces) { |
| + std::vector<VASurfaceID>* va_surfaces) { |
| base::AutoLock auto_lock(va_lock_); |
| DVLOG(2) << "Creating " << num_surfaces << " surfaces"; |
| @@ -331,10 +242,10 @@ bool VaapiWrapper::CreateSurfaces(gfx::Size size, |
| } |
| // And create a context associated with them. |
| - va_res = VAAPI_CreateContext(va_display_, va_config_id_, |
| - size.width(), size.height(), VA_PROGRESSIVE, |
| - &va_surface_ids_[0], va_surface_ids_.size(), |
| - &va_context_id_); |
| + va_res = vaCreateContext(va_display_, va_config_id_, |
| + size.width(), size.height(), VA_PROGRESSIVE, |
| + &va_surface_ids_[0], va_surface_ids_.size(), |
| + &va_context_id_); |
| VA_LOG_ON_ERROR(va_res, "vaCreateContext failed"); |
| if (va_res != VA_STATUS_SUCCESS) { |
| @@ -351,13 +262,13 @@ void VaapiWrapper::DestroySurfaces() { |
| DVLOG(2) << "Destroying " << va_surface_ids_.size() << " surfaces"; |
| if (va_context_id_ != VA_INVALID_ID) { |
| - VAStatus va_res = VAAPI_DestroyContext(va_display_, va_context_id_); |
| + VAStatus va_res = vaDestroyContext(va_display_, va_context_id_); |
| VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed"); |
| } |
| if (!va_surface_ids_.empty()) { |
| - VAStatus va_res = VAAPI_DestroySurfaces(va_display_, &va_surface_ids_[0], |
| - va_surface_ids_.size()); |
| + VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0], |
| + va_surface_ids_.size()); |
| VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed"); |
| } |
| @@ -371,9 +282,9 @@ bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type, |
| base::AutoLock auto_lock(va_lock_); |
| VABufferID buffer_id; |
| - VAStatus va_res = VAAPI_CreateBuffer(va_display_, va_context_id_, |
| - va_buffer_type, size, |
| - 1, buffer, &buffer_id); |
| + VAStatus va_res = vaCreateBuffer(va_display_, va_context_id_, |
| + va_buffer_type, size, |
| + 1, buffer, &buffer_id); |
| VA_SUCCESS_OR_RETURN(va_res, "Failed to create a VA buffer", false); |
| switch (va_buffer_type) { |
| @@ -394,12 +305,12 @@ void VaapiWrapper::DestroyPendingBuffers() { |
| base::AutoLock auto_lock(va_lock_); |
| for (size_t i = 0; i < pending_va_bufs_.size(); ++i) { |
| - VAStatus va_res = VAAPI_DestroyBuffer(va_display_, pending_va_bufs_[i]); |
| + VAStatus va_res = vaDestroyBuffer(va_display_, pending_va_bufs_[i]); |
| VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
| } |
| for (size_t i = 0; i < pending_slice_bufs_.size(); ++i) { |
| - VAStatus va_res = VAAPI_DestroyBuffer(va_display_, pending_slice_bufs_[i]); |
| + VAStatus va_res = vaDestroyBuffer(va_display_, pending_slice_bufs_[i]); |
| VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed"); |
| } |
| @@ -415,23 +326,23 @@ bool VaapiWrapper::SubmitDecode(VASurfaceID va_surface_id) { |
| DVLOG(4) << "Decoding into VA surface " << va_surface_id; |
| // Get ready to decode into surface. |
| - VAStatus va_res = VAAPI_BeginPicture(va_display_, va_context_id_, |
| - va_surface_id); |
| + VAStatus va_res = vaBeginPicture(va_display_, va_context_id_, |
| + va_surface_id); |
| VA_SUCCESS_OR_RETURN(va_res, "vaBeginPicture failed", false); |
| // Commit parameter and slice buffers. |
| - va_res = VAAPI_RenderPicture(va_display_, va_context_id_, |
| - &pending_va_bufs_[0], pending_va_bufs_.size()); |
| + va_res = vaRenderPicture(va_display_, va_context_id_, |
| + &pending_va_bufs_[0], pending_va_bufs_.size()); |
| VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for va_bufs failed", false); |
| - va_res = VAAPI_RenderPicture(va_display_, va_context_id_, |
| - &pending_slice_bufs_[0], |
| - pending_slice_bufs_.size()); |
| + va_res = vaRenderPicture(va_display_, va_context_id_, |
| + &pending_slice_bufs_[0], |
| + pending_slice_bufs_.size()); |
| VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for slices failed", false); |
| // Instruct HW decoder to start processing committed buffers (decode this |
| // picture). This does not block until the end of decode. |
| - va_res = VAAPI_EndPicture(va_display_, va_context_id_); |
| + va_res = vaEndPicture(va_display_, va_context_id_); |
| VA_SUCCESS_OR_RETURN(va_res, "vaEndPicture failed", false); |
| return true; |
| @@ -448,16 +359,16 @@ bool VaapiWrapper::PutSurfaceIntoPixmap(VASurfaceID va_surface_id, |
| gfx::Size dest_size) { |
| base::AutoLock auto_lock(va_lock_); |
| - VAStatus va_res = VAAPI_SyncSurface(va_display_, va_surface_id); |
| + VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
| VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
| // Put the data into an X Pixmap. |
| - va_res = VAAPI_PutSurface(va_display_, |
| - va_surface_id, |
| - x_pixmap, |
| - 0, 0, dest_size.width(), dest_size.height(), |
| - 0, 0, dest_size.width(), dest_size.height(), |
| - NULL, 0, 0); |
| + va_res = vaPutSurface(va_display_, |
| + va_surface_id, |
| + x_pixmap, |
| + 0, 0, dest_size.width(), dest_size.height(), |
| + 0, 0, dest_size.width(), dest_size.height(), |
| + NULL, 0, 0); |
| VA_SUCCESS_OR_RETURN(va_res, "Failed putting decode surface to pixmap", |
| false); |
| return true; |
| @@ -468,40 +379,41 @@ bool VaapiWrapper::GetVaImageForTesting(VASurfaceID va_surface_id, |
| void** mem) { |
| base::AutoLock auto_lock(va_lock_); |
| - VAStatus va_res = VAAPI_SyncSurface(va_display_, va_surface_id); |
| + VAStatus va_res = vaSyncSurface(va_display_, va_surface_id); |
| VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); |
| // Derive a VAImage from the VASurface |
| - va_res = VAAPI_DeriveImage(va_display_, va_surface_id, image); |
| + va_res = vaDeriveImage(va_display_, va_surface_id, image); |
| VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed"); |
| if (va_res != VA_STATUS_SUCCESS) |
| return false; |
| // Map the VAImage into memory |
| - va_res = VAAPI_MapBuffer(va_display_, image->buf, mem); |
| + va_res = vaMapBuffer(va_display_, image->buf, mem); |
| VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); |
| if (va_res == VA_STATUS_SUCCESS) |
| return true; |
| - VAAPI_DestroyImage(va_display_, image->image_id); |
| + vaDestroyImage(va_display_, image->image_id); |
| return false; |
| } |
| void VaapiWrapper::ReturnVaImageForTesting(VAImage* image) { |
| base::AutoLock auto_lock(va_lock_); |
| - VAAPI_UnmapBuffer(va_display_, image->buf); |
| - VAAPI_DestroyImage(va_display_, image->image_id); |
| + vaUnmapBuffer(va_display_, image->buf); |
| + vaDestroyImage(va_display_, image->image_id); |
| } |
| // static |
| bool VaapiWrapper::PostSandboxInitialization() { |
| vaapi_handle = dlopen("libva.so.1", RTLD_NOW); |
| - vaapi_x11_handle = dlopen("libva-x11.so.1", RTLD_NOW); |
| - |
| - if (!vaapi_handle || !vaapi_x11_handle) |
| + if (!vaapi_handle) |
| return false; |
| -#define VAAPI_DLSYM_OR_RETURN_ON_ERROR(name, handle) \ |
| + |
| +// TODO(halton): Abondon dlsym for vaCreateSurfaces when support for |
| +// VAAPI < 0.34 is not needed. |
| +#define VAAPI_DLSYM_OR_RETURN_BOOL_ON_ERROR(name, handle) \ |
| do { \ |
| VAAPI_##name = reinterpret_cast<Vaapi##name>(dlsym((handle), "va"#name)); \ |
| if (VAAPI_##name == NULL) { \ |
| @@ -510,33 +422,14 @@ bool VaapiWrapper::PostSandboxInitialization() { |
| } \ |
| } while (0) |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(BeginPicture, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateBuffer, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateConfig, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateContext, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateSurfaces, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(DeriveImage, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyBuffer, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyConfig, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyContext, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyImage, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroySurfaces, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(DisplayIsValid, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(EndPicture, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(ErrorStr, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetConfigAttributes, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetDisplay, vaapi_x11_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(Initialize, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(MapBuffer, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(PutSurface, vaapi_x11_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(RenderPicture, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(SetDisplayAttributes, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(SyncSurface, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(Terminate, vaapi_handle); |
| - VAAPI_DLSYM_OR_RETURN_ON_ERROR(UnmapBuffer, vaapi_handle); |
| -#undef VAAPI_DLSYM |
| +VAAPI_DLSYM_OR_RETURN_BOOL_ON_ERROR(CreateSurfaces, vaapi_handle); |
| - return true; |
| +#undef VAAPI_DLSYM_OR_RETURN_ON_ERROR |
| + |
| + StubPathMap paths; |
| + paths[kModuleVa].push_back(kVaLib); |
| + |
| + return InitializeStubs(paths); |
| } |
| } // namespace content |