AVAssetWriterInputPixelBufferAdaptor appendPixelBuffer

我使用下面的代码将图像写入video

-(void) writeImagesToMovieAtPath:(NSString *) path withSize:(CGSize) size { NSLog(@"Write Started"); NSError *error = nil; AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL: [NSURL fileURLWithPath:path] fileType:AVFileTypeMPEG4 error:&error]; NSParameterAssert(videoWriter); NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys: AVVideoCodecH264, AVVideoCodecKey, [NSNumber numberWithInt:size.width], AVVideoWidthKey, [NSNumber numberWithInt:size.height], AVVideoHeightKey, nil]; AVAssetWriterInput* videoWriterInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings] retain]; AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoWriterInput sourcePixelBufferAttributes:nil]; NSParameterAssert(videoWriterInput); NSParameterAssert([videoWriter canAddInput:videoWriterInput]); videoWriterInput.expectsMediaDataInRealTime = YES; [videoWriter addInput:videoWriterInput]; //Start a session: [videoWriter startWriting]; [videoWriter startSessionAtSourceTime:kCMTimeZero]; CVPixelBufferRef buffer = NULL; //convert uiimage to CGImage. int frameCount = 16; int kRecordingFPS = 30; UIImage * im = [UIImage imageNamed:@"IMG_0103.JPG"]; NSArray * imageArray = [[NSArray alloc]initWithObjects:im,im,im,im,im,im,im,im,im,im,im,im,im,im,im,im, nil]; for(UIImage * img in imageArray) { buffer = [self pixelBufferFromCGImage:[img CGImage] andSize:size]; BOOL append_ok = NO; int j = 0; while (!append_ok && j < 30) { if (adaptor.assetWriterInput.readyForMoreMediaData) { printf("appending %d attemp %d\n", frameCount, j); CMTime frameTime = CMTimeMake(frameCount,(int32_t) kRecordingFPS); append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime]; if(buffer) CVBufferRelease(buffer); [NSThread sleepForTimeInterval:0.05]; } else { printf("adaptor not ready %d, %d\n", frameCount, j); [NSThread sleepForTimeInterval:0.1]; } j++; } if (!append_ok) { printf("error appending image %d times %d\n", frameCount, j); } frameCount++; } //Finish the session: [videoWriterInput markAsFinished]; [videoWriter finishWriting]; NSLog(@"Write Ended"); [videoWriterInput release]; [videoWriter release]; [imageArray release]; } 

它第一次工作,但如果我运行代码2,3倍或更多,它报告:

 !appending 0 0-0 attemp 0 !appending 0 0-0 attemp 1 My App(11385,0xb0103000) malloc: *** error for object 0x9ab4270: double free *** set a breakpoint in malloc_error_break to debug !appending 0 0-0 attemp 2 My App(11385,0xb0103000) malloc: *** error for object 0x9ab4270: double free *** set a breakpoint in malloc_error_break to debug !appending 0 0-0 attemp 3 

Soemtime引起了崩溃

我试图find原因,但没有结果,

您的评论欢迎

而不是使用[NSThread sleepForTimeInterval:0.1]; 使用while(!adaptor.assetWriterInput.readyForMoreMediaData){}

因为readyForMoreMediaData多次在0.1的时间间隔内从不设置为YES。

也尝试释放占用appendPixelBuffer的内存:withPresentationTime:方法实际上这个方法阻止你成功运行

您需要使用CFRelease()释放缓冲区,如“创build规则”中所述

 if ([assetWriterInput isReadyForMoreMediaData]) { CVPixelBufferRef pixelBuffer = [self newPixelBufferFromCGImage:image.CGImage]; CMTime frameTime = CMTimeMake(frameCount,(int32_t) kRecordingFPS); if (![adaptor appendPixelBuffer:pixelBuffer withPresentationTime:frameTime]) { NSError *error = [videoWriter error]; NSLog(@"failed to append sbuf: %@", error); } CFRelease(pixelBuffer); }