Я нахожусь в своем уме, несмотря на хорошую информацию здесь, в StackOverflow ...
Я пытаюсь написать рендербуфер OpenGL для видео на iPad 2 (используя iOS 4.3). Это более точно то, что я пытаюсь сделать:
A)настроить AVAssetWriterInputPixelBufferAdaptor
создать AVAssetWriter, который указывает на видеофайл
настроить AVAssetWriterInput с соответствующими настройками
настроить AVAssetWriterInputPixelBufferAdaptor для добавления данных в видеофайл
B) записать данные в видео файл, используя этот AVAssetWriterInputPixelBufferAdaptor
, отображать код OpenGL на экране
получить буфер OpenGL через glReadPixels
создать CVPixelBufferRef из данных OpenGL
добавить этот PixelBuffer к методу AVAssetWriterInputPixel90 с помощью метода 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 -> Видео, это было бы потрясающе ... Спасибо!