我正在开发一个应用在OpenGLES场景中使用纹理播放视频的应用 当我开始播放视频时,它进入循环并耗尽内存导致应用程序崩溃。 xCode只是说“与------ iPhone失去联系”(感谢Apple,很好的帮助),但是在深入了解之后...... 似乎很清楚问题来自纹理,但我无法修复它。 以下是我宣布变种的方法: 这是代码的其余部分: 我是OpenGL的新手,所以我想我错过了“HOW”和“WHERE”来释放以前的帧。 我尝试了“glDeleteTextures”,但不确定这是否是解决方案。 // Points to an unmanaged texture manager object, which can access an OpenGL texture
private var texturePointer = UnsafeMutablePointer<CVOpenGLESTexture?>.alloc(1)
// Cache for managing the video texture pointers
private var videoTextureCachePointer = UnsafeMutablePointer<CVOpenGLESTextureCache?>.alloc(1)
// Load an image buffer into OpenGL
private func loadImageTexture(pixelBuffer: CVPixelBuffer!) {
// If null, return for safety
if (pixelBuffer == nil) {
return;
}
// Get frame size
let frameWidth = CVPixelBufferGetWidth(pixelBuffer)
let frameHeight = CVPixelBufferGetHeight(pixelBuffer)
// Release previous frame: No longer valid on iOS9! <-I should be removing old frames!
//texturePointer.release()
// Periodic texture cache flush every frame
let videoTextureCache = videoTextureCachePointer.memory!
CVOpenGLESTextureCacheFlush(videoTextureCache, 0);
// Copy from CPU to GPU
glActiveTexture(GLenum(GL_TEXTURE0))
CVOpenGLESTextureCacheCreateTextureFromImage(
kCFAllocatorDefault,
videoTextureCache,
pixelBuffer,
nil,
GLenum(GL_TEXTURE_2D),
GLint(GL_RGBA),
GLsizei(frameWidth),
GLsizei(frameHeight),
GLenum(GL_BGRA),
GLenum(GL_UNSIGNED_BYTE),
0,
&texturePointer.memory)
// Extract texture
let videoTexture = texturePointer[0]!
let videoTextureId = CVOpenGLESTextureGetName(videoTexture)
imageTexture = videoTextureId
// Configure texture
glBindTexture(CVOpenGLESTextureGetTarget(videoTexture), CVOpenGLESTextureGetName(videoTexture));
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_LINEAR);
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GL_LINEAR);
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), GL_CLAMP_TO_EDGE);
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), GL_CLAMP_TO_EDGE);
}
答案 0 :(得分:1)
不需要多个纹理或任何类型的缓存。我建议你创建一个固定(足够大)大小的单个纹理,例如2024x2024,带有空数据(传递nil作为数据参数)。然后,当您获得像素缓冲区时,请使用glTexSubImage
在(0, 0 , videoWidth, videoHeight)
传输数据。现在,您的纹理已填充,由像素缓冲区数据重写,可以绘制。需要计算纹理坐标,然后(0, 0, videoWidth/textureWidth, videoHeight/textureHeight)
。这就是它。如果泄漏持续存在,则与openGL无关。如果你不再需要它(当视频完成播放时,或者如果你想将其重复用于其他视频,则应删除纹理)。