# Copyright (c) 2018 Mathieu Duponchelle # # This file is part of the FFmpeg Meson build # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, see . project('FFmpeg', 'c', meson_version: '>= 0.59', license: 'LGPL2.1+', default_options: [ 'buildtype=debugoptimized', 'c_std=c99', 'cpp_std=c++11'], version: '4.4.3', ) # HOWTO: # # Get meson >= 0.59 from pip or your distro's package manager then: # # meson build && ninja -C build # Overview of the configure process: # # This port is relatively faithful to the original configure script: # We first gather system information (compiler checks, dependencies, ..), # then pass this information through a temporary configure file to a # script named "depresolver.py". This script implements the logic implemented # in the configure script by the "check_deps" function, the dependency # graph lives in a python file named "depgraph.py". # # That graph is made up of a set of nodes, each optionally containing # information about the components it selects, depends on or conflicts # with. # # The depresolver script returns two things: # # * A set of key-value pairs, indicating for each component whether # it was enabled or not. # * A second set of key-value pairs, associating to each component # the set of enabled components it depended upon. # # The first set is used to determine which sources to compile in, # using the dictionaries present in the relevant meson.build definitions # in the subdirectories (eg. libavutil/meson.build) # # The second set is used to compute the external dependencies passed # to the various build targets, when a component is compiled into library # we check whether a @0@_flattened_deps.format(component) variable was # set, and add it to the set of dependencies for that library. # # Various other python scripts have been implemented to reproduce other # bits of logic in the configure script, eg. find_things.py ... # TODO: # # * Assembler extensions (mmx etc..) # * Porting the FATE test suite # * Continue going over the configure script and importing various # bits of logic common_incs = [include_directories('.')] python3 = import('python').find_installation() cc = meson.get_compiler('c') languages_map = {} if cc.get_id() == 'msvc' # Ignore several spurious warnings for things FFmpeg does very commonly # If a warning is completely useless and spammy, use '/wdXXXX' to suppress it # If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once # NOTE: Only add warnings here if you are sure they're spurious or they're # for a pattern that ffmpeg does not care about add_project_arguments( '/wo4005', # macro redefinition (this likely need to be fixed) '/wd4018', # implicit signed/unsigned conversion '/wd4146', # unary minus on unsigned (beware INT_MIN) '/wd4244', # lossy type conversion (e.g. double -> int) '/wd4305', # truncating type conversion (e.g. double -> float) '/wd4554', # operator precedence '/wd4114', # same type qualifier used more than once '/wd4028', # formal parameter {n} different from declaration '/wd4090', # 'function': different 'const' qualifiers '/wd4133', # 'type' : incompatible types - from 'type1' to 'type2' cc.get_supported_arguments(['/utf-8']), # set the input encoding to utf-8 language : 'c') endif project_c_args = [ '-D_ISOC99_SOURCE', '-D_GNU_SOURCE', '-D_LARGEFILE_SOURCE', '-DPIC', '-Wno-parentheses', '-Wno-pointer-sign', '-Wno-switch', '-Wno-format-truncation', '-Wno-deprecated-declarations', '-Wno-unused-function', '-Wno-maybe-uninitialized', '-Wno-discarded-qualifiers', '-Wno-unused-variable', '-Wno-bool-operation', '-Wno-incompatible-pointer-types', '-Wno-address', ] # Work around meson subprojects ignoring default_options # https://github.com/mesonbuild/meson/issues/1889#issuecomment-1275991958 if meson.is_subproject() and meson.version().version_compare('< 0.63') project_c_args += ['-std=c99'] endif project_c_args = cc.get_supported_arguments(project_c_args) thread_dep = dependency('threads') common_deps = [thread_dep] if host_machine.system() == 'windows' common_deps += [cc.find_library('ws2_32')] endif conf = configuration_data() document_list = [ 'doc', 'htmlpages', 'manpages', 'podpages', 'txtpages', ] example_list = [ 'avio_dir_cmd_example', 'avio_reading_example', 'decode_audio_example', 'decode_video_example', 'demuxing_decoding_example', 'encode_audio_example', 'encode_video_example', 'extract_mvs_example', 'filter_audio_example', 'filtering_audio_example', 'filtering_video_example', 'http_multiclient_example', 'hw_decode_example', 'metadata_example', 'muxing_example', 'qsvdec_example', 'remuxing_example', 'resampling_audio_example', 'scaling_video_example', 'transcode_aac_example', 'transcoding_example', 'vaapi_encode_example', 'vaapi_transcode_example', ] arch_ext_list_arm = [ 'armv5te', 'armv6', 'armv6t2', 'armv8', 'neon', 'vfp', 'vfpv3', 'setend', ] arch_ext_list_ppc = [ 'altivec', 'dcbzl', 'ldbrx', 'power8', 'ppc4xx', 'vsx', ] arch_ext_list_x86_simd = [ 'aesni', 'amd3dnow', 'amd3dnowext', 'avx', 'avx2', 'avx512', 'fma3', 'fma4', 'mmx', 'mmxext', 'sse', 'sse2', 'sse3', 'sse4', 'sse42', 'ssse3', 'xop', ] arch_ext_list_x86 = arch_ext_list_x86_simd + [ 'cpunop', 'i686', ] arch_ext_list_mips = [ 'mipsfpu', 'mips32r2', 'mips32r5', 'mips64r2', 'mips32r6', 'mips64r6', 'mipsdsp', 'mipsdspr2', 'msa', ] arch_ext_list_loongson = [ 'loongson2', 'loongson3', 'mmi', ] arch_ext_list = arch_ext_list_arm + arch_ext_list_ppc + arch_ext_list_x86 + arch_ext_list_mips + arch_ext_list_loongson arch_features = [ 'aligned_stack', 'fast_64bit', 'fast_clz', 'fast_cmov', 'local_aligned', 'simd_align_16', 'simd_align_32', 'simd_align_64', ] builtin_list = [ 'atomic_cas_ptr', 'machine_rw_barrier', 'MemoryBarrier', 'mm_empty', 'rdtsc', 'sem_timedwait', 'sync_val_compare_and_swap', ] complex_funcs = [ 'cabs', 'cexp', ] have_list_cmdline = [ 'inline_asm', 'symver', 'x86asm', ] have_list_pub = [ 'bigendian', 'fast_unaligned', ] headers_list = [ 'arpa_inet_h', 'asm_types_h', 'cdio_paranoia_h', 'cdio_paranoia_paranoia_h', 'cuda_h', 'dispatch_dispatch_h', 'dev_bktr_ioctl_bt848_h', 'dev_bktr_ioctl_meteor_h', 'dev_ic_bt8xx_h', 'dev_video_bktr_ioctl_bt848_h', 'dev_video_meteor_ioctl_meteor_h', 'direct_h', 'dirent_h', 'dxgidebug_h', 'dxva_h', 'ES2_gl_h', 'gsm_h', 'io_h', 'linux_perf_event_h', 'machine_ioctl_bt848_h', 'machine_ioctl_meteor_h', 'malloc_h', 'opencv2_core_core_c_h', 'OpenGL_gl3_h', 'poll_h', 'sys_param_h', 'sys_resource_h', 'sys_select_h', 'sys_soundcard_h', 'sys_time_h', 'sys_un_h', 'sys_videoio_h', 'termios_h', 'udplite_h', 'unistd_h', 'valgrind_valgrind_h', 'windows_h', 'winsock2_h', ] intrinsics_list = [ 'intrinsics_neon', ] math_funcs = [ 'atanf', 'atan2f', 'cbrt', 'cbrtf', 'copysign', 'cosf', 'erf', 'exp2', 'exp2f', 'expf', 'hypot', 'isfinite', 'isinf', 'isnan', 'ldexpf', 'llrint', 'llrintf', 'log2', 'log2f', 'log10f', 'lrint', 'lrintf', 'powf', 'rint', 'round', 'roundf', 'sinf', 'trunc', 'truncf', ] system_features = [ 'dos_paths', 'libc_msvcrt', 'MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS', 'section_data_rel_ro', 'threads', 'uwp', 'winrt', ] system_funcs = [ 'access', 'aligned_malloc', 'arc4random', 'clock_gettime', 'closesocket', 'CommandLineToArgvW', 'fcntl', 'getaddrinfo', 'gethrtime', 'getopt', 'GetProcessAffinityMask', 'GetProcessMemoryInfo', 'GetProcessTimes', 'getrusage', 'GetSystemTimeAsFileTime', 'gettimeofday', 'glob', 'glXGetProcAddress', 'gmtime_r', 'inet_aton', 'isatty', 'kbhit', 'localtime_r', 'lstat', 'lzo1x_999_compress', 'mach_absolute_time', 'MapViewOfFile', 'memalign', 'mkstemp', 'mmap', 'mprotect', 'nanosleep', 'PeekNamedPipe', 'posix_memalign', 'pthread_cancel', 'sched_getaffinity', 'SecItemImport', 'SetConsoleTextAttribute', 'SetConsoleCtrlHandler', 'setmode', 'setrlimit', 'Sleep', 'strerror_r', 'sysconf', 'sysctl', 'usleep', 'UTGetOSTypeFromString', 'VirtualAlloc', 'wglGetProcAddress', ] system_libraries = [ 'bcrypt', 'vaapi_drm', 'vaapi_x11', 'vdpau_x11', ] threads_list = [ 'pthreads', 'os2threads', 'w32threads', ] toolchain_features = [ 'as_arch_directive', 'as_dn_directive', 'as_fpu_directive', 'as_func', 'as_object_arch', 'asm_mod_q', 'blocks_extension', 'ebp_available', 'ebx_available', 'gnu_as', 'gnu_windres', 'ibm_asm', 'inline_asm_direct_symbol_refs', 'inline_asm_labels', 'inline_asm_nonlocal_labels', 'pragma_deprecated', 'rsync_contimeout', 'symver_asm_label', 'symver_gnu_asm', 'vfp_args', 'xform_asm', 'xmm_clobbers', ] types_list = [ 'kCMVideoCodecType_HEVC', 'socklen_t', 'struct_addrinfo', 'struct_group_source_req', 'struct_ip_mreq_source', 'struct_ipv6_mreq', 'struct_msghdr_msg_flags', 'struct_pollfd', 'struct_rusage_ru_maxrss', 'struct_sctp_event_subscribe', 'struct_sockaddr_in6', 'struct_sockaddr_sa_len', 'struct_sockaddr_storage', 'struct_stat_st_mtim_tv_nsec', 'struct_v4l2_frmivalenum_discrete', ] conf.set('runtime_cpudetect', 1) asm = get_option('asm') inline_asm = get_option('inline_asm') conf.set10('asm', asm.allowed()) if inline_asm.allowed() conf.set10('inline_asm', cc.compiles( 'void foo(void){ __asm__ volatile(@0@); }'.format('"" ::'), name: 'inline_asm' ) ) else conf.set10('inline_asm', false) endif arch_ext_list_external = [] arch_ext_list_inline = [] foreach arch_ext : arch_ext_list conf.set10(arch_ext, conf.get('asm') == 1) conf.set10('@0@_external'.format(arch_ext), conf.get('asm') == 1) conf.set10('@0@_inline'.format(arch_ext), conf.get('asm') == 1 and conf.get('inline_asm') == 1) arch_ext_list_external += ['@0@_external'.format(arch_ext)] arch_ext_list_inline += ['@0@_inline'.format(arch_ext)] endforeach have_list = (arch_ext_list + arch_ext_list_external + arch_ext_list_inline + arch_features + builtin_list + complex_funcs + have_list_cmdline + have_list_pub + headers_list + intrinsics_list + math_funcs + system_features + system_funcs + system_libraries + threads_list + toolchain_features + types_list + [ 'makeinfo', 'makeinfo_html', 'mmx2', 'opencl_d3d11', 'opencl_drm_arm', 'opencl_drm_beignet', 'opencl_dxva2', 'opencl_vaapi_beignet', 'opencl_vaapi_intel_media', 'perl', 'pod2man', 'texi2html', ]) arch_features = [ ['aligned_stack', ['aarch64', 'ppc', 'x86']], ['fast_64bit', ['aarch64', 'alpha', 'ia64', 'mips64', 'parisc64', 'ppc64', 'sparc64', 'x86_64']], ['fast_clz', ['aarch64', 'alpha', 'avr32', 'mips', 'ppc', 'x86']], ['fast_unaligned', ['aarch64', 'ppc', 'x86']], ['simd_align_16', ['altivec', 'neon', 'sse']], ['simd_align_32', ['avx']], ['simd_align_64', ['avx512']], ] arch_list = [ 'aarch64', 'alpha', 'arm', 'avr32', 'avr32_ap', 'avr32_uc', 'bfin', 'ia64', 'm68k', 'mips', 'mips64', 'parisc', 'ppc', 'ppc64', 's390', 'sh4', 'sparc', 'sparc64', 'tilegx', 'tilepro', 'tomi', 'x86', 'x86_32', 'x86_64', ] ioctl_meteor_headers = [ ['dev/bktr/ioctl_meteor.h', 'dev/bktr/ioctl_bt848.h'], ['machine/ioctl_meteor.h', 'machine/ioctl_bt848.h'], ['dev/video/meteor/ioctl_meteor.h', 'dev/video/bktr/ioctl_bt848.h'], ['dev/ic/bt8xx.h']] headers_found = false foreach headers : ioctl_meteor_headers if not headers_found n_headers_found = 0 foreach header : headers header_found = cc.has_header(header) if header_found n_headers_found += 1 endif endforeach headers_found = headers.length() == n_headers_found foreach header : headers conf.set10(header.underscorify(), headers_found) endforeach endif endforeach check_structs = [ ['struct rusage', 'ru_maxrss', '#include \n#include\n'], ['struct stat', 'st_mtim.tv_nsec', '#include \n#define _BSD_SOURCE'], ] hwaccel_autodetect_library_list = [ 'amf', 'audiotoolbox', 'crystalhd', 'cuda', 'cuvid', 'd3d11va', 'dxva2', 'ffnvcodec', 'nvdec', 'nvenc', 'vaapi', 'vdpau', 'videotoolbox', 'v4l2_m2m', 'xvmc', ] external_autodetect_library_list = [ 'alsa', 'appkit', 'avfoundation', 'bzlib', 'coreimage', 'iconv', 'libxcb', 'libxcb_shm', 'libxcb_shape', 'libxcb_xfixes', 'lzma', 'mediafoundation', 'schannel', 'sdl2', 'securetransport', 'sndio', 'xlib', 'zlib', ] library_gpl_list = [ 'avisynth', 'frei0r', 'libcdio', 'libdavs2', 'librubberband', 'libvidstab', 'libx264', 'libx265', 'libxavs', 'libxavs2', 'libxvid', ] library_nonfree_list = [ 'decklink', 'libfdk_aac', 'openssl', 'libtls', ] library_version3_list = [ 'gmp', 'libaribb24', 'liblensfun', 'libopencore_amrnb', 'libopencore_amrwb', 'libvo_amrwbenc', 'rkmpp', ] library_gplv3_list = [ 'libsmbclient', ] all_checks = [] cpp_cond = ''' #include <@0@> #if !(@1@) #error "unsatisfied condition: @1@" #endif int main(void) { return 0; } ''' check_winapi_family = ''' #ifdef WINAPI_FAMILY #include #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #error not desktop #endif #endif int main(void) { return 0; } ''' libc_type = '' if cc.links(cpp_cond.format('features.h', 'defined __UCLIBC__')) libc_type = 'uclibc' project_c_args += ['-D_POSIX_C_SOURCE=200112', '-D_XOPEN_SOURCE=600'] elif cc.links(cpp_cond.format('features.h', 'defined __GLIBC__')) libc_type = 'glibc' project_c_args += ['-D_POSIX_C_SOURCE=200112', '-D_XOPEN_SOURCE=600'] elif cc.links(cpp_cond.format('newlib.h', 'defined _NEWLIB_VERSION')) libc_type = 'newlib' project_c_args += ['-U__STRICT_ANSI__', '-D_XOPEN_SOURCE=600'] elif cc.links(cpp_cond.format('_mingw.h', 'defined __MINGW64_VERSION_MAJOR')) libc_type = 'mingw64' if cc.links(cpp_cond.format('_mingw.h', '__MINGW64_VERSION_MAJOR < 3')) # FIXME compat endif project_c_args += ['-U__STRICT_ANSI__', '-D__USE_MINGW_ANSI_STDIO=1'] if cc.get_id() == 'gcc' project_c_args += ['-D__printf__=__gnu_printf__'] endif if cc.links(cpp_cond.format('windows.h', '!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600')) project_c_args += ['-D_WIN32_WINNT=0x0600'] endif elif (cc.links(cpp_cond.format('_mingw.h', 'defined __MINGW_VERSION')) or cc.links(cpp_cond.format('_mingw.h', 'defined __MINGW32_VERSION'))) libc_type = 'mingw32' if cc.links(cpp_cond.format('_mingw.h', '__MINGW32_MAJOR_VERSION > 3 || (__MINGW32_MAJOR_VERSION == 3 && __MINGW32_MINOR_VERSION >= 15')) error('MinGW32 runtime version must be >= 3.15') endif project_c_args += ['-U__STRICT_ANSI__', '-D__USE_MINGW_ANSI_STDIO=1'] if cc.links(cpp_cond.format('_mingw.h', '__MSVCRT_VERSION__ < 0x0700')) project_c_args += ['-D__MSVCRT_VERSION__=0x0700'] endif if cc.links(cpp_cond.format('windows.h', '!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600')) project_c_args += ['-D_WIN32_WINNT=0x0600'] endif if cc.get_id() == 'gcc' project_c_args += ['-D__printf__=__gnu_printf__'] endif elif cc.links(cpp_cond.format('crtversion.h', 'defined _VC_CRT_MAJOR_VERSION')) libc_type = 'msvcrt' if cc.links(cpp_cond.format('crtversion.h', '_VC_CRT_MAJOR_VERSION < 14')) # FIXME compat endif project_c_args += ['-D_USE_MATH_DEFINES', '-D_CRT_SECURE_NO_WARNINGS', '-D_CRT_NONSTDC_NO_WARNINGS'] if (cc.links(cpp_cond.format('stdlib.h', 'defined(_WIN32_WINNT)')) or cc.links(check_winapi_family)) project_c_args += ['-D_WIN32_WINNT=0x0600'] endif if not cc.has_function('strtoll') project_c_args += ['-Dstrtoll=_strtoi64'] endif if not cc.has_function('strtoull') project_c_args += ['-Dstrtoull=_strtoui64'] endif elif cc.links(cpp_cond.format('stddef.h', 'defined __KLIBC__')) libc_type = 'klibc' elif cc.links(cpp_cond.format('stddef.h', 'defined __BIONIC__')) libc_type = 'bionic' elif cc.links(cpp_cond.format('sys/brand.h', 'defined LABELED_BRAND_NAME')) libc_type = 'solaris' project_c_args += ['-D__EXTENSIONS__', '-D_XOPEN_SOURCE=600'] endif if not cc.has_function('localtime_r', prefix: '#include ', args: project_c_args) if cc.has_function('localtime_r', prefix: '#include ', args: project_c_args + ['-D_POSIX_C_SOURCE=200112', '-D_XOPEN_SOURCE=600']) project_c_args += ['-D_POSIX_C_SOURCE=200112', '-D_XOPEN_SOURCE=600'] endif endif if libc_type != '' conf.set('libc_@0@'.format(libc_type), 1) endif conf.set10('pic', conf.get('pic', cc.links(cpp_cond.format('stdlib.h', 'defined(__PIC__) || defined(__pic__) || defined(PIC)')))) check_pkg_config = [ ['alsa', ['alsa/asoundlib.h'], ['snd_pcm_htimestamp'], {}], ['ffnvcodec', ['ffnvcodec/nvEncodeAPI.h', 'ffnvcodec/dynlink_cuda.h', 'ffnvcodec/dynlink_cuviddec.h', 'ffnvcodec/dynlink_nvcuvid.h'], [], {'versions': ['>= 9.1.23.1', ['>= 9.0.18.3', '< 9.1'], ['>= 8.2.15.10', '< 8.3'], ['>= 8.1.24.11', '< 8.2']]}], ['libgme', ['gme/gme.h'], ['gme_new_emu'], {}], ['gnutls', ['gnutls/gnutls.h'], ['gnutls_global_init'], {}], ['libaom', ['aom/aom_codec.h'], ['aom_codec_version'], {'pkg': 'aom', 'version': '>= 0.1.0'}], ['libaribb24', ['aribb24/aribb24.h'], ['arib_instance_new'], {'pkg': 'aribb24', 'version': '> 1.0.3'}], ['lv2', ['lilv-0/lilv/lilv.h'], ['lilv_world_new'], {'pkg': 'lilv-0'}], ['libass', ['ass/ass.h'], ['ass_library_init'], {}], ['libbluray', ['libbluray/bluray.h'], ['bd_open'], {}], ['libbs2b', ['bs2b.h'], ['bs2b_open'], {}], ['libcaca', ['caca.h'], ['caca_create_canvas'], {'pkg': 'caca'}], ['libcdio', ['cdio/cdda.h', 'cdio/paranoia.h'], ['cdio_cddap_open'], {'pkg': 'libcdio_paranoia'}], ['libcdio', ['cdio/paranoia/cdda.h', 'cdio/paranoia/paranoia.h'], ['cdio_cddap_open'], {'pkg': 'libcdio_paranoia'}], ['libdavs2', ['davs2.h'], ['davs2_decoder_open'], {'pkg': 'davs2', 'version': '>= 1.6.0'}], ['libdc1394', ['dc1394/dc1394.h'], ['dc1394_new'], {'pkg': 'libdc1394-2'}], ['libdrm', ['xf86drm.h'], ['drmGetVersion'], {}], ['libfdk_aac', ['fdk-aac/aacenc_lib.h'], ['aacEncOpen'], {'pkg': 'fdk-aac'}], ['libfontconfig', ['fontconfig/fontconfig.h'], ['FcInit'], {'pkg': 'fontconfig'}], ['libfreetype', ['ft2build.h', 'FT_FREETYPE_H'], ['FT_Init_FreeType'], {'pkg': 'freetype2'}], ['libfribidi', ['fribidi.h'], ['fribidi_version_info'], {'pkg': 'fribidi'}], ['libjack', ['jack/jack.h'], ['jack_port_get_latency_range'], {'pkg': 'jack'}], ['libklvanc', ['libklvanc/vanc.h'], ['klvanc_context_create'], {}], ['libkvazaar', ['kvazaar.h'], ['kvz_api_get'], {'pkg': 'kvazaar', 'version': '>= 0.8.1'}], ['liblensfun', ['lensfun.h'], ['lf_db_new'], {'pkg': 'lensfun'}], ['libmfx', ['mfx/mfxvideo.h'], ['MFXInit'], {}], ['libmodplug', ['libmodplug/modplug.h'], ['ModPlug_Load'], {}], ['libopencv', ['opencv2/core/core_c.h'], ['cvCreateImageHeader'], {'pkg': 'opencv'}], ['libopencv', ['opencv/cxcore.h'], ['cvCreateImageHeader'], {'pkg': 'opencv'}], ['libopenh264', ['wels/codec_api.h'], ['WelsGetCodecVersion'], {'pkg': 'openh264'}], ['libdav1d', ['dav1d/dav1d.h'], ['dav1d_version'], {'pkg': 'dav1d', 'version': '>= 0.4.0'}], ['libopenjpeg', ['openjpeg.h'], ['opj_version'], {'pkg': 'libopenjp2', 'version': '>= 2.1.0'}], ['libopenjpeg', ['openjpeg.h'], ['opj_version'], {'pkg': 'libopenjp2', 'version': '>= 2.1.0', 'c_args': ['-DOPJ_STATIC']}], ['libopenmpt', ['libopenmpt/libopenmpt.h'], ['openmpt_module_create'], {'version': '>= 0.2.6557'}], ['libopus', ['opus_multistream.h'], ['opus_multistream_decoder_create', 'opus_multistream_surround_encoder_create'], {'pkg': 'opus'}], ['libpulse', ['pulse/pulseaudio.h'], ['pa_context_new'], {}], ['librabbitmq', ['amqp.h'], ['amqp_new_connection'], {'pkg': 'librabbitmq', 'version': '>= 0.7.1'}], ['librav1e', ['rav1e.h'], ['rav1e_context_new'], {'pkg': 'rav1e', 'version': '>= 0.1.0'}], ['librist', ['librist/librist.h'], ['rist_receiver_create'], {'pkg': 'rist', 'version': '>= 0.2'}], ['librsvg', ['librsvg-2.0/librsvg/rsvg.h'], ['rsvg_handle_render_cairo'], {'pkg': 'librsvg-2.0'}], ['librtmp', ['librtmp/rtmp.h'], ['RTMP_Socket'], {}], ['librubberband', ['rubberband/rubberband-c.h'], ['rubberband_new'], {'pkg': 'rubberband', 'version': '>= 1.8.1'}], ['libshine', ['shine/layer3.h'], ['shine_encode_buffer'], {'pkg': 'shine'}], ['libsmbclient', ['libsmbclient.h'], ['smbc_init'], {'pkg': 'smbclient'}], ['libssh', ['libssh/sftp.h'], ['sftp_init'], {}], ['libspeex', ['speex/speex.h'], ['speex_decoder_init'], {'pkg': 'speex'}], ['libsrt', ['srt/srt.h'], ['srt_socket'], {'pkg': 'srt', 'version': '>= 1.2.0'}], ['libsvtav1', ['EbSvtAv1Enc.h'], ['svt_av1_enc_init_handle'], {'pkg': 'SvtAv1Enc', 'version': '>= 0.8.4'}], ['libtesseract', ['tesseract/capi.h'], ['TessBaseAPICreate'], {'pkg': 'tesseract'}], ['libtls', ['tls.h'], ['tls_configure'], {}], ['libv4l2', ['libv4l2.h'], ['v4l2_ioctl'], {}], ['libvidstab', ['vid.stab/libvidstab.h'], ['vsMotionDetectInit'], {'pkg': 'vidstab', 'version': '>= 0.98'}], ['libvmaf', ['libvmaf.h'], ['compute_vmaf'], {'version': '>= 0.6.2'}], ['libvorbis', ['vorbis/codec.h'], ['vorbis_info_init'], {'pkg': 'vorbis'}], ['libvorbisenc', ['vorbis/vorbisenc.h'], ['vorbis_encode_init'], {'pkg': 'vorbisenc'}], ['libvpx', ['vpx/vpx_decoder.h', 'vpx/vpx_encoder.h'], [], {'pkg': 'vpx', 'version': '>= 1.4.0'}], ['libvpx_vp8_decoder', ['vpx/vpx_decoder.h', 'vpx/vp8dx.h'], ['vpx_codec_vp8_dx'], {'pkg': 'vpx', 'version': '>= 1.4.0'}], ['libvpx_vp8_encoder', ['vpx/vpx_encoder.h', 'vpx/vp8cx.h'], ['vpx_codec_vp8_cx'], {'pkg': 'vpx', 'version': '>= 1.4.0'}], ['libvpx_vp9_decoder', ['vpx/vpx_decoder.h', 'vpx/vp8dx.h'], ['vpx_codec_vp9_dx'], {'pkg': 'vpx', 'version': '>= 1.4.0'}], ['libvpx_vp9_encoder', ['vpx/vpx_encoder.h', 'vpx/vp8cx.h'], ['vpx_codec_vp9_cx'], {'pkg': 'vpx', 'version': '>= 1.4.0'}], ['libwebp', ['webp/encode.h'], ['WebPGetEncoderVersion'], {'version': '>= 0.2.0'}], ['libwebp_anim_encoder', ['webp/mux.h'], ['WebPAnimEncoderOptionsInit'], {'pkg': 'libwebpmux', 'version': '>= 0.4.0'}], ['libx264', ['stdint.h', 'x264.h'], ['x264_encoder_encode'], {'pkg': 'x264'}], ['libx265', ['x265.h'], ['x265_api_get'], {'pkg': 'x265'}], ['libxcb', ['xcb/xcb.h'], ['xcb_connect'], {'pkg': 'xcb', 'version': '>= 1.4'}], ['libxcb_shm', ['xcb/shm.h'], ['xcb_shm_attach'], {'pkg': 'xcb-shm'}], ['libxcb_shape', ['xcb/shape.h'], ['xcb_shape_get_rectangles'], {'pkg': 'xcb-shape'}], ['libxcb_xfixes', ['xcb/xfixes.h'], ['xcb_xfixes_get_cursor_image'], {'pkg': 'xcb-xfixes'}], ['libxml2', ['libxml2/libxml/xmlversion.h'], ['xmlCheckVersion'], {'pkg': 'libxml-2.0'}], ['libzimg', ['zimg.h'], ['zimg_get_api_version'], {'pkg': 'zimg', 'version': '>= 2.7.0'}], ['libzmq', ['zmq.h'], ['zmq_ctx_new'], {}], ['libzvbi', ['libzvbi.h'], ['vbi_decoder_new'], {'pkg': 'zvbi-0.2'}], ['openssl', ['openssl/ssl.h'], ['OPENSSL_init_ssl', 'SSL_library_init'], {'has_any_func': true}], ['pocketsphinx', ['pocketsphinx/pocketsphinx.h'], ['ps_init'], {}], ['rkmpp', ['rockchip/rk_mpi.h'], ['mpp_create'], {'pkg': 'rockchip_mpp'}], ['rockchip_mpp', ['rockchip/rk_mpi.h'], ['mpp_create'], {'version': '>= 1.3.7'}], ['sdl2', ['SDL_events.h'], ['SDL_PollEvent'], {'version': ['>= 2.0.1', '< 3.0.0']}], ['vapoursynth', ['VSScript.h'], ['vsscript_init'], {'pkg': 'vapoursynth-script', 'version': '>= 42'}], ['vulkan', ['vulkan/vulkan.h'], ['vkCreateInstance'], {'pkg': 'vulkan', 'version': '>= 1.1.97'}], ] foreach check : check_pkg_config all_checks += [['pkg-config', check]] endforeach conf.set10('vdpau', cc.has_header('vdpau/vdpau.h') and cc.get_define('VDP_DECODER_PROFILE_MPEG4_PART2_ASP', prefix: '#include ') != '') conf.set10('nanosleep', cc.has_function('nanosleep', prefix: '#include ')) check_components = [ ['advapi32', ['windows.h'], ['RegCloseKey'], ['advapi32']], ['avsynth', ['avisynth/avisynth_c.h'], [], []], ['alsa', ['alsa/asoundlib.h'], ['snd_pcm_htimestamp'], ['asound']], ['android', ['android/native_window.h'], ['ANativeWindow_acquire'], ['android']], ['bcrypt', ['windows.h', 'bcrypt.h'], ['BCryptGenRandom'], ['bcrypt']], ['bzlib', ['bzlib.h'], ['BZ2_bzlibVersion'], ['bz2']], ['camera2ndk', ['stdbool.h', 'stdint.h', 'camera/NdkCameraManager.h'], ['ACameraManager_create'], ['camera2ndk']], ['decklink', ['DeckLinkAPI.h'], [], []], ['libcelt', ['celt/celt.h'], ['celt_decoder_create_custom'], ['celt0']], ['chromaprint', ['chromaprint.h'], ['chromaprint_get_version'], ['chromaprint']], ['clock_gettime', ['time.h'], ['clock_gettime'], []], ['clock_gettime', ['time.h'], ['clock_gettime'], ['rt']], ['cuda_sdk', ['cuda.h'], ['cuCtxCreate'], ['cuda']], ['crystalhd', ['stdint.h', 'libcrystalhd/libcrystalhd_if.h'], ['DtsCrystalHDVersion'], ['crystalhd']], ['frei0r', ['frei0r.h', 'dlfcn.h'], [], []], ['libgme', ['gme/gme.h'], ['gme_new_emu'], ['gme', 'stdc++']], ['gcrypt', ['gcrypt.h'], ['gcry_mpi_new'], ['gcrypt']], ['gmp', ['gmp.h'], ['mpz_export'], ['gmp']], ['ladspa', ['ladspa.h', 'dlfcn.h'], [], []], ['libcdio', ['cdio/cdda.h', 'cdio/paranoia.h'], ['cdio_cddap_open'], ['cdio_paranoia', 'cdio_cdda', 'cdio']], ['libcdio', ['cdio/paranoia/cdda.h', 'cdio/paranoia/paranoia.h'], ['cdio_cddap_open'], ['cdio_paranoia', 'cdio_cdda', 'cdio']], ['libcodec2', ['codec2/codec2.h'], ['codec2_create'], ['codec2']], ['libdl', ['dlfcn.h'], ['dlopen', 'dlsym'], []], ['libdl', ['dlfcn.h'], ['dlopen', 'dlsym'], ['dl']], ['libfdk_aac', ['fdk-aac/aacenc_lib.h'], ['aacEncOpen'], ['fdk-aac']], ['libflite', ['flite/flite.h'], ['flite_init'], ['flite_cmu_time_awb', 'flite_cmu_us_awb', 'flite_cmu_us_kal', 'flite_cmu_us_kal16', 'flite_cmu_us_rms', 'flite_cmu_us_slt', 'flite_usenglish', 'flite_cmulex', 'flite']], ['libgsm', ['gsm.h'], ['gsm_create'], ['gsm']], ['libgsm', ['gsm/gsm.h'], ['gsm_create'], ['gsm']], ['libiec61883', ['libiec61883/iec61883.h'], ['iec61883_cmp_connect'], ['raw1394', 'avc1394', 'rom1394', 'iec61883']], ['libilbc', ['ilbc.h'], ['WebRtcIlbcfix_InitDecode'], ['lbc']], ['libm', ['math.h'], ['sin'], ['m'], {'always-check': true}], # always check for libm don't provide an option to disable it ['libopenvino', ['c_api/ie_c_api.h'], ['ie_c_api_version'], ['inference_engine_c_api']], ['libnpp', ['npp.h'], ['nppGetLibVersion'], ['nppig', 'nppicc', 'nppc']], ['libnpp', ['npp.h'], ['nppGetLibVersion'], ['nppi', 'nppc']], ['libopencore_amrnb', ['opencore-amrnb/interf_dec.h'], ['Decoder_Interface_init'], ['opencore-amrnb']], ['libopencore_amrwb', ['opencore-amrwb/dec_if.h'], ['D_IF_init'], ['opencore-amrwb']], ['libopencv', ['opencv2/core/core_c.h'], ['cvCreateImageHeader'], ['opencv_core', 'opencv_imgproc']], ['libsmbclient', ['libsmbclient.h'], ['smbc_init'], ['smbclient']], ['libsnappy', ['snappy-c.h'], ['snappy_compress'], ['snappy', 'stdc++']], ['libsoxr', ['soxr.h'], ['soxr_create'], ['soxr']], ['libtensorflow', ['tensorflow/c/c_api.h'], ['TF_Version'], ['tensorflow']], ['libtheora', ['theora/theoraenc.h'], ['th_info_init'], ['theoraenc', 'theoradec', 'ogg']], ['libtwolame', ['twolame.h'], ['twolame_init', 'twolame_encode_buffer_float32_interleaved'], ['twolame']], ['libvo_amrwbenc', ['vo-amrwbenc/enc_if.h'], ['E_IF_init'], ['vo-amrwbenc']], ['libvpx_vp8_decoder', ['vpx/vpx_decoder.h', 'vpx/vp8dx.h'], ['vpx_codec_vp8_dx'], ['vpx'], {'defines': ['VPX_IMG_FMT_HIGHBITDEPTH'], 'extra_deps': ['libm_extra_deps', 'thread_dep']}], ['libvpx_vp8_encoder', ['vpx/vpx_encoder.h', 'vpx/vp8cx.h'], ['vpx_codec_vp8_cx'], ['vpx'], {'defines': ['VPX_IMG_FMT_HIGHBITDEPTH'], 'extra_deps': ['libm_extra_deps', 'thread_dep']}], ['libvpx_vp9_decoder', ['vpx/vpx_decoder.h', 'vpx/vp8dx.h'], ['vpx_codec_vp9_dx'], ['vpx'], {'defines': ['VPX_IMG_FMT_HIGHBITDEPTH'], 'extra_deps': ['libm_extra_deps', 'thread_dep']}], ['libvpx_vp9_encoder', ['vpx/vpx_encoder.h', 'vpx/vp8cx.h'], ['vpx_codec_vp9_cx'], ['vpx'], {'defines': ['VPX_IMG_FMT_HIGHBITDEPTH'], 'extra_deps': ['libm_extra_deps', 'thread_dep']}], ['libxvid', ['xvid.h'], ['xvid_global'], ['xvidcore']], ['linux_fb_h', ['linux/fb.h'], [], []], ['lzma', ['lzma.h'], ['lzma_version_number'], ['lzma']], ['mediafoundation', ['mfapi.h'], ['MFCreateAlignedMemoryBuffer'], ['mfplat', 'mfuuid', 'ole32', 'strmiids'], {'defines': ['mftransform_h']}], ['mediandk', ['stdint.h', 'media/NdkImage.h'], ['AImage_delete'], ['mediandk']], ['mmal', ['interface/mmal/mmal.h'], ['mmal_port_connect'], ['mmal_core', 'mmal_util', 'mmal_vc_client', 'bcm_host']], ['nanosleep', ['time.h'], ['nanosleep'], ['rt']], ['ole32', ['windows.h'], ['CoTaskMemFree'], ['ole32']], ['omx', ['OMX_Core.h'], [], []], ['openal', ['AL/al.h'], ['alGetError'], ['openal']], ['openal', ['AL/al.h'], ['alGetError'], ['OpenAL32']], # FIXME- Get opencl working - remove the disabler() at that time. ['opencl', ['CL/cl.h'], ['clEnqueueNDRangeKernel'], ['OpenCL', disabler()]], ['opengl', ['GL/glx.h'], ['glXGetProcAddress'], ['GL']], ['opengl', ['windows.h'], ['wglGetProcAddress'], ['opengl32', 'gdi32']], ['openssl', ['openssl/ssl.h'], ['SSL_library_init'], ['ssl', 'crypto']], ['openssl', ['openssl/ssl.h'], ['SSL_library_init'], ['ssl32', 'eay32']], ['openssl', ['openssl/ssl.h'], ['SSL_library_init'], ['ssl', 'crypto', 'ws2_32', 'gdi32']], ['psapi', ['windows.h', 'psapi.h'], ['GetProcessMemoryInfo'], ['psapi']], ['shell32', ['windows.h', 'shellapi.h'], ['CommandLineToArgvW'], ['shell32']], ['sndio', ['sndio.h'], ['sio_open'], ['sndio']], ['user32', ['windows.h', 'winuser.h'], ['GetShellWindow'], ['user32']], ['vfw32', ['windows.h', 'vfw.h'], ['capCreateCaptureWindow'], ['vfw3']], ['vaapi', ['va/va.h'], ['vaInitialize'], ['va']], ['zlib', ['zlib.h'], ['zlibVersion'], ['z'], {'meson-dep': 'zlib'}], # Libraries with preconditions ['vaapi_drm', ['va/va.h', 'va/va_drm.h'], ['vaGetDisplayDRM'], ['va', 'va-drm'], {'preconditions': ['vaapi']}], ['vaapi_x11', ['va/va.h', 'va/va_x11.h'], ['vaGetDisplay'], ['va', 'va-x11', 'X11'], {'preconditions': ['vaapi']}], ['vdpau_x11', ['vdpau/vdpau.h', 'vdpau/vdpau_x11.h'], ['vdp_device_create_x11'], ['vdpau', 'X11'], {'preconditions' : ['vdpau']}], ['libmfx', ['mfx/mfxvideo.h'], ['MFXInit'], ['libmfx'], {'preconditions': ['advapi32'], 'extra_deps': ['advapi32_extra_deps']}], ['libmp3lame', ['lame/lame.h'], ['lame_set_VBR_quality'], ['mp3lame'], {'preconditions': ['libm'], 'extra_deps': ['libm_extra_deps']}], ['libmysofa', ['mysofa.h'], ['mysofa_load'], ['mysofa'], {'preconditions': ['zlib'], 'extra_deps': ['zlib_extra_deps']}], ['libx264', ['stdint.h', 'x264.h'], ['x264_encoder_encode'], ['x264'], {'preconditions': ['libm'], 'extra_deps': ['libm_extra_deps']}], ['libxavs', ['stdint.h', 'xavs.h'], ['xavs_encoder_encode'], ['xavs'], {'preconditions': ['libm'], 'extra_deps': ['libm_extra_deps']}], ] foreach check : check_components all_checks += [['component', check]] endforeach check_header_funcs = [ ['aligned_malloc', ['malloc.h'], {'funcs': ['_aligned_malloc']}], ['arc4random', ['stdlib.h']], ['kbhit', ['conio.h']], ['setmode', ['io.h']], ['lzo1x_999_compress', ['lzo/lzo1x.h']], ['mach_absolute_time', ['mach/mach_time.h']], ['getenv', ['stdlib.h']], ['lstat', ['sys/stat.h']], ['GetProcessAffinityMask', ['windows.h']], ['GetProcessTimes', ['windows.h']], ['GetSystemTimeAsFileTime', ['windows.h']], ['LoadLibrary', ['windows.h']], ['MapViewOfFile', ['windows.h']], ['PeekNamedPipe', ['windows.h']], ['SetConsoleTextAttribute', ['windows.h']], ['SetConsoleCtrlHandler', ['windows.h']], ['Sleep', ['windows.h']], ['VirtualAlloc', ['windows.h']], ['glob', ['glob.h']], ['XvGetPortAttribute', ['X11/Xlib.h', 'X11/extensions/Xvlib.h'], {'link_with': ['Xv', 'X11', 'Xext']}], ['CreateDIBSection', ['windows.h'], {'link_with': ['gdi32']}], ['InitializeSecurityContext', ['windows.h', 'security.h'], {'link_with': ['secur32']}], ['atomic_cas_ptr', ['atomic.h']], ['machine_rw_barrier', ['mbarrier.h'], {'funcs': ['__machine_rw_barrier']}], ['MemoryBarrier', ['windows.h']], ['x264_csp_bgr', ['stdint.h', 'x264.h'], {'defines': ['X264_CSP_BGR']}], ['posix_memalign', ['stdlib.h']], ['sem_timedwait', ['semaphore.h'], {'preconditions': ['pthreads'], 'extra_deps': ['thread_dep']}], ] foreach func : complex_funcs check_header_funcs += [[func, ['complex.h', 'math.h']]] endforeach foreach func : math_funcs check_header_funcs += [[func, ['math.h'], {'extra_deps': ['libm_extra_deps']}]] endforeach check_funcs = [ ['getaddrinfo'], ['inet_aton'], ['memalign'], ['access'], ['fcntl'], ['fork'], ['gethrtime'], ['getopt'], ['getrusage'], ['gettimeofday'], ['isatty'], ['mkstemp'], ['mmap'], ['mprotect'], ['sched_getaffinity'], ['setrlimit'], ['strerror_r'], ['sysconf'], ['sysctl'], ['usleep'], ['pthread_join', {'preconditions': ['pthreads'], 'extra_deps': ['thread_dep']}], ['pthread_create', {'preconditions': ['pthreads'], 'extra_deps': ['thread_dep']}], ['pthread_cancel', {'preconditions': ['pthreads'], 'extra_deps': ['thread_dep']}], ['sync_val_compare_and_swap', {'funcs': ['__sync_val_compare_and_swap']}], ['gmtime_r'], ['localtime_r'], ] check_types = [ ['DXVA_PicParams_HEVC', ['windows.h', 'dxva.h'], {'c_args': ['-DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP', '-D_CRT_BUILD_DESKTOP_APP=0']}], ['DXVA_PicParams_VP9', ['windows.h', 'dxva.h'], {'c_args': ['-DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP', '-D_CRT_BUILD_DESKTOP_APP=0']}], ['ID3D11VideoDecoder', ['windows.h', 'd3d11.h']], ['ID3D11VideoContext', ['windows.h', 'd3d11.h']], ['DXVA2_ConfigPictureDecode', ['d3d9.h', 'dxva2api.h'], {'c_args': ['-D_WIN32_WINNT=0x0602']}], ['VAPictureParameterBufferHEVC', ['va/va.h', 'va/va_dec_hevc.h']], ['VAPictureParameterBufferVP8', ['va/va.h', 'va/va_dec_vp8.h']], ['VAProcPipelineParameterBuffer', ['va/va.h', 'va/va_vpp.h']], ['VAProcPipelineParameterBuffer', ['va/va.h', 'va/va_vpp.h']], ['VAEncPictureParameterBufferH264', ['va/va.h', 'va/va_enc_h264.h']], ['VAEncPictureParameterBufferHEVC', ['va/va.h', 'va/va_enc_hevc.h']], ['VAEncPictureParameterBufferJPEG', ['va/va.h', 'va/va_enc_mpeg2.h']], ['VAEncPictureParameterBufferMPEG2', ['va/va.h', 'va/va_enc_mpeg2.h']], ['VAEncPictureParameterBufferVP8', ['va/va.h', 'va/va_enc_vp8.h']], ['VAEncPictureParameterBufferVP9', ['va/va.h', 'va/va_enc_vp9.h']], ['VdpPictureInfoHEVC', ['vdpau/vdpau.h']], ['IBaseFilter', ['dshow.h']], ['clCreateImageFromFdINTEL_fn', ['CL/cl_intel.h'], {'preconditions': ['libdrm', 'opencl']}], ['clCreateFromVA_APIMediaSurfaceINTEL_fn', ['CL/cl.h', 'CL/va_ext.h'], {'preconditions': ['vaapi', 'opencl', 'libmfx']}], ['cl_dx9_surface_info_khr', ['CL/cl_dx9_media_sharing.h'], {'preconditions': ['dxva2', 'opencl']}], ['clGetDeviceIDsFromD3D11KHR_fn', ['CL/cl_d3d11.h'], {'preconditions': ['d3d11va', 'opencl']}], ['struct addrinfo', ['netdb.h']], ['struct group_source_req', ['netinet/in.h']], ['struct ip_mreq_source', ['netinet/in.h']], ['struct ipv6_mreq', ['netinet/in.h']], ['struct pollfd', ['poll.h']], ['struct sctp_event_subscribe', ['netinet/sctp.h']], ['struct sockaddr_in6', ['netinet/in.h']], ['struct sockaddr_storage', ['sys/types.h', 'sys/socket.h']], ['socklen_t', ['sys/types.h', 'sys/socket.h']], ] if cc.has_header('arpa/inet.h') conf.set('arpa_inet_h', 1) check_funcs += [['closesocket']] elif cc.has_header('winsock2.h') conf.set('winsock2_h', 1) # FIXME network_extralibs check_header_funcs += [ ['closesocket', ['winsock2.h']], ['getaddrinfo', ['ws2tcpip.h']], ] check_types += [ ['socklen_t', ['ws2tcpip.h']], ['struct addrinfo', ['ws2tcpip.h']], ['struct group_source_req', ['ws2tcpip.h']], ['struct ip_mreq_source', ['ws2tcpip.h']], ['struct ipv6_mreq', ['ws2tcpip.h']], ['struct pollfd', ['winsock2.h']], ['struct sockaddr_in6', ['ws2tcpip.h']], ['struct sockaddr_storage', ['ws2tcpip.h']], ] endif foreach check : check_funcs all_checks += [['func', check]] endforeach foreach check : check_header_funcs all_checks += [['header-func', check]] endforeach foreach check : check_types all_checks += [['type', check]] endforeach check_headers = [ ['direct.h'], ['dirent.h'], ['dxgidebug.h'], ['msa.h'], ['net/udplite.h'], ['sys/param.h'], ['sys/resource.h'], ['sys/select.h'], ['sys/soundcard.h'], ['sys/un.h'], ['sys/videoio.h'], ['termios.h'], ['unistd.h'], ['valgrind/valgrind.h'], ['X11/extensions/XvMClib.h'], ['asm/types.h'], ] if host_machine.system() == 'darwin' check_headers += [['dispatch/dispatch.h']] elif host_machine.system() == 'android' check_headers += [['jni.h']] endif foreach check : check_headers all_checks += [['header', check]] endforeach external_library_list = library_gpl_list + library_nonfree_list + library_version3_list + library_gplv3_list + [ 'chromaprint', 'gcrypt', 'gnutls', 'jni', 'ladspa', 'libaom', 'libass', 'libbluray', 'libbs2b', 'libcaca', 'libcelt', 'libcodec2', 'libdav1d', 'libdc1394', 'libdrm', 'libflite', 'libfontconfig', 'libfreetype', 'libfribidi', 'libglslang', 'libgme', 'libgsm', 'libiec61883', 'libilbc', 'libjack', 'libklvanc', 'libkvazaar', 'libmodplug', 'libmp3lame', 'libmysofa', 'libopencv', 'libopenh264', 'libopenjpeg', 'libopenmpt', 'libopus', 'libpulse', 'librabbitmq', 'librav1e', 'librist', 'librsvg', 'librtmp', 'libshine', 'libsmbclient', 'libsnappy', 'libsoxr', 'libspeex', 'libsrt', 'libssh', 'libsvtav1', 'libtesseract', 'libtheora', 'libtwolame', 'libuavs3d', 'libv4l2', 'libvmaf', 'libvorbis', 'libvpx', 'libwebp', 'libxml2', 'libzimg', 'libzmq', 'libzvbi', 'lv2', 'mediacodec', 'openal', 'opengl', 'pocketsphinx', 'vapoursynth', ] hwaccel_library_nonfree_list = [ 'cuda_sdk', 'libnpp', ] hwaccel_library_list = hwaccel_library_nonfree_list + [ 'libmfx', 'mmal', 'omx', 'opencl', 'vulkan' ] subsystem_list = [ 'dct', 'dwt', 'error_resilience', 'faan', 'fast_unaligned', 'fft', 'lsp', 'lzo', 'mdct', 'pixelutils', 'network', 'rdft', ] meta_list = [ 'autodetect', 'fontconfig', 'linux_perf', 'memory_poisoning', 'neon_clobber_test', 'ossfuzz', 'pic', 'thumb', 'valgrind_backtrace', 'xmm_clobber_test', ] feature_list = [ 'ftrapv', 'gray', 'hardcoded_tables', 'omx_rpi', 'runtime_cpudetect', 'safe_bitstream_reader', 'shared', 'small', 'static', 'swscale_alpha', ] network_funcs = [ 'getaddrinfo', 'inet_aton', ] extra_funcs = [] config_extra = [ 'aandcttables', 'ac3dsp', 'adts_header', 'audio_frame_queue', 'audiodsp', 'blockdsp', 'bswapdsp', 'cabac', 'cbs', 'cbs_h264', 'cbs_h265', 'cbs_mpeg2', 'dirac_parse', 'dnn', 'dvprofile', 'exif', 'faandct', 'faanidct', 'fdctdsp', 'flacdsp', 'fmtconvert', 'frame_thread_encoder', 'g722dsp', 'golomb', 'gplv3', 'h263dsp', 'h264chroma', 'h264dsp', 'h264parse', 'h264pred', 'h264qpel', 'hevcparse', 'hpeldsp', 'huffman', 'huffyuvdsp', 'huffyuvencdsp', 'idctdsp', 'iirfilter', 'mdct15', 'intrax8', 'iso_media', 'ividsp', 'jpegtables', 'lgplv3', 'libx262', 'llauddsp', 'llviddsp', 'llvidencdsp', 'lpc', 'lzf', 'me_cmp', 'mpeg_er', 'mpegaudio', 'mpegaudiodsp', 'mpegaudioheader', 'mpegvideo', 'mpegvideoenc', 'mss34dsp', 'pixblockdsp', 'qpeldsp', 'qsv', 'qsvdec', 'qsvenc', 'qsvvpp', 'rangecoder', 'riffdec', 'riffenc', 'rtpdec', 'rtpenc_chain', 'rv34dsp', 'sinewin', 'snappy', 'srtp', 'startcode', 'texturedsp', 'texturedspenc', 'tpeldsp', 'vaapi_1', 'vaapi_encode', 'vc1dsp', 'videodsp', 'vp3dsp', 'vp56dsp', 'vp8dsp', 'wma_freqs', 'wmv2dsp', ] license_list = [ 'gpl', 'nonfree', 'version3', ] library_list = [ 'avcodec', 'avdevice', 'avfilter', 'avformat', 'avresample', 'avutil', 'postproc', 'swresample', 'swscale', ] program_list = [ 'ffplay', 'ffprobe', 'ffmpeg', ] apple_frameworks = [ 'CoreFoundation', 'CoreMedia', 'CoreVideo', 'AppKit', 'AudioToolbox', 'AVFoundation', 'CoreImage', 'VideoToolbox', 'CoreGraphics', 'CoreServices', 'ApplicationServices', ] avcodec_components = [ 'bsfs', 'decoders', 'encoders', 'hwaccels', 'parsers', ] avdevice_components = [ 'indevs', 'outdevs', ] avfilter_components = [ 'filters', ] avformat_components = [ 'demuxers', 'muxers', 'protocols', ] component_list = avcodec_components + avdevice_components + avfilter_components + avformat_components foreach component : component_list conf.set10(component, get_option(component).allowed()) endforeach config_list = ( document_list + example_list + external_library_list + external_autodetect_library_list + hwaccel_library_list + hwaccel_autodetect_library_list + feature_list + license_list + library_list + program_list + subsystem_list + [ 'autodetect', 'fontconfig', 'linux_perf', 'memory_poisoning', 'neon_clobber_test', 'ossfuzz', 'pic', 'thumb', 'valgrind_backtrace', 'xmm_clobber_test', ] + component_list ) check_compiles = [ ['v4l2_m2m', ['linux/videodev2.h'], 'int i = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_VIDEO_M2M | V4L2_BUF_FLAG_LAST;'], ['pragma_deprecated', [], 'int main(void) {_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\""); return 0; }'], ['const_nan', ['math.h'], 'struct { double d; } static const bar[] = { { NAN } };'], ['intrinsics_neon', ['arm_neon.h'], 'int16x8_t test = vdupq_n_s16(0);'], ] check_links = [ ['stdatomic', ['stdatomic.h'], 'int main(void) {atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += bar;}', {'link_with': ['atomic']}], ['stdatomic', ['stdatomic.h'], 'int main(void) {atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += bar;}'], ] v4l2m2m_formats = [ ['vc1', 'VC1_ANNEX_G'], ['mpeg1'], ['mpeg2'], ['mpeg4'], ['hevc'], ['h263'], ['h264'], ['vp8'], ['vp9'], ] foreach format : v4l2m2m_formats suffix = format.length() > 1 ? format[1] : format[0].to_upper() check_compiles += [['@0@_v4l2_m2m'.format(format[0]), ['sys/time.h', 'linux/videodev2.h'], 'int i = V4L2_PIX_FMT_@0@;'.format(suffix)]] endforeach foreach check : check_compiles all_checks += [['compiles', check]] endforeach foreach check : check_links all_checks += [['links', check]] endforeach foreach arch : arch_list conf.set(arch, 0) endforeach foreach lib : hwaccel_autodetect_library_list conf.set(lib, 0) endforeach foreach check_struct : check_structs conf_name = '@0@_@1@'.format(check_struct[0].underscorify(), check_struct[1].underscorify()) conf.set10(conf_name, cc.has_member(check_struct[0], check_struct[1], prefix : check_struct[2])) endforeach foreach license : license_list conf.set10(license, not get_option(license).disabled()) endforeach foreach lib : library_list conf.set(lib, get_option(lib).enabled().to_int()) endforeach arch = 'c' cpu = host_machine.cpu_family() if cpu == 'x86' arch = 'x86' conf.set('x86', 1) conf.set('i686', 1) conf.set('x86_32', 1) elif cpu == 'x86_64' arch = 'x86' conf.set('x86', 1) conf.set('i686', 1) conf.set('x86_64', 1) elif cpu == 'aarch64' # FIXME: Implement assembly support for MSVC # It relies on Meson adding support for armasm and MASM, # see foreach check : asm_as_checks below. if cc.get_id() == 'msvc' warning('Using aarch64 assembly on MSVC is not yet supported by Meson.') else arch = 'aarch64' conf.set('aarch64', 1) endif elif cpu == 'arm' arch = 'arm' conf.set('arm', 1) endif foreach feature : arch_features name = feature[0] have = false conditions = feature[1] foreach condition: conditions if conf.get(condition, 0) == 1 have = true endif endforeach conf.set10(name, have) endforeach if cc.get_id() == 'clang' if conf.get('x86_32') == 1 # Clang doesn't support maintaining alignment without assuming the # same alignment in every function. If 16 byte alignment would be # enabled, one would also have to either add attribute_align_arg on # every single entry point into the libraries or enable -mstackrealign # (doing stack realignment in every single function). if ['windows', 'freebsd', 'netbsd', 'openbsd'].contains(host_machine.system()) conf.set('aligned_stack', 0) else project_c_args += cc.get_supported_arguments([ '-mllvm -stack-alignment=16', '-mstack-alignment=16' ]) endif else project_c_args += cc.get_supported_arguments([ '-mllvm -stack-alignment=16', '-mstack-alignment=16' ]) endif elif cc.get_id() == 'msvc' if conf.get('x86_32') == 1 conf.set('aligned_stack', 0) endif # the new SSA optimzer in VS2015 U3 is mis-optimizing some parts of the code # Issue has been fixed in MSVC v19.00.24218. if cc.links(cpp_cond.format('windows.h', '_MSC_FULL_VER < 190024218')) project_c_args += cc.get_supported_arguments([ 'd2SSAOptimizer-' ]) endif if conf.get('x86_32') == 1 and (get_option('buildtype') == 'debug' or get_option('optimization') == '0') project_c_args += cc.get_supported_arguments([ '-Oy-' ]) endif endif conf.set10('shared', get_option('default_library') != 'static') conf.set('pthreads', 0) conf.set('w32threads', 0) conf.set('os2threads', 0) conf.set10('bigendian', host_machine.endian() == 'big') conf.set10('fast_unaligned', ['x86', 'x86_64', 'aarch', 'ppc'].contains(host_machine.cpu_family())) conf.set('frame_thread_encoder', 1) if ['linux', 'darwin', 'android'].contains(host_machine.system()) conf.set10('pthreads', thread_dep.found()) elif host_machine.system() == 'windows' conf.set10('w32threads', thread_dep.found()) conf.set('symver', 0) conf.set('dos_paths', 1) endif if ['linux', 'openbsd', 'android'].contains(host_machine.system()) conf.set('section_data_rel_ro', 1) endif # Our option names can't be 1:1 mapping because newer meson versions disallow # options with language prefixes i.e. "cuda_sdk" in our case options_map = { 'cuda_sdk' : 'ff_cuda_sdk', 'linux_fb_h' : 'linux_fbdev', } foreach check : all_checks check_type = check[0] check = check[1] name = check[0] opt_name = options_map.get(name, name) if check_type == 'func' headers = [] elif check_type == 'header' headers = [name] else headers = check[1] endif opts = {} link_withs = [] funcs = [] compiles = '' links = '' type = '' if check_type == 'pkg-config' if check.length() > 3 opts = check[3] endif elif check_type == 'component' link_withs = check[3] if check.length() > 4 opts = check[4] endif elif check_type == 'header-func' if check.length() > 2 opts = check[2] endif elif check_type == 'func' or check_type == 'header' if check.length() > 1 opts = check[1] endif elif check_type == 'compiles' if check.length() > 3 opts = check[3] endif compiles = check[2] elif check_type == 'links' if check.length() > 3 opts = check[3] endif links = check[2] elif check_type == 'type' if check.length() > 2 opts = check[2] endif type = name endif if check_type == 'header-func' or check_type == 'func' funcs = opts.get('funcs', [name]) elif check_type == 'pkg-config' or check_type == 'component' funcs = check[2] endif if check_type != 'component' link_withs = opts.get('link_with', []) endif found = false if conf.get(name.underscorify(), 0) == 0 defines = opts.get('defines', []) has_any_func = opts.get('has_any_func', false) c_args = opts.get('c_args', []) extra_deps = [] foreach dep_name : opts.get('extra_deps', []) extra_deps += [get_variable(dep_name)] endforeach prefix = '' found = true skipchecks = false preconditions = opts.get('preconditions', []) foreach precondition : preconditions found = found and conf.get(precondition) == 1 endforeach # FIXME: or should these just be preconditions in the list above instead? disabled = false if get_option('gpl').disabled() gpl_list = library_gpl_list + library_gplv3_list disabled = gpl_list.contains(name) endif if get_option('version3').disabled() v3_list = library_gplv3_list + library_version3_list disabled = disabled or v3_list.contains(name) endif if get_option('nonfree').disabled() nonfree_list = library_nonfree_list + hwaccel_library_nonfree_list disabled = disabled or nonfree_list.contains(name) endif if disabled if get_option(opt_name).enabled() error('Incompatible options combination: @0@ requested, but has disabled license.'.format(name)) endif message('Skipping @0@ because of license'.format(name)) found = false endif if found if check_type != 'pkg-config' foreach link_with : link_withs if check_type == 'component' and not ('always-check' in opts) req = get_option(opt_name) else req = false endif dep = cc.find_library(link_with, required : req) if not dep.found() and opts.has_key('meson-dep') dep = dependency(opts.get('meson-dep'), required: false) # We can't do compiler checks for non-external dependencies, so skip them and trust the meson dependency skipchecks = true endif found = found and dep.found() extra_deps += dep endforeach else req = get_option(opt_name) pkg_name = opts.get('pkg', name) if opts.has_key('versions') foreach version: opts['versions'] dep = dependency(pkg_name, required: false, version: version) endforeach if not dep.found() and req.enabled() error('@0@ @1@ could not be found'.format(pkg_name, opts['versions'])) endif elif opts.has_key('version') dep = dependency(pkg_name, required : req, version: opts.get('version')) else dep = dependency(pkg_name, required : req) endif found = dep.found() and dep.type_name() != 'internal' extra_deps += dep endif endif if found foreach header : headers if header.endswith('.h') prefix += '#include <@0@>\n'.format(header) else prefix += '#include @0@\n'.format(header) endif if not conf.has(header.underscorify()) has_header = skipchecks or cc.has_header(header, dependencies: extra_deps) conf.set10(header.underscorify().to_lower(), has_header) found = found and has_header endif endforeach endif if found and not skipchecks n_funcs_found = 0 foreach symbol : funcs if check_type == 'header-func' if cc.has_header_symbol(headers[0], symbol, dependencies : extra_deps, prefix: prefix, args : c_args + project_c_args) n_funcs_found += 1 endif else if cc.has_function(symbol, dependencies : extra_deps, prefix: prefix, args : c_args + project_c_args) n_funcs_found += 1 endif endif endforeach if has_any_func found = n_funcs_found >= 1 else found = n_funcs_found == funcs.length() endif endif if found and not skipchecks n_defines_found = 0 foreach symbol : defines if cc.get_define(symbol, dependencies : extra_deps, prefix: prefix, args : c_args + project_c_args) != '' n_defines_found += 1 endif endforeach found = n_defines_found == defines.length() endif if found and compiles != '' and not skipchecks found = cc.compiles('\n\n'.join([prefix, compiles]), dependencies : extra_deps, args : c_args + project_c_args, name: name) endif if found and links != '' and not skipchecks found = cc.links('\n\n'.join([prefix, links]), dependencies : extra_deps, args : c_args + project_c_args, name: name) endif if found and type != '' and not skipchecks found = cc.has_type(type, prefix : prefix, dependencies : extra_deps, args : c_args + project_c_args) endif if check_type != 'header' conf.set10(name.underscorify().to_lower(), found) endif foreach symbol : funcs + defines conf.set10(symbol.to_lower(), found) endforeach if found set_variable('@0@_extra_deps'.format(name.to_lower().underscorify()), extra_deps) else set_variable('@0@_extra_deps'.format(name.to_lower().underscorify()), []) endif endif endforeach if conf.get('gnutls') == 1 and conf.get('openssl') == 1 # Simply picking one for now conf.set('openssl', 0) endif if conf.get('opengl') == 1 and not cc.has_header('GL/glext.h') conf.set('opengl', 0) endif if conf.get('libx265') == 1 x265_build = cc.get_define('X265_BUILD', prefix: '#include ', dependencies: libx265_extra_deps) if x265_build == '' message ('X265_BUILD not found, disabling') conf.set('libx265', 0) elif x265_build.to_int() < 68 message ('X265_BUILD too old, disabling') conf.set('libx265', 0) else message ('X265_BUILD >= 68, keeping enabled') endif endif if conf.get('libzvbi') == 1 conf.set('libzvbi', cc.compute_int( 'VBI_VERSION_MAJOR > 0 || VBI_VERSION_MINOR > 2 || VBI_VERSION_MINOR == 2 && VBI_VERSION_MICRO >= 28', prefix: '#include ', dependencies: libzvbi_extra_deps)) endif x86asm_type = 'none' x86asm_checks = [] asm_inline_checks = [ ['"1:\\n"', 'inline_asm_labels'], ['"Label:\\n"', 'inline_asm_nonlocal_labels'] ] extern_prefix = cc.symbols_have_underscore_prefix() ? '_' : '' asm_insn_checks = [] asm_as_checks = [] if host_machine.system() == 'windows' asm_format = conf.get('x86_64') == 1 ? 'win64' : 'win32' elif host_machine.system() == 'darwin' asm_format = conf.get('x86_64') == 1 ? 'macho64' : 'macho32' else asm_format = conf.get('x86_64') == 1 ? 'elf64' : 'elf32' endif x86asm = disabler() conf.set('x86asm', 0) if conf.get('x86') == 1 conf.set10('rdtsc', cc.has_function('__rdtsc', prefix: '#include ')) conf.set10('mm_empty', cc.has_function('_mm_empty', prefix: '#include ')) conf.set('local_aligned', 1) if conf.get('asm', 0) == 1 nasm_version = '>=0' if host_machine.system() == 'windows' nasm_version = '>=2.12' endif x86asm = find_program('nasm', version: nasm_version, required: false) x86asm_type = 'nasm' if not x86asm.found() and host_machine.system() == 'windows' # Note that on Windows we require NASM because when optimizations are # disabled, the Windows linker does not optimize out functions with # EXTERNAL_* SIMD calls and errors out with unresolved symbols subproject('win-nasm') x86asm = find_program('nasm', version: nasm_version) endif if not x86asm.found() x86asm = find_program('yasm', required: false) x86asm_type = 'yasm' endif conf.set10('x86asm', x86asm.found()) if x86asm.found() x86asm_checks += [ ['meson_asm_checks/cpunop.asm', 'cpunop'], ['meson_asm_checks/avx2_external.asm', 'avx2_external'], ['meson_asm_checks/avx512_external.asm', 'avx512_external'], ['meson_asm_checks/fma4_external.asm', 'fma4_external'], ['meson_asm_checks/xop_external.asm', 'xop_external'], ] asm_inline_checks += [ ['"":::"%xmm0"', 'xmm_clobbers'], ['"pabsw %xmm0, %xmm0"', 'ssse3_inline'], ['"pmaxub %mm0, %mm1"', 'mmxext_inline'], ] endif endif ebp_available = cc.run(''' int main() { volatile int i=0; __asm__ volatile ("xorl %%ebp, %%ebp" ::: "%ebp"); return i; } ''', name: 'if_ebp_available_this_should_crash') # FFmpeg upstream doesn't know that EBP is always unavailable # under Clang if stack realignment is used. This is probably # because the only compilers still supporting the architecture # are the Android NDK and MSYS CLANG32. # Thus an additional check on aligned_stack is done here. # See: # - https://github.com/android/ndk/issues/693 # - https://bugs.llvm.org/show_bug.cgi?id=37542 conf.set10('ebp_available', conf.get('aligned_stack') == 1 and ebp_available.compiled() and ebp_available.returncode() != 0) asm_inline_checks += [ ['""::"b"(0)', 'ebx_available_1'], ['"":::"%ebx"', 'ebx_available_2'], ['"movl @0@test, %eax"'.format(extern_prefix), 'inline_asm_direct_symbol_refs_1'], ['"movl @0@test(%rip), %eax"'.format(extern_prefix), 'inline_asm_direct_symbol_refs_2'], ['"":::"%xmm0"', 'xmm_clobbers'], ['"pabsw %xmm0, %xmm0"', 'ssse3_inline'], ['"pmaxub %mm0, %mm1"', 'mmxext_inline'], ] elif conf.get('aarch64') == 1 asm_insn_checks += [ ['prfm pldl1strm, [x0]', 'armv8'], ['ext v0.8B, v0.8B, v1.8B, #1', 'neon'], ['fmadd d0, d0, d1, d2', 'vfp'], ] elif conf.get('arm') == 1 if cc.get_id() == 'msvc' conf.set10('thumb', cc.has_header_symbol('stddef.h', '_M_ARMT')) endif if cc.has_header_symbol('stddef.h', '__thumb__') conf.set10('thumb', cc.compiles( 'float func(float a, float b){ return a+b; }', name: 'weak_thumb')) endif if conf.get('thumb', 0) == 1 if cc.has_argument('-mthumb') project_c_args += ['-mthumb'] elif cc.has_argument('-marm') project_c_args += ['-marm'] endif endif if cc.has_header_symbol('stddef.h', '__ARM_PCS_VFP') conf.set('vfp_args', 1) elif cc.links(cpp_cond.format('stddef.h', 'defined _M_ARM_FP && _M_ARM_FP >= 30'), name: 'vfp_args_fp') conf.set('vfp_args', 1) elif not cc.links(cpp_cond.format('stddef.h', 'defined __ARM_PCS || defined __SOFTFP__'), name: 'arm_pcs_or_softfp') and host_machine.system() != 'darwin' if not cc.has_header_symbol('stddef.h', '__SOFTFP__') conf.set('vfp_args', 1) conf.set('fpabi', 'vfp') elif cc.links('__asm__ (".eabi_attribute 28, 1"); int main(void) { return 0; }', name: 'vfp_abi_check') conf.set('vfp_args', 1) conf.set('fpabi', 'vfp') else conf.set('fpabi', 'soft') endif message('Floating point ABI: @0@'.format(conf.get('fpabi'))) endif asm_insn_checks += [ ['qadd r0, r0, r0', 'armv5te'], ['sadd16 r0, r0, r0', 'armv6'], ['movt r0, #0', 'armv6t2'], ['vadd.i16 q0, q0, q0', 'neon'], ['fadds s0, s0, s0', 'vfp'], ['vmov.f32 s0, #1.0', 'vfpv3'], ['setend be', 'setend'] ] asm_inline_checks += [ ['"add r0, %Q0, %R0" :: "r"((long long)0)', 'asm_mod_q'] ] asm_as_checks += [ ['.arch armv7-a', 'as_arch_directive'], ['ra .dn d0.i16', 'as_dn_directive'], ['.fpu neon', 'as_fpu_directive'] ] # llvm's integrated assembler supports .object_arch from llvm 3.5 if asm_format == 'elf32' or asm_format == 'elf64' asm_as_checks += [ ['.object_arch armv4', 'as_object_arch'] ] endif endif asm_args = ['-DPIC'] # Add debug args explicitly # yasm: `-g ` # nasm: ` -g -F ` # The only modern debugging format supported by either is DWARF # # nasm and yasm don't support DWARF in the PE format (Windows) if asm_format.startswith('win') debug_format = 'null' else # Supported on Linux, BSD, macOS debug_format = 'dwarf' endif # Add the format args if x86asm_type == 'yasm' if debug_format == 'dwarf' asm_args += ['-g', 'dwarf2'] else asm_args += ['-g', 'null'] endif elif x86asm_type == 'nasm' if debug_format == 'dwarf' asm_args += ['-g', '-F', 'dwarf'] endif endif asm_inc = join_paths(meson.current_source_dir(), 'libavutil/x86/') if extern_prefix != '' asm_args += ['-DPREFIX'] endif foreach ext : arch_ext_list_x86_simd if ext == 'mmx' continue endif inline = '@0@_inline'.format(ext) external = '@0@_external'.format(ext) conf.set10(inline, conf.get(ext) == 1 and conf.get('inline_asm') == 1 and conf.get('x86') == 1) conf.set10(external, conf.get(ext) == 1 and conf.get('x86asm') == 1) endforeach foreach check: x86asm_checks result = run_command(x86asm, '-f', asm_format, asm_args, '-Werror', check[0], '-o', join_paths(meson.current_build_dir(), 'tmpasm.o'), check: false) if conf.get('asm') == 1 conf.set10(check[1], result.returncode() == 0) if result.returncode() != 0 message('@0@ x86 asm check failed: @1@'.format(check[1], result.stderr().strip())) endif else conf.set10(check[1], false) endif endforeach foreach check : asm_insn_checks asm_inline_checks += [ ['"@0@"'.format(check[0]), '@0@_inline'.format(check[1])] ] asm_as_checks += [ [check[0], '@0@_external'.format(check[1])] ] endforeach foreach check: asm_inline_checks if conf.get('inline_asm') == 1 result = cc.compiles( 'void foo(void){ __asm__ volatile(@0@); }'.format(check[0]), name: check[1] ) conf.set10(check[1], result) else conf.set10(check[1], false) endif endforeach if (conf.get('arm', 0) == 1 or conf.get('aarch64', 0) == 1) and cc.get_id() != 'msvc' asm_as_checks += [ [''' .macro m n, y:vararg=0 .int \y .endm m x ''', 'vararg'], ] if conf.get('arm', 0) == 1 asm_as_checks += [ ['.altmacro', 'gnu_as'] ] endif asm_as_checks += [ ['''.func test .endfunc''', 'as_func'] ] endif # FIXME: this won't work until Meson detects and # exposes the underlying assembler. # These checks cannot be done with run_command either # because they rely on setup-time input. # See: # - https://github.com/mesonbuild/meson/issues/9889 # - https://github.com/mesonbuild/meson/pull/10916 # - https://github.com/mesonbuild/meson/pull/10922 foreach check : asm_as_checks warning('Meson does not yet expose the ASM compiler, skipping @0@ check'.format(check[1])) # if conf.get('asm') == 1 # conf.set10(check[1], cc.compiles( # check[0], # args: ['-x', 'assembler'], # name: check[1] # )) # else conf.set10(check[1], false) # endif endforeach if conf.get('x86') == 1 conf.set10('ebx_available', conf.get('ebx_available_1') == 1 and conf.get('ebx_available_2') == 1) message('EBX available: @0@'.format(conf.get('ebx_available'))) conf.set10('inline_asm_direct_symbol_refs', conf.get('inline_asm_direct_symbol_refs_1') == 1 or conf.get('inline_asm_direct_symbol_refs_2') == 1) message('Inline assembly direct symbol references available: @0@'.format(conf.get('inline_asm_direct_symbol_refs'))) endif arm_skip_checks = conf.get('arm', 0) == 1 and (host_machine.system() == 'linux' or host_machine.system() == 'android') foreach ext : arch_ext_list_arm inline = '@0@_inline'.format(ext) external = '@0@_external'.format(ext) if not arm_skip_checks conf.set10(ext, conf.get(inline, 0) == 1 or conf.get(external, 0) == 1) endif endforeach if get_option('b_lto') conf.set10('inline_asm_direct_symbol_refs', 0) endif extern_things = [ ['AVOutputFormat', 'muxer', 'libavformat/allformats.c', 'muxer_list'], ['AVInputFormat', 'demuxer', 'libavformat/allformats.c', 'demuxer_list'], ['AVCodec', 'encoder', 'libavcodec/allcodecs.c', 'encoder_list'], ['AVCodec', 'decoder', 'libavcodec/allcodecs.c', 'decoder_list'], ['AVCodecParser', 'parser', 'libavcodec/parsers.c', 'parser_list'], ['AVBitStreamFilter', 'bsf', 'libavcodec/bitstream_filters.c', 'bsf_list'], ['AVHWAccel', 'hwaccel', 'libavcodec/hwaccels.h', 'hwaccel_list'], ['URLProtocol', 'protocol', 'libavformat/protocols.c', 'protocol_list'], ['AVOutputFormat', 'muxer', 'libavdevice/alldevices.c', 'outdev_list', 'outdev'], ['AVInputFormat', 'demuxer', 'libavdevice/alldevices.c', 'indev_list', 'indev'], ] find_things_extern = find_program('find_things_extern.py') foreach extern_thing : extern_things c_type = extern_thing[0] type = extern_thing[1] filename = extern_thing[2] variable_name = extern_thing[3] if extern_thing.length() > 4 thing_suffix = extern_thing[4] else thing_suffix = type endif result = run_command(find_things_extern, '--type=@0@'.format(c_type), '--suffix=@0@'.format(type), '--thing-suffix=@0@'.format(thing_suffix), files(filename), check: true) list = result.stdout().strip().split('\n') thing_allowed = get_option('@0@s'.format(thing_suffix)).allowed() foreach elem : list opt = get_option(elem) conf.set(elem, (opt.enabled() or (opt.allowed() and thing_allowed)).to_int()) endforeach set_variable(variable_name, list) endforeach find_things = find_program('find_things.py') result = run_command(find_things, files('libavfilter/allfilters.c'), check: true) filter_list = result.stdout().strip().split('\n') filters_allowed = get_option('filters').allowed() foreach filter : filter_list opt = get_option(filter) conf.set(filter, (opt.enabled() or (opt.allowed() and filters_allowed)).to_int()) endforeach foreach program : program_list conf.set(program, get_option(program).allowed().to_int()) endforeach result = run_command(find_things, '--full', files('libavfilter/allfilters.c'), check: true) full_filter_list = result.stdout().strip().split('\n') avcodec_components_list = bsf_list + decoder_list + encoder_list + hwaccel_list + parser_list avdevice_components_list = indev_list + outdev_list avfilter_components_list = filter_list avformat_components_list = demuxer_list + muxer_list + protocol_list all_components = avcodec_components_list + avdevice_components_list + avfilter_components_list + avformat_components_list tmpconfig_h = configure_file(configuration: conf, output: 'tmpconfig.h') # Working around Windows command line limitation components_to_resolve = configuration_data() foreach comp : config_list + config_extra + have_list + all_components components_to_resolve.set(comp, true) endforeach components_h = configure_file(configuration: components_to_resolve, output: 'components.h') dep_resolver = find_program('depresolver.py') res = run_command(dep_resolver, tmpconfig_h, components_h, check: true) conf = configuration_data() split = res.stdout().split('//BEGIN_DEPENDS') resolved = split[0] flattened_deps = split[1] foreach kv : resolved.split() split = kv.split('=') k = split[0] v = split[1].to_int() conf.set(k, v) endforeach foreach kv : flattened_deps.split() split = kv.split('=') k = split[0] v = split[1].split(',') set_variable('@0@_flattened_deps'.format(k), v) endforeach dshow_indev_extra_deps = [] if host_machine.system() == 'windows' foreach libname: ['psapi', 'ole32', 'strmiids', 'uuid', 'oleaut32', 'shlwapi'] dshow_indev_extra_deps += [cc.find_library(libname, required: false)] endforeach endif foreach comp : avcodec_components_list avcodec_flattened_deps += get_variable('@0@_flattened_deps'.format(comp), []) endforeach foreach comp : avdevice_components_list avdevice_flattened_deps += get_variable('@0@_flattened_deps'.format(comp), []) endforeach foreach comp : avfilter_components_list avfilter_flattened_deps += get_variable('@0@_flattened_deps'.format(comp), []) endforeach foreach comp : avformat_components_list avformat_flattened_deps += get_variable('@0@_flattened_deps'.format(comp), []) endforeach subdir('libavutil') subdir('libpostproc') subdir('libswresample') subdir('libswscale') subdir('libavcodec') subdir('libavformat') subdir('libavfilter') subdir('libavdevice') subdir('libavresample') subdir('fftools') util_list = ['cuda', 'd3d11va', 'dxva2', 'libdrm', 'lzo', 'mediacodec', 'opencl', 'qsv', 'vaapi', 'vdpau', 'videotoolbox'] if conf.get('schannel') == 1 secur32_dep = cc.find_library('secur32') if secur32_dep.found() libavformat_optional_deps += [secur32_dep] else conf.set('schannel', 0) endif endif things_to_print = [ ['libavcodec/codec_list.c', 'AVCodec', 'codec_list', encoder_list + decoder_list], ['libavcodec/parser_list.c', 'AVCodecParser', 'parser_list', parser_list], ['libavcodec/bsf_list.c', 'AVBitStreamFilter', 'bitstream_filters', bsf_list], ['libavformat/muxer_list.c', 'AVOutputFormat', 'muxer_list', muxer_list], ['libavformat/demuxer_list.c', 'AVInputFormat', 'demuxer_list', demuxer_list], ['libavformat/protocol_list.c', 'URLProtocol', 'url_protocols', protocol_list], ['libavdevice/outdev_list.c', 'AVOutputFormat', 'outdev_list', outdev_list], ['libavdevice/indev_list.c', 'AVInputFormat', 'indev_list', indev_list], ['libavfilter/filter_list.c', 'AVFilter', 'filter_list', filter_list], ] print_things = find_program('print_things.py') foreach thing : things_to_print list = [] ctr = 0 foreach comp : thing[3] if conf.get(comp) == 1 if thing[1] == 'AVFilter' comp_name = full_filter_list[ctr] elif thing[2] == 'indev_list' comp_name = '@0@_demuxer'.format(comp.split('_indev')[0]) elif thing[2] == 'outdev_list' comp_name = '@0@_muxer'.format(comp.split('_outdev')[0]) else comp_name = comp endif list += [comp_name] endif ctr += 1 endforeach if thing[1] == 'AVFilter' list += ['asrc_abuffer', 'vsrc_buffer', 'asink_abuffer', 'vsink_buffer'] endif res = run_command(print_things, '--filename=@0@'.format(join_paths(meson.current_build_dir(), thing[0])), '--struct-name=@0@'.format(thing[1]), '--name=@0@'.format(thing[2]), list, check: true) endforeach if not cc.check_header('stdatomic.h') and thread_dep.found() if host_machine.system() == 'windows' common_incs += [include_directories('compat/atomics/win32')] elif cc.get_id() == 'gcc' common_incs += [include_directories('compat/atomics/gcc')] endif endif add_project_arguments(project_c_args, language: 'c') libavutil_optional_deps = [vaapi_drm_extra_deps + vaapi_x11_extra_deps + vdpau_x11_extra_deps] libavdevice_extra_deps = [xvgetportattribute_extra_deps] libswresample_optional_deps = [libsoxr_extra_deps] common_deps += libm_extra_deps built_libs = [ ['avutil', []], ['postproc', ['libavutil']], ['swresample', ['libavutil']], ['swscale', ['libavutil']], ['avcodec', ['libavutil', 'libswresample']], ['avformat', ['libavutil', 'libavcodec']], ['avresample', ['libavutil']], ['avfilter', ['libavutil', 'libavcodec', 'libavformat', 'libswscale', 'libswresample', 'libavresample', 'libpostproc']], ['avdevice', ['libavutil', 'libavformat', 'libavfilter', 'libavcodec']], ] windows = import('windows') makedef = find_program('compat/windows/makedef.py') makedef_args = [makedef] if cc.get_id() != 'msvc' nm = find_program('nm', required: true) makedef_args += ['--nm', nm] else dumpbin = find_program('dumpbin', required: true) makedef_args += ['--dumpbin', dumpbin] endif makedef_args += ['--prefix', extern_prefix] foreach built_lib : built_libs sources = get_variable('lib@0@_sources'.format(built_lib[0])) + [ffversion_h] x86asm_sources = [] tests = get_variable('lib@0@_tests'.format(built_lib[0]), []) gen_objects = [] optional_deps = get_variable('lib@0@_optional_deps'.format(built_lib[0]), []) sources += get_variable('lib@0@_@1@_sources'.format(built_lib[0], arch), []) if host_machine.system() == 'windows' sources += windows.compile_resources( 'lib@0@/@1@res.rc'.format(built_lib[0], built_lib[0]), include_directories: common_incs, depends: ffversion_h ) endif foreach arch_ext : arch_list if conf.get(arch_ext, 0) == 1 sources += get_variable('lib@0@_@1@_sources'.format(built_lib[0], arch_ext), []) endif endforeach foreach arch_ext : arch_ext_list if conf.get(arch_ext, 0) == 1 sources += get_variable('lib@0@_@1@_@2@_sources'.format(built_lib[0], arch, arch_ext), []) endif endforeach if conf.get('x86asm') == 1 x86asm_sources += get_variable('lib@0@_@1@_x86asm_sources'.format(built_lib[0], arch), []) endif optional_sources = get_variable('lib@0@_optional_sources'.format(built_lib[0]), {}) optional_tests = get_variable('lib@0@_optional_tests'.format(built_lib[0]), {}) foreach comp_name, comp_sources : optional_sources if conf.get(comp_name, 0) == 1 sources += comp_sources endif if languages_map.has_key(comp_name) foreach lang: languages_map[comp_name] add_languages(languages_map[comp_name], required: get_option(comp_name).enabled(), native: false) endforeach endif endforeach optional_sources = get_variable('lib@0@_@1@_optional_sources'.format(built_lib[0], arch), {}) foreach comp_name, comp_sources : optional_sources if conf.get(comp_name, 0) == 1 sources += comp_sources endif endforeach if conf.get('x86asm') == 1 optional_sources = get_variable('lib@0@_@1@_x86asm_optional_sources'.format(built_lib[0], arch), {}) foreach comp_name, comp_sources : optional_sources if conf.get(comp_name, 0) == 1 x86asm_sources += comp_sources endif endforeach endif foreach arch_ext : arch_ext_list if conf.get(arch_ext, 0) == 1 optional_sources = get_variable('lib@0@_@1@_@2@_optional_sources'.format(built_lib[0], arch, arch_ext), {}) foreach comp_name, comp_sources : optional_sources if conf.get(comp_name, 0) == 1 sources += comp_sources endif endforeach endif endforeach foreach comp_name, comp_tests : optional_tests if conf.get(comp_name, 0) == 1 tests += comp_tests endif endforeach foreach dep_comp_name: get_variable('@0@_flattened_deps'.format(built_lib[0]), []) optional_deps += get_variable('@0@_extra_deps'.format(dep_comp_name), []) endforeach deps = common_deps + optional_deps link_with = [] foreach dep : built_lib[1] link_with += [get_variable(dep)] endforeach version = get_variable('lib@0@_majorver'.format(built_lib[0])) if x86asm_sources.length() > 0 # FIXME dedup should happen in meson deduped_sources = [] foreach source : x86asm_sources if not deduped_sources.contains(source) deduped_sources += [source] endif endforeach asm_gen = generator(x86asm, output : '@BASENAME@.o', arguments : asm_args + [ '-f', asm_format, '-i', meson.current_source_dir() + '/', '-i', meson.current_build_dir() + '/', '-i', join_paths(meson.current_source_dir(), 'lib@0@'.format(built_lib[0]), 'x86', ''), '-P', join_paths(meson.current_build_dir(), 'config.asm'), '@INPUT@', '-o', '@OUTPUT@']) gen_objects += asm_gen.process(deduped_sources) endif vflag = '-Wl,--version-script,@0@/lib@1@/lib@1@.ver'.format(meson.current_build_dir(), built_lib[0]) c_args = ['-DHAVE_AV_CONFIG_H', '-DBUILDING_@0@'.format(built_lib[0])] link_args = cc.get_supported_link_arguments([vflag]) static_link_args = [] if cc.get_id() == 'msvc' message('Applying MSVC link workaround for Debug mode and static libraries.') static_link_args += cc.get_supported_link_arguments('/FORCE:UNRESOLVED') if get_option('buildtype') == 'debug' or get_option('optimization') == '0' link_args += cc.get_supported_link_arguments('/FORCE:UNRESOLVED') endif endif static_lib = static_library('@0@-static'.format(built_lib[0]), sources + gen_objects, dependencies: deps, include_directories: common_incs, link_with: link_with, link_args: static_link_args, c_args: c_args, implicit_include_directories : false, ) vs_module_def = custom_target('@0@-def'.format(built_lib[0]), output: '@0@.def'.format(built_lib[0]), command: [makedef_args, '@0@/lib@1@/lib@1@.ver'.format(meson.current_build_dir(), built_lib[0]), static_lib], capture: true ) lib = library(built_lib[0], dependencies: deps, soversion: version, include_directories: common_incs, link_with: link_with, link_whole: static_lib, link_args: link_args, c_args: c_args, vs_module_defs: vs_module_def, implicit_include_directories : false, install: true, ) set_variable('lib@0@'.format(built_lib[0]), lib) declared_dep = declare_dependency(link_with: lib, include_directories: include_directories('.'), dependencies: deps, version: get_variable('lib@0@_version'.format(built_lib[0])) ) set_variable('lib@0@_dep'.format(built_lib[0]), declared_dep) if not get_option('tests').disabled() foreach test_ : tests test_name = test_[0] test_sources = test_[1] opts = test_.get(2, {}) test_deps = deps extra_libs = opts.get('extra_libs', []) foreach libname: extra_libs test_deps += [cc.find_library(libname)] endforeach exe = executable('test_@0@_@1@'.format(built_lib[0], test_name), test_sources, c_args: c_args, dependencies: test_deps, include_directories: common_incs, link_args: static_link_args, link_with: [static_lib] + link_with, implicit_include_directories : false) test('@0@_@1@'.format(built_lib[0], test_name), exe, timeout: 180, workdir: join_paths(meson.current_source_dir(), 'lib@0@'.format(built_lib[0]), 'tests')) endforeach endif endforeach built_exe_list = [] if not get_option('cli').disabled() foreach program : program_list if conf.get(program) == 1 built_exe_list += program endif endforeach endif foreach built_exe : built_exe_list sources = get_variable('@0@_sources'.format(built_exe)) + [ffversion_h] optional_deps = [] message('Checking @0@ dependencies'.format(built_exe)) optional_sources = get_variable('@0@_optional_sources'.format(built_exe), {}) foreach comp_name, comp_sources : optional_sources if conf.get(comp_name, 0) == 1 sources += comp_sources endif endforeach foreach dep_comp_name: get_variable('@0@_flattened_deps'.format(built_exe), []) optional_deps += get_variable('@0@_extra_deps'.format(dep_comp_name), []) endforeach message('Gathered @0@ optional deps'.format(optional_deps.length())) deps = common_deps + optional_deps exe = executable(built_exe, sources, install: true, dependencies: deps, include_directories: common_incs, link_with: [libavutil, libavcodec, libavfilter, libavdevice, libavformat, libavresample, libswscale, libswresample, libpostproc], implicit_include_directories : false, ) set_variable('@0@_exe'.format(built_exe[0]), exe) endforeach pkg = import('pkgconfig') pkg_infos = [ ['Multimedia utilities', 'libavutil'], ['FFmpeg postprocessing library', 'libpostproc'], ['FFmpeg audio resampling library', 'libswresample'], ['FFmpeg image rescaling library', 'libswscale'], ['Multimedia codecs', 'libavcodec'], ['Multimedia formats', 'libavformat'], ['Media device handling', 'libavdevice'], ['Audio/video filtering library', 'libavfilter'], ['Libav audio resampling library', 'libavresample'], ] foreach pkg_info : pkg_infos libname = pkg_info[1] pkg.generate(get_variable(libname), filebase: libname, description: pkg_info[0], version: get_variable(libname + '_version') ) endforeach final_conf = configuration_data() final_conf.set_quoted('FFMPEG_CONFIGURATION', '') # FIXME final_conf.set('CONFIG_THIS_YEAR', 2022) final_conf.set_quoted('FFMPEG_DATADIR', join_paths(get_option('prefix'), get_option('datadir'))) final_conf.set_quoted('AVCONV_DATADIR', join_paths(get_option('prefix'), get_option('datadir'))) final_conf.set_quoted('CC_IDENT', '@0@ @1@'.format(cc.get_id(), cc.version())) final_conf.set_quoted('BUILDSUF', '') final_conf.set_quoted('SLIBSUF', host_machine.system() == 'windows' ? '.dll' : '.so') final_conf.set('SWS_MAX_FILTER_SIZE', 256) final_conf.set('EXTERN_ASM', extern_prefix) final_conf.set_quoted('EXTERN_PREFIX', extern_prefix) if not get_option('nonfree').disabled() license = 'nonfree and unredistributable' elif not get_option('gpl').disabled() and not get_option('version3').disabled() license = 'GPL version 3 or later' elif not get_option('version3').disabled() license = 'LGPL version 3 or later' elif not get_option('gpl').disabled() license = 'GPL version 2 or later' else license = 'LGPL version 2.1 or later' endif final_conf.set_quoted('FFMPEG_LICENSE', license) message('License: ' + license) if not get_option('version3').disabled() if not get_option('gpl').disabled() conf.set('gplv3', 1) else conf.set('lgplv3', 1) endif endif conf.set('mmx2', conf.get('mmxext')) foreach restrict_kw : ['restrict', '__restrict__', '__restrict', ''] if not final_conf.has('av_restrict') and cc.compiles('void foo(char * @0@ p);'.format(restrict_kw)) final_conf.set('av_restrict', restrict_kw) endif endforeach foreach arch: arch_list final_conf.set('ARCH_@0@'.format(arch.to_upper()), conf.get(arch.to_lower())) endforeach foreach have: have_list if have == 'unistd_h' and conf.get(have) == 0 # an atrocious hack to get this working with the zlib subproject on windows... # zlib also uses a HAVE_UNISTD_H define, but it checks it with #ifdef and not #if continue endif final_conf.set('HAVE_@0@'.format(have.to_upper()), conf.get(have.to_lower())) endforeach foreach config: config_list + config_extra + all_components final_conf.set('CONFIG_@0@'.format(config.to_upper()), conf.get(config.to_lower())) endforeach configure_file( output: 'config.h', configuration: final_conf, ) configure_file( output: 'config.asm', output_format: 'nasm', configuration: final_conf, ) # Put this at the end so people see it if conf.get('x86_32') == 1 and conf.get('asm') == 1 and cc.get_id() == 'msvc' and cc.version().version_compare('<19.30') # -Dasm=enabled seems to hang reliably on some Visual Studio 2019 installations, ask users to report back to us warning('Using VS 2019 x86 with `asm` enabled: if you see a hang while linking, please report an issue at https://gitlab.freedesktop.org/gstreamer/meson-ports/ffmpeg/-/issues') endif