From d254e7e05b9e0b54c0e04eaa6c4a8b1bc2ca7310 Mon Sep 17 00:00:00 2001 From: "fischman@chromium.org" Date: Sat, 4 Aug 2012 08:38:10 +0000 Subject: Only dlopen() OMX/VAAPI libs in the GPU process, and only lazily dlsym() their symbols. This reinstates r150007, which was reverted in r150009. TBR=piman@chromium.org BUG=140412 Review URL: https://chromiumcodereview.appspot.com/10827173 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150024 0039d316-1c4b-4281-b951-d872f2087c98 --- .../gpu/media/omx_video_decode_accelerator.cc | 55 ++++++--- .../gpu/media/omx_video_decode_accelerator.h | 10 ++ content/common/gpu/media/vaapi_h264_decoder.cc | 135 +++++++++++++-------- content/common/gpu/media/vaapi_h264_decoder.h | 10 ++ .../gpu/media/vaapi_video_decode_accelerator.cc | 14 +++ .../gpu/media/vaapi_video_decode_accelerator.h | 9 +- .../gpu/media/video_decode_accelerator_unittest.cc | 4 + content/content_gpu.gypi | 10 ++ content/gpu/gpu_main.cc | 10 ++ 9 files changed, 186 insertions(+), 71 deletions(-) (limited to 'content') diff --git a/content/common/gpu/media/omx_video_decode_accelerator.cc b/content/common/gpu/media/omx_video_decode_accelerator.cc index 57fe2fd..de86219 100644 --- a/content/common/gpu/media/omx_video_decode_accelerator.cc +++ b/content/common/gpu/media/omx_video_decode_accelerator.cc @@ -21,8 +21,7 @@ typedef std::pair, int32> SharedMemoryAndId; enum { kNumPictureBuffers = 4 }; -// Open the libOmxCore here for now. -void* omx_handle = dlopen("libOmxCore.so", RTLD_NOW); +void* omx_handle = NULL; typedef OMX_ERRORTYPE (*OMXInit)(); typedef OMX_ERRORTYPE (*OMXGetHandle)( @@ -31,21 +30,11 @@ typedef OMX_ERRORTYPE (*OMXGetComponentsOfRole)(OMX_STRING, OMX_U32*, OMX_U8**); typedef OMX_ERRORTYPE (*OMXFreeHandle)(OMX_HANDLETYPE); typedef OMX_ERRORTYPE (*OMXDeinit)(); -OMXInit omx_init = reinterpret_cast(dlsym(omx_handle, "OMX_Init")); -OMXGetHandle omx_gethandle = - reinterpret_cast(dlsym(omx_handle, "OMX_GetHandle")); -OMXGetComponentsOfRole omx_get_components_of_role = - reinterpret_cast( - dlsym(omx_handle, "OMX_GetComponentsOfRole")); -OMXFreeHandle omx_free_handle = - reinterpret_cast(dlsym(omx_handle, "OMX_FreeHandle")); -OMXDeinit omx_deinit = - reinterpret_cast(dlsym(omx_handle, "OMX_Deinit")); - -static bool AreOMXFunctionPointersInitialized() { - return (omx_init && omx_gethandle && omx_get_components_of_role && - omx_free_handle && omx_deinit); -} +OMXInit omx_init = NULL; +OMXGetHandle omx_gethandle = NULL; +OMXGetComponentsOfRole omx_get_components_of_role = NULL; +OMXFreeHandle omx_free_handle = NULL; +OMXDeinit omx_deinit = NULL; // Maps h264-related Profile enum values to OMX_VIDEO_AVCPROFILETYPE values. static OMX_U32 MapH264ProfileToOMXAVCProfile(uint32 profile) { @@ -97,6 +86,9 @@ static OMX_U32 MapH264ProfileToOMXAVCProfile(uint32 profile) { log << ", OMX result: 0x" << std::hex << omx_result, \ error, ret_val) +// static +bool OmxVideoDecodeAccelerator::pre_sandbox_init_done_ = false; + OmxVideoDecodeAccelerator::OmxVideoDecodeAccelerator( EGLDisplay egl_display, EGLContext egl_context, media::VideoDecodeAccelerator::Client* client) @@ -118,7 +110,8 @@ OmxVideoDecodeAccelerator::OmxVideoDecodeAccelerator( codec_(UNKNOWN), h264_profile_(OMX_VIDEO_AVCProfileMax), component_name_is_nvidia_h264ext_(false) { - RETURN_ON_FAILURE(AreOMXFunctionPointersInitialized(), + static bool omx_functions_initialized = PostSandboxInitialization(); + RETURN_ON_FAILURE(omx_functions_initialized, "Failed to load openmax library", PLATFORM_FAILURE,); RETURN_ON_OMX_FAILURE(omx_init(), "Failed to init OpenMAX core", PLATFORM_FAILURE,); @@ -994,6 +987,32 @@ void OmxVideoDecodeAccelerator::EventHandlerCompleteTask(OMX_EVENTTYPE event, } // static +void OmxVideoDecodeAccelerator::PreSandboxInitialization() { + DCHECK(!pre_sandbox_init_done_); + omx_handle = dlopen("libOmxCore.so", RTLD_NOW); + pre_sandbox_init_done_ = omx_handle != NULL; +} + +// static +bool OmxVideoDecodeAccelerator::PostSandboxInitialization() { + if (!pre_sandbox_init_done_) + return false; + + omx_init = reinterpret_cast(dlsym(omx_handle, "OMX_Init")); + omx_gethandle = + reinterpret_cast(dlsym(omx_handle, "OMX_GetHandle")); + omx_get_components_of_role = + reinterpret_cast( + dlsym(omx_handle, "OMX_GetComponentsOfRole")); + omx_free_handle = + reinterpret_cast(dlsym(omx_handle, "OMX_FreeHandle")); + omx_deinit = + reinterpret_cast(dlsym(omx_handle, "OMX_Deinit")); + return (omx_init && omx_gethandle && omx_get_components_of_role && + omx_free_handle && omx_deinit); +} + +// static OMX_ERRORTYPE OmxVideoDecodeAccelerator::EventHandler(OMX_HANDLETYPE component, OMX_PTR priv_data, OMX_EVENTTYPE event, diff --git a/content/common/gpu/media/omx_video_decode_accelerator.h b/content/common/gpu/media/omx_video_decode_accelerator.h index 60fc638..2a846ec 100644 --- a/content/common/gpu/media/omx_video_decode_accelerator.h +++ b/content/common/gpu/media/omx_video_decode_accelerator.h @@ -54,6 +54,9 @@ class CONTENT_EXPORT OmxVideoDecodeAccelerator : base::WeakPtr weak_this() { return weak_this_; } + // Do any necessary initialization before the sandbox is enabled. + static void PreSandboxInitialization(); + private: // Because OMX state-transitions are described solely by the "state reached" // (3.1.2.9.1, table 3-7 of the spec), we track what transition was requested @@ -143,6 +146,10 @@ class CONTENT_EXPORT OmxVideoDecodeAccelerator : // Decode bitstream buffers that were queued (see queued_bitstream_buffers_). void DecodeQueuedBitstreamBuffers(); + // Lazily initialize static data after sandbox is enabled. Return false on + // init failure. + static bool PostSandboxInitialization(); + // Weak pointer to |this|; used to safely trampoline calls from the OMX thread // to the ChildThread. Since |this| is kept alive until OMX is fully shut // down, only the OMX->Child thread direction needs to be guarded this way. @@ -207,6 +214,9 @@ class CONTENT_EXPORT OmxVideoDecodeAccelerator : uint32 h264_profile_; // OMX_AVCProfile requested during Initialization. bool component_name_is_nvidia_h264ext_; + // Has static initialization of pre-sandbox components completed successfully? + static bool pre_sandbox_init_done_; + // Method to handle events void EventHandlerCompleteTask(OMX_EVENTTYPE event, OMX_U32 data1, diff --git a/content/common/gpu/media/vaapi_h264_decoder.cc b/content/common/gpu/media/vaapi_h264_decoder.cc index b5b2772..7ccc4082 100644 --- a/content/common/gpu/media/vaapi_h264_decoder.cc +++ b/content/common/gpu/media/vaapi_h264_decoder.cc @@ -34,8 +34,8 @@ namespace content { -void *vaapi_handle = dlopen("libva.so", RTLD_NOW); -void *vaapi_x11_handle = dlopen("libva-x11.so", RTLD_NOW); +void *vaapi_handle = NULL; +void *vaapi_x11_handle = NULL; typedef VADisplay (*VaapiGetDisplay)(Display *dpy); typedef int (*VaapiDisplayIsValid)(VADisplay dpy); @@ -106,51 +106,30 @@ typedef VAStatus (*VaapiCreateBuffer)(VADisplay dpy, typedef VAStatus (*VaapiDestroyBuffer)(VADisplay dpy, VABufferID buffer_id); typedef const char* (*VaapiErrorStr)(VAStatus error_status); -#define VAAPI_DLSYM(name, handle) \ - Vaapi##name VAAPI_##name = \ - reinterpret_cast(dlsym((handle), "va"#name)) - -VAAPI_DLSYM(GetDisplay, vaapi_x11_handle); -VAAPI_DLSYM(DisplayIsValid, vaapi_handle); -VAAPI_DLSYM(Initialize, vaapi_handle); -VAAPI_DLSYM(Terminate, vaapi_handle); -VAAPI_DLSYM(GetConfigAttributes, vaapi_handle); -VAAPI_DLSYM(CreateConfig, vaapi_handle); -VAAPI_DLSYM(DestroyConfig, vaapi_handle); -VAAPI_DLSYM(CreateSurfaces, vaapi_handle); -VAAPI_DLSYM(DestroySurfaces, vaapi_handle); -VAAPI_DLSYM(CreateContext, vaapi_handle); -VAAPI_DLSYM(DestroyContext, vaapi_handle); -VAAPI_DLSYM(PutSurface, vaapi_x11_handle); -VAAPI_DLSYM(SyncSurface, vaapi_x11_handle); -VAAPI_DLSYM(BeginPicture, vaapi_handle); -VAAPI_DLSYM(RenderPicture, vaapi_handle); -VAAPI_DLSYM(EndPicture, vaapi_handle); -VAAPI_DLSYM(CreateBuffer, vaapi_handle); -VAAPI_DLSYM(DestroyBuffer, vaapi_handle); -VAAPI_DLSYM(ErrorStr, vaapi_handle); - -static bool AreVaapiFunctionPointersInitialized() { - return VAAPI_GetDisplay && - VAAPI_DisplayIsValid && - VAAPI_Initialize && - VAAPI_Terminate && - VAAPI_GetConfigAttributes && - VAAPI_CreateConfig && - VAAPI_DestroyConfig && - VAAPI_CreateSurfaces && - VAAPI_DestroySurfaces && - VAAPI_CreateContext && - VAAPI_DestroyContext && - VAAPI_PutSurface && - VAAPI_SyncSurface && - VAAPI_BeginPicture && - VAAPI_RenderPicture && - VAAPI_EndPicture && - VAAPI_CreateBuffer && - VAAPI_DestroyBuffer && - VAAPI_ErrorStr; -} +#define VAAPI_SYM(name, handle) Vaapi##name VAAPI_##name = NULL + +VAAPI_SYM(GetDisplay, vaapi_x11_handle); +VAAPI_SYM(DisplayIsValid, vaapi_handle); +VAAPI_SYM(Initialize, vaapi_handle); +VAAPI_SYM(Terminate, vaapi_handle); +VAAPI_SYM(GetConfigAttributes, vaapi_handle); +VAAPI_SYM(CreateConfig, vaapi_handle); +VAAPI_SYM(DestroyConfig, vaapi_handle); +VAAPI_SYM(CreateSurfaces, vaapi_handle); +VAAPI_SYM(DestroySurfaces, vaapi_handle); +VAAPI_SYM(CreateContext, vaapi_handle); +VAAPI_SYM(DestroyContext, vaapi_handle); +VAAPI_SYM(PutSurface, vaapi_x11_handle); +VAAPI_SYM(SyncSurface, vaapi_x11_handle); +VAAPI_SYM(BeginPicture, vaapi_handle); +VAAPI_SYM(RenderPicture, vaapi_handle); +VAAPI_SYM(EndPicture, vaapi_handle); +VAAPI_SYM(CreateBuffer, vaapi_handle); +VAAPI_SYM(DestroyBuffer, vaapi_handle); +VAAPI_SYM(ErrorStr, vaapi_handle); + +// static +bool VaapiH264Decoder::pre_sandbox_init_done_ = false; class VaapiH264Decoder::DecodeSurface { public: @@ -502,11 +481,6 @@ bool VaapiH264Decoder::Initialize( return false; } - if (!AreVaapiFunctionPointersInitialized()) { - DVLOG(1) << "Could not load libva"; - return false; - } - if (!InitializeFBConfig()) { DVLOG(1) << "Could not get a usable FBConfig"; return false; @@ -2132,4 +2106,61 @@ size_t VaapiH264Decoder::GetRequiredNumOfPictures() { return kNumReqPictures; } +// static +void VaapiH264Decoder::PreSandboxInitialization() { + DCHECK(!pre_sandbox_init_done_); + vaapi_handle = dlopen("libva.so", RTLD_NOW); + vaapi_x11_handle = dlopen("libva-x11.so", RTLD_NOW); + pre_sandbox_init_done_ = vaapi_handle && vaapi_x11_handle; +} + +// static +bool VaapiH264Decoder::PostSandboxInitialization() { + if (!pre_sandbox_init_done_) + return false; +#define VAAPI_DLSYM(name, handle) \ + VAAPI_##name = reinterpret_cast(dlsym((handle), "va"#name)) \ + + VAAPI_DLSYM(GetDisplay, vaapi_x11_handle); + VAAPI_DLSYM(DisplayIsValid, vaapi_handle); + VAAPI_DLSYM(Initialize, vaapi_handle); + VAAPI_DLSYM(Terminate, vaapi_handle); + VAAPI_DLSYM(GetConfigAttributes, vaapi_handle); + VAAPI_DLSYM(CreateConfig, vaapi_handle); + VAAPI_DLSYM(DestroyConfig, vaapi_handle); + VAAPI_DLSYM(CreateSurfaces, vaapi_handle); + VAAPI_DLSYM(DestroySurfaces, vaapi_handle); + VAAPI_DLSYM(CreateContext, vaapi_handle); + VAAPI_DLSYM(DestroyContext, vaapi_handle); + VAAPI_DLSYM(PutSurface, vaapi_x11_handle); + VAAPI_DLSYM(SyncSurface, vaapi_x11_handle); + VAAPI_DLSYM(BeginPicture, vaapi_handle); + VAAPI_DLSYM(RenderPicture, vaapi_handle); + VAAPI_DLSYM(EndPicture, vaapi_handle); + VAAPI_DLSYM(CreateBuffer, vaapi_handle); + VAAPI_DLSYM(DestroyBuffer, vaapi_handle); + VAAPI_DLSYM(ErrorStr, vaapi_handle); +#undef VAAPI_DLSYM + + return VAAPI_GetDisplay && + VAAPI_DisplayIsValid && + VAAPI_Initialize && + VAAPI_Terminate && + VAAPI_GetConfigAttributes && + VAAPI_CreateConfig && + VAAPI_DestroyConfig && + VAAPI_CreateSurfaces && + VAAPI_DestroySurfaces && + VAAPI_CreateContext && + VAAPI_DestroyContext && + VAAPI_PutSurface && + VAAPI_SyncSurface && + VAAPI_BeginPicture && + VAAPI_RenderPicture && + VAAPI_EndPicture && + VAAPI_CreateBuffer && + VAAPI_DestroyBuffer && + VAAPI_ErrorStr; +} + } // namespace content diff --git a/content/common/gpu/media/vaapi_h264_decoder.h b/content/common/gpu/media/vaapi_h264_decoder.h index 4cdf23b..9242227 100644 --- a/content/common/gpu/media/vaapi_h264_decoder.h +++ b/content/common/gpu/media/vaapi_h264_decoder.h @@ -129,6 +129,13 @@ class VaapiH264Decoder { // Valid after a successful DecodeInitial(). static size_t GetRequiredNumOfPictures(); + // Do any necessary initialization before the sandbox is enabled. + static void PreSandboxInitialization(); + + // Lazily initialize static data after sandbox is enabled. Return false on + // init failure. + static bool PostSandboxInitialization(); + private: // We need to keep at least kDPBMaxSize pictures in DPB for // reference/to display later and an additional one for the one currently @@ -333,6 +340,9 @@ class VaapiH264Decoder { // Called by decoder when a picture should be outputted. OutputPicCB output_pic_cb_; + // Has static initialization of pre-sandbox components completed successfully? + static bool pre_sandbox_init_done_; + DISALLOW_COPY_AND_ASSIGN(VaapiH264Decoder); }; diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator.cc index d54db04..06b0823 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.cc @@ -67,6 +67,10 @@ VaapiVideoDecodeAccelerator::VaapiVideoDecodeAccelerator( client_(client_ptr_factory_.GetWeakPtr()), decoder_thread_("VaapiDecoderThread") { DCHECK(client); + static bool vaapi_functions_initialized = PostSandboxInitialization(); + RETURN_AND_NOTIFY_ON_FAILURE(vaapi_functions_initialized, + "Failed to initialize VAAPI libs", + PLATFORM_FAILURE, ); } VaapiVideoDecodeAccelerator::~VaapiVideoDecodeAccelerator() { @@ -555,6 +559,16 @@ void VaapiVideoDecodeAccelerator::Destroy() { delete this; } +// static +void VaapiVideoDecodeAccelerator::PreSandboxInitialization() { + VaapiH264Decoder::PreSandboxInitialization(); +} + +// static +bool VaapiVideoDecodeAccelerator::PostSandboxInitialization() { + return VaapiH264Decoder::PostSandboxInitialization(); +} + void VaapiVideoDecodeAccelerator::OutputPicCallback(int32 input_id, int32 output_id) { TRACE_EVENT2("Video Decoder", "VAVDA::OutputPicCallback", diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.h b/content/common/gpu/media/vaapi_video_decode_accelerator.h index a5abed4..eda4117 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.h +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.h @@ -56,7 +56,10 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator : virtual void Reset() OVERRIDE; virtual void Destroy() OVERRIDE; - private: + // Do any necessary initialization before the sandbox is enabled. + static void PreSandboxInitialization(); + +private: // Ensure data has been synced with the output texture and notify // the client it is ready for displaying. void SyncAndNotifyPictureReady(int32 input_id, int32 output_id); @@ -122,6 +125,10 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator : // Helper for Destroy(), doing all the actual work except for deleting self. void Cleanup(); + // Lazily initialize static data after sandbox is enabled. Return false on + // init failure. + static bool PostSandboxInitialization(); + // Client-provided X/GLX state. Display* x_display_; GLXContext glx_context_; diff --git a/content/common/gpu/media/video_decode_accelerator_unittest.cc b/content/common/gpu/media/video_decode_accelerator_unittest.cc index a86fb67..1460bba 100644 --- a/content/common/gpu/media/video_decode_accelerator_unittest.cc +++ b/content/common/gpu/media/video_decode_accelerator_unittest.cc @@ -889,6 +889,10 @@ int main(int argc, char **argv) { #if defined(OS_WIN) DXVAVideoDecodeAccelerator::PreSandboxInitialization(); +#elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) + OmxVideoDecodeAccelerator::PreSandboxInitialization(); +#elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) + VaapiVideoDecodeAccelerator::PreSandboxInitialization(); #endif return RUN_ALL_TESTS(); diff --git a/content/content_gpu.gypi b/content/content_gpu.gypi index 3327a69..d55093c 100644 --- a/content/content_gpu.gypi +++ b/content/content_gpu.gypi @@ -100,5 +100,15 @@ '../third_party/libXNVCtrl/libXNVCtrl.gyp:libXNVCtrl', ], }], + ['target_arch=="arm" and chromeos == 1', { + 'include_dirs': [ + '<(DEPTH)/third_party/openmax/il', + ], + }], + ['target_arch!="arm" and chromeos == 1', { + 'include_dirs': [ + '<(DEPTH)/third_party/libva', + ], + }], ], } diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc index 75ab303..be58304 100644 --- a/content/gpu/gpu_main.cc +++ b/content/gpu/gpu_main.cc @@ -30,6 +30,10 @@ #if defined(OS_WIN) #include "content/common/gpu/media/dxva_video_decode_accelerator.h" #include "sandbox/win/src/sandbox.h" +#elif defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) +#include "content/common/gpu/media/omx_video_decode_accelerator.h" +#elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) +#include "content/common/gpu/media/vaapi_video_decode_accelerator.h" #endif #if defined(USE_X11) @@ -149,6 +153,12 @@ int GpuMain(const content::MainFunctionParams& parameters) { TRACE_EVENT0("gpu", "Initialize sandbox"); bool do_init_sandbox = true; +#if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) + OmxVideoDecodeAccelerator::PreSandboxInitialization(); +#elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) + VaapiVideoDecodeAccelerator::PreSandboxInitialization(); +#endif + #if defined(OS_CHROMEOS) && defined(NDEBUG) // On Chrome OS and when not on a debug build, initialize // the GPU process' sandbox only for Intel GPUs. -- cgit v1.1