在iPhone GPU上解码video帧
我正在寻找最快的方式来解码iPhone上的本地mpeg-4video帧。 我只是感兴趣的像素在每10帧的亮度值。 我不需要在任何地方渲染video。
我试过ffmpeg,AVAssetReader,ImageAssetGenerator,OpenCV和MPMoviePlayer,但它们都太慢了。 我能得到的最快速度是2倍(一分钟内扫描2分钟的video)。 我想要更接近10倍的东西。
假设我上面的尝试没有使用GPU,是否有任何方法来完成我的目标与GPU上运行的东西? OpenGL似乎主要是为渲染输出,但我已经看到它用作传入video的filter。 也许这是一个select?
提前致谢!
如果您愿意使用仅适用于iOS 5的解决scheme,请参阅AVCaputureSession上2011年WWDC会话中的示例应用程序ChromaKey。
该演示从内置摄像头捕获30 FPS的video,并将每帧作为纹理传递给OpenGL。 然后使用OpenGL来处理帧,并将结果写入输出video文件。
该代码使用一些严重的低级魔法,将AVCaptureSession的Core Video Pixel缓冲区绑定到OpenGL,以便在graphics硬件中共享内存。
将AVCaptureSession更改为使用电影文件作为input而不是相机input应该相当简单。
您可能可以设置会话以Y / UV格式而不是RGB格式传送帧,其中Y分量是亮度。 否则,写一个将每个像素的RGB值转换为亮度值的着色器将是非常简单的事情。
你应该可以在所有帧上做所有这些,而不是每10帧。
看起来vImage可能是合适的,假设你可以使用iOS 5.每一个第10帧似乎都是使用像vImage这样的框架的理由。 但是,任何types的实时实时处理几乎肯定会需要OpenGL。
假设应用程序的瓶颈在于将video帧转换为可显示格式(如RGB)的代码,您可能对我共享的代码感兴趣,该代码用于将一个.mp4帧(编码为YV12)转换为RGB Qt和OpenGL 。 这个应用程序将该帧上传到GPU并激活GLSL片段着色器来执行从YV12到RGB的转换,因此它可以显示在QImage
。
static const char *p_s_fragment_shader = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;" "uniform float ImgHeight, chromaHeight_Half, chromaWidth;" "void main()" "{" " vec2 t = gl_TexCoord[0].xy;" // get texcoord from fixed-function pipeline " float CbY = ImgHeight + floor(ty / 4.0);" " float CrY = ImgHeight + chromaHeight_Half + floor(ty / 4.0);" " float CbCrX = floor(tx / 2.0) + chromaWidth * floor(mod(ty, 2.0));" " float Cb = texture2DRect(tex, vec2(CbCrX, CbY)).x - .5;" " float Cr = texture2DRect(tex, vec2(CbCrX, CrY)).x - .5;" " float y = texture2DRect(tex, t).x;" // redundant texture read optimized away by texture cache " float r = y + 1.28033 * Cr;" " float g = y - .21482 * Cb - .38059 * Cr;" " float b = y + 2.12798 * Cb;" " gl_FragColor = vec4(r, g, b, 1.0);" "}"