Layoutrecorders now add audio tracks to their map dynamically as they are created. This fixes the main layout recorder not seeing new tracks since it is active from program start now.

This commit is contained in:
Zakk 2020-02-23 23:18:40 -05:00
parent 805fef9159
commit 8cbac8a54a
8 changed files with 108 additions and 56 deletions

View file

@ -86,5 +86,6 @@
-(instancetype)initWithDefaultTrackUUID:(NSString *)outputUUID;
-(CAMultiAudioInput *)findInputForSystemUUID:(NSString *)uuid;
-(CAMultiAudioInput *)createInputForSystemUUID:(NSString *)uuid;
-(void)startEncoder:(NSString *)trackUID;
@end

View file

@ -442,18 +442,24 @@ OSStatus encoderRenderCallback( void *inRefCon, AudioUnitRenderActionFlags *ioAc
}
-(bool)removeInput:(CAMultiAudioInput *)input fromTrack:(CAMultiAudioOutputTrack *)outputTrack
-(bool)removeInput:(CAMultiAudioInput *)input fromTrack:(NSString *)outputTrackUUID
{
if (!outputTrack)
if (!outputTrackUUID)
{
return NO;
}
NSNumber *trackOutBus = outputTrack.outputBus;
CAMultiAudioConnection *inputConn = [self.graph findOutputConnection:input.headNode forNode:self.encodeMixer onBus:0];
CAMultiAudioOutputTrackConnection *trackConn = input.outputTracks[outputTrackUUID];
if (!trackConn)
{
return NO;
}
NSNumber *trackOutBus = trackConn.outputTrack.outputBus;
[self.encodeMixer disconnectInputBus:inputConn.bus fromOutputBus:trackOutBus.unsignedIntValue];
[input.outputTracks removeObjectForKey:outputTrack.uuid];
[self.encodeMixer disconnectInputBus:trackConn.bus fromOutputBus:trackOutBus.unsignedIntValue];
[input.outputTracks removeObjectForKey:outputTrackUUID];
return YES;
}
@ -577,6 +583,7 @@ OSStatus encoderRenderCallback( void *inRefCon, AudioUnitRenderActionFlags *ioAc
[self attachOutputTrack:outputTrack];
[self willChangeValueForKey:@"outputTracks"];
[self.outputTracks setObject:outputTrack forKey:outputTrack.uuid];
[self didChangeValueForKey:@"outputTracks"];
[[CaptureController sharedCaptureController] postNotification:CSNotificationAudioTrackCreated forObject:withName];
@ -620,9 +627,10 @@ OSStatus encoderRenderCallback( void *inRefCon, AudioUnitRenderActionFlags *ioAc
for (CAMultiAudioInput *input in self.audioInputs)
{
if ([input.outputTracks valueForKey:withUUID])
{
[input removeFromOutputTrack:trackInfo];
[input removeFromOutputTrack:withUUID];
}
}
@ -993,21 +1001,29 @@ OSStatus encoderRenderCallback( void *inRefCon, AudioUnitRenderActionFlags *ioAc
}
[self.encodeMixer restoreDataFromDict:encodeEffectChain];
[self.graph graphUpdate];
[self.graph startGraph];
}
-(void)startEncoder:(NSString *)trackUID
{
CAMultiAudioOutputTrack *outputTrack = self.outputTracks[trackUID];
if (outputTrack)
{
NSLog(@"STARTING ENCODER FOR %@", trackUID);
CAMultiAudioNode *renderNode = outputTrack.encoderNode;
CSAacEncoder *encoder = outputTrack.encoder;
AudioUnitAddRenderNotify(renderNode.audioUnit, encoderRenderCallback, [encoder inputBufferPtr]);
}
}
-(void)startEncoders
{
for(NSString *trackName in self.outputTracks)
{
CAMultiAudioOutputTrack *outputTrack = self.outputTracks[trackName];
CAMultiAudioNode *renderNode = outputTrack.encoderNode;
CSAacEncoder *encoder = outputTrack.encoder;
AudioUnitAddRenderNotify(renderNode.audioUnit, encoderRenderCallback, [encoder inputBufferPtr]);
[self startEncoder:trackName];
}
}
@ -1215,7 +1231,6 @@ OSStatus encoderRenderCallback( void *inRefCon, AudioUnitRenderActionFlags *ioAc
disconnectNode.headNode = nil;
disconnectNode.graph = nil;
[self.graph graphUpdate];
[CaptureController.sharedCaptureController postNotification:CSNotificationAudioRemoved forObject:self];
return YES;
}
@ -1346,10 +1361,8 @@ OSStatus encoderRenderCallback( void *inRefCon, AudioUnitRenderActionFlags *ioAc
TPCircularBuffer *encodeBuffer = (TPCircularBuffer *)inRefCon;
if (encodeBuffer && ((*ioActionFlags) & kAudioUnitRenderAction_PostRender))
{
TPCircularBufferCopyAudioBufferList(encodeBuffer, ioData, inTimeStamp, kTPCircularBufferCopyAll, NULL);
/*

View file

@ -53,7 +53,6 @@
-(bool)startGraph;
-(bool)stopGraph;
-(bool)graphUpdate;
-(bool)removeNode:(CAMultiAudioNode *)node;
@end

View file

@ -61,6 +61,6 @@
-(void)updatePowerlevel;
-(void)removeFromEngine;
-(void)addToOutputTrack:(CAMultiAudioOutputTrack *)trackName;
-(void)removeFromOutputTrack:(CAMultiAudioOutputTrack *)trackName;
-(void)removeFromOutputTrack:(NSString *)trackUUID;
@end

View file

@ -104,10 +104,12 @@
}
-(void)removeFromOutputTrack:(CAMultiAudioOutputTrack *)outputTrack
-(void)removeFromOutputTrack:(NSString *)trackUUID
{
[self willChangeValueForKey:@"outputTracks"];
[self.engine removeInput:self fromTrack:outputTrack];
[self.engine removeInput:self fromTrack:trackUUID];
[self didChangeValueForKey:@"outputTracks"];
[[CaptureController sharedCaptureController] postNotification:CSNotificationAudioTrackInputDeleted forObject:self];
}
@ -248,7 +250,7 @@
saveDict[@"downMixerData"] = [self.downMixer saveData];
}
saveDict[@"isGlobal"] = [NSNumber numberWithBool:self.isGlobal];
saveDict[@"outputTracks"] = self.outputTracks.copy;
saveDict[@"outputTracksUUIDs"] = self.outputTracks.allKeys;
}
@ -269,7 +271,7 @@
self.isGlobal = [restoreDict[@"isGlobal"] boolValue];
}
NSDictionary *outputTracks = restoreDict[@"outputTracks"];
NSArray *outputTracks = restoreDict[@"outputTracksUUIDs"];
if (outputTracks)
{
for(NSString *trackUUID in outputTracks)

View file

@ -33,6 +33,7 @@
@implementation CSLayoutRecorder
@synthesize audioEngine = _audioEngine;
-(instancetype) init
{
@ -194,6 +195,13 @@
}
}
-(void)attachToEncoder:(NSString *)trackUID
{
CAMultiAudioOutputTrack *outputTrack = self.audioEngine.outputTracks[trackUID];
CSAacEncoder *enc = outputTrack.encoder;
enc.encodedReceiver = self;
[self.audioEngine startEncoder:trackUID];
}
-(void)startRecordingCommon
{
@ -259,11 +267,8 @@
for(NSString *trackName in self.audioEngine.outputTracks)
{
CAMultiAudioOutputTrack *outputTrack = self.audioEngine.outputTracks[trackName];
CSAacEncoder *enc = outputTrack.encoder;
enc.encodedReceiver = self;
[self attachToEncoder:trackName];
}
[self.audioEngine startEncoders];
if (!self.renderer)
{
self.renderer = [[LayoutRenderer alloc] init];
@ -292,7 +297,7 @@
self.recordingActive = YES;
self.layout.isActive = YES;
[self.audioEngine addObserver:self forKeyPath:@"outputTracks.@allKeys" options:NSKeyValueObservingOptionNew context:nil];
dispatch_async(_frame_queue, ^{
[self newFrameTimed];
@ -302,8 +307,37 @@
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
if (!self.audioEngine)
{
return;
}
NSArray *trackKeys = change[NSKeyValueChangeNewKey];
for (NSString *trackUID in trackKeys)
{
CAMultiAudioOutputTrack *outTrack = self.audioEngine.outputTracks[trackUID];
if (!outTrack.encoder.encodedReceiver)
{
[self attachToEncoder:trackUID];
}
}
}
-(CAMultiAudioEngine *)audioEngine
{
return _audioEngine;
}
-(void)setAudioEngine:(CAMultiAudioEngine *)audioEngine
{
if (self.audioEngine)
{
[self.audioEngine removeObserver:self forKeyPath:@"outputTracks.@allKeys"];
}
_audioEngine = audioEngine;
}
-(NSObject<VideoCompressor> *)compressorByName:(NSString *)name
@ -735,15 +769,15 @@
if (CMTIME_COMPARE_INLINE(pcmBuffer.firstAudioTime, ==, kCMTimeZero))
if (CMTIME_COMPARE_INLINE(_firstPcmAudioTime, ==, kCMTimeZero))
{
pcmBuffer.firstAudioTime = orig_pts;
_firstPcmAudioTime = orig_pts;
return;
}
CMTime pts = CMTimeSubtract(orig_pts, pcmBuffer.firstAudioTime);
CMTime pts = CMTimeSubtract(orig_pts, _firstPcmAudioTime);
//CMTime adjust_pts = CMTimeMakeWithSeconds(self.audio_adjust, orig_pts.timescale);
//CMTime pts = CMTimeAdd(real_pts, adjust_pts);
@ -782,23 +816,20 @@
if (CMTIME_COMPARE_INLINE(audioBuffer.firstAudioTime, ==, kCMTimeZero))
if (CMTIME_COMPARE_INLINE(_firstAudioTime, ==, kCMTimeZero))
{
audioBuffer.firstAudioTime = orig_pts;
_firstAudioTime = orig_pts;
return;
}
CMTime pts = CMTimeSubtract(orig_pts, audioBuffer.firstAudioTime);
CMTime pts = CMTimeSubtract(orig_pts, _firstAudioTime);
//CMTime adjust_pts = CMTimeMakeWithSeconds(self.audio_adjust, orig_pts.timescale);
//CMTime pts = CMTimeAdd(real_pts, adjust_pts);
CMSampleBufferSetOutputPresentationTimeStamp(sampleBuffer, pts);
if (CMTIME_COMPARE_INLINE(pts, >, audioBuffer.previousAudioTime))
{
if (sampleBuffer)
@ -809,5 +840,11 @@
}
}
-(void)dealloc
{
if (self.audioEngine)
{
[self.audioEngine removeObserver:self forKeyPath:@"outputTracks.@allKeys"];
}
}
@end

View file

@ -88,8 +88,8 @@
NSArray *selectedTracks = self.audioTracksDictionaryController.selectedObjects;
for (NSDictionaryControllerKeyValuePair *trackInfo in selectedTracks)
{
CAMultiAudioOutputTrack *track = [trackInfo value];
[self.audioNode removeFromOutputTrack:track];
CAMultiAudioOutputTrackConnection *trackConn = [trackInfo value];
[self.audioNode removeFromOutputTrack:trackConn.outputTrack.uuid];
}
}

View file

@ -26,7 +26,7 @@
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6qE-t2-zqe">
<rect key="frame" x="19" y="476" width="84" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Stream Volume" id="clH-Fr-TJ1">
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -34,7 +34,7 @@
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wwP-vq-QJZ">
<rect key="frame" x="18" y="528" width="65" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Samplerate" id="qPp-Ym-izV">
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -42,7 +42,7 @@
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ssR-h6-svZ">
<rect key="frame" x="91" y="548" width="59" height="19"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="lBZ-LI-XH0">
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -54,7 +54,7 @@
<rect key="frame" x="88" y="523" width="70" height="22"/>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="FJb-Og-tdf" id="uSC-7v-E4B">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<menu key="menu" id="6Ra-rI-plD">
<items>
<menuItem title="Item 1" state="on" id="FJb-Og-tdf"/>
@ -74,7 +74,7 @@
<constraint firstAttribute="width" constant="58" id="q2p-hX-TR0"/>
</constraints>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="kbits/sec" id="S8r-Xg-ebh">
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -82,7 +82,7 @@
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="zuo-gj-1Pr">
<rect key="frame" x="18" y="506" width="63" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Audio Shift" id="6Pl-mK-60G">
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -90,7 +90,7 @@
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="I72-n8-A7m">
<rect key="frame" x="91" y="504" width="59" height="19"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="Utr-K4-fTZ">
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -101,7 +101,7 @@
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3S3-NA-Pfr">
<rect key="frame" x="157" y="506" width="49" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="seconds" id="ktg-pa-9dP">
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -112,7 +112,7 @@
<constraint firstAttribute="width" constant="36" id="8wR-h0-BoG"/>
</constraints>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Bitrate" id="FVz-ie-6Zt">
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -120,7 +120,7 @@
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="GNm-og-wRf">
<rect key="frame" x="19" y="372" width="101" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Monitor volume" id="IAm-lt-PXz">
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -148,7 +148,7 @@
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5HX-Gi-83X">
<rect key="frame" x="19" y="420" width="84" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Monitor Output" id="41g-2s-fF7">
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -160,7 +160,7 @@
</constraints>
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="KN8-OL-txf" id="SEL-4J-m1s">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<menu key="menu" id="sce-bW-EMX">
<items>
<menuItem title="Item 1" state="on" id="KN8-OL-txf"/>
@ -199,7 +199,7 @@
</constraints>
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="Mute_Icon" imagePosition="only" alignment="center" alternateImage="Speaker_Icon" controlSize="small" imageScaling="proportionallyUpOrDown" inset="2" id="HFf-ty-SwM" customClass="CSNSButtonCellThemed">
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
</buttonCell>
<connections>
<binding destination="dRe-6o-71e" name="value" keyPath="selection.encodeMixer.enabled" id="gtc-5g-Cnh"/>
@ -226,7 +226,7 @@
</constraints>
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="Mute_Icon" imagePosition="only" alignment="center" alternateImage="Speaker_Icon" controlSize="small" imageScaling="proportionallyUpOrDown" inset="2" id="6fp-6X-2wk" customClass="CSNSButtonCellThemed">
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
</buttonCell>
<connections>
<binding destination="dRe-6o-71e" name="value" keyPath="selection.previewMixer.enabled" id="GY9-T8-HVd"/>
@ -247,7 +247,7 @@
<tableColumns>
<tableColumn width="135" minWidth="40" maxWidth="1000" id="Gka-Lc-OMt">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@ -301,7 +301,7 @@
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8BQ-Ld-p55">
<rect key="frame" x="19" y="282" width="72" height="14"/>
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="Audio Tracks" id="szd-Om-2xO">
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -314,7 +314,7 @@
</constraints>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="NSAddTemplate" imagePosition="overlaps" alignment="center" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="caC-7M-URI">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
</buttonCell>
<connections>
<action selector="addAudioTrack:" target="-2" id="Kp6-Qm-Mq6"/>
@ -328,7 +328,7 @@
</constraints>
<buttonCell key="cell" type="smallSquare" bezelStyle="smallSquare" image="NSRemoveTemplate" imagePosition="overlaps" alignment="center" controlSize="small" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="EQD-RZ-rXn">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="toolTip"/>
<font key="font" metaFont="controlContent" size="11"/>
</buttonCell>
<connections>
<action selector="removeAudioTrack:" target="-2" id="Vpk-YM-Bjv"/>