41#ifndef HAVE_SQLITE_ERRSTR
42#define sqlite3_errstr(rc) ""
45#define STRINGIFY(x) #x
46#define TOSTRING(x) STRINGIFY(x)
50 , m_filename(filename)
51 , m_select_stmt(nullptr)
52 , m_insert_stmt(nullptr)
53 , m_delete_stmt(nullptr)
60 if (m_db_handle !=
nullptr)
62#ifdef HAVE_SQLITE_CACHEFLUSH
66 sqlite3_finalize(m_select_stmt);
67 sqlite3_finalize(m_insert_stmt);
68 sqlite3_finalize(m_delete_stmt);
70 sqlite3_close(m_db_handle);
84 "PRIMARY KEY(`filename`,`desttype`)"
92 {
"filename",
"TEXT NOT NULL" },
93 {
"desttype",
"CHAR ( 10 ) NOT NULL" },
97 {
"enable_ismv",
"BOOLEAN NOT NULL" },
98 {
"audiobitrate",
"UNSIGNED INT NOT NULL" },
99 {
"audiosamplerate",
"UNSIGNED INT NOT NULL" },
100 {
"videobitrate",
"UNSIGNED INT NOT NULL" },
101 {
"videowidth",
"UNSIGNED INT NOT NULL" },
102 {
"videoheight",
"UNSIGNED INT NOT NULL" },
103 {
"deinterlace",
"BOOLEAN NOT NULL" },
107 {
"duration",
"UNSIGNED BIG INT NOT NULL" },
108 {
"predicted_filesize",
"UNSIGNED BIG INT NOT NULL" },
109 {
"encoded_filesize",
"UNSIGNED BIG INT NOT NULL" },
110 {
"video_frame_count",
"UNSIGNED BIG INT NOT NULL" },
111 {
"segment_count",
"UNSIGNED BIG INT NOT NULL" },
112 {
"finished",
"INT NOT NULL" },
113 {
"error",
"BOOLEAN NOT NULL" },
114 {
"errno",
"INT NOT NULL" },
115 {
"averror",
"INT NOT NULL" },
116 {
"creation_time",
"DATETIME NOT NULL" },
117 {
"access_time",
"DATETIME NOT NULL" },
118 {
"file_time",
"DATETIME NOT NULL" },
119 {
"file_size",
"UNSIGNED BIG INT NOT NULL" }
134 {
"db_version_major",
"INTEGER NOT NULL" },
135 {
"db_version_minor",
"INTEGER NOT NULL" }
145 for (
auto& [key, value] :
m_cache)
160 sql =
"INSERT OR REPLACE INTO cache_entry\n"
161 "(filename, desttype, enable_ismv, audiobitrate, audiosamplerate, videobitrate, videowidth, videoheight, deinterlace, duration, predicted_filesize, encoded_filesize, video_frame_count, segment_count, finished, error, errno, averror, creation_time, access_time, file_time, file_size) VALUES\n"
162 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?);\n";
170 sql =
"SELECT desttype, enable_ismv, audiobitrate, audiosamplerate, videobitrate, videowidth, videoheight, deinterlace, duration, predicted_filesize, encoded_filesize, video_frame_count, segment_count, finished, error, errno, averror, strftime('%s', creation_time), strftime('%s', access_time), strftime('%s', file_time), file_size FROM cache_entry WHERE filename = ? AND desttype = ?;\n";
178 sql =
"DELETE FROM cache_entry WHERE filename = ? AND desttype = ?;\n";
196 sql =
"SELECT Count(*) FROM sqlite_master WHERE type='table' AND name='";
200 if (SQLITE_OK != (ret = sqlite3_prepare_v2(*
m_cacheidx_db, sql.c_str(), -1, &stmt,
nullptr)))
206 ret = sqlite3_step(stmt);
208 if (ret == SQLITE_ROW)
210 results = sqlite3_column_int(stmt, 0);
213 sqlite3_finalize(stmt);
215 return (results == 1);
225 sql =
"SELECT COUNT(*) AS CNTREC FROM pragma_table_info('";
227 sql +=
"') WHERE name='";
231 if (SQLITE_OK != (ret = sqlite3_prepare_v2(*
m_cacheidx_db, sql.c_str(), -1, &stmt,
nullptr)))
237 ret = sqlite3_step(stmt);
239 if (ret == SQLITE_ROW)
241 results = sqlite3_column_int(stmt, 0);
244 sqlite3_finalize(stmt);
246 return (results == 1);
255 sql =
"SELECT db_version_major, db_version_minor FROM version;";
257 if (SQLITE_OK != (ret = sqlite3_prepare_v2(*
m_cacheidx_db, sql.c_str(), -1, &stmt,
nullptr)))
263 ret = sqlite3_step(stmt);
265 if (ret == SQLITE_ROW)
267 *db_version_major = sqlite3_column_int(stmt, 0);
268 *db_version_minor = sqlite3_column_int(stmt, 1);
271 sqlite3_finalize(stmt);
276int Cache::cmp_version(
int version_major_l,
int version_minor_l,
int version_major_r,
int version_minor_r)
278 if (version_major_l > version_major_r)
282 if (version_major_l < version_major_r)
289 if (version_minor_l > version_minor_r)
293 if (version_minor_l < version_minor_r)
305 char *errmsg =
nullptr;
309 sql =
"BEGIN TRANSACTION;";
310 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql,
nullptr,
nullptr, &errmsg)))
313 sqlite3_free(errmsg);
321 char *errmsg =
nullptr;
325 sql =
"END TRANSACTION;";
326 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql,
nullptr,
nullptr, &errmsg)))
329 sqlite3_free(errmsg);
337 char *errmsg =
nullptr;
342 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql,
nullptr,
nullptr, &errmsg)))
345 sqlite3_free(errmsg);
353 char *errmsg =
nullptr;
357 sql =
"CREATE TABLE `";
374 if (table->primary_key !=
nullptr)
377 sql += table->primary_key;
382 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql.c_str(),
nullptr,
nullptr, &errmsg)))
385 sqlite3_free(errmsg);
398 char *errmsg =
nullptr;
405 sql =
"ALTER TABLE `";
407 sql +=
"` ADD COLUMN `video_frame_count` UNSIGNED BIG INT NOT NULL DEFAULT 0;\n";
408 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql.c_str(),
nullptr,
nullptr, &errmsg)))
410 Logging::error(
m_cacheidx_db->filename(),
"SQLite3 exec error adding column `video_frame_count`: (%1) %2\n%3", ret, errmsg, sql.c_str());
411 sqlite3_free(errmsg);
419 char *errmsg =
nullptr;
431 sql =
"PRAGMA foreign_keys=off;\n";
432 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql.c_str(),
nullptr,
nullptr, &errmsg)))
435 sqlite3_free(errmsg);
442 char *errmsg =
nullptr;
446 sql =
"ALTER TABLE `";
448 sql +=
"` RENAME TO `";
451 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql.c_str(),
nullptr,
nullptr, &errmsg)))
454 sqlite3_free(errmsg);
468 char *errmsg =
nullptr;
475 if (!columns.empty())
484 sql =
"INSERT INTO `";
494 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql.c_str(),
nullptr,
nullptr, &errmsg)))
497 sqlite3_free(errmsg);
503 char *errmsg =
nullptr;
512 sql +=
"SET `finished` = 3\n";
513 sql +=
"WHERE `finished` = 1\n";
514 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql.c_str(),
nullptr,
nullptr, &errmsg)))
517 sqlite3_free(errmsg);
524 char *errmsg =
nullptr;
528 sql =
"DROP TABLE `cache_entry_old`";
529 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql.c_str(),
nullptr,
nullptr, &errmsg)))
531 Logging::error(
m_cacheidx_db->filename(),
"SQLite3 exec error adding column `video_frame_count`: (%1) %2\n%3", ret, errmsg, sql.c_str());
532 sqlite3_free(errmsg);
536 sql =
"PRAGMA foreign_keys=on;\n";
537 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql.c_str(),
nullptr,
nullptr, &errmsg)))
540 sqlite3_free(errmsg);
548 char *errmsg =
nullptr;
555 sql =
"ALTER TABLE `";
557 sql +=
"` ADD COLUMN `duration` UNSIGNED BIG INT NOT NULL DEFAULT 0;\n";
558 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql.c_str(),
nullptr,
nullptr, &errmsg)))
561 sqlite3_free(errmsg);
568 char *errmsg =
nullptr;
575 sql =
"ALTER TABLE `";
577 sql +=
"` ADD COLUMN `segment_count` UNSIGNED BIG INT NOT NULL DEFAULT 0;\n";
578 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql.c_str(),
nullptr,
nullptr, &errmsg)))
580 Logging::error(
m_cacheidx_db->filename(),
"SQLite3 exec error adding column `segment_count`: (%1) %2\n%3", ret, errmsg, sql.c_str());
581 sqlite3_free(errmsg);
590 char *errmsg =
nullptr;
595 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql,
nullptr,
nullptr, &errmsg)))
598 sqlite3_free(errmsg);
617 std::string filename;
618 char *errmsg =
nullptr;
620 bool new_database =
false;
621 bool need_upate =
false;
625 if (
mktree(filename, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) && errno != EEXIST)
627 Logging::error(filename,
"Error creating cache directory: (%1) %2\n%3", errno, strerror(errno),
m_cacheidx_db->filename().c_str());
634 if (SQLITE_OK != (ret = sqlite3_initialize()))
641 m_cacheidx_db = std::make_unique<sqlite_t>(filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_SHAREDCACHE);
655 if (SQLITE_OK != (ret = sqlite3_busy_timeout(*
m_cacheidx_db, 1000)))
663 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db,
"pragma journal_mode = WAL",
nullptr,
nullptr,
nullptr)))
671 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db,
"PRAGMA case_sensitive_like = 1;",
nullptr,
nullptr,
nullptr)))
713 if (SQLITE_OK != (ret = sqlite3_exec(*
m_cacheidx_db, sql,
nullptr,
nullptr, &errmsg)))
716 sqlite3_free(errmsg);
735 if (!
upgrade_db(&db_version_major, &db_version_minor))
746#ifdef HAVE_SQLITE_CACHEFLUSH
759 catch (
bool _success)
767#ifdef HAVE_SQLITE_CACHEFLUSH
768bool Cache::sqlite_t::flush_index()
770 if (m_db_handle !=
nullptr)
775 if (SQLITE_OK != (ret = sqlite3_db_cacheflush(m_db_handle)))
816 std::lock_guard<std::recursive_mutex> lock_mutex(
m_mutex);
822 assert(sqlite3_bind_parameter_count(
m_cacheidx_db->m_select_stmt) == 2);
824 if (SQLITE_OK != (ret = sqlite3_bind_text(
m_cacheidx_db->m_select_stmt, 1, cache_info->
m_destfile.c_str(), -1,
nullptr)))
830 if (SQLITE_OK != (ret = sqlite3_bind_text(
m_cacheidx_db->m_select_stmt, 2, cache_info->
m_desttype.data(), -1,
nullptr)))
838 if (ret == SQLITE_ROW)
840 const char *text =
reinterpret_cast<const char *
>(sqlite3_column_text(
m_cacheidx_db->m_select_stmt, 0));
867 else if (ret != SQLITE_DONE)
873 catch (
bool _success)
888#define SQLBINDTXT(idx, var) \
889 if (SQLITE_OK != (ret = sqlite3_bind_text(m_cacheidx_db->m_insert_stmt, idx, var, -1, nullptr))) \
891 Logging::error(m_cacheidx_db->filename(), "SQLite3 select column #%1 error: %2\n%3", idx, ret, sqlite3_errstr(ret)); \
895#define SQLBINDNUM(func, idx, var) \
896 if (SQLITE_OK != (ret = func(m_cacheidx_db->m_insert_stmt, idx, var))) \
898 Logging::error(m_cacheidx_db->filename(), "SQLite3 select column #%1 error: %2\n%3", idx, ret, sqlite3_errstr(ret)); \
912 std::lock_guard<std::recursive_mutex> lock_mutex(
m_mutex);
917 bool enable_ismv_dummy =
false;
919 assert(sqlite3_bind_parameter_count(
m_cacheidx_db->m_insert_stmt) == 22);
921 SQLBINDTXT(1, cache_info->m_destfile.c_str());
924 SQLBINDNUM(sqlite3_bind_int, 3, enable_ismv_dummy);
925 SQLBINDNUM(sqlite3_bind_int64, 4, cache_info->m_audiobitrate);
926 SQLBINDNUM(sqlite3_bind_int, 5, cache_info->m_audiosamplerate);
927 SQLBINDNUM(sqlite3_bind_int64, 6, cache_info->m_videobitrate);
928 SQLBINDNUM(sqlite3_bind_int, 7,
static_cast<int>(cache_info->m_videowidth));
929 SQLBINDNUM(sqlite3_bind_int, 8,
static_cast<int>(cache_info->m_videoheight));
930 SQLBINDNUM(sqlite3_bind_int, 9, cache_info->m_deinterlace);
931 SQLBINDNUM(sqlite3_bind_int64, 10,
static_cast<sqlite3_int64
>(cache_info->m_duration));
932 SQLBINDNUM(sqlite3_bind_int64, 11,
static_cast<sqlite3_int64
>(cache_info->m_predicted_filesize));
933 SQLBINDNUM(sqlite3_bind_int64, 12,
static_cast<sqlite3_int64
>(cache_info->m_encoded_filesize));
934 SQLBINDNUM(sqlite3_bind_int, 13,
static_cast<int32_t
>(cache_info->m_video_frame_count));
935 SQLBINDNUM(sqlite3_bind_int, 14,
static_cast<int32_t
>(cache_info->m_segment_count));
936 SQLBINDNUM(sqlite3_bind_int, 15,
static_cast<int32_t
>(cache_info->m_result));
937 SQLBINDNUM(sqlite3_bind_int, 16, cache_info->m_error);
938 SQLBINDNUM(sqlite3_bind_int, 17, cache_info->m_errno);
939 SQLBINDNUM(sqlite3_bind_int, 18, cache_info->m_averror);
940 SQLBINDNUM(sqlite3_bind_int64, 19, cache_info->m_creation_time);
941 SQLBINDNUM(sqlite3_bind_int64, 20, cache_info->m_access_time);
942 SQLBINDNUM(sqlite3_bind_int64, 21, cache_info->m_file_time);
943 SQLBINDNUM(sqlite3_bind_int64, 22,
static_cast<sqlite3_int64
>(cache_info->m_file_size));
947 if (ret != SQLITE_DONE)
953 catch (
bool _success)
978 std::lock_guard<std::recursive_mutex> lock_mutex(
m_mutex);
984 assert(sqlite3_bind_parameter_count(
m_cacheidx_db->m_delete_stmt) == 2);
986 if (SQLITE_OK != (ret = sqlite3_bind_text(
m_cacheidx_db->m_delete_stmt, 1, filename.c_str(), -1,
nullptr)))
992 if (SQLITE_OK != (ret = sqlite3_bind_text(
m_cacheidx_db->m_delete_stmt, 2, desttype.c_str(), -1,
nullptr)))
1000 if (ret != SQLITE_DONE)
1006 catch (
bool _success)
1030 if (cache_entry ==
nullptr)
1043 if (*cache_entry ==
nullptr)
1048 bool deleted =
false;
1050 if ((*cache_entry)->closeio(flags))
1055 m_cache.erase(make_pair((*cache_entry)->m_cache_info.m_destfile, (*cache_entry)->m_cache_info.m_desttype.data()));
1057 deleted = (*cache_entry)->destroy();
1058 *cache_entry =
nullptr;
1077 cache_entry = p->second;
1085 if (*cache_entry ==
nullptr)
1092 std::string filename((*cache_entry)->filename());
1115 std::vector<cache_key_t> keys;
1117 time_t now = time(
nullptr);
1122 strsprintf(&sql,
"SELECT filename, desttype, strftime('%%s', access_time) FROM cache_entry WHERE strftime('%%s', access_time) + %" FFMPEGFS_FORMAT_TIME_T
" < %" FFMPEGFS_FORMAT_TIME_T
";\n",
params.
m_expiry_time, now);
1124 std::lock_guard<std::recursive_mutex> lock_mutex(
m_mutex);
1126 sqlite3_prepare(*
m_cacheidx_db, sql.c_str(), -1, &stmt,
nullptr);
1129 while ((ret = sqlite3_step(stmt)) == SQLITE_ROW)
1131 const char *filename =
reinterpret_cast<const char *
>(sqlite3_column_text(stmt, 0));
1132 const char *desttype =
reinterpret_cast<const char *
>(sqlite3_column_text(stmt, 1));
1134 keys.emplace_back(filename, desttype);
1136 Logging::trace(filename,
"Found %1 old entries.",
format_time(now -
static_cast<time_t
>(sqlite3_column_int64(stmt, 2))).c_str());
1141 if (ret == SQLITE_DONE)
1143 for (
const auto& [key, value] : keys)
1147 cache_t::iterator p =
m_cache.find(make_pair(key, value));
1164 sqlite3_finalize(stmt);
1177 std::vector<cache_key_t> keys;
1178 std::vector<size_t> filesizes;
1184 sql =
"SELECT filename, desttype, encoded_filesize FROM cache_entry ORDER BY access_time ASC;\n";
1186 std::lock_guard<std::recursive_mutex> lock_mutex(
m_mutex);
1191 size_t total_size = 0;
1192 while((ret = sqlite3_step(stmt)) == SQLITE_ROW)
1194 const char *filename =
reinterpret_cast<const char *
>(sqlite3_column_text(stmt, 0));
1195 const char *desttype =
reinterpret_cast<const char *
>(sqlite3_column_text(stmt, 1));
1196 size_t size =
static_cast<size_t>(sqlite3_column_int64(stmt, 2));
1198 keys.emplace_back(filename, desttype);
1199 filesizes.push_back(size);
1208 if (ret == SQLITE_DONE)
1211 for (
const auto& [key, value] : keys)
1215 cache_t::iterator p =
m_cache.find(make_pair(key, value));
1226 total_size -= filesizes[n++];
1242 sqlite3_finalize(stmt);
1249 std::string cachepath;
1255 if (!free_bytes && errno)
1257 if (errno == ENOENT)
1263 Logging::error(cachepath,
"prune_disk_space() cannot determine free disk space: (%1) %2", errno, strerror(errno));
1267 if (free_bytes < predicted_filesize)
1269 Logging::error(cachepath,
"prune_disk_space() : Insufficient disk space %1 on cache drive, at least %2 required.",
format_size(free_bytes).c_str(),
format_size(predicted_filesize).c_str());
1274 std::lock_guard<std::recursive_mutex> lock_mutex(
m_mutex);
1279 std::vector<cache_key_t> keys;
1280 std::vector<size_t> filesizes;
1284 sql =
"SELECT filename, desttype, encoded_filesize FROM cache_entry ORDER BY access_time ASC;\n";
1289 while ((ret = sqlite3_step(stmt)) == SQLITE_ROW)
1291 const char *filename =
reinterpret_cast<const char *
>(sqlite3_column_text(stmt, 0));
1292 const char *desttype =
reinterpret_cast<const char *
>(sqlite3_column_text(stmt, 1));
1293 size_t size =
static_cast<size_t>(sqlite3_column_int64(stmt, 2));
1295 keys.emplace_back(filename, desttype);
1296 filesizes.push_back(size);
1301 if (ret == SQLITE_DONE)
1304 for (
const auto& [key, value] : keys)
1306 Logging::trace(cachepath,
"Pruning: %1 Type: %2", key.c_str(), value.c_str());
1308 cache_t::iterator p =
m_cache.find(make_pair(key, value));
1319 free_bytes += filesizes[n++];
1333 sqlite3_finalize(stmt);
1341 bool success =
true;
1357 bool success =
true;
1359 std::lock_guard<std::recursive_mutex> lock_mutex(
m_mutex);
1361 std::vector<cache_key_t> keys;
1365 sql =
"SELECT filename, desttype FROM cache_entry;\n";
1370 while((ret = sqlite3_step(stmt)) == SQLITE_ROW)
1372 const char *filename =
reinterpret_cast<const char *
>(sqlite3_column_text(stmt, 0));
1373 const char *desttype =
reinterpret_cast<const char *
>(sqlite3_column_text(stmt, 1));
1375 keys.emplace_back(filename, desttype);
1380 if (ret == SQLITE_DONE)
1382 for (
const auto& [key, value] : keys)
1386 cache_t::iterator p =
m_cache.find(make_pair(key, value));
1403 sqlite3_finalize(stmt);
1410 std::string cachefile;
1430#ifdef HAVE_SQLITE_EXPANDED_SQL
1431 char * p = sqlite3_expanded_sql(pStmt);
1435 const char *p = sqlite3_sql(pStmt);
#define CACHE_CLOSE_FREE
Free memory for cache entry.
#define CACHE_CHECK_BIT(mask, var)
Check bit in bitmask.
#define CACHE_CLOSE_DELETE
Delete cache entry, will unlink cached file! Implies CACHE_CLOSE_FREE.
#define SQLBINDTXT(idx, var)
Bind text column to SQLite statement.
#define sqlite3_errstr(rc)
If our version of SQLite hasn't go this function.
#define SQLBINDNUM(func, idx, var)
Bind numeric column to SQLite statement.
#define TOSTRING(x)
Convert a macro argument into a string constant.
#define DB_VERSION_MINOR
Current database version minor.
#define DB_MIN_VERSION_MAJOR
Required database version major (required 1.95)
#define DB_MIN_VERSION_MINOR
Required database version minor (required 1.95)
#define DB_VERSION_MAJOR
Current database version major.
RESULTCODE
RESULTCODE of transcoding operation.
@ NONE
No result code available.
#define DB_BASE_VERSION_MINOR
The oldest database version minor (Release < 1.95)
#define DB_BASE_VERSION_MAJOR
The oldest database version major (Release < 1.95)
CACHE_INFO const * LPCCACHE_INFO
Pointer version of CACHE_INFO.
struct sqlite3_stmt sqlite3_stmt
Forward declaration of sqlite3 statement handle.
static bool remove_file(const std::string &filename)
Remove (unlink) the file.
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.
sqlite3 * m_db_handle
SQLite handle of cache index database.
std::string m_filename
Name of SQLite cache index database.
virtual ~sqlite_t()
Free sqlite_t object.
sqlite_t(const std::string &filename, int flags, const char *zVfs=nullptr)
Construct sqlite_t object.
int m_ret
Return code of last SQL operation.
static Cache_Entry * create(Cache *owner, LPVIRTUALFILE virtualfile)
Create a new Cache_Entry object.
Cache_Entry * openio(LPVIRTUALFILE virtualfile)
Open cache entry.
static const TABLECOLUMNS_VEC m_columns_cache_entry
Columns of table "cache_entry".
bool prune_disk_space(size_t predicted_filesize)
Prune cache entries to ensure disk space.
bool delete_info(const std::string &filename, const std::string &desttype)
Delete cache file info.
bool delete_entry(Cache_Entry **cache_entry, int flags)
Delete cache entry object.
int cmp_version(int version_major_l, int version_minor_l, int version_major_r, int version_minor_r)
Compare two versions.
bool create_table_cache_entry(LPCTABLE_DEF table, const TABLECOLUMNS_VEC &columns)
Create cache_entry table.
bool clear()
Clear cache: deletes all entries.
cache_t m_cache
Cache file (memory mapped file)
bool prepare_stmts()
Prepare all SQL statements.
bool remove_cachefile(const std::string &filename, const std::string &fileext)
Remove a cache file from disk.
bool maintenance(size_t predicted_filesize=0)
Run disk maintenance.
Cache()
Construct Cache object.
std::vector< TABLE_COLUMNS > TABLECOLUMNS_VEC
Table columns array.
std::string expanded_sql(sqlite3_stmt *pStmt)
Get expanded SQL string for a statement.
TABLE_DEF const * LPCTABLE_DEF
Pointer version of TABLE_DEF.
bool load_index()
Load cache index from disk.
bool write_info(LPCCACHE_INFO cache_info)
Write cache file info.
std::unique_ptr< sqlite_t > m_cacheidx_db
SQLite handle of cache index database.
static const TABLECOLUMNS_VEC m_columns_version
Columns of table "version".
static const TABLE_DEF m_table_version
Definition and indexes of table "version".
bool rollback_transaction()
Rollback a database transaction.
void close_index()
Close cache index.
bool begin_transaction()
Begin a database transactio.n.
bool read_info(LPCACHE_INFO cache_info)
Read cache file info.
bool table_exists(const char *table)
Check if SQL table exists in database.
bool end_transaction()
End a database transaction.
bool upgrade_db(int *db_version_major, int *db_version_minor)
Upgrade database from version below 1.95.
bool prune_cache_size()
Prune cache entries to keep cache size within limit.
std::recursive_mutex m_mutex
Access mutex.
bool closeio(Cache_Entry **cache_entry, int flags=CACHE_CLOSE_NOOPT)
Close a cache entry.
Cache_Entry * create_entry(LPVIRTUALFILE virtualfile, const std::string &desttype)
Create cache entry object for a VIRTUALFILE.
bool column_exists(const char *table, const char *column)
Check if column exists in SQL table.
bool prune_expired()
Prune expired cache entries.
bool check_min_version(int *db_version_major, int *db_version_minor)
Check the db version if upgrade needed.
virtual ~Cache()
Destruct Cache object.
static const TABLE_DEF m_table_cache_entry
Definition and indexes of table "cache_entry".
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 mktree(const std::string &path, mode_t mode)
Make directory tree.
const std::string & append_filename(std::string *path, const std::string &filename)
Add filename to path, including / after the path if required.
size_t get_disk_free(std::string &path)
Get free disk space.
std::string format_time(time_t value)
Format a time in format "w d m s".
std::string format_size(uint64_t value)
Format size.
const std::string & strsprintf(std::string *str, const std::string &format, Args ... args)
Format a std::string sprintf-like.
FFMPEGFS_PARAMS params
FFmpegfs command line parameters.
Main include for FFmpegfs project.
void transcoder_cache_path(std::string *path)
Get transcoder cache path.
Provide various log facilities to stderr, disk or syslog.
uint32_t m_video_frame_count
Number of frames in video or 0 if not a video.
int64_t m_audiobitrate
Audio bitrate in bit/s.
size_t m_file_size
Source file file size.
time_t m_access_time
Source file last access time.
RESULTCODE m_result
Result code:
bool m_deinterlace
true if video was deinterlaced
int64_t m_duration
File duration, in AV_TIME_BASE fractional seconds.
uint32_t m_segment_count
Number of segments for HLS.
size_t m_encoded_filesize
Actual file size after encode.
int m_audiosamplerate
Audio sample rate in Hz.
bool m_error
true if encode failed
size_t m_predicted_filesize
Predicted file size.
std::string m_destfile
Destination filename after transcode.
int m_averror
FFmpeg error code if encode failed.
time_t m_file_time
Source file file time.
std::array< char, 11 > m_desttype
Destination type.
int m_videowidth
Video width.
int m_videoheight
Video height.
int64_t m_videobitrate
Video bitrate in bit/s.
int m_errno
errno if encode failed
time_t m_creation_time
Source file creation time.
Column definition of sql table.
const char * name
Table name.
time_t m_expiry_time
Time (seconds) after which an cache entry is deleted.
const FFmpegfs_Format * current_format(LPCVIRTUALFILE virtualfile) const
Get FFmpegfs_Format for a virtual file.
size_t m_max_cache_size
Max. cache size in MB. When exceeded, oldest entries will be pruned.
size_t m_min_diskspace
Min. diskspace required for cache.
std::string m_destfile
Name and path of destination file.