下面的代码将编译并运行,但是当我尝试 appendBuffer 时 AVAssetWriterInputPixelBufferAdaptor 返回 NO:
关于为什么的任何想法?
- (void) performCompression
{
CGSize size = CGSizeMake(480, 320);
NSString *compressionDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
[self evaluateTrimmers];
scrubTime = 0.0;
currentFrameIndex = 0;
NSError *error = nil;
//----initialize compression engine
self.videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:[compressionDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.m4v",[[NSUserDefaults standardUserDefaults] valueForKey:@"RecentFileName"]]]]
fileType:AVFileTypeQuickTimeMovie
error:&error];
NSParameterAssert(videoWriter);
if(error)
NSLog(@"error = %@", [error localizedDescription]);
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:size.width], AVVideoWidthKey,
[NSNumber numberWithInt:size.height], AVVideoHeightKey, nil];
writerInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings] retain]; //[[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
NSDictionary *sourcePixelBufferAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil];
adaptor = [[AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary] retain]; //[[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:writerInput
//sourcePixelBufferAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil]];
NSParameterAssert(writerInput);
NSParameterAssert([videoWriter canAddInput:writerInput]);
[videoWriter addInput:writerInput];
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
//---
// insert demo debugging code to write the same image repeated as a movie
CGImageRef theImage = [[UIImage imageNamed:@"Default-Landscape.png"] CGImage];
CVPixelBufferRef buffer = NULL;
buffer = (CVPixelBufferRef)[self pixelBufferFromCGImage:theImage size:size];
[adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];
for (int i = 0; i < 120; i++)
{
if (adaptor.assetWriterInput.readyForMoreMediaData)
{
printf("inside for loop %i\n", i);
CMTime frameTime = CMTimeMake(1, 20);
CMTime lastTime = CMTimeMake(i, 20);
CMTime presentTime = CMTimeAdd(lastTime, frameTime);
buffer = (CVPixelBufferRef)[self pixelBufferFromCGImage:theImage size:size];
if (![adaptor appendPixelBuffer:buffer withPresentationTime:frameTime])
NSLog(@"FAIL");
CVBufferRelease(buffer);
}
else {
printf("error\n");
i--;
}
}
NSLog(@"outside for loop");
[writerInput markAsFinished];
[videoWriter finishWriting];
}
- (CVPixelBufferRef )pixelBufferFromCGImage:(CGImageRef)image size:(CGSize)size
{
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, nil];
CVPixelBufferRef pxbuffer = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, size.width, size.height, kCVPixelFormatType_32ARGB, (CFDictionaryRef) options, &pxbuffer);
// CVReturn status = CVPixelBufferPoolCreatePixelBuffer(NULL, adaptor.pixelBufferPool, &pxbuffer);
NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
NSParameterAssert(pxdata != NULL);
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata, size.width, size.height, 8, 4*size.width, rgbColorSpace, kCGImageAlphaNoneSkipFirst);
NSParameterAssert(context);
CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}