Bug 685236 - Stop using GetNativePath in ffvpx. r?jya draft
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Fri, 15 Dec 2017 23:16:39 +0900
changeset 715692 3c7a6e50dde65de54928c313f1ce6afadda6b4eb
parent 715691 4295716047daef1499355640992486975296f4b0
child 715693 7e1cccdb0f07dbb118645921ec6deb218ed943e2
push id94228
push userVYV03354@nifty.ne.jp
push dateThu, 04 Jan 2018 11:56:10 +0000
reviewersjya
bugs685236
milestone59.0a1
Bug 685236 - Stop using GetNativePath in ffvpx. r?jya MozReview-Commit-ID: 9ES1xFELjDs
dom/media/platforms/ffmpeg/ffvpx/FFVPXRuntimeLinker.cpp
--- a/dom/media/platforms/ffmpeg/ffvpx/FFVPXRuntimeLinker.cpp
+++ b/dom/media/platforms/ffmpeg/ffvpx/FFVPXRuntimeLinker.cpp
@@ -5,16 +5,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "FFVPXRuntimeLinker.h"
 #include "FFmpegLibWrapper.h"
 #include "FFmpegLog.h"
 #include "nsIFile.h"
 #include "prmem.h"
 #include "prlink.h"
+#ifdef XP_WIN
+#include <windows.h>
+#endif
 
 // We use a known symbol located in lgpllibs to determine its location.
 // soundtouch happens to be always included in lgpllibs
 #include "soundtouch/SoundTouch.h"
 
 namespace mozilla {
 
 template <int V> class FFmpegDecoderModule
@@ -23,84 +26,146 @@ public:
   static already_AddRefed<PlatformDecoderModule> Create(FFmpegLibWrapper*);
 };
 
 static FFmpegLibWrapper sFFVPXLib;
 
 FFVPXRuntimeLinker::LinkStatus FFVPXRuntimeLinker::sLinkStatus =
   LinkStatus_INIT;
 
+static filesystem::Path::string_type
+GetLibraryName(const filesystem::Path::value_type* aPath, const char* aLib)
+{
+#ifdef XP_WIN
+  nsAutoString fullName;
+  if (aPath) {
+    fullName.Assign(aPath);
+    fullName.Append('\\');
+  }
+  AppendUTF8toUTF16(aLib, fullName);
+  if (!strstr(aLib, ".dll")) {
+    fullName.AppendLiteral(".dll");
+  }
+  return fullName;
+#else
+  char* temp = PR_GetLibraryName(aPath, aLib);
+  if (!temp) {
+    return EmptyCString();
+  }
+  nsAutoCString libname(temp);
+  PR_FreeLibraryName(temp);
+  return libname;
+#endif
+}
+
+static filesystem::Path::string_type
+GetLibraryFilePathname(const filesystem::Path::value_type* aName,
+                       PRFuncPtr aAddr)
+{
+#ifdef XP_WIN
+  HMODULE handle = GetModuleHandleW(char16ptr_t(aName));
+  if (!handle) {
+    return EmptyString();
+  }
+
+  nsAutoString path;
+  path.SetLength(MAX_PATH);
+  DWORD len = GetModuleFileNameW(handle, char16ptr_t(path.BeginWriting()),
+                                 path.Length());
+  if (!len) {
+    return EmptyString();
+  }
+
+  path.SetLength(len);
+  return path;
+#else
+  char* temp = PR_GetLibraryFilePathname(aName, aAddr);
+  if (!temp) {
+    return EmptyCString();
+  }
+  nsAutoCString path(temp);
+  PR_Free(temp); // PR_GetLibraryFilePathname() uses PR_Malloc().
+  return path;
+#endif
+}
+
 static PRLibrary*
-MozAVLink(const char* aName)
+MozAVLink(const filesystem::Path::string_type& aName)
 {
   PRLibSpec lspec;
+#ifdef XP_WIN
+  lspec.type = PR_LibSpec_PathnameU;
+  lspec.value.pathname_u = aName.get();
+#else
   lspec.type = PR_LibSpec_Pathname;
-  lspec.value.pathname = aName;
+  lspec.value.pathname = aName.get();
+#endif
 #ifdef MOZ_WIDGET_ANDROID
   PRLibrary* lib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_GLOBAL);
 #else
   PRLibrary* lib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL);
 #endif
   if (!lib) {
-    FFMPEG_LOG("unable to load library %s", aName);
+#ifdef XP_WIN
+    FFMPEG_LOG("unable to load library %s", NS_ConvertUTF16toUTF8(aName).get());
+#else
+    FFMPEG_LOG("unable to load library %s", aName.get());
+#endif
   }
   return lib;
 }
 
 /* static */ bool
 FFVPXRuntimeLinker::Init()
 {
   if (sLinkStatus) {
     return sLinkStatus == LinkStatus_SUCCEEDED;
   }
 
   sLinkStatus = LinkStatus_FAILED;
 
   // We retrieve the path of the lgpllibs library as this is where mozavcodec
   // and mozavutil libs are located.
-  char* lgpllibsname = PR_GetLibraryName(nullptr, "lgpllibs");
-  if (!lgpllibsname) {
+  filesystem::Path::string_type lgpllibsname =
+    GetLibraryName(nullptr, "lgpllibs");
+  if (lgpllibsname.IsEmpty()) {
     return false;
   }
-  char* path =
-    PR_GetLibraryFilePathname(lgpllibsname,
-                              (PRFuncPtr)&soundtouch::SoundTouch::getVersionId);
-  PR_FreeLibraryName(lgpllibsname);
-  if (!path) {
+  filesystem::Path::string_type path =
+    GetLibraryFilePathname(lgpllibsname.get(),
+                           (PRFuncPtr)&soundtouch::SoundTouch::getVersionId);
+  if (path.IsEmpty()) {
     return false;
   }
   nsCOMPtr<nsIFile> xulFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
   if (!xulFile ||
-      NS_FAILED(xulFile->InitWithNativePath(nsDependentCString(path)))) {
-    PR_Free(path); // PR_GetLibraryFilePathname() uses PR_Malloc().
+#ifdef XP_WIN
+      NS_FAILED(xulFile->InitWithPath(path))) {
+#else
+      NS_FAILED(xulFile->InitWithNativePath(path))) {
+#endif
     return false;
   }
-  PR_Free(path); // PR_GetLibraryFilePathname() uses PR_Malloc().
 
   nsCOMPtr<nsIFile> rootDir;
   if (NS_FAILED(xulFile->GetParent(getter_AddRefs(rootDir))) || !rootDir) {
     return false;
   }
-  nsAutoCString rootPath;
-  if (NS_FAILED(rootDir->GetNativePath(rootPath))) {
-    return false;
-  }
+  filesystem::Path::string_type rootPath = rootDir->NativePath();
 
-  char* libname = NULL;
   /* Get the platform-dependent library name of the module */
-  libname = PR_GetLibraryName(rootPath.get(), "mozavutil");
-  if (!libname) {
+  filesystem::Path::string_type
+    libname = GetLibraryName(rootPath.get(), "mozavutil");
+  if (libname.IsEmpty()) {
     return false;
   }
   sFFVPXLib.mAVUtilLib = MozAVLink(libname);
-  PR_FreeLibraryName(libname);
-  libname = PR_GetLibraryName(rootPath.get(), "mozavcodec");
-  if (libname) {
+  libname = GetLibraryName(rootPath.get(), "mozavcodec");
+  if (!libname.IsEmpty()) {
     sFFVPXLib.mAVCodecLib = MozAVLink(libname);
-    PR_FreeLibraryName(libname);
   }
   if (sFFVPXLib.Link() == FFmpegLibWrapper::LinkResult::Success) {
     sLinkStatus = LinkStatus_SUCCEEDED;
     return true;
   }
   return false;
 }