}
#include "defs.h"
-#include "metacube2.h"
+#include "shared/metacube2.h"
struct MHD_Connection;
struct MHD_Response;
#include "defs.h"
#include "jpeg_destroyer.h"
-#include "post_to_main_thread.h"
+#include "shared/post_to_main_thread.h"
#include "video_stream.h"
#include "ycbcr_converter.h"
#include "context.h"
#include "defs.h"
#include "disk_space_estimator.h"
-#include "ffmpeg_raii.h"
+#include "shared/ffmpeg_raii.h"
#include "flags.h"
#include "frame_on_disk.h"
#include "frame.pb.h"
#include "httpd.h"
#include "mainwindow.h"
#include "player.h"
-#include "post_to_main_thread.h"
+#include "shared/post_to_main_thread.h"
#include "ref_counted_gl_sync.h"
#include "timebase.h"
#include "ui_mainwindow.h"
#include "flags.h"
#include "frame_on_disk.h"
#include "player.h"
-#include "post_to_main_thread.h"
+#include "shared/post_to_main_thread.h"
#include "timebase.h"
#include "ui_mainwindow.h"
srcs = ['flow.cpp', 'gpu_timers.cpp']
# All the other files.
-srcs += ['ffmpeg_raii.cpp', 'main.cpp', 'player.cpp', 'httpd.cpp', 'mux.cpp', 'metacube2.cpp', 'video_stream.cpp', 'context.cpp', 'chroma_subsampler.cpp']
-srcs += ['vaapi_jpeg_decoder.cpp', 'memcpy_interleaved.cpp', 'db.cpp', 'disk_space_estimator.cpp', 'ycbcr_converter.cpp', 'flags.cpp']
+srcs += ['main.cpp', 'player.cpp', 'httpd.cpp', 'mux.cpp', 'video_stream.cpp', 'context.cpp', 'chroma_subsampler.cpp']
+srcs += ['vaapi_jpeg_decoder.cpp', 'db.cpp', 'disk_space_estimator.cpp', 'ycbcr_converter.cpp', 'flags.cpp']
srcs += ['mainwindow.cpp', 'jpeg_frame_view.cpp', 'clip_list.cpp', 'frame_on_disk.cpp']
srcs += moc_files
srcs += proto_generated
shader_srcs = bin2h_gen.process(shaders)
srcs += shader_srcs
-executable('futatabi', srcs, dependencies: [qt5deps, libjpegdep, movitdep, libmicrohttpddep, protobufdep, sqlite3dep, vax11dep, vadrmdep, x11dep, libavformatdep, libavcodecdep, libavutildep, libswscaledep])
+executable('futatabi', srcs, dependencies: [shareddep, qt5deps, libjpegdep, movitdep, libmicrohttpddep, protobufdep, sqlite3dep, vax11dep, vadrmdep, x11dep, libavformatdep, libavcodecdep, libavutildep, libswscaledep], link_with: shared)
executable('flow', 'flow_main.cpp', 'flow.cpp', 'gpu_timers.cpp', shader_srcs, dependencies: [epoxydep, sdl2dep, sdl2_imagedep])
executable('eval', 'eval.cpp', 'util.cpp')
executable('vis', 'vis.cpp', 'util.cpp')
#include "clip_list.h"
#include "context.h"
#include "defs.h"
-#include "ffmpeg_raii.h"
+#include "shared/ffmpeg_raii.h"
#include "frame_on_disk.h"
#include "httpd.h"
#include "jpeg_frame_view.h"
#include "jpeg_destroyer.h"
#include "jpeg_frame.h"
-#include "memcpy_interleaved.h"
+#include "shared/memcpy_interleaved.h"
#include <X11/Xlib.h>
#include <assert.h>
project('nageru', 'cpp', default_options: ['buildtype=debugoptimized'])
+cxx = meson.get_compiler('cpp')
+
+# Use lld if we can; it links a lot faster than ld.bfd or gold.
+code = '''#include <stdio.h>
+int main() { printf("Hello, world!\n"); return 0; }
+'''
+if cxx.links(code, args: '-fuse-ld=lld', name: 'check for LLD')
+ add_project_link_arguments('-fuse-ld=lld')
+endif
+
# Add the right MOVIT_SHADER_DIR definition.
r = run_command('pkg-config', '--variable=shaderdir', 'movit')
if r.returncode() != 0
endif
add_project_arguments('-DMOVIT_SHADER_DIR="' + r.stdout().strip() + '"', language: 'cpp')
+# DeckLink has these issues, and we include it from various places.
+if cxx.has_argument('-Wno-non-virtual-dtor')
+ add_project_arguments('-Wno-non-virtual-dtor', language: 'cpp')
+endif
+
+# FFmpeg has a lot of deprecated APIs whose replacements are not available
+# in Debian stable, so we suppress these warnings.
+if cxx.has_argument('-Wno-deprecated-declarations')
+ add_project_arguments('-Wno-deprecated-declarations', language: 'cpp')
+endif
+
+top_include = include_directories('.')
+
+subdir('shared')
subdir('nageru')
subdir('futatabi')
#include <libavutil/frame.h>
}
-#include "ffmpeg_raii.h"
+#include "shared/ffmpeg_raii.h"
class Mux;
#include "bmusb/bmusb.h"
#include "decklink_util.h"
#include "flags.h"
-#include "memcpy_interleaved.h"
+#include "shared/memcpy_interleaved.h"
#include "v210_converter.h"
#define FRAME_SIZE (8 << 20) // 8 MB.
#include <vector>
#include "bmusb/bmusb.h"
-#include "ffmpeg_raii.h"
+#include "shared/ffmpeg_raii.h"
#include "ffmpeg_util.h"
#include "flags.h"
#include "image_input.h"
}
#include "bmusb/bmusb.h"
-#include "ffmpeg_raii.h"
+#include "shared/ffmpeg_raii.h"
#include "ref_counted_frame.h"
#include "quittable_sleeper.h"
+++ /dev/null
-#include "ffmpeg_raii.h"
-
-extern "C" {
-#include <libavcodec/avcodec.h>
-#include <libavformat/avformat.h>
-#include <libavutil/dict.h>
-#include <libavutil/frame.h>
-#include <libswscale/swscale.h>
-}
-
-using namespace std;
-
-// AVFormatContext
-
-void avformat_close_input_unique::operator() (AVFormatContext *format_ctx) const
-{
- avformat_close_input(&format_ctx);
-}
-
-AVFormatContextWithCloser avformat_open_input_unique(
- const char *pathname, AVInputFormat *fmt,
- AVDictionary **options)
-{
- return avformat_open_input_unique(pathname, fmt, options, AVIOInterruptCB{ nullptr, nullptr });
-}
-
-AVFormatContextWithCloser avformat_open_input_unique(
- const char *pathname, AVInputFormat *fmt,
- AVDictionary **options,
- const AVIOInterruptCB &interrupt_cb)
-{
- AVFormatContext *format_ctx = avformat_alloc_context();
- format_ctx->interrupt_callback = interrupt_cb;
- if (avformat_open_input(&format_ctx, pathname, fmt, options) != 0) {
- format_ctx = nullptr;
- }
- return AVFormatContextWithCloser(format_ctx);
-}
-
-// AVCodecContext
-
-void avcodec_free_context_unique::operator() (AVCodecContext *codec_ctx) const
-{
- avcodec_free_context(&codec_ctx);
-}
-
-AVCodecContextWithDeleter avcodec_alloc_context3_unique(const AVCodec *codec)
-{
- return AVCodecContextWithDeleter(avcodec_alloc_context3(codec));
-}
-
-
-// AVCodecParameters
-
-void avcodec_parameters_free_unique::operator() (AVCodecParameters *codec_par) const
-{
- avcodec_parameters_free(&codec_par);
-}
-
-// AVFrame
-
-void av_frame_free_unique::operator() (AVFrame *frame) const
-{
- av_frame_free(&frame);
-}
-
-AVFrameWithDeleter av_frame_alloc_unique()
-{
- return AVFrameWithDeleter(av_frame_alloc());
-}
-
-// SwsContext
-
-void sws_free_context_unique::operator() (SwsContext *context) const
-{
- sws_freeContext(context);
-}
+++ /dev/null
-#ifndef _FFMPEG_RAII_H
-#define _FFMPEG_RAII_H 1
-
-// Some helpers to make RAII versions of FFmpeg objects.
-// The cleanup functions don't interact all that well with unique_ptr,
-// so things get a bit messy and verbose, but overall it's worth it to ensure
-// we never leak things by accident in error paths.
-//
-// This does not cover any of the types that can actually be declared as
-// a unique_ptr with no helper functions for deleter.
-
-#include <memory>
-
-struct AVCodec;
-struct AVCodecContext;
-struct AVCodecParameters;
-struct AVDictionary;
-struct AVFormatContext;
-struct AVFrame;
-struct AVInputFormat;
-struct SwsContext;
-typedef struct AVIOInterruptCB AVIOInterruptCB;
-
-// AVFormatContext
-struct avformat_close_input_unique {
- void operator() (AVFormatContext *format_ctx) const;
-};
-
-typedef std::unique_ptr<AVFormatContext, avformat_close_input_unique>
- AVFormatContextWithCloser;
-
-AVFormatContextWithCloser avformat_open_input_unique(
- const char *pathname, AVInputFormat *fmt,
- AVDictionary **options);
-
-AVFormatContextWithCloser avformat_open_input_unique(
- const char *pathname, AVInputFormat *fmt,
- AVDictionary **options,
- const AVIOInterruptCB &interrupt_cb);
-
-
-// AVCodecContext
-struct avcodec_free_context_unique {
- void operator() (AVCodecContext *ctx) const;
-};
-
-typedef std::unique_ptr<AVCodecContext, avcodec_free_context_unique>
- AVCodecContextWithDeleter;
-
-AVCodecContextWithDeleter avcodec_alloc_context3_unique(const AVCodec *codec);
-
-
-// AVCodecParameters
-struct avcodec_parameters_free_unique {
- void operator() (AVCodecParameters *codec_par) const;
-};
-
-typedef std::unique_ptr<AVCodecParameters, avcodec_parameters_free_unique>
- AVCodecParametersWithDeleter;
-
-
-// AVFrame
-struct av_frame_free_unique {
- void operator() (AVFrame *frame) const;
-};
-
-typedef std::unique_ptr<AVFrame, av_frame_free_unique>
- AVFrameWithDeleter;
-
-AVFrameWithDeleter av_frame_alloc_unique();
-
-// SwsContext
-struct sws_free_context_unique {
- void operator() (SwsContext *context) const;
-};
-
-typedef std::unique_ptr<SwsContext, sws_free_context_unique>
- SwsContextWithDeleter;
-
-#endif // !defined(_FFMPEG_RAII_H)
}
#include "defs.h"
-#include "metacube2.h"
+#include "shared/metacube2.h"
#include "metrics.h"
struct MHD_Connection;
#include <utility>
#include <vector>
-#include "ffmpeg_raii.h"
+#include "shared/ffmpeg_raii.h"
#include "ffmpeg_util.h"
#include "flags.h"
#include "alsa_pool.h"
#include "defs.h"
-#include "post_to_main_thread.h"
+#include "shared/post_to_main_thread.h"
#include "ui_input_mapping.h"
using namespace std;
#include "midi_mapping_dialog.h"
#include "mixer.h"
#include "nonlinear_fader.h"
-#include "post_to_main_thread.h"
+#include "shared/post_to_main_thread.h"
#include "ui_audio_expanded_view.h"
#include "ui_audio_miniview.h"
#include "ui_display.h"
+++ /dev/null
-#ifndef _MEMCPY_INTERLEAVED_H
-#define _MEMCPY_INTERLEAVED_H 1
-
-#include <stddef.h>
-#include <stdint.h>
-
-// Copies every other byte from src to dest1 and dest2.
-// TODO: Support stride.
-void memcpy_interleaved(uint8_t *dest1, uint8_t *dest2, const uint8_t *src, size_t n);
-
-#endif // !defined(_MEMCPY_INTERLEAVED_H)
protoc = find_program('protoc')
cxx = meson.get_compiler('cpp')
-# Use lld if we can; it links a lot faster than ld.bfd or gold.
-nageru_link_args = []
-code = '''#include <stdio.h>
-int main() { printf("Hello, world!\n"); return 0; }
-'''
-if cxx.links(code, args: '-fuse-ld=lld', name: 'check for LLD')
- nageru_link_args += '-fuse-ld=lld'
-endif
-
embedded_bmusb = get_option('embedded_bmusb')
alsadep = dependency('alsa')
zitaresamplerdep = cxx.find_library('zita-resampler')
srcs = []
-nageru_deps = [qt5deps, libjpegdep, movitdep, libmicrohttpddep, protobufdep,
+nageru_deps = [shareddep, qt5deps, libjpegdep, movitdep, libmicrohttpddep, protobufdep,
vax11dep, vadrmdep, x11dep, libavformatdep, libavresampledep, libavcodecdep, libavutildep,
libswscaledep, libusbdep, luajitdep, dldep, x264dep, alsadep, zitaresamplerdep,
qcustomplotdep, threaddep]
kaeru_link_with = []
kaeru_extra_deps = []
-# DeckLink has these issues, and we include it from various places.
-if cxx.has_argument('-Wno-non-virtual-dtor')
- add_project_arguments('-Wno-non-virtual-dtor', language: 'cpp')
-endif
-
-# FFmpeg has a lot of deprecated APIs whose replacements are not available
-# in Debian stable, so we suppress these warnings.
-if cxx.has_argument('-Wno-deprecated-declarations')
- add_project_arguments('-Wno-deprecated-declarations', language: 'cpp')
-endif
-
# CEF.
exe_dir = join_paths(get_option('prefix'), 'lib/nageru')
cef_dir = get_option('cef_dir')
# Streaming and encoding objects (largely the set that is shared between Nageru and Kaeru).
stream_srcs = ['quicksync_encoder.cpp', 'x264_encoder.cpp', 'x264_dynamic.cpp', 'x264_speed_control.cpp', 'video_encoder.cpp',
- 'metacube2.cpp', 'mux.cpp', 'audio_encoder.cpp', 'ffmpeg_raii.cpp', 'ffmpeg_util.cpp', 'httpd.cpp', 'ffmpeg_capture.cpp',
+ 'mux.cpp', 'audio_encoder.cpp', 'ffmpeg_util.cpp', 'httpd.cpp', 'ffmpeg_capture.cpp',
'print_latency.cpp', 'basic_stats.cpp', 'ref_counted_frame.cpp']
stream = static_library('stream', stream_srcs, dependencies: nageru_deps, include_directories: nageru_include_dirs)
nageru_link_with += stream
dependencies: nageru_deps,
include_directories: nageru_include_dirs,
link_with: nageru_link_with,
- link_args: nageru_link_args,
build_rpath: nageru_build_rpath,
install_rpath: nageru_install_rpath,
install: true,
dependencies: [nageru_deps, kaeru_extra_deps],
include_directories: nageru_include_dirs,
link_with: [stream, aux, kaeru_link_with],
- link_args: nageru_link_args,
install: true)
# Audio mixer microbenchmark.
-executable('benchmark_audio_mixer', 'benchmark_audio_mixer.cpp', dependencies: nageru_deps, include_directories: nageru_include_dirs, link_args: nageru_link_args, link_with: [audio, aux])
+executable('benchmark_audio_mixer', 'benchmark_audio_mixer.cpp', dependencies: nageru_deps, include_directories: nageru_include_dirs, link_with: [audio, aux])
# These are needed for a default run.
data_files = ['theme.lua', 'simple.lua', 'bg.jpeg', 'akai_midimix.midimapping']
+++ /dev/null
-/*
- * Implementation of Metacube2 utility functions.
- *
- * Note: This file is meant to compile as both C and C++, for easier inclusion
- * in other projects.
- */
-
-#include "metacube2.h"
-
-#include <byteswap.h>
-#include <netinet/in.h>
-
-/*
- * https://www.ece.cmu.edu/~koopman/pubs/KoopmanCRCWebinar9May2012.pdf
- * recommends this for messages as short as ours (see table at page 34).
- */
-#define METACUBE2_CRC_POLYNOMIAL 0x8FDB
-
-/* Semi-random starting value to make sure all-zero won't pass. */
-#define METACUBE2_CRC_START 0x1234
-
-/* This code is based on code generated by pycrc. */
-uint16_t metacube2_compute_crc(const struct metacube2_block_header *hdr)
-{
- static const int data_len = sizeof(hdr->size) + sizeof(hdr->flags);
- const uint8_t *data = (uint8_t *)&hdr->size;
- uint16_t crc = METACUBE2_CRC_START;
- int i, j;
-
- for (i = 0; i < data_len; ++i) {
- uint8_t c = data[i];
- for (j = 0; j < 8; j++) {
- int bit = crc & 0x8000;
- crc = (crc << 1) | ((c >> (7 - j)) & 0x01);
- if (bit) {
- crc ^= METACUBE2_CRC_POLYNOMIAL;
- }
- }
- }
-
- /* Finalize. */
- for (i = 0; i < 16; i++) {
- int bit = crc & 0x8000;
- crc = crc << 1;
- if (bit) {
- crc ^= METACUBE2_CRC_POLYNOMIAL;
- }
- }
-
- /*
- * Invert the checksum for metadata packets, so that clients that
- * don't understand metadata will ignore it as broken. There will
- * probably be logging, but apart from that, it's harmless.
- */
- if (ntohs(hdr->flags) & METACUBE_FLAGS_METADATA) {
- crc ^= 0xffff;
- }
-
- return crc;
-}
+++ /dev/null
-#ifndef _METACUBE2_H
-#define _METACUBE2_H
-
-/*
- * Definitions for the Metacube2 protocol, used to communicate with Cubemap.
- *
- * Note: This file is meant to compile as both C and C++, for easier inclusion
- * in other projects.
- */
-
-#include <stdint.h>
-
-#define METACUBE2_SYNC "cube!map" /* 8 bytes long. */
-#define METACUBE_FLAGS_HEADER 0x1
-#define METACUBE_FLAGS_NOT_SUITABLE_FOR_STREAM_START 0x2
-
-/*
- * Metadata packets; should not be counted as data, but rather
- * parsed (or ignored if you don't understand them).
- *
- * Metadata packets start with a uint64_t (network byte order)
- * that describe the type; the rest is defined by the type.
- */
-#define METACUBE_FLAGS_METADATA 0x4
-
-struct metacube2_block_header {
- char sync[8]; /* METACUBE2_SYNC */
- uint32_t size; /* Network byte order. Does not include header. */
- uint16_t flags; /* Network byte order. METACUBE_FLAGS_*. */
- uint16_t csum; /* Network byte order. CRC16 of size and flags.
- If METACUBE_FLAGS_METADATA is set, inverted
- so that older clients will ignore it as broken. */
-};
-
-uint16_t metacube2_compute_crc(const struct metacube2_block_header *hdr);
-
-/*
- * Set by the encoder, and can be measured for latency purposes (e.g., if the
- * network can't keep up, the latency will tend to increase.
- */
-#define METACUBE_METADATA_TYPE_ENCODER_TIMESTAMP 0x1
-
-struct metacube2_timestamp_packet {
- uint64_t type; /* METACUBE_METADATA_TYPE_ENCODER_TIMESTAMP, in network byte order. */
-
- /*
- * Time since the UTC epoch. Basically a struct timespec.
- * Both are in network byte order.
- */
- uint64_t tv_sec;
- uint64_t tv_nsec;
-};
-
-/*
- * Sent before a block to mark its presentation timestamp (ie., counts
- * only for the next Metacube block). Used so that the reflector can know
- * the length (in seconds) of fragments.
- */
-#define METACUBE_METADATA_TYPE_NEXT_BLOCK_PTS 0x2
-
-struct metacube2_pts_packet {
- uint64_t type; /* METACUBE_METADATA_TYPE_NEXT_BLOCK_PTS, in network byte order. */
-
- /* The timestamp of the first packet in the next block, in network byte order. */
- int64_t pts;
-
- /* Timebase "pts" is expressed in, as a fraction. Network byte order. */
- uint64_t timebase_num, timebase_den;
-};
-
-#endif /* !defined(_METACUBE_H) */
#include "midi_mapper.h"
#include "midi_mapping.pb.h"
-#include "post_to_main_thread.h"
+#include "shared/post_to_main_thread.h"
#include "ui_midi_mapping.h"
class QObject;
+++ /dev/null
-#ifndef _POST_TO_MAIN_THREAD_H
-#define _POST_TO_MAIN_THREAD_H 1
-
-#include <QApplication>
-#include <QObject>
-#include <memory>
-
-// http://stackoverflow.com/questions/21646467/how-to-execute-a-functor-in-a-given-thread-in-qt-gcd-style
-template<typename F>
-static inline void post_to_main_thread(F &&fun)
-{
- QObject signalSource;
- QObject::connect(&signalSource, &QObject::destroyed, qApp, std::move(fun));
-}
-
-#endif // !defined(_POST_TO_MAIN_THREAD_H)
#include "context.h"
#include "defs.h"
#include "disk_space_estimator.h"
-#include "ffmpeg_raii.h"
+#include "shared/ffmpeg_raii.h"
#include "flags.h"
#include "mux.h"
#include "print_latency.h"
#include "audio_encoder.h"
#include "defs.h"
-#include "ffmpeg_raii.h"
+#include "shared/ffmpeg_raii.h"
#include "flags.h"
#include "httpd.h"
#include "mux.h"
--- /dev/null
+
+srcs = ['memcpy_interleaved.cpp', 'metacube2.cpp', 'ffmpeg_raii.cpp']
+shared = static_library('shared', srcs, include_directories: top_include)
+shareddep = declare_dependency(
+ include_directories: top_include,
+ link_with: shared,
+ sources: srcs)