Line data Source code
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 : // We use a known symbol located in lgpllibs to determine its location.
15 : // soundtouch happens to be always included in lgpllibs
16 : #include "soundtouch/SoundTouch.h"
17 :
18 : namespace mozilla {
19 :
20 : template <int V> class FFmpegDecoderModule
21 : {
22 : public:
23 : static already_AddRefed<PlatformDecoderModule> Create(FFmpegLibWrapper*);
24 : };
25 :
26 3 : static FFmpegLibWrapper sFFVPXLib;
27 :
28 : FFVPXRuntimeLinker::LinkStatus FFVPXRuntimeLinker::sLinkStatus =
29 : LinkStatus_INIT;
30 :
31 : static PRLibrary*
32 0 : MozAVLink(const char* aName)
33 : {
34 : PRLibSpec lspec;
35 0 : lspec.type = PR_LibSpec_Pathname;
36 0 : lspec.value.pathname = aName;
37 0 : PRLibrary* lib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL);
38 0 : if (!lib) {
39 0 : FFMPEG_LOG("unable to load library %s", aName);
40 : }
41 0 : return lib;
42 : }
43 :
44 : /* static */ bool
45 0 : FFVPXRuntimeLinker::Init()
46 : {
47 0 : if (sLinkStatus) {
48 0 : return sLinkStatus == LinkStatus_SUCCEEDED;
49 : }
50 :
51 0 : sLinkStatus = LinkStatus_FAILED;
52 :
53 : // We retrieve the path of the lgpllibs library as this is where mozavcodec
54 : // and mozavutil libs are located.
55 0 : char* lgpllibsname = PR_GetLibraryName(nullptr, "lgpllibs");
56 0 : if (!lgpllibsname) {
57 0 : return false;
58 : }
59 : char* path =
60 : PR_GetLibraryFilePathname(lgpllibsname,
61 0 : (PRFuncPtr)&soundtouch::SoundTouch::getVersionId);
62 0 : PR_FreeLibraryName(lgpllibsname);
63 0 : if (!path) {
64 0 : return false;
65 : }
66 0 : nsCOMPtr<nsIFile> xulFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
67 0 : if (!xulFile ||
68 0 : NS_FAILED(xulFile->InitWithNativePath(nsDependentCString(path)))) {
69 0 : PR_Free(path); // PR_GetLibraryFilePathname() uses PR_Malloc().
70 0 : return false;
71 : }
72 0 : PR_Free(path); // PR_GetLibraryFilePathname() uses PR_Malloc().
73 :
74 0 : nsCOMPtr<nsIFile> rootDir;
75 0 : if (NS_FAILED(xulFile->GetParent(getter_AddRefs(rootDir))) || !rootDir) {
76 0 : return false;
77 : }
78 0 : nsAutoCString rootPath;
79 0 : if (NS_FAILED(rootDir->GetNativePath(rootPath))) {
80 0 : return false;
81 : }
82 :
83 0 : char* libname = NULL;
84 : /* Get the platform-dependent library name of the module */
85 0 : libname = PR_GetLibraryName(rootPath.get(), "mozavutil");
86 0 : if (!libname) {
87 0 : return false;
88 : }
89 0 : sFFVPXLib.mAVUtilLib = MozAVLink(libname);
90 0 : PR_FreeLibraryName(libname);
91 0 : libname = PR_GetLibraryName(rootPath.get(), "mozavcodec");
92 0 : if (libname) {
93 0 : sFFVPXLib.mAVCodecLib = MozAVLink(libname);
94 0 : PR_FreeLibraryName(libname);
95 : }
96 0 : if (sFFVPXLib.Link() == FFmpegLibWrapper::LinkResult::Success) {
97 0 : sLinkStatus = LinkStatus_SUCCEEDED;
98 0 : return true;
99 : }
100 0 : return false;
101 : }
102 :
103 : /* static */ already_AddRefed<PlatformDecoderModule>
104 0 : FFVPXRuntimeLinker::CreateDecoderModule()
105 : {
106 0 : if (!Init()) {
107 0 : return nullptr;
108 : }
109 0 : return FFmpegDecoderModule<FFVPX_VERSION>::Create(&sFFVPXLib);
110 : }
111 :
112 9 : } // namespace mozilla
|