3

在 RPBroadcastSampleHandler 中处理 CMSampleBuffer 到 NSData 转换时出现超出内存允许的错误。错误代码:线程 7:EXC_RESOURCE RESOURCE_TYPE_MEMORY(限制 = 50 MB,未使用 = 0x0)

我正在处理将大型 1920x1440 图像转换为二进制以发送到套接字服务器的功能。我尝试将大小调整为 1200x900,但没有任何效果。

我花了一个星期来处理这个问题,但无济于事。我尝试了以下方法:使用此处的说明调整图像大小:https ://nshipster.com/image-resizing/

  1. 从 SampleBuffer 中获取 UIImage 对象,然后将其转换为压缩质量最低的 jpegData。
    func getDataFromCMSampleBuffer (sampleBuffer: CMSampleBuffer) -> Data? {
        if CMSampleBufferDataIsReady (sampleBuffer),
            let pixelBuffer = CMSampleBufferGetImageBuffer (sampleBuffer) {
            let ciImage = CIImage (cvImageBuffer: pixelBuffer)
            let image = UIImage (ciImage: ciImage)
            return (image.jpegData (compressionQuality: 0.0)) // Error Thread 7: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit = 50 MB, unused = 0x0)
        }
        return nil
    }
  1. 在转换为 NSData 之前从 CMSampleBuffer 调整 UIImage 对象的大小
    let renderer = UIGraphicsImageRenderer (size: CGSize (width: 1200, height: 900))
    return renderer.image {(context) in
        image.draw (in: CGRect (origin: .zero, size: size)) // Error Thread 7: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit = 50 MB, unused = 0x0)
    }

或者

    UIGraphicsBeginImageContextWithOptions (CGSizeMake (newWidth, newHeight), NO, 0);
    [sourceImage drawInRect: CGRectMake (0, 0, 1200, 900)]; //// Error Thread 7: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit = 50 MB, unused = 0x0)
    UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext ();
    UIGraphicsEndImageContext ();
  1. 在转换为 NSData 之前从 CMSampleBuffer 获取图像位图
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB ();
    CGContextRef context = CGBitmapContextCreate (rgbBuffer, width, height, 8, width * bytesPerPixel, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
    CGImageRef quartzImage = CGBitmapContextCreateImage (context); // Thread 7 error: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit = 50 MB, unused = 0x0)
    UIImage * image = [UIImage imageWithCGImage: quartzImage];
  1. 在转换为 NSData 之前缩放 CIImage
    CIFilter *filter = [CIFilter filterWithName:@"CILanczosScaleTransform"];
    [filter setValue:image forKey:kCIInputImageKey];
    [filter setValue:[NSNumber numberWithDouble:0.2] forKey:kCIInputScaleKey];
    [filter setValue:@1.0 forKey:kCIInputAspectRatioKey];
    CIImage *img = (CIImage*)[filter valueForKey:kCIOutputImageKey];

...
    CIContext *context = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer: @NO}];

    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();

    [context render:img toBitmap:rawData rowBytes:width*kComponentsPerPixel bounds:img.extent format:kCIFormatRGBA8 colorSpace:rgb];// Thread 7 error: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit = 50 MB, unused = 0x0)

    CGDataProviderRef provider = CGDataProviderCreateWithData(nil, rawData, memsize, releasePixels);

有没有办法在不超过 50MB 内存的情况下从 CMSampleBuffer 转换为 NSData 图像并且图像质量不会降低太多。或者有什么方法可以调整不使用超过 50MB 内存的大图像的大小?

我提供的任何建议都非常感谢。

4

0 回答 0