Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 来自OpenGL的CMSampleBuffer,用于使用AvassestWriter输出视频_Iphone_Objective C_Opengl Es_Avassetwriter_Core Motion - Fatal编程技术网

Iphone 来自OpenGL的CMSampleBuffer,用于使用AvassestWriter输出视频

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

我需要为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);
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,而是对其进行回收。我创建了一个缓冲池类。我对短循环的操作略有不同。我将每个图像保存到存储器中,然后在稍后按顺序将其读回。