shithub: openh264

Download patch

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.

diff: cannot open b/include/wels//null: file does not exist: 'b/include/wels//null' diff: cannot open b/include//null: file does not exist: 'b/include//null' diff: cannot open b/subprojects//null: file does not exist: 'b/subprojects//null'
--- 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)