Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fixed one frame memory leak in FFMPEG player input
Small changes to SourceLayout; it allocates root and transition layers on demand, so non-visible copies of a layout do not incur any potential CALayer/video resource waste
  • Loading branch information
zakk4223 committed Jul 28, 2018
1 parent efc1325 commit 6b25be1
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 25 deletions.
18 changes: 17 additions & 1 deletion CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegInput.m
Expand Up @@ -569,6 +569,7 @@ -(void)readAndDecodeVideoFrames:(int)frameCnt
{
self.is_ready = YES;
dispatch_semaphore_wait(_read_loop_semaphore, DISPATCH_TIME_FOREVER);

}
}
}
Expand Down Expand Up @@ -708,7 +709,6 @@ -(void)closeMedia

-(void) internal_closeMedia
{

struct frame_message msg;

if (_video_message_queue)
Expand Down Expand Up @@ -745,6 +745,14 @@ -(void) internal_closeMedia

if (_video_codec_ctx)
{
AVFrame *outFrame = av_frame_alloc();
avcodec_send_packet(_video_codec_ctx, NULL);
while (avcodec_receive_frame(_video_codec_ctx, outFrame) != AVERROR_EOF)
{
av_frame_unref(outFrame);
}

av_frame_free(&outFrame);

avcodec_close(_video_codec_ctx);
avcodec_free_context(&_video_codec_ctx);
Expand All @@ -754,6 +762,14 @@ -(void) internal_closeMedia

if (_audio_codec_ctx)
{
AVFrame *outFrame = av_frame_alloc();
avcodec_send_packet(_audio_codec_ctx, NULL);
while (avcodec_receive_frame(_audio_codec_ctx, outFrame) != AVERROR_EOF)
{
av_frame_unref(outFrame);
}

av_frame_free(&outFrame);
avcodec_close(_audio_codec_ctx);
avcodec_free_context(&_audio_codec_ctx);

Expand Down
21 changes: 13 additions & 8 deletions CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegPlayer.m
Expand Up @@ -290,8 +290,8 @@ -(void)playItem:(CSFFMpegInput *)item

-(void)enqueueItem:(CSFFMpegInput *)item
{
[self insertObject:item inInputQueueAtIndex:self.inputQueue.count];
if (self.inputQueue.count == 1)
[self insertObject:item inInputQueueAtIndex:self.inputQueue.count];
if (self.inputQueue.count == 1)
{
[item openMedia:20];
}
Expand Down Expand Up @@ -432,7 +432,6 @@ -(void)audioThread
if (!self.playing) break;
}
}

_audio_done = YES;
[self inputDone];
}
Expand Down Expand Up @@ -510,8 +509,9 @@ -(CVPixelBufferRef)frameForMediaTime:(CFTimeInterval)mediaTime
bool play_audio = YES;


int av_error = 0;

int av_error = 0;

if (_first_frame_host_time == 0)
{
play_audio = NO;
Expand Down Expand Up @@ -568,8 +568,10 @@ -(CVPixelBufferRef)frameForMediaTime:(CFTimeInterval)mediaTime
{
av_frame_unref(use_frame);
av_frame_free(&use_frame);
use_frame = _peek_frame;

}

use_frame = _peek_frame;
consumed++;
}
if (av_error == AVERROR_EOF)
Expand Down Expand Up @@ -604,8 +606,7 @@ -(CVPixelBufferRef)frameForMediaTime:(CFTimeInterval)mediaTime
self.lastVideoTime = use_frame->pts * av_q2d(_useInput.videoTimeBase);

ret = [self convertFrameToPixelBuffer:use_frame];
av_frame_unref(use_frame);
av_frame_free(&use_frame);

CVPixelBufferRetain(ret);
if (_last_buf)
{
Expand All @@ -616,7 +617,11 @@ -(CVPixelBufferRef)frameForMediaTime:(CFTimeInterval)mediaTime
CVPixelBufferRetain(_last_buf);
ret = _last_buf;
}

if (use_frame)
{
av_frame_unref(use_frame);
av_frame_free(&use_frame);
}
[self inputDone];
return ret;
}
Expand Down
4 changes: 2 additions & 2 deletions CocoaSplit/CaptureController.m
Expand Up @@ -3697,7 +3697,7 @@ -(void)undoSwitchToLayout:(SourceLayout *)usingLayout previousLayout:(SourceLayo

[usingLayout saveSourceList];
SourceLayout *undoCopy = usingLayout.copy;
[undoCopy clearSourceList];
//[undoCopy clearSourceList];
[usingLayout replaceWithSourceLayout:previousLayout];

[[self.mainWindow.undoManager prepareWithInvocationTarget:self] switchToLayout:undoCopy usingLayout:usingLayout];
Expand All @@ -3713,7 +3713,7 @@ -(void)switchToLayout:(SourceLayout *)layout usingLayout:(SourceLayout *)usingLa

[usingLayout saveSourceList];
SourceLayout *undoCopy = usingLayout.copy;
[undoCopy clearSourceList];
//[undoCopy clearSourceList];
[[self.mainWindow.undoManager prepareWithInvocationTarget:self] undoSwitchToLayout:usingLayout previousLayout:undoCopy];
[self applyTransitionSettings:usingLayout];

Expand Down
7 changes: 6 additions & 1 deletion CocoaSplit/Interface/CSLayoutButtonView.m
Expand Up @@ -88,7 +88,7 @@ -(void)rightMouseDown:(NSEvent *)theEvent

-(void)updateLayer
{
CGColorRef backgroundColor;
CGColorRef backgroundColor = NULL;
CGFloat useAlpha = 1.0f;


Expand All @@ -109,6 +109,11 @@ -(void)updateLayer
backgroundColor = CGColorCreateGenericRGB(0.353f, 0.534f, 0.434, useAlpha);
}
self.layer.backgroundColor = backgroundColor;
if (backgroundColor)
{
CGColorRelease(backgroundColor);
}

self.layer.cornerRadius = 5.0f;
}

Expand Down
Expand Up @@ -24,6 +24,7 @@ - (NSScriptObjectSpecifier *)objectSpecifier {
}
-(void)scriptActivate:(NSScriptCommand *)command
{

[CaptureController sharedCaptureController].activeTransition = self;
}

Expand Down
Expand Up @@ -103,6 +103,7 @@ -(void)scriptRemoveLayout:(NSScriptCommand *)command

-(void)scriptSwitchToLayout:(NSScriptCommand *)command
{

SourceLayout *useLayout = [self getUseLayout:command];

[[CaptureController sharedCaptureController] switchToLayout:self usingLayout:useLayout];
Expand Down
65 changes: 59 additions & 6 deletions CocoaSplit/SourceLayout.m
Expand Up @@ -50,17 +50,14 @@ @implementation SourceLayout
@synthesize layoutTimingSource = _layoutTimingSource;
@synthesize startColor = _startColor;
@synthesize stopColor = _stopColor;
@synthesize rootLayer = _rootLayer;
@synthesize transitionLayer = _transitionLayer;

-(instancetype) init
{
if (self = [super init])
{
self.containerOnly = NO;

_sourceDepthSorter = [[NSSortDescriptor alloc] initWithKey:@"depth" ascending:YES];
_sourceDepthSorterRev = [[NSSortDescriptor alloc] initWithKey:@"depth" ascending:NO];

_sourceUUIDSorter = [[NSSortDescriptor alloc] initWithKey:@"uuid" ascending:YES];
_frameRate = 30;
_canvas_height = 720;
_canvas_width = 1280;
Expand All @@ -74,10 +71,10 @@ -(instancetype) init

_containedLayouts = [[NSMutableArray alloc] init];
_topLevelSourceArray = [[NSMutableArray alloc] init];
//self.rootLayer.geometryFlipped = YES;
self.rootLayer = [self newRootLayer];
self.transitionLayer = [self newTransitionLayer];
[self.transitionLayer addSublayer:self.rootLayer];
//self.rootLayer.geometryFlipped = YES;
_rootSize = NSMakeSize(_canvas_width, _canvas_height);
self.sourceList = [NSMutableArray array];
self.sourceListPresentation = [NSMutableArray array];
Expand All @@ -102,6 +99,47 @@ -(instancetype) init
return self;
}

-(void)setTransitionLayer:(CALayer *)transitionLayer
{
_transitionLayer = transitionLayer;
}

-(CALayer *)transitionLayer
{
/* lazy allocation */
if (!_transitionLayer)
{
_transitionLayer = [self newTransitionLayer];
if (!_rootLayer)
{
/* getter allocs a new instance if needed */
[_transitionLayer addSublayer:self.rootLayer];
}
}
return _transitionLayer;
}


-(void)setRootLayer:(CAGradientLayer *)rootLayer
{
_rootLayer = rootLayer;
}

-(CAGradientLayer *) rootLayer
{
/* lazy allocation */
if (!_rootLayer)
{
_rootLayer = [self newRootLayer];
if (!_transitionLayer)
{
/* getter allocs a new instance if needed */
[self.transitionLayer addSublayer:_rootLayer];
}
}
return _rootLayer;
}


-(NSString *)undoNameForKeyPath:(NSString *)keyPath usingValue:(id)propertyValue
{
Expand Down Expand Up @@ -392,6 +430,7 @@ -(void)doAnimation:(NSDictionary *)threadDict
@try {

[CATransaction begin];

[CATransaction setCompletionBlock:^{
[self.pendingScripts removeObjectForKey:runUUID];
if (completionBlock)
Expand Down Expand Up @@ -712,12 +751,26 @@ -(NSArray *)sourceListOrdered:(bool)depthReverse
NSSortDescriptor *depthSorter = nil;
if (depthReverse)
{
if (!_sourceDepthSorterRev)
{
_sourceDepthSorterRev = [[NSSortDescriptor alloc] initWithKey:@"depth" ascending:NO];
}
depthSorter = _sourceDepthSorterRev;
} else {
if (!_sourceDepthSorter)
{
_sourceDepthSorter = [[NSSortDescriptor alloc] initWithKey:@"depth" ascending:YES];
}
depthSorter = _sourceDepthSorter;
}


if (!_sourceUUIDSorter)
{
_sourceUUIDSorter = [[NSSortDescriptor alloc] initWithKey:@"uuid" ascending:YES];

}

NSArray *listCopy = [mylist sortedArrayUsingDescriptors:@[depthSorter, _sourceUUIDSorter]];
return listCopy;
}
Expand Down
17 changes: 10 additions & 7 deletions CocoaSplit/Transitions/CSTransitionInput.m
Expand Up @@ -64,6 +64,7 @@ -(void)encodeWithCoder:(NSCoder *)aCoder
[aCoder encodeBool:self.transitionAfterPre forKey:@"transitionAfterPre"];
[aCoder encodeBool:self.wholeLayout forKey:@"wholeLayout"];
[aCoder encodeObject:_savedInputName forKey:@"savedInputName"];

}


Expand Down Expand Up @@ -131,8 +132,10 @@ -(NSString *)name
ret = _savedInputName;
}
}

if (!ret && self.inputSource)
{

ret = self.inputSource.name;
}
return ret;
Expand All @@ -141,7 +144,10 @@ -(NSString *)name
-(void)setInputSource:(NSObject<CSInputSourceProtocol> *)inputSource
{
_inputSource = inputSource;
_savedInputName = inputSource.name;
if (inputSource)
{
_savedInputName = inputSource.name;
}
if (inputSource && inputSource.isVideo)
{
[(InputSource *)inputSource frameTick];
Expand Down Expand Up @@ -206,12 +212,8 @@ -(NSString *)preChangeAction:(SourceLayout *)targetLayout
return nil;
}

//self.inputSource.persistent = YES;
//self.inputSource.isTransitionInput = YES;
if (self.inputSource.isVideo)
{
//[(InputSource *)self.inputSource autoCenter];
}
self.inputSource.persistent = YES;
self.inputSource.isTransitionInput = YES;

self.inputSourceUUID = self.inputSource.uuid;
NSMutableString *scriptRet = [NSMutableString string];
Expand Down Expand Up @@ -289,6 +291,7 @@ -(NSString *)postChangeAction:(SourceLayout *)targetLayout
{
ret = [NSKeyedUnarchiver unarchiveObjectWithData:self.inputSourceSavedata];
}

return ret;
}

Expand Down

0 comments on commit 6b25be1

Please sign in to comment.