这真是个笨蛋。
正如Lio Ben-Kereth指出的那样,从调试器可以看到,填充为48
(gdb) po pixelBuffer
<CVPixelBuffer 0x2934d0 width=852 height=640 bytesPerRow=3456 pixelFormat=BGRA
# => 3456 - 852 * 4 = 48
OpenGL的可以弥补这一点,但OpenGL ES的不能 (更多的信息在这里openGL的SubTexturing )
所以这是我在OpenGL ES中的操作方式:
(CVImageBufferRef)pixelBuffer // pixelBuffer containing the raw image data is passed in
/* ... */
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, videoFrameTexture_);
int frameWidth = CVPixelBufferGetWidth(pixelBuffer);
int frameHeight = CVPixelBufferGetHeight(pixelBuffer);
size_t bytesPerRow, extraBytes;
bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer);
extraBytes = bytesPerRow - frameWidth*4;
GLubyte *pixelBufferAddr = CVPixelBufferGetBaseAddress(pixelBuffer);
if ( [[captureSession sessionPreset] isEqualToString:@"AVCaptureSessionPresetPhoto"] )
{
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, frameWidth, frameHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL );
for( int h = 0; h < frameHeight; h++ )
{
GLubyte *row = pixelBufferAddr + h * (frameWidth * 4 + extraBytes);
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, h, frameWidth, 1, GL_BGRA, GL_UNSIGNED_BYTE, row );
}
}
else
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, frameWidth, frameHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixelBufferAddr);
}
以前,我使用AVCaptureSessionPresetMedium
并获得30fps。在AVCaptureSessionPresetPhoto
我在iPhone 4上获得16fps的帧。子纹理的循环似乎并不影响帧速率。
我在iOS 5上使用iPhone 4。
0
在较高的层次上,我创建了一个应用程序,使用户可以将他或她的iPhone相机指向周围,并查看经过视觉效果处理的视频帧。此外,用户可以点击一个按钮以将当前预览的定格图像作为高分辨率照片保存在其iPhone库中。
为此,该应用遵循以下过程:
1)创建一个AVCaptureSession
2)使用后置摄像头连接AVCaptureDeviceInput。
3)将AVCaptureStillImageOutput连接到会话,以便能够以照片分辨率捕获静止帧。
4)将AVCaptureVideoDataOutput连接到会话,以便能够以较低的分辨率捕获单个视频帧(CVImageBuffers)
5)捕获视频帧后,将使用每个新帧作为CVImageBuffer调用委托的方法:
6)然后,委托人处理/绘制它们:
所有这些都起作用,并导致正确的结果。我可以看到通过OpenGL处理的640x480的视频预览。看起来像这样:
但是,如果我从此会话中捕获静止图像,则其分辨率也将为640x480。我希望它具有高分辨率,因此在第一步中,将预设行更改为:
这样可以正确捕获iPhone4(2592x1936)最高分辨率的静止图像。
但是,视频预览(由代表在步骤5和6中收到)现在看起来像这样:
我已经确认所有其他预设(高,中,低,640x480和1280x720)都能按预期进行预览。但是,“照片”预设似乎以不同的格式发送缓冲区数据。
我还通过获取缓冲区并从中创建UIImage而不是将其发送到openGL来确认,在“照片”预设处发送到缓冲区的数据实际上是有效的图像数据:
这显示了未失真的视频帧。
我已经做了很多搜索,但似乎无法解决。我的直觉是这是数据格式问题。也就是说,我相信缓冲区设置正确,但是格式是该行不理解的:
我的直觉是,将外部格式从GL_BGRA更改为其他格式会有所帮助,但这无济于事……并且通过各种方式,看起来缓冲区实际上在GL_BGRA中。
有人知道这是怎么回事吗?还是您对我如何调试这种情况的原因有任何建议? (超级奇怪的是,这发生在iphone4上,而不是在iPhone 3GS上……都运行ios4.3)