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

我想在AVAssetWriter的帮助下将使用OpenGL渲染的图像logging到电影文件中。 问题出现了,从OpenGL framebuffer访问像素的唯一方法是使用glReadPixels,它只支持iOS上的RGBA-pixel格式。 但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崩溃。 如果我不移动一个字节的缓冲区,它完美的作品(但显然在video文件颜色错误)。 这里有什么问题?

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

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

将图片渲染为纹理(使用具有该纹理的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 } 

如果您在缓冲区的末尾放置了额外的128字节的冗余,会发生什么? 可能是因为OpenGL试图一次性填充4/8/16 / etc字节,并且在缓冲区不alignment或者其他东西的时候出现错误。 这不会是第一次在OpenGL的性能优化有边缘情况下的问题:)

尝试打电话

 glPixelStorei(GL_PACK_ALIGNMENT,1) 

之前glReadPixels。

从文档 :

GL_PACK_ALIGNMENT

指定内存中每个像素行起始的alignment要求。 允许的值是1(字节alignment),2(alignment到偶数字节的行),4(字alignment)和8(行在双字边界上开始)。

默认值是4(见glGet )。 这经常被认为是各种“ OpenGL陷阱 ”types列表中的麻烦制造者,尽pipe这通常与其行填充效果相比缓冲器alignment更重要。

作为一种替代方法,如果malloc增加4个字节会发生什么情况,将glReadPixels作为从缓冲区+4开始的4字节alignment方式,然后传递你的AVAssetWriter缓冲区+3(尽pipe我不知道AVAssetWriter是否更容忍alignment问题)?

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

使用buffer+1将意味着数据不会写在你malloc'd内存的开始,而是一个字节,所以它会写在你malloc'd内存的结束,导致崩溃。

如果iOS的glReadPixels将只接受GL_RGBA,那么你将不得不通过并重新安排他们自己,我认为。

更新,抱歉,我错过了你的malloc中的+1,StilesCrisis可能是正确的关于崩溃的原因。