AVAssetWriter 内存错误
Posted
技术标签:
【中文标题】AVAssetWriter 内存错误【英文标题】:AVAssetWriter memory error 【发布时间】:2014-07-15 12:53:22 【问题描述】:我有几个方法应该将 mov 文件中的视频写入临时目录,但大约 15 秒后。我收到错误:
收到内存警告。 收到内存警告。 收到内存警告。 收到内存警告。然后应用程序崩溃了。我被卡住了,不知道出了什么问题......
- (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】:您应该使用 Profile 工具检查您的代码。特别是对于内存泄漏。可能是您没有释放样本缓冲区:
CMSampleBufferInvalidate(buffer);
CFRelease(buffer);
buffer = NULL;
【讨论】:
这是个好电话。我已经分析了泄漏的应用程序,尽我所能释放/空,现在没有内存警告,但我仍然可以找到使我的视频全绿的错误。这就是我所得到的,绿屏n秒。知道为什么吗? 我已经设法使用 AVAssetWriterInputPixelBufferAdaptor 并从 CVPixelBufferRef 保存来做到这一点,因此创建 CMSampleBuffer 形式 CIImage (CIImage -> CVPixelBuffer -> CMSampleBuffer) 只需要 CIImage 到 CVPixelBuffer。以上是关于AVAssetWriter 内存错误的主要内容,如果未能解决你的问题,请参考以下文章
AVAssetWriter 记录设置不像 AVAudioRecorder 那样工作