tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FFmpegLibWrapper.cpp (19196B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "FFmpegLibWrapper.h"
      6 
      7 #include "FFmpegLog.h"
      8 #include "mozilla/PodOperations.h"
      9 #ifdef MOZ_FFMPEG
     10 #  include "mozilla/StaticPrefs_media.h"
     11 #endif
     12 #include "PlatformDecoderModule.h"
     13 #include "prlink.h"
     14 #ifdef MOZ_WIDGET_GTK
     15 #  include "VALibWrapper.h"
     16 #  include "mozilla/gfx/gfxVars.h"
     17 #  include "mozilla/widget/DMABufDevice.h"
     18 #endif
     19 
     20 #define AV_LOG_QUIET -8
     21 #define AV_LOG_PANIC 0
     22 #define AV_LOG_FATAL 8
     23 #define AV_LOG_ERROR 16
     24 #define AV_LOG_WARNING 24
     25 #define AV_LOG_INFO 32
     26 #define AV_LOG_VERBOSE 40
     27 #define AV_LOG_DEBUG 48
     28 #define AV_LOG_TRACE 56
     29 
     30 namespace mozilla {
     31 
     32 static LazyLogModule sFFmpegLibLog("FFmpegLib");
     33 
     34 FFmpegLibWrapper::LinkResult FFmpegLibWrapper::Link() {
     35  if (!mAVCodecLib || !mAVUtilLib) {
     36    Unlink();
     37    return LinkResult::NoProvidedLib;
     38  }
     39 
     40  avcodec_version =
     41      (decltype(avcodec_version))PR_FindSymbol(mAVCodecLib, "avcodec_version");
     42  if (!avcodec_version) {
     43    Unlink();
     44    return LinkResult::NoAVCodecVersion;
     45  }
     46  uint32_t version = avcodec_version();
     47  uint32_t macro = (version >> 16) & 0xFFu;
     48  mVersion = static_cast<int>(macro);
     49  uint32_t micro = version & 0xFFu;
     50  // A micro version >= 100 indicates that it's FFmpeg (as opposed to LibAV).
     51  bool isFFMpeg = micro >= 100;
     52  if (!isFFMpeg) {
     53    if (macro == 57) {
     54      // Due to current AVCodecContext binary incompatibility we can only
     55      // support FFmpeg 57 at this stage.
     56      Unlink();
     57      FFMPEGP_LOG("FFmpeg 57 is banned due to binary incompatibility");
     58      return LinkResult::CannotUseLibAV57;
     59    }
     60 #ifdef MOZ_FFMPEG
     61    if (version < (54u << 16 | 35u << 8 | 1u) &&
     62        !StaticPrefs::media_libavcodec_allow_obsolete()) {
     63      // Refuse any libavcodec version prior to 54.35.1.
     64      // (Unless media.libavcodec.allow-obsolete==true)
     65      Unlink();
     66      FFMPEGP_LOG("libavcodec version prior to 54.35.1 is too old");
     67      return LinkResult::BlockedOldLibAVVersion;
     68    }
     69 #endif
     70  }
     71 
     72  enum {
     73    AV_FUNC_AVUTIL_MASK = 1 << 15,
     74    AV_FUNC_53 = 1 << 0,
     75    AV_FUNC_54 = 1 << 1,
     76    AV_FUNC_55 = 1 << 2,
     77    AV_FUNC_56 = 1 << 3,
     78    AV_FUNC_57 = 1 << 4,
     79    AV_FUNC_58 = 1 << 5,
     80    AV_FUNC_59 = 1 << 6,
     81    AV_FUNC_60 = 1 << 7,
     82    AV_FUNC_61 = 1 << 8,
     83    AV_FUNC_62 = 1 << 9,
     84    AV_FUNC_AVUTIL_53 = AV_FUNC_53 | AV_FUNC_AVUTIL_MASK,
     85    AV_FUNC_AVUTIL_54 = AV_FUNC_54 | AV_FUNC_AVUTIL_MASK,
     86    AV_FUNC_AVUTIL_55 = AV_FUNC_55 | AV_FUNC_AVUTIL_MASK,
     87    AV_FUNC_AVUTIL_56 = AV_FUNC_56 | AV_FUNC_AVUTIL_MASK,
     88    AV_FUNC_AVUTIL_57 = AV_FUNC_57 | AV_FUNC_AVUTIL_MASK,
     89    AV_FUNC_AVUTIL_58 = AV_FUNC_58 | AV_FUNC_AVUTIL_MASK,
     90    AV_FUNC_AVUTIL_59 = AV_FUNC_59 | AV_FUNC_AVUTIL_MASK,
     91    AV_FUNC_AVUTIL_60 = AV_FUNC_60 | AV_FUNC_AVUTIL_MASK,
     92    AV_FUNC_AVUTIL_61 = AV_FUNC_61 | AV_FUNC_AVUTIL_MASK,
     93    AV_FUNC_AVUTIL_62 = AV_FUNC_62 | AV_FUNC_AVUTIL_MASK,
     94    AV_FUNC_AVCODEC_ALL = AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 | AV_FUNC_56 |
     95                          AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 |
     96                          AV_FUNC_61 | AV_FUNC_62,
     97    AV_FUNC_AVUTIL_ALL = AV_FUNC_AVCODEC_ALL | AV_FUNC_AVUTIL_MASK
     98  };
     99 
    100  switch (macro) {
    101    case 53:
    102      version = AV_FUNC_53;
    103      break;
    104    case 54:
    105      version = AV_FUNC_54;
    106      break;
    107    case 55:
    108      version = AV_FUNC_55;
    109      break;
    110    case 56:
    111      version = AV_FUNC_56;
    112      break;
    113    case 57:
    114      version = AV_FUNC_57;
    115      break;
    116    case 58:
    117      version = AV_FUNC_58;
    118      break;
    119    case 59:
    120      version = AV_FUNC_59;
    121      break;
    122    case 60:
    123      version = AV_FUNC_60;
    124      break;
    125    case 61:
    126      version = AV_FUNC_61;
    127      break;
    128    case 62:
    129      version = AV_FUNC_62;
    130      break;
    131    default:
    132      FFMPEGV_LOG("Unknown avcodec version: %d", macro);
    133      Unlink();
    134      return isFFMpeg ? ((macro > 57) ? LinkResult::UnknownFutureFFMpegVersion
    135                                      : LinkResult::UnknownOlderFFMpegVersion)
    136                      // All LibAV versions<54.35.1 are blocked, therefore we
    137                      // must be dealing with a later one.
    138                      : LinkResult::UnknownFutureLibAVVersion;
    139  }
    140 
    141  FFMPEGP_LOG("version: 0x%x, macro: %d, micro: %d, isFFMpeg: %s", version,
    142              macro, micro, isFFMpeg ? "yes" : "no");
    143 
    144 #define AV_FUNC_OPTION_SILENT(func, ver)                                \
    145  if ((ver) & version) {                                                \
    146    if (!((func) = (decltype(func))PR_FindSymbol(                       \
    147              ((ver) & AV_FUNC_AVUTIL_MASK) ? mAVUtilLib : mAVCodecLib, \
    148              #func))) {                                                \
    149    }                                                                   \
    150  } else {                                                              \
    151    (func) = (decltype(func))nullptr;                                   \
    152  }
    153 
    154 #define AV_FUNC_OPTION(func, ver)                             \
    155  AV_FUNC_OPTION_SILENT(func, ver)                            \
    156  if ((ver) & version && (func) == (decltype(func))nullptr) { \
    157    FFMPEGP_LOG("Couldn't load function " #func);             \
    158  }
    159 
    160 #define AV_FUNC(func, ver)                              \
    161  AV_FUNC_OPTION(func, ver)                             \
    162  if ((ver) & version && !(func)) {                     \
    163    Unlink();                                           \
    164    return isFFMpeg ? LinkResult::MissingFFMpegFunction \
    165                    : LinkResult::MissingLibAVFunction; \
    166  }
    167 
    168  AV_FUNC(av_lockmgr_register, AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 |
    169                                   AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58)
    170  AV_FUNC(avcodec_alloc_context3, AV_FUNC_AVCODEC_ALL)
    171  AV_FUNC(avcodec_close, AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 | AV_FUNC_56 |
    172                             AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 |
    173                             AV_FUNC_61)
    174 
    175  AV_FUNC(avcodec_decode_audio4, AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 |
    176                                     AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58)
    177  AV_FUNC(avcodec_decode_video2, AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 |
    178                                     AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58)
    179  AV_FUNC(avcodec_find_decoder, AV_FUNC_AVCODEC_ALL)
    180  AV_FUNC(avcodec_find_decoder_by_name,
    181          AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61 | AV_FUNC_62)
    182  AV_FUNC(avcodec_find_encoder, AV_FUNC_AVCODEC_ALL)
    183  AV_FUNC(avcodec_find_encoder_by_name,
    184          AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61 | AV_FUNC_62)
    185  AV_FUNC(avcodec_flush_buffers, AV_FUNC_AVCODEC_ALL)
    186  AV_FUNC(avcodec_open2, AV_FUNC_AVCODEC_ALL)
    187  AV_FUNC(avcodec_register_all, AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 |
    188                                    AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58)
    189  AV_FUNC(av_init_packet, (AV_FUNC_55 | AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58 |
    190                           AV_FUNC_59 | AV_FUNC_60))
    191  AV_FUNC(av_parser_init, AV_FUNC_AVCODEC_ALL)
    192  AV_FUNC(av_parser_close, AV_FUNC_AVCODEC_ALL)
    193  AV_FUNC(av_parser_parse2, AV_FUNC_AVCODEC_ALL)
    194  AV_FUNC(avcodec_align_dimensions, AV_FUNC_AVCODEC_ALL)
    195  AV_FUNC(avcodec_alloc_frame, (AV_FUNC_53 | AV_FUNC_54))
    196  AV_FUNC(avcodec_get_frame_defaults, (AV_FUNC_53 | AV_FUNC_54))
    197  AV_FUNC(avcodec_free_frame, AV_FUNC_54)
    198  AV_FUNC(avcodec_send_packet,
    199          AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61 | AV_FUNC_62)
    200  AV_FUNC(avcodec_receive_packet,
    201          AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61 | AV_FUNC_62)
    202  AV_FUNC(avcodec_send_frame,
    203          AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61 | AV_FUNC_62)
    204  AV_FUNC(avcodec_receive_frame,
    205          AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61 | AV_FUNC_62)
    206  AV_FUNC(avcodec_default_get_buffer2,
    207          (AV_FUNC_55 | AV_FUNC_56 | AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 |
    208           AV_FUNC_60 | AV_FUNC_61 | AV_FUNC_62))
    209  AV_FUNC(av_packet_alloc, (AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 |
    210                            AV_FUNC_61 | AV_FUNC_62))
    211  AV_FUNC(av_packet_unref, (AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 |
    212                            AV_FUNC_61 | AV_FUNC_62))
    213  AV_FUNC(av_packet_free, (AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 |
    214                           AV_FUNC_61 | AV_FUNC_62))
    215  AV_FUNC(avcodec_descriptor_get, AV_FUNC_AVCODEC_ALL)
    216  AV_FUNC(av_log_set_callback, AV_FUNC_AVUTIL_ALL)
    217  AV_FUNC(av_log_set_level, AV_FUNC_AVUTIL_ALL)
    218  AV_FUNC(av_malloc, AV_FUNC_AVUTIL_ALL)
    219  AV_FUNC(av_freep, AV_FUNC_AVUTIL_ALL)
    220  AV_FUNC(av_frame_alloc,
    221          (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
    222           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
    223           AV_FUNC_AVUTIL_61 | AV_FUNC_AVUTIL_62))
    224  AV_FUNC(av_frame_clone,
    225          (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
    226           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
    227           AV_FUNC_AVUTIL_61 | AV_FUNC_AVUTIL_62))
    228  AV_FUNC(av_frame_free,
    229          (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
    230           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
    231           AV_FUNC_AVUTIL_61 | AV_FUNC_AVUTIL_62))
    232  AV_FUNC(av_frame_unref,
    233          (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
    234           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
    235           AV_FUNC_AVUTIL_61 | AV_FUNC_AVUTIL_62))
    236  AV_FUNC(av_frame_get_buffer,
    237          (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
    238           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
    239           AV_FUNC_AVUTIL_61 | AV_FUNC_AVUTIL_62))
    240  AV_FUNC(av_frame_make_writable,
    241          (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
    242           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
    243           AV_FUNC_AVUTIL_61 | AV_FUNC_AVUTIL_62))
    244  AV_FUNC(av_image_check_size, AV_FUNC_AVUTIL_ALL)
    245  AV_FUNC(av_image_get_buffer_size, AV_FUNC_AVUTIL_ALL)
    246  AV_FUNC_OPTION(av_channel_layout_default,
    247                 AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61 | AV_FUNC_AVUTIL_62)
    248  AV_FUNC_OPTION(av_channel_layout_from_mask,
    249                 AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61 | AV_FUNC_AVUTIL_62)
    250  AV_FUNC_OPTION(av_channel_layout_copy,
    251                 AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61 | AV_FUNC_AVUTIL_62)
    252  AV_FUNC_OPTION(av_buffer_get_opaque,
    253                 (AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 | AV_FUNC_AVUTIL_58 |
    254                  AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61 |
    255                  AV_FUNC_AVUTIL_62))
    256  AV_FUNC(av_buffer_create,
    257          (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
    258           AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
    259           AV_FUNC_61 | AV_FUNC_62))
    260  AV_FUNC_OPTION(av_frame_get_colorspace,
    261                 AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
    262                     AV_FUNC_AVUTIL_58)
    263  AV_FUNC_OPTION(av_frame_get_color_range,
    264                 AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57 |
    265                     AV_FUNC_AVUTIL_58)
    266  AV_FUNC(av_strerror, AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 |
    267                           AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61 |
    268                           AV_FUNC_AVUTIL_62)
    269  AV_FUNC(av_get_sample_fmt_name, AV_FUNC_AVUTIL_ALL)
    270  AV_FUNC(av_dict_set, AV_FUNC_AVUTIL_ALL)
    271  AV_FUNC(av_dict_free, AV_FUNC_AVUTIL_ALL)
    272  AV_FUNC(av_opt_set, AV_FUNC_AVUTIL_ALL)
    273  AV_FUNC(av_opt_set_double, AV_FUNC_AVUTIL_ALL)
    274  AV_FUNC(av_opt_set_int, AV_FUNC_AVUTIL_ALL)
    275  AV_FUNC(avcodec_free_context, AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 |
    276                                    AV_FUNC_60 | AV_FUNC_61 | AV_FUNC_62)
    277  AV_FUNC_OPTION_SILENT(avcodec_get_hw_config, AV_FUNC_58 | AV_FUNC_59 |
    278                                                   AV_FUNC_60 | AV_FUNC_61 |
    279                                                   AV_FUNC_62)
    280  AV_FUNC_OPTION_SILENT(av_codec_is_decoder, AV_FUNC_58 | AV_FUNC_59 |
    281                                                 AV_FUNC_60 | AV_FUNC_61 |
    282                                                 AV_FUNC_62)
    283  AV_FUNC_OPTION_SILENT(av_codec_is_encoder, AV_FUNC_58 | AV_FUNC_59 |
    284                                                 AV_FUNC_60 | AV_FUNC_61 |
    285                                                 AV_FUNC_62)
    286  AV_FUNC_OPTION_SILENT(av_codec_iterate, AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 |
    287                                              AV_FUNC_61 | AV_FUNC_62)
    288  AV_FUNC_OPTION_SILENT(av_hwdevice_ctx_init,
    289                        AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 |
    290                            AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61 |
    291                            AV_FUNC_AVUTIL_62)
    292  AV_FUNC_OPTION_SILENT(av_hwdevice_ctx_alloc,
    293                        AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 |
    294                            AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61 |
    295                            AV_FUNC_AVUTIL_62)
    296  AV_FUNC_OPTION_SILENT(
    297      av_buffer_ref, AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 | AV_FUNC_AVUTIL_60 |
    298                         AV_FUNC_AVUTIL_61 | AV_FUNC_AVUTIL_62)
    299  AV_FUNC_OPTION_SILENT(av_buffer_unref, AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 |
    300                                             AV_FUNC_AVUTIL_60 |
    301                                             AV_FUNC_AVUTIL_61 |
    302                                             AV_FUNC_AVUTIL_62)
    303  AV_FUNC_OPTION_SILENT(av_hwframe_ctx_alloc,
    304                        AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 |
    305                            AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61 |
    306                            AV_FUNC_AVUTIL_62)
    307  AV_FUNC_OPTION_SILENT(av_hwframe_ctx_init,
    308                        AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 |
    309                            AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61 |
    310                            AV_FUNC_AVUTIL_62)
    311 
    312 #ifdef MOZ_WIDGET_GTK
    313  AV_FUNC_OPTION_SILENT(av_hwdevice_hwconfig_alloc, AV_FUNC_58 | AV_FUNC_59 |
    314                                                        AV_FUNC_60 |
    315                                                        AV_FUNC_61 | AV_FUNC_62)
    316  AV_FUNC_OPTION_SILENT(
    317      av_hwdevice_get_hwframe_constraints,
    318      AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61 | AV_FUNC_62)
    319  AV_FUNC_OPTION_SILENT(
    320      av_hwframe_constraints_free,
    321      AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61 | AV_FUNC_62)
    322  AV_FUNC_OPTION_SILENT(
    323      av_hwframe_transfer_get_formats,
    324      AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61 | AV_FUNC_62)
    325  AV_FUNC_OPTION_SILENT(
    326      av_hwdevice_ctx_create_derived,
    327      AV_FUNC_58 | AV_FUNC_59 | AV_FUNC_60 | AV_FUNC_61 | AV_FUNC_62)
    328  AV_FUNC_OPTION_SILENT(avcodec_get_name, AV_FUNC_57 | AV_FUNC_58 | AV_FUNC_59 |
    329                                              AV_FUNC_60 | AV_FUNC_61 |
    330                                              AV_FUNC_62)
    331  AV_FUNC_OPTION_SILENT(av_get_pix_fmt_string,
    332                        AV_FUNC_AVUTIL_58 | AV_FUNC_AVUTIL_59 |
    333                            AV_FUNC_AVUTIL_60 | AV_FUNC_AVUTIL_61 |
    334                            AV_FUNC_AVUTIL_62)
    335 #endif
    336 
    337  AV_FUNC_OPTION(av_tx_init, AV_FUNC_AVUTIL_ALL)
    338  AV_FUNC_OPTION(av_tx_uninit, AV_FUNC_AVUTIL_ALL)
    339 
    340 #ifdef MOZ_WIDGET_ANDROID
    341  AV_FUNC(av_mediacodec_release_buffer, AV_FUNC_AVCODEC_ALL);
    342  AV_FUNC(moz_avcodec_mediacodec_is_eos, AV_FUNC_AVCODEC_ALL);
    343 #endif
    344 
    345 #undef AV_FUNC
    346 #undef AV_FUNC_OPTION
    347 
    348  if (avcodec_register_all) {
    349    avcodec_register_all();
    350  }
    351 
    352  UpdateLogLevel();
    353  av_log_set_callback(Log);
    354  return LinkResult::Success;
    355 }
    356 
    357 void FFmpegLibWrapper::Unlink() {
    358  if (av_lockmgr_register) {
    359    // Registering a null lockmgr cause the destruction of libav* global mutexes
    360    // as the default lockmgr that allocated them will be deregistered.
    361    // This prevents ASAN and valgrind to report sizeof(pthread_mutex_t) leaks.
    362    av_lockmgr_register(nullptr);
    363  }
    364 #ifndef MOZ_TSAN
    365  // With TSan, we cannot unload libav once we have loaded it because
    366  // TSan does not support unloading libraries that are matched from its
    367  // suppression list. Hence we just keep the library loaded in TSan builds.
    368  if (mAVUtilLib && mAVUtilLib != mAVCodecLib) {
    369    PR_UnloadLibrary(mAVUtilLib);
    370  }
    371  if (mAVCodecLib) {
    372    PR_UnloadLibrary(mAVCodecLib);
    373  }
    374 #endif
    375  PodZero(this);
    376 }
    377 
    378 void FFmpegLibWrapper::UpdateLogLevel() {
    379  LogModule* mod = sFFmpegLibLog;
    380  av_log_set_level(ToLibLogLevel(mod->Level()));
    381 }
    382 
    383 /* static */ void FFmpegLibWrapper::RegisterCallbackLogLevel(
    384    PrefChangedFunc aCallback) {
    385  if (!NS_IsMainThread()) {
    386    NS_DispatchToMainThread(NS_NewRunnableFunction(
    387        __func__, [aCallback]() { RegisterCallbackLogLevel(aCallback); }));
    388    return;
    389  }
    390 
    391  Preferences::RegisterCallback(aCallback, "logging.FFmpegLib"_ns);
    392 }
    393 
    394 /* static */ int FFmpegLibWrapper::ToLibLogLevel(LogLevel aLevel) {
    395  switch (aLevel) {
    396    case LogLevel::Disabled:
    397      return AV_LOG_QUIET;
    398    case LogLevel::Error:
    399      return AV_LOG_ERROR;
    400    case LogLevel::Warning:
    401      return AV_LOG_WARNING;
    402    case LogLevel::Info:
    403      return AV_LOG_INFO;
    404    case LogLevel::Debug:
    405      return AV_LOG_DEBUG;
    406    case LogLevel::Verbose:
    407      return AV_LOG_TRACE;
    408    default:
    409      MOZ_ASSERT_UNREACHABLE("Unhandled log level!");
    410      break;
    411  }
    412  return AV_LOG_QUIET;
    413 }
    414 
    415 /* static */ LogLevel FFmpegLibWrapper::FromLibLogLevel(int aLevel) {
    416  switch (aLevel) {
    417    case AV_LOG_QUIET:
    418      return LogLevel::Disabled;
    419    case AV_LOG_PANIC:
    420    case AV_LOG_FATAL:
    421    case AV_LOG_ERROR:
    422      return LogLevel::Error;
    423    case AV_LOG_WARNING:
    424      return LogLevel::Warning;
    425    case AV_LOG_INFO:
    426      return LogLevel::Info;
    427    case AV_LOG_DEBUG:
    428      return LogLevel::Debug;
    429    case AV_LOG_VERBOSE:
    430    case AV_LOG_TRACE:
    431      return LogLevel::Verbose;
    432    default:
    433      MOZ_ASSERT_UNREACHABLE("Unhandled log level!");
    434      break;
    435  }
    436  return LogLevel::Disabled;
    437 }
    438 
    439 /* static */ void FFmpegLibWrapper::Log(void* aPtr, int aLevel,
    440                                        const char* aFmt, va_list aArgs) {
    441  LogLevel level = FromLibLogLevel(aLevel);
    442  if (MOZ_LOG_TEST(sFFmpegLibLog, level)) {
    443    nsAutoCString msg;
    444    msg.AppendVprintf(aFmt, aArgs);
    445    MOZ_LOG(sFFmpegLibLog, level, ("[%p] %s", aPtr, msg.get()));
    446  }
    447 }
    448 
    449 #ifdef MOZ_WIDGET_GTK
    450 bool FFmpegLibWrapper::IsVAAPIAvailable() const {
    451 #  define VA_FUNC_LOADED(func) ((func) != nullptr)
    452  return VA_FUNC_LOADED(avcodec_get_hw_config) &&
    453         VA_FUNC_LOADED(av_hwdevice_ctx_alloc) &&
    454         VA_FUNC_LOADED(av_hwdevice_ctx_init) &&
    455         VA_FUNC_LOADED(av_hwdevice_hwconfig_alloc) &&
    456         VA_FUNC_LOADED(av_hwdevice_get_hwframe_constraints) &&
    457         VA_FUNC_LOADED(av_hwframe_constraints_free) &&
    458         VA_FUNC_LOADED(av_buffer_ref) && VA_FUNC_LOADED(av_buffer_unref) &&
    459         VA_FUNC_LOADED(av_hwframe_transfer_get_formats) &&
    460         VA_FUNC_LOADED(av_hwdevice_ctx_create_derived) &&
    461         VA_FUNC_LOADED(av_hwframe_ctx_alloc) && VA_FUNC_LOADED(av_dict_set) &&
    462         VA_FUNC_LOADED(av_dict_free) && VA_FUNC_LOADED(avcodec_get_name) &&
    463         VA_FUNC_LOADED(av_get_pix_fmt_string) &&
    464         VALibWrapper::IsVAAPIAvailable();
    465 }
    466 #endif
    467 
    468 }  // namespace mozilla