0

I have few methods that are supposed to write video in mov file to temp dir, but after ~15 sec. I'm getting errors:

  • Received memory warning.
  • Received memory warning.
  • Received memory warning.
  • Received memory warning.

Then app is crashing. I'm stuck and have no idea what is wrong...

- (void) saveVideoToFileFromBuffer:(CMSampleBufferRef) buffer {


    if (!movieWriter) {

        NSString *moviePath = [NSString stringWithFormat:@"%@tmpMovie", NSTemporaryDirectory()];

        if ([[NSFileManager defaultManager] fileExistsAtPath:moviePath])
            [self removeMovieAtPath:moviePath];

        NSError *error = nil;

        movieWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:moviePath] fileType: AVFileTypeQuickTimeMovie error:&error];
        if (error) {

            m_log(@"Error allocating AssetWriter: %@", [error localizedDescription]);

        } else {

            CMFormatDescriptionRef description = CMSampleBufferGetFormatDescription(buffer);

            if(![self setUpMovieWriterObjectWithDescriptor:description])
                    m_log(@"ET go home, no video recording!!");
        }

    }

    if (movieWriter.status != AVAssetWriterStatusWriting) {

        [movieWriter startWriting];

        [movieWriter startSessionAtSourceTime:kCMTimeZero];

        apiStatusChangeIndicator = NO;

    }

    if (movieWriter.status == AVAssetWriterStatusWriting) {

        if (![movieInput appendSampleBuffer:buffer]) m_log(@"Failed to append sample buffer!");

    }


}

Rest of code:

- (BOOL) setUpMovieWriterObjectWithDescriptor:(CMFormatDescriptionRef) descriptor {

    CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(descriptor);

    NSDictionary *compressionSettings = [NSDictionary dictionaryWithObjectsAndKeys: AVVideoProfileLevelH264Baseline31,AVVideoProfileLevelKey,
                                        [NSNumber numberWithInteger:30], AVVideoMaxKeyFrameIntervalKey, nil];
    //AVVideoProfileLevelKey set because of errors


    NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey,[NSNumber numberWithInt:dimensions.width], AVVideoWidthKey,
                                    [NSNumber numberWithInt:dimensions.height], AVVideoHeightKey, compressionSettings, AVVideoCompressionPropertiesKey, nil];


    if ([movieWriter canApplyOutputSettings:videoSettings forMediaType:AVMediaTypeVideo]) {

        movieInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
        movieInput.expectsMediaDataInRealTime = YES;

        if ([movieWriter canAddInput:movieInput]) {

            [movieWriter addInput:movieInput];
        } else {

            m_log(@"Couldn't apply video input to Asset Writer!");

            return NO;
        }

    } else {

        m_log(@"Couldn't apply video settings to AVAssetWriter!");

        return NO;
    }



    return YES;
}

Would be great if someone could point my mistake! Can share more code if needed. SampleBuffer comes from CIImage with filters.

Now new thing, I can record few seconds of movie and saved it, but it's all black screen...

UPDATE

Saving video works, but creating CMSampleBufferRef from CIImage fails. It's reason that I got green or black screen, here's the code:

- (CMSampleBufferRef) processCIImageToPixelBuffer:(CIImage*) image andSampleBuffer:(CMSampleTimingInfo) info{

    CVPixelBufferRef renderTargetPixelBuffer;

    CFDictionaryRef empty;
    CFMutableDictionaryRef attrs;

    empty = CFDictionaryCreate(kCFAllocatorDefault,
                               NULL,
                               NULL,
                               0,
                               &kCFTypeDictionaryKeyCallBacks,
                               &kCFTypeDictionaryValueCallBacks);

    attrs = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                      1,
                                      &kCFTypeDictionaryKeyCallBacks,
                                      &kCFTypeDictionaryValueCallBacks);

    CFDictionarySetValue(attrs,
                         kCVPixelBufferIOSurfacePropertiesKey,
                         empty);

    CVReturn cvError = CVPixelBufferCreate(kCFAllocatorSystemDefault,
                                           [image extent].size.width,
                                           [image extent].size.height,
                                           kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,
                                           attrs,
                                           &renderTargetPixelBuffer);
    if (cvError != 0) {

        m_log(@"Error when init Pixel buffer: %i", cvError);

    }

    CFRelease(empty);
    CFRelease(attrs);

    CVPixelBufferLockBaseAddress(renderTargetPixelBuffer, 0 );

    [_coreImageContext render:image toCVPixelBuffer:renderTargetPixelBuffer];

    CVPixelBufferUnlockBaseAddress(renderTargetPixelBuffer, 0 );

    CMVideoFormatDescriptionRef videoInfo = NULL;
    CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, renderTargetPixelBuffer, &videoInfo);

    CMSampleBufferRef recordingBuffer;


    OSStatus cmError = CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault, renderTargetPixelBuffer, true, NULL, NULL, videoInfo, &info, &recordingBuffer);

    if (cmError != 0 ) {

        m_log(@"Error creating sample buffer: %i", (int)cmError);
    }

    CVPixelBufferRelease(renderTargetPixelBuffer);
    renderTargetPixelBuffer = NULL;
    CFRelease(videoInfo);
    videoInfo = NULL;

    return recordingBuffer;
}
palusik
  • 111
  • 11

1 Answers1

4

You should check your code with Profile tool. Especially for memory leaks. May be you do not release sample buffer:

CMSampleBufferInvalidate(buffer);
CFRelease(buffer);
buffer = NULL;
anatoliy_v
  • 1,782
  • 15
  • 24
  • This was good call. I've profiled app for the leaks, release/null all I can and now there is no memory warning, BUT I still can find error that makes my video all green. That's all I get, green screen for n seconds. Any idea why is that ? – palusik Jul 17 '14 at 11:39
  • I've managed to do this using AVAssetWriterInputPixelBufferAdaptor and saving from CVPixelBufferRef, so no memoery needed to creating CMSampleBuffer form CIImage (CIImage -> CVPixelBuffer -> CMSampleBuffer) only CIImage to CVPixelBuffer. – palusik Jul 18 '14 at 12:10