我目前正在尝试使用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];
然后,我使用copyPixelBufferForItemTime
中的AVPlayerItemVideoOutput
功能,并在特定时间接收与初始视频的帧相对应的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);
}
通过这样做(以及使用一些非相关算法来做一些增强现实的事情)我得到了一个非常奇怪的结果,好像视频已被放入切片中(我无法告诉你,因为我没有&#39有足够的声誉这样做。)
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
文件,但我该怎么做才能检查此文件是否有问题?
非常感谢您的帮助,我真的坚持这个问题好几个小时/几天!
答案 0 :(得分:1)
您需要使用kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange。
然后将它们转移到单独的色度和亮度OpenGLES纹理。 https://developer.apple.com/library/ios/samplecode/AVBasicVideoOutput/Listings/AVBasicVideoOutput_APLEAGLView_m.html
上的示例我尝试使用几种基于RGB的选项,但无法使其正常工作。