我这样做的方法是创建一个Core Graphics位图上下文然后绘制它,但它太慢了.具体来说,我需要将图像绘制到缓冲区中.
那么可以提供某种关于如何更有效地做到这一点的提示或建议吗?
我想过使用OpenGL来实现它,即首先从CMSampleBuffer创建一个纹理A.然后将从我想要绘制的图像创建的纹理B渲染到纹理A中,然后从OpenGL检索支持纹理A的数据,最后将该数据移交给AVAssetWriter / AVAssetWriterinput.但是文档说,将纹理数据从GPU传输回cpu有点贵.
那么,有关如何处理的任何建议?
提前致谢
解决方法 OpenGL可能就是这样.但是,渲染到屏幕外的帧缓冲区而不是纹理可能稍微有点效率.要从样本缓冲区中提取纹理:
// Note the caller is responsible for calling glDeleteTextures on the return value.- (gluint)textureFromSampleBuffer:(CMSampleBufferRef)sampleBuffer { gluint texture = 0; glGenTextures(1,&texture); glBindTexture(GL_TEXTURE_2D,texture); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_liNEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); CVImageBufferRef pixelBuffer = CMSampleBufferGetimageBuffer(sampleBuffer); CVPixelBufferLockBaseAddress(pixelBuffer,0); int wIDth = CVPixelBufferGetWIDth(pixelBuffer); int height = CVPixelBufferGetHeight(pixelBuffer); glTexImage2D(GL_TEXTURE_2D,GL_RGBA,wIDth,height,GL_BGRA,GL_UNSIGNED_BYTE,CVPixelBufferGetBaseAddress(pixelBuffer)); CVPixelBufferUnlockBaseAddress(pixelBuffer,0); return texture;}
要通过OpenGL处理纹理,您可以执行以下 *** 作:
// This function exists to free the malloced data when the CGDataProvIDerRef is// eventually freed.voID dataProvIDerFreeData(voID *info,const voID *data,size_t size){ free((voID *)data);}// Returns an autoreleased CGImageRef.- (CGImageRef)processtexture:(gluint)texture wIDth:(int)wIDth height:(int)height { CGImageRef newImage = NulL; // Set up framebuffer and renderbuffer. gluint framebuffer; glGenFramebuffers(1,&framebuffer); glBindFramebuffer(GL_FRAMEBUFFER,framebuffer); gluint colorRenderbuffer; glGenRenderbuffers(1,&colorRenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER,colorRenderbuffer); glrenderbufferStorage(GL_RENDERBUFFER,GL_RGBA8_OES,height); glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_color_ATTACHMENT0,GL_RENDERBUFFER,colorRenderbuffer); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { NSLog(@"Failed to create OpenGL frame buffer: %x",status); } else { glVIEwport(0,height); glClearcolor(0.0,0.0,1.0); glClear(GL_color_BUFFER_BIT); // Do whatever is necessary to actually draw the texture to the framebuffer [self renderTexturetoCurrentFrameBuffer:texture]; // Read the pixels out of the framebuffer voID *data = malloc(wIDth * height * 4); glreadPixels(0,data); // Convert the data to a CGImageRef. Note that CGDataProvIDerRef takes // ownership of our malloced data buffer,and the CGImageRef internally // retains the CGDataProvIDerRef. Hence the callback above,to free the data // buffer when the provIDer is finally released. CGDataProvIDerRef dataProvIDer = CGDataProvIDerCreateWithData(NulL,data,wIDth * height * 4,dataProvIDerFreeData); CGcolorSpaceRef colorspace = CGcolorSpaceCreateDeviceRGB(); newImage = CGImageCreate(wIDth,8,32,wIDth*4,colorspace,kCGBitmapByteOrder32Big | kCGImageAlphaPremultiplIEdLast,dataProvIDer,NulL,true,kCGRenderingIntentDefault); CFRelease(dataProvIDer); CGcolorSpaceRelease(colorspace); // autorelease the CGImageRef newImage = (CGImageRef)[NSMakeCollectable(newImage) autorelease]; } // Clean up the framebuffer and renderbuffer. glDeleteRenderbuffers(1,&colorRenderbuffer); glDeleteFramebuffers(1,&framebuffer); return newImage;}总结
以上是内存溢出为你收集整理的ios – 修改CMSampleBuffer内容的最有效方法全部内容,希望文章能够帮你解决ios – 修改CMSampleBuffer内容的最有效方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)