mirror of
https://github.com/zakk4223/CocoaSplit.git
synced 2026-05-15 14:15:50 -06:00
Convert source item outline view to use a data source instead of bound NSTreeController (was causing weird memory leaks..????)
Actually bounce the NDIReceiver audio delegate call through the requested queue Fixed drag and drop reorder bug with source lists that was preventing a source from being placed at the bottom
This commit is contained in:
parent
46362e71ce
commit
dfa4e76244
10 changed files with 161 additions and 57 deletions
|
|
@ -471,7 +471,6 @@
|
|||
|
||||
-(void)registerPCMOutput:(CMItemCount)frameCount audioFormat:(const AudioStreamBasicDescription *)audioFormat
|
||||
{
|
||||
|
||||
if (self.pcmPlayer)
|
||||
{
|
||||
//looks like we already have one?
|
||||
|
|
|
|||
|
|
@ -158,9 +158,11 @@
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
_pcmPlayer = [self createPCMInput:self.captureName withFormat:audioFormat];
|
||||
_pcmPlayer.name = self.captureName;
|
||||
//dispatch_async(dispatch_get_main_queue(), ^{
|
||||
_pcmPlayer = [self createPCMInput:self.captureName withFormat:audioFormat];
|
||||
_pcmPlayer.name = self.captureName;
|
||||
|
||||
// });
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -181,8 +183,6 @@
|
|||
-(void)NDIAudioOutput:(CAMultiAudioPCM *)pcmData fromReceiver:(CSNDIReceiver *)fromReceiver
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (!_pcmPlayer && self.isLive)
|
||||
{
|
||||
AudioStreamBasicDescription useFormat = pcmData.pcmFormat;
|
||||
|
|
@ -311,5 +311,16 @@
|
|||
return [bundle imageForResource:@"ndi_logo"];
|
||||
}
|
||||
|
||||
-(void)willDelete
|
||||
{
|
||||
NSLog(@"WILL DELEGTE");
|
||||
|
||||
[self deregisterPCMOutput];
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
NSLog(@"DEALLOC NDI");
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
CSNDISource *_ndi_source;
|
||||
CVPixelBufferPoolRef _cvpool;
|
||||
NSSize _currentSize;
|
||||
dispatch_queue_t _video_output_queue;
|
||||
dispatch_queue_t _audio_output_queue;
|
||||
__weak dispatch_queue_t _video_output_queue;
|
||||
__weak dispatch_queue_t _audio_output_queue;
|
||||
bool _stop_audio;
|
||||
bool _stop_video;
|
||||
bool _audio_running;
|
||||
|
|
|
|||
|
|
@ -243,7 +243,9 @@
|
|||
{
|
||||
memcpy(dBuf, audio_frame.p_data, 4*audio_frame.no_samples*audio_frame.no_channels);
|
||||
}
|
||||
[_audioDelegate NDIAudioOutput:retPCM fromReceiver:self];
|
||||
dispatch_async(_audio_output_queue, ^{
|
||||
[_audioDelegate NDIAudioOutput:retPCM fromReceiver:self];
|
||||
});
|
||||
}
|
||||
|
||||
dispatch->NDIlib_recv_free_audio(_receiver_instance, &audio_frame);
|
||||
|
|
|
|||
|
|
@ -423,7 +423,6 @@
|
|||
useEngine = layerSrc.sourceLayout.recorder.audioEngine;
|
||||
}
|
||||
}
|
||||
|
||||
if (!useEngine)
|
||||
{
|
||||
useEngine = [CaptureController sharedCaptureController].multiAudioEngine;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
// CocoaSplit
|
||||
//
|
||||
// Created by Zakk on 7/4/14.
|
||||
// Copyright (c) 2014 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CompressorBase.h"
|
||||
|
|
|
|||
|
|
@ -2502,6 +2502,9 @@ static NSArray *_sourceTypes = nil;
|
|||
|
||||
self.name = _editedName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(void) setSelectedVideoType:(NSString *)selectedVideoType
|
||||
{
|
||||
NSMutableDictionary *pluginMap = [[CSPluginLoader sharedPluginLoader] sourcePlugins];
|
||||
|
|
|
|||
|
|
@ -50,19 +50,73 @@
|
|||
|
||||
-(void)outlineViewDoubleClick:(NSOutlineView *)sender
|
||||
{
|
||||
NSTreeNode *node = [sender itemAtRow:sender.clickedRow];
|
||||
if (node)
|
||||
NSObject<CSInputSourceProtocol>*src = [sender itemAtRow:sender.clickedRow];
|
||||
if (src)
|
||||
{
|
||||
NSObject<CSInputSourceProtocol>*src = node.representedObject;
|
||||
[self openInputConfigWindows:@[src]];
|
||||
}
|
||||
}
|
||||
|
||||
-(id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
|
||||
{
|
||||
|
||||
if (!item)
|
||||
{
|
||||
SourceLayout *layout = self.sourceLayoutController.content;
|
||||
|
||||
return [layout.topLevelSourceList objectAtIndex:index];
|
||||
}
|
||||
|
||||
|
||||
NSObject<CSInputSourceProtocol> *useItem = item;
|
||||
if (useItem.isVideo)
|
||||
{
|
||||
InputSource *vItem = (InputSource *)useItem;
|
||||
return [vItem.attachedInputs objectAtIndex:index];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
-(BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
|
||||
{
|
||||
|
||||
if (!item)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
NSObject<CSInputSourceProtocol> *useItem = item;
|
||||
if (!useItem.isVideo)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
InputSource *vSrc = item;
|
||||
return vSrc.attachedInputs.count > 0;
|
||||
}
|
||||
|
||||
-(NSInteger) outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
|
||||
{
|
||||
if (!item)
|
||||
{
|
||||
SourceLayout *layout = self.sourceLayoutController.content;
|
||||
return layout.topLevelSourceList.count;
|
||||
}
|
||||
|
||||
NSObject<CSInputSourceProtocol> *useItem = item;
|
||||
if (useItem.isVideo)
|
||||
{
|
||||
InputSource *vItem = item;
|
||||
return vItem.attachedInputs.count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
-(void)outlineView:(NSOutlineView *)outlineView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row
|
||||
{
|
||||
|
||||
NSTreeNode *node = [outlineView itemAtRow:row];
|
||||
NSObject<CSInputSourceProtocol> *src = node.representedObject;
|
||||
NSObject<CSInputSourceProtocol> *src = [outlineView itemAtRow:row];
|
||||
if (!src.isVideo || !((InputSource *)src).parentInput)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
|
@ -72,15 +126,23 @@
|
|||
|
||||
}
|
||||
|
||||
-(NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
|
||||
{
|
||||
|
||||
NSTableCellView *ret = [outlineView makeViewWithIdentifier:@"defaultView" owner:self];
|
||||
ret.objectValue = item;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
-(BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pasteboard
|
||||
{
|
||||
|
||||
NSPasteboardItem *pItem = [[NSPasteboardItem alloc] init];
|
||||
|
||||
NSMutableArray *sourceIDS = [NSMutableArray array];
|
||||
for (NSTreeNode *node in items)
|
||||
for (NSObject<CSInputSourceProtocol>*iSrc in items)
|
||||
{
|
||||
NSObject<CSInputSourceProtocol> *iSrc = node.representedObject;
|
||||
NSString *iUUID = iSrc.uuid;
|
||||
[sourceIDS addObject:iUUID];
|
||||
|
||||
|
|
@ -93,12 +155,7 @@
|
|||
-(NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id<NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
|
||||
{
|
||||
|
||||
NSTreeNode *nodeItem = (NSTreeNode *)item;
|
||||
InputSource *nodeInput = nil;
|
||||
if (nodeItem)
|
||||
{
|
||||
nodeInput = nodeItem.representedObject;
|
||||
}
|
||||
InputSource *nodeInput = item;
|
||||
|
||||
|
||||
|
||||
|
|
@ -306,8 +363,7 @@
|
|||
|
||||
NSArray *draggedUUIDS = [pb propertyListForType:@"cocoasplit.input.item"];
|
||||
|
||||
NSTreeNode *parentNode = (NSTreeNode *)item;
|
||||
InputSource *parentSource = nil;
|
||||
InputSource *parentSource = item;
|
||||
|
||||
NSMutableDictionary *currentDepths = [NSMutableDictionary dictionary];
|
||||
|
||||
|
|
@ -317,32 +373,26 @@
|
|||
}
|
||||
|
||||
|
||||
NSIndexPath *droppedIdxPath = nil;
|
||||
|
||||
if (parentNode)
|
||||
{
|
||||
parentSource = parentNode.representedObject;
|
||||
droppedIdxPath = [[parentNode indexPath] indexPathByAddingIndex:index];
|
||||
} else {
|
||||
droppedIdxPath = [NSIndexPath indexPathWithIndex:index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
NSTreeNode *idxNode = nil;
|
||||
NSObject <CSInputSourceProtocol> *iSrc = nil;
|
||||
float newDepth = 1;
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
newDepth = -FLT_MAX;
|
||||
} else {
|
||||
idxNode = [self.sourceTreeController.arrangedObjects descendantNodeAtIndexPath:droppedIdxPath];
|
||||
|
||||
if (index < [outlineView numberOfChildrenOfItem:item])
|
||||
{
|
||||
iSrc = [outlineView child:index ofItem:item];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (idxNode)
|
||||
if (iSrc)
|
||||
{
|
||||
NSObject<CSInputSourceProtocol> *iSrc = idxNode.representedObject;
|
||||
if (iSrc.isVideo)
|
||||
{
|
||||
InputSource *dSrc = (InputSource *)iSrc;
|
||||
|
|
@ -382,6 +432,7 @@
|
|||
[parentSource attachInput:iSrc];
|
||||
[[undoManager prepareWithInvocationTarget:self] detachSourcesByUUID:@[iSrc.uuid]];
|
||||
}
|
||||
|
||||
iSrc.depth = newDepth++;
|
||||
}
|
||||
|
||||
|
|
@ -533,10 +584,29 @@
|
|||
|
||||
_activeConfigWindows = [NSMutableDictionary dictionary];
|
||||
_activeConfigControllers = [NSMutableDictionary dictionary];
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
|
||||
{
|
||||
|
||||
if ([keyPath isEqualToString:@"content.topLevelSourceList"])
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.sourceOutlineView reloadData];
|
||||
});
|
||||
}
|
||||
}
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
if (self.sourceLayoutController)
|
||||
{
|
||||
[self.sourceLayoutController addObserver:self forKeyPath:@"content.topLevelSourceList" options:NSKeyValueObservingOptionNew context:NULL];
|
||||
}
|
||||
// Do view setup here.
|
||||
}
|
||||
|
||||
|
|
@ -607,11 +677,26 @@
|
|||
|
||||
|
||||
|
||||
-(NSArray *)getSelectedItems
|
||||
{
|
||||
NSIndexSet *selectedRows = [self.sourceOutlineView selectedRowIndexes];
|
||||
NSMutableArray *selectedItems = [NSMutableArray array];
|
||||
|
||||
[selectedRows enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
id item = [self.sourceOutlineView itemAtRow:idx];
|
||||
if (item)
|
||||
{
|
||||
[selectedItems addObject:item];
|
||||
}
|
||||
}];
|
||||
|
||||
return selectedItems;
|
||||
}
|
||||
|
||||
-(IBAction)sourceDeleteClicked:(NSButton *)sender
|
||||
{
|
||||
|
||||
NSArray *selectedSources = self.sourceTreeController.selectedObjects;
|
||||
NSArray *selectedSources = [self getSelectedItems];
|
||||
|
||||
NSUndoManager *undoManager = self.view.window.undoManager;
|
||||
|
||||
|
|
@ -640,6 +725,8 @@
|
|||
[undoMap addObject:undoEntry];
|
||||
}
|
||||
|
||||
self.selectedObjects = @[];
|
||||
|
||||
NSData *undoData = [NSKeyedArchiver archivedDataWithRootObject:undoMap];
|
||||
[[undoManager prepareWithInvocationTarget:self] undoDeleteSources:undoData];
|
||||
}
|
||||
|
|
@ -647,7 +734,7 @@
|
|||
|
||||
-(IBAction)sourceConfigClicked:(NSButton *)sender
|
||||
{
|
||||
NSArray *selectedSources = self.sourceTreeController.selectedObjects;
|
||||
NSArray *selectedSources = [self getSelectedItems];
|
||||
[self openInputConfigWindows:selectedSources];
|
||||
}
|
||||
|
||||
|
|
@ -661,20 +748,23 @@
|
|||
|
||||
-(void)highlightSources:(NSArray *)sources
|
||||
{
|
||||
[self.sourceTreeController setSelectionIndexPaths:@[]];
|
||||
NSMutableIndexSet *selectedRows = [[NSMutableIndexSet alloc] init];
|
||||
|
||||
for (NSObject *src in sources)
|
||||
{
|
||||
NSIndexPath *srcPath = [self.sourceTreeController indexPathOfObject:src];
|
||||
if (srcPath)
|
||||
{
|
||||
[self.sourceTreeController addSelectionIndexPaths:@[srcPath]];
|
||||
}
|
||||
NSInteger idx = [self.sourceOutlineView rowForItem:src];
|
||||
|
||||
[selectedRows addIndex:idx];
|
||||
}
|
||||
|
||||
[self.sourceOutlineView selectRowIndexes:selectedRows byExtendingSelection:NO];
|
||||
}
|
||||
|
||||
-(void)outlineViewSelectionDidChange:(NSNotification *)notification
|
||||
{
|
||||
self.selectedObjects = self.sourceTreeController.selectedObjects;
|
||||
|
||||
self.selectedObjects = [self getSelectedItems];
|
||||
|
||||
}
|
||||
|
||||
-(void)menuEndedTracking:(NSNotification *)notification
|
||||
|
|
@ -941,5 +1031,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
if (self.sourceLayoutController)
|
||||
{
|
||||
[self.sourceLayoutController removeObserver:self forKeyPath:@"content.topLevelSourceList"];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="K7P-gj-44p">
|
||||
<tableCellView identifier="defaultView" id="K7P-gj-44p">
|
||||
<rect key="frame" x="1" y="1" width="415" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
|
|
@ -106,8 +106,6 @@
|
|||
</tableColumns>
|
||||
<connections>
|
||||
<action trigger="doubleAction" selector="outlineViewDoubleClick:" target="-2" id="SnR-fY-bsU"/>
|
||||
<binding destination="d5r-1v-wmD" name="content" keyPath="arrangedObjects" id="REu-8i-kkD"/>
|
||||
<binding destination="d5r-1v-wmD" name="selectionIndexPaths" keyPath="selectionIndexPaths" previousBinding="REu-8i-kkD" id="Ccb-Xm-9EN"/>
|
||||
<outlet property="dataSource" destination="-2" id="J0b-9p-2zz"/>
|
||||
<outlet property="delegate" destination="-2" id="sxE-KE-Fjx"/>
|
||||
</connections>
|
||||
|
|
@ -192,11 +190,7 @@ CA
|
|||
</constraints>
|
||||
<point key="canvasLocation" x="-90" y="137.5"/>
|
||||
</customView>
|
||||
<treeController childrenKeyPath="attachedInputs" id="d5r-1v-wmD" userLabel="sourceTreeController">
|
||||
<connections>
|
||||
<binding destination="-2" name="contentArray" keyPath="self.sourceLayoutController.selection.topLevelSourceList" id="jp4-cZ-FTe"/>
|
||||
</connections>
|
||||
</treeController>
|
||||
<treeController childrenKeyPath="attachedInputs" id="d5r-1v-wmD" userLabel="sourceTreeController"/>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="NSActionTemplate" width="14" height="14"/>
|
||||
|
|
|
|||
|
|
@ -497,7 +497,7 @@ JS_EXPORT void JSSynchronousGarbageCollectForDebugging(JSContextRef ctx);
|
|||
NSMutableArray *tmpArray = [NSMutableArray array];
|
||||
|
||||
NSMutableArray *noLayer = [NSMutableArray array];
|
||||
float currentDepth = 0.0f;
|
||||
float currentDepth = 100.0f;
|
||||
|
||||
[self willChangeValueForKey:@"topLevelSourceList"];
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue