AVAssetWriter内存错误

时间:2014-07-15 12:53:23

标签: ios avfoundation avassetwriter

我有几种方法可以将mov文件中的视频写入临时目录,但是大约15秒后。我收到了错误:

  • 收到内存警告。
  • 收到内存警告。
  • 收到内存警告。
  • 收到内存警告。

然后app崩溃了。我被困住了,不知道出了什么问题......

- (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!");

    }


}

其余代码:

- (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;
}

如果有人可以指出我的错误,那就太好了!如果需要,可以共享更多代码。 SampleBuffer来自带有过滤器的CIImage。

现在新的东西,我可以录制几秒钟的电影并保存它,但它全是黑屏...

更新

保存视频,但从CIImage创建CMSampleBufferRef失败。我有绿屏或黑屏的原因,这是代码:

- (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;
}

1 个答案:

答案 0 :(得分:4)

您应该使用个人资料工具检查您的代码。特别是对于内存泄漏。可能是你没有发布样本缓冲区:

CMSampleBufferInvalidate(buffer);
CFRelease(buffer);
buffer = NULL;