23#import "libavutil/ffversion.h"
57#define SESSION_MAP_SIZE 1000
76static NSRecursiveLock *
lock;
99typedef NS_ENUM(NSUInteger, CallbackType) {
105 NSNumber* sessionIdNumber = [NSNumber numberWithLong:[session getSessionId]];
107 [sessionHistoryLock lock];
114 [sessionHistoryMap setObject:session forKey:sessionIdNumber];
115 [sessionHistoryList addObject:session];
117 id<Session> first = [sessionHistoryList firstObject];
119 NSNumber* key = [NSNumber numberWithLong:[first getSessionId]];
120 [sessionHistoryList removeObject:key];
121 [sessionHistoryMap removeObjectForKey:key];
126 [sessionHistoryLock unlock];
152 - (instancetype)init:(
long)sessionId logLevel:(
int)logLevel data:(NSString*)logData {
164 - (instancetype)init:(
long)sessionId
165 videoFrameNumber:(
int)videoFrameNumber
167 quality:(
float)videoQuality
170 bitrate:(
double)bitrate
171 speed:(
double)speed {
174 _type = StatisticsType;
188- (CallbackType)getType {
192- (long)getSessionId {
200- (NSString*)getLogData {
204- (
int)getStatisticsFrameNumber {
208- (float)getStatisticsFps {
212- (float)getStatisticsQuality {
216- (int64_t)getStatisticsSize {
220- (
int)getStatisticsTime {
224- (double)getStatisticsBitrate {
228- (double)getStatisticsSpeed {
240 dispatch_semaphore_wait(
semaphore, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(milliSeconds * NSEC_PER_MSEC)));
260 [callbackDataArray addObject:callbackData];
272 CallbackData *callbackData = [[
CallbackData alloc] init:globalSessionId videoFrameNumber:frameNumber fps:fps quality:quality size:size time:time bitrate:bitrate speed:speed];
275 [callbackDataArray addObject:callbackData];
293 newData = [callbackDataArray objectAtIndex:0];
294 [callbackDataArray removeObjectAtIndex:0];
296 }
@catch(NSException *exception) {
369 int activeLogLevel = av_log_get_level();
372 if ((activeLogLevel == LevelAVLogQuiet && level != LevelAVLogStdErr) || (level > activeLogLevel)) {
376 NSString *logData = [[NSString alloc] initWithFormat:[NSString stringWithCString:format encoding:NSUTF8StringEncoding] arguments:vargs];
378 if (logData.length > 0) {
398void process_log(
long sessionId,
int levelValue, NSString* logMessage) {
399 int activeLogLevel = av_log_get_level();
400 Log* log = [[
Log alloc] init:sessionId:levelValue:logMessage];
401 BOOL globalCallbackDefined =
false;
402 BOOL sessionCallbackDefined =
false;
406 if ((activeLogLevel == LevelAVLogQuiet && levelValue != LevelAVLogStdErr) || (levelValue > activeLogLevel)) {
412 if (session != nil) {
413 activeLogRedirectionStrategy = [session getLogRedirectionStrategy];
414 [session addLog:log];
416 LogCallback sessionLogCallback = [session getLogCallback];
417 if (sessionLogCallback != nil) {
418 sessionCallbackDefined = TRUE;
422 sessionLogCallback(log);
424 @catch(NSException* exception) {
425 NSLog(
@"Exception thrown inside session LogCallback block. %@", [exception callStackSymbols]);
431 if (globalLogCallback != nil) {
432 globalCallbackDefined = TRUE;
436 globalLogCallback(log);
438 @catch(NSException* exception) {
439 NSLog(
@"Exception thrown inside global LogCallback block. %@", [exception callStackSymbols]);
444 switch (activeLogRedirectionStrategy) {
445 case LogRedirectionStrategyNeverPrintLogs: {
448 case LogRedirectionStrategyPrintLogsWhenGlobalCallbackNotDefined: {
449 if (globalCallbackDefined) {
454 case LogRedirectionStrategyPrintLogsWhenSessionCallbackNotDefined: {
455 if (sessionCallbackDefined) {
459 case LogRedirectionStrategyPrintLogsWhenNoCallbacksDefined: {
460 if (globalCallbackDefined || sessionCallbackDefined) {
464 case LogRedirectionStrategyAlwaysPrintLogs: {
469 switch (levelValue) {
470 case LevelAVLogQuiet:
475 NSLog(
@"%@: %@", [
FFmpegKitConfig logLevelToString:levelValue], logMessage);
480void process_statistics(
long sessionId,
int videoFrameNumber,
float videoFps,
float videoQuality,
long size,
int time,
double bitrate,
double speed) {
482 Statistics *statistics = [[
Statistics alloc] init:sessionId videoFrameNumber:videoFrameNumber videoFps:videoFps videoQuality:videoQuality size:size time:time bitrate:bitrate speed:speed];
485 if (session != nil && [session isFFmpeg]) {
490 if (sessionStatisticsCallback != nil) {
492 sessionStatisticsCallback(statistics);
494 @catch(NSException* exception) {
495 NSLog(
@"Exception thrown inside session StatisticsCallback block. %@", [exception callStackSymbols]);
501 if (globalStatisticsCallback != nil) {
503 globalStatisticsCallback(statistics);
505 @catch(NSException* exception) {
506 NSLog(
@"Exception thrown inside global StatisticsCallback block. %@", [exception callStackSymbols]);
515 int activeLogLevel = av_log_get_level();
516 if ((activeLogLevel != LevelAVLogQuiet) && (LevelAVLogDebug <= activeLogLevel)) {
517 NSLog(
@"Async callback block started.\n");
525 if (callbackData != nil) {
527 if ([callbackData getType] == LogType) {
528 process_log([callbackData getSessionId], [callbackData getLogLevel], [callbackData getLogData]);
531 [callbackData getStatisticsFrameNumber],
532 [callbackData getStatisticsFps],
533 [callbackData getStatisticsQuality],
534 [callbackData getStatisticsSize],
535 [callbackData getStatisticsTime],
536 [callbackData getStatisticsBitrate],
537 [callbackData getStatisticsSpeed]);
546 }
@catch(NSException *exception) {
547 activeLogLevel = av_log_get_level();
548 if ((activeLogLevel != LevelAVLogQuiet) && (LevelAVLogWarning <= activeLogLevel)) {
549 NSLog(
@"Async callback block received error: %@n\n", exception);
550 NSLog(
@"%@", [exception callStackSymbols]);
556 activeLogLevel = av_log_get_level();
557 if ((activeLogLevel != LevelAVLogQuiet) && (LevelAVLogDebug <= activeLogLevel)) {
558 NSLog(
@"Async callback block stopped.\n");
563 NSString*
const LIB_NAME =
@"ffmpeg";
568 char **commandCharPArray = (
char **)av_malloc(
sizeof(
char*) * ([arguments count] + 1));
574 commandCharPArray[0] = (
char *)av_malloc(
sizeof(
char) * ([LIB_NAME length] + 1));
575 strcpy(commandCharPArray[0], [LIB_NAME UTF8String]);
578 for (
int i=0; i < [arguments count]; i++) {
579 NSString *argument = [arguments objectAtIndex:i];
580 commandCharPArray[i + 1] = (
char *) [argument UTF8String];
590 int returnCode =
ffmpeg_execute(([arguments count] + 1), commandCharPArray);
596 av_free(commandCharPArray[0]);
597 av_free(commandCharPArray);
603 NSString*
const LIB_NAME =
@"ffprobe";
608 char **commandCharPArray = (
char **)av_malloc(
sizeof(
char*) * ([arguments count] + 1));
614 commandCharPArray[0] = (
char *)av_malloc(
sizeof(
char) * ([LIB_NAME length] + 1));
615 strcpy(commandCharPArray[0], [LIB_NAME UTF8String]);
618 for (
int i=0; i < [arguments count]; i++) {
619 NSString *argument = [arguments objectAtIndex:i];
620 commandCharPArray[i + 1] = (
char *) [argument UTF8String];
630 int returnCode =
ffprobe_execute(([arguments count] + 1), commandCharPArray);
636 av_free(commandCharPArray[0]);
637 av_free(commandCharPArray);
670 lock = [[NSRecursiveLock alloc] init];
671 semaphore = dispatch_semaphore_create(0);
688 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
707 av_log_set_callback(av_log_default_callback);
713+ (
int)setFontconfigConfigurationPath:(NSString*)path {
717+ (void)setFontDirectory:(NSString*)fontDirectoryPath with:(NSDictionary*)fontNameMapping {
721+ (void)setFontDirectoryList:(NSArray*)fontDirectoryArray with:(NSDictionary*)fontNameMapping {
722 NSError *error = nil;
723 BOOL isDirectory = YES;
725 int validFontNameMappingCount = 0;
726 NSString *tempConfigurationDirectory = [NSTemporaryDirectory() stringByAppendingPathComponent:@"fontconfig"];
727 NSString *fontConfigurationFile = [tempConfigurationDirectory stringByAppendingPathComponent:@"fonts.conf"];
729 if (![[NSFileManager defaultManager] fileExistsAtPath:tempConfigurationDirectory isDirectory:&isDirectory]) {
730 if (![[NSFileManager defaultManager] createDirectoryAtPath:tempConfigurationDirectory withIntermediateDirectories:YES attributes:nil error:&error]) {
731 NSLog(
@"Failed to set font directory. Error received while creating temp conf directory: %@.", error);
734 NSLog(
@"Created temporary font conf directory: TRUE.");
737 if ([[NSFileManager defaultManager] fileExistsAtPath:fontConfigurationFile isDirectory:&isFile]) {
738 BOOL fontConfigurationDeleted = [[NSFileManager defaultManager] removeItemAtPath:fontConfigurationFile error:nil];
739 NSLog(
@"Deleted old temporary font configuration: %s.", fontConfigurationDeleted?
"TRUE":
"FALSE");
743 NSString *fontNameMappingBlock =
@"";
744 for (NSString *fontName in [fontNameMapping allKeys]) {
745 NSString *mappedFontName = [fontNameMapping objectForKey:fontName];
747 if ((fontName != nil) && (mappedFontName != nil) && ([fontName length] > 0) && ([mappedFontName length] > 0)) {
749 fontNameMappingBlock = [NSString stringWithFormat:@"%@\n%@\n%@%@%@\n%@\n%@\n%@%@%@\n%@\n%@\n",
750 @" <match target=\"pattern\">",
751 @" <test qual=\"any\" name=\"family\">",
752 @" <string>", fontName, @"</string>",
754 @" <edit name=\"family\" mode=\"assign\" binding=\"same\">",
755 @" <string>", mappedFontName, @"</string>",
759 validFontNameMappingCount++;
763 NSMutableString *fontConfiguration = [NSMutableString stringWithFormat:@"%@\n%@\n%@\n%@\n",
764 @"<?xml version=\"1.0\"?>",
765 @"<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">",
767 @" <dir prefix=\"cwd\">.</dir>"];
768 for (
int i=0; i < [fontDirectoryArray count]; i++) {
769 NSString *fontDirectoryPath = [fontDirectoryArray objectAtIndex:i];
770 [fontConfiguration appendString: @" <dir>"];
771 [fontConfiguration appendString: fontDirectoryPath];
772 [fontConfiguration appendString: @"</dir>"];
774 [fontConfiguration appendString:fontNameMappingBlock];
775 [fontConfiguration appendString:@"</fontconfig>"];
777 if (![fontConfiguration writeToFile:fontConfigurationFile atomically:YES encoding:NSUTF8StringEncoding error:&error]) {
778 NSLog(
@"Failed to set font directory. Error received while saving font configuration: %@.", error);
782 NSLog(
@"Saved new temporary font configuration with %d font name mappings.", validFontNameMappingCount);
786 for (
int i=0; i < [fontDirectoryArray count]; i++) {
787 NSString *fontDirectoryPath = [fontDirectoryArray objectAtIndex:i];
788 NSLog(
@"Font directory %@ registered successfully.", fontDirectoryPath);
793 NSError *error = nil;
797 NSString *cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
798 NSString *pipesDir = [cacheDir stringByAppendingPathComponent:@"pipes"];
800 if (![[NSFileManager defaultManager] fileExistsAtPath:pipesDir isDirectory:&isDirectory]) {
801 if (![[NSFileManager defaultManager] createDirectoryAtPath:pipesDir withIntermediateDirectories:YES attributes:nil error:&error]) {
802 NSLog(
@"Failed to create pipes directory: %@. Operation failed with %@.", pipesDir, error);
807 NSString *newFFmpegPipePath = [NSString stringWithFormat:@"%@/%@%ld", pipesDir, FFmpegKitNamedPipePrefix, [pipeIndexGenerator
getAndIncrement]];
812 int rc = mkfifo([newFFmpegPipePath UTF8String], S_IRWXU | S_IRWXG | S_IROTH);
814 return newFFmpegPipePath;
816 NSLog(
@"Failed to register new FFmpeg pipe %@. Operation failed with rc=%d.", newFFmpegPipePath, rc);
821+ (void)closeFFmpegPipe:(NSString*)ffmpegPipePath {
822 NSFileManager *fileManager = [NSFileManager defaultManager];
824 if ([fileManager fileExistsAtPath:ffmpegPipePath]){
825 [fileManager removeItemAtPath:ffmpegPipePath error:nil];
830 return [NSString stringWithUTF8String:FFMPEG_VERSION];
835 return [NSString stringWithFormat:@"%@-lts", FFmpegKitVersion];
842 #if defined(FFMPEG_KIT_LTS)
851 sprintf(buildDate,
"%d", FFMPEG_KIT_BUILD_DATE);
852 return [NSString stringWithUTF8String:buildDate];
855+ (
int)setEnvironmentVariable:(NSString*)variableName value:(NSString*)variableValue {
856 return setenv([variableName UTF8String], [variableValue UTF8String],
true);
859+ (void)ignoreSignal:(Signal)signal {
860 if (signal == SignalQuit) {
862 }
else if (signal == SignalInt) {
864 }
else if (signal == SignalTerm) {
866 }
else if (signal == SignalXcpu) {
868 }
else if (signal == SignalPipe) {
877 int returnCode =
executeFFmpeg([ffmpegSession getSessionId], [ffmpegSession getArguments]);
879 }
@catch (NSException *exception) {
880 [ffmpegSession
fail:exception];
881 NSLog(
@"FFmpeg execute failed: %@.%@", [
FFmpegKitConfig argumentsToString:[ffmpegSession getArguments]], [NSString stringWithFormat:
@"%@", [exception callStackSymbols]]);
889 int returnCode =
executeFFprobe([ffprobeSession getSessionId], [ffprobeSession getArguments]);
891 }
@catch (NSException *exception) {
892 [ffprobeSession
fail:exception];
893 NSLog(
@"FFprobe execute failed: %@.%@", [
FFmpegKitConfig argumentsToString:[ffprobeSession getArguments]], [NSString stringWithFormat:
@"%@", [exception callStackSymbols]]);
897+ (void)getMediaInformationExecute:(
MediaInformationSession*)mediaInformationSession withTimeout:(
int)waitTimeout {
901 int returnCodeValue =
executeFFprobe([mediaInformationSession getSessionId], [mediaInformationSession getArguments]);
903 [mediaInformationSession
complete:returnCode];
904 if ([returnCode isSuccess]) {
908 }
@catch (NSException *exception) {
909 [mediaInformationSession
fail:exception];
910 NSLog(
@"Get media information execute failed: %@.%@", [
FFmpegKitConfig argumentsToString:[mediaInformationSession getArguments]], [NSString stringWithFormat:
@"%@", [exception callStackSymbols]]);
918+ (void)asyncFFmpegExecute:(
FFmpegSession*)ffmpegSession onDispatchQueue:(dispatch_queue_t)queue {
919 dispatch_async(queue, ^{
922 if (globalExecuteCallback != nil) {
923 globalExecuteCallback(ffmpegSession);
927 if (sessionExecuteCallback != nil) {
928 sessionExecuteCallback(ffmpegSession);
937+ (void)asyncFFprobeExecute:(
FFprobeSession*)ffprobeSession onDispatchQueue:(dispatch_queue_t)queue {
938 dispatch_async(queue, ^{
941 if (globalExecuteCallback != nil) {
942 globalExecuteCallback(ffprobeSession);
946 if (sessionExecuteCallback != nil) {
947 sessionExecuteCallback(ffprobeSession);
952+ (void)asyncGetMediaInformationExecute:(
MediaInformationSession*)mediaInformationSession withTimeout:(
int)waitTimeout {
956+ (void)asyncGetMediaInformationExecute:(
MediaInformationSession*)mediaInformationSession onDispatchQueue:(dispatch_queue_t)queue withTimeout:(
int)waitTimeout {
957 dispatch_async(queue, ^{
960 if (globalExecuteCallback != nil) {
961 globalExecuteCallback(mediaInformationSession);
965 if (sessionExecuteCallback != nil) {
966 sessionExecuteCallback(mediaInformationSession);
991+ (void)setLogLevel:(
int)level {
995+ (NSString*)logLevelToString:(
int)level {
997 case LevelAVLogStdErr:
return @"STDERR";
998 case LevelAVLogTrace:
return @"TRACE";
999 case LevelAVLogDebug:
return @"DEBUG";
1000 case LevelAVLogVerbose:
return @"VERBOSE";
1001 case LevelAVLogInfo:
return @"INFO";
1002 case LevelAVLogWarning:
return @"WARNING";
1003 case LevelAVLogError:
return @"ERROR";
1004 case LevelAVLogFatal:
return @"FATAL";
1005 case LevelAVLogPanic:
return @"PANIC";
1006 case LevelAVLogQuiet:
return @"QUIET";
1007 default:
return @"";
1015+ (void)setSessionHistorySize:(
int)pSessionHistorySize {
1021 @throw([NSException exceptionWithName:NSInvalidArgumentException reason:@"Session history size must not exceed the hard limit!" userInfo:nil]);
1022 }
else if (pSessionHistorySize > 0) {
1027+ (id<
Session>)getSession:(
long)sessionId {
1028 [sessionHistoryLock lock];
1030 id<Session> session = [sessionHistoryMap objectForKey:[NSNumber numberWithLong:sessionId]];
1032 [sessionHistoryLock unlock];
1038 [sessionHistoryLock lock];
1040 id<Session> lastSession = [sessionHistoryList lastObject];
1042 [sessionHistoryLock unlock];
1048 id<Session> lastCompletedSession = nil;
1050 [sessionHistoryLock lock];
1053 id<Session> session = [sessionHistoryList objectAtIndex:i];
1054 if ([session getState] == SessionStateCompleted) {
1055 lastCompletedSession = session;
1060 [sessionHistoryLock unlock];
1062 return lastCompletedSession;
1066 [sessionHistoryLock lock];
1068 NSArray* sessionsCopy = [sessionHistoryList copy];
1070 [sessionHistoryLock unlock];
1072 return sessionsCopy;
1076 [sessionHistoryLock lock];
1078 [sessionHistoryList removeAllObjects];
1080 [sessionHistoryLock unlock];
1084 NSMutableArray* ffmpegSessions = [[NSMutableArray alloc] init];
1086 [sessionHistoryLock lock];
1088 for(
int i = 0; i < [sessionHistoryList count]; i++) {
1089 id<Session> session = [sessionHistoryList objectAtIndex:i];
1090 if ([session isFFmpeg]) {
1091 [ffmpegSessions addObject:session];
1095 [sessionHistoryLock unlock];
1097 return ffmpegSessions;
1101 NSMutableArray* ffprobeSessions = [[NSMutableArray alloc] init];
1103 [sessionHistoryLock lock];
1105 for(
int i = 0; i < [sessionHistoryList count]; i++) {
1106 id<Session> session = [sessionHistoryList objectAtIndex:i];
1107 if ([session isFFprobe]) {
1108 [ffprobeSessions addObject:session];
1112 [sessionHistoryLock unlock];
1114 return ffprobeSessions;
1117+ (NSArray*)getSessionsByState:(SessionState)state {
1118 NSMutableArray* sessions = [[NSMutableArray alloc] init];
1120 [sessionHistoryLock lock];
1122 for(
int i = 0; i < [sessionHistoryList count]; i++) {
1123 id<Session> session = [sessionHistoryList objectAtIndex:i];
1124 if ([session getState] == state) {
1125 [sessions addObject:session];
1129 [sessionHistoryLock unlock];
1138+ (void)setLogRedirectionStrategy:(LogRedirectionStrategy)logRedirectionStrategy {
1142+ (
int)messagesInTransmit:(
long)sessionId {
1146+ (NSString*)sessionStateToString:(SessionState)state {
1148 case SessionStateCreated:
return @"CREATED";
1149 case SessionStateRunning:
return @"RUNNING";
1150 case SessionStateFailed:
return @"FAILED";
1151 case SessionStateCompleted:
return @"COMPLETED";
1152 default:
return @"";
1156+ (NSArray*)parseArguments:(NSString*)command {
1157 NSMutableArray *argumentArray = [[NSMutableArray alloc] init];
1158 NSMutableString *currentArgument = [[NSMutableString alloc] init];
1160 bool singleQuoteStarted =
false;
1161 bool doubleQuoteStarted =
false;
1163 for (
int i = 0; i < command.length; i++) {
1164 unichar previousChar;
1166 previousChar = [command characterAtIndex:(i - 1)];
1170 unichar currentChar = [command characterAtIndex:i];
1172 if (currentChar ==
' ') {
1173 if (singleQuoteStarted || doubleQuoteStarted) {
1174 [currentArgument appendFormat: @"%C", currentChar];
1175 }
else if ([currentArgument length] > 0) {
1176 [argumentArray addObject: currentArgument];
1177 currentArgument = [[NSMutableString alloc] init];
1179 }
else if (currentChar ==
'\'' && (previousChar == 0 || previousChar !=
'\\')) {
1180 if (singleQuoteStarted) {
1181 singleQuoteStarted =
false;
1182 }
else if (doubleQuoteStarted) {
1183 [currentArgument appendFormat: @"%C", currentChar];
1185 singleQuoteStarted =
true;
1187 }
else if (currentChar ==
'\"' && (previousChar == 0 || previousChar !=
'\\')) {
1188 if (doubleQuoteStarted) {
1189 doubleQuoteStarted =
false;
1190 }
else if (singleQuoteStarted) {
1191 [currentArgument appendFormat: @"%C", currentChar];
1193 doubleQuoteStarted =
true;
1196 [currentArgument appendFormat: @"%C", currentChar];
1200 if ([currentArgument length] > 0) {
1201 [argumentArray addObject: currentArgument];
1204 return argumentArray;
1207+ (NSString*)argumentsToString:(NSArray*)arguments {
1208 if (arguments == nil) {
1212 NSMutableString *
string = [NSMutableString stringWithString:@""];
1213 for (
int i=0; i < [arguments count]; i++) {
1214 NSString *argument = [arguments objectAtIndex:i];
1216 [string appendString:@" "];
1218 [string appendString:argument];
void(^ ExecuteCallback)(id< Session > session)
int executeFFprobe(long sessionId, NSArray *arguments)
void callbackWait(int milliSeconds)
void ffmpegkit_log_callback_function(void *ptr, int level, const char *format, va_list vargs)
static atomic_short sessionMap[SESSION_MAP_SIZE]
void cancelSession(long sessionId)
static volatile NSMutableDictionary * sessionHistoryMap
static int sessionHistorySize
static NSRecursiveLock * lock
volatile int handleSIGINT
int ffprobe_execute(int argc, char **argv)
volatile int handleSIGTERM
void process_log(long sessionId, int levelValue, NSString *logMessage)
void ffmpegkit_statistics_callback_function(int frameNumber, float fps, float quality, int64_t size, int time, double bitrate, double speed)
static dispatch_queue_t asyncDispatchQueue
void removeSession(long sessionId)
void statisticsCallbackDataAdd(int frameNumber, float fps, float quality, int64_t size, int time, double bitrate, double speed)
static LogCallback logCallback
void callbackBlockFunction()
double _statisticsBitrate
void registerSessionId(long sessionId)
static NSRecursiveLock * sessionHistoryLock
static ExecuteCallback executeCallback
static dispatch_semaphore_t semaphore
static int redirectionEnabled
void resetMessagesInTransmit(long sessionId)
static NSMutableArray * callbackDataArray
CallbackData * callbackDataRemove()
int _statisticsFrameNumber
void process_statistics(long sessionId, int videoFrameNumber, float videoFps, float videoQuality, long size, int time, double bitrate, double speed)
int cancelRequested(long sessionId)
volatile int handleSIGPIPE
NSString *const FFmpegKitVersion
void logCallbackDataAdd(int level, NSString *logData)
volatile int handleSIGXCPU
static LogRedirectionStrategy globalLogRedirectionStrategy
static StatisticsCallback statisticsCallback
static atomic_int sessionInTransitMessageCountMap[SESSION_MAP_SIZE]
static AtomicLong * pipeIndexGenerator
static NSMutableArray * sessionHistoryList
typedef NS_ENUM(NSUInteger, CallbackType)
NSString *const FFmpegKitNamedPipePrefix
void addSessionToSessionHistory(id< Session > session)
int ffmpeg_execute(int argc, char **argv)
__thread volatile long globalSessionId
volatile int handleSIGQUIT
int executeFFmpeg(long sessionId, NSArray *arguments)
void(^ LogCallback)(Log *log)
void(^ StatisticsCallback)(Statistics *statistics)
void fail:(NSException *exception)
void complete:(ReturnCode *returnCode)
ExecuteCallback getExecuteCallback()
NSString * getAllLogsAsStringWithTimeout:(int waitTimeout)
void asyncFFmpegExecute:onDispatchQueue:(FFmpegSession *ffmpegSession,[onDispatchQueue] dispatch_queue_t queue)
NSArray * getFFmpegSessions()
LogRedirectionStrategy getLogRedirectionStrategy()
void getMediaInformationExecute:withTimeout:(MediaInformationSession *mediaInformationSession,[withTimeout] int waitTimeout)
void disableRedirection()
NSString * registerNewFFmpegPipe()
int setFontconfigConfigurationPath:(NSString *path)
ExecuteCallback getExecuteCallback()
NSString * getBuildDate()
void ffprobeExecute:(FFprobeSession *ffprobeSession)
NSArray * getFFprobeSessions()
void ffmpegExecute:(FFmpegSession *ffmpegSession)
int getSessionHistorySize()
id< Session > getSession:(long sessionId)
int setEnvironmentVariable:value:(NSString *variableName,[value] NSString *variableValue)
id< Session > getLastSession()
void asyncFFprobeExecute:onDispatchQueue:(FFprobeSession *ffprobeSession,[onDispatchQueue] dispatch_queue_t queue)
NSString * getFFmpegVersion()
void asyncGetMediaInformationExecute:onDispatchQueue:withTimeout:(MediaInformationSession *mediaInformationSession,[onDispatchQueue] dispatch_queue_t queue,[withTimeout] int waitTimeout)
void setFontDirectoryList:with:(NSArray *fontDirectoryList,[with] NSDictionary *fontNameMapping)
void closeFFmpegPipe:(NSString *ffmpegPipePath)
id< Session > getLastCompletedSession()
StatisticsCallback getStatisticsCallback()
void addStatistics:(Statistics *statistics)