Skip to content

Commit

Permalink
Added delay option for outputs, fixed preview view sometimes causing …
Browse files Browse the repository at this point in the history
…fullscreen performance issues with other openGL applications. Stream warning colors.
  • Loading branch information
Zakk authored and Zakk committed Jun 22, 2014
1 parent 7651190 commit cb4a07d
Show file tree
Hide file tree
Showing 13 changed files with 600 additions and 220 deletions.
11 changes: 11 additions & 0 deletions CocoaSplit/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
}


-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
if (self.captureController)
{
return [self.captureController applicationShouldTerminate:sender];
}

return NSTerminateNow;
}


-(void) applicationWillTerminate: (NSNotification *)notification
{

Expand Down
16 changes: 15 additions & 1 deletion CocoaSplit/CaptureController.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ void VideoCompressorReceiveFrame(void *, void *, OSStatus , VTEncodeInfoFlags ,
dispatch_queue_t _main_capture_queue;
dispatch_queue_t _preview_queue;
dispatch_source_t _dispatch_timer;
dispatch_source_t _statistics_timer;

CFAbsoluteTime _frame_interval;
mach_timebase_info_data_t _mach_timebase;
double _frame_time;
Expand All @@ -65,7 +67,9 @@ void VideoCompressorReceiveFrame(void *, void *, OSStatus , VTEncodeInfoFlags ,
NSMutableArray *audioBuffer;
NSMutableArray *videoBuffer;
dispatch_source_t _log_source;

int _saved_stderr;





Expand Down Expand Up @@ -208,11 +212,14 @@ void VideoCompressorReceiveFrame(void *, void *, OSStatus , VTEncodeInfoFlags ,
@property (strong) NSPipe *loggingPipe;
@property (strong) NSFileHandle *logReadHandle;

@property (assign) bool useStatusColors;

@property (unsafe_unretained) IBOutlet NSTextView *logTextView;





- (void) outputSampleBuffer:(CMSampleBufferRef)theBuffer;
- (void) outputAVPacket:(AVPacket *)avpkt codec_ctx:(AVCodecContext *)codec_ctx;
- (void)saveSettings;
Expand All @@ -223,6 +230,13 @@ void VideoCompressorReceiveFrame(void *, void *, OSStatus , VTEncodeInfoFlags ,
-(void)setExtraData:(id)saveData forKey:(NSString *)forKey;
-(id)getExtraData:(NSString *)forkey;
-(CVPixelBufferRef)currentFrame;
-(double)mach_time_seconds;
-(bool)pendingStreamConfirmation:(NSString *)queryString;
-(int)streamsPendingCount;
-(int)streamsActiveCount;
-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
-(NSColor *)statusColor;


-(void)setupLogging;

Expand Down
192 changes: 178 additions & 14 deletions CocoaSplit/CaptureController.m
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,11 @@ -(id) init
{


#ifndef DEBUG
[self setupLogging];
#endif



audioLastReadPosition = 0;
audioWritePosition = 0;
Expand All @@ -392,6 +396,8 @@ -(id) init
videoBuffer = [[NSMutableArray alloc] init];


self.useStatusColors = YES;


dispatch_source_t sigsrc = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGPIPE, 0, dispatch_get_global_queue(0, 0));
dispatch_source_set_event_handler(sigsrc, ^{ return;});
Expand Down Expand Up @@ -470,6 +476,22 @@ -(id) init
dispatch_resume(_dispatch_timer);
*/

_statistics_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());

dispatch_source_set_timer(_statistics_timer, DISPATCH_TIME_NOW, 1*NSEC_PER_SEC, 0);
dispatch_source_set_event_handler(_statistics_timer, ^{

for (OutputDestination *outdest in _captureDestinations)
{
[outdest updateStatistics];
}

});

dispatch_resume(_statistics_timer);


self.extraSaveData = [[NSMutableDictionary alloc] init];


Expand All @@ -483,6 +505,22 @@ -(id) init
}


-(NSColor *)statusColor
{
if (self.captureRunning && [self streamsActiveCount] > 0)
{
return [NSColor redColor];
}

if ([self streamsPendingCount] > 0)
{
return [NSColor orangeColor];
}

return [NSColor blackColor];
}


- (NSString *) saveFilePath
{

Expand Down Expand Up @@ -543,6 +581,7 @@ -(void)setupLogging
self.loggingPipe = [NSPipe pipe];

self.logReadHandle = [self.loggingPipe fileHandleForReading];

dup2([[self.loggingPipe fileHandleForWriting] fileDescriptor], fileno(stderr));

_log_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, [self.logReadHandle fileDescriptor], 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
Expand All @@ -559,6 +598,7 @@ -(void)setupLogging
if (read_size > 0)
{


dispatch_async(dispatch_get_main_queue(), ^{
NSString *logStr = [[NSString alloc] initWithBytesNoCopy:data length:read_size encoding:NSUTF8StringEncoding freeWhenDone:YES];
[self appendToLogView:logStr];
Expand Down Expand Up @@ -608,6 +648,7 @@ -(void) saveSettings
[saveRoot setValue:[NSNumber numberWithInt:self.maxOutputPending] forKey:@"maxOutputPending"];
[saveRoot setValue:self.resolutionOption forKey:@"resolutionOption"];
[saveRoot setValue:[NSNumber numberWithDouble:self.audio_adjust] forKey:@"audioAdjust"];
[saveRoot setValue: [NSNumber numberWithBool:self.useStatusColors] forKey:@"useStatusColors"];



Expand Down Expand Up @@ -651,6 +692,14 @@ -(void) loadSettings
}


for (OutputDestination *outdest in _captureDestinations)
{
outdest.settingsController = self;
}


self.useStatusColors = [[saveRoot valueForKeyPath:@"useStatusColors"] boolValue];

self.x264tune = [saveRoot valueForKey:@"x264tune"];
self.x264preset = [saveRoot valueForKey:@"x264preset"];
self.x264profile = [saveRoot valueForKey:@"x264profile"];
Expand Down Expand Up @@ -752,7 +801,7 @@ - (IBAction)addStreamingService:(id)sender {


[[self mutableArrayValueForKey:@"captureDestinations"] addObject:newDest];
[newDest attachOutput:self];
newDest.settingsController = self;
[self closeCreateSheet:nil];

}
Expand Down Expand Up @@ -809,13 +858,8 @@ - (void) outputEncodedData:(CapturedFrameData *)newFrameData

for (OutputDestination *outdest in _captureDestinations)
{
if (outdest.active)
{

id ffmpeg = outdest.ffmpeg_out;
[ffmpeg writeEncodedData:frameData];

}
[outdest writeEncodedData:frameData];

}

}
Expand Down Expand Up @@ -935,6 +979,12 @@ -(bool) startStream

}

for (OutputDestination *outdest in _captureDestinations)
{
[outdest reset];
}


self.captureRunning = YES;

return YES;
Expand Down Expand Up @@ -1106,6 +1156,7 @@ -(void) loadCmdlineSettings:(NSUserDefaults *)cmdargs

newDest.active = YES;
newDest.destination = outstr;
newDest.settingsController = self;
[[self mutableArrayValueForKey:@"captureDestinations"] addObject:newDest];
}

Expand Down Expand Up @@ -1154,6 +1205,13 @@ - (IBAction)streamButtonPushed:(id)sender {

if ([button state] == NSOnState)
{
if ([self pendingStreamConfirmation:@"Start streaming?"] == NO)
{
[sender setNextState];
return;
}



if ([self startStream] == YES)
{
Expand Down Expand Up @@ -1287,8 +1345,11 @@ -(BOOL) setupResolution:(CVImageBufferRef)withFrame error:(NSError **)therror

-(double)mach_time_seconds
{
double retval;

uint64_t mach_now = mach_absolute_time();
return (double)((mach_now * _mach_timebase.numer / _mach_timebase.denom))/NSEC_PER_SEC;
retval = (double)((mach_now * _mach_timebase.numer / _mach_timebase.denom))/NSEC_PER_SEC;
return retval;
}


Expand Down Expand Up @@ -1472,16 +1533,15 @@ -(void) newFrame
{
[self stopStream];
[NSApp presentError:error];
} else {
/*} else {
OutputDestination *output;
NSLog(@"Attaching destinations");
for (output in _captureDestinations)
{
[output attachOutput:self];
output.settingsController = self;
}
}
*/}

}

Expand All @@ -1494,10 +1554,17 @@ -(void) newFrame
capturedData.videoFrame = newFrame;

[self processVideoFrame:capturedData];
//} else {
} else {
for (OutputDestination *outdest in _captureDestinations)
{
[outdest writeEncodedData:nil];
}

}




CVPixelBufferRelease(newFrame);


Expand Down Expand Up @@ -1569,6 +1636,78 @@ -(void)processVideoFrame:(CapturedFrameData *)frameData

}

-(int)streamsActiveCount
{
int ret = 0;
for (OutputDestination *outdest in _captureDestinations)
{
if (outdest.active)
{
ret++;
}
}

return ret;
}


-(int)streamsPendingCount
{
int ret = 0;

for (OutputDestination *outdest in _captureDestinations)
{
if (outdest.buffer_draining)
{
ret++;
}
}

return ret;
}


-(bool)actionConfirmation:(NSString *)queryString infoString:(NSString *)infoString
{

bool retval;

NSAlert *confirmationAlert = [[NSAlert alloc] init];
[confirmationAlert addButtonWithTitle:@"Yes"];
[confirmationAlert addButtonWithTitle:@"No"];
[confirmationAlert setMessageText:queryString];
if (infoString)
{
[confirmationAlert setInformativeText:infoString];
}

[confirmationAlert setAlertStyle:NSWarningAlertStyle];

if ([confirmationAlert runModal] == NSAlertFirstButtonReturn)
{
retval = YES;
} else {
retval = NO;
}

return retval;
}


-(bool)pendingStreamConfirmation:(NSString *)queryString
{
int pending_count = [self streamsPendingCount];
bool retval;

if (pending_count > 0)
{
retval = [self actionConfirmation:queryString infoString:[NSString stringWithFormat:@"There are %d streams pending output", pending_count]];
} else {
retval = YES;
}

return retval;
}

- (void) setNilValueForKey:(NSString *)key
{
Expand All @@ -1594,5 +1733,30 @@ - (IBAction)removeDestination:(id)sender

}];

}

-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{


if (self.captureRunning && [self streamsActiveCount] > 0)

{
if ([self actionConfirmation:@"Really quit?" infoString:@"There are still active outputs"])
{
return NSTerminateNow;
} else {
return NSTerminateCancel;
}
}

if ([self pendingStreamConfirmation:@"Quit now?"])
{
return NSTerminateNow;
} else {
return NSTerminateCancel;
}
return NSTerminateNow;

}
@end
Loading

0 comments on commit cb4a07d

Please sign in to comment.