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