Skip to content

Commit

Permalink
Fixed an issue where audio sample buffers were being invalidated earl…
Browse files Browse the repository at this point in the history
…ier than they should be on movie writing, leading to errors and crashes.
  • Loading branch information
BradLarson committed Jul 19, 2013
1 parent 8986763 commit 42a6838
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
[filterNavigationController pushViewController:filterListController animated:NO];

[self.window makeKeyAndVisible];

return YES;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@

- (IBAction)updatePixelWidth:(id)sender;

@end
@end
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,11 @@ - (void)viewDidLoad

movieFile = [[GPUImageMovie alloc] initWithURL:sampleURL];
movieFile.runBenchmark = YES;
movieFile.playAtActualSpeed = YES;
// filter = [[GPUImagePixellateFilter alloc] init];
movieFile.playAtActualSpeed = NO;
filter = [[GPUImagePixellateFilter alloc] init];
// filter = [[GPUImageUnsharpMaskFilter alloc] init];

filter = [[GPUImageDissolveBlendFilter alloc] init];
[(GPUImageDissolveBlendFilter *)filter setMix:0.5];

UIImage *inputImage = [UIImage imageNamed:@"WID-small.jpg"];
GPUImagePicture *overlayPicture = [[GPUImagePicture alloc] initWithImage:inputImage];

[movieFile addTarget:filter];
[overlayPicture addTarget:filter];
[overlayPicture processImage];

// Only rotate the video for display, leave orientation the same for recording
GPUImageView *filterView = (GPUImageView *)self.view;
Expand All @@ -63,16 +55,6 @@ - (void)viewDidLoad
[filter removeTarget:movieWriter];
[movieWriter finishRecording];
}];

/*
double delayInSeconds = 5.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[filter removeTarget:movieWriter];
[movieWriter finishRecording];
NSLog(@"Done recording");
});
*/
}

- (void)viewDidUnload
Expand All @@ -88,8 +70,7 @@ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface
- (IBAction)updatePixelWidth:(id)sender
{
// [(GPUImageUnsharpMaskFilter *)filter setIntensity:[(UISlider *)sender value]];
[(GPUImageDissolveBlendFilter *)filter setMix:[(UISlider *)sender value]];
// pixellateFilter.fractionalWidthOfAPixel = [(UISlider *)sender value];
[(GPUImagePixellateFilter *)filter setFractionalWidthOfAPixel:[(UISlider *)sender value]];
}

@end
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<int key="IBDocument.SystemTarget">1024</int>
<string key="IBDocument.SystemVersion">13A510d</string>
<string key="IBDocument.InterfaceBuilderVersion">4457.9</string>
<string key="IBDocument.AppKitVersion">1242.11</string>
<string key="IBDocument.HIToolboxVersion">683.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
<string key="NS.object.0">3682.9</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBProxyObject</string>
<string>IBUIView</string>
<string>IBUISlider</string>
<string>IBUIView</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
Expand All @@ -32,28 +32,24 @@
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="191373211">
<reference key="NSNextResponder"/>
<nil key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUISlider" id="601521545">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">266</int>
<string key="NSFrame">{{18, 418}, {284, 23}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:623</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<float key="IBUIValue">1</float>
<float key="IBUIMaxValue">5</float>
<float key="IBUIValue">0.10000000149011612</float>
<float key="IBUIMaxValue">0.20000000298023224</float>
</object>
</array>
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="601521545"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
Expand All @@ -67,14 +63,15 @@
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<bool key="usesAutoincrementingIDs">NO</bool>
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="191373211"/>
</object>
<int key="connectionID">3</int>
<string key="id">3</string>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
Expand All @@ -83,38 +80,38 @@
<reference key="destination" ref="372490531"/>
<int key="IBEventType">13</int>
</object>
<int key="connectionID">5</int>
<string key="id">5</string>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<string key="id">0</string>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">1</int>
<string key="id">1</string>
<reference key="object" ref="191373211"/>
<array class="NSMutableArray" key="children">
<reference ref="601521545"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<string key="id">-1</string>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<string key="id">-2</string>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<string key="id">4</string>
<reference key="object" ref="601521545"/>
<reference key="parent" ref="191373211"/>
</object>
Expand All @@ -133,47 +130,20 @@
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">5</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">GPUImageView</string>
<string key="superclassName">UIView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/GPUImageView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">SimpleVideoFileFilterViewController</string>
<string key="superclassName">UIViewController</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">updatePixelWidth:</string>
<string key="NS.object.0">id</string>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
<string key="NS.key.0">updatePixelWidth:</string>
<object class="IBActionInfo" key="NS.object.0">
<string key="name">updatePixelWidth:</string>
<string key="candidateClassName">id</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/SimpleVideoFileFilterViewController.h</string>
</object>
</object>
</array>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
<real value="1024" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
<integer value="4600" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1179</string>
<string key="IBCocoaTouchPluginVersion">3682.9</string>
</data>
</archive>
32 changes: 17 additions & 15 deletions framework/Source/GPUImageMovie.m
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ - (void)dealloc
CFRelease(coreVideoTextureCache);
}
}

#pragma mark -
#pragma mark Movie processing

Expand Down Expand Up @@ -115,15 +116,17 @@ - (void)startProcessing
GPUImageMovie __block *blockSelf = self;

[inputAsset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:@"tracks"] completionHandler: ^{
NSError *error = nil;
AVKeyValueStatus tracksStatus = [inputAsset statusOfValueForKey:@"tracks" error:&error];
if (!tracksStatus == AVKeyValueStatusLoaded)
{
return;
}
blockSelf.asset = inputAsset;
[blockSelf processAsset];
blockSelf = nil;
runSynchronouslyOnVideoProcessingQueue(^{
NSError *error = nil;
AVKeyValueStatus tracksStatus = [inputAsset statusOfValueForKey:@"tracks" error:&error];
if (!tracksStatus == AVKeyValueStatusLoaded)
{
return;
}
blockSelf.asset = inputAsset;
[blockSelf processAsset];
blockSelf = nil;
});
}];
}

Expand All @@ -147,6 +150,8 @@ - (void)processAsset
{
audioEncodingIsFinished = NO;

[self.audioEncodingTarget setShouldInvalidateAudioSampleWhenDone:YES];

// This might need to be extended to handle movies with more than one audio track
AVAssetTrack* audioTrack = [audioTracks objectAtIndex:0];
readerAudioTrackOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:audioTrack outputSettings:nil];
Expand Down Expand Up @@ -266,12 +271,9 @@ - (void)readNextAudioSampleFromOutput:(AVAssetReaderTrackOutput *)readerAudioTra

if (audioSampleBufferRef)
{
runSynchronouslyOnVideoProcessingQueue(^{
[self.audioEncodingTarget processAudioBuffer:audioSampleBufferRef];

CMSampleBufferInvalidate(audioSampleBufferRef);
CFRelease(audioSampleBufferRef);
});
[self.audioEncodingTarget processAudioBuffer:audioSampleBufferRef];

CFRelease(audioSampleBufferRef);
}
else
{
Expand Down
1 change: 1 addition & 0 deletions framework/Source/iOS/GPUImageMovieWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ extern NSString *const kGPUImageColorSwizzlingFragmentShaderString;

@property(readwrite, nonatomic) BOOL hasAudioTrack;
@property(readwrite, nonatomic) BOOL shouldPassthroughAudio;
@property(readwrite, nonatomic) BOOL shouldInvalidateAudioSampleWhenDone;
@property(nonatomic, copy) void(^completionBlock)(void);
@property(nonatomic, copy) void(^failureBlock)(NSError*);
@property(nonatomic, assign) id<GPUImageMovieWriterDelegate> delegate;
Expand Down
11 changes: 10 additions & 1 deletion framework/Source/iOS/GPUImageMovieWriter.m
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ @implementation GPUImageMovieWriter
@synthesize videoInputReadyCallback;
@synthesize audioInputReadyCallback;
@synthesize enabled;
@synthesize shouldInvalidateAudioSampleWhenDone = _shouldInvalidateAudioSampleWhenDone;

@synthesize delegate = _delegate;

Expand All @@ -74,6 +75,8 @@ - (id)initWithMovieURL:(NSURL *)newMovieURL size:(CGSize)newSize fileType:(NSStr
return nil;
}

_shouldInvalidateAudioSampleWhenDone = NO;

self.enabled = YES;

movieWritingQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.movieWritingQueue", NULL);
Expand Down Expand Up @@ -319,6 +322,8 @@ - (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer;

if (_hasAudioTrack)
{
CFRetain(audioBuffer);

CMTime currentSampleTime = CMSampleBufferGetOutputPresentationTimeStamp(audioBuffer);

if (CMTIME_IS_INVALID(startTime))
Expand All @@ -340,9 +345,13 @@ - (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer;
}

// NSLog(@"Recorded audio sample time: %lld, %d, %lld", currentSampleTime.value, currentSampleTime.timescale, currentSampleTime.epoch);
CFRetain(audioBuffer);
dispatch_async(movieWritingQueue, ^{
[assetWriterAudioInput appendSampleBuffer:audioBuffer];

if (_shouldInvalidateAudioSampleWhenDone)
{
CMSampleBufferInvalidate(audioBuffer);
}
CFRelease(audioBuffer);
});
}
Expand Down

0 comments on commit 42a6838

Please sign in to comment.