# FFmpegKit Linux API: FFmpegKitConfig.cpp Source File

FFmpegKitConfig.cpp
Go to the documentation of this file.
/*
* Copyright (c) 2022 Taner Sener
*
* This file is part of FFmpegKit.
*
* FFmpegKit is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FFmpegKit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <pthread.h>
extern "C" {
#include "libavutil/ffversion.h"
#include "libavutil/bprint.h"
#include "fftools_ffmpeg.h"
}
#include "ArchDetect.h"
#include "FFmpegKit.h"
#include "FFmpegKitConfig.h"
#include "FFmpegSession.h"
#include "FFprobeKit.h"
#include "FFprobeSession.h"
#include "Level.h"
#include "LogRedirectionStrategy.h"
#include "MediaInformationSession.h"
#include "Packages.h"
#include "SessionState.h"
#include <atomic>
#include <mutex>
#include <future>
#include <condition_variable>
#include <iostream>
#include <fstream>
#include <algorithm>
static std::atomic<long> pipeIndexGenerator(1);
/* Session history variables */
static int sessionHistorySize;
static std::map<long, std::shared_ptr<ffmpegkit::Session>> sessionHistoryMap;
static std::list<std::shared_ptr<ffmpegkit::Session>> sessionHistoryList;
static std::recursive_mutex sessionMutex;
#define SESSION_MAP_SIZE 1000
static std::atomic<short> sessionMap[SESSION_MAP_SIZE];
static std::atomic<int> sessionInTransitMessageCountMap[SESSION_MAP_SIZE];
static ffmpegkit::LogCallback logCallback;
static ffmpegkit::StatisticsCallback statisticsCallback;
static ffmpegkit::FFmpegSessionCompleteCallback ffmpegSessionCompleteCallback;
static ffmpegkit::FFprobeSessionCompleteCallback ffprobeSessionCompleteCallback;
static ffmpegkit::MediaInformationSessionCompleteCallback mediaInformationSessionCompleteCallback;
static ffmpegkit::LogRedirectionStrategy globalLogRedirectionStrategy;
static int redirectionEnabled;
static std::recursive_mutex callbackDataMutex;
static std::mutex callbackMutex;
static std::condition_variable callbackMonitor;
class CallbackData;
static std::list<CallbackData*> callbackDataList;
volatile int handleSIGQUIT = 1;
volatile int handleSIGINT = 1;
volatile int handleSIGTERM = 1;
volatile int handleSIGXCPU = 1;
volatile int handleSIGPIPE = 1;
__thread long globalSessionId = 0;
int configuredLogLevel = ffmpegkit::LevelAVLogInfo;
#ifdef __cplusplus
extern "C" {
#endif
int ffmpeg_execute(int argc, char **argv);
int ffprobe_execute(int argc, char **argv);
void ffmpegkit_log_callback_function(void *ptr, int level, const char* format, va_list vargs);
#ifdef __cplusplus
}
#endif
static std::once_flag ffmpegKitInitializerFlag;
static pthread_t callbackThread;
void* ffmpegKitInitialize();
const void* _ffmpegKitConfigInitializer{ffmpegKitInitialize()};
enum CallbackType {
LogType,
StatisticsType
};
static bool fs_exists(const std::string& s, const bool isFile, const bool isDirectory) {
struct stat dir_info;
if (stat(s.c_str(), &dir_info) == 0) {
if (isFile && S_ISREG(dir_info.st_mode)) {
return true;
}
if (isDirectory && S_ISDIR(dir_info.st_mode)) {
return true;
}
}
return false;
}
static bool fs_create_dir(const std::string& s) {
if (!fs_exists(s, false, true)) {
if (mkdir(s.c_str(), S_IRWXU | S_IRWXG | S_IROTH) != 0) {
std::cout << "Failed to create directory: " << s << ". Operation failed with " << errno << "." << std::endl;
return false;
}
}
return true;
}
void deleteExpiredSessions() {
while (sessionHistoryList.size() > sessionHistorySize) {
auto first = sessionHistoryList.front();
if (first != nullptr) {
sessionHistoryList.pop_front();
sessionHistoryMap.erase(first->getSessionId());
}
}
}
void addSessionToSessionHistory(const std::shared_ptr<ffmpegkit::Session> session) {
std::unique_lock<std::recursive_mutex> lock(sessionMutex, std::defer_lock);
const long sessionId = session->getSessionId();
lock.lock();
/*
* ASYNC SESSIONS CALL THIS METHOD TWICE
* THIS CHECK PREVENTS ADDING THE SAME SESSION AGAIN
*/
if (sessionHistoryMap.count(sessionId) == 0) {
sessionHistoryMap.insert({sessionId, session});
sessionHistoryList.push_back(session);
deleteExpiredSessions();
}
lock.unlock();
}
class CallbackData {
public:
CallbackData(const long sessionId, const int logLevel, const AVBPrint* data) :
_type{LogType}, _sessionId{sessionId}, _logLevel{logLevel} {
av_bprint_init(&_logData, 0, AV_BPRINT_SIZE_UNLIMITED);
av_bprintf(&_logData, "%s", data->str);
}
CallbackData(const long sessionId,
const int videoFrameNumber,
const float videoFps,
const float videoQuality,
const int64_t size,
const int time,
const double bitrate,
const double speed) :
_type{StatisticsType},
_sessionId{sessionId},
_statisticsFrameNumber{videoFrameNumber},
_statisticsFps{videoFps},
_statisticsQuality{videoQuality},
_statisticsSize{size},
_statisticsTime{time},
_statisticsBitrate{bitrate},
_statisticsSpeed{speed} {
}
CallbackType getType() {
return _type;
}
long getSessionId() {
return _sessionId;
}
int getLogLevel() {
return _logLevel;
}
AVBPrint* getLogData() {
return &_logData;
}
int getStatisticsFrameNumber() {
return _statisticsFrameNumber;
}
float getStatisticsFps() {
return _statisticsFps;
}
float getStatisticsQuality() {
return _statisticsQuality;
}
int64_t getStatisticsSize() {
return _statisticsSize;
}
int getStatisticsTime() {
return _statisticsTime;
}
double getStatisticsBitrate() {
return _statisticsBitrate;
}
double getStatisticsSpeed() {
return _statisticsSpeed;
}
private:
CallbackType _type;
long _sessionId; // session id
int _logLevel; // log level
AVBPrint _logData; // log data
int _statisticsFrameNumber; // statistics frame number
float _statisticsFps; // statistics fps
float _statisticsQuality; // statistics quality
int64_t _statisticsSize; // statistics size
int _statisticsTime; // statistics time
double _statisticsBitrate; // statistics bitrate
double _statisticsSpeed; // statistics speed
};
static void callbackWait(int milliSeconds) {
std::unique_lock<std::mutex> callbackLock{callbackMutex};
callbackMonitor.wait_for(callbackLock, std::chrono::milliseconds(milliSeconds));
}
static void callbackNotify() {
callbackMonitor.notify_one();
}
static const char *avutil_log_get_level_str(int level) {
switch (level) {
case AV_LOG_STDERR:
return "stderr";
case AV_LOG_QUIET:
return "quiet";
case AV_LOG_DEBUG:
return "debug";
case AV_LOG_VERBOSE:
return "verbose";
case AV_LOG_INFO:
return "info";
case AV_LOG_WARNING:
return "warning";
case AV_LOG_ERROR:
return "error";
case AV_LOG_FATAL:
return "fatal";
case AV_LOG_PANIC:
return "panic";
default:
return "";
}
}
static void avutil_log_format_line(void *avcl, int level, const char *fmt, va_list vl, AVBPrint part[4], int *print_prefix) {
int flags = av_log_get_flags();
AVClass* avc = avcl ? *(AVClass **) avcl : NULL;
av_bprint_init(part+0, 0, 1);
av_bprint_init(part+1, 0, 1);
av_bprint_init(part+2, 0, 1);
av_bprint_init(part+3, 0, 65536);
if (*print_prefix && avc) {
if (avc->parent_log_context_offset) {
AVClass** parent = *(AVClass ***) (((uint8_t *) avcl) +
avc->parent_log_context_offset);
if (parent && *parent) {
av_bprintf(part+0, "[%s @ %p] ",
(*parent)->item_name(parent), parent);
}
}
av_bprintf(part+1, "[%s @ %p] ",
avc->item_name(avcl), avcl);
}
if (*print_prefix && (level > AV_LOG_QUIET) && (flags & AV_LOG_PRINT_LEVEL))
av_bprintf(part+2, "[%s] ", avutil_log_get_level_str(level));
av_vbprintf(part+3, fmt, vl);
if(*part[0].str || *part[1].str || *part[2].str || *part[3].str) {
char lastc = part[3].len && part[3].len <= part[3].size ? part[3].str[part[3].len - 1] : 0;
*print_prefix = lastc == '\n' || lastc == '\r';
}
}
static void avutil_log_sanitize(char *line) {
while(*line){
if(*line < 0x08 || (*line > 0x0D && *line < 0x20))
*line='?';
line++;
}
}
static void logCallbackDataAdd(int level, AVBPrint *data) {
std::unique_lock<std::recursive_mutex> lock(callbackDataMutex, std::defer_lock);
CallbackData* callbackData = new CallbackData(globalSessionId, level, data);
lock.lock();
callbackDataList.push_back(callbackData);
lock.unlock();
callbackNotify();
std::atomic_fetch_add(&sessionInTransitMessageCountMap[globalSessionId % SESSION_MAP_SIZE], 1);
}
static void statisticsCallbackDataAdd(int frameNumber, float fps, float quality, int64_t size, int time, double bitrate, double speed) {
std::unique_lock<std::recursive_mutex> lock(callbackDataMutex, std::defer_lock);
CallbackData* callbackData = new CallbackData(globalSessionId, frameNumber, fps, quality, size, time, bitrate, speed);
lock.lock();
callbackDataList.push_back(callbackData);
lock.unlock();
callbackNotify();
std::atomic_fetch_add(&sessionInTransitMessageCountMap[globalSessionId % SESSION_MAP_SIZE], 1);
}
static CallbackData *callbackDataRemove() {
std::unique_lock<std::recursive_mutex> lock(callbackDataMutex, std::defer_lock);
CallbackData* newData = nullptr;
lock.lock();
if (callbackDataList.size() > 0) {
newData = callbackDataList.front();
callbackDataList.pop_front();
}
lock.unlock();
return newData;
}
static void registerSessionId(long sessionId) {
std::atomic_store(&sessionMap[sessionId % SESSION_MAP_SIZE], (short)1);
}
static void removeSession(long sessionId) {
std::atomic_store(&sessionMap[sessionId % SESSION_MAP_SIZE], (short)0);
}
#ifdef __cplusplus
extern "C" {
#endif
void cancelSession(long sessionId) {
std::atomic_store(&sessionMap[sessionId % SESSION_MAP_SIZE], (short)2);
}
int cancelRequested(long sessionId) {
if (std::atomic_load(&sessionMap[sessionId % SESSION_MAP_SIZE]) == 2) {
return 1;
} else {
return 0;
}
}
#ifdef __cplusplus
}
#endif
static void resetMessagesInTransmit(long sessionId) {
std::atomic_store(&sessionInTransitMessageCountMap[sessionId % SESSION_MAP_SIZE], 0);
}
void ffmpegkit_log_callback_function(void *ptr, int level, const char* format, va_list vargs) {
AVBPrint fullLine;
AVBPrint part[4];
int print_prefix = 1;
// DO NOT PROCESS UNWANTED LOGS
if (level >= 0) {
level &= 0xff;
}
int activeLogLevel = av_log_get_level();
// LevelAVLogStdErr logs are always redirected
if ((activeLogLevel == ffmpegkit::LevelAVLogQuiet && level != ffmpegkit::LevelAVLogStdErr) || (level > activeLogLevel)) {
return;
}
av_bprint_init(&fullLine, 0, AV_BPRINT_SIZE_UNLIMITED);
avutil_log_format_line(ptr, level, format, vargs, part, &print_prefix);
avutil_log_sanitize(part[0].str);
avutil_log_sanitize(part[1].str);
avutil_log_sanitize(part[2].str);
avutil_log_sanitize(part[3].str);
// COMBINE ALL 4 LOG PARTS
av_bprintf(&fullLine, "%s%s%s%s", part[0].str, part[1].str, part[2].str, part[3].str);
if (fullLine.len > 0) {
logCallbackDataAdd(level, &fullLine);
}
av_bprint_finalize(part, NULL);
av_bprint_finalize(part+1, NULL);
av_bprint_finalize(part+2, NULL);
av_bprint_finalize(part+3, NULL);
av_bprint_finalize(&fullLine, NULL);
}
void ffmpegkit_statistics_callback_function(int frameNumber, float fps, float quality, int64_t size, int time, double bitrate, double speed) {
statisticsCallbackDataAdd(frameNumber, fps, quality, size, time, bitrate, speed);
}
static void process_log(long sessionId, int levelValueInt, AVBPrint* logMessage) {
int activeLogLevel = av_log_get_level();
ffmpegkit::Level levelValue = static_cast< ffmpegkit::Level >(levelValueInt);
std::shared_ptr<ffmpegkit::Log> log = std::make_shared<ffmpegkit::Log>(sessionId, levelValue, logMessage->str);
bool globalCallbackDefined = false;
bool sessionCallbackDefined = false;
ffmpegkit::LogRedirectionStrategy activeLogRedirectionStrategy = globalLogRedirectionStrategy;
// LevelAVLogStdErr logs are always redirected
if ((activeLogLevel == ffmpegkit::LevelAVLogQuiet && levelValue != ffmpegkit::LevelAVLogStdErr) || (levelValue > activeLogLevel)) {
// LOG NEITHER PRINTED NOR FORWARDED
return;
}
auto session = ffmpegkit::FFmpegKitConfig::getSession(sessionId);
if (session != nullptr) {
activeLogRedirectionStrategy = session->getLogRedirectionStrategy();
session->addLog(log);
ffmpegkit::LogCallback sessionLogCallback = session->getLogCallback();
if (sessionLogCallback != nullptr) {
sessionCallbackDefined = true;
try {
// NOTIFY SESSION CALLBACK DEFINED
sessionLogCallback(log);
} catch(const std::exception& exception) {
std::cout << "Exception thrown inside session log callback. " << exception.what() << std::endl;
}
}
}
ffmpegkit::LogCallback globalLogCallback = logCallback;
if (globalLogCallback != nullptr) {
globalCallbackDefined = true;
try {
// NOTIFY GLOBAL CALLBACK DEFINED
globalLogCallback(log);
} catch(const std::exception& exception) {
std::cout << "Exception thrown inside global log callback. " << exception.what() << std::endl;
}
}
// EXECUTE THE LOG STRATEGY
switch (activeLogRedirectionStrategy) {
case ffmpegkit::LogRedirectionStrategyNeverPrintLogs: {
return;
}
case ffmpegkit::LogRedirectionStrategyPrintLogsWhenGlobalCallbackNotDefined: {
if (globalCallbackDefined) {
return;
}
}
break;
case ffmpegkit::LogRedirectionStrategyPrintLogsWhenSessionCallbackNotDefined: {
if (sessionCallbackDefined) {
return;
}
}
break;
case ffmpegkit::LogRedirectionStrategyPrintLogsWhenNoCallbacksDefined: {
if (globalCallbackDefined || sessionCallbackDefined) {
return;
}
}
break;
case ffmpegkit::LogRedirectionStrategyAlwaysPrintLogs: {
}
break;
}
// PRINT LOGS
switch (levelValue) {
case ffmpegkit::LevelAVLogQuiet:
// PRINT NO OUTPUT
break;
default:
// WRITE TO STDOUT
std::cout << ffmpegkit::FFmpegKitConfig::logLevelToString(levelValue) << ": " << logMessage->str;
break;
}
}
void process_statistics(long sessionId, int videoFrameNumber, float videoFps, float videoQuality, long size, int time, double bitrate, double speed) {
std::shared_ptr<ffmpegkit::Statistics> statistics = std::make_shared<ffmpegkit::Statistics>(sessionId, videoFrameNumber, videoFps, videoQuality, size, time, bitrate, speed);
auto session = ffmpegkit::FFmpegKitConfig::getSession(sessionId);
if (session != nullptr && session->isFFmpeg()) {
std::shared_ptr<ffmpegkit::FFmpegSession> ffmpegSession = std::static_pointer_cast<ffmpegkit::FFmpegSession>(session);
ffmpegSession->addStatistics(statistics);
ffmpegkit::StatisticsCallback sessionStatisticsCallback = ffmpegSession->getStatisticsCallback();
if (sessionStatisticsCallback != nullptr) {
try {
sessionStatisticsCallback(statistics);
} catch(const std::exception& exception) {
std::cout << "Exception thrown inside session statistics callback. " << exception.what() << std::endl;
}
}
}
ffmpegkit::StatisticsCallback globalStatisticsCallback = statisticsCallback;
if (globalStatisticsCallback != nullptr) {
try {
globalStatisticsCallback(statistics);
} catch(const std::exception& exception) {
std::cout << "Exception thrown inside global statistics callback. " << exception.what() << std::endl;
}
}
}
void *callbackThreadFunction(void *pointer) {
int activeLogLevel = av_log_get_level();
if ((activeLogLevel != ffmpegkit::LevelAVLogQuiet) && (ffmpegkit::LevelAVLogDebug <= activeLogLevel)) {
std::cout << "Async callback block started." << std::endl;
}
while(redirectionEnabled) {
try {
CallbackData* callbackData = callbackDataRemove();
if (callbackData != nullptr) {
if (callbackData->getType() == LogType) {
process_log(callbackData->getSessionId(), callbackData->getLogLevel(), callbackData->getLogData());
av_bprint_finalize(callbackData->getLogData(), NULL);
} else {
process_statistics(callbackData->getSessionId(),
callbackData->getStatisticsFrameNumber(),
callbackData->getStatisticsFps(),
callbackData->getStatisticsQuality(),
callbackData->getStatisticsSize(),
callbackData->getStatisticsTime(),
callbackData->getStatisticsBitrate(),
callbackData->getStatisticsSpeed());
}
std::atomic_fetch_sub(&sessionInTransitMessageCountMap[callbackData->getSessionId() % SESSION_MAP_SIZE], 1);
} else {
callbackWait(100);
}
} catch(const std::exception& exception) {
activeLogLevel = av_log_get_level();
if ((activeLogLevel != ffmpegkit::LevelAVLogQuiet) && (ffmpegkit::LevelAVLogWarning <= activeLogLevel)) {
std::cout << "Async callback block received error: " << exception.what() << std::endl;
}
}
}
activeLogLevel = av_log_get_level();
if ((activeLogLevel != ffmpegkit::LevelAVLogQuiet) && (ffmpegkit::LevelAVLogDebug <= activeLogLevel)) {
std::cout << "Async callback block stopped." << std::endl;
}
return NULL;
}
static int executeFFmpeg(const long sessionId, const std::shared_ptr<std::list<std::string>> arguments) {
const char* LIB_NAME = "ffmpeg";
// SETS DEFAULT LOG LEVEL BEFORE STARTING A NEW RUN
av_log_set_level(configuredLogLevel);
char **commandCharPArray = (char **)av_malloc(sizeof(char*) * (arguments->size() + 1));
/* PRESERVE USAGE FORMAT
*
* ffmpeg <arguments>
*/
commandCharPArray[0] = (char *)av_malloc(sizeof(char) * (strlen(LIB_NAME) + 1));
strcpy(commandCharPArray[0], LIB_NAME);
// PREPARE ARRAY ELEMENTS
int i = 0;
for (auto it=arguments->begin(); it != arguments->end(); it++, i++) {
commandCharPArray[i + 1] = (char*)it->c_str();
}
// REGISTER THE ID BEFORE STARTING THE SESSION
globalSessionId = sessionId;
registerSessionId(sessionId);
resetMessagesInTransmit(sessionId);
// RUN
int returnCode = ffmpeg_execute((arguments->size() + 1), commandCharPArray);
// ALWAYS REMOVE THE ID FROM THE MAP
removeSession(sessionId);
// CLEANUP
av_free(commandCharPArray[0]);
av_free(commandCharPArray);
return returnCode;
}
int executeFFprobe(const long sessionId, const std::shared_ptr<std::list<std::string>> arguments) {
const char* LIB_NAME = "ffprobe";
// SETS DEFAULT LOG LEVEL BEFORE STARTING A NEW RUN
av_log_set_level(configuredLogLevel);
char **commandCharPArray = (char **)av_malloc(sizeof(char*) * (arguments->size() + 1));
/* PRESERVE USAGE FORMAT
*
* ffprobe <arguments>
*/
commandCharPArray[0] = (char *)av_malloc(sizeof(char) * (strlen(LIB_NAME) + 1));
strcpy(commandCharPArray[0], LIB_NAME);
// PREPARE ARRAY ELEMENTS
int i = 0;
for (auto it=arguments->begin(); it != arguments->end(); it++, i++) {
commandCharPArray[i + 1] = (char*)it->c_str();
}
// REGISTER THE ID BEFORE STARTING THE SESSION
globalSessionId = sessionId;
registerSessionId(sessionId);
resetMessagesInTransmit(sessionId);
// RUN
int returnCode = ffprobe_execute((arguments->size() + 1), commandCharPArray);
// ALWAYS REMOVE THE ID FROM THE MAP
removeSession(sessionId);
// CLEANUP
av_free(commandCharPArray[0]);
av_free(commandCharPArray);
return returnCode;
}
void* ffmpegKitInitialize() {
std::call_once(ffmpegKitInitializerFlag, [](){
std::cout << "Loading ffmpeg-kit." << std::endl;
sessionHistorySize = 10;
for(int i = 0; i<SESSION_MAP_SIZE; i++) {
std::atomic_init(&sessionMap[i], (short)0);
std::atomic_init(&sessionInTransitMessageCountMap[i], 0);
}
logCallback = nullptr;
statisticsCallback = nullptr;
ffmpegSessionCompleteCallback = nullptr;
ffprobeSessionCompleteCallback = nullptr;
mediaInformationSessionCompleteCallback = nullptr;
globalLogRedirectionStrategy = ffmpegkit::LogRedirectionStrategyPrintLogsWhenNoCallbacksDefined;
redirectionEnabled = 0;
ffmpegkit::FFmpegKitConfig::enableRedirection();
std::cout << "Loaded ffmpeg-kit-" << ffmpegkit::Packages::getPackageName() << "-" << ffmpegkit::ArchDetect::getArch() << "-" << ffmpegkit::FFmpegKitConfig::getVersion() << "-" << ffmpegkit::FFmpegKitConfig::getBuildDate() << "." << std::endl;
});
return NULL;
}
void ffmpegkit::FFmpegKitConfig::enableRedirection() {
std::unique_lock<std::recursive_mutex> lock(callbackDataMutex, std::defer_lock);
lock.lock();
if (redirectionEnabled != 0) {
lock.unlock();
return;
}
redirectionEnabled = 1;
lock.unlock();
int rc = pthread_create(&callbackThread, NULL, callbackThreadFunction, NULL);
if (rc != 0) {
std::cout << "Failed to create async callback block: %d" << rc << std::endl;
lock.unlock();
return;
}
av_log_set_callback(ffmpegkit_log_callback_function);
set_report_callback(ffmpegkit_statistics_callback_function);
}
void ffmpegkit::FFmpegKitConfig::disableRedirection() {
std::unique_lock<std::recursive_mutex> lock(callbackDataMutex, std::defer_lock);
lock.lock();
if (redirectionEnabled != 1) {
lock.unlock();
return;
}
redirectionEnabled = 0;
lock.unlock();
callbackNotify();
pthread_detach(callbackThread);
av_log_set_callback(av_log_default_callback);
set_report_callback(NULL);
}
int ffmpegkit::FFmpegKitConfig::setFontconfigConfigurationPath(const std::string& path) {
return ffmpegkit::FFmpegKitConfig::setEnvironmentVariable("FONTCONFIG_PATH", path);
}
void ffmpegkit::FFmpegKitConfig::setFontDirectory(const std::string& fontDirectoryPath, const std::map<std::string,std::string>& fontNameMapping) {
ffmpegkit::FFmpegKitConfig::setFontDirectoryList(std::list<std::string>{fontDirectoryPath}, fontNameMapping);
}
void ffmpegkit::FFmpegKitConfig::setFontDirectoryList(const std::list<std::string>& fontDirectoryList, const std::map<std::string,std::string>& fontNameMapping) {
int validFontNameMappingCount = 0;
const char *parentDirectory = std::getenv("HOME");
if (parentDirectory == NULL) {
parentDirectory = std::getenv("TMPDIR");
if (parentDirectory == NULL) {
parentDirectory = ".";
}
}
std::string cacheDir = std::string(parentDirectory) + "/.cache";
std::string ffmpegKitDir = cacheDir + "/ffmpegkit";
auto tempConfigurationDirectory = ffmpegKitDir + "/fontconfig";
auto fontConfigurationFile = std::string(tempConfigurationDirectory) + "/fonts.conf";
if (!fs_create_dir(cacheDir) || !fs_create_dir(ffmpegKitDir) || !fs_create_dir(tempConfigurationDirectory)) {
return;
}
std::cout << "Created temporary font conf directory: TRUE." << std::endl;
if (fs_exists(fontConfigurationFile, true, false)) {
bool fontConfigurationDeleted = std::remove(fontConfigurationFile.c_str());
std::cout << "Deleted old temporary font configuration: " << (fontConfigurationDeleted == 0?"TRUE":"FALSE") << "." << std::endl;
}
/* PROCESS MAPPINGS FIRST */
std::string fontNameMappingBlock = "";
for (auto const& pair : fontNameMapping) {
if ((pair.first.size() > 0) && (pair.second.size() > 0)) {
fontNameMappingBlock += " <match target=\"pattern\">\n";
fontNameMappingBlock += " <test qual=\"any\" name=\"family\">\n";
fontNameMappingBlock += " <string>";
fontNameMappingBlock += pair.first;
fontNameMappingBlock += "</string>\n";
fontNameMappingBlock += " </test>\n";
fontNameMappingBlock += " <edit name=\"family\" mode=\"assign\" binding=\"same\">\n";
fontNameMappingBlock += " <string>";
fontNameMappingBlock += pair.second;
fontNameMappingBlock += "</string>\n";
fontNameMappingBlock += " </edit>\n";
fontNameMappingBlock += " </match>\n";
validFontNameMappingCount++;
}
}
std::string fontConfiguration;
fontConfiguration += "<?xml version=\"1.0\"?>\n";
fontConfiguration += "<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n";
fontConfiguration += "<fontconfig>\n";
fontConfiguration += " <dir prefix=\"cwd\">.</dir>\n";
for (const auto& fontDirectoryPath : fontDirectoryList) {
fontConfiguration += " <dir>";
fontConfiguration += fontDirectoryPath;
fontConfiguration += "</dir>\n";
}
fontConfiguration += fontNameMappingBlock;
fontConfiguration += "</fontconfig>\n";
std::ofstream fontConfigurationStream(fontConfigurationFile, std::ios::out | std::ios::trunc);
if (fontConfigurationStream) {
fontConfigurationStream << fontConfiguration;
}
if (fontConfigurationStream.bad()) {
std::cout << "Failed to set font directory. Error received while saving font configuration: " << fontConfigurationStream.rdbuf() << "." << std::endl;
}
fontConfigurationStream.close();
std::cout << "Saved new temporary font configuration with " << validFontNameMappingCount << " font name mappings." << std::endl;
ffmpegkit::FFmpegKitConfig::setFontconfigConfigurationPath(tempConfigurationDirectory.c_str());
for (const auto& fontDirectoryPath : fontDirectoryList) {
std::cout << "Font directory " << fontDirectoryPath << " registered successfully." << std::endl;
}
}
std::shared_ptr<std::string> ffmpegkit::FFmpegKitConfig::registerNewFFmpegPipe() {
const char *parentDirectory = std::getenv("HOME");
if (parentDirectory == NULL) {
parentDirectory = std::getenv("TMPDIR");
if (parentDirectory == NULL) {
parentDirectory = ".";
}
}
// PIPES ARE CREATED UNDER THE PIPES DIRECTORY
std::string cacheDir = std::string(parentDirectory) + "/.cache";
std::string ffmpegKitDir = cacheDir + "/ffmpegkit";
std::string pipesDir = ffmpegKitDir + "/pipes";
if (!fs_create_dir(cacheDir) || !fs_create_dir(ffmpegKitDir) || !fs_create_dir(pipesDir)) {
return nullptr;
}
std::shared_ptr<std::string> newFFmpegPipePath = std::make_shared<std::string>(pipesDir + "/" + FFmpegKitNamedPipePrefix + std::to_string(pipeIndexGenerator++));
// FIRST CLOSE OLD PIPES WITH THE SAME NAME
ffmpegkit::FFmpegKitConfig::closeFFmpegPipe(newFFmpegPipePath->c_str());
int rc = mkfifo(newFFmpegPipePath->c_str(), S_IRWXU | S_IRWXG | S_IROTH);
if (rc == 0) {
return newFFmpegPipePath;
} else {
std::cout << "Failed to register new FFmpeg pipe " << newFFmpegPipePath << ". Operation failed with rc=" << rc << "." << std::endl;
return nullptr;
}
}
void ffmpegkit::FFmpegKitConfig::closeFFmpegPipe(const std::string& ffmpegPipePath) {
std::remove(ffmpegPipePath.c_str());
}
std::string ffmpegkit::FFmpegKitConfig::getFFmpegVersion() {
return FFMPEG_VERSION;
}
std::string ffmpegkit::FFmpegKitConfig::getVersion() {
if (FFmpegKitConfig::isLTSBuild()) {
return std::string("").append(FFmpegKitVersion).append("-lts");
} else {
return FFmpegKitVersion;
}
}
bool ffmpegkit::FFmpegKitConfig::isLTSBuild() {
#if defined(FFMPEG_KIT_LTS)
return true;
#else
return false;
#endif
}
std::string ffmpegkit::FFmpegKitConfig::getBuildDate() {
char buildDate[10];
sprintf(buildDate, "%d", FFMPEG_KIT_BUILD_DATE);
return std::string(buildDate);
}
int ffmpegkit::FFmpegKitConfig::setEnvironmentVariable(const std::string& variableName, const std::string& variableValue) {
return setenv(variableName.c_str(), variableValue.c_str(), true);
}
void ffmpegkit::FFmpegKitConfig::ignoreSignal(const ffmpegkit::Signal signal) {
if (signal == ffmpegkit::SignalQuit) {
handleSIGQUIT = 0;
} else if (signal == ffmpegkit::SignalInt) {
handleSIGINT = 0;
} else if (signal == ffmpegkit::SignalTerm) {
handleSIGTERM = 0;
} else if (signal == ffmpegkit::SignalXcpu) {
handleSIGXCPU = 0;
} else if (signal == ffmpegkit::SignalPipe) {
handleSIGPIPE = 0;
}
}
void ffmpegkit::FFmpegKitConfig::ffmpegExecute(const std::shared_ptr<ffmpegkit::FFmpegSession> ffmpegSession) {
ffmpegSession->startRunning();
try {
int returnCode = executeFFmpeg(ffmpegSession->getSessionId(), ffmpegSession->getArguments());
ffmpegSession->complete(std::make_shared<ffmpegkit::ReturnCode>(returnCode));
} catch(const std::exception& exception) {
ffmpegSession->fail(exception.what());
std::cout << "FFmpeg execute failed: " << ffmpegkit::FFmpegKitConfig::argumentsToString(ffmpegSession->getArguments()) << "." << exception.what() << std::endl;
}
}
void ffmpegkit::FFmpegKitConfig::ffprobeExecute(const std::shared_ptr<ffmpegkit::FFprobeSession> ffprobeSession) {
ffprobeSession->startRunning();
try {
int returnCode = executeFFprobe(ffprobeSession->getSessionId(), ffprobeSession->getArguments());
ffprobeSession->complete(std::make_shared<ffmpegkit::ReturnCode>(returnCode));
} catch(const std::exception& exception) {
ffprobeSession->fail(exception.what());
std::cout << "FFprobe execute failed: " << ffmpegkit::FFmpegKitConfig::argumentsToString(ffprobeSession->getArguments()) << "." << exception.what() << std::endl;
}
}
void ffmpegkit::FFmpegKitConfig::getMediaInformationExecute(const std::shared_ptr<ffmpegkit::MediaInformationSession> mediaInformationSession, const int waitTimeout) {
mediaInformationSession->startRunning();
try {
int returnCodeValue = executeFFprobe(mediaInformationSession->getSessionId(), mediaInformationSession->getArguments());
auto returnCode = std::make_shared<ffmpegkit::ReturnCode>(returnCodeValue);
mediaInformationSession->complete(returnCode);
if (returnCode->isValueSuccess()) {
auto allLogs = mediaInformationSession->getAllLogsWithTimeout(waitTimeout);
std::string ffprobeJsonOutput;
std::for_each(allLogs->cbegin(), allLogs->cend(), [&](std::shared_ptr<ffmpegkit::Log> log) {
if (log->getLevel() == LevelAVLogStdErr) {
ffprobeJsonOutput.append(log->getMessage());
}
});
auto mediaInformation = ffmpegkit::MediaInformationJsonParser::fromWithError(ffprobeJsonOutput.c_str());
mediaInformationSession->setMediaInformation(mediaInformation);
}
} catch(const std::exception& exception) {
mediaInformationSession->fail(exception.what());
std::cout << "Get media information execute failed: " << ffmpegkit::FFmpegKitConfig::argumentsToString(mediaInformationSession->getArguments()) << "." << exception.what() << std::endl;
}
}
void ffmpegkit::FFmpegKitConfig::asyncFFmpegExecute(const std::shared_ptr<ffmpegkit::FFmpegSession> ffmpegSession) {
auto thread = std::thread([ffmpegSession]() {
ffmpegkit::FFmpegKitConfig::ffmpegExecute(ffmpegSession);
ffmpegkit::FFmpegSessionCompleteCallback completeCallback = ffmpegSession->getCompleteCallback();
if (completeCallback != nullptr) {
try {
// NOTIFY SESSION CALLBACK DEFINED
completeCallback(ffmpegSession);
} catch(const std::exception& exception) {
std::cout << "Exception thrown inside session complete callback. " << exception.what() << std::endl;
}
}
ffmpegkit::FFmpegSessionCompleteCallback globalFFmpegSessionCompleteCallback = ffmpegkit::FFmpegKitConfig::getFFmpegSessionCompleteCallback();
if (globalFFmpegSessionCompleteCallback != nullptr) {
try {
// NOTIFY SESSION CALLBACK DEFINED
globalFFmpegSessionCompleteCallback(ffmpegSession);
} catch(const std::exception& exception) {
std::cout << "Exception thrown inside global complete callback. " << exception.what() << std::endl;
}
}
});
thread.detach();
}
void ffmpegkit::FFmpegKitConfig::asyncFFprobeExecute(const std::shared_ptr<ffmpegkit::FFprobeSession> ffprobeSession) {
auto thread = std::thread([ffprobeSession]() {
ffmpegkit::FFmpegKitConfig::ffprobeExecute(ffprobeSession);
ffmpegkit::FFprobeSessionCompleteCallback completeCallback = ffprobeSession->getCompleteCallback();
if (completeCallback != nullptr) {
try {
// NOTIFY SESSION CALLBACK DEFINED
completeCallback(ffprobeSession);
} catch(const std::exception& exception) {
std::cout << "Exception thrown inside session complete callback. " << exception.what() << std::endl;
}
}
ffmpegkit::FFprobeSessionCompleteCallback globalFFprobeSessionCompleteCallback = ffmpegkit::FFmpegKitConfig::getFFprobeSessionCompleteCallback();
if (globalFFprobeSessionCompleteCallback != nullptr) {
try {
// NOTIFY SESSION CALLBACK DEFINED
globalFFprobeSessionCompleteCallback(ffprobeSession);
} catch(const std::exception& exception) {
std::cout << "Exception thrown inside global complete callback. " << exception.what() << std::endl;
}
}
});
thread.detach();
}
void ffmpegkit::FFmpegKitConfig::asyncGetMediaInformationExecute(const std::shared_ptr<ffmpegkit::MediaInformationSession> mediaInformationSession, const int waitTimeout) {
auto thread = std::thread([mediaInformationSession,waitTimeout]() {
ffmpegkit::FFmpegKitConfig::getMediaInformationExecute(mediaInformationSession, waitTimeout);
ffmpegkit::MediaInformationSessionCompleteCallback completeCallback = mediaInformationSession->getCompleteCallback();
if (completeCallback != nullptr) {
try {
// NOTIFY SESSION CALLBACK DEFINED
completeCallback(mediaInformationSession);
} catch(const std::exception& exception) {
std::cout << "Exception thrown inside session complete callback. " << exception.what() << std::endl;
}
}
ffmpegkit::MediaInformationSessionCompleteCallback globalMediaInformationSessionCompleteCallback = ffmpegkit::FFmpegKitConfig::getMediaInformationSessionCompleteCallback();
if (globalMediaInformationSessionCompleteCallback != nullptr) {
try {
// NOTIFY SESSION CALLBACK DEFINED
globalMediaInformationSessionCompleteCallback(mediaInformationSession);
} catch(const std::exception& exception) {
std::cout << "Exception thrown inside global complete callback. " << exception.what() << std::endl;
}
}
});
thread.detach();
}
void ffmpegkit::FFmpegKitConfig::enableLogCallback(const ffmpegkit::LogCallback callback) {
logCallback = callback;
}
void ffmpegkit::FFmpegKitConfig::enableStatisticsCallback(const ffmpegkit::StatisticsCallback callback) {
statisticsCallback = callback;
}
void ffmpegkit::FFmpegKitConfig::enableFFmpegSessionCompleteCallback(const FFmpegSessionCompleteCallback completeCallback) {
ffmpegSessionCompleteCallback = completeCallback;
}
ffmpegkit::FFmpegSessionCompleteCallback ffmpegkit::FFmpegKitConfig::getFFmpegSessionCompleteCallback() {
return ffmpegSessionCompleteCallback;
}
void ffmpegkit::FFmpegKitConfig::enableFFprobeSessionCompleteCallback(const FFprobeSessionCompleteCallback completeCallback) {
ffprobeSessionCompleteCallback = completeCallback;
}
ffmpegkit::FFprobeSessionCompleteCallback ffmpegkit::FFmpegKitConfig::getFFprobeSessionCompleteCallback() {
return ffprobeSessionCompleteCallback;
}
void ffmpegkit::FFmpegKitConfig::enableMediaInformationSessionCompleteCallback(const MediaInformationSessionCompleteCallback completeCallback) {
mediaInformationSessionCompleteCallback = completeCallback;
}
ffmpegkit::MediaInformationSessionCompleteCallback ffmpegkit::FFmpegKitConfig::getMediaInformationSessionCompleteCallback() {
return mediaInformationSessionCompleteCallback;
}
ffmpegkit::Level ffmpegkit::FFmpegKitConfig::getLogLevel() {
return static_cast< ffmpegkit::Level >(configuredLogLevel);
}
void ffmpegkit::FFmpegKitConfig::setLogLevel(const ffmpegkit::Level level) {
configuredLogLevel = level;
}
std::string ffmpegkit::FFmpegKitConfig::logLevelToString(const ffmpegkit::Level level) {
switch (level) {
case ffmpegkit::LevelAVLogStdErr: return "STDERR";
case ffmpegkit::LevelAVLogTrace: return "TRACE";
case ffmpegkit::LevelAVLogDebug: return "DEBUG";
case ffmpegkit::LevelAVLogVerbose: return "VERBOSE";
case ffmpegkit::LevelAVLogInfo: return "INFO";
case ffmpegkit::LevelAVLogWarning: return "WARNING";
case ffmpegkit::LevelAVLogError: return "ERROR";
case ffmpegkit::LevelAVLogFatal: return "FATAL";
case ffmpegkit::LevelAVLogPanic: return "PANIC";
case ffmpegkit::LevelAVLogQuiet: return "QUIET";
default: return "";
}
}
int ffmpegkit::FFmpegKitConfig::getSessionHistorySize() {
return sessionHistorySize;
}
void ffmpegkit::FFmpegKitConfig::setSessionHistorySize(const int newSessionHistorySize) {
if (newSessionHistorySize >= SESSION_MAP_SIZE) {
/*
* THERE IS A HARD LIMIT ON THE NATIVE SIDE. HISTORY SIZE MUST BE SMALLER THAN SESSION_MAP_SIZE
*/
throw std::runtime_error("Session history size must not exceed the hard limit!");
} else if (newSessionHistorySize > 0) {
sessionHistorySize = newSessionHistorySize;
deleteExpiredSessions();
}
}
std::shared_ptr<ffmpegkit::Session> ffmpegkit::FFmpegKitConfig::getSession(const long sessionId) {
std::unique_lock<std::recursive_mutex> lock(sessionMutex, std::defer_lock);
lock.lock();
auto session = sessionHistoryMap.find(sessionId);
if (session != sessionHistoryMap.end()) {
return session->second;
} else {
return nullptr;
}
}
std::shared_ptr<ffmpegkit::Session> ffmpegkit::FFmpegKitConfig::getLastSession() {
std::unique_lock<std::recursive_mutex> lock(sessionMutex, std::defer_lock);
lock.lock();
return sessionHistoryList.front();
}
std::shared_ptr<ffmpegkit::Session> ffmpegkit::FFmpegKitConfig::getLastCompletedSession() {
std::unique_lock<std::recursive_mutex> lock(sessionMutex, std::defer_lock);
lock.lock();
for(auto rit=sessionHistoryList.rbegin(); rit != sessionHistoryList.rend(); ++rit) {
auto session = *rit;
if (session->getState() == SessionStateCompleted) {
return session;
}
}
return nullptr;
}
std::shared_ptr<std::list<std::shared_ptr<ffmpegkit::Session>>> ffmpegkit::FFmpegKitConfig::getSessions() {
std::unique_lock<std::recursive_mutex> lock(sessionMutex, std::defer_lock);
lock.lock();
auto sessionHistoryListCopy = std::make_shared<std::list<std::shared_ptr<ffmpegkit::Session>>>(sessionHistoryList);
lock.unlock();
return sessionHistoryListCopy;
}
void ffmpegkit::FFmpegKitConfig::clearSessions() {
std::unique_lock<std::recursive_mutex> lock(sessionMutex, std::defer_lock);
lock.lock();
sessionHistoryList.clear();
sessionHistoryMap.clear();
lock.unlock();
}
std::shared_ptr<std::list<std::shared_ptr<ffmpegkit::FFmpegSession>>> ffmpegkit::FFmpegKitConfig::getFFmpegSessions() {
std::unique_lock<std::recursive_mutex> lock(sessionMutex, std::defer_lock);
const auto ffmpegSessions = std::make_shared<std::list<std::shared_ptr<ffmpegkit::FFmpegSession>>>();
lock.lock();
for(auto it=sessionHistoryList.begin(); it != sessionHistoryList.end(); ++it) {
auto session = *it;
if (session->isFFmpeg()) {
ffmpegSessions->push_back(std::static_pointer_cast<ffmpegkit::FFmpegSession>(session));
}
}
lock.unlock();
return ffmpegSessions;
}
std::shared_ptr<std::list<std::shared_ptr<ffmpegkit::FFprobeSession>>> ffmpegkit::FFmpegKitConfig::getFFprobeSessions() {
std::unique_lock<std::recursive_mutex> lock(sessionMutex, std::defer_lock);
const auto ffprobeSessions = std::make_shared<std::list<std::shared_ptr<ffmpegkit::FFprobeSession>>>();
lock.lock();
for(auto it=sessionHistoryList.begin(); it != sessionHistoryList.end(); ++it) {
auto session = *it;
if (session->isFFprobe()) {
ffprobeSessions->push_back(std::static_pointer_cast<ffmpegkit::FFprobeSession>(session));
}
}
lock.unlock();
return ffprobeSessions;
}
std::shared_ptr<std::list<std::shared_ptr<ffmpegkit::MediaInformationSession>>> ffmpegkit::FFmpegKitConfig::getMediaInformationSessions() {
std::unique_lock<std::recursive_mutex> lock(sessionMutex, std::defer_lock);
const auto mediaInformationSessions = std::make_shared<std::list<std::shared_ptr<ffmpegkit::MediaInformationSession>>>();
lock.lock();
for(auto it=sessionHistoryList.begin(); it != sessionHistoryList.end(); ++it) {
auto session = *it;
if (session->isMediaInformation()) {
mediaInformationSessions->push_back(std::static_pointer_cast<ffmpegkit::MediaInformationSession>(session));
}
}
lock.unlock();
return mediaInformationSessions;
}
std::shared_ptr<std::list<std::shared_ptr<ffmpegkit::Session>>> ffmpegkit::FFmpegKitConfig::getSessionsByState(const SessionState state) {
std::unique_lock<std::recursive_mutex> lock(sessionMutex, std::defer_lock);
auto sessions = std::make_shared<std::list<std::shared_ptr<ffmpegkit::Session>>>();
lock.lock();
for(auto it=sessionHistoryList.begin(); it != sessionHistoryList.end(); ++it) {
auto session = *it;
if (session->getState() == state) {
sessions->push_back(session);
}
}
lock.unlock();
return sessions;
}
ffmpegkit::LogRedirectionStrategy ffmpegkit::FFmpegKitConfig::getLogRedirectionStrategy() {
return globalLogRedirectionStrategy;
}
void ffmpegkit::FFmpegKitConfig::setLogRedirectionStrategy(const LogRedirectionStrategy logRedirectionStrategy) {
globalLogRedirectionStrategy = logRedirectionStrategy;
}
int ffmpegkit::FFmpegKitConfig::messagesInTransmit(const long sessionId) {
return std::atomic_load(&sessionInTransitMessageCountMap[sessionId % SESSION_MAP_SIZE]);
}
std::string ffmpegkit::FFmpegKitConfig::sessionStateToString(SessionState state) {
switch (state) {
case SessionStateCreated: return "CREATED";
case SessionStateRunning: return "RUNNING";
case SessionStateFailed: return "FAILED";
case SessionStateCompleted: return "COMPLETED";
default: return "";
}
}
std::list<std::string> ffmpegkit::FFmpegKitConfig::parseArguments(const std::string& command) {
std::list<std::string> argumentList;
std::string currentArgument;
bool singleQuoteStarted = false;
bool doubleQuoteStarted = false;
for (int i = 0; i < command.size(); i++) {
char previousChar;
if (i > 0) {
previousChar = command[i - 1];
} else {
previousChar = 0;
}
char currentChar = command[i];
if (currentChar == ' ') {
if (singleQuoteStarted || doubleQuoteStarted) {
currentArgument += currentChar;
} else if (currentArgument.size() > 0) {
argumentList.push_back(currentArgument);
currentArgument = "";
}
} else if (currentChar == '\'' && (previousChar == 0 || previousChar != '\\')) {
if (singleQuoteStarted) {
singleQuoteStarted = false;
} else if (doubleQuoteStarted) {
currentArgument += currentChar;
} else {
singleQuoteStarted = true;
}
} else if (currentChar == '\"' && (previousChar == 0 || previousChar != '\\')) {
if (doubleQuoteStarted) {
doubleQuoteStarted = false;
} else if (singleQuoteStarted) {
currentArgument += currentChar;
} else {
doubleQuoteStarted = true;
}
} else {
currentArgument += currentChar;
}
}
if (currentArgument.size() > 0) {
argumentList.push_back(currentArgument);
}
return argumentList;
}
std::string ffmpegkit::FFmpegKitConfig::argumentsToString(std::shared_ptr<std::list<std::string>> arguments) {
if (arguments == nullptr) {
return "null";
}
std::string string;
for(auto it=arguments->begin(); it != arguments->end(); ++it) {
auto argument = *it;
if (it != arguments->begin()) {
string += " ";
}
string += argument;
}
return string;
}
ArchDetect.h
FFmpegKit.h
callbackMutex
static std::mutex callbackMutex
Definition: FFmpegKitConfig.cpp:79
ffmpegkit_log_callback_function
void ffmpegkit_log_callback_function(void *ptr, int level, const char *format, va_list vargs)
Definition: FFmpegKitConfig.cpp:470
process_log
static void process_log(long sessionId, int levelValueInt, AVBPrint *logMessage)
Definition: FFmpegKitConfig.cpp:523
callbackThreadFunction
void * callbackThreadFunction(void *pointer)
Definition: FFmpegKitConfig.cpp:638
executeFFprobe
int executeFFprobe(const long sessionId, const std::shared_ptr< std::list< std::string > > arguments)
Definition: FFmpegKitConfig.cpp:726
pipeIndexGenerator
static std::atomic< long > pipeIndexGenerator(1)
statisticsCallbackDataAdd
static void statisticsCallbackDataAdd(int frameNumber, float fps, float quality, int64_t size, int time, double bitrate, double speed)
Definition: FFmpegKitConfig.cpp:374
cancelSession
void cancelSession(long sessionId)
Definition: FFmpegKitConfig.cpp:431
SESSION_MAP_SIZE
#define SESSION_MAP_SIZE
Definition: FFmpegKitConfig.cpp:59
sessionHistorySize
static int sessionHistorySize
Definition: FFmpegKitConfig.cpp:53
fs_exists
static bool fs_exists(const std::string &s, const bool isFile, const bool isDirectory)
Definition: FFmpegKitConfig.cpp:125
callbackDataList
static std::list< CallbackData * > callbackDataList
Definition: FFmpegKitConfig.cpp:82
CallbackType
CallbackType
Definition: FFmpegKitConfig.cpp:120
StatisticsType
@ StatisticsType
Definition: FFmpegKitConfig.cpp:122
LogType
@ LogType
Definition: FFmpegKitConfig.cpp:121
callbackDataMutex
static std::recursive_mutex callbackDataMutex
Definition: FFmpegKitConfig.cpp:78
logCallbackDataAdd
static void logCallbackDataAdd(int level, AVBPrint *data)
Definition: FFmpegKitConfig.cpp:358
avutil_log_sanitize
static void avutil_log_sanitize(char *line)
Definition: FFmpegKitConfig.cpp:344
handleSIGINT
volatile int handleSIGINT
Definition: FFmpegKitConfig.cpp:86
registerSessionId
static void registerSessionId(long sessionId)
Definition: FFmpegKitConfig.cpp:409
ffprobe_execute
int ffprobe_execute(int argc, char **argv)
Definition: fftools_ffprobe.c:4050
handleSIGTERM
volatile int handleSIGTERM
Definition: FFmpegKitConfig.cpp:87
ffmpegSessionCompleteCallback
static ffmpegkit::FFmpegSessionCompleteCallback ffmpegSessionCompleteCallback
Definition: FFmpegKitConfig.cpp:70
sessionInTransitMessageCountMap
static std::atomic< int > sessionInTransitMessageCountMap[SESSION_MAP_SIZE]
Definition: FFmpegKitConfig.cpp:61
avutil_log_get_level_str
static const char * avutil_log_get_level_str(int level)
Definition: FFmpegKitConfig.cpp:287
ffmpegkit_statistics_callback_function
void ffmpegkit_statistics_callback_function(int frameNumber, float fps, float quality, int64_t size, int time, double bitrate, double speed)
Definition: FFmpegKitConfig.cpp:519
avutil_log_format_line
static void avutil_log_format_line(void *avcl, int level, const char *fmt, va_list vl, AVBPrint part[4], int *print_prefix)
Definition: FFmpegKitConfig.cpp:312
sessionMutex
static std::recursive_mutex sessionMutex
Definition: FFmpegKitConfig.cpp:56
sessionMap
static std::atomic< short > sessionMap[SESSION_MAP_SIZE]
Definition: FFmpegKitConfig.cpp:60
addSessionToSessionHistory
void addSessionToSessionHistory(const std::shared_ptr< ffmpegkit::Session > session)
Definition: FFmpegKitConfig.cpp:160
resetMessagesInTransmit
static void resetMessagesInTransmit(long sessionId)
Definition: FFmpegKitConfig.cpp:458
logCallback
static ffmpegkit::LogCallback logCallback
Definition: FFmpegKitConfig.cpp:64
callbackNotify
static void callbackNotify()
Definition: FFmpegKitConfig.cpp:283
callbackThread
static pthread_t callbackThread
Definition: FFmpegKitConfig.cpp:114
callbackMonitor
static std::condition_variable callbackMonitor
Definition: FFmpegKitConfig.cpp:80
sessionHistoryList
static std::list< std::shared_ptr< ffmpegkit::Session > > sessionHistoryList
Definition: FFmpegKitConfig.cpp:55
sessionHistoryMap
static std::map< long, std::shared_ptr< ffmpegkit::Session > > sessionHistoryMap
Definition: FFmpegKitConfig.cpp:54
statisticsCallback
static ffmpegkit::StatisticsCallback statisticsCallback
Definition: FFmpegKitConfig.cpp:67
globalLogRedirectionStrategy
static ffmpegkit::LogRedirectionStrategy globalLogRedirectionStrategy
Definition: FFmpegKitConfig.cpp:74
ffmpegKitInitializerFlag
static std::once_flag ffmpegKitInitializerFlag
Definition: FFmpegKitConfig.cpp:113
ffmpegKitInitialize
void * ffmpegKitInitialize()
Definition: FFmpegKitConfig.cpp:766
executeFFmpeg
static int executeFFmpeg(const long sessionId, const std::shared_ptr< std::list< std::string > > arguments)
Definition: FFmpegKitConfig.cpp:686
deleteExpiredSessions
void deleteExpiredSessions()
Definition: FFmpegKitConfig.cpp:150
globalSessionId
__thread long globalSessionId
Definition: FFmpegKitConfig.cpp:92
redirectionEnabled
static int redirectionEnabled
Definition: FFmpegKitConfig.cpp:77
callbackWait
static void callbackWait(int milliSeconds)
Definition: FFmpegKitConfig.cpp:275
process_statistics
void process_statistics(long sessionId, int videoFrameNumber, float videoFps, float videoQuality, long size, int time, double bitrate, double speed)
Definition: FFmpegKitConfig.cpp:607
cancelRequested
int cancelRequested(long sessionId)
Definition: FFmpegKitConfig.cpp:441
handleSIGPIPE
volatile int handleSIGPIPE
Definition: FFmpegKitConfig.cpp:89
callbackDataRemove
static CallbackData * callbackDataRemove()
Definition: FFmpegKitConfig.cpp:390
handleSIGXCPU
volatile int handleSIGXCPU
Definition: FFmpegKitConfig.cpp:88
ffprobeSessionCompleteCallback
static ffmpegkit::FFprobeSessionCompleteCallback ffprobeSessionCompleteCallback
Definition: FFmpegKitConfig.cpp:71
removeSession
static void removeSession(long sessionId)
Definition: FFmpegKitConfig.cpp:418
fs_create_dir
static bool fs_create_dir(const std::string &s)
Definition: FFmpegKitConfig.cpp:140
configuredLogLevel
int configuredLogLevel
Definition: FFmpegKitConfig.cpp:95
mediaInformationSessionCompleteCallback
static ffmpegkit::MediaInformationSessionCompleteCallback mediaInformationSessionCompleteCallback
Definition: FFmpegKitConfig.cpp:72
ffmpeg_execute
int ffmpeg_execute(int argc, char **argv)
Definition: fftools_ffmpeg.c:4775
_ffmpegKitConfigInitializer
const void * _ffmpegKitConfigInitializer
Definition: FFmpegKitConfig.cpp:118
handleSIGQUIT
volatile int handleSIGQUIT
Definition: FFmpegKitConfig.cpp:85
FFmpegKitConfig.h
FFmpegSession.h
FFprobeKit.h
FFprobeSession.h
Level.h
LogRedirectionStrategy.h
MediaInformationSession.h
Packages.h
SessionState.h
CallbackData
Definition: FFmpegKitConfig.cpp:183
CallbackData::_statisticsSize
int64_t _statisticsSize
Definition: FFmpegKitConfig.cpp:264
CallbackData::getStatisticsQuality
float getStatisticsQuality()
Definition: FFmpegKitConfig.cpp:234
CallbackData::getLogData
AVBPrint * getLogData()
Definition: FFmpegKitConfig.cpp:222
CallbackData::_statisticsTime
int _statisticsTime
Definition: FFmpegKitConfig.cpp:265
CallbackData::_statisticsBitrate
double _statisticsBitrate
Definition: FFmpegKitConfig.cpp:266
CallbackData::_statisticsSpeed
double _statisticsSpeed
Definition: FFmpegKitConfig.cpp:267
CallbackData::CallbackData
CallbackData(const long sessionId, const int videoFrameNumber, const float videoFps, const float videoQuality, const int64_t size, const int time, const double bitrate, const double speed)
Definition: FFmpegKitConfig.cpp:191
CallbackData::getStatisticsSpeed
double getStatisticsSpeed()
Definition: FFmpegKitConfig.cpp:250
CallbackData::_logLevel
int _logLevel
Definition: FFmpegKitConfig.cpp:258
CallbackData::_statisticsFps
float _statisticsFps
Definition: FFmpegKitConfig.cpp:262
CallbackData::_logData
AVBPrint _logData
Definition: FFmpegKitConfig.cpp:259
CallbackData::getStatisticsFrameNumber
int getStatisticsFrameNumber()
Definition: FFmpegKitConfig.cpp:226
CallbackData::_statisticsQuality
float _statisticsQuality
Definition: FFmpegKitConfig.cpp:263
CallbackData::_sessionId
long _sessionId
Definition: FFmpegKitConfig.cpp:256
CallbackData::getStatisticsSize
int64_t getStatisticsSize()
Definition: FFmpegKitConfig.cpp:238
CallbackData::CallbackData
CallbackData(const long sessionId, const int logLevel, const AVBPrint *data)
Definition: FFmpegKitConfig.cpp:185
CallbackData::_statisticsFrameNumber
int _statisticsFrameNumber
Definition: FFmpegKitConfig.cpp:261
CallbackData::getStatisticsBitrate
double getStatisticsBitrate()
Definition: FFmpegKitConfig.cpp:246
CallbackData::getStatisticsTime
int getStatisticsTime()
Definition: FFmpegKitConfig.cpp:242
CallbackData::getLogLevel
int getLogLevel()
Definition: FFmpegKitConfig.cpp:218
CallbackData::getType
CallbackType getType()
Definition: FFmpegKitConfig.cpp:210
CallbackData::_type
CallbackType _type
Definition: FFmpegKitConfig.cpp:255
CallbackData::getStatisticsFps
float getStatisticsFps()
Definition: FFmpegKitConfig.cpp:230
CallbackData::getSessionId
long getSessionId()
Definition: FFmpegKitConfig.cpp:214
ffmpegkit::ArchDetect::getArch
static std::string getArch()
Definition: ArchDetect.cpp:26
ffmpegkit::FFmpegKitConfig::getVersion
static std::string getVersion()
Definition: FFmpegKitConfig.cpp:967
ffmpegkit::FFmpegKitConfig::disableRedirection
static void disableRedirection()
Definition: FFmpegKitConfig.cpp:818
ffmpegkit::FFmpegKitConfig::getMediaInformationSessions
static std::shared_ptr< std::list< std::shared_ptr< ffmpegkit::MediaInformationSession > > > getMediaInformationSessions()
Definition: FFmpegKitConfig.cpp:1303
ffmpegkit::FFmpegKitConfig::enableFFmpegSessionCompleteCallback
static void enableFFmpegSessionCompleteCallback(const FFmpegSessionCompleteCallback ffmpegSessionCompleteCallback)
Definition: FFmpegKitConfig.cpp:1147
ffmpegkit::FFmpegKitConfig::getSessionHistorySize
static int getSessionHistorySize()
Definition: FFmpegKitConfig.cpp:1195
ffmpegkit::FFmpegKitConfig::getLastSession
static std::shared_ptr< ffmpegkit::Session > getLastSession()
Definition: FFmpegKitConfig.cpp:1224
ffmpegkit::FFmpegKitConfig::enableRedirection
static void enableRedirection()
Definition: FFmpegKitConfig.cpp:795
ffmpegkit::FFmpegKitConfig::enableLogCallback
static void enableLogCallback(const ffmpegkit::LogCallback logCallback)
Definition: FFmpegKitConfig.cpp:1139
ffmpegkit::FFmpegKitConfig::registerNewFFmpegPipe
static std::shared_ptr< std::string > registerNewFFmpegPipe()
Definition: FFmpegKitConfig.cpp:927
ffmpegkit::FFmpegKitConfig::getLogRedirectionStrategy
static LogRedirectionStrategy getLogRedirectionStrategy()
Definition: FFmpegKitConfig.cpp:1339
ffmpegkit::FFmpegKitConfig::getFFprobeSessions
static std::shared_ptr< std::list< std::shared_ptr< ffmpegkit::FFprobeSession > > > getFFprobeSessions()
Definition: FFmpegKitConfig.cpp:1285
ffmpegkit::FFmpegKitConfig::messagesInTransmit
static int messagesInTransmit(const long sessionId)
Definition: FFmpegKitConfig.cpp:1347
ffmpegkit::FFmpegKitConfig::closeFFmpegPipe
static void closeFFmpegPipe(const std::string &ffmpegPipePath)
Definition: FFmpegKitConfig.cpp:959
ffmpegkit::FFmpegKitConfig::asyncFFprobeExecute
static void asyncFFprobeExecute(const std::shared_ptr< ffmpegkit::FFprobeSession > ffprobeSession)
Definition: FFmpegKitConfig.cpp:1083
ffmpegkit::FFmpegKitConfig::getLogLevel
static ffmpegkit::Level getLogLevel()
Definition: FFmpegKitConfig.cpp:1171
ffmpegkit::FFmpegKitConfig::getSession
static std::shared_ptr< ffmpegkit::Session > getSession(const long sessionId)
Definition: FFmpegKitConfig.cpp:1212
ffmpegkit::FFmpegKitConfig::asyncGetMediaInformationExecute
static void asyncGetMediaInformationExecute(const std::shared_ptr< ffmpegkit::MediaInformationSession > mediaInformationSession, int waitTimeout)
Definition: FFmpegKitConfig.cpp:1111
ffmpegkit::FFmpegKitConfig::setLogRedirectionStrategy
static void setLogRedirectionStrategy(const LogRedirectionStrategy logRedirectionStrategy)
Definition: FFmpegKitConfig.cpp:1343
ffmpegkit::FFmpegKitConfig::getMediaInformationExecute
static void getMediaInformationExecute(const std::shared_ptr< ffmpegkit::MediaInformationSession > mediaInformationSession, const int waitTimeout)
Definition: FFmpegKitConfig.cpp:1031
ffmpegkit::FFmpegKitConfig::setEnvironmentVariable
static int setEnvironmentVariable(const std::string &variableName, const std::string &variableValue)
Definition: FFmpegKitConfig.cpp:989
ffmpegkit::FFmpegKitConfig::getSessionsByState
static std::shared_ptr< std::list< std::shared_ptr< ffmpegkit::Session > > > getSessionsByState(const SessionState state)
Definition: FFmpegKitConfig.cpp:1321
ffmpegkit::FFmpegKitConfig::enableStatisticsCallback
static void enableStatisticsCallback(const ffmpegkit::StatisticsCallback statisticsCallback)
Definition: FFmpegKitConfig.cpp:1143
ffmpegkit::FFmpegKitConfig::parseArguments
static std::list< std::string > parseArguments(const std::string &command)
Definition: FFmpegKitConfig.cpp:1361
ffmpegkit::FFmpegKitConfig::ffprobeExecute
static void ffprobeExecute(const std::shared_ptr< ffmpegkit::FFprobeSession > ffprobeSession)
Definition: FFmpegKitConfig.cpp:1019
ffmpegkit::FFmpegKitConfig::setSessionHistorySize
static void setSessionHistorySize(const int sessionHistorySize)
Definition: FFmpegKitConfig.cpp:1199
ffmpegkit::FFmpegKitConfig::setLogLevel
static void setLogLevel(const ffmpegkit::Level level)
Definition: FFmpegKitConfig.cpp:1175
ffmpegkit::FFmpegKitConfig::setFontDirectory
static void setFontDirectory(const std::string &fontDirectoryPath, const std::map< std::string, std::string > &fontNameMapping)
Definition: FFmpegKitConfig.cpp:843
ffmpegkit::FFmpegKitConfig::asyncFFmpegExecute
static void asyncFFmpegExecute(const std::shared_ptr< ffmpegkit::FFmpegSession > ffmpegSession)
Definition: FFmpegKitConfig.cpp:1055
ffmpegkit::FFmpegKitConfig::getFFmpegSessionCompleteCallback
static FFmpegSessionCompleteCallback getFFmpegSessionCompleteCallback()
Definition: FFmpegKitConfig.cpp:1151
ffmpegkit::FFmpegKitConfig::ignoreSignal
static void ignoreSignal(const ffmpegkit::Signal signal)
Definition: FFmpegKitConfig.cpp:993
ffmpegkit::FFmpegKitConfig::getFFprobeSessionCompleteCallback
static FFprobeSessionCompleteCallback getFFprobeSessionCompleteCallback()
Definition: FFmpegKitConfig.cpp:1159
ffmpegkit::FFmpegKitConfig::getLastCompletedSession
static std::shared_ptr< ffmpegkit::Session > getLastCompletedSession()
Definition: FFmpegKitConfig.cpp:1231
ffmpegkit::FFmpegKitConfig::clearSessions
static void clearSessions()
Definition: FFmpegKitConfig.cpp:1257
ffmpegkit::FFmpegKitConfig::isLTSBuild
static bool isLTSBuild()
Definition: FFmpegKitConfig.cpp:975
ffmpegkit::FFmpegKitConfig::sessionStateToString
static std::string sessionStateToString(SessionState state)
Definition: FFmpegKitConfig.cpp:1351
ffmpegkit::FFmpegKitConfig::getFFmpegSessions
static std::shared_ptr< std::list< std::shared_ptr< ffmpegkit::FFmpegSession > > > getFFmpegSessions()
Definition: FFmpegKitConfig.cpp:1267
ffmpegkit::FFmpegKitConfig::setFontconfigConfigurationPath
static int setFontconfigConfigurationPath(const std::string &path)
Definition: FFmpegKitConfig.cpp:839
ffmpegkit::FFmpegKitConfig::argumentsToString
static std::string argumentsToString(std::shared_ptr< std::list< std::string > > arguments)
Definition: FFmpegKitConfig.cpp:1412
ffmpegkit::FFmpegKitConfig::logLevelToString
static std::string logLevelToString(const ffmpegkit::Level level)
Definition: FFmpegKitConfig.cpp:1179
ffmpegkit::FFmpegKitConfig::setFontDirectoryList
static void setFontDirectoryList(const std::list< std::string > &fontDirectoryList, const std::map< std::string, std::string > &fontNameMapping)
Definition: FFmpegKitConfig.cpp:847
ffmpegkit::FFmpegKitConfig::enableMediaInformationSessionCompleteCallback
static void enableMediaInformationSessionCompleteCallback(const MediaInformationSessionCompleteCallback mediaInformationSessionCompleteCallback)
Definition: FFmpegKitConfig.cpp:1163
ffmpegkit::FFmpegKitConfig::enableFFprobeSessionCompleteCallback
static void enableFFprobeSessionCompleteCallback(const FFprobeSessionCompleteCallback ffprobeSessionCompleteCallback)
Definition: FFmpegKitConfig.cpp:1155
ffmpegkit::FFmpegKitConfig::getFFmpegVersion
static std::string getFFmpegVersion()
Definition: FFmpegKitConfig.cpp:963
ffmpegkit::FFmpegKitConfig::getSessions
static std::shared_ptr< std::list< std::shared_ptr< ffmpegkit::Session > > > getSessions()
Definition: FFmpegKitConfig.cpp:1246
ffmpegkit::FFmpegKitConfig::getBuildDate
static std::string getBuildDate()
Definition: FFmpegKitConfig.cpp:983
ffmpegkit::FFmpegKitConfig::ffmpegExecute
static void ffmpegExecute(const std::shared_ptr< ffmpegkit::FFmpegSession > ffmpegSession)
Definition: FFmpegKitConfig.cpp:1007
ffmpegkit::FFmpegKitConfig::getMediaInformationSessionCompleteCallback
static MediaInformationSessionCompleteCallback getMediaInformationSessionCompleteCallback()
Definition: FFmpegKitConfig.cpp:1167
ffmpegkit::MediaInformationJsonParser::fromWithError
static std::shared_ptr< ffmpegkit::MediaInformation > fromWithError(const std::string &ffprobeJsonOutput)
Definition: MediaInformationJsonParser.cpp:40
ffmpegkit::Packages::getPackageName
static std::string getPackageName()
Definition: Packages.cpp:25
AV_LOG_STDERR
#define AV_LOG_STDERR
Definition: fftools_cmdutils.h:75
set_report_callback
void set_report_callback(void(*callback)(int, float, float, int64_t, int, double, double))
Definition: fftools_ffmpeg.c:4759
fftools_ffmpeg.h
ffmpegkit::LogRedirectionStrategy
LogRedirectionStrategy
Definition: LogRedirectionStrategy.h:25
ffmpegkit::LogRedirectionStrategyPrintLogsWhenSessionCallbackNotDefined
@ LogRedirectionStrategyPrintLogsWhenSessionCallbackNotDefined
Definition: LogRedirectionStrategy.h:29
ffmpegkit::LogRedirectionStrategyAlwaysPrintLogs
@ LogRedirectionStrategyAlwaysPrintLogs
Definition: LogRedirectionStrategy.h:26
ffmpegkit::LogRedirectionStrategyNeverPrintLogs
@ LogRedirectionStrategyNeverPrintLogs
Definition: LogRedirectionStrategy.h:30
ffmpegkit::LogRedirectionStrategyPrintLogsWhenNoCallbacksDefined
@ LogRedirectionStrategyPrintLogsWhenNoCallbacksDefined
Definition: LogRedirectionStrategy.h:27
ffmpegkit::LogRedirectionStrategyPrintLogsWhenGlobalCallbackNotDefined
@ LogRedirectionStrategyPrintLogsWhenGlobalCallbackNotDefined
Definition: LogRedirectionStrategy.h:28
ffmpegkit::StatisticsCallback
std::function< void(const std::shared_ptr< ffmpegkit::Statistics > statistics)> StatisticsCallback
Definition: StatisticsCallback.h:35
ffmpegkit::Level
Level
Definition: Level.h:28
ffmpegkit::LevelAVLogError
@ LevelAVLogError
Definition: Level.h:57
ffmpegkit::LevelAVLogDebug
@ LevelAVLogDebug
Definition: Level.h:78
ffmpegkit::LevelAVLogStdErr
@ LevelAVLogStdErr
Definition: Level.h:34
ffmpegkit::LevelAVLogQuiet
@ LevelAVLogQuiet
Definition: Level.h:39
ffmpegkit::LevelAVLogPanic
@ LevelAVLogPanic
Definition: Level.h:44
ffmpegkit::LevelAVLogWarning
@ LevelAVLogWarning
Definition: Level.h:63
ffmpegkit::LevelAVLogVerbose
@ LevelAVLogVerbose
Definition: Level.h:73
ffmpegkit::LevelAVLogTrace
@ LevelAVLogTrace
Definition: Level.h:83
ffmpegkit::LevelAVLogInfo
@ LevelAVLogInfo
Definition: Level.h:68
ffmpegkit::LevelAVLogFatal
@ LevelAVLogFatal
Definition: Level.h:51
ffmpegkit::SessionState
SessionState
Definition: SessionState.h:25
ffmpegkit::SessionStateRunning
@ SessionStateRunning
Definition: SessionState.h:27
ffmpegkit::SessionStateFailed
@ SessionStateFailed
Definition: SessionState.h:28
ffmpegkit::SessionStateCreated
@ SessionStateCreated
Definition: SessionState.h:26
ffmpegkit::SessionStateCompleted
@ SessionStateCompleted
Definition: SessionState.h:29
ffmpegkit::MediaInformationSessionCompleteCallback
std::function< void(const std::shared_ptr< ffmpegkit::MediaInformationSession > session)> MediaInformationSessionCompleteCallback
Definition: MediaInformationSessionCompleteCallback.h:53
ffmpegkit::LogCallback
std::function< void(const std::shared_ptr< ffmpegkit::Log > log)> LogCallback
Definition: LogCallback.h:35
ffmpegkit::Signal
Signal
Definition: Signal.h:25
ffmpegkit::SignalXcpu
@ SignalXcpu
Definition: Signal.h:30
ffmpegkit::SignalQuit
@ SignalQuit
Definition: Signal.h:27
ffmpegkit::SignalInt
@ SignalInt
Definition: Signal.h:26
ffmpegkit::SignalTerm
@ SignalTerm
Definition: Signal.h:29
ffmpegkit::SignalPipe
@ SignalPipe
Definition: Signal.h:28
ffmpegkit::FFprobeSessionCompleteCallback
std::function< void(const std::shared_ptr< ffmpegkit::FFprobeSession > session)> FFprobeSessionCompleteCallback
Definition: FFprobeSessionCompleteCallback.h:52
ffmpegkit::FFmpegSessionCompleteCallback
std::function< void(const std::shared_ptr< ffmpegkit::FFmpegSession > session)> FFmpegSessionCompleteCallback
Definition: FFmpegSessionCompleteCallback.h:52