簡體   English   中英

在CVPixelBufferGetBaseAddress()讀取緩沖區時,我得到了以前的渲染圖像(不是當前圖像)

[英]I get previous rendered image (not current) when read buffer at CVPixelBufferGetBaseAddress()

現在,我正在開發針對iOS4.1或更高版本的圖像處理應用程序。

我想在iOS5上運行應用時使用CVOpenGLESTextureCache。

我通過以下代碼創建紋理緩存

NSDictionary *empty = [NSDictionary dictionary];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                        [NSNumber numberWithBool:NO], kCVPixelBufferCGImageCompatibilityKey,
                        [NSNumber numberWithBool:NO], kCVPixelBufferCGBitmapContextCompatibilityKey,
                        empty, kCVPixelBufferIOSurfacePropertiesKey,
                        nil];
CVPixelBufferCreate(kCFAllocatorDefault, texSize_.width, texSize_.height, kCVPixelFormatType_32BGRA, (CFDictionaryRef)options, &renderTarget);
CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
                                   filterTextureCache, renderTarget,
                                   NULL, // texture attributes
                                   GL_TEXTURE_2D,
                                   GL_RGBA, // opengl format
                                   (int)texSize_.width, 
                                   (int)texSize_.height,
                                   GL_BGRA, // native iOS format
                                   GL_UNSIGNED_BYTE,
                                   0,
                                   &renderTexture);
texID_ = CVOpenGLESTextureGetName(renderTexture);

並通過標准方法(glFrameBufferTexture2D和glDrawArray)渲染一些元素以創建紋理。

之后,我嘗試讀取CVPixelBuffer並創建映像。

- (UIImage *)imageFromTextureCache {
    if (renderTarget) {
        if (kCVReturnSuccess == CVPixelBufferLockBaseAddress(renderTarget,
                                                             kCVPixelBufferLock_ReadOnly)) {
            uint8_t* pixels=(uint8_t*)CVPixelBufferGetBaseAddress(renderTarget);

            CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, CVPixelBufferGetDataSize(renderTarget), bufferFree);
            CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
            CGImageRef imageRef = CGImageCreate(texSize_.width, texSize_.height, 8, 32, 4 * texSize_.width, colorSpaceRef, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst, provider, NULL, NO, kCGRenderingIntentDefault);
            CGImageRef cloppedImageRef = imageRef;
            if (!CGSizeEqualToSize(CGSizeMake(1.0, 1.0), contentRatio_)) {
                cloppedImageRef = CGImageCreateWithImageInRect(imageRef, CGRectMake(0, 0, texSize_.width * contentRatio_.width, texSize_.height * contentRatio_.height));
            }

            UIImage *image = [UIImage imageWithCGImage:cloppedImageRef];

            if (!CGSizeEqualToSize(CGSizeMake(1.0, 1.0), contentRatio_)) {
                CGImageRelease(cloppedImageRef);
            }
            CGColorSpaceRelease(colorSpaceRef);
            CGDataProviderRelease(provider);
            CVPixelBufferUnlockBaseAddress(renderTarget, kCVPixelBufferLock_ReadOnly);
            return image;
        }
        return nil;
    }
    return nil;
}

UIImage *image = [outputTexture_ imageFromTextureCache];

然后我得到了以前的渲染圖像。 不是最新的。

但是我修改了如下代碼,以獲得當前的渲染圖像。

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texID, 0);
GLubyte *buffer = (GLubyte *)calloc(sizeof(GLubyte), 1);
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

UIImage *image = [outputTexture_ imageFromTextureCache];

我不明白會發生什么。 而且我找不到關於此的任何文檔。

有人幫我嗎?

抱歉,我的英文很便宜...謝謝。

直接從與紋理緩存關聯的紋理讀取時,不能保證在讀取這些字節時對該紋理執行的任何OpenGL ES渲染都已完成。 使用glReadPixels()時看到正確的當前幀的原因是它會阻塞直到渲染完成。

為了確保從紋理讀取之前所有渲染都已完成,可以在讀取紋理數據之前放置glFinish()調用。 這將阻塞,直到所有渲染完成。 對於視頻,可以通過錯開glFlush()glFinish()調用來獲得一些技巧,以獲得更好的性能,但是在您的情況下,簡單的glFinish()應該可以解決問題。

是的,請在訪問緩沖區之前使用glFlush,並在訪問后使用glFinish。 我有同樣的問題

http://www.khronos.org/opengles/sdk/1.1/docs/man/glFlush.xml

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM