1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "FFVPXRuntimeLinker.h" 8 #include "FFmpegLibWrapper.h" 9 #include "FFmpegLog.h" 10 #include "nsIFile.h" 11 #include "prmem.h" 12 #include "prlink.h" 13 14 #ifdef MOZ_SYSTEM_SOUNDTOUCH 15 #include "nsXPCOMPrivate.h" // for XUL_DLL 16 #else 17 // We use a known symbol located in lgpllibs to determine its location. 18 // soundtouch happens to be always included in lgpllibs 19 #include "soundtouch/SoundTouch.h" 20 #endif 21 22 namespace mozilla 23 { 24 25 template <int V> class FFmpegDecoderModule 26 { 27 public: 28 static already_AddRefed<PlatformDecoderModule> Create(FFmpegLibWrapper*); 29 }; 30 31 static FFmpegLibWrapper sFFVPXLib; 32 33 FFVPXRuntimeLinker::LinkStatus FFVPXRuntimeLinker::sLinkStatus = 34 LinkStatus_INIT; 35 36 static PRLibrary* MozAVLink(const char * aName)37MozAVLink(const char* aName) 38 { 39 PRLibSpec lspec; 40 lspec.type = PR_LibSpec_Pathname; 41 lspec.value.pathname = aName; 42 PRLibrary* lib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL); 43 if (!lib) { 44 FFMPEG_LOG("unable to load library %s", aName); 45 } 46 return lib; 47 } 48 49 /* static */ bool Init()50FFVPXRuntimeLinker::Init() 51 { 52 if (sLinkStatus) { 53 return sLinkStatus == LinkStatus_SUCCEEDED; 54 } 55 56 sLinkStatus = LinkStatus_FAILED; 57 58 #ifdef MOZ_SYSTEM_SOUNDTOUCH 59 // We retrieve the path of the XUL library as this is where mozavcodec and 60 // mozavutil libs are located. 61 char* path = 62 PR_GetLibraryFilePathname(XUL_DLL, (PRFuncPtr)&FFVPXRuntimeLinker::Init); 63 #else 64 // We retrieve the path of the lgpllibs library as this is where mozavcodec 65 // and mozavutil libs are located. 66 char* lgpllibsname = PR_GetLibraryName(nullptr, "lgpllibs"); 67 if (!lgpllibsname) { 68 return false; 69 } 70 char* path = 71 PR_GetLibraryFilePathname(lgpllibsname, 72 (PRFuncPtr)&soundtouch::SoundTouch::getVersionId); 73 PR_FreeLibraryName(lgpllibsname); 74 #endif 75 if (!path) { 76 return false; 77 } 78 nsCOMPtr<nsIFile> xulFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID); 79 if (!xulFile || 80 NS_FAILED(xulFile->InitWithNativePath(nsDependentCString(path)))) { 81 PR_Free(path); 82 return false; 83 } 84 PR_Free(path); 85 86 nsCOMPtr<nsIFile> rootDir; 87 if (NS_FAILED(xulFile->GetParent(getter_AddRefs(rootDir))) || !rootDir) { 88 return false; 89 } 90 nsAutoCString rootPath; 91 if (NS_FAILED(rootDir->GetNativePath(rootPath))) { 92 return false; 93 } 94 95 char* libname = NULL; 96 /* Get the platform-dependent library name of the module */ 97 libname = PR_GetLibraryName(rootPath.get(), "mozavutil"); 98 if (!libname) { 99 return false; 100 } 101 sFFVPXLib.mAVUtilLib = MozAVLink(libname); 102 PR_FreeLibraryName(libname); 103 libname = PR_GetLibraryName(rootPath.get(), "mozavcodec"); 104 if (libname) { 105 sFFVPXLib.mAVCodecLib = MozAVLink(libname); 106 PR_FreeLibraryName(libname); 107 } 108 if (sFFVPXLib.Link() == FFmpegLibWrapper::LinkResult::Success) { 109 sLinkStatus = LinkStatus_SUCCEEDED; 110 return true; 111 } 112 return false; 113 } 114 115 /* static */ already_AddRefed<PlatformDecoderModule> CreateDecoderModule()116FFVPXRuntimeLinker::CreateDecoderModule() 117 { 118 if (!Init()) { 119 return nullptr; 120 } 121 return FFmpegDecoderModule<FFVPX_VERSION>::Create(&sFFVPXLib); 122 } 123 124 } // namespace mozilla 125