/* static */ bool FFmpegRuntimeLinker::Init() { if (sLinkStatus) { return sLinkStatus == LinkStatus_SUCCEEDED; } for (size_t i = 0; i < ArrayLength(sLibs); i++) { const char* lib = sLibs[i]; PRLibSpec lspec; lspec.type = PR_LibSpec_Pathname; lspec.value.pathname = lib; sLibAV.mAVCodecLib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL); if (sLibAV.mAVCodecLib) { sLibAV.mAVUtilLib = sLibAV.mAVCodecLib; if (sLibAV.Link()) { sLinkStatus = LinkStatus_SUCCEEDED; return true; } } } FFMPEG_LOG("H264/AAC codecs unsupported without ["); for (size_t i = 0; i < ArrayLength(sLibs); i++) { FFMPEG_LOG("%s %s", i ? "," : " ", sLibs[i]); } FFMPEG_LOG(" ]\n"); sLinkStatus = LinkStatus_FAILED; return false; }
/* static */ bool FFVPXRuntimeLinker::Init() { if (sLinkStatus) { return sLinkStatus == LinkStatus_SUCCEEDED; } MOZ_ASSERT(NS_IsMainThread()); sLinkStatus = LinkStatus_FAILED; // We retrieve the path of the lgpllibs library as this is where mozavcodec // and mozavutil libs are located. PathString lgpllibsname = GetLibraryName(nullptr, "lgpllibs"); if (lgpllibsname.IsEmpty()) { return false; } PathString path = GetLibraryFilePathname(lgpllibsname.get(), (PRFuncPtr)&soundtouch::SoundTouch::getVersionId); if (path.IsEmpty()) { return false; } RefPtr<nsLocalFile> xulFile = new nsLocalFile(path); if (xulFile->NativePath().IsEmpty()) { return false; } nsCOMPtr<nsIFile> rootDir; if (NS_FAILED(xulFile->GetParent(getter_AddRefs(rootDir))) || !rootDir) { return false; } PathString rootPath = rootDir->NativePath(); /* Get the platform-dependent library name of the module */ PathString libname = GetLibraryName(rootPath.get(), "mozavutil"); if (libname.IsEmpty()) { return false; } RefPtr<nsLocalFile> libFile = new nsLocalFile(libname); if (libFile->NativePath().IsEmpty()) { return false; } sFFVPXLib.mAVUtilLib = MozAVLink(libFile); libname = GetLibraryName(rootPath.get(), "mozavcodec"); if (!libname.IsEmpty()) { libFile = new nsLocalFile(libname); if (!libFile->NativePath().IsEmpty()) { sFFVPXLib.mAVCodecLib = MozAVLink(libFile); } } if (sFFVPXLib.Link() == FFmpegLibWrapper::LinkResult::Success) { sLinkStatus = LinkStatus_SUCCEEDED; return true; } return false; }
namespace mozilla { FFmpegRuntimeLinker::LinkStatus FFmpegRuntimeLinker::sLinkStatus = LinkStatus_INIT; template <int V> class FFmpegDecoderModule { public: static already_AddRefed<PlatformDecoderModule> Create(FFmpegLibWrapper*); }; static FFmpegLibWrapper sLibAV; static const char* sLibs[] = { #if defined(XP_DARWIN) "libavcodec.57.dylib", "libavcodec.56.dylib", "libavcodec.55.dylib", "libavcodec.54.dylib", "libavcodec.53.dylib", #else "libavcodec-ffmpeg.so.57", "libavcodec-ffmpeg.so.56", "libavcodec.so.57", "libavcodec.so.56", "libavcodec.so.55", "libavcodec.so.54", "libavcodec.so.53", #endif }; /* static */ bool FFmpegRuntimeLinker::Init() { if (sLinkStatus) { return sLinkStatus == LinkStatus_SUCCEEDED; } for (size_t i = 0; i < ArrayLength(sLibs); i++) { const char* lib = sLibs[i]; PRLibSpec lspec; lspec.type = PR_LibSpec_Pathname; lspec.value.pathname = lib; sLibAV.mAVCodecLib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL); if (sLibAV.mAVCodecLib) { sLibAV.mAVUtilLib = sLibAV.mAVCodecLib; if (sLibAV.Link()) { sLinkStatus = LinkStatus_SUCCEEDED; return true; } } } FFMPEG_LOG("H264/AAC codecs unsupported without ["); for (size_t i = 0; i < ArrayLength(sLibs); i++) { FFMPEG_LOG("%s %s", i ? "," : " ", sLibs[i]); } FFMPEG_LOG(" ]\n"); sLinkStatus = LinkStatus_FAILED; return false; } /* static */ already_AddRefed<PlatformDecoderModule> FFmpegRuntimeLinker::CreateDecoderModule() { if (!Init()) { return nullptr; } RefPtr<PlatformDecoderModule> module; switch (sLibAV.mVersion) { case 53: module = FFmpegDecoderModule<53>::Create(&sLibAV); break; case 54: module = FFmpegDecoderModule<54>::Create(&sLibAV); break; case 55: case 56: module = FFmpegDecoderModule<55>::Create(&sLibAV); break; case 57: module = FFmpegDecoderModule<57>::Create(&sLibAV); break; default: module = nullptr; } return module.forget(); } } // namespace mozilla
namespace mozilla { template <int V> class FFmpegDecoderModule { public: static already_AddRefed<PlatformDecoderModule> Create(FFmpegLibWrapper*); }; static FFmpegLibWrapper sFFVPXLib; FFVPXRuntimeLinker::LinkStatus FFVPXRuntimeLinker::sLinkStatus = LinkStatus_INIT; static PRLibrary* MozAVLink(nsIFile* aFile) { PRLibSpec lspec; PathString path = aFile->NativePath(); #ifdef XP_WIN lspec.type = PR_LibSpec_PathnameU; lspec.value.pathname_u = path.get(); #else lspec.type = PR_LibSpec_Pathname; lspec.value.pathname = path.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", aFile->HumanReadablePath().get()); } return lib; } /* static */ bool FFVPXRuntimeLinker::Init() { if (sLinkStatus) { return sLinkStatus == LinkStatus_SUCCEEDED; } MOZ_ASSERT(NS_IsMainThread()); sLinkStatus = LinkStatus_FAILED; // We retrieve the path of the lgpllibs library as this is where mozavcodec // and mozavutil libs are located. PathString lgpllibsname = GetLibraryName(nullptr, "lgpllibs"); if (lgpllibsname.IsEmpty()) { return false; } PathString path = GetLibraryFilePathname(lgpllibsname.get(), (PRFuncPtr)&soundtouch::SoundTouch::getVersionId); if (path.IsEmpty()) { return false; } RefPtr<nsLocalFile> xulFile = new nsLocalFile(path); if (xulFile->NativePath().IsEmpty()) { return false; } nsCOMPtr<nsIFile> rootDir; if (NS_FAILED(xulFile->GetParent(getter_AddRefs(rootDir))) || !rootDir) { return false; } PathString rootPath = rootDir->NativePath(); /* Get the platform-dependent library name of the module */ PathString libname = GetLibraryName(rootPath.get(), "mozavutil"); if (libname.IsEmpty()) { return false; } RefPtr<nsLocalFile> libFile = new nsLocalFile(libname); if (libFile->NativePath().IsEmpty()) { return false; } sFFVPXLib.mAVUtilLib = MozAVLink(libFile); libname = GetLibraryName(rootPath.get(), "mozavcodec"); if (!libname.IsEmpty()) { libFile = new nsLocalFile(libname); if (!libFile->NativePath().IsEmpty()) { sFFVPXLib.mAVCodecLib = MozAVLink(libFile); } } if (sFFVPXLib.Link() == FFmpegLibWrapper::LinkResult::Success) { sLinkStatus = LinkStatus_SUCCEEDED; return true; } return false; } /* static */ already_AddRefed<PlatformDecoderModule> FFVPXRuntimeLinker::CreateDecoderModule() { if (!Init()) { return nullptr; } return FFmpegDecoderModule<FFVPX_VERSION>::Create(&sFFVPXLib); } /* static */ void FFVPXRuntimeLinker::GetRDFTFuncs(FFmpegRDFTFuncs* aOutFuncs) { MOZ_ASSERT(sLinkStatus != LinkStatus_INIT); if (sFFVPXLib.av_rdft_init && sFFVPXLib.av_rdft_calc && sFFVPXLib.av_rdft_end) { aOutFuncs->init = sFFVPXLib.av_rdft_init; aOutFuncs->calc = sFFVPXLib.av_rdft_calc; aOutFuncs->end = sFFVPXLib.av_rdft_end; } else { NS_WARNING("RDFT functions expected but not found"); *aOutFuncs = FFmpegRDFTFuncs(); // zero } } } // namespace mozilla