Ios OpenGL格式纹理

Ios OpenGL格式纹理,ios,opengl-es,textures,avfoundation,Ios,Opengl Es,Textures,Avfoundation,我目前正在尝试在iOS上使用OpenGL ES 2在屏幕上显示视频 我将总结一下我在屏幕上播放和显示视频所做的工作: 首先,我使用GPUImageMovieWriter对象录制了一个.mov文件。录制完成后,我将使用AVPlayer播放视频。因此,我将AVPlayerItemVideoOutput设置为能够从视频中检索帧: NSDictionary *test = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt:kCVPi

我目前正在尝试在iOS上使用
OpenGL ES 2
在屏幕上显示视频

我将总结一下我在屏幕上播放和显示视频所做的工作:

首先,我使用
GPUImageMovieWriter
对象录制了一个.mov文件。录制完成后,我将使用
AVPlayer
播放视频。因此,我将
AVPlayerItemVideoOutput
设置为能够从视频中检索帧:

NSDictionary *test = [NSDictionary dictionaryWithObject: [NSNumber  numberWithInt:kCVPixelFormatType_32BGRA] forKey: (id)kCVPixelBufferPixelFormatTypeKey];
        self.videoOutput = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:test];
然后,我使用
AVPlayerItemVideoOutput
中的
copyPixelBufferForItemTime
功能,在特定时间接收与初始视频帧对应的
CVImageBufferRef

最后,这里是我创建的用于从缓冲区创建
OpenGL
纹理的函数:

- (void)setupTextureFromBuffer:(CVImageBufferRef)imageBuffer {

  CVPixelBufferLockBaseAddress(imageBuffer, 0);

  int bufferHeight = CVPixelBufferGetHeight(imageBuffer);
  int bufferWidth = CVPixelBufferGetWidth(imageBuffer);

  CVPixelBufferGetPixelFormatType(imageBuffer);
  glBindTexture(GL_TEXTURE_2D, m_videoTexture);

  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferWidth, bufferHeight, 0, GL_RGBA,    GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress(imageBuffer));

  CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
}
通过这样做(同时使用一些无关的算法来做一些增强现实的事情),我得到了一个非常奇怪的结果,好像视频被分成了几片(我不能给你看,因为我没有足够的声誉来这样做)

看起来数据没有被
OpenGL
很好地解释(错误的格式?类型?)

我使用此函数检查是否可能是损坏的缓冲区错误:

- (void)saveImage:(CVPixelBufferRef)pixBuffer
{
    CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixBuffer];

    CIContext *temporaryContext = [CIContext contextWithOptions:nil];
    CGImageRef videoImage = [temporaryContext
                             createCGImage:ciImage
                             fromRect:CGRectMake(0, 0,
                                                 CVPixelBufferGetWidth(pixBuffer),
                                                 CVPixelBufferGetHeight(pixBuffer))];

    UIImage *uiImage = [UIImage imageWithCGImage:videoImage];

    UIImageWriteToSavedPhotosAlbum(uiImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

}    
->保存的图像正确显示在相册中

它可能来自
.mov
文件,但如何检查此文件是否有问题


非常感谢你的帮助,我真的被这个问题困扰了好几个小时/天

您需要使用kcvpixelformattype420ypcbcr8biplanarvidearrange

然后将它们转移到单独的色度和亮度OpenGLES纹理。举例


我尝试使用了几种基于RGB的选项,但无法使其正常工作。

最好的选择是您的像素缓冲区不包含纹理预期的RGBA数据。尝试从缓冲区获取格式,或者至少检查缓冲区中每行的字节数,看看它是否签出(4*宽度)。因为它来自视频,所以可能只是RGB数据导致图像被切片。导致切片图像的另一个问题可能是缓冲区数据翻转了轴,因此宽度和高度被翻转,在这种情况下,在将数据发送到纹理时,只需翻转宽度和高度参数。您好,eesdee,我检查了每行的字节数,你是对的,我通过计算4*bufferWidth得到1440,通过函数CVPixelBufferGetBytesPerRow(imageBuffer)得到1472。这意味着我使用的RGBA格式不是视频的正确格式,对吗?我可以使用CVPixelBufferGetPixelFormatType检查像素格式,但我会得到一个数字,我不知道该怎么办..我犯了一个错误,我的意思是:你是对的,很抱歉出错尝试这样显示它:char cString[5];cString[4]=0;memcpy(cString,cvpixelbuffergetpixelformatype(),4);NSString*string=[NSString stringWithUTF8String:cString];你能告诉我缓冲器的尺寸(宽度和高度)吗。