61static void init_stat(
struct stat *stbuf,
size_t fsize, time_t ftime,
bool directory);
65static bool virtual_name(std::string *virtualpath,
const std::string &origpath =
"",
const FFmpegfs_Format **current_format =
nullptr);
74static std::string
get_number(
const char *path, uint32_t *value);
78static int selector(
const struct dirent * de);
79static int scandir(
const char *dirp, std::vector<struct dirent> * _namelist,
int (*
selector) (
const struct dirent *),
int (*cmp) (
const struct dirent **,
const struct dirent **));
82static int ffmpegfs_readdir(
const char *path,
void *buf, fuse_fill_dir_t filler, off_t offset,
struct fuse_file_info *fi);
84static int ffmpegfs_fgetattr(
const char *path,
struct stat * stbuf,
struct fuse_file_info *fi);
85static int ffmpegfs_open(
const char *path,
struct fuse_file_info *fi);
86static int ffmpegfs_read(
const char *path,
char *buf,
size_t size, off_t offset,
struct fuse_file_info *fi);
102std::unique_ptr<thread_pool>
tp;
115 static const std::set<std::string, comp> passthrough_set =
244 return (passthrough_set.find(ext) != passthrough_set.cend());
271 std::string origpath;
272 std::string transcoded;
280 len = readlink(origpath.c_str(), buf, size - 2);
289 strncat(buf, transcoded.c_str(), size);
304static int ffmpegfs_readdir(
const char *path,
void *buf, fuse_fill_dir_t filler, off_t ,
struct fuse_file_info * )
306 std::string origpath;
322 if (virtualfile ==
nullptr)
324#if defined(USE_LIBBLURAY) || defined(USE_LIBDVD) || defined(USE_LIBVCD)
333 return (res >= 0 ? 0 : res);
341 return (res >= 0 ? 0 : res);
349 return (res >= 0 ? 0 : res);
356 DIR *dp = opendir(origpath.c_str());
361 std::map<const std::string, struct stat> files;
364 for (
struct dirent *de = readdir(dp); de !=
nullptr; de = readdir(dp))
368 if (lstat((origpath + de->d_name).c_str(), &stbuf) == -1)
374 files.insert({ de->d_name, stbuf });
378 for (
auto& [key, value] : files)
380 std::string origname(key);
387 std::string origfile;
388 std::string filename(key);
389 struct stat & stbuf = value;
392 origfile = origpath + origname;
397 if (S_ISREG(stbuf.st_mode) || S_ISLNK(stbuf.st_mode))
404 if (current_format->
video_codec() == AV_CODEC_ID_NONE)
408 if (newvirtualfile ==
nullptr)
411 Logging::error(origfile,
"INTERNAL ERROR: ffmpegfs_readdir()! newvirtualfile is NULL.");
420 Logging::debug(origfile,
"Unable to transcode. The source has no audio stream, but the target just supports audio.");
511 else if (ffmpegfs_format->
is_hls())
522 load_path(origpath,
nullptr, buf, filler);
552 std::string origpath;
566 if (virtualfile ==
nullptr && lstat(origpath.c_str(), stbuf) == 0)
570 std::string filename(origpath);
572 if (S_ISREG(stbuf->st_mode) &&
virtual_name(&filename,
"", ¤t_format))
583 Logging::trace(origpath,
"getattr: Creating frame set directory of file.");
591 else if (current_format->
is_hls())
600 Logging::trace(origpath,
"getattr: Treating existing file/directory as passthrough.");
608 Logging::debug(origpath,
"getattr: File not recoded because --recodesame=NO.");
619 bool no_check =
false;
626 mempcpy(stbuf, &virtualfile->
m_st,
sizeof(
struct stat));
641 mempcpy(stbuf, &virtualfile->
m_st,
sizeof(
struct stat));
649 mempcpy(stbuf, &virtualfile->
m_st,
sizeof(
struct stat));
657 if (!no_check && lstat(origpath.c_str(), stbuf) == -1)
664 if (virtualfile ==
nullptr)
666 std::string pathonly(origpath);
696 std::string origfile(origpath);
732 if (virtualfile2 ==
nullptr)
738 mempcpy(stbuf, &virtualfile2->
m_st,
sizeof(
struct stat));
764 if (virtualfile2 ==
nullptr)
770 mempcpy(stbuf, &virtualfile2->
m_st,
sizeof(
struct stat));
782 return (!res ? error : res);
788 if (virtualfile ==
nullptr)
794 mempcpy(stbuf, &virtualfile->
m_st,
sizeof(
struct stat));
809 else if (S_ISREG(stbuf->st_mode))
812 if (virtualfile ==
nullptr)
821 if (cache_entry ==
nullptr)
837 mempcpy(stbuf, &virtualfile->
m_st,
sizeof(
struct stat));
862 std::string origpath;
878 if ((virtualfile ==
nullptr || (virtualfile->m_flags &
VIRTUALFLAG_PASSTHROUGH)) && lstat(origpath.c_str(), stbuf) == 0)
892 bool no_check =
false;
894 switch (virtualfile->m_type)
907 mempcpy(stbuf, &virtualfile->m_st,
sizeof(
struct stat));
915 mempcpy(stbuf, &virtualfile->m_st,
sizeof(
struct stat));
921 if (lstat(origpath.c_str(), stbuf) == -1)
928 if (S_ISREG(stbuf->st_mode))
932 if (cache_entry ==
nullptr)
939 uint32_t segment_no = 0;
951 mempcpy(stbuf, &virtualfile->m_st,
sizeof(
struct stat));
973 std::string origpath;
983 int fd = open(origpath.c_str(), fi->flags);
1007 switch (virtualfile->
m_type)
1029 if (parent_file !=
nullptr)
1034 if (cache_entry ==
nullptr)
1040 fi->fh =
reinterpret_cast<uintptr_t
>(cache_entry);
1054 if (cache_entry ==
nullptr)
1060 fi->fh =
reinterpret_cast<uintptr_t
>(cache_entry);
1090static int ffmpegfs_read(
const char *path,
char *buf,
size_t size, off_t offset,
struct fuse_file_info *fi)
1092 std::string origpath;
1093 size_t locoffset =
static_cast<size_t>(offset);
1096 Logging::trace(path,
"read: Reading %1 bytes from offset %2 to %3.", size, locoffset, size + locoffset);
1104 int fd = open(origpath.c_str(), O_RDONLY);
1108 bytes_read =
static_cast<int>(pread(fd, buf, size, offset));
1110 if (bytes_read >= 0)
1119 else if (errno != ENOENT)
1132 bool success =
true;
1134 if (virtualfile ==
nullptr)
1137 Logging::error(origpath.c_str(),
"read: INTERNAL ERROR: ffmpegfs_read()! virtualfile == NULL");
1141 switch (virtualfile->
m_type)
1151 size_t bytes = size;
1162 bytes_read =
static_cast<int>(bytes);
1180 cache_entry =
reinterpret_cast<Cache_Entry*
>(fi->fh);
1182 if (cache_entry ==
nullptr)
1186 Logging::error(origpath.c_str(),
"read: Tried to read from unopen file: (%1) %2", errno, strerror(errno));
1191 uint32_t frame_no = 0;
1192 std::string filename =
get_number(path, &frame_no);
1196 Logging::error(origpath.c_str(),
"read: Unable to deduct frame no. from file name (%1): (%2) %3", filename.c_str(), errno, strerror(errno));
1200 success =
transcoder_read_frame(cache_entry, buf, locoffset, size, frame_no, &bytes_read, virtualfile);
1206 cache_entry =
reinterpret_cast<Cache_Entry*
>(fi->fh);
1208 if (cache_entry ==
nullptr)
1212 Logging::error(origpath.c_str(),
"read: Tried to read from unopen file: (%1) %2", errno, strerror(errno));
1217 uint32_t segment_no = 0;
1221 std::string filename =
get_number(path, &segment_no);
1225 Logging::error(origpath.c_str(),
"read: Unable to deduct segment no. from file name (%1): (%2) %3", filename.c_str(), errno, strerror(errno));
1230 success =
transcoder_read(cache_entry, buf, locoffset, size, &bytes_read, segment_no);
1245 Logging::trace(path,
"read: Read %1 bytes from offset %2 to %3.", bytes_read, locoffset,
static_cast<size_t>(bytes_read) + locoffset);
1268 std::string origpath;
1275 if (!origpath.empty() && statvfs(origpath.c_str(), stbuf) == 0)
1289 statvfs(origpath.c_str(), stbuf);
1308 if (cache_entry !=
nullptr)
1310 uint32_t segment_no = 0;
1314 std::string filename =
get_number(path, &segment_no);
1318 Logging::error(path,
"release: Unable to deduct segment no. from file name (%1): (%2) %3", filename.c_str(), errno, strerror(errno));
1345 struct sigaction sa;
1346 std::memset(&sa, 0,
sizeof(sa));
1347 sigemptyset(&sa.sa_mask);
1348 sigaddset(&sa.sa_mask, SIGINT);
1353 conn->async_read = 0;
1415 if (cache_entry ==
nullptr)
1434static void init_stat(
struct stat * stbuf,
size_t fsize, time_t ftime,
bool directory)
1436 std::memset(stbuf, 0,
sizeof(
struct stat));
1438 stbuf->st_mode = DEFFILEMODE;
1441 stbuf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
1442 stbuf->st_nlink = 2;
1446 stbuf->st_mode |= S_IFREG;
1447 stbuf->st_nlink = 1;
1453 stbuf->st_uid = getuid();
1454 stbuf->st_gid = getgid();
1457 stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = ftime;
1472static LPVIRTUALFILE make_file(
void *buf, fuse_fill_dir_t filler,
VIRTUALTYPE type,
const std::string & origpath,
const std::string & filename,
size_t fsize, time_t ftime,
int flags)
1483 return insert_file(type, origpath + filename, &stbuf, flags);
1491 std::string scriptsource;
1498 FILE *fpi = fopen(scriptsource.c_str(),
"rt");
1501 Logging::warning(scriptsource,
"File open failed. Disabling script: (%1) %2", errno, strerror(errno));
1507 if (fstat(fileno(fpi), &stbuf) == -1)
1509 Logging::warning(scriptsource,
"File could not be accessed. Disabling script: (%1) %2", errno, strerror(errno));
1514 script_file.resize(
static_cast<size_t>(stbuf.st_size));
1516 if (fread(&
script_file[0], 1,
static_cast<size_t>(stbuf.st_size), fpi) !=
static_cast<size_t>(stbuf.st_size))
1518 Logging::warning(scriptsource,
"File could not be read. Disabling script: (%1) %2", errno, strerror(errno));
1542 if (current_format !=
nullptr)
1544 *current_format =
nullptr;
1559 newvirtualfile.
m_origfile = origpath + *virtualpath;
1563 if (ffmpegfs_format !=
nullptr)
1576 newvirtualfile.
m_destfile = origpath + *virtualpath;
1579 if (lstat(newvirtualfile.
m_destfile.c_str(), &newvirtualfile.
m_st) == 0)
1597 if (current_format !=
nullptr)
1599 *current_format = ffmpegfs_format;
1616 FILENAME_MAP::const_iterator it = map.lower_bound(search_for);
1617 if (it != map.cend())
1619 const std::string & key = it->first;
1620 if (key.compare(0, search_for.size(), search_for) == 0)
1640 return insert_file(type, virtfile, virtfile, stbuf, flags);
1647 FILENAME_MAP::iterator it =
filenames.find(sanitised_virtfile);
1655 std::memcpy(&virtualfile.
m_st, stbuf,
sizeof(
struct stat));
1657 virtualfile.
m_type = type;
1669 it =
filenames.find(sanitised_virtfile);
1681 stbuf->st_mode &= ~static_cast<mode_t>(S_IFREG | S_IFLNK);
1682 stbuf->st_mode |= S_IFDIR;
1683 if (stbuf->st_mode & S_IRWXU)
1685 stbuf->st_mode |= S_IXUSR;
1687 if (stbuf->st_mode & S_IRWXG)
1689 stbuf->st_mode |= S_IXGRP;
1691 if (stbuf->st_mode & S_IRWXO)
1693 stbuf->st_mode |= S_IXOTH;
1695 stbuf->st_nlink = 2;
1696 stbuf->st_size = stbuf->st_blksize;
1719 struct stat stbufdir;
1721 std::memcpy(&stbufdir, stbuf,
sizeof(stbufdir));
1728 std::string path(virtdir);
1740 return (it !=
filenames.end() ? &it->second :
nullptr);
1749 return (it !=
rfilenames.end() ? &it->second :
nullptr);
1759int load_path(
const std::string & path,
const struct stat *statbuf,
void *buf, fuse_fill_dir_t filler)
1767 int title_count = 0;
1769 for (FILENAME_MAP::iterator it =
filenames.lower_bound(path); it !=
filenames.end(); ++it)
1771 std::string virtfilepath = it->first;
1781 #ifdef USE_LIBBLURAY
1791 if (virtfilepath == path)
1794 std::string destfile(virtualfile->
m_destfile);
1805 std::string cachefile;
1810 if (!lstat(cachefile.c_str(), &stbuf2))
1816 std::memcpy(&stbuf, &virtualfile->
m_st,
sizeof(
struct stat));
1820 if (statbuf ==
nullptr)
1822 std::memcpy(&stbuf, &virtualfile->
m_st,
sizeof(
struct stat));
1826 std::memcpy(&stbuf, statbuf,
sizeof(
struct stat));
1852 if (de->d_type & (DT_REG | DT_LNK))
1854 return (av_guess_format(
nullptr, de->d_name,
nullptr) !=
nullptr);
1874static int scandir(
const char *dirp, std::vector<struct dirent> * _namelist,
int (*
selector) (
const struct dirent *),
int (*cmp) (
const struct dirent **,
const struct dirent **))
1876 struct dirent **namelist;
1883 for (
int n = 0; n < count; n++)
1885 _namelist->push_back(*namelist[n]);
1896 std::string buffer(origpath);
1908 if (virtualfile !=
nullptr)
1919 std::string dir(*filepath);
1920 std::string searchexp(*filepath);
1921 std::string origfile;
1922 std::vector<struct dirent> namelist;
1934 if (errno != ENOTDIR)
1936 Logging::error(dir,
"Error scanning directory: (%1) %2", errno, strerror(errno));
1944 for (
size_t n = 0; n < static_cast<size_t>(count); n++)
1946 if (!strcmp(namelist[n].d_name, searchexp.c_str()))
1955 if (found && lstat(origfile.c_str(), &stbuf) == 0)
1960 if (*filepath != origfile)
1963 *filepath = origfile;
1969 return virtualfile2;
1984 std::string filepath(origpath);
2015 std::string master_contents;
2016 std::string index_0_av_contents;
2030 master_contents =
"#EXTM3U\n"
2031 "#EXT-X-STREAM-INF:PROGRAM-ID=1\n"
2032 "index_0_av.m3u8\n";
2035 "#EXT-X-TARGETDURATION:%i\n"
2036 "#EXT-X-ALLOW-CACHE:YES\n"
2037 "#EXT-X-PLAYLIST-TYPE:VOD\n"
2038 "#EXT-X-VERSION:3\n"
2044 for (uint32_t file_no = 1; file_no <= virtualfile->
get_segment_count(); file_no++)
2050 std::string cachefile;
2051 std::string _origpath(origpath);
2054 std::string filename(_origpath);
2056 filename.append(
".");
2057 filename.append(segment_name);
2061 if (!lstat(cachefile.c_str(), &stbuf))
2070 if (file_no < virtualfile->get_segment_count())
2076 strsprintf(&buffer,
"#EXTINF:%.3f,\n",
static_cast<double>(remaining_duration) / AV_TIME_BASE);
2079 index_0_av_contents += buffer;
2080 index_0_av_contents += segment_name;
2081 index_0_av_contents +=
"\n";
2084 index_0_av_contents +=
"#EXT-X-ENDLIST\n";
2088 std::copy(master_contents.begin(), master_contents.end(), std::back_inserter(child_file->
m_file_contents));
2091 std::copy(index_0_av_contents.begin(), index_0_av_contents.end(), std::back_inserter(child_file->
m_file_contents));
2095 std::string hls_html;
2101 " <title>HLS Demo</title>\n"
2102 " <script src=\"https://cdn.jsdelivr.net/npm/hls.js@latest\"></script>\n"
2103 " <meta charset=\"utf-8\">\n"
2108 " <h1>Hls.js demo - basic usage</h1>\n"
2109 " <video height=\"600\" id=\"video\" controls></video>\n"
2112 " var video = document.getElementById(\"video\");\n"
2113 " var videoSrc = \"index_0_av.m3u8\";\n"
2114 " if (Hls.isSupported()) {\n"
2115 " var hls = new Hls();\n"
2116 " hls.loadSource(videoSrc);\n"
2117 " hls.attachMedia(video);\n"
2118 " hls.on(Hls.Events.MANIFEST_PARSED, function() {\n"
2122 " // hls.js is not supported on platforms that do not have Media Source Extensions (MSE) enabled.\n"
2123 " // When the browser has built-in HLS support (check using `canPlayType`), we can provide an HLS manifest (i.e. .m3u8 URL) directly to the video element through the `src` property.\n"
2124 " // This is using the built-in support of the plain video element, without using hls.js.\n"
2125 " // Note: it would be more normal to wait on the 'canplay' event below, but on Safari (where you are most likely to find built-in HLS support), the video.src URL must be on the user-driven\n"
2126 " // white-list before a 'canplay' event will be emitted; the last video event that can be reliably listened to when the URL is not on the white-list is 'loadedmetadata'.\n"
2127 " else if (video.canPlayType(\"application/vnd.apple.mpegurl\")) {\n"
2128 " video.src = videoSrc;\n"
2129 " video.addEventListener(\"loadedmetadata\", function() {\n"
2139 std::copy(hls_html.begin(), hls_html.end(), std::back_inserter(child_file->
m_file_contents));
2158 if (virtualfile ==
nullptr)
2175 if (cache_entry ==
nullptr)
2196 if (signum == SIGINT)
2216 std::string filename(path);
2221 *value =
static_cast<uint32_t
>(std::stoi(filename));
2233 const AVOutputFormat* oformat = ::av_guess_format(
nullptr, filepath.c_str(),
nullptr);
2235 if (oformat !=
nullptr)
2268 AVFormatContext *format_ctx =
nullptr;
2275 res = avformat_open_input(&format_ctx, newvirtualfile->
m_origfile.c_str(),
nullptr,
nullptr);
2282 res = avformat_find_stream_info(format_ctx,
nullptr);
2290 AVDictionaryEntry *tag = av_dict_get(format_ctx->metadata,
"CUESHEET",
nullptr, AV_DICT_IGNORE_SUFFIX);
2305 if (ret != AVERROR_STREAM_NOT_FOUND)
2315 newvirtualfile->
m_duration = format_ctx->duration;
2318 if (lstat(newvirtualfile->
m_origfile.c_str(), &stbuf) == 0)
2320 std::memcpy(&newvirtualfile->
m_st, &stbuf,
sizeof(stbuf));
2323 for (
unsigned int stream_idx = 0; stream_idx < format_ctx->nb_streams; stream_idx++)
2325 switch (format_ctx->streams[stream_idx]->codecpar->codec_type)
2327 case AVMEDIA_TYPE_VIDEO:
2329 if (!
is_album_art(format_ctx->streams[stream_idx]->codecpar->codec_id))
2335 case AVMEDIA_TYPE_SUBTITLE:
2352 if (format_ctx !=
nullptr)
2354 avformat_close_input(&format_ctx);
2369 if (virtualfile !=
nullptr)
2406int add_fuse_entry(
void *buf, fuse_fill_dir_t filler,
const std::string & name,
const struct stat *stbuf, off_t off)
2408 if (buf ==
nullptr || filler ==
nullptr)
2413 return filler(buf, name.c_str(), stbuf, off);
2416int add_dotdot(
void *buf, fuse_fill_dir_t filler,
const struct stat *stbuf, off_t off)
2418 struct stat *stbuf2 =
nullptr;
2421 if (stbuf !=
nullptr)
2424 init_stat(stbuf2, 0, stbuf->st_ctime,
true);
int check_bluray(const std::string &path, void *buf, fuse_fill_dir_t filler)
Get number of titles on Blu-ray.
#define CACHE_FLAG_RO
Mark cache file read-only.
bool stop_cache_maintenance()
Stop cache maintenance timer.
bool start_cache_maintenance(time_t interval)
Start cache maintenance timer.
static const std::string & make_cachefile_name(std::string *cachefile, const std::string &filename, const std::string &fileext, bool is_idx)
Make up a cache file name, including the full path.
LPVIRTUALFILE virtualfile()
Get the underlying VIRTUALFILE object.
std::unique_ptr< Buffer > m_buffer
Buffer object.
static void warning(const T filename, const std::string &format_string, Args &&...args)
Write warning level log entry.
static void debug(const T filename, const std::string &format_string, Args &&...args)
Write debug level log entry.
static void trace(const T filename, const std::string &format_string, Args &&...args)
Write trace level log entry.
static void info(const T filename, const std::string &format_string, Args &&...args)
Write info level log entry.
static void error(const T filename, const std::string &format_string, Args &&...args)
Write error level log entry.
int check_cuesheet(const std::string &filename, void *buf, fuse_fill_dir_t filler)
Get number of titles in cue sheet.
int check_dvd(const std::string &path, void *buf, fuse_fill_dir_t filler)
Get number of titles on DVD.
#define FALLTHROUGH_INTENDED
Allow fallthrough in case statements for GCC.
const std::string & remove_path(std::string *filepath)
Remove path from filename. Handy basename alternative.
void exepath(std::string *path)
Path to FFmpegfs binary.
const std::string & append_filename(std::string *path, const std::string &filename)
Add filename to path, including / after the path if required.
const std::string & remove_filename(std::string *filepath)
Remove filename from path. Handy dirname alternative.
bool check_ext(const std::string &ext, const std::string &filename)
Check if filename has a certain extension. The check is case sensitive.
bool is_blocked(const std::string &filename)
Check if filename should be hidden from output path.
std::string sanitise_filepath(std::string *filepath)
Sanitise file name. Calls realpath() to remove duplicate // or resolve ../.. etc. Changes the path in...
bool is_selected(const std::string &ext)
Find extension in include list, if existing.
int strcasecmp(const std::string &s1, const std::string &s2)
strcasecmp() equivalent for std::string.
bool is_album_art(AVCodecID codec_id, const AVRational *frame_rate)
Minimal check if codec is an album art. Requires frame_rate to decide whether this is a video stream ...
std::string make_filename(uint32_t file_no, const std::string &fileext)
Make a file name from file number and file extension.
const std::string & replace_ext(std::string *filepath, const std::string &ext)
Replace extension in filename, taking into account that there might not be an extension already.
const std::string & remove_sep(std::string *path)
Remove / from the path.
const std::string & remove_ext(std::string *filepath)
Remove extension from filename.
const std::string & append_ext(std::string *filepath, const std::string &ext)
Append extension to filename. If ext is the same as.
const std::string & append_sep(std::string *path)
Add / to the path if required.
void append_basepath(std::string *origpath, const char *path)
Translate file names from FUSE to the original absolute path.
void stat_set_size(struct stat *st, size_t size)
Properly fill in all size related members in stat struct.
int get_audio_props(AVFormatContext *format_ctx, int *channels, int *samplerate)
Get first audio stream.
std::string replace_all(std::string str, const std::string &from, const std::string &to)
Same as std::string replace(), but replaces all occurrences.
bool replace_start(std::string *str, const std::string &from, const std::string &to)
Replace start of string from "from" to "to".
bool find_ext(std::string *ext, const std::string &filename)
Find extension in filename, if existing.
std::string ffmpeg_geterror(int errnum)
Get FFmpeg error string for errnum. Internally calls av_strerror().
@ YES
Always recode to same format.
@ NO
Never recode to same format.
#define FFMPEFS_VERSION
FFmpegfs version number.
const std::string & strsprintf(std::string *str, const std::string &format, Args ... args)
Format a std::string sprintf-like.
@ VIDEO
FFmpegfs_Format info, 0: video file.
@ AUDIO
FFmpegfs_Format info, 1: audio file.
FFMPEGFS_PARAMS params
FFmpegfs command line parameters.
FFMPEGFS_FORMAT_ARR ffmpeg_format
Two FFmpegfs_Format infos, 0: video file, 1: audio file.
void transcoder_free()
Free transcoder.
VIRTUALTYPE
Virtual file types enum.
@ DISK
Regular disk file to transcode.
@ BLURAY
Blu-ray disk file.
@ PASSTHROUGH
passthrough file, not used
#define VIRTUALFLAG_CUESHEET
File is part of a set of cue sheet tracks or the directory.
#define VIRTUALFLAG_HIDDEN
File is not transcodable or should otherwise show in listings.
VIRTUALFILE const * LPCVIRTUALFILE
Pointer to const version of VIRTUALFILE.
#define VIRTUALFLAG_FILESET
File is file set (images, HLS)
#define VIRTUALFLAG_HLS
File is part of a set of HLS transport stream (ts) files.
#define VIRTUALFLAG_DIRECTORY
File is a virtual directory.
#define VIRTUALFLAG_NONE
No flags.
#define VIRTUALFLAG_FRAME
File is part of a set of frames.
#define VIRTUALFLAG_PASSTHROUGH
passthrough file, not used
static size_t guess_format_idx(const std::string &filepath)
Try to guess the format index (audio or video) for a file.
LPVIRTUALFILE find_file(const std::string &virtfile)
Find file in cache.
static int ffmpegfs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
Read data from an open file.
static int ffmpegfs_fgetattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi)
Get attributes from an open file.
LPVIRTUALFILE find_parent(const std::string &origpath)
Given the destination (post-transcode) file name, determine the parent of the file to be transcoded.
LPVIRTUALFILE insert_dir(VIRTUALTYPE type, const std::string &virtdir, const struct stat *stbuf, int flags)
Add new virtual directory to the internal list. If the file already exists, it will be updated.
int add_dotdot(void *buf, fuse_fill_dir_t filler, const struct stat *stbuf, off_t off)
Make dot and double dot entries for a virtual directory.
static int parse_file(LPVIRTUALFILE newvirtualfile)
Open file with FFmpeg API and parse for streams and cue sheet.
fuse_operations ffmpegfs_ops
FUSE file system operations.
std::map< const std::string, VIRTUALFILE > RFILENAME_MAP
Map source file names to virtual file objects.
static RFILENAME_MAP rfilenames
Reverse map virtual files to real files.
static int ffmpegfs_release(const char *path, struct fuse_file_info *fi)
Release an open file.
static std::vector< char > script_file
Buffer for the virtual script if enabled.
bool docker_client
True if running inside a Docker container.
int add_fuse_entry(void *buf, fuse_fill_dir_t filler, const std::string &name, const struct stat *stbuf, off_t off)
Wrapper to the Fuse filler function.
static void init_stat(struct stat *stbuf, size_t fsize, time_t ftime, bool directory)
Initialise a stat structure.
static FILENAME_MAP::const_iterator find_prefix(const FILENAME_MAP &map, const std::string &search_for)
Find mapped file by prefix. Normally used to find a path.
static int ffmpegfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
Read directory.
static int selector(const struct dirent *de)
Filter function used for scandir.
static bool virtual_name(std::string *virtualpath, const std::string &origpath="", const FFmpegfs_Format **current_format=nullptr)
Convert file name from source to destination name.
static struct sigaction oldHandler
Saves old SIGINT handler to restore on shutdown.
int load_path(const std::string &path, const struct stat *statbuf, void *buf, fuse_fill_dir_t filler)
Load a path with virtual files for FUSE.
static void stat_to_dir(struct stat *stbuf)
Convert stbuf to directory.
static int ffmpegfs_open(const char *path, struct fuse_file_info *fi)
File open operation.
static int ffmpegfs_getattr(const char *path, struct stat *stbuf)
Get file attributes.
static bool is_passthrough(const std::string &ext)
Check if a file should be treated passthrough, i.e. bitmaps etc.
static void sighandler(int signum)
Replacement SIGINT handler.
LPVIRTUALFILE find_original(const std::string &origpath)
Given the destination (post-transcode) file name, determine the parent of the file to be transcoded.
static void ffmpegfs_destroy(__attribute__((unused)) void *p)
Clean up filesystem.
static int get_source_properties(const std::string &origpath, LPVIRTUALFILE virtualfile)
Calculate the video frame count.
static int scandir(const char *dirp, std::vector< struct dirent > *_namelist, int(*selector)(const struct dirent *), int(*cmp)(const struct dirent **, const struct dirent **))
Scans the directory dirp Works exactly like the scandir(3) function, the only difference is that it r...
static int make_hls_fileset(void *buf, fuse_fill_dir_t filler, const std::string &origpath, LPVIRTUALFILE virtualfile)
Build a virtual HLS file set.
static int ffmpegfs_readlink(const char *path, char *buf, size_t size)
Read the target of a symbolic link.
static void * ffmpegfs_init(struct fuse_conn_info *conn)
Initialise filesystem.
bool check_path(const std::string &path)
Check if the path has already been parsed. Only useful if for DVD, Blu-ray or VCD where it is guarant...
static int ffmpegfs_statfs(const char *path, struct statvfs *stbuf)
Get file system statistics.
LPVIRTUALFILE find_file_from_orig(const std::string &origfile)
Look for the file in the cache.
static std::string get_number(const char *path, uint32_t *value)
Extract the number for a file name.
LPVIRTUALFILE insert_file(VIRTUALTYPE type, const std::string &virtfile, const struct stat *stbuf, int flags)
Add new virtual file to internal list.
static FILENAME_MAP filenames
Map files to virtual files.
static void prepare_script()
Read the virtual script file into memory and store in buffer.
static int kick_next(LPVIRTUALFILE virtualfile)
Give next song in cuesheet list a kick start Starts transcoding of the next song on the cuesheet list...
static void insert(const VIRTUALFILE &virtualfile)
Insert virtualfile into list.
std::map< const std::string, VIRTUALFILE > FILENAME_MAP
Map virtual file names to virtual file objects.
static const FFmpegfs_Format * get_format(LPVIRTUALFILE newvirtualfile)
Get FFmpegfs_Format for the file.
void init_fuse_ops()
Initialise FUSE operation structure.
std::unique_ptr< thread_pool > tp
Thread pool object.
static LPVIRTUALFILE make_file(void *buf, fuse_fill_dir_t filler, VIRTUALTYPE type, const std::string &origpath, const std::string &filename, size_t fsize, time_t ftime=time(nullptr), int flags=VIRTUALFLAG_NONE)
Make a virtual file.
static void flags_to_dir(int *flags)
Convert flags to directory.
Provide various log facilities to stderr, disk or syslog.
std::string m_scriptsource
Source script.
time_t m_cache_maintenance
Prune timer interval.
bool smart_transcode() const
Check for smart transcode mode.
int m_oldnamescheme
Use old output name scheme, can create duplicate filenames.
const FFmpegfs_Format * current_format(LPCVIRTUALFILE virtualfile) const
Get FFmpegfs_Format for a virtual file.
int64_t m_segment_duration
Duration of one HLS segment file, in AV_TIME_BASE fractional seconds.
RECODESAME m_recodesame
Recode to same format options.
unsigned int m_max_threads
Max. number of recoder threads.
std::string m_mountpath
Mount path: Files from m_mountpath will be mapped to this directory.
int m_enablescript
Enable virtual script.
std::string m_scriptfile
Script name.
std::string m_basepath
Base path: Files from this directory (including all sub directories) will be mapped to m_mountpath.
VIRTUALFILE * m_nextfile
Next (probable) file to be played. Used for cuesheet lists.
int m_sample_rate
Audio sample rate - Filled in for the DVD/Blu-ray directory.
std::string m_destfile
Name and path of destination file.
size_t m_predicted_size
Use this as the size instead of computing it over and over.
VIRTUALTYPE m_type
Type of this virtual file.
bool m_has_audio
True if file has an audio track.
std::string m_origfile
Sanitised name and path of original file.
int m_flags
One of the VIRTUALFLAG_* flags.
int m_channels
Audio channels - Filled in for the DVD/Blu-ray directory.
std::string m_virtfile
Name and path of virtual file.
bool m_has_video
True if file has a video track.
struct stat m_st
stat structure with size etc.
bool m_has_subtitle
True if file has a subtitle track.
std::vector< char > m_file_contents
Buffer for virtual files.
std::string m_cuesheet
Cue sheet file contents for physical file.
size_t m_format_idx
Index into params.format[] array.
struct VIRTUALFILE::CUESHEET_TRACK m_cuesheet_track
Cue sheet data for track.
uint32_t get_segment_count() const
Number of HLS segments in set.
uint32_t m_video_frame_count
Number of frames in video or 0 if not a video.
int64_t m_duration
Track/chapter duration, in AV_TIME_BASE fractional seconds.
Thread pool class implementation.
Cache_Entry * transcoder_new(LPVIRTUALFILE virtualfile, bool begin_transcode)
Allocate and initialise the transcoder.
bool transcoder_read(Cache_Entry *cache_entry, char *buff, size_t offset, size_t len, int *bytes_read, uint32_t segment_no)
Read some bytes from the internal buffer and into the given buffer.
void transcoder_exit()
Exit transcoding.
size_t transcoder_get_size(Cache_Entry *cache_entry)
Return size of output file, as computed by encoder.
bool transcoder_read_frame(Cache_Entry *cache_entry, char *buff, size_t offset, size_t len, uint32_t frame_no, int *bytes_read, LPVIRTUALFILE virtualfile)
Read one image frame from the internal buffer and into the given buffer.
size_t transcoder_buffer_watermark(Cache_Entry *cache_entry, uint32_t segment_no)
Return the current watermark of the file while transcoding.
bool transcoder_cached_filesize(LPVIRTUALFILE virtualfile, struct stat *stbuf)
Simply get encoded file size (do not create the whole encoder/decoder objects)
void transcoder_delete(Cache_Entry *cache_entry)
Free the cache entry structure.
File transcoder interface (for use with by FUSE)
int check_vcd(const std::string &path, void *buf, fuse_fill_dir_t filler)
Get number of chapters on S/VCD.
Video CD and Super Video CD parser.