Live video on the AT Protocol
1project(
2 'streamplace',
3 'c',
4 'cpp',
5 default_options: {
6 'cpp_std': 'c++11',
7 'default_library': 'static',
8 'auto_features': 'disabled',
9 'force_fallback_for': 'gio-2.0,gstreamer-controller-1.0,gstreamer-app-1.0,gstreamer-pbutils-1.0,glib-2.0,gobject-2.0,gio-2.0,gio-unix-2.0,fdk-aac,zlib,libffi,pcre2,intl,proxy-libintl,x264,freetype2,libpng,libjpeg,fontconfig,pango,opus,fribidi,harfbuzz,nettle,cairo,pixman,expat,openssl',
10 'buildtype': 'debugoptimized',
11 'prefix': meson.current_build_dir(), # otherwise mac meson will try and do /opt/homebrew sometimes
12 'libdir': 'lib'
13 },
14)
15
16env = {}
17if get_option('default_library') == 'static'
18 env = {
19 'PKG_CONFIG_PATH': meson.current_build_dir() + '/meson-uninstalled',
20 }
21else
22 env = {
23 'PKG_CONFIG_PATH': meson.current_build_dir() + '/lib/pkgconfig',
24 }
25endif
26
27GOOS = meson.get_external_property('GOOS', host_machine.system())
28GOARCH = meson.get_external_property('GOARCH', host_machine.cpu())
29if GOARCH == 'x86_64'
30 GOARCH = 'amd64'
31endif
32if GOARCH == 'aarch64'
33 GOARCH = 'arm64'
34endif
35if meson.is_cross_build()
36 env += {
37 'GOOS': GOOS,
38 'GOARCH': GOARCH,
39 'CGO_ENABLED': '1',
40 'CC': meson.get_compiler('c', native: false).cmd_array()[0],
41 }
42endif
43
44streamplace_deps = []
45# if host_machine.system() == 'linux'
46# mistserver_proj = subproject(
47# 'mistserver',
48# default_options: {
49# 'APPNAME': 'MistServer',glib
50# },
51# )
52# mistserver = mistserver_proj.get_variable('libmistserver_dep')
53# streamplace_deps += mistserver
54# endif
55
56x264_proj = subproject(
57 'x264',
58 default_options: {},
59)
60
61proxy_libintl_proj = subproject(
62 'proxy-libintl',
63 default_options: {},
64)
65
66ffmpeg_opts = {
67 'aac_adtstoasc_bsf': 'enabled',
68 'aac_decoder': 'enabled',
69 'aac_latm_parser': 'enabled',
70 'aac_parser': 'enabled',
71 'aformat_filter': 'enabled',
72 'aresample_filter': 'enabled',
73 'asetnsamples_filter': 'enabled',
74 'auto_features': 'enabled',
75 'concat_demuxer': 'enabled',
76 'concat_filter': 'enabled',
77 'concat_protocol': 'enabled',
78 'concatf_protocol': 'enabled',
79 'extract_extradata_bsf': 'enabled',
80 'fd_protocol': 'enabled',
81 'fifo_muxer': 'enabled',
82 'file_protocol': 'enabled',
83 'flac_decoder': 'enabled',
84 'flac_demuxer': 'enabled',
85 'flac_muxer': 'enabled',
86 'flac_parser': 'enabled',
87 'flv_demuxer': 'enabled',
88 'format_filter': 'enabled',
89 'fps_filter': 'enabled',
90 'gpl': 'enabled',
91 'h264_cuvid_decoder': 'enabled',
92 'h264_decoder': 'enabled',
93 'h264_metadata_bsf': 'enabled',
94 'h264_mp4toannexb_bsf': 'enabled',
95 'h264_parser': 'enabled',
96 'h264_redundant_pps_bsf': 'enabled',
97 'hevc_cuvid_decoder': 'enabled',
98 'hevc_mp4toannexb_bsf': 'enabled',
99 'hevc_muxer': 'enabled',
100 'hevc_parser': 'enabled',
101 'hls_muxer': 'enabled',
102 'http_protocol': 'enabled',
103 'hwdownload_filter': 'enabled',
104 'image2_demuxer': 'enabled',
105 'libxcb': 'enabled',
106 'matroska_audio_muxer': 'enabled',
107 'matroska_demuxer': 'enabled',
108 'matroska_muxer': 'enabled',
109 'mov_demuxer': 'enabled',
110 'mp3_decoder': 'enabled',
111 'mp3_demuxer': 'enabled',
112 'mp3_muxer': 'enabled',
113 'mp4_muxer': 'enabled',
114 'mpegaudio_parser': 'enabled',
115 'mpegts_demuxer': 'enabled',
116 'mpegts_muxer': 'enabled',
117 'network': 'enabled',
118 'null_muxer': 'enabled',
119 'opus_decoder': 'enabled',
120 'opus_parser': 'enabled',
121 'pipe_protocol': 'enabled',
122 'png_decoder': 'enabled',
123 'png_parser': 'enabled',
124 'rtmp_protocol': 'enabled',
125 'scale_filter': 'enabled',
126 'segment_muxer': 'enabled',
127 'stream_segment_muxer': 'enabled',
128 'select_filter': 'enabled',
129 'signature_filter': 'enabled',
130 'tcp_protocol': 'enabled',
131 'vorbis_decoder': 'enabled',
132 'vorbis_parser': 'enabled',
133 'vp8_cuvid_decoder': 'enabled',
134 'vp8_parser': 'enabled',
135 'vp9_cuvid_decoder': 'enabled',
136 'vp9_parser': 'enabled',
137 'wav_demuxer': 'enabled',
138 'wav_muxer': 'enabled',
139 'webm_muxer': 'enabled',
140 'x86asm': 'enabled',
141 'mov_muxer': 'enabled',
142 'vp9_superframe_bsf': 'enabled',
143 'ac3_parser': 'enabled',
144 'pgs_frame_merge_bsf': 'enabled',
145 'libx264': 'enabled',
146 'libx264_encoder': 'enabled',
147 'libx264rgb_encoder': 'enabled',
148 'mpegtsraw_demuxer': 'enabled',
149 'adts_muxer': 'enabled',
150 'latm_muxer': 'enabled',
151 'vvc_mp4toannexb_bsf': 'enabled',
152}
153
154if host_machine.system() != 'windows'
155 ffmpeg_opts += {'nanosleep': 'enabled'}
156endif
157
158# Someday maybe once the meson port of ffmpeg supports cuda
159
160# if host_machine.system() != 'darwin'
161# ffmpeg_opts += {
162# 'ff_cuda_llvm': 'enabled',
163# 'cuda': 'enabled',
164# 'hwupload_cuda_filter': 'enabled',
165# 'scale_cuda_filter': 'enabled',
166# # 'signature_cuda_filter': 'enabled',
167# 'ffnvcodec': 'enabled',
168# 'h264_nvenc_encoder': 'enabled',
169# 'nvenc': 'enabled',
170# 'nvdec': 'enabled',
171# 'h264_nvdec_hwaccel': 'enabled',
172# 'libdl': 'enabled',
173# }
174# endif
175
176ffmpeg_proj = subproject(
177 'FFmpeg',
178 # vvc seems to have problems building as a submodule?
179 default_options: ffmpeg_opts,
180)
181avformat = ffmpeg_proj.get_variable('libavformat_dep')
182avfilter = ffmpeg_proj.get_variable('libavfilter_dep')
183streamplace_deps += [avformat, avfilter]
184
185gstreamer_proj = subproject(
186 'gstreamer-full',
187 default_options: {},
188)
189
190streamplace_deps += [
191 dependency('gio-2.0'),
192 dependency('gstreamer-controller-1.0'),
193 dependency('gstreamer-app-1.0'),
194 dependency('gstreamer-pbutils-1.0'),
195 dependency('libffi'),
196]
197
198atproto = subproject(
199 'atproto',
200 default_options: {},
201)
202
203if get_option('default_library') == 'static'
204 gst_full_dep = gstreamer_proj.get_variable('gst_full_dep')
205 streamplace_deps += [
206 gst_full_dep,
207 dependency('gstplayback'),
208 ]
209endif
210
211subdir('rust/iroh-streamplace')
212
213if host_machine.system() == 'darwin'
214 streamplace_deps += [
215 dependency(
216 'appleframeworks',
217 modules: ['CoreFoundation', 'Security', 'SystemConfiguration'],
218 ),
219 ]
220endif
221if host_machine.system() == 'windows'
222 add_project_link_arguments(
223 [
224 '-lntdll',
225 '-luserenv',
226 '-lcrypt32',
227 '-lbcrypt',
228 '-static-libstdc++',
229 '-static-libgcc',
230 ],
231 language: ['c', 'cpp'],
232 )
233endif
234
235pkg = import('pkgconfig')
236pkg.generate(
237 name: 'streamplacedeps',
238 libraries: [streamplace_deps, iroh_streamplace_dep],
239 description: 'all streamplace dependencies bundled for easy inclusion',
240)
241
242# dummy executable that we use as a target to convince meson to build all the streamplace dependencies
243executable(
244 'streamplacedeps',
245 ['cmd/streamplace/empty.c'],
246 dependencies: [
247 streamplace_deps,
248 ],
249 link_with: [iroh_streamplace_dep],
250 install_tag: 'streamplacedeps',
251)
252
253if get_option('default_library') == 'static'
254 prog_go = find_program('go')
255
256 flagbuilder = custom_target(
257 'flagbuilder',
258 input: ['pkg/config/git/git.go'],
259 output: ['flagbuilder'],
260 command: [prog_go, 'build', '-o', '@OUTPUT0@', '@INPUT@'],
261 build_always_stale: true,
262 env: {
263 'CGO_ENABLED': '0',
264 },
265 )
266 version_cmd = run_command(prog_go, 'run', 'pkg/config/git/git.go', '-v', check: true, env: {
267 'CGO_ENABLED': '0',
268 })
269 version = version_cmd.stdout().strip()
270
271 streamplace_go = custom_target(
272 'streamplace.go',
273 input: 'cmd/libstreamplace/streamplace.go',
274 output: 'streamplace.go',
275 command: ['cp', '@INPUT@', '@OUTPUT@'],
276 )
277 flags = custom_target(
278 'flags',
279 input: [],
280 output: ['build-flags.go'],
281 command: [flagbuilder, '-o', '@OUTPUT0@'],
282 build_always_stale: true,
283 )
284
285 libstreamplace = custom_target(
286 'libstreamplace',
287 input: [streamplace_go, flags],
288 output: ['streamplace.a', 'streamplace.h'],
289 command: [
290 prog_go,
291 'build',
292 '-o', '@OUTPUT0@',
293 '-buildmode', 'c-archive',
294 '-tags', 'netgo,static,mainnet',
295 '@INPUT@',
296 ],
297 build_always_stale: true,
298 env: env,
299 )
300
301 if build_machine.system() == 'linux' and host_machine.system() == 'darwin'
302 # this only exists to convince meson to build all of the streamplace dependencies
303 # the real binary comes from the `go build` command below
304 cstreamplace = executable(
305 'cstreamplace',
306 ['cmd/streamplace/streamplace.c', libstreamplace],
307 dependencies: [
308 streamplace_deps,
309 ],
310 link_with: [iroh_streamplace_dep],
311 )
312
313 streamplace = custom_target(
314 'streamplace',
315 input: [cstreamplace, flags],
316 output: ['streamplace'],
317 command: [
318 prog_go,
319 'build',
320 '-o', '@OUTPUT0@',
321 '-tags', 'netgo,static,mainnet',
322 'streamplace.go',
323 '@INPUT1@'
324 ],
325 build_always_stale: true,
326 env: env,
327 )
328 else
329 streamplace = executable(
330 'streamplace',
331 ['cmd/streamplace/streamplace.c', libstreamplace],
332 dependencies: [
333 streamplace_deps,
334 ],
335 link_with: [iroh_streamplace_dep],
336 )
337 endif
338
339
340 if not meson.is_cross_build()
341 test(
342 'go-tests',
343 prog_go,
344 depends: [streamplace],
345 env: env,
346 verbose: true,
347 timeout: 0,
348 args: [
349 'test',
350 '-p', '1',
351 '-timeout', '600s',
352 '@0@/pkg/...'.format(meson.current_source_dir()),
353 '@0@/cmd/...'.format(meson.current_source_dir()),
354 ],
355 )
356 endif
357
358 if host_machine.system() == 'windows'
359 prog_zip = find_program('zip')
360 archive_name = 'streamplace-' + version + '-' + GOOS + '-' + GOARCH + '.zip'
361 custom_target(
362 'archive',
363 input: [streamplace],
364 output: ['streamplace.zip'],
365 command: [prog_zip, '../bin/' + archive_name, '@INPUT@'],
366 install: true,
367 install_dir: './bin',
368 build_by_default: false,
369 )
370 else
371 prog_tar = find_program('tar')
372 # archive_name = streamplace-$(VERSION)-$$GOOS-$$GOARCH.tar.gz
373 archive_name = 'streamplace-' + version + '-' + GOOS + '-' + GOARCH + '.tar.gz'
374 custom_target(
375 'archive',
376 input: [streamplace],
377 output: ['streamplace.tar.gz'],
378 command: [prog_tar, '-czvf', '../bin/' + archive_name, '@INPUT@'],
379 install: true,
380 install_dir: './bin',
381 build_by_default: false,
382 )
383 endif
384endif