Захват видео в представлении GLKView с использованием буфера кадра останавливает отображение содержимого openGLES на экране
Я пытаюсь записать видео контента, который отображается в GLKView. Я использую Sparrow для отображения необходимого содержимого в openGL. Я использую Framebuffer Object или FBO, чтобы получить кадры из openGLES и записать эти кадры в видео, используя AVAssetwriter. Ну, я могу создать видео, но из-за этого отображение контента в GLKView остановилось. Это больше не обновляется.
Что я делаю, это:
1. Перед тем, как начать писать видео, я создаю объект FrameBuffer, используя следующий метод:
-(void)createFBO{
SPViewController *vC = Sparrow.currentController;
int contentScaleFactor = Sparrow.contentScaleFactor;
int width = vC.view.bounds.size.width*contentScaleFactor;
int height = vC.view.bounds.size.height*contentScaleFactor;
CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, [vC context], NULL, &coreVideoTextureCache);
if (err)
{
NSAssert(NO, @"Error at CVOpenGLESTextureCacheCreate");
}
CFDictionaryRef empty; // empty value for attr value.
CFMutableDictionaryRef attrs;
empty = CFDictionaryCreate(kCFAllocatorDefault, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); // our empty IOSurface properties dictionary
attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(attrs, kCVPixelBufferIOSurfacePropertiesKey, empty);
err = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, attrs, &renderTarget);
if (err)
{
NSAssert(NO, @"Error at CVPixelBufferCreate %d", err);
}
CVPixelBufferPoolCreatePixelBuffer (NULL, [assetWriterPixelBufferInput pixelBufferPool], &renderTarget);
CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault, coreVideoTextureCache, renderTarget,
NULL, // texture attributes
GL_TEXTURE_2D,
GL_RGBA, // opengl format
width,
height,
GL_BGRA, // native iOS format
GL_UNSIGNED_BYTE,
0,
&renderTexture);
glBindTexture(CVOpenGLESTextureGetTarget(renderTexture), CVOpenGLESTextureGetName(renderTexture));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, CVOpenGLESTextureGetName(renderTexture), 0);
/////////
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
NSAssert(status == GL_FRAMEBUFFER_COMPLETE, @"Incomplete filter FBO: %d", status);
glBindTexture(GL_TEXTURE_2D, 0);
CFRelease(attrs);
CFRelease(empty);
}
2. Затем я вызываю фактический код написания в -glkView:drawInRect: метод как:
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
//Check for recording status and write a frame to video
if (_movieWriter && _movieWriter.isRecording) {
[_movieWriter writeCurrentFrameToVideo];
}
//The code below is unmodified Sparrow-Framework code
@autoreleasepool
{
if (!_root)
{
// ideally, we'd do this in 'viewDidLoad', but when iOS starts up in landscape mode,
// the view width and height are swapped. In this method, however, they are correct.
[self readjustStageSize];
[self createRoot];
}
[Sparrow setCurrentController:self];
[EAGLContext setCurrentContext:_context];
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
[_support nextFrame];
[_stage render:_support];
[_support finishQuadBatch];
if (_statsDisplay)
_statsDisplay.numDrawCalls = _support.numDrawCalls - 2; // stats display requires 2 itself
#if DEBUG
[SPRenderSupport checkForOpenGLError];
#endif
}
}
и написание кода:
-(void)writeCurrentFrameToVideo{
CVPixelBufferLockBaseAddress(renderTarget, 0);
if (!startTime) {
startTime = [NSDate date];
}
CMTime currentTime = CMTimeMakeWithSeconds([[NSDate date] timeIntervalSinceDate:startTime],120);
//[assetWriterPixelBufferInput appendPixelBuffer:pixelBuffer withPresentationTime:currentTime];
if(![assetWriterPixelBufferInput appendPixelBuffer:renderTarget withPresentationTime:currentTime])
{
NSLog(@"Problem appending pixel buffer at time: %lld", currentTime.value);
}
else
{
NSLog(@"Recorded pixel buffer at time: %lld", currentTime.value);
}
CVPixelBufferUnlockBaseAddress(renderTarget, 0);
}
Я новичок в openGLES и не знаю много об этом. Пожалуйста помоги.
Спасибо