Я в своем уме здесь, несмотря на хорошую информацию о StackOverflow ...
Я пытаюсь записать буфер визуализации OpenGL для видео на iPad 2 (с помощью iOS 4.3).Это более точно то, что я пытаюсь:
A) настроить AVAssetWriterInputPixelBufferAdaptor
создать AVAssetWriter, который указывает на видеофайл
настроить AVAssetWriterInput с соответствующими настройками
настроить AVAssetWriterInputPixelBufferAdaptor для добавления данных в видеофайл
B) записать данныев видеофайл, используя этот AVAssetWriterInputPixelBufferAdaptor
визуализация кода OpenGL на экране
получение буфера OpenGL через glReadPixels
создать CVPixelBufferRef из данных OpenGL
добавить этот PixelBuffer к AVAssetWriterInputPixelBufferAdaptor, используя метод appendPixelBuffer
Однако,возникли проблемы с этим.Моя стратегия сейчас заключается в том, чтобы настроить AVAssetWriterInputPixelBufferAdaptor при нажатии кнопки.После того, как AVAssetWriterInputPixelBufferAdaptor допустим, я установил флаг, чтобы сигнализировать EAGLView о создании пиксельного буфера и добавлять его к видеофайлу через appendPixelBuffer для заданного числа кадров.
Сейчас мой код падает при попыткедобавить второй пиксельный буфер, выдав мне следующую ошибку:
-[__NSCFDictionary appendPixelBuffer:withPresentationTime:]: unrecognized selector sent to instance 0x131db0
Вот мой код установки AVAsset (большая часть была основана на коде Руди Арамайо, который работает в обычном режимеизображения, но не настроен для текстур):
- (void) testVideoWriter {
//initialize global info
MOVIE_NAME = @"Documents/Movie.mov";
CGSize size = CGSizeMake(480, 320);
frameLength = CMTimeMake(1, 5);
currentTime = kCMTimeZero;
currentFrame = 0;
NSString *MOVIE_PATH = [NSHomeDirectory() stringByAppendingPathComponent:MOVIE_NAME];
NSError *error = nil;
unlink([betaCompressionDirectory UTF8String]);
videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:betaCompressionDirectory] fileType:AVFileTypeQuickTimeMovie error:&error];
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:size.width], AVVideoWidthKey,
[NSNumber numberWithInt:size.height], AVVideoHeightKey, nil];
writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
//writerInput.expectsMediaDataInRealTime = NO;
NSDictionary *sourcePixelBufferAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey, nil];
adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary];
[adaptor retain];
[videoWriter addInput:writerInput];
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
VIDEO_WRITER_IS_READY = true;
}
Хорошо, теперь, когда мои videoWriter и адаптер настроены, я говорю моему OpenGL-рендереру создать буфер пикселей для каждого кадра:
- (void) captureScreenVideo {
if (!writerInput.readyForMoreMediaData) {
return;
}
CGSize esize = CGSizeMake(eagl.backingWidth, eagl.backingHeight);
NSInteger myDataLength = esize.width * esize.height * 4;
GLuint *buffer = (GLuint *) malloc(myDataLength);
glReadPixels(0, 0, esize.width, esize.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
CVPixelBufferRef pixel_buffer = NULL;
CVPixelBufferCreateWithBytes (NULL, esize.width, esize.height, kCVPixelFormatType_32BGRA, buffer, 4 * esize.width, NULL, 0, NULL, &pixel_buffer);
/* DON'T FREE THIS BEFORE USING pixel_buffer! */
//free(buffer);
if(![adaptor appendPixelBuffer:pixel_buffer withPresentationTime:currentTime]) {
NSLog(@"FAIL");
} else {
NSLog(@"Success:%d", currentFrame);
currentTime = CMTimeAdd(currentTime, frameLength);
}
free(buffer);
CVPixelBufferRelease(pixel_buffer);
}
currentFrame++;
if (currentFrame > MAX_FRAMES) {
VIDEO_WRITER_IS_READY = false;
[writerInput markAsFinished];
[videoWriter finishWriting];
[videoWriter release];
[self moveVideoToSavedPhotos];
}
}
И, наконец, я перемещаю видео в рулон камеры:
- (void) moveVideoToSavedPhotos {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
NSString *localVid = [NSHomeDirectory() stringByAppendingPathComponent:MOVIE_NAME];
NSURL* fileURL = [NSURL fileURLWithPath:localVid];
[library writeVideoAtPathToSavedPhotosAlbum:fileURL
completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
NSLog(@"%@: Error saving context: %@", [self class], [error localizedDescription]);
}
}];
[library release];
}
Однако, как я уже сказал, у меня сбой при вызове appendPixelBuffer.
Извините за отправкутак много кода, но я действительно не знаю, что я делаю неправильно.Казалось, что было бы тривиально обновить проект, который записывает изображения в видео, но я не могу взять пиксельный буфер, который я создаю через glReadPixels, и добавить его.Это сводит меня с ума!Если у кого-нибудь есть совет или пример с рабочим кодом OpenGL -> Видео, это было бы замечательно ... Спасибо!