BradLarson / GPUImage

An open source iOS framework for GPU-based image and video processing
http://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework
BSD 3-Clause "New" or "Revised" License
20.23k stars 4.61k forks source link

Memory Issue in GPUImageMovieWriter #2442

Open a2zZuhaib opened 7 years ago

a2zZuhaib commented 7 years ago

Hello,

Below Method @ 4 i write in class GPUImageWriter.m to apply multiple filter on one video, for testing purpose i just apply a single static filter on video via code in this method. for first time its working fine and write output with very high battery usage. screen shot 2017-03-06 at 2 27 39 pm

but when i restart app without attaching to debugger its goes crash on 40-50%, I trace that its printing log --> (Message from debugger: Terminated due to memory issue,)

1: input video properties below: length: 2min 40sec

screen shot 2017-03-06 at 2 13 36 pm

2: I add GPUImage using Pod: (pod 'GPUImage') 3: I am calling this Method from Swift VC

call method:

    @IBAction func btnEditVideo(_ sender: Any) {
        let f1 = GPUImageBrightnessFilter()
        let f2 = GPUImageContrastFilter()

        f1.brightness = 0.5

        let output = videoOutputUrl(deleteIfExist_: true)
        let input = videoInputUrl()

        if(FileManager.default.fileExists(atPath: input.path)){        
            GPUImageMovieWriter().writeVideo(input,
                                             withFilters: [f1,f2],
                                             asOutput: output,
                                             progressBlock: { (progress) in
                                                print("\(progress)")
                                                (sender as! UIButton).setTitle("\(progress)", for: .normal)

            },
                                             successBlock: {
                                                print("Successful")

                                                let av = AVPlayerViewController()
                                                av.player = AVPlayer(url: output)
                                                self.present(av, animated: true, completion: {

                                                })
            })
            { (error) in
                print("Failure: \(error)")
            }

        }
    //        performSegue(withIdentifier: "vdoEditorSegue", sender: nil)

    }

4: Below is Method:

- (void)writeVideo:(NSURL*)inputUrl withFilters:(NSArray *)filters asOutput:(NSURL*)outputUrl progressBlock:(MovieWriterProgressBlock)progressBlock  successBlock:(MovieWriterSuccessBlock)successBlock  failureBlock:(MovieWriterFailureBlock)failureBlock {

    @try {

        // Configure this for video from the movie file, where we want to preserve all video frames and audio samples

        @autoreleasepool {

            NSArray<AVAssetTrack *> *vdoTracks = [[AVAsset assetWithURL:inputUrl] tracksWithMediaType:AVMediaTypeVideo];
            NSArray<AVAssetTrack *> *adoTracks = [[AVAsset assetWithURL:inputUrl] tracksWithMediaType:AVMediaTypeVideo];

            movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:outputUrl size:vdoTracks[0].naturalSize];
            movieWriter.shouldPassthroughAudio = YES;

            movieFile = [[GPUImageMovie alloc] initWithURL:inputUrl];
            movieFile.runBenchmark = NO;
            movieFile.playAtActualSpeed = NO;
            movieFile.audioEncodingTarget = movieWriter;
            [movieFile enableSynchronizedEncodingUsingMovieWriter:movieWriter];

            filter = [[GPUImagePixellateFilter alloc] init];
            [movieFile addTarget:filter];

            [filter addTarget:movieWriter];
            [movieWriter startRecording];
            [movieFile startProcessing];

            [movieWriter setCompletionBlock:^{
                [filter removeTarget:movieWriter];
                [movieWriter finishRecording];

                dispatch_async(dispatch_get_main_queue(), ^{
                    successBlock();
                });
            }];
        }

         NSTimer *timer= [NSTimer scheduledTimerWithTimeInterval:0.3f
                                        repeats:YES
                                          block:^(NSTimer * _Nonnull timer) {
                                              progressBlock(movieFile.progress);
                                              if(movieFile.progress >= 0.999){
                                                  [timer invalidate];
                                              }
                                          }];
    } @catch (NSException *exception) {
        failureBlock(exception);
    }
}