Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
Line
Count
Source (jump to first uncovered line)
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 "FFmpegRuntimeLinker.h"
8
#include "FFmpegLibWrapper.h"
9
#include "mozilla/ArrayUtils.h"
10
#include "FFmpegLog.h"
11
#include "prlink.h"
12
13
namespace mozilla {
14
15
FFmpegRuntimeLinker::LinkStatus FFmpegRuntimeLinker::sLinkStatus =
16
  LinkStatus_INIT;
17
const char* FFmpegRuntimeLinker::sLinkStatusLibraryName = "";
18
19
template <int V> class FFmpegDecoderModule
20
{
21
public:
22
  static already_AddRefed<PlatformDecoderModule> Create(FFmpegLibWrapper*);
23
};
24
25
static FFmpegLibWrapper sLibAV;
26
27
static const char* sLibs[] = {
28
#if defined(XP_DARWIN)
29
  "libavcodec.58.dylib",
30
  "libavcodec.57.dylib",
31
  "libavcodec.56.dylib",
32
  "libavcodec.55.dylib",
33
  "libavcodec.54.dylib",
34
  "libavcodec.53.dylib",
35
#else
36
  "libavcodec.so.58",
37
  "libavcodec-ffmpeg.so.58",
38
  "libavcodec-ffmpeg.so.57",
39
  "libavcodec-ffmpeg.so.56",
40
  "libavcodec.so.57",
41
  "libavcodec.so.56",
42
  "libavcodec.so.55",
43
  "libavcodec.so.54",
44
  "libavcodec.so.53",
45
#endif
46
};
47
48
/* static */ bool
49
FFmpegRuntimeLinker::Init()
50
0
{
51
0
  if (sLinkStatus != LinkStatus_INIT) {
52
0
    return sLinkStatus == LinkStatus_SUCCEEDED;
53
0
  }
54
0
55
0
  // While going through all possible libs, this status will be updated with a
56
0
  // more precise error if possible.
57
0
  sLinkStatus = LinkStatus_NOT_FOUND;
58
0
59
0
  for (size_t i = 0; i < ArrayLength(sLibs); i++) {
60
0
    const char* lib = sLibs[i];
61
0
    PRLibSpec lspec;
62
0
    lspec.type = PR_LibSpec_Pathname;
63
0
    lspec.value.pathname = lib;
64
0
    sLibAV.mAVCodecLib =
65
0
      PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL);
66
0
    if (sLibAV.mAVCodecLib) {
67
0
      sLibAV.mAVUtilLib = sLibAV.mAVCodecLib;
68
0
      switch (sLibAV.Link()) {
69
0
        case FFmpegLibWrapper::LinkResult::Success:
70
0
          sLinkStatus = LinkStatus_SUCCEEDED;
71
0
          sLinkStatusLibraryName = lib;
72
0
          return true;
73
0
        case FFmpegLibWrapper::LinkResult::NoProvidedLib:
74
0
          MOZ_ASSERT_UNREACHABLE("Incorrectly-setup sLibAV");
75
0
          break;
76
0
        case FFmpegLibWrapper::LinkResult::NoAVCodecVersion:
77
0
          if (sLinkStatus > LinkStatus_INVALID_CANDIDATE) {
78
0
            sLinkStatus = LinkStatus_INVALID_CANDIDATE;
79
0
            sLinkStatusLibraryName = lib;
80
0
          }
81
0
          break;
82
0
        case FFmpegLibWrapper::LinkResult::CannotUseLibAV57:
83
0
          if (sLinkStatus > LinkStatus_UNUSABLE_LIBAV57) {
84
0
            sLinkStatus = LinkStatus_UNUSABLE_LIBAV57;
85
0
            sLinkStatusLibraryName = lib;
86
0
          }
87
0
          break;
88
0
        case FFmpegLibWrapper::LinkResult::BlockedOldLibAVVersion:
89
0
          if (sLinkStatus > LinkStatus_OBSOLETE_LIBAV) {
90
0
            sLinkStatus = LinkStatus_OBSOLETE_LIBAV;
91
0
            sLinkStatusLibraryName = lib;
92
0
          }
93
0
          break;
94
0
        case FFmpegLibWrapper::LinkResult::UnknownFutureLibAVVersion:
95
0
        case FFmpegLibWrapper::LinkResult::MissingLibAVFunction:
96
0
          if (sLinkStatus > LinkStatus_INVALID_LIBAV_CANDIDATE) {
97
0
            sLinkStatus = LinkStatus_INVALID_LIBAV_CANDIDATE;
98
0
            sLinkStatusLibraryName = lib;
99
0
          }
100
0
          break;
101
0
        case FFmpegLibWrapper::LinkResult::UnknownFutureFFMpegVersion:
102
0
        case FFmpegLibWrapper::LinkResult::MissingFFMpegFunction:
103
0
          if (sLinkStatus > LinkStatus_INVALID_FFMPEG_CANDIDATE) {
104
0
            sLinkStatus = LinkStatus_INVALID_FFMPEG_CANDIDATE;
105
0
            sLinkStatusLibraryName = lib;
106
0
          }
107
0
          break;
108
0
        case FFmpegLibWrapper::LinkResult::UnknownOlderFFMpegVersion:
109
0
          if (sLinkStatus > LinkStatus_OBSOLETE_FFMPEG) {
110
0
            sLinkStatus = LinkStatus_OBSOLETE_FFMPEG;
111
0
            sLinkStatusLibraryName = lib;
112
0
          }
113
0
          break;
114
0
      }
115
0
    }
116
0
  }
117
0
118
0
  FFMPEG_LOG("H264/AAC codecs unsupported without [");
119
0
  for (size_t i = 0; i < ArrayLength(sLibs); i++) {
120
0
    FFMPEG_LOG("%s %s", i ? "," : " ", sLibs[i]);
121
0
  }
122
0
  FFMPEG_LOG(" ]\n");
123
0
124
0
  return false;
125
0
}
126
127
/* static */ already_AddRefed<PlatformDecoderModule>
128
FFmpegRuntimeLinker::CreateDecoderModule()
129
0
{
130
0
  if (!Init()) {
131
0
    return nullptr;
132
0
  }
133
0
  RefPtr<PlatformDecoderModule> module;
134
0
  switch (sLibAV.mVersion) {
135
0
    case 53: module = FFmpegDecoderModule<53>::Create(&sLibAV); break;
136
0
    case 54: module = FFmpegDecoderModule<54>::Create(&sLibAV); break;
137
0
    case 55:
138
0
    case 56: module = FFmpegDecoderModule<55>::Create(&sLibAV); break;
139
0
    case 57: module = FFmpegDecoderModule<57>::Create(&sLibAV); break;
140
0
    case 58: module = FFmpegDecoderModule<58>::Create(&sLibAV); break;
141
0
    default: module = nullptr;
142
0
  }
143
0
  return module.forget();
144
0
}
145
146
/* static */ const char*
147
FFmpegRuntimeLinker::LinkStatusString()
148
0
{
149
0
  switch (sLinkStatus) {
150
0
    case LinkStatus_INIT:
151
0
      return "Libavcodec not initialized yet";
152
0
    case LinkStatus_SUCCEEDED:
153
0
      return "Libavcodec linking succeeded";
154
0
    case LinkStatus_INVALID_FFMPEG_CANDIDATE:
155
0
      return "Invalid FFMpeg libavcodec candidate";
156
0
    case LinkStatus_UNUSABLE_LIBAV57:
157
0
      return "Unusable LibAV's libavcodec 57";
158
0
    case LinkStatus_INVALID_LIBAV_CANDIDATE:
159
0
      return "Invalid LibAV libavcodec candidate";
160
0
    case LinkStatus_OBSOLETE_FFMPEG:
161
0
      return "Obsolete FFMpeg libavcodec candidate";
162
0
    case LinkStatus_OBSOLETE_LIBAV:
163
0
      return "Obsolete LibAV libavcodec candidate";
164
0
    case LinkStatus_INVALID_CANDIDATE:
165
0
      return "Invalid libavcodec candidate";
166
0
    case LinkStatus_NOT_FOUND:
167
0
      return "Libavcodec not found";
168
0
  }
169
0
  MOZ_ASSERT_UNREACHABLE("Unknown sLinkStatus value");
170
0
  return "?";
171
0
}
172
173
} // namespace mozilla