Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.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
Objective c CVPixelBufferRef的优化_Objective C_Ios_Avassetwriter - Fatal编程技术网

Objective c CVPixelBufferRef的优化

Objective c CVPixelBufferRef的优化,objective-c,ios,avassetwriter,Objective C,Ios,Avassetwriter,我正在做一个项目,在这个项目中,我从UIImage生成了一个视频,其中包含我在这里找到的代码,为了优化它,我挣扎了几天(对于大约300张图像,在模拟器上需要5分钟,并且由于内存问题而在设备上崩溃) 我将从今天的工作代码开始(我使用arc): 现在是获取像素缓冲区的函数,我正在努力: - (CVPixelBufferRef) newPixelBufferFromCGImage: (CGImageRef) image { CVPixelBufferRef pxbuffer = NULL;

我正在做一个项目,在这个项目中,我从UIImage生成了一个视频,其中包含我在这里找到的代码,为了优化它,我挣扎了几天(对于大约300张图像,在模拟器上需要5分钟,并且由于内存问题而在设备上崩溃)

我将从今天的工作代码开始(我使用arc):

现在是获取像素缓冲区的函数,我正在努力:

- (CVPixelBufferRef) newPixelBufferFromCGImage: (CGImageRef) image
{
    CVPixelBufferRef pxbuffer = NULL;

    int width = CGImageGetWidth(image)*2;
    int height = CGImageGetHeight(image)*2;

    NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, [NSNumber numberWithInt:width], kCVPixelBufferWidthKey, [NSNumber numberWithInt:height], kCVPixelBufferHeightKey, nil];
    CVPixelBufferPoolRef pixelBufferPool; 
    CVReturn theError = CVPixelBufferPoolCreate(kCFAllocatorDefault, NULL, (__bridge CFDictionaryRef) attributes, &pixelBufferPool);
    NSParameterAssert(theError == kCVReturnSuccess);
    CVReturn status = CVPixelBufferPoolCreatePixelBuffer(NULL, pixelBufferPool, &pxbuffer);
    NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);

    CVPixelBufferLockBaseAddress(pxbuffer, 0);
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
    NSParameterAssert(pxdata != NULL);

    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pxdata, width,
                                             height, 8, width*4, rgbColorSpace, 
                                             kCGImageAlphaNoneSkipFirst);
    NSParameterAssert(context);
    CGContextDrawImage(context, CGRectMake(0, 0, width, 
                                       height), image);
    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);

    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

    return pxbuffer;
}
第一件奇怪的事情:正如你在这个函数中看到的,我必须将宽度和高度乘以2,否则,结果视频会乱七八糟,我不明白为什么(如果有帮助的话,我可以发布屏幕截图;像素似乎来自我的图像,但宽度不正确,视频的半底部有一个大的黑色正方形)

另一个问题是它需要很大的内存;我认为像素缓冲区不能很好地释放,但我不明白为什么

最后,它非常慢,但我有两个改进它的想法,但我没有使用

  • 第一个是避免使用UIImage创建像素缓冲区,因为我自己用(uint8_t*)数据生成UIImage。我尝试使用“CVPixelBufferCreateWithBytes”,但它不起作用。以下是我如何尝试的:

    OSType pixFmt = CVPixelBufferGetPixelFormatType(pxbuffer);
    CVPixelBufferCreateWithBytes(kCFAllocatorDefault, width, height, pixFmt, self.composition.srcImage.resultImageData, width*2, NULL, NULL, (__bridge CFDictionaryRef) attributes, &pxbuffer);
    
(参数与上述函数的参数相同;我的图像数据以每像素16位进行编码,我找不到一个好的OSType参数提供给函数。) 如果有人知道如何使用它(可能16位/像素数据不可能),它将帮助我避免一个真正无用的转换

  • 第二件事是,我希望在视频中避免使用kCVPixelFormatType_32ARGB。我想使用更少位/像素的东西会更快,但当我尝试它时(我尝试了所有kCVPixelFormatType_16XXXXX格式,使用5位/组件和kCGImageAlphaNoneSkipFirst创建上下文),要么崩溃,要么结果视频不包含任何内容(使用kCVPixelFormatType_16BE555)

我知道我只在一篇文章中问了很多问题,但我对这段代码有点迷茫,我尝试了这么多的组合,但没有一个有效…

我必须将宽度和高度乘以2,否则,结果视频会乱七八糟,我不明白为什么


点与像素?高dpi视网膜屏幕的每点像素数是原来的两倍。

这最多需要10秒。听起来像是你在泄露和复制你的图像数据。你是如何加载图像的?也许有一种更直接的方法可以将它们加载到CVPixelBuffer中。我昨天才设法找到一种不会泄漏的东西!我不太确定问题出在哪里,因为我一直在同时向各个方向搜索。。。我使用了这里的代码:我修改了很多,最后得到了一些不会泄漏的代码。。。它仍然不是完美的,因为我从(int*)数据创建图像,然后再将它们转换为该数据,但至少它不会因为内存问题而崩溃……您有这段代码的最终版本吗?我也有同样的问题。如果你能与我分享,我将不胜感激。谢谢。有同样的问题你能帮忙吗?
OSType pixFmt = CVPixelBufferGetPixelFormatType(pxbuffer);
CVPixelBufferCreateWithBytes(kCFAllocatorDefault, width, height, pixFmt, self.composition.srcImage.resultImageData, width*2, NULL, NULL, (__bridge CFDictionaryRef) attributes, &pxbuffer);