summaryrefslogtreecommitdiff
path: root/src/codec
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-09-08 13:54:36 -0400
committerAndrew Opalach <andrew@akon.city> 2025-09-08 13:54:36 -0400
commitce955da36daa278d5b331b3c97e228e733a5125e (patch)
treee221231e7c0da5324355af44a2e53f41166e3a05 /src/codec
parentcbbb0c16dc3d9c375ac2a18ca3d59cc308d41beb (diff)
downloadcamu-ce955da36daa278d5b331b3c97e228e733a5125e.tar.gz
camu-ce955da36daa278d5b331b3c97e228e733a5125e.tar.bz2
camu-ce955da36daa278d5b331b3c97e228e733a5125e.zip
Major FFmpeg build improvements
- Make build more compatible with a traditional linux environment. Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/codec')
-rw-r--r--src/codec/codec.h2
-rw-r--r--src/codec/ffmpeg/common.c16
-rw-r--r--src/codec/ffmpeg/decoder.c17
-rw-r--r--src/codec/ffmpeg/decoder.h2
-rw-r--r--src/codec/ffmpeg/demuxer.c12
-rw-r--r--src/codec/ffmpeg/meson.build157
-rw-r--r--src/codec/ffmpeg/packet_ext.c8
7 files changed, 115 insertions, 99 deletions
diff --git a/src/codec/codec.h b/src/codec/codec.h
index 701ef16..9820316 100644
--- a/src/codec/codec.h
+++ b/src/codec/codec.h
@@ -56,8 +56,10 @@ enum {
CAMU_SAMPLE_FORMAT_S32P = AV_SAMPLE_FMT_S32P,
CAMU_SAMPLE_FORMAT_FLTP = AV_SAMPLE_FMT_FLTP,
CAMU_SAMPLE_FORMAT_DBLP = AV_SAMPLE_FMT_DBLP,
+#ifndef CAMU_OLD_FFMPEG
CAMU_SAMPLE_FORMAT_S64 = AV_SAMPLE_FMT_S64,
CAMU_SAMPLE_FORMAT_S64P = AV_SAMPLE_FMT_S64P
+#endif
};
enum {
diff --git a/src/codec/ffmpeg/common.c b/src/codec/ffmpeg/common.c
index 5226df6..e697a00 100644
--- a/src/codec/ffmpeg/common.c
+++ b/src/codec/ffmpeg/common.c
@@ -1,4 +1,5 @@
#define AL_LOG_SECTION "ff"
+//#define AL_LOG_ENABLE_TRACE
#include <al/log.h>
#include <al/lib.h>
#include <libavutil/log.h>
@@ -27,10 +28,6 @@ static void av_log_callback(void *userdata, s32 level, const char *fmt, va_list
{
(void)userdata;
- if (level >= AV_LOG_DEBUG) {
- return;
- }
-
char *offset = log_context.buf + log_context.pos;
s32 ret = al_vsnprintf(offset, AV_LOG_MAX_CHUNK, fmt, args);
al_assert(ret > 0);
@@ -41,8 +38,10 @@ static void av_log_callback(void *userdata, s32 level, const char *fmt, va_list
if ((log_context.pos > 0 && *(offset - 1) == '\n') || log_context.pos >= AV_LOG_MAX_CHUNK) {
if (level < AV_LOG_WARNING) {
log_info(log_context.buf);
- } else {
+ } else if (level < AL_LOG_DEBUG) {
log_debug(log_context.buf);
+ } else {
+ log_trace(log_context.buf);
}
log_context.pos = 0;
}
@@ -55,9 +54,14 @@ void camu_ff_set_log_callback(void (*callback)(void *, s32, const char *, va_lis
void camu_ff_common_init(void)
{
- log_info("Using FFmpeg version "FFMPEG_VERSION".");
+
#ifdef CAMU_OLD_FFMPEG
+ log_info("Using FFmpeg version "FFMPEG_VERSION" (old).");
+ AL_IGNORE_WARNING("-Wdeprecated-declarations")
av_register_all();
+ AL_IGNORE_WARNING_END
+#else
+ log_info("Using FFmpeg version "FFMPEG_VERSION".");
#endif
camu_ff_set_log_callback(av_log_callback);
}
diff --git a/src/codec/ffmpeg/decoder.c b/src/codec/ffmpeg/decoder.c
index 7be21a2..47bab44 100644
--- a/src/codec/ffmpeg/decoder.c
+++ b/src/codec/ffmpeg/decoder.c
@@ -5,17 +5,20 @@
#include "decoder.h"
-#if !defined CAMU_SINK_NO_VIDEO && defined CAMU_FF_DECODER_HWACCEL
+#ifdef CAMU_FF_DECODER_HWACCEL
#include "../../render/renderer.h"
static const char *hwdevces[] = {
-#if defined STELA_API_VULKAN
+#ifdef CAMU_HAVE_VULKAN_DECODE
"vulkan",
-#else
-#if defined NAUNET_ON_WINDOWS
- "d3d11va",
-#else
+#endif
+#ifdef CAMU_HAVE_VAAPI
"vaapi",
#endif
+#ifdef CAMU_HAVE_D3D11VA
+ "d3d11va",
+#endif
+#ifdef CAMU_HAVE_DXVA2
+ "dxva2",
#endif
};
#endif
@@ -179,6 +182,8 @@ static bool get_hwdevice_config(struct camu_ff_decoder *av, const AVCodec *codec
return true;
}
}
+ const char *hwdevice_name = av_hwdevice_get_type_name(hw_device_type);
+ log_warn("No hw_config for device type %s (type: %d).", hwdevice_name, hw_device_type);
return false;
}
diff --git a/src/codec/ffmpeg/decoder.h b/src/codec/ffmpeg/decoder.h
index 85b88dc..ff513b9 100644
--- a/src/codec/ffmpeg/decoder.h
+++ b/src/codec/ffmpeg/decoder.h
@@ -4,7 +4,7 @@
#include "../codec.h"
-#ifdef CAMU_USE_HWACCEL
+#if defined CAMU_TRY_HWACCEL && !defined CAMU_SINK_NO_VIDEO
#define CAMU_FF_DECODER_HWACCEL
#endif
diff --git a/src/codec/ffmpeg/demuxer.c b/src/codec/ffmpeg/demuxer.c
index f05cfa9..a8f1df7 100644
--- a/src/codec/ffmpeg/demuxer.c
+++ b/src/codec/ffmpeg/demuxer.c
@@ -1,4 +1,5 @@
#define AL_LOG_SECTION "ff_demuxer"
+//#define AL_LOG_ENABLE_TRACE
#include <al/log.h>
#include <al/lib.h>
@@ -9,7 +10,12 @@ static void close_internal(struct camu_ff_demuxer *av)
{
if (av->io_context) {
av_free(av->io_context->buffer);
+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 80, 100)
avio_context_free(&av->io_context);
+#else
+ av_free(av->io_context);
+ av->io_context = NULL;
+#endif
}
if (av->format_context) {
avformat_flush(av->format_context);
@@ -126,9 +132,13 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl
}));
}
+#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(60, 30, 100)
av_format_inject_global_side_data(av->format_context);
+#endif
- //av_dump_format(av->format_context, 0, "", 0);
+#ifdef AL_LOG_ENABLE_TRACE
+ av_dump_format(av->format_context, 0, "", 0);
+#endif
av->eof = false;
diff --git a/src/codec/ffmpeg/meson.build b/src/codec/ffmpeg/meson.build
index 56a75b2..6482426 100644
--- a/src/codec/ffmpeg/meson.build
+++ b/src/codec/ffmpeg/meson.build
@@ -1,97 +1,88 @@
-ffmpeg_src = [
- 'common.c',
- 'packet_ext.c',
-]
+ffmpeg_src = ['common.c', 'packet_ext.c']
ffmpeg_args = ['-DCAMU_HAVE_FFMPEG']
-if get_option('codec-hwaccel').enabled()
- ffmpeg_args += ['-DCAMU_USE_HWACCEL']
-endif
-ffmpeg_deps = []
-
-ffmpeg_server_src = [
- ffmpeg_src,
- 'demuxer.c',
- 'avio.c'
-]
-ffmpeg_server_deps = []
-
-ffmpeg_client_src = [
- ffmpeg_src,
- 'decoder.c',
- 'resampler.c',
- 'scaler.c'
-]
-ffmpeg_client_deps = []
+ffmpeg_server_src = [ffmpeg_src, 'demuxer.c', 'avio.c']
server_transcode = not get_option('sink-only')
if server_transcode
- ffmpeg_server_src += [
- 'decoder.c',
- 'resampler.c',
- 'scaler.c',
- 'encoder.c'
- ]
+ ffmpeg_server_src += ['decoder.c', 'resampler.c', 'scaler.c', 'encoder.c']
endif
+ffmpeg_server_deps = []
+
+ffmpeg_client_src = [ffmpeg_src, 'decoder.c', 'resampler.c', 'scaler.c']
+ffmpeg_client_deps = []
-libavutil = dependency('libavutil', required: false)
-libavformat = dependency('libavformat', required: false)
-libavcodec = dependency('libavcodec', required: false)
-#libavdevice = dependency('libavdevice', required: false)
-libswresample = dependency('libswresample', required: false)
-libswscale = dependency('libswscale', required: false)
-if not (libavutil.found() and libavformat.found() and libavcodec.found() and libswresample.found() and libswscale.found())
- if get_option('win32-compat')
- ffmpeg_proj = subproject('ffmpeg-compat', required: false)
- ffmpeg_args += ['-DCAMU_OLD_FFMPEG']
+ffmpeg_force_fallback = false
+foreach dep: ['ffmpeg', 'libavutil', 'libavformat', 'libavcodec', 'libavdevice', 'libswresample', 'libswscale']
+ if dep in get_option('force_fallback_for')
+ ffmpeg_force_fallback = true
+ break
+ endif
+endforeach
+ffmpeg_version_option = get_option('codec-ffmpeg-version')
+# Check for FFmpeg version in the environment.
+if not ffmpeg_force_fallback
+ libavutil_version_map = { '54': '2', '55': '3', '56': '4', '57': '5', '58': '6', '59': '7', '60': '8' }
+ libavutil_version_rev = { '2': '54', '3': '55', '4': '56', '5': '57', '6': '58', '7': '59', '8': '60' }
+ if ffmpeg_version_option != 'system'
+ ffmpeg_version_int = ffmpeg_version_option.to_int()
+ # Overriding a found dependency will error but overriding a found dependency of the wrong version is allowed.
+ libavutil_version_request = ['>=' + libavutil_version_rev[(ffmpeg_version_int).to_string()] + '.0.0']
+ if ffmpeg_version_int < 8
+ libavutil_version_request += ['<' + libavutil_version_rev[(ffmpeg_version_int + 1).to_string()] + '.0.0']
+ endif
+ libavutil = dependency('libavutil', required: false, allow_fallback: false, version: libavutil_version_request)
else
- ffmpeg_proj = subproject('ffmpeg', required: false)
+ libavutil = dependency('libavutil', required: false, allow_fallback: false)
endif
- if ffmpeg_proj.found()
- libavutil = ffmpeg_proj.get_variable('avutil')
- libavformat = ffmpeg_proj.get_variable('avformat')
- libavcodec = ffmpeg_proj.get_variable('avcodec')
- #libavdevice = ffmpeg_proj.get_variable('avdevice')
- libswresample = ffmpeg_proj.get_variable('swresample')
- libswscale = ffmpeg_proj.get_variable('swscale')
- # Only used to set include dirs for FFmpeg.
- ffmpeg_deps += [ffmpeg_proj.get_variable('ffmpeg_include')]
- # We explicitly enable zlib and maybe bzlib in the FFmpeg build.
- ffmpeg_deps += [dependency('zlib')]
- if not get_option('sink-only')
- ffmpeg_deps += [dependency('bzip2')]
+ if libavutil.found()
+ ffmpeg_version_string = run_command('sh', join_paths(meson.current_source_dir(), 'version.sh'), check: true).stdout().strip()
+ if ffmpeg_version_string == '(unknown)'
+ ffmpeg_version_string = libavutil_version_map[libavutil.version().split('.')[0]] + '.x'
endif
- if is_windows and not get_option('win32-compat')
- # Extra static dependencies for Windows.
- ffmpeg_client_deps += [compiler.find_library('bcrypt')]
- elif is_android
- # Android MediaCodec HW decoding.
- ffmpeg_client_deps += [compiler.find_library('mediandk')]
+ ffmpeg_args += ['-DFFMPEG_VERSION="' + ffmpeg_version_string + '"']
+ if get_option('codec-hwaccels').length() > 0
+ hwaccel_map = {
+ 'vulkan': '-DCAMU_HAVE_VULKAN_DECODE',
+ 'vaapi': '-DCAMU_HAVE_VAAPI',
+ 'd3d11va': '-DCAMU_HAVE_D3D11VA',
+ 'dxva2': '-DCAMU_HAVE_DXVA2',
+ 'mediacodec': '-DCAMU_HAVE_MEDIACODEC',
+ }
+ foreach hwaccel: get_option('codec-hwaccels')
+ if hwaccel in hwaccel_map
+ ffmpeg_args += hwaccel_map[hwaccel]
+ endif
+ endforeach
+ ffmpeg_args += ['-DCAMU_TRY_HWACCEL']
endif
- ffmpeg_version_string = ffmpeg_proj.get_variable('ffmpeg_version_string')
+ elif ffmpeg_version_option == 'system'
+ error('System FFmpeg requested but not found. Add \'--force-fallback-for=ffmpeg\' or \'-Dcodec-ffmpeg-version=[8,7,6,...]\'.')
endif
-else
- ffmpeg_version_string = run_command('sh', join_paths(meson.current_source_dir(), 'version.sh'), check: true).stdout().strip()
endif
-
-if libavutil.found() and libavformat.found() and libavcodec.found() and libswresample.found() and libswscale.found()
- # This is probably meaningless compared to libav* versions, it's just something I wanted.
- ffmpeg_args += ['-DFFMPEG_VERSION="' + ffmpeg_version_string + '"']
- ffmpeg_server_deps += [libavutil, libavformat, libavcodec]
- if server_transcode
- ffmpeg_server_deps += [libswresample, libswscale]
- endif
- ffmpeg_client_deps += [libavutil, libavformat, libavcodec, libswresample, libswscale]
- soxr = compiler.find_library('soxr', required: false)
- if soxr.found()
- ffmpeg_client_deps += [soxr]
- ffmpeg_args += ['-DCAMU_HAVE_SOXR']
+# Fallback if requested or necessary.
+if ffmpeg_force_fallback or not libavutil.found()
+ if ffmpeg_version_option == 'system'
+ ffmpeg_version_option = '8' # Default to current latest.
endif
- codec_server_deps += [
- declare_dependency(sources: ffmpeg_server_src,
- dependencies: [ffmpeg_deps, ffmpeg_server_deps], compile_args: ffmpeg_args)
- ]
- codec_client_deps += [
- declare_dependency(sources: ffmpeg_client_src,
- dependencies: [ffmpeg_deps, ffmpeg_client_deps], compile_args: ffmpeg_args)
- ]
+ subproject('ffmpeg' + ffmpeg_version_option) # Override libav dependencies.
+endif
+
+libavutil = dependency('libavutil')
+libavutil_version = libavutil.version().split('.')[0].to_int()
+if libavutil_version <= 54
+ error('FFmpeg version 2.x and lower currently unsupported.')
+elif libavutil_version <= 56
+ ffmpeg_args += ['-DCAMU_OLD_FFMPEG']
+endif
+libavformat = dependency('libavformat')
+libavcodec = dependency('libavcodec')
+libavdevice = dependency('libavdevice')
+libswresample = dependency('libswresample')
+libswscale = dependency('libswscale')
+ffmpeg_server_deps += [libavutil, libavformat, libavcodec]
+if server_transcode
+ ffmpeg_server_deps += [libswresample, libswscale]
endif
+ffmpeg_client_deps += [libavutil, libavformat, libavcodec, libswresample, libswscale]
+codec_server_deps += [declare_dependency(sources: ffmpeg_server_src, dependencies: ffmpeg_server_deps, compile_args: ffmpeg_args)]
+codec_client_deps += [declare_dependency(sources: ffmpeg_client_src, dependencies: ffmpeg_client_deps, compile_args: ffmpeg_args)]
diff --git a/src/codec/ffmpeg/packet_ext.c b/src/codec/ffmpeg/packet_ext.c
index 7dcda88..6b66dd1 100644
--- a/src/codec/ffmpeg/packet_ext.c
+++ b/src/codec/ffmpeg/packet_ext.c
@@ -16,7 +16,7 @@ void nn_packet_write_av_codec_parameters(struct nn_packet *packet, AVCodecParame
NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->width);
NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->height);
NNWT_PACKET_WRITE_TYPE(packet, AVRational, codecpar->sample_aspect_ratio);
-#if !defined CAMU_OLD_FFMPEG && LIBAVCODEC_VERSION_INT >= 60
+#if !defined CAMU_OLD_FFMPEG && LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(60, 11, 100)
NNWT_PACKET_WRITE_TYPE(packet, AVRational, codecpar->framerate);
#endif
NNWT_PACKET_WRITE_TYPE(packet, enum AVFieldOrder, codecpar->field_order);
@@ -108,6 +108,10 @@ void nn_packet_write_av_packet(struct nn_packet *packet, AVPacket *pkt)
#endif
}
+// @TODO: coded_side_data
+// https://github.com/FFmpeg/FFmpeg/blob/f62d8789116fef8d8cd7f20062b16ccd93f7ce23/doc/APIchanges#L537
+// https://ffmpeg.org/doxygen/8.0/structAVCodecParameters.html#ad54da9241deabb3601e6e0e8fa832c19
+// #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(60, 30, 100)
void nn_packet_read_av_codec_parameters(struct nn_packet *packet, AVCodecParameters *codecpar)
{
NNWT_PACKET_READ_TYPE(packet, enum AVMediaType, codecpar->codec_type);
@@ -127,7 +131,7 @@ void nn_packet_read_av_codec_parameters(struct nn_packet *packet, AVCodecParamet
NNWT_PACKET_READ_TYPE(packet, s32, codecpar->width);
NNWT_PACKET_READ_TYPE(packet, s32, codecpar->height);
NNWT_PACKET_READ_TYPE(packet, AVRational, codecpar->sample_aspect_ratio);
-#if !defined CAMU_OLD_FFMPEG && LIBAVCODEC_VERSION_INT >= 60
+#if !defined CAMU_OLD_FFMPEG && LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(60, 11, 100)
NNWT_PACKET_READ_TYPE(packet, AVRational, codecpar->framerate);
#endif
NNWT_PACKET_READ_TYPE(packet, enum AVFieldOrder, codecpar->field_order);