ref: b357123e7ce10816e947a8e4a07b9cff5b462c9e
parent: bfc4f5154840d0b3a3d611f65bd460826a8fcaf0
author: Mathieu Duponchelle <mathieu@centricular.com>
date: Sat Apr 14 19:03:33 EDT 2018
Add meson build definitions This is not a complete port, but a good first step towards using a simpler build system. In their current state, the build definitions work and have been tested on Linux and Windows (both against MSVC and mingw). The build will fail explicitly on all other platforms. No configuration options are currently exposed. The test suite has been ported, and the README updated.
--- a/README.md
+++ b/README.md
@@ -126,6 +126,10 @@
For All Platforms
-------------------
+
+Using make
+----------
+
From the main project directory:
- `make` for automatically detecting architecture and building accordingly
- `make ARCH=i386` for x86 32-bit builds
@@ -138,6 +142,32 @@
A shell script to run the command-line apps is in `testbin/CmdLineExample.sh`
Usage information can be found in `testbin/CmdLineReadMe`
+
+Using meson
+-----------
+
+Meson build definitions have been added, and are known to work on Linux
+and Windows, for x86 and x86 64-bit.
+
+See <http://mesonbuild.com/Installing.html> for instructions on how to
+install meson, then:
+
+``` shell
+meson builddir
+ninja -C builddir
+```
+
+Run the tests with:
+
+``` shell
+meson test -C builddir -v
+```
+
+Install with:
+
+``` shell
+ninja -C builddir install
+```
Using the Source
----------------
--- /dev/null
+++ b/codec/api/meson.build
@@ -1,0 +1,1 @@
+subdir ('svc')
--- /dev/null
+++ b/codec/api/svc/meson.build
@@ -1,0 +1,13 @@
+headers = [
+ 'codec_api.h',
+ 'codec_app_def.h',
+ 'codec_def.h',
+ 'codec_ver.h',
+]
+
+foreach header : headers
+ api_headers += [[header, files(header)]]
+endforeach
+
+install_headers(headers,
+ subdir: 'wels')
--- /dev/null
+++ b/codec/common/meson.build
@@ -1,0 +1,37 @@
+cpp_sources = [
+ 'src/common_tables.cpp',
+ 'src/copy_mb.cpp',
+ 'src/cpu.cpp',
+ 'src/crt_util_safe_x.cpp',
+ 'src/deblocking_common.cpp',
+ 'src/expand_pic.cpp',
+ 'src/intra_pred_common.cpp',
+ 'src/mc.cpp',
+ 'src/memory_align.cpp',
+ 'src/sad_common.cpp',
+ 'src/utils.cpp',
+ 'src/welsCodecTrace.cpp',
+ 'src/WelsTaskThread.cpp',
+ 'src/WelsThread.cpp',
+ 'src/WelsThreadLib.cpp',
+ 'src/WelsThreadPool.cpp',
+]
+
+asm_sources = [
+ 'x86/cpuid.asm',
+ 'x86/dct.asm',
+ 'x86/deblock.asm',
+ 'x86/expand_picture.asm',
+ 'x86/intra_pred_com.asm',
+ 'x86/mb_copy.asm',
+ 'x86/mc_chroma.asm',
+ 'x86/mc_luma.asm',
+ 'x86/satd_sad.asm',
+ 'x86/vaa.asm',
+]
+
+objs_asm = asm_gen.process(asm_sources)
+
+libcommon = static_library('common', cpp_sources, objs_asm,
+ include_directories: inc,
+ dependencies: deps)
--- /dev/null
+++ b/codec/console/common/meson.build
@@ -1,0 +1,12 @@
+cpp_sources = [
+ 'src/read_config.cpp'
+]
+
+conscomminc = [
+ inc,
+ console_common_inc,
+]
+
+libconsole_common = static_library('console_common', cpp_sources,
+ include_directories: conscomminc,
+ dependencies: deps)
--- /dev/null
+++ b/codec/console/dec/meson.build
@@ -1,0 +1,15 @@
+cpp_sources = [
+ 'src/d3d9_utils.cpp',
+ 'src/h264dec.cpp',
+]
+
+decinc = [
+ inc,
+ console_common_inc,
+ include_directories('inc'),
+]
+
+decexe = executable('h264dec', cpp_sources,
+ include_directories: decinc,
+ link_with: [libdecoder, libcommon, libconsole_common],
+ dependencies: deps)
--- /dev/null
+++ b/codec/console/enc/meson.build
@@ -1,0 +1,9 @@
+cpp_sources = [
+ 'src/welsenc.cpp',
+]
+
+encexe = executable('h264enc', cpp_sources,
+ include_directories: [inc, console_common_inc, processing_inc, encoder_inc],
+
+ link_with: [libencoder, libcommon, libprocessing, libconsole_common],
+ dependencies: [deps])
--- /dev/null
+++ b/codec/console/meson.build
@@ -1,0 +1,3 @@
+subdir('common')
+subdir('dec')
+subdir('enc')
--- /dev/null
+++ b/codec/decoder/meson.build
@@ -1,0 +1,33 @@
+cpp_sources = [
+ 'core/src/au_parser.cpp',
+ 'core/src/bit_stream.cpp',
+ 'core/src/cabac_decoder.cpp',
+ 'core/src/deblocking.cpp',
+ 'core/src/decode_mb_aux.cpp',
+ 'core/src/decode_slice.cpp',
+ 'core/src/decoder.cpp',
+ 'core/src/decoder_core.cpp',
+ 'core/src/decoder_data_tables.cpp',
+ 'core/src/error_concealment.cpp',
+ 'core/src/fmo.cpp',
+ 'core/src/get_intra_predictor.cpp',
+ 'core/src/manage_dec_ref.cpp',
+ 'core/src/memmgr_nal_unit.cpp',
+ 'core/src/mv_pred.cpp',
+ 'core/src/parse_mb_syn_cabac.cpp',
+ 'core/src/parse_mb_syn_cavlc.cpp',
+ 'core/src/pic_queue.cpp',
+ 'core/src/rec_mb.cpp',
+ 'plus/src/welsDecoderExt.cpp',
+]
+
+asm_sources = [
+ 'core/x86/dct.asm',
+ 'core/x86/intra_pred.asm',
+]
+
+objs_asm = asm_gen.process(asm_sources)
+
+libdecoder = static_library('decoder', cpp_sources, objs_asm,
+ include_directories: [inc, decoder_inc],
+ dependencies: deps)
--- /dev/null
+++ b/codec/encoder/meson.build
@@ -1,0 +1,51 @@
+cpp_sources = [
+ 'core/src/au_set.cpp',
+ 'core/src/deblocking.cpp',
+ 'core/src/decode_mb_aux.cpp',
+ 'core/src/encode_mb_aux.cpp',
+ 'core/src/encoder.cpp',
+ 'core/src/encoder_data_tables.cpp',
+ 'core/src/encoder_ext.cpp',
+ 'core/src/get_intra_predictor.cpp',
+ 'core/src/md.cpp',
+ 'core/src/mv_pred.cpp',
+ 'core/src/nal_encap.cpp',
+ 'core/src/paraset_strategy.cpp',
+ 'core/src/picture_handle.cpp',
+ 'core/src/ratectl.cpp',
+ 'core/src/ref_list_mgr_svc.cpp',
+ 'core/src/sample.cpp',
+ 'core/src/set_mb_syn_cabac.cpp',
+ 'core/src/set_mb_syn_cavlc.cpp',
+ 'core/src/slice_multi_threading.cpp',
+ 'core/src/svc_base_layer_md.cpp',
+ 'core/src/svc_enc_slice_segment.cpp',
+ 'core/src/svc_encode_mb.cpp',
+ 'core/src/svc_encode_slice.cpp',
+ 'core/src/svc_mode_decision.cpp',
+ 'core/src/svc_motion_estimate.cpp',
+ 'core/src/svc_set_mb_syn_cabac.cpp',
+ 'core/src/svc_set_mb_syn_cavlc.cpp',
+ 'core/src/wels_preprocess.cpp',
+ 'core/src/wels_task_base.cpp',
+ 'core/src/wels_task_encoder.cpp',
+ 'core/src/wels_task_management.cpp',
+ 'plus/src/welsEncoderExt.cpp',
+]
+
+asm_sources = [
+ 'core/x86/coeff.asm',
+ 'core/x86/dct.asm',
+ 'core/x86/intra_pred.asm',
+ 'core/x86/matrix_transpose.asm',
+ 'core/x86/memzero.asm',
+ 'core/x86/quant.asm',
+ 'core/x86/sample_sc.asm',
+ 'core/x86/score.asm',
+]
+
+objs_asm = asm_gen.process(asm_sources)
+
+libencoder = static_library('encoder', cpp_sources, objs_asm,
+ include_directories: [inc, processing_inc, encoder_inc],
+ dependencies: deps)
--- /dev/null
+++ b/codec/meson.build
@@ -1,0 +1,6 @@
+subdir('common')
+subdir('decoder')
+subdir('encoder')
+subdir('processing')
+subdir('console')
+subdir('api')
--- /dev/null
+++ b/codec/processing/meson.build
@@ -1,0 +1,31 @@
+cpp_sources = [
+ 'src/adaptivequantization/AdaptiveQuantization.cpp',
+ 'src/backgrounddetection/BackgroundDetection.cpp',
+ 'src/common/memory.cpp',
+ 'src/common/WelsFrameWork.cpp',
+ 'src/common/WelsFrameWorkEx.cpp',
+ 'src/complexityanalysis/ComplexityAnalysis.cpp',
+ 'src/denoise/denoise.cpp',
+ 'src/denoise/denoise_filter.cpp',
+ 'src/downsample/downsample.cpp',
+ 'src/downsample/downsamplefuncs.cpp',
+ 'src/imagerotate/imagerotate.cpp',
+ 'src/imagerotate/imagerotatefuncs.cpp',
+ 'src/scenechangedetection/SceneChangeDetection.cpp',
+ 'src/scrolldetection/ScrollDetection.cpp',
+ 'src/scrolldetection/ScrollDetectionFuncs.cpp',
+ 'src/vaacalc/vaacalcfuncs.cpp',
+ 'src/vaacalc/vaacalculation.cpp',
+]
+
+asm_sources = [
+ 'src/x86/denoisefilter.asm',
+ 'src/x86/downsample_bilinear.asm',
+ 'src/x86/vaa.asm',
+]
+
+objs_asm = asm_gen.process(asm_sources)
+
+libprocessing = static_library('processing', cpp_sources, objs_asm,
+ include_directories: [inc, processing_inc],
+ dependencies: deps)
--- /dev/null
+++ b/filecopier.py
@@ -1,0 +1,7 @@
+#!/usr/bin/env python3
+
+import sys
+import shutil
+
+shutil.copyfile(sys.argv[1], sys.argv[2])
+shutil.copymode(sys.argv[1], sys.argv[2])
--- /dev/null
+++ b/filesymlinker.py
@@ -1,0 +1,9 @@
+#!/usr/bin/env python3
+
+import sys
+import os
+
+try:
+ os.symlink(sys.argv[1], sys.argv[2])
+except:
+ pass
--- /dev/null
+++ b/include/meson.build
@@ -1,0 +1,1 @@
+subdir('wels')
--- /dev/null
+++ b/include/wels/meson.build
@@ -1,0 +1,9 @@
+api_header_deps
+
+foreach header : api_headers
+ api_header_deps += custom_target(header[0],
+ build_by_default: true,
+ input : header[1],
+ output : header[0],
+ command : [filecopier, '@INPUT@', '@OUTPUT@'])
+endforeach
--- /dev/null
+++ b/meson.build
@@ -1,0 +1,172 @@
+project('openh264', ['c', 'cpp'],
+ version : '1.7.0',
+ meson_version : '>= 0.43',
+ default_options : [ 'warning_level=1',
+ 'buildtype=debugoptimized' ])
+
+major_version = '4'
+
+cpp = meson.get_compiler('cpp')
+
+inc = include_directories([
+ join_paths('codec', 'api', 'svc'),
+ join_paths('codec', 'common', 'inc'),
+])
+
+processing_inc = include_directories([
+ join_paths('codec', 'processing', 'interface'),
+ join_paths('codec', 'processing', 'src', 'common'),
+ join_paths('codec', 'processing', 'src', 'adaptivequantization'),
+ join_paths('codec', 'processing', 'src', 'downsample'),
+ join_paths('codec', 'processing', 'src', 'scrolldetection'),
+ join_paths('codec', 'processing', 'src', 'vaacalc'),
+])
+
+console_common_inc = include_directories([
+ join_paths('codec', 'console', 'common', 'inc')
+])
+
+decoder_inc = include_directories([
+ join_paths('codec', 'decoder', 'core', 'inc'),
+ join_paths('codec', 'decoder', 'plus', 'inc'),
+])
+
+encoder_inc = include_directories([
+ join_paths('codec', 'encoder', 'core', 'inc'),
+ join_paths('codec', 'encoder', 'plus', 'inc'),
+])
+
+asm_inc = join_paths(meson.current_source_dir(), 'codec', 'common', 'x86', '')
+
+nasm = find_program('nasm', 'nasm.exe')
+
+system = host_machine.system()
+cpu_family = host_machine.cpu_family()
+
+supported_arguments = cpp.get_supported_arguments([
+ '-Wno-non-virtual-dtor',
+ '-Wno-strict-aliasing'])
+
+add_project_arguments(supported_arguments, language: 'cpp')
+
+deps = [dependency('threads')]
+c_args = []
+cpp_args = []
+asm_args = []
+shared_lib_suffix = ''
+
+if system == 'linux'
+ if cpu_family == 'x86'
+ asm_format = 'elf'
+ asm_args += ['-DX86_32']
+ add_project_arguments('-DX86_32_ASM', language: 'c')
+ elif cpu_family == 'x86_64'
+ asm_format = 'elf64'
+ asm_args += ['-DUNIX64']
+ else
+ error ('FIXME: unhandled CPU family @0@ for Linux'.format(cpu_family))
+ endif
+
+ deps += [cpp.find_library('libm')]
+
+ shared_lib_suffix = 'so.@0@'.format(meson.project_version())
+
+ asm_args += ['-DHAVE_AVX2']
+ add_project_arguments('-DHAVE_AVX2', language: 'cpp')
+ add_project_arguments('-DHAVE_AVX2', '-DX86_ASM', language: 'c')
+elif system == 'windows'
+ if cpu_family == 'x86'
+ asm_format = 'win32'
+ asm_args += ['-DPREFIX', '-DX86_32']
+ elif cpu_family == 'x86_64'
+ asm_format = 'win64'
+ asm_args += ['-DWIN64']
+ else
+ error ('FIXME: unhandled CPU family @0@ for Windows'.format(cpu_family))
+ endif
+else
+ error ('FIXME: Unhandled system @0@'.format(system))
+endif
+
+asm_gen = generator(nasm,
+ output : '@BASENAME@.o',
+ arguments : [
+ '-f', asm_format,
+ '-i', asm_inc,
+ '@INPUT@',
+ '-o', '@OUTPUT@'] + asm_args)
+
+api_headers = []
+api_header_deps = []
+
+subdir ('codec')
+subdir ('test')
+
+all_objects = [
+ libcommon.extract_all_objects(),
+ libprocessing.extract_all_objects(),
+ libencoder.extract_all_objects(),
+ libdecoder.extract_all_objects()
+]
+
+libopenh264_shared = shared_library('openh264',
+ objects: all_objects,
+ install: true,
+ name_suffix: shared_lib_suffix,
+ dependencies: deps)
+
+libopenh264_static = static_library('openh264',
+ objects: all_objects,
+ install: true,
+ dependencies: deps)
+
+pkg_install_dir = '@0@/pkgconfig'.format(get_option('libdir'))
+
+foreach t : ['', '-static']
+ pkgconf = configuration_data()
+ pkgconf.set('prefix', join_paths(get_option('prefix')))
+ pkgconf.set('VERSION', meson.project_version())
+ if t == '-static'
+ do_install = false
+ pkgconf.set('LIBS', '-lstdc++ -lpthread -lm')
+ pkgconf.set('LIBS_PRIVATE', '')
+ else
+ do_install = true
+ pkgconf.set('LIBS', '')
+ pkgconf.set('LIBS_PRIVATE', '-lstdc++ -lpthread -lm')
+ endif
+
+ message('do_install: @0@'.format(do_install))
+
+ configure_file(
+ input: 'openh264.pc.in',
+ output: 'openh264@0@.pc'.format(t),
+ install: t == '-static' ? false : true,
+ install_dir: t == '-static' ? '' : pkg_install_dir,
+ configuration: pkgconf)
+endforeach
+
+openh264_dep = declare_dependency(
+ link_with: libopenh264_shared,
+ include_directories: include_directories('include'),
+ dependencies: deps + api_header_deps)
+
+if system == 'linux'
+ filesymlinker = find_program('filesymlinker.py')
+ res = custom_target('libopenh264.so',
+ build_by_default: true,
+ input : libopenh264_shared,
+ output : 'libopenh264.so',
+ command : [filesymlinker, '@INPUT@', '@OUTPUT@'])
+
+ res = custom_target('libopenh264.so.@0@'.format(major_version),
+ build_by_default: true,
+ input : libopenh264_shared,
+ output : 'libopenh264.so.@0@'.format(major_version),
+ command : [filesymlinker, '@INPUT@', '@OUTPUT@'])
+
+ meson.add_install_script('post_install.py', get_option('libdir'), shared_lib_suffix, major_version)
+endif
+
+filecopier = find_program('filecopier.py')
+subdir ('include')
--- /dev/null
+++ b/post_install.py
@@ -1,0 +1,20 @@
+#!/usr/bin/env python3
+
+import sys
+import os
+
+destdir_prefix = os.environ['MESON_INSTALL_DESTDIR_PREFIX']
+libdir = os.path.join(destdir_prefix, sys.argv[1])
+suffix = sys.argv[2]
+major_version = sys.argv[3]
+
+try:
+ os.symlink('libopenh264.{}'.format(suffix), os.path.join(libdir, 'libopenh264.so.{}'.format(major_version)))
+except:
+ pass
+
+try:
+ os.symlink('libopenh264.so.{}'.format(major_version), os.path.join(libdir, 'libopenh264.so'))
+except:
+ pass
+
--- /dev/null
+++ b/subprojects/gtest.wrap
@@ -1,0 +1,10 @@
+[wrap-file]
+directory = googletest-release-1.8.0
+
+source_url = https://github.com/google/googletest/archive/release-1.8.0.zip
+source_filename = gtest-1.8.0.zip
+source_hash = f3ed3b58511efd272eb074a3a6d6fb79d7c2e6a0e374323d1e6bcbcc1ef141bf
+
+patch_url = https://wrapdb.mesonbuild.com/v1/projects/gtest/1.8.0/4/get_zip
+patch_filename = gtest-1.8.0-4-wrap.zip
+patch_hash = 0b90fe055acbdb002a37dfb035184b306008b763931158497ef5dbaa8c7925af
--- /dev/null
+++ b/test/api/meson.build
@@ -1,0 +1,29 @@
+test_sources = [
+ 'BaseDecoderTest.cpp',
+ 'BaseEncoderTest.cpp',
+ 'cpp_interface_test.cpp',
+ 'DataGenerator.cpp',
+ 'decode_api_test.cpp',
+ 'decode_encode_test.cpp',
+ 'decoder_ec_test.cpp',
+ 'decoder_test.cpp',
+ 'encode_decode_api_test.cpp',
+ 'encode_options_test.cpp',
+ 'encoder_test.cpp',
+ 'ltr_test.cpp',
+ 'simple_test.cpp',
+ 'c_interface_test.c',
+ 'sha1.c',
+]
+
+cpp_args = cpp.get_supported_arguments(['-Wno-dangling-else'])
+
+e = executable('test_api', test_sources,
+ dependencies : gtest_dep,
+ include_directories: [inc, test_inc],
+ cpp_args: cpp_args,
+ link_with: [libcommon, libencoder, libdecoder, libprocessing])
+
+test('api', e,
+ timeout: 300,
+ workdir: join_paths(meson.current_source_dir(), '..', '..'))
--- /dev/null
+++ b/test/common/meson.build
@@ -1,0 +1,13 @@
+test_sources = [
+ 'CWelsListTest.cpp',
+ 'ExpandPicture.cpp',
+ 'WelsThreadPoolTest.cpp',
+ 'WelsTaskListTest.cpp'
+]
+
+e = executable('test_common', test_sources,
+ dependencies : gtest_main_dep,
+ include_directories: [inc, test_inc],
+ link_with: [libcommon])
+
+test('common', e)
--- /dev/null
+++ b/test/decoder/meson.build
@@ -1,0 +1,18 @@
+test_sources = [
+ 'DecUT_Deblock.cpp',
+ 'DecUT_DeblockCommon.cpp',
+ 'DecUT_DecExt.cpp',
+ 'DecUT_ErrorConcealment.cpp',
+ 'DecUT_IdctResAddPred.cpp',
+ 'DecUT_IntraPrediction.cpp',
+ 'DecUT_ParseSyntax.cpp',
+ 'DecUT_PredMv.cpp',
+]
+
+e = executable('test_decoder', test_sources,
+ dependencies : gtest_main_dep,
+ include_directories: [inc, test_inc, decoder_inc],
+ link_with: [libcommon, libdecoder])
+
+test('decoder', e,
+ workdir: join_paths(meson.current_source_dir(), '..', '..'))
--- /dev/null
+++ b/test/encoder/meson.build
@@ -1,0 +1,32 @@
+test_sources = [
+ 'EncUT_Cavlc.cpp',
+ 'EncUT_DecodeMbAux.cpp',
+ 'EncUT_EncoderExt.cpp',
+ 'EncUT_EncoderMb.cpp',
+ 'EncUT_EncoderMbAux.cpp',
+ 'EncUT_EncoderTaskManagement.cpp',
+ 'EncUT_ExpGolomb.cpp',
+ 'EncUT_GetIntraPredictor.cpp',
+ 'EncUT_InterfaceTest.cpp',
+ 'EncUT_MBCopy.cpp',
+ 'EncUT_MemoryAlloc.cpp',
+ 'EncUT_MemoryZero.cpp',
+ 'EncUT_MotionCompensation.cpp',
+ 'EncUT_MotionEstimate.cpp',
+ 'EncUT_ParameterSetStrategy.cpp',
+ 'EncUT_Reconstruct.cpp',
+ 'EncUT_Sample.cpp',
+ 'EncUT_SVC_me.cpp',
+ 'EncUT_SliceBufferReallocate.cpp',
+]
+
+cpp_args = cpp.get_supported_arguments(['-Wno-dangling-else'])
+
+e = executable('test_encoder', test_sources + test_data_generator_sources + test_base_encoder_sources,
+ dependencies : gtest_main_dep,
+ include_directories: [inc, test_inc, encoder_inc, processing_inc],
+ cpp_args: cpp_args,
+ link_with: [libcommon, libencoder, libprocessing])
+
+test('encoder', e,
+ workdir: join_paths(meson.current_source_dir(), '..', '..'))
--- /dev/null
+++ b/test/meson.build
@@ -1,0 +1,15 @@
+gtest_main_dep = dependency('gtest', main : true, fallback: ['gtest', 'gtest_main_dep'], required: false)
+gtest_dep = dependency('gtest', fallback: ['gtest', 'gtest_dep'], required: false)
+
+test_inc = include_directories('.')
+
+test_data_generator_sources = files('api/DataGenerator.cpp')
+test_base_encoder_sources = files('api/BaseEncoderTest.cpp')
+
+if gtest_dep.found()
+ subdir('api')
+ subdir('common')
+ subdir('decoder')
+ subdir('encoder')
+ subdir('processing')
+endif
--- /dev/null
+++ b/test/processing/meson.build
@@ -1,0 +1,13 @@
+test_sources = [
+ 'ProcessUT_AdaptiveQuantization.cpp',
+ 'ProcessUT_DownSample.cpp',
+ 'ProcessUT_ScrollDetection.cpp',
+ 'ProcessUT_VaaCalc.cpp',
+]
+
+e = executable('test_processing', test_sources + test_data_generator_sources,
+ dependencies : gtest_main_dep,
+ include_directories: [inc, test_inc, processing_inc],
+ link_with: [libcommon, libprocessing])
+
+test('processing', e)