多次使用 GPUImageMovieWriter 时发生内存泄漏

Memory leak occurs When use GPUImageMovieWriter multiple times

释放GPUImageMovieWriter对象需要哪些步骤? 想安全使用多次MovieWriter怎么办?

使用我创建的 GPUImage 的应用程序发生内存泄漏。 在 movieWriter 中输出两倍以上的视频时会发生内存泄漏。 使用Instruments调试,结果GPUImageMovieWriter没有释放

实施概述

@property (nonatomic, strong) GPUImageMovieComposition *gpuMovieFileComp;
@property (nonatomic, weak) GPUImageMovieWriter *movieWriter;
@property (nonatomic, weak) GPUImageFilter *exportFilter;
@property (nonatomic, weak) AVMutableComposition *mixComposition;
@property (nonatomic, weak) AVMutableVideoComposition *transformVideoComposition;
@property (nonatomic, weak) AVMutableAudioMix *mutableAudioMix;

_gpuMovieFileComp = [[GPUImageMovieComposition alloc] initWithComposition:self.mixComposition andVideoComposition:self.transformVideoComposition andAudioMix:self.mutableAudioMix];
GPUImageMovieWriter *mr = [[GPUImageMovieWriter alloc]initWithMovieURL:_exportUrl size:CGSizeMake(MOVIE_SIZE_W, MOVIE_SIZE_H)];
[_gpuMovieFileComp enableSynchronizedEncodingUsingMovieWriter:mr];
_movieWriter = mr;
mr = nil;

_movieWriter.shouldPassthroughAudio = YES;
_movieWriter.encodingLiveVideo = NO;
_movieWriter.hasAudioTrack = YES;
_gpuMovieFileComp.playAtActualSpeed = YES;
_gpuMovieFileComp.audioEncodingTarget = _movieWriter;

[_gpuMovieFileComp addTarget:_exportFilter];
[_exportFilter addTarget:_movieWriter];

[_movieWriter setCompletionBlock:^{
    weakSelf.gpuMovieFileComp removeTarget:weakSelf.exportFilter];
    [weakSelf.exportFilter removeTarget:weakSelf.MovieWriter];
    [weakSelf.movieWriter finishRecording];
}];
[_gpuMovieFileComp startProcessing];
[_movieWriter startRecording];

我被确认或在GPUImage中的Sample Program的SimpleVideoFilter中发生了类似的内存泄漏。 SimpleVideoFilter的xib添加一个UIbutton,文件输出方式修改为在action中触发。

-(IBAction)startBtn:(id)sender
{
    NSURL *sampleURL = [[NSBundle mainBundle] URLForResource:@"sample_iPod" withExtension:@"m4v"];

    movieFile = [[GPUImageMovie alloc] initWithURL:sampleURL];
    movieFile.runBenchmark = YES;
    movieFile.playAtActualSpeed = NO;
    …

因此,现在可以多次调用 movieWriter。 使用仪器进行了多次文件输出,确认GPUImageMovieWriter在第二次或之后内存泄漏。

泄漏对象

movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(640.0, 480.0)];

这样,会不会是GPUImageMovieWriter的问题? 或者我的代码有问题?如果有解决办法,请告诉我。 对不起我糟糕的英语。我在等建议。 谢谢。

最后,我解决了这个问题。 GPUImageMovieWriter 中的 _movieWriterContext 是泄漏的对象。 我重写了 GPUImageMovieWriter.m 如下。

97 //    _movieWriterContext = [[GPUImageContext alloc] init];
98     _movieWriterContext = [GPUImageContext sharedImageProcessingContext];
99 //    [_movieWriterContext useSharegroup:[[[GPUImageContext sharedImageProcessingContext] context] sharegroup]];

目前,内存泄漏不再发生,崩溃导致内存压力也不再发生。 我希望这个解决方案能帮助面临同样问题的人。

根据@ootknym 的回答,这是 GPUImage 0.1.7 的一个分支,其中包含更改:

https://github.com/getnexar/GPUImage.git