将RGBA转换为ARGB(glReadPixels - > AVAssetWriter)

时间:2012-01-07 17:11:45

标签: ios opengl-es glreadpixels

我希望在AVAssetWriter的帮助下将使用OpenGL渲染的图像记录到电影文件中。问题出现了,从OpenGL帧缓冲区访问像素的唯一方法是使用glReadPixels,它只支持iOS上的RGBA像素格式。但AVAssetWriter不支持此格式。在这里,我可以使用ARGB或BGRA。由于可以忽略alpha值,我得出结论,将RGBA转换为ARGB的最快方法是给glReadPixels缓冲移位一个字节:

UInt8 *buffer = malloc(width*height*4+1);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer+1);

问题是,glReadPixels电话会导致EXC_BAD_ACCESS崩溃。如果我不将缓冲区移动一个字节,它可以很好地工作(但显然在视频文件中有错误的颜色)。这有什么问题?

5 个答案:

答案 0 :(得分:5)

  

我得出结论,将RGBA转换为ARGB的最快方法是给glReadPixels缓冲移一个字节

然而,这也会将您的Alpha值移动1个像素。这是另一个建议:

将图片渲染为纹理(使用带有该纹理的FBO作为颜色附件)。接下来将纹理渲染到另一个帧缓冲区,使用一个混合片段着色器:

#version ...
uniform sampler2D image;
uniform vec2 image_dim;
void main() 
{
    // we want to address texel centers by absolute fragment coordinates, this
    // requires a bit of work (OpenGL-ES SL doesn't provide texelFetch function).
    gl_FragColor.rgba = 
        texture2D(image, vec2( (2*gl_FragCoord.x + 1)/(2*image_dim.y), 
                               (2*gl_FragCoord.y + 1)/(2*image_dim.y) )
        ).argb; // this swizzles RGBA into ARGB order if read into a RGBA buffer
}

答案 1 :(得分:1)

如果在缓冲区的末尾添加额外的128字节松弛会怎样?可能是OpenGL试图一次填充4/8/16 / etc字节以获得性能,并且当缓冲区未对齐或某事时有错误。这不是第一次OpenGL中的性能优化在边缘情况下出现问题:)

答案 2 :(得分:1)

尝试拨打

glPixelStorei(GL_PACK_ALIGNMENT,1) 

在glReadPixels之前。

来自docs

  

GL_PACK_ALIGNMENT

     

指定内存中每个像素行开头的对齐要求。                               允许的值是                               1(字节对齐),                               2(行与偶数字节对齐),                               4(字对齐),和                               8(行以双字边界开始)。

默认值为4(请参阅glGet)。这通常被称为各种“OpenGL pitfalls”类型lists中的麻烦制造者,尽管这通常更多地与其行填充效果相关,而不是缓冲区对齐。

作为一种替代方法,如果你使用malloc 4个额外字节会发生什么,将glReadPixels作为4字节对齐从缓冲区+4开始,然后传递你的AVAssetWriter缓冲区+3(虽然我不知道AVAssetWriter是否更多容忍对齐问题)?

答案 3 :(得分:0)

您需要通过执行memcpy或其他复制操作来移位字节。修改指针将使它们不对齐,这可能是也可能不在任何底层硬件的能力范围内(DMA总线宽度,磁贴粒度等)。

答案 4 :(得分:-1)

使用buffer+1意味着数据不会写入malloc内存的开头,而是写入一个字节,因此它将写入malloc内存的末尾,导致崩溃

如果iOS的glReadPixels只接受GL_RGBA,那么我认为你必须自己完成并重新安排它们。

更新,对不起我错过了你的malloc中的+1,StilesCrisis可能是关于坠机原因的。