AVAssetWriter 获取原始字节会使设备上的视频损坏适用于 sim

问题描述

所以我的目标是以超高速CVPixelBuffers添加到我的AVAssetWriter / AVAssetWriterInputPixelBufferAdaptor中。我之前的解决方案使用了 CGContextDrawImage,但绘制速度非常慢(0.1 秒)。原因似乎与颜色匹配和转换有关,但我认为这是另一个问题。

我当前的解决方案是尝试直接读取图像的字节以跳过绘制调用。我这样做:

CGImageRef cgImageRef = [image CGImage];
CGImageRetain(cgImageRef);
CVPixelBufferRef pixelBuffer = NULL;
CGDataProviderRef dataProvider = CGImageGetDataProvider(cgImageRef);
CGDataProviderRetain(dataProvider);
CFDataRef da = CGDataProvidercopyData(dataProvider);
CVPixelBufferCreateWithBytes(NULL,CGImageGetWidth(cgImageRef),CGImageGetHeight(cgImageRef),kCVPixelFormatType_32BGRA,(void*)CFDataGetBytePtr(da),CGImageGetBytesPerRow(cgImageRef),NULL,&pixelBuffer);
[writeradaptor appendPixelBuffer:pixelBuffer withPresentationTime:presentTime];    
-- releases here --

这在我的模拟器和应用程序中很好。但是当我在 SpringBoard 进程中运行代码时,它如下图所示。在沙箱外运行它是一项要求,它适用于越狱设备。

我曾尝试玩弄例如像素格式样式,但它主要是带有不同损坏的图像。

正确的图像/视频文件看起来不错:

enter image description here

但这就是我在破碎状态下得到的:

enter image description here

enter image description here

解决方法

回答我自己的问题,因为我认为我得到了答案。分辨率差异是一个简单的代码错误,没有使用后者的设备边界。

颜色问题。简而言之,我在沙箱外运行时得到的 CGImages 使用了更多的字节每像素,8 字节。我在沙箱内运行时得到的图像是 4 个字节。所以基本上我只是将错误的数据写入缓冲区。

因此,不是简单地将较大图像中的所有字节都拍打到较小的缓冲区中。我逐行、逐字节循环遍历像素缓冲区,然后为每个像素选择 RGBA 值。我基本上必须跳过源图像中的所有其他字节才能将正确的数据放入缓冲区中的正确位置。