2

我正在尝试录制 GLKView 中显示的内容的视频。我正在使用 Sparrow 框架在 openGL 中显示所需的内容。我正在使用帧缓冲区对象或 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的新手,对它了解不多。请帮忙。

谢谢

4

0 回答 0