我需要为OpenGL框架获取CMSampleBuffer。我用这个:
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);
我获得了CMSampleBufferCreate的EXEC_BAD_ACCESS。
感谢任何帮助,谢谢。
答案 0 :(得分:6)
解决方案是使用AVAssetWriterInputPixelBufferAdaptor类。
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)];
答案 1 :(得分:1)
为什么代码中第三个参数CMSampleBufferCreate()
为真?根据{{3}}:
<强>参数强>
分配器
用于为CMSampleBuffer分配内存的分配器 宾语。将kCFAllocatorDefault传递给 使用当前的默认分配器。
dataBuffer
这可以是NULL,一个没有后备内存的CMBlockBuffer, 带有后备内存的CMBlockBuffer 但还没有数据,或者是CMBlockBuffer 已经包含媒体数据。 仅在最后一种情况下(或者如果是NULL和 numSamples是0)dataReady应该是 真。
dataReady
指示dataBuffer是否已包含媒体 数据
作为缓冲区传入的cm_block_buffer_ref
不包含任何数据(出于安全考虑,您应该将其设为NULL,我认为编译器默认不这样做),因此您应该使用false
这里。
这可能还有其他问题,但这是跳出来的第一个项目。
答案 2 :(得分:0)
为什么双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);
}