39#pragma GCC diagnostic push
40#pragma GCC diagnostic ignored "-Wconversion"
41#pragma GCC diagnostic ignored "-Wsign-conversion"
42#include <libavcodec/avcodec.h>
43#include <libavformat/avformat.h>
44#include <libavfilter/avfilter.h>
45#pragma GCC diagnostic pop
56#include "ffmpegfshelp.h"
58#include <sys/sysinfo.h>
65#include <libbluray/bluray-version.h>
70#pragma GCC diagnostic ignored "-Wimplicit-int-conversion"
73#ifndef AV_PROFILE_UNKNOWN
77#define AV_PROFILE_UNKNOWN FF_PROFILE_UNKNOWN
83FFMPEGFS_PARAMS::FFMPEGFS_PARAMS()
87 , m_audio_codec(AV_CODEC_ID_NONE)
88 , m_video_codec(AV_CODEC_ID_NONE)
97 , m_audiobitrate(128*1024)
98 , m_audiosamplerate(44100)
103 , m_videobitrate(2*1024*1024)
107 , m_segment_duration(10 * AV_TIME_BASE)
108 , m_min_seek_time_diff(30 * AV_TIME_BASE)
111 , m_hwaccel_enc_device_type(AV_HWDEVICE_TYPE_NONE)
113 , m_hwaccel_dec_device_type(AV_HWDEVICE_TYPE_NONE)
114 , m_hwaccel_dec_blocked(nullptr)
123 , m_scriptfile(
"index.php")
124 , m_scriptsource(
"scripts/videotag.php")
127 , m_log_maxlevel(
"INFO")
132 , m_expiry_time((60*60*24 ) * 7)
133 , m_max_inactive_suspend(15)
134 , m_max_inactive_abort(30)
135 , m_prebuffer_time(0)
136 , m_prebuffer_size(100 * 1024)
137 , m_max_cache_size(0)
141 , m_cache_maintenance((60*60))
145 , m_decoding_errors(0)
146 , m_min_dvd_chapter_duration(1)
148 , m_include_extensions(new (std::nothrow)
MATCHVEC)
149 , m_hide_extensions(new (std::nothrow)
MATCHVEC)
159FFMPEGFS_PARAMS::~FFMPEGFS_PARAMS()
169 m_mountpath = other.m_mountpath;
171 m_audio_codec = other.m_audio_codec;
172 m_video_codec = other.m_video_codec;
174 m_autocopy = other.m_autocopy;
175 m_recodesame = other.m_recodesame;
176 m_profile = other.m_profile;
177 m_level = other.m_level;
179 m_audiobitrate = other.m_audiobitrate;
180 m_audiosamplerate = other.m_audiosamplerate;
181 m_audiochannels = other.m_audiochannels;
182 m_sample_fmt = other.m_sample_fmt;
184 m_videobitrate = other.m_videobitrate;
185 m_videowidth = other.m_videowidth;
186 m_videoheight = other.m_videoheight;
187 m_deinterlace = other.m_deinterlace;
188 m_segment_duration = other.m_segment_duration;
189 m_min_seek_time_diff = other.m_min_seek_time_diff;
191 m_hwaccel_enc_API = other.m_hwaccel_enc_API;
192 m_hwaccel_enc_device_type = other.m_hwaccel_enc_device_type;
193 m_hwaccel_enc_device = other.m_hwaccel_enc_device;
194 m_hwaccel_dec_API = other.m_hwaccel_dec_API;
195 m_hwaccel_dec_device_type = other.m_hwaccel_dec_device_type;
196 m_hwaccel_dec_device = other.m_hwaccel_dec_device;
197 m_hwaccel_dec_blocked = other.m_hwaccel_dec_blocked;
199 m_no_subtitles = other.m_no_subtitles;
201 m_noalbumarts = other.m_noalbumarts;
203 m_enablescript = other.m_enablescript;
204 m_scriptfile = other.m_scriptfile;
205 m_scriptsource = other.m_scriptsource;
207 m_debug = other.m_debug;
208 m_log_maxlevel = other.m_log_maxlevel;
209 m_log_stderr = other.m_log_stderr;
210 m_log_syslog = other.m_log_syslog;
211 m_logfile = other.m_logfile;
213 m_expiry_time = other.m_expiry_time;
214 m_max_inactive_suspend = other.m_max_inactive_suspend;
215 m_max_inactive_abort = other.m_max_inactive_abort;
216 m_prebuffer_time = other.m_prebuffer_time;
217 m_prebuffer_size = other.m_prebuffer_size;
218 m_max_cache_size = other.m_max_cache_size;
219 m_min_diskspace = other.m_min_diskspace;
220 m_cachepath = other.m_cachepath;
221 m_disable_cache = other.m_disable_cache;
222 m_cache_maintenance = other.m_cache_maintenance;
223 m_prune_cache = other.m_prune_cache;
224 m_clear_cache = other.m_clear_cache;
225 m_max_threads = other.m_max_threads;
226 m_decoding_errors = other.m_decoding_errors;
227 m_min_dvd_chapter_duration = other.m_min_dvd_chapter_duration;
228 m_oldnamescheme = other.m_oldnamescheme;
229 *m_include_extensions = *other.m_include_extensions;
230 *m_hide_extensions = *other.m_hide_extensions;
231 m_win_smb_fix = other.m_win_smb_fix;
244 if (virtualfile ==
nullptr || virtualfile->m_format_idx > 1)
262 KEY_AUDIO_SAMPLERATE,
264 KEY_AUDIO_SAMPLE_FMT,
266 KEY_SEGMENT_DURATION,
267 KEY_MIN_SEEK_TIME_DIFF,
271 KEY_MAX_INACTIVE_SUSPEND_TIME,
272 KEY_MAX_INACTIVE_ABORT_TIME,
276 KEY_MIN_DISKSPACE_SIZE,
278 KEY_CACHE_MAINTENANCE,
285 KEY_HWACCEL_ENCODER_API,
286 KEY_HWACCEL_ENCODER_DEVICE,
287 KEY_HWACCEL_DECODER_API,
288 KEY_HWACCEL_DECODER_DEVICE,
289 KEY_HWACCEL_DECODER_BLOCKED,
290 KEY_INCLUDE_EXTENSIONS,
297#define FFMPEGFS_OPT(templ, param, value) { templ, offsetof(FFMPEGFS_PARAMS, param), value }
304#pragma GCC diagnostic push
305#pragma GCC diagnostic ignored "-Wnarrowing"
306#pragma GCC diagnostic ignored "-Wsign-conversion"
310 FUSE_OPT_KEY(
"--desttype=%s", KEY_DESTTYPE),
311 FUSE_OPT_KEY(
"desttype=%s", KEY_DESTTYPE),
312 FUSE_OPT_KEY(
"--audiocodec=%s", KEY_AUDIOCODEC),
313 FUSE_OPT_KEY(
"audiocodec=%s", KEY_AUDIOCODEC),
314 FUSE_OPT_KEY(
"--videocodec=%s", KEY_VIDEOCODEC),
315 FUSE_OPT_KEY(
"videocodec=%s", KEY_VIDEOCODEC),
316 FUSE_OPT_KEY(
"--profile=%s", KEY_PROFILE),
317 FUSE_OPT_KEY(
"profile=%s", KEY_PROFILE),
318 FUSE_OPT_KEY(
"--autocopy=%s", KEY_AUTOCOPY),
319 FUSE_OPT_KEY(
"autocopy=%s", KEY_AUTOCOPY),
320 FUSE_OPT_KEY(
"--recodesame=%s", KEY_RECODESAME),
321 FUSE_OPT_KEY(
"recodesame=%s", KEY_RECODESAME),
322 FUSE_OPT_KEY(
"--level=%s", KEY_LEVEL),
323 FUSE_OPT_KEY(
"level=%s", KEY_LEVEL),
326 FUSE_OPT_KEY(
"--audiobitrate=%s", KEY_AUDIO_BITRATE),
327 FUSE_OPT_KEY(
"audiobitrate=%s", KEY_AUDIO_BITRATE),
328 FUSE_OPT_KEY(
"--audiosamplerate=%s", KEY_AUDIO_SAMPLERATE),
329 FUSE_OPT_KEY(
"audiosamplerate=%s", KEY_AUDIO_SAMPLERATE),
330 FUSE_OPT_KEY(
"--audiochannels=%s", KEY_AUDIO_CHANNELS),
331 FUSE_OPT_KEY(
"audiochannels=%s", KEY_AUDIO_CHANNELS),
332 FUSE_OPT_KEY(
"--audiosamplefmt=%s", KEY_AUDIO_SAMPLE_FMT),
333 FUSE_OPT_KEY(
"audiosamplefmt=%s", KEY_AUDIO_SAMPLE_FMT),
335 FUSE_OPT_KEY(
"--videobitrate=%s", KEY_VIDEO_BITRATE),
336 FUSE_OPT_KEY(
"videobitrate=%s", KEY_VIDEO_BITRATE),
344 FUSE_OPT_KEY(
"--segment_duration=%s", KEY_SEGMENT_DURATION),
345 FUSE_OPT_KEY(
"segment_duration=%s", KEY_SEGMENT_DURATION),
346 FUSE_OPT_KEY(
"--min_seek_time_diff=%s", KEY_MIN_SEEK_TIME_DIFF),
347 FUSE_OPT_KEY(
"min_seek_time_diff=%s", KEY_MIN_SEEK_TIME_DIFF),
349 FUSE_OPT_KEY(
"--hwaccel_enc=%s", KEY_HWACCEL_ENCODER_API),
350 FUSE_OPT_KEY(
"hwaccel_enc=%s", KEY_HWACCEL_ENCODER_API),
351 FUSE_OPT_KEY(
"--hwaccel_enc_device=%s", KEY_HWACCEL_ENCODER_DEVICE),
352 FUSE_OPT_KEY(
"hwaccel_enc_device=%s", KEY_HWACCEL_ENCODER_DEVICE),
353 FUSE_OPT_KEY(
"--hwaccel_dec=%s", KEY_HWACCEL_DECODER_API),
354 FUSE_OPT_KEY(
"hwaccel_dec=%s", KEY_HWACCEL_DECODER_API),
355 FUSE_OPT_KEY(
"--hwaccel_dec_device=%s", KEY_HWACCEL_DECODER_DEVICE),
356 FUSE_OPT_KEY(
"hwaccel_dec_device=%s", KEY_HWACCEL_DECODER_DEVICE),
357 FUSE_OPT_KEY(
"--hwaccel_dec_blocked=%s", KEY_HWACCEL_DECODER_BLOCKED),
358 FUSE_OPT_KEY(
"hwaccel_dec_blocked=%s", KEY_HWACCEL_DECODER_BLOCKED),
368 FUSE_OPT_KEY(
"--scriptfile=%s", KEY_SCRIPTFILE),
369 FUSE_OPT_KEY(
"scriptfile=%s", KEY_SCRIPTFILE),
370 FUSE_OPT_KEY(
"--scriptsource=%s", KEY_SCRIPTSOURCE),
371 FUSE_OPT_KEY(
"scriptsource=%s", KEY_SCRIPTSOURCE),
374 FUSE_OPT_KEY(
"--expiry_time=%s", KEY_EXPIRY_TIME),
375 FUSE_OPT_KEY(
"expiry_time=%s", KEY_EXPIRY_TIME),
376 FUSE_OPT_KEY(
"--max_inactive_suspend=%s", KEY_MAX_INACTIVE_SUSPEND_TIME),
377 FUSE_OPT_KEY(
"max_inactive_suspend=%s", KEY_MAX_INACTIVE_SUSPEND_TIME),
378 FUSE_OPT_KEY(
"--max_inactive_abort=%s", KEY_MAX_INACTIVE_ABORT_TIME),
379 FUSE_OPT_KEY(
"max_inactive_abort=%s", KEY_MAX_INACTIVE_ABORT_TIME),
380 FUSE_OPT_KEY(
"--prebuffer_time=%s", KEY_PREBUFFER_TIME),
381 FUSE_OPT_KEY(
"prebuffer_time=%s", KEY_PREBUFFER_TIME),
382 FUSE_OPT_KEY(
"--prebuffer_size=%s", KEY_PREBUFFER_SIZE),
383 FUSE_OPT_KEY(
"prebuffer_size=%s", KEY_PREBUFFER_SIZE),
384 FUSE_OPT_KEY(
"--max_cache_size=%s", KEY_MAX_CACHE_SIZE),
385 FUSE_OPT_KEY(
"max_cache_size=%s", KEY_MAX_CACHE_SIZE),
386 FUSE_OPT_KEY(
"--min_diskspace=%s", KEY_MIN_DISKSPACE_SIZE),
387 FUSE_OPT_KEY(
"min_diskspace=%s", KEY_MIN_DISKSPACE_SIZE),
388 FUSE_OPT_KEY(
"--cachepath=%s", KEY_CACHEPATH),
389 FUSE_OPT_KEY(
"cachepath=%s", KEY_CACHEPATH),
392 FUSE_OPT_KEY(
"--cache_maintenance=%s", KEY_CACHE_MAINTENANCE),
393 FUSE_OPT_KEY(
"cache_maintenance=%s", KEY_CACHE_MAINTENANCE),
401 FFMPEGFS_OPT(
"--decoding_errors=%u", m_decoding_errors, 0),
402 FFMPEGFS_OPT(
"decoding_errors=%u", m_decoding_errors, 0),
403 FFMPEGFS_OPT(
"--min_dvd_chapter_duration=%u", m_min_dvd_chapter_duration, 0),
404 FFMPEGFS_OPT(
"min_dvd_chapter_duration=%u", m_min_dvd_chapter_duration, 0),
407 FUSE_OPT_KEY(
"--include_extensions=%s", KEY_INCLUDE_EXTENSIONS),
408 FUSE_OPT_KEY(
"include_extensions=%s", KEY_INCLUDE_EXTENSIONS),
409 FUSE_OPT_KEY(
"--hide_extensions=%u", KEY_HIDE_EXTENSIONS),
410 FUSE_OPT_KEY(
"hide_extensions=%u", KEY_HIDE_EXTENSIONS),
417 FUSE_OPT_KEY(
"--log_maxlevel=%s", KEY_LOG_MAXLEVEL),
418 FUSE_OPT_KEY(
"log_maxlevel=%s", KEY_LOG_MAXLEVEL),
423 FUSE_OPT_KEY(
"--logfile=%s", KEY_LOGFILE),
424 FUSE_OPT_KEY(
"logfile=%s", KEY_LOGFILE),
426 FUSE_OPT_KEY(
"-h", KEY_HELP),
427 FUSE_OPT_KEY(
"--help", KEY_HELP),
428 FUSE_OPT_KEY(
"-V", KEY_VERSION),
429 FUSE_OPT_KEY(
"--version", KEY_VERSION),
430 FUSE_OPT_KEY(
"-c", KEY_FFMPEG_CAPS),
431 FUSE_OPT_KEY(
"--capabilities", KEY_FFMPEG_CAPS),
432 FUSE_OPT_KEY(
"-d", KEY_KEEP_OPT),
433 FUSE_OPT_KEY(
"debug", KEY_KEEP_OPT),
436#pragma GCC diagnostic pop
439typedef std::map<const std::string, const PROFILE, comp>
PROFILE_MAP;
440typedef std::map<const std::string, const PRORESLEVEL, comp>
LEVEL_MAP;
451typedef std::map<const std::string, const AVCodecID, comp>
CODEC_MAP;
462 {
"AAC", AV_CODEC_ID_AAC },
463 {
"AC3", AV_CODEC_ID_AC3 },
464 {
"MP3", AV_CODEC_ID_MP3 },
465 {
"OPUS", AV_CODEC_ID_OPUS },
467 {
"VORBIS", AV_CODEC_ID_VORBIS },
468 {
"DTS", AV_CODEC_ID_DTS },
469 {
"PCM16", AV_CODEC_ID_PCM_S16LE },
470 {
"PCM24", AV_CODEC_ID_PCM_S24LE },
471 {
"PCM32", AV_CODEC_ID_PCM_S32LE },
479 {
"MPEG1", AV_CODEC_ID_MPEG1VIDEO },
480 {
"MPEG2", AV_CODEC_ID_MPEG2VIDEO },
481 {
"H264", AV_CODEC_ID_H264 },
482 {
"H265", AV_CODEC_ID_H265 },
483 {
"VP8", AV_CODEC_ID_VP8 },
484 {
"VP9", AV_CODEC_ID_VP9 },
557 {
"NONE", {
true, HWACCELAPI::NONE, AV_HWDEVICE_TYPE_NONE } },
570 {
"CUDA", {
false, HWACCELAPI::CUDA, AV_HWDEVICE_TYPE_NONE } },
571 {
"V4L2M2M", {
false, HWACCELAPI::V4L2M2M, AV_HWDEVICE_TYPE_NONE } },
572 {
"VDPAU", {
false, HWACCELAPI::VDPAU, AV_HWDEVICE_TYPE_NONE } },
573 {
"QSV", {
false, HWACCELAPI::QSV, AV_HWDEVICE_TYPE_NONE } },
574 {
"OPENCL", {
false, HWACCELAPI::OPENCL, AV_HWDEVICE_TYPE_NONE } },
575 #if HAVE_VULKAN_HWACCEL
576 {
"VULKAN", {
false, HWACCELAPI::VULKAN, AV_HWDEVICE_TYPE_NONE } },
580 {
"VIDEOTOOLBOX", {
false, HWACCELAPI::VIDEOTOOLBOX, AV_HWDEVICE_TYPE_NONE } },
584 {
"MEDIACODEC", {
false, HWACCELAPI::MEDIACODEC, AV_HWDEVICE_TYPE_NONE } },
590 {
"DRM", {
false, HWACCELAPI::DRM, AV_HWDEVICE_TYPE_NONE } },
593 {
"DXVA2", {
false, HWACCELAPI::DXVA2, AV_HWDEVICE_TYPE_NONE } },
594 {
"D3D11VA", {
false, HWACCELAPI::D3D11VA, AV_HWDEVICE_TYPE_NONE } },
604 {
"H263", AV_CODEC_ID_H263 },
605 {
"H264", AV_CODEC_ID_H264 },
606 {
"HEVC", AV_CODEC_ID_HEVC },
607 {
"MPEG2", AV_CODEC_ID_MPEG2VIDEO },
608 {
"MPEG4", AV_CODEC_ID_MPEG4 },
609 {
"VC1", AV_CODEC_ID_VC1 },
610 {
"VP8", AV_CODEC_ID_VP8 },
611 {
"VP9", AV_CODEC_ID_VP9 },
612 {
"WMV3", AV_CODEC_ID_WMV3 },
633static int get_samplerate(
const std::string & arg,
int * samplerate);
635static int get_time(
const std::string & arg, time_t *time);
636static int get_size(
const std::string & arg,
size_t *size);
638static int get_audiocodec(
const std::string & arg, AVCodecID *audio_codec);
639static int get_videocodec(
const std::string & arg, AVCodecID *video_codec);
646static int get_hwaccel(
const std::string & arg,
HWACCELAPI *hwaccel_API, AVHWDeviceType *hwaccel_device_type);
647static int get_codec(
const std::string & codec, AVCodecID *codec_id);
649static int get_value(
const std::string & arg,
int *value);
650static int get_value(
const std::string & arg, std::string *value);
653static int get_value(
const std::string & arg,
double *value);
655static int ffmpegfs_opt_proc(__attribute__((unused))
void* data,
const char* arg,
int key,
struct fuse_args *outargs);
660static void ffmpeg_log(
void *ptr,
int level,
const char *fmt, va_list vl);
661static bool init_logging(
const std::string &logfile,
const std::string & max_level,
bool to_stderr,
bool to_syslog);
671 help.assign(
reinterpret_cast<const char*
>(ffmpegfshelp), ffmpegfshelp_len);
672 pos = help.find(
"OPTIONS\n");
674 std::cout << help.substr(pos +
sizeof(
"OPTIONS\n"));
686 for (
typename T::const_iterator it = map.cbegin(); it != map.cend();)
688 buffer += it->first.c_str();
690 if (++it != map.cend())
698 std::fprintf(stderr,
"%s: %s\n", info, buffer.c_str());
702 std::fprintf(stderr,
"%s\n", buffer.c_str());
720 size_t pos = arg.find(
'=');
722 if (pos != std::string::npos)
724 std::string param(arg.substr(0, pos));
725 std::string data(arg.substr(pos + 1));
729 reti =
reg_compare(data,
"^([1-9][0-9]*|0)?(bps)?$", std::regex::icase);
737 *bitrate =
static_cast<BITRATE>(std::stol(data));
742 reti =
reg_compare(data,
"^[1-9][0-9]*(\\.[0-9]+)?K(bps)?$", std::regex::icase);
750 *bitrate =
static_cast<BITRATE>(std::stof(data) * 1000);
755 reti =
reg_compare(data,
"^[1-9][0-9]*(\\.[0-9]+)?M(bps)?$", std::regex::icase);
763 *bitrate =
static_cast<BITRATE>(std::stof(data) * 1000000);
767 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid bit rate '%s'\n", param.c_str(), data.c_str());
770 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
788 size_t pos = arg.find(
'=');
790 if (pos != std::string::npos)
792 std::string param(arg.substr(0, pos));
793 std::string data(arg.substr(pos + 1));
797 reti =
reg_compare(data,
"^([1-9][0-9]*|0)(Hz)?$", std::regex::icase);
805 *samplerate = std::stoi(data);
810 reti =
reg_compare(data,
"^[1-9][0-9]*(\\.[0-9]+)?K(Hz)?$", std::regex::icase);
818 *samplerate =
static_cast<int>(std::stof(data) * 1000);
822 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid sample rate '%s'\n", param.c_str(), data.c_str());
826 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
840 size_t pos = arg.find(
'=');
844 if (pos != std::string::npos)
846 std::string param(arg.substr(0, pos));
847 std::string data(arg.substr(pos + 1));
853 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid sample format option: %s\n", param.c_str(), data.c_str());
861 *sample_fmt = it->second;
866 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
896static int get_time(
const std::string & arg, time_t *time)
898 size_t pos = arg.find(
'=');
900 if (pos != std::string::npos)
902 std::string param(arg.substr(0, pos));
903 std::string data(arg.substr(pos + 1));
907 reti =
reg_compare(data,
"^([1-9][0-9]*|0)?s?$", std::regex::icase);
915 *time =
static_cast<time_t
>(std::stol(data));
920 reti =
reg_compare(data,
"^[1-9][0-9]*(\\.[0-9]+)?m$", std::regex::icase);
928 *time =
static_cast<time_t
>(std::stof(data) * 60);
933 reti =
reg_compare(data,
"^[1-9][0-9]*(\\.[0-9]+)?h$", std::regex::icase);
941 *time =
static_cast<time_t
>(std::stof(data) * 60 * 60);
946 reti =
reg_compare(data,
"^[1-9][0-9]*(\\.[0-9]+)?d$", std::regex::icase);
954 *time =
static_cast<time_t
>(std::stof(data) * 60 * 60 * 24);
959 reti =
reg_compare(data,
"^[1-9][0-9]*(\\.[0-9]+)?w$", std::regex::icase);
967 *time =
static_cast<time_t
>(std::stof(data) * 60 * 60 * 24 * 7);
971 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid time format '%s'\n", param.c_str(), data.c_str());
975 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid time format\n", arg.c_str());
995static int get_size(
const std::string & arg,
size_t *size)
997 size_t pos = arg.find(
'=');
999 if (pos != std::string::npos)
1001 std::string param(arg.substr(0, pos));
1002 std::string data(arg.substr(pos + 1));
1006 reti =
reg_compare(data,
"^([1-9][0-9]*|0)?B?$", std::regex::icase);
1014 *size =
static_cast<size_t>(std::stol(data));
1019 reti =
reg_compare(data,
"^[1-9][0-9]*(\\.[0-9]+)?KB?$", std::regex::icase);
1027 *size =
static_cast<size_t>(std::stof(data) * 1024);
1032 reti =
reg_compare(data,
"^[1-9][0-9]*(\\.[0-9]+)?MB?$", std::regex::icase);
1040 *size =
static_cast<size_t>(std::stof(data) * 1024 * 1024);
1045 reti =
reg_compare(data,
"^[1-9][0-9]*(\\.[0-9]+)?GB?$", std::regex::icase);
1053 *size =
static_cast<size_t>(std::stof(data) * 1024 * 1024 * 1024);
1058 reti =
reg_compare(data,
"^[1-9][0-9]*(\\.[0-9]+)?TB?$", std::regex::icase);
1066 *size =
static_cast<size_t>(std::stof(data) * 1024 * 1024 * 1024 * 1024);
1070 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid size '%s'\n", param.c_str(), data.c_str());
1074 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid size\n", arg.c_str());
1089 size_t pos = arg.find(
'=');
1091 if (pos != std::string::npos)
1093 std::string param(arg.substr(0, pos));
1094 std::vector<std::string> results =
split(arg.substr(pos + 1),
"\\+");
1096 if (results.size() > 0 && results.size() < 3)
1099 if (!format[0].init(results[0]))
1101 std::fprintf(stderr,
"INVALID PARAMETER (%s): No codecs available for desttype: %s\n", param.c_str(), results[0].c_str());
1105 if (results.size() == 2)
1107 if (format[0].video_codec() == AV_CODEC_ID_NONE)
1109 std::fprintf(stderr,
"INVALID PARAMETER (%s): First format %s does not support video\n", param.c_str(), results[0].c_str());
1113 if (!format[1].init(results[1]))
1115 std::fprintf(stderr,
"INVALID PARAMETER (%s): No codecs available for desttype: %s\n", param.c_str(), results[1].c_str());
1119 if (format[1].video_codec() != AV_CODEC_ID_NONE)
1121 std::fprintf(stderr,
"INVALID PARAMETER (%s): Second format %s should be audio only\n", param.c_str(), results[1].c_str());
1130 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1143 *audio_codec = AV_CODEC_ID_NONE;
1145 size_t pos = arg.find(
'=');
1147 if (pos != std::string::npos)
1149 std::string param(arg.substr(0, pos));
1150 std::string data(arg.substr(pos + 1));
1156 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid videocodec option: %s\n", param.c_str(), data.c_str());
1163 *audio_codec = it->second;
1168 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1181 *video_codec = AV_CODEC_ID_NONE;
1183 size_t pos = arg.find(
'=');
1185 if (pos != std::string::npos)
1187 std::string param(arg.substr(0, pos));
1188 std::string data(arg.substr(pos + 1));
1194 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid videocodec option: %s\n", param.c_str(), data.c_str());
1201 *video_codec = it->second;
1206 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1219 size_t pos = arg.find(
'=');
1221 if (pos != std::string::npos)
1223 std::string param(arg.substr(0, pos));
1224 std::string data(arg.substr(pos + 1));
1226 AUTOCOPY_MAP::const_iterator it =
autocopy_map.find(data);
1230 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid autocopy option: %s\n", param.c_str(), data.c_str());
1237 *autocopy = it->second;
1242 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1285 size_t pos = arg.find(
'=');
1287 if (pos != std::string::npos)
1289 std::string param(arg.substr(0, pos));
1290 std::string data(arg.substr(pos + 1));
1292 RECODESAME_MAP::const_iterator it =
recode_map.find(data);
1296 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid recode option: %s\n", param.c_str(), data.c_str());
1303 *recode = it->second;
1308 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1331 size_t pos = arg.find(
'=');
1333 if (pos != std::string::npos)
1335 std::string param(arg.substr(0, pos));
1336 std::string data(arg.substr(pos + 1));
1338 PROFILE_MAP::const_iterator it =
profile_map.find(data);
1342 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid profile: %s\n", param.c_str(), data.c_str());
1349 *profile = it->second;
1354 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1378 size_t pos = arg.find(
'=');
1380 if (pos != std::string::npos)
1382 std::string param(arg.substr(0, pos));
1383 std::string data(arg.substr(pos + 1));
1389 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid level: %s\n", param.c_str(), data.c_str());
1396 *level = it->second;
1401 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1433 std::fprintf(stderr,
"INVALID PARAMETER: segment_duration %.1f is out of range. For obvious reasons this must be greater than zero.\n", duration);
1437 *value =
static_cast<int>(duration * AV_TIME_BASE);
1458 std::fprintf(stderr,
"INVALID PARAMETER: seek time %.1f is out of range. For obvious reasons this must be greater than or equal zero.\n", duration);
1462 *value =
static_cast<int>(duration * AV_TIME_BASE);
1478 size_t pos = arg.find(
'=');
1480 if (pos != std::string::npos)
1482 std::string param(arg.substr(0, pos));
1483 std::string data(arg.substr(pos + 1));
1485 HWACCEL_MAP::const_iterator it =
hwaccel_map.find(data);
1489 std::fprintf(stderr,
"INVALID PARAMETER (%s): Invalid hardware acceleration API: %s\n", param.c_str(), data.c_str());
1496 const HWACCEL & hwaccel = it->second;
1500 std::fprintf(stderr,
"INVALID PARAMETER (%s): Unsupported hardware acceleration API: %s\n", param.c_str(), data.c_str());
1509 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1520static int get_codec(
const std::string & codec, AVCodecID *codec_id)
1526 std::fprintf(stderr,
"INVALID PARAMETER: Unknown codec '%s'.\n", codec.c_str());
1530 *codec_id = AV_CODEC_ID_NONE;
1534 *codec_id = it->second;
1547 size_t pos = arg.find(
'=');
1549 if (pos != std::string::npos)
1551 std::string param(arg.substr(0, pos));
1552 std::stringstream data(arg.substr(pos + 1));
1555 if (*hwaccel_dec_blocked ==
nullptr)
1560 if (!std::getline(data, codec,
':'))
1562 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", param.c_str());
1570 std::fprintf(stderr,
"INVALID PARAMETER (%s): Unknown codec '%s'\n", param.c_str(), codec.c_str());
1574 int nProfilesFound = 0;
1575 for (std::string profile; std::getline(data, profile,
':');)
1579 (*hwaccel_dec_blocked)->insert(std::pair<AVCodecID, int>(codec_id, std::stoi(profile)));
1582 if (!nProfilesFound)
1585 (*hwaccel_dec_blocked)->insert(std::pair<AVCodecID, int>(codec_id,
AV_PROFILE_UNKNOWN));
1591 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1605 if (it->first == codec_id && (it->second == profile || it->second ==
AV_PROFILE_UNKNOWN))
1616 HWACCEL_MAP::const_iterator it =
hwaccel_map.cbegin();
1619 if (it->second.m_hwaccel_API == hwaccel_API)
1638 size_t pos = arg.find(
'=');
1640 if (pos != std::string::npos)
1642 *value = std::stoi(arg.substr(pos + 1));
1647 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1659static int get_value(
const std::string & arg, std::string *value)
1661 size_t pos = arg.find(
'=');
1663 if (pos != std::string::npos)
1665 *value = arg.substr(pos + 1);
1670 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1684 size_t pos = arg.find(
'=');
1686 if (pos != std::string::npos)
1688 std::vector<std::string> v =
split(arg.substr(pos + 1),
",");
1690 for (
const std::string & str : v)
1692 int res = fnmatch(str.c_str(),
"", 0);
1694 if (res != 0 && res != FNM_NOMATCH)
1696 std::fprintf(stderr,
"INVALID PARAMETER (%s): Error in wildcard pattern\n", str.c_str());
1702 value->insert(value->end(), v.begin(), v.end());
1707 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1720static int get_value(
const std::string & arg, std::optional<std::string> *value)
1722 size_t pos = arg.find(
'=');
1724 if (pos != std::string::npos)
1726 *value = arg.substr(pos + 1);
1731 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1746 size_t pos = arg.find(
'=');
1748 if (pos != std::string::npos)
1750 *value = std::stof(arg.substr(pos + 1));
1755 std::fprintf(stderr,
"INVALID PARAMETER (%s): Missing argument\n", arg.c_str());
1768static int ffmpegfs_opt_proc(__attribute__((unused))
void* data,
const char* arg,
int key,
struct fuse_args *outargs)
1772 case FUSE_OPT_KEY_NONOPT:
1816 fuse_opt_add_arg(outargs,
"-ho");
1817 fuse_main(outargs->argc, outargs->argv, &
ffmpegfs_ops,
nullptr);
1822 std::printf(
"-------------------------------------------------------------------------------------------\n");
1825#ifndef __clang_version__
1826 std::printf(
"%-20s: %s (%s)\n",
"Built with",
"gcc " __VERSION__, HOST_OS);
1828 std::printf(
"%-20s: %s (%s)\n",
"Built with",
"clang " __clang_version__, HOST_OS);
1831 std::printf(
"%-20s: %s\n\n",
"configuration", CONFIGURE_ARGS);
1838 std::printf(
"%-20s: %s\n",
"Video CD Library",
"enabled");
1841 std::printf(
"%-20s: %s\n",
"DVD Library",
"enabled");
1844 std::printf(
"%-20s: %s\n",
"Blu-ray Library", BLURAY_VERSION_STRING);
1847 fuse_opt_add_arg(outargs,
"--version");
1848 fuse_main(outargs->argc, outargs->argv, &
ffmpegfs_ops,
nullptr);
1852 case KEY_FFMPEG_CAPS:
1854 std::printf(
"-------------------------------------------------------------------------------------------\n\n");
1859 std::printf(
"\nFFMpeg Capabilities\n\n");
1869 case KEY_AUDIOCODEC:
1873 case KEY_VIDEOCODEC:
1881 case KEY_RECODESAME:
1893 case KEY_AUDIO_BITRATE:
1897 case KEY_AUDIO_SAMPLERATE:
1901 case KEY_AUDIO_CHANNELS:
1905 case KEY_AUDIO_SAMPLE_FMT:
1909 case KEY_SCRIPTFILE:
1913 case KEY_SCRIPTSOURCE:
1917 case KEY_VIDEO_BITRATE:
1921 case KEY_SEGMENT_DURATION:
1925 case KEY_MIN_SEEK_TIME_DIFF:
1929 case KEY_HWACCEL_ENCODER_API:
1933 case KEY_HWACCEL_ENCODER_DEVICE:
1937 case KEY_HWACCEL_DECODER_API:
1941 case KEY_HWACCEL_DECODER_DEVICE:
1945 case KEY_HWACCEL_DECODER_BLOCKED:
1949 case KEY_EXPIRY_TIME:
1953 case KEY_MAX_INACTIVE_SUSPEND_TIME:
1957 case KEY_MAX_INACTIVE_ABORT_TIME:
1961 case KEY_PREBUFFER_TIME:
1965 case KEY_PREBUFFER_SIZE:
1969 case KEY_MAX_CACHE_SIZE:
1973 case KEY_MIN_DISKSPACE_SIZE:
1981 case KEY_CACHE_MAINTENANCE:
1985 case KEY_LOG_MAXLEVEL:
1991 std::string logfile;
2004 case KEY_INCLUDE_EXTENSIONS:
2008 case KEY_HIDE_EXTENSIONS:
2023 if (
ffmpeg_format[FORMAT::VIDEO].video_codec() == AV_CODEC_ID_PRORES)
2041 for (AVHWDeviceType device_type = AV_HWDEVICE_TYPE_NONE; (device_type = av_hwdevice_iterate_types(device_type)) != AV_HWDEVICE_TYPE_NONE;)
2043 HWACCEL_MAP::iterator it =
hwaccel_map.find(av_hwdevice_get_type_name(device_type));
2050 it->second.m_hwaccel_device_type = device_type;
2065 return (value !=
nullptr ? value :
"NONE");
2073 std::string cachepath;
2077 Logging::trace(
nullptr,
"********* " PACKAGE_NAME
" Options *********");
2081 if (
ffmpeg_format[FORMAT::AUDIO].filetype() != FILETYPE::UNKNOWN)
2084 if (
ffmpeg_format[FORMAT::AUDIO].audio_codec() != AV_CODEC_ID_NONE)
2089 if (
ffmpeg_format[FORMAT::VIDEO].audio_codec() != AV_CODEC_ID_NONE)
2093 if (
ffmpeg_format[FORMAT::VIDEO].video_codec() != AV_CODEC_ID_NONE)
2101 if (
ffmpeg_format[FORMAT::VIDEO].audio_codec() != AV_CODEC_ID_NONE)
2105 if (
ffmpeg_format[FORMAT::VIDEO].video_codec() != AV_CODEC_ID_NONE)
2172 Logging::trace(
nullptr,
"--------- Experimental Options ---------");
2183static void ffmpeg_log(
void *ptr,
int level,
const char *fmt, va_list vl)
2191 if (level <= AV_LOG_ERROR)
2196 else if (level <= AV_LOG_WARNING)
2208 else if (level < AV_LOG_DEBUG)
2221 ffmpegfs_level = DEBUG;
2231 static int print_prefix = 1;
2233#if (LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 23, 0))
2236 std::string category;
2240 AVClass* avc = *(AVClass **)ptr;
2242 switch (avc->category)
2244 case AV_CLASS_CATEGORY_NA:
2248 case AV_CLASS_CATEGORY_INPUT:
2250 category =
"INPUT ";
2253 case AV_CLASS_CATEGORY_OUTPUT:
2255 category =
"OUTPUT ";
2258 case AV_CLASS_CATEGORY_MUXER:
2260 category =
"MUXER ";
2263 case AV_CLASS_CATEGORY_DEMUXER:
2265 category =
"DEMUXER ";
2268 case AV_CLASS_CATEGORY_ENCODER:
2270 category =
"ENCODER ";
2273 case AV_CLASS_CATEGORY_DECODER:
2275 category =
"DECODER ";
2278 case AV_CLASS_CATEGORY_FILTER:
2280 category =
"FILTER ";
2283 case AV_CLASS_CATEGORY_BITSTREAM_FILTER:
2285 category =
"BITFILT ";
2288 case AV_CLASS_CATEGORY_SWSCALER:
2290 category =
"SWSCALE ";
2293 case AV_CLASS_CATEGORY_SWRESAMPLER:
2295 category =
"SWRESAM ";
2300 strsprintf(&category,
"CAT %3i ",
static_cast<int>(avc->category));
2307 av_log_default_callback(ptr, level, fmt, vl);
2308 line_size = av_log_format_line2(ptr, level, fmt, vl2,
nullptr, 0, &print_prefix);
2314 line =
static_cast<char *
>(av_malloc(
static_cast<size_t>(line_size)));
2315 if (line ==
nullptr)
2319 av_log_format_line2(ptr, level, fmt, vl2, line, line_size, &print_prefix);
2325 av_log_default_callback(ptr, level, fmt, vl);
2326 av_log_format_line(ptr, level, fmt, vl2, line,
sizeof(line), &print_prefix);
2332#if (LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 23, 0))
2345static bool init_logging(
const std::string &logfile,
const std::string & max_level,
bool to_stderr,
bool to_syslog)
2347 static const std::map<const std::string, const Logging::LOGLEVEL, comp> log_level_map =
2356 std::map<const std::string, const Logging::LOGLEVEL, comp>::const_iterator it = log_level_map.find(max_level);
2358 if (it == log_level_map.cend())
2360 std::fprintf(stderr,
"Invalid logging level string: %s\n", max_level.c_str());
2378 struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
2381 if (getppid() == getpgid(0))
2384 std::printf(
"Copyright (C) 2017-2026 Norbert Schlia (nschlia@oblivion-software.de)\n"
2385 "David Collett (2006-2008) and K. Henriksson (2008-2012)\n\n");
2404 std::fprintf(stderr,
"\nError parsing command line options.\n\n");
2421 av_log_set_level(AV_LOG_INFO);
2425 av_log_set_level(AV_LOG_QUIET);
2430 std::fprintf(stderr,
"ERROR: Failed to initialise logging module.\n");
2431 std::fprintf(stderr,
"Maybe log file couldn't be opened for writing?\n\n");
2439 std::fprintf(stderr,
"INVALID PARAMETER: Invalid additional parameters for --prune_cache:\n");
2440 for (
int n = 1; n < args.argc; n++)
2442 std::fprintf(stderr,
"Invalid: '%s'\n", args.argv[n]);
2458 std::fprintf(stderr,
"INVALID PARAMETER: No valid basepath specified.\n\n");
2464 std::fprintf(stderr,
"INVALID PARAMETER: basepath must be an absolute path.\n\n");
2469 if (stat(
params.
m_basepath.c_str(), &stbuf) != 0 || !S_ISDIR(stbuf.st_mode))
2471 std::fprintf(stderr,
"INVALID PARAMETER: basepath is not a valid directory: %s\n\n",
params.
m_basepath.c_str());
2477 std::fprintf(stderr,
"INVALID PARAMETER: No valid mountpath specified.\n\n");
2483 std::fprintf(stderr,
"INVALID PARAMETER: mountpath must be an absolute path.\n\n");
2489 std::fprintf(stderr,
"INVALID PARAMETER: mountpath is not a valid directory: %s\n\n",
params.
m_mountpath.c_str());
2496 if (fmt.filetype() != FILETYPE::UNKNOWN && !fmt.is_sample_fmt_supported())
2499 std::fprintf(stderr,
"Supported formats: %s\n\n", fmt.sample_fmt_list().c_str());
2507 if (fmt.filetype() != FILETYPE::UNKNOWN)
2512 std::fprintf(stderr,
"Supported formats: %s\n\n", fmt.audio_codec_list().c_str());
2519 std::fprintf(stderr,
"Supported formats: %s\n\n", fmt.video_codec_list().c_str());
2547 ret = fuse_main(args.argc, args.argv, &
ffmpegfs_ops,
nullptr);
2549 fuse_opt_free_args(&args);
@ NONE
No result code available.
static void log_with_level(LOGLEVEL loglevel, const char *filename, const std::string &message)
Write log entry.
static bool init_logging(const std::string &logfile, LOGLEVEL max_level, bool to_stderr, bool to_syslog)
Initialise the logging facility.
static void trace(const T filename, const std::string &format_string, Args &&...args)
Write trace level log entry.
static bool show(LOGLEVEL loglevel)
Check if log entry should be displayed at the current log level.
LOGLEVEL
Logging level types enum.
const char * get_codec_name(AVCodecID codec_id, bool long_name)
Safe way to get the codec name. Function never fails, will return "unknown" on error.
std::string format_duration(int64_t value, uint32_t fracs)
Format a time in format HH:MM:SS.fract.
int is_mount(const std::string &path)
Check if path is a mount.
std::string ffmpeg_libinfo()
Get info about the FFmpeg libraries used.
std::string sanitise_filepath(std::string *filepath)
Sanitise file name. Calls realpath() to remove duplicate // or resolve ../.. etc. Changes the path in...
int reg_compare(const std::string &value, const std::string &pattern, std::regex::flag_type flag)
Compare value with pattern.
int show_caps(int device_only)
Lists all supported codecs and devices.
std::string format_time(time_t value)
Format a time in format "w d m s".
std::string format_samplerate(int value)
Format a samplerate.
std::string format_bitrate(BITRATE value)
Format a bit rate.
bool detect_docker()
Detect if we are running under Docker.
const std::string & append_sep(std::string *path)
Add / to the path if required.
const std::string & expand_path(std::string *tgt, const std::string &src)
Expand path, e.g., expand ~/ to home directory.
std::string format_size(uint64_t value)
Format size.
std::vector< std::string > split(const std::string &input, const std::string ®ex)
Split string into an array delimited by a regular expression.
std::string format_number(int64_t value)
Format numeric value.
@ PRORES_STANDARD
Prores Level: STANDARD.
@ PRORES_PROXY
Prores Level: PROXY.
@ PRORES_HQ
Prores Level: HQ.
@ PRORES_LT
Prores Level: LT.
std::array< FFmpegfs_Format, 2 > FFMPEGFS_FORMAT_ARR
Array of FFmpegfs formats. There are two, for audio and video.
@ YES
Always recode to same format.
@ NO
Never recode to same format.
#define BITRATE
For FFmpeg bit rate is an int.
std::string implode(const T &s)
Combine array of strings into comma separated list.
@ MP4_CHROME
Google Chrome.
@ MP4_IE
MS Internet Explorer.
@ ALAC_ITUNES
Optimised for iTunes.
@ DEFAULT
No specific profile/Don't care.
@ MP4_SAFARI
Apple Safari.
#define FFMPEFS_VERSION
FFmpegfs version number.
std::map< conststd::string, constT, comp >::const_iterator search_by_value(const std::map< const std::string, const T, comp > &mapOfWords, T value)
Iterate through all elements in map and search for the passed element.
@ STRICT
Copy stream if codec matches desired target, transcode otherwise.
@ MATCH
Copy stream if target supports codec.
@ MATCHLIMIT
Same as MATCH, only copy if target not larger transcode otherwise.
@ OFF
Never copy streams, transcode always.
@ STRICTLIMIT
Same as STRICT, only copy if target not larger, transcode otherwise.
const std::string & strsprintf(std::string *str, const std::string &format, Args ... args)
Format a std::string sprintf-like.
std::vector< std::string > MATCHVEC
Array of strings, sorted/search case insensitive.
@ FMT_F16
16 bit floating point
@ FMT_F32
32 bit floating point
@ FMT_F24
24 bit floating point
@ FMT_DONTCARE
Don't care, leave to FFmpegfs to choose.
@ FMT_F64
64 bit floating point
static const AUDIOCODEC_MAP audiocodec_map
List of audio codecs.
static int get_value(const std::string &arg, int *value)
Get value from command line string. Finds whatever is after the "=" sign.
int main(int argc, char *argv[])
Main program entry point.
static const VIDEOCODEC_MAP videocodec_map
List of video codecs.
static int get_size(const std::string &arg, size_t *size)
Read size: .
std::map< const std::string, HWACCEL, comp > HWACCEL_MAP
Map command line option to HWACCEL struct.
std::string get_recodesame_text(RECODESAME recode)
Convert RECODESAME enum to human readable text.
#define AV_PROFILE_UNKNOWN
Compatibility alias for older FFmpeg versions that only define FF_PROFILE_UNKNOWN.
std::map< const std::string, const AVCodecID, comp > VIDEOCODEC_MAP
Map command line option to video AVCodecID.
static HWACCEL_MAP hwaccel_map
#define FFMPEGFS_OPT(templ, param, value)
static void ffmpeg_log(void *ptr, int level, const char *fmt, va_list vl)
Custom FFmpeg log function. Used with av_log_set_callback().
static const SAMPLE_FMT_MAP sample_fmt_map
static int get_hwaccel(const std::string &arg, HWACCELAPI *hwaccel_API, AVHWDeviceType *hwaccel_device_type)
Get type of hardware acceleration. To keep it simple, currently all values are accepted.
static int get_seek_time_diff(const std::string &arg, int64_t *value)
Get seek time diff. Input value must be in seconds.
static int get_audiocodec(const std::string &arg, AVCodecID *audio_codec)
Get the audio codec.
FFMPEGFS_PARAMS params
FFmpegfs command line parameters.
static bool init_logging(const std::string &logfile, const std::string &max_level, bool to_stderr, bool to_syslog)
Inititalise logging facility.
std::map< const std::string, const AUTOCOPY, comp > AUTOCOPY_MAP
Map command line option to AUTOCOPY enum.
std::map< const std::string, const AVCodecID, comp > CODEC_MAP
Map command line option to AVCodecID.
static int get_bitrate(const std::string &arg, BITRATE *bitrate)
Get formatted bitrate.
std::map< const std::string, const SAMPLE_FMT, comp > SAMPLE_FMT_MAP
Map command line option to SAMPLE_FMT.
std::map< const std::string, const AVCodecID, comp > AUDIOCODEC_MAP
Map command line option to audio AVCodecID.
static void usage()
Print program usage info.
static const LEVEL_MAP prores_level_map
static const AUTOCOPY_MAP autocopy_map
std::map< const std::string, const PRORESLEVEL, comp > LEVEL_MAP
Map command line option to LEVEL enum.
static int get_videocodec(const std::string &arg, AVCodecID *video_codec)
Get the video codec.
static struct fuse_opt ffmpegfs_opts[]
static const PROFILE_MAP profile_map
static int get_profile(const std::string &arg, PROFILE *profile)
Get profile option.
static int get_desttype(const std::string &arg, FFMPEGFS_FORMAT_ARR &format)
Get destination type.
static int get_level(const std::string &arg, PRORESLEVEL *level)
Get ProRes level.
std::string get_profile_text(PROFILE profile)
Convert PROFILE enum to human readable text.
const char * value_or_none(const char *value)
Return a printable parameter value.
static int get_hwaccel_dec_blocked(const std::string &arg, HWACCEL_BLOCKED_MAP **hwaccel_dec_blocked)
Get list of codecs and optional profiles blocked for hardware accelerated decoding.
static void print_params()
Print currently selected parameters.
static const CODEC_MAP hwaccel_codec_map
std::string get_level_text(PRORESLEVEL level)
Convert PRORESLEVEL enum to human readable text.
std::string get_sampleformat_text(SAMPLE_FMT sample_fmt)
Convert SAMPLE_FMT enum to human readable text.
static int get_sampleformat(const std::string &arg, SAMPLE_FMT *sample_fmt)
Get sample format.
static int ffmpegfs_opt_proc(__attribute__((unused)) void *data, const char *arg, int key, struct fuse_args *outargs)
FUSE option parsing function.
static int get_segment_duration(const std::string &arg, int64_t *value)
Get HLS segment duration. Input value must be in seconds.
static void build_device_type_list()
Build list of available device types. Builds a list of device types supported by the current FFmpeg l...
static int get_time(const std::string &arg, time_t *time)
Get formatted time,.
std::string get_video_codec_text(AVCodecID video_codec)
Convert AVCodecID enum for video codec to human readable text.
std::map< const std::string, const PROFILE, comp > PROFILE_MAP
Map command line option to PROFILE enum.
static int get_recodesame(const std::string &arg, RECODESAME *recode)
Get recode option.
static void list_options(const char *info, const T &map)
Iterate through all elements in map print all keys.
static const RECODESAME_MAP recode_map
FFMPEGFS_FORMAT_ARR ffmpeg_format
Two FFmpegfs_Format infos, 0: video file, 1: audio file.
std::map< const std::string, const RECODESAME, comp > RECODESAME_MAP
Map command line option to RECODESAME enum.
static int get_samplerate(const std::string &arg, int *samplerate)
Get formatted sample rate.
std::string get_autocopy_text(AUTOCOPY autocopy)
Convert AUTOCOPY enum to human readable text.
std::string get_audio_codec_text(AVCodecID audio_codec)
Convert AVCodecID enum for audio codec to human readable text.
static int get_codec(const std::string &codec, AVCodecID *codec_id)
Get AVCodecID for codec string.
bool check_hwaccel_dec_blocked(AVCodecID codec_id, int profile)
Check if codec_id and the optional profile are in the block list.
std::string get_hwaccel_API_text(HWACCELAPI hwaccel_API)
Get the selected hardware acceleration as text.
static int get_autocopy(const std::string &arg, AUTOCOPY *autocopy)
Get autocopy option.
static bool set_defaults()
Set default values.
Main include for FFmpegfs project.
fuse_operations ffmpegfs_ops
Fuse operations struct.
void transcoder_cache_path(std::string *path)
Get transcoder cache path.
bool docker_client
True if running inside a Docker container.
HWACCELAPI
Hardware acceleration types.
bool transcoder_init()
Initialise transcoder, create cache.
std::multimap< AVCodecID, int > HWACCEL_BLOCKED_MAP
Map command line option to AVCodecID.
FFMPEGFS_FORMAT_ARR ffmpeg_format
Two FFmpegfs_Format infos, 0: video file, 1: audio file.
bool transcoder_cache_clear()
Clear transcoder cache.
bool transcoder_cache_maintenance()
Run cache maintenance.
void init_fuse_ops()
Initialise FUSE operation structure.
VIRTUALFILE const * LPCVIRTUALFILE
Pointer to const version of VIRTUALFILE.
Provide various log facilities to stderr, disk or syslog.
constexpr Logging::LOGLEVEL LOGDEBUG
Shorthand for log level DEBUG.
constexpr Logging::LOGLEVEL LOGTRACE
Shorthand for log level TRACE.
constexpr Logging::LOGLEVEL LOGWARN
Shorthand for log level WARNING.
constexpr Logging::LOGLEVEL LOGERROR
Shorthand for log level ERROR.
constexpr Logging::LOGLEVEL LOGINFO
Shorthand for log level INFO.
Global program parameters.
std::string m_scriptsource
Source script.
std::string m_hwaccel_enc_device
Encoder device. May be AUTO to auto detect or empty.
int m_log_stderr
Log output to standard error.
time_t m_cache_maintenance
Prune timer interval.
bool smart_transcode() const
Check for smart transcode mode.
AVHWDeviceType m_hwaccel_dec_device_type
Enable hardware acceleration buffering for decoder.
time_t m_max_inactive_suspend
Time (seconds) that must elapse without access until transcoding is suspended.
int m_deinterlace
1: deinterlace video, 0: no deinterlace
int m_decoding_errors
Break transcoding on decoding error.
int m_oldnamescheme
Use old output name scheme, can create duplicate filenames.
AVHWDeviceType m_hwaccel_enc_device_type
Enable hardware acceleration buffering for encoder.
time_t m_expiry_time
Time (seconds) after which an cache entry is deleted.
int m_no_subtitles
0: allow subtitles, 1: do no transcode subtitles
FFMPEGFS_PARAMS & operator=(const FFMPEGFS_PARAMS &other) noexcept
Make copy from other FFMPEGFS_PARAMS object.
int m_clear_cache
Clear cache on start up.
std::string m_hwaccel_dec_device
Decoder device. May be AUTO to auto detect or empty.
const FFmpegfs_Format * current_format(LPCVIRTUALFILE virtualfile) const
Get FFmpegfs_Format for a virtual file.
int m_audiochannels
Max. number of audio channels.
int64_t m_min_seek_time_diff
Minimum time diff from current to next requested segment to perform a seek, in AV_TIME_BASE fractiona...
int m_videowidth
Output video width.
BITRATE m_videobitrate
Output video bit rate (bits per second)
HWACCELAPI m_hwaccel_dec_API
Decoder API.
size_t m_prebuffer_size
Number of bytes that will be decoded before the output can be accessed.
int m_videoheight
Output video height.
time_t m_prebuffer_time
Playing time that will be decoded before the output can be accessed.
int64_t m_segment_duration
Duration of one HLS segment file, in AV_TIME_BASE fractional seconds.
BITRATE m_audiobitrate
Output audio bit rate (bits per second)
std::string m_cachepath
Disk cache path, defaults to $XDG_CACHE_HOME.
int m_prune_cache
Prune cache immediately.
RECODESAME m_recodesame
Recode to same format options.
SAMPLE_FMT m_sample_fmt
Sample format.
PROFILE m_profile
Target profile: Firefox, MS Edge/IE or other.
int m_audiosamplerate
Output audio sample rate (in Hz)
size_t m_max_cache_size
Max. cache size in MB. When exceeded, oldest entries will be pruned.
AVCodecID m_video_codec
Either AV_CODEC_ID_NONE for default, or a user selected codec.
unsigned int m_max_threads
Max. number of recoder threads.
int m_disable_cache
Disable cache.
std::unique_ptr< MATCHVEC > m_hide_extensions
Set of extensions to block/hide. Must be a pointer as the fuse API cannot handle advanced c++ objects...
time_t m_max_inactive_abort
Time (seconds) that must elapse without access until transcoding is aborted.
int m_min_dvd_chapter_duration
Min. DVD chapter duration. Shorter chapters will be ignored.
std::string m_logfile
Output filename if logging to file.
std::string m_log_maxlevel
Max. log level.
std::string m_mountpath
Mount path: Files from m_mountpath will be mapped to this directory.
AVCodecID m_audio_codec
Either AV_CODEC_ID_NONE for default, or a user selected codec.
PRORESLEVEL m_level
Level, currently proxy/hq/lt/HQ (ProRes only)
size_t m_min_diskspace
Min. diskspace required for cache.
int m_noalbumarts
Skip album arts.
int m_enablescript
Enable virtual script.
std::unique_ptr< MATCHVEC > m_include_extensions
Set of extensions to include. If empty, include all. Must be a pointer as the fuse API cannot handle ...
HWACCEL_BLOCKED_MAP * m_hwaccel_dec_blocked
List of blocked decoders and optional profiles.
int m_debug
Debug mode (stay in foreground.
std::string m_scriptfile
Script name.
int m_win_smb_fix
Experimental Windows fix for access to EOF at file open.
int m_log_syslog
Log output to system log.
std::string m_basepath
Base path: Files from this directory (including all sub directories) will be mapped to m_mountpath.
HWACCELAPI m_hwaccel_enc_API
Encoder API.
AUTOCOPY m_autocopy
Copy streams if codec matches.
Hardware acceleration device and type.
HWACCELAPI m_hwaccel_API
Acceleration API, e.g VAAPI, MMAL or OMX.
AVHWDeviceType m_hwaccel_device_type
Hardware buffering type, NONE if not used.
bool m_supported
true if API supported, false if not