michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:set ts=2 sw=2 sts=2 et cindent: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include michael@0: michael@0: #include "nsDebug.h" michael@0: michael@0: #include "FFmpegRuntimeLinker.h" michael@0: michael@0: // For FFMPEG_LOG michael@0: #include "FFmpegDecoderModule.h" michael@0: michael@0: #define NUM_ELEMENTS(X) (sizeof(X) / sizeof((X)[0])) michael@0: michael@0: #define LIBAVCODEC 0 michael@0: #define LIBAVFORMAT 1 michael@0: #define LIBAVUTIL 2 michael@0: michael@0: namespace mozilla michael@0: { michael@0: michael@0: FFmpegRuntimeLinker::LinkStatus FFmpegRuntimeLinker::sLinkStatus = michael@0: LinkStatus_INIT; michael@0: michael@0: static const char * const sLibNames[] = { michael@0: "libavcodec.so.53", "libavformat.so.53", "libavutil.so.51", michael@0: }; michael@0: michael@0: void* FFmpegRuntimeLinker::sLinkedLibs[NUM_ELEMENTS(sLibNames)] = { michael@0: nullptr, nullptr, nullptr michael@0: }; michael@0: michael@0: #define AV_FUNC(lib, func) typeof(func) func; michael@0: #include "FFmpegFunctionList.h" michael@0: #undef AV_FUNC michael@0: michael@0: /* static */ bool michael@0: FFmpegRuntimeLinker::Link() michael@0: { michael@0: if (sLinkStatus) { michael@0: return sLinkStatus == LinkStatus_SUCCEEDED; michael@0: } michael@0: michael@0: for (uint32_t i = 0; i < NUM_ELEMENTS(sLinkedLibs); i++) { michael@0: if (!(sLinkedLibs[i] = dlopen(sLibNames[i], RTLD_NOW | RTLD_LOCAL))) { michael@0: NS_WARNING("Couldn't link ffmpeg libraries."); michael@0: goto fail; michael@0: } michael@0: } michael@0: michael@0: #define AV_FUNC(lib, func) \ michael@0: func = (typeof(func))dlsym(sLinkedLibs[lib], #func); \ michael@0: if (!func) { \ michael@0: NS_WARNING("Couldn't load FFmpeg function " #func "."); \ michael@0: goto fail; \ michael@0: } michael@0: #include "FFmpegFunctionList.h" michael@0: #undef AV_FUNC michael@0: michael@0: sLinkStatus = LinkStatus_SUCCEEDED; michael@0: return true; michael@0: michael@0: fail: michael@0: Unlink(); michael@0: michael@0: sLinkStatus = LinkStatus_FAILED; michael@0: return false; michael@0: } michael@0: michael@0: /* static */ void michael@0: FFmpegRuntimeLinker::Unlink() michael@0: { michael@0: FFMPEG_LOG("Unlinking ffmpeg libraries."); michael@0: for (uint32_t i = 0; i < NUM_ELEMENTS(sLinkedLibs); i++) { michael@0: if (sLinkedLibs[i]) { michael@0: dlclose(sLinkedLibs[i]); michael@0: sLinkedLibs[i] = nullptr; michael@0: } michael@0: } michael@0: } michael@0: michael@0: } // namespace mozilla