use av_bprint methods to convert char* to nsstring, fixes #192

This commit is contained in:
Taner Sener 2021-10-19 23:33:19 +01:00
parent c514991b02
commit a72e3f501d

View File

@ -21,6 +21,7 @@
#import <sys/types.h> #import <sys/types.h>
#import <sys/stat.h> #import <sys/stat.h>
#import "libavutil/ffversion.h" #import "libavutil/ffversion.h"
#import "libavutil/bprint.h"
#import "fftools_ffmpeg.h" #import "fftools_ffmpeg.h"
#import "ArchDetect.h" #import "ArchDetect.h"
#import "AtomicLong.h" #import "AtomicLong.h"
@ -138,7 +139,7 @@ void addSessionToSessionHistory(id<Session> session) {
long _sessionId; // session id long _sessionId; // session id
int _logLevel; // log level int _logLevel; // log level
NSString* _logData; // log data AVBPrint _logData; // log data
int _statisticsFrameNumber; // statistics frame number int _statisticsFrameNumber; // statistics frame number
float _statisticsFps; // statistics fps float _statisticsFps; // statistics fps
@ -149,13 +150,14 @@ void addSessionToSessionHistory(id<Session> session) {
double _statisticsSpeed; // statistics speed double _statisticsSpeed; // statistics speed
} }
- (instancetype)init:(long)sessionId logLevel:(int)logLevel data:(NSString*)logData { - (instancetype)init:(long)sessionId logLevel:(int)logLevel data:(AVBPrint*)data {
self = [super init]; self = [super init];
if (self) { if (self) {
_type = LogType; _type = LogType;
_sessionId = sessionId; _sessionId = sessionId;
_logLevel = logLevel; _logLevel = logLevel;
_logData = logData; av_bprint_init(&_logData, 0, AV_BPRINT_SIZE_UNLIMITED);
av_bprintf(&_logData, "%s", data->str);
} }
return self; return self;
@ -197,8 +199,8 @@ void addSessionToSessionHistory(id<Session> session) {
return _logLevel; return _logLevel;
} }
- (NSString*)getLogData { - (AVBPrint*)getLogData {
return _logData; return &_logData;
} }
- (int)getStatisticsFrameNumber { - (int)getStatisticsFrameNumber {
@ -247,14 +249,79 @@ void callbackNotify() {
dispatch_semaphore_signal(semaphore); dispatch_semaphore_signal(semaphore);
} }
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(uint8_t *line) {
while(*line){
if(*line < 0x08 || (*line > 0x0D && *line < 0x20))
*line='?';
line++;
}
}
/** /**
* Adds log data to the end of callback data list. * Adds log data to the end of callback data list.
* *
* @param level log level * @param level log level
* @param logData log data * @param data log data
*/ */
void logCallbackDataAdd(int level, NSString *logData) { void logCallbackDataAdd(int level, AVBPrint *data) {
CallbackData* callbackData = [[CallbackData alloc] init:globalSessionId logLevel:level data:logData]; CallbackData* callbackData = [[CallbackData alloc] init:globalSessionId logLevel:level data:data];
[lock lock]; [lock lock];
[callbackDataArray addObject:callbackData]; [callbackDataArray addObject:callbackData];
@ -361,6 +428,9 @@ void resetMessagesInTransmit(long sessionId) {
* @param vargs arguments * @param vargs arguments
*/ */
void ffmpegkit_log_callback_function(void *ptr, int level, const char* format, va_list vargs) { 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 // DO NOT PROCESS UNWANTED LOGS
if (level >= 0) { if (level >= 0) {
@ -373,11 +443,26 @@ void ffmpegkit_log_callback_function(void *ptr, int level, const char* format, v
return; return;
} }
NSString *logData = [[NSString alloc] initWithFormat:[NSString stringWithCString:format encoding:NSUTF8StringEncoding] arguments:vargs]; av_bprint_init(&fullLine, 0, AV_BPRINT_SIZE_UNLIMITED);
if (logData.length > 0) { avutil_log_format_line(ptr, level, format, vargs, part, &print_prefix);
logCallbackDataAdd(level, logData); 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);
} }
/** /**
@ -395,9 +480,9 @@ void ffmpegkit_statistics_callback_function(int frameNumber, float fps, float qu
statisticsCallbackDataAdd(frameNumber, fps, quality, size, time, bitrate, speed); statisticsCallbackDataAdd(frameNumber, fps, quality, size, time, bitrate, speed);
} }
void process_log(long sessionId, int levelValue, NSString* logMessage) { void process_log(long sessionId, int levelValue, AVBPrint* logMessage) {
int activeLogLevel = av_log_get_level(); int activeLogLevel = av_log_get_level();
Log* log = [[Log alloc] init:sessionId:levelValue:logMessage]; Log* log = [[Log alloc] init:sessionId:levelValue:[NSString stringWithCString:logMessage->str encoding:NSUTF8StringEncoding]];
BOOL globalCallbackDefined = false; BOOL globalCallbackDefined = false;
BOOL sessionCallbackDefined = false; BOOL sessionCallbackDefined = false;
LogRedirectionStrategy activeLogRedirectionStrategy = globalLogRedirectionStrategy; LogRedirectionStrategy activeLogRedirectionStrategy = globalLogRedirectionStrategy;
@ -472,7 +557,7 @@ void process_log(long sessionId, int levelValue, NSString* logMessage) {
break; break;
default: default:
// WRITE TO NSLOG // WRITE TO NSLOG
NSLog(@"%@: %@", [FFmpegKitConfig logLevelToString:levelValue], logMessage); NSLog(@"%@: %@", [FFmpegKitConfig logLevelToString:levelValue], [NSString stringWithCString:logMessage->str encoding:NSUTF8StringEncoding]);
break; break;
} }
} }
@ -526,6 +611,7 @@ void callbackBlockFunction() {
if ([callbackData getType] == LogType) { if ([callbackData getType] == LogType) {
process_log([callbackData getSessionId], [callbackData getLogLevel], [callbackData getLogData]); process_log([callbackData getSessionId], [callbackData getLogLevel], [callbackData getLogData]);
av_bprint_finalize([callbackData getLogData], NULL);
} else { } else {
process_statistics([callbackData getSessionId], process_statistics([callbackData getSessionId],
[callbackData getStatisticsFrameNumber], [callbackData getStatisticsFrameNumber],