Iphone 来自OpenGL的CMSampleBuffer,用于使用AvassestWriter输出视频
我需要为OpenGL框架获取一个CMSampleBuffer。我用这个:Iphone 来自OpenGL的CMSampleBuffer,用于使用AvassestWriter输出视频,iphone,objective-c,opengl-es,avassetwriter,core-motion,Iphone,Objective C,Opengl Es,Avassetwriter,Core Motion,我需要为OpenGL框架获取一个CMSampleBuffer。我用这个: int s = 1; UIScreen * screen = [UIScreen mainScreen]; if ([screen respondsToSelector:@selector(scale)]){ s = (int)[screen scale]; } const int w = viewController.view.fra
int s = 1;
UIScreen * screen = [UIScreen mainScreen];
if ([screen respondsToSelector:@selector(scale)]){
s = (int)[screen scale];
}
const int w = viewController.view.frame.size.width/2;
const int h = viewController.view.frame.size.height/2;
const NSInteger my_data_length = 4*w*h*s*s;
// allocate array and read pixels into it.
GLubyte * buffer = malloc(my_data_length);
glReadPixels(0, 0, w*s, h*s, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// gl renders "upside down" so swap top to bottom into new array.
GLubyte * buffer2 = malloc(my_data_length);
for(int y = 0; y < h*s; y++){
memcpy(buffer2 + (h*s - 1 - y)*4*w*s, buffer + (4*y*w*s), 4*w*s);
}
free(buffer);
CMBlockBufferRef * cm_block_buffer_ref;
CMBlockBufferAccessDataBytes(cm_block_buffer_ref,0,my_data_length,buffer2,*buffer2);
CMSampleBufferRef * cm_buffer;
CMSampleBufferCreate (kCFAllocatorDefault,cm_block_buffer_ref,true,NULL,NULL,NULL,1,1,NULL,0,NULL,cm_buffer);
ints=1;
UIScreen*屏幕=[UIScreen Main screen];
如果([屏幕响应选择器:@选择器(比例)]){
s=(int)[屏幕比例];
}
const int w=viewController.view.frame.size.width/2;
const int h=viewController.view.frame.size.height/2;
const NSInteger my_data_length=4*w*h*s*s;
//分配数组并将像素读入其中。
GLubyte*buffer=malloc(我的数据长度);
glReadPixels(0,0,w*s,h*s,GL_RGBA,GL_无符号字节,缓冲区);
//gl呈现“倒置”,以便从上到下交换到新阵列中。
GLubyte*buffer2=malloc(我的数据长度);
对于(int y=0;y
我获得了CMSampleBufferCreate的EXEC\u BAD\u访问权限
非常感谢您的帮助。为什么在您的代码中
CMSampleBufferCreate()
的第三个参数为true?根据报告:
参数
分配器
用于为CMSampleBuffer分配内存的分配器
对象将kCFAllocatorDefault传递给
使用当前的默认分配器
数据缓冲器
这可以是NULL,一个没有备份内存的CMBClockBuffer,
带后备存储器的缓冲区
但是还没有数据,或者是缓冲区
已包含媒体数据的。
仅在最后一种情况下(或如果为NULL且
numSamples为0)是否应为dataReady
对
数据就绪
指示dataBuffer是否已包含媒体
数据
作为缓冲区传入的cm\u block\u buffer\u ref
不包含任何数据(为了安全起见,您应该将其设为NULL,我认为编译器默认不会这样做),因此您应该在此处使用false
这可能还有其他问题,但这是我想到的第一个问题。解决方案是使用AvassetWriteInputPixelBufferAdapter类
int s = 1;
UIScreen * screen = [UIScreen mainScreen];
if ([screen respondsToSelector:@selector(scale)]){
s = (int)[screen scale];
}
const int w = viewController.view.frame.size.width/2;
const int h = viewController.view.frame.size.height/2;
const NSInteger my_data_length = 4*w*h*s*s;
// allocate array and read pixels into it.
GLubyte * buffer = malloc(my_data_length);
glReadPixels(0, 0, w*s, h*s, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// gl renders "upside down" so swap top to bottom into new array.
GLubyte * buffer2 = malloc(my_data_length);
for(int y = 0; y < h*s; y++){
memcpy(buffer2 + (h*s - 1 - y)*4*w*s, buffer + (4*y*w*s), 4*w*s);
}
free(buffer);
CVPixelBufferRef pixel_buffer = NULL;
CVPixelBufferCreateWithBytes (NULL,w*2,h*2,kCVPixelFormatType_32BGRA,buffer2,4*w*s,NULL,0,NULL,&pixel_buffer);
[av_adaptor appendPixelBuffer: pixel_buffer withPresentationTime:CMTimeMakeWithSeconds([[NSDate date] timeIntervalSinceDate: start_time],30)];
ints=1;
UIScreen*屏幕=[UIScreen Main screen];
如果([屏幕响应选择器:@选择器(比例)]){
s=(int)[屏幕比例];
}
const int w=viewController.view.frame.size.width/2;
const int h=viewController.view.frame.size.height/2;
const NSInteger my_data_length=4*w*h*s*s;
//分配数组并将像素读入其中。
GLubyte*buffer=malloc(我的数据长度);
glReadPixels(0,0,w*s,h*s,GL_RGBA,GL_无符号字节,缓冲区);
//gl呈现“倒置”,以便从上到下交换到新阵列中。
GLubyte*buffer2=malloc(我的数据长度);
对于(int y=0;y
为什么要使用双malloc,为什么不通过临时缓冲区就地交换
大概是这样的:
GLubyte * raw = (GLubyte *) wyMalloc(size);
LOGD("raw address %p", raw);
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, raw);
const size_t end = h/2;
const size_t W = 4*w;
GLubyte row[4*w];
for (int i=0; i <= end; i++) {
void * top = raw + (h - i - 1)*W;
void * bottom = raw + i*W;
memcpy(row, top, W);
memcpy(top, bottom, W);
memcpy(bottom, row, W);
}
GLubyte*raw=(GLubyte*)wyMalloc(大小);
LOGD(“原始地址%p”,原始);
glReadPixels(x、y、w、h、GL_RGBA、GL_无符号字节、raw);
常数大小=h/2;
常数大小W=4*W;
GLubyte行[4*w];
对于(int i=0;谢谢。如何让cm_block_buffer_ref包含OpenGL数据?@Matthew-看看它,我认为您需要创建一个CVPixelBuffer,然后使用CMSampleBufferCreateForImageBuffer()
而不是CMSampleBufferCreate())
。事实上,使用AvassetWriterInputPixelBufferAdapter可能会更好:哦,是的,我添加了自己的答案。我已经设法让它工作了(有点慢,但glReadPixels应该是这样的)。但谢谢。我甚至不再对原始缓冲区进行malloc,而是对其进行回收。我创建了一个缓冲池类。我对短循环的操作略有不同。我将每个图像保存到存储器中,然后在稍后按顺序将其读回。