美文网首页
AVFrame转UIImage导致ERROR_CGDataPro

AVFrame转UIImage导致ERROR_CGDataPro

作者: 星星杨 | 来源:发表于2022-11-28 10:56 被阅读0次

在处理视频的时候,有个画中画的需求,需要展示视频的一张静态图,作为占位;所以选择把AVFrame转成UIImage供后面需要调用的地方使用,当然如果截屏的操作也可以这么做;但是后面在使用UIImage过程中会遇到一个问题,如下所示;



分析原因大概就是要访问的这片内存空间不可被读取,结合之前使用UIImage做视频渲染所遇到的问题:
即AVFrame->UIImage->render->release;
也是遇到同样的问题,报错定位在Release;
CGColorSpaceRelease(colorSpace);

现在的步骤是:
即AVFrame->UIImage->saveCache->release->waitRender;
所以分析原因还是图片在使用之前时候已经被释放掉了,所以此时考虑对图片做一次深拷贝,保证图片颜色内存空间跟数据缓存区不被释放;

处理方法是,对图片进行缩放(因为占位小图不需要那么大的size),再对图片信息进行压缩,最后再转成image缓存起来;

result = [UIImage imageWithCGImage:cgImage];
        UIImage *uimage = (UIImage *)result;
        CGFloat zoomWidth = kScreenWidth/3 * 2;
        // 转一下,才能保证后续在使用的时候不报错,缩小尺寸,减少内存占用
        uimage = [uimage transformWidth:zoomWidth Height:zoomWidth*kPreviewImageScale];
        NSData *imageData = UIImageJPEGRepresentation(uimage, 0.5);
        result = [UIImage imageWithData:imageData];

完整的AVFrame转UIImage的代码

// type:0、获取识别到的人脸数组 1、获取转码的image
- (id)getFaceResultData:(const AVFrame *)frame type:(int)type {
    int width = frame->width;
    int height = frame->height;
    
    enum AVPixelFormat format = AV_PIX_FMT_RGB24;// (enum AVPixelFormat)srcFrame->format;
    AVFrame *picture = av_frame_alloc();
    picture->width = width;
    picture->height = height;
    int ret = av_image_alloc(
                   picture->data,
                   picture->linesize,
                   picture->width,
                   picture->height,
                   format, 1);
    SwsContext *sws_ctx = NULL;
    sws_ctx = sws_getContext(width, height, (enum AVPixelFormat)frame->format,
                             width, height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
    ret = sws_scale(sws_ctx,         // 转换格式上下文
                    frame->data,     // 输入图像每个颜色AV_PIX_FMT_YUV420通道数据的指针
                    frame->linesize, // 输入图像每个颜色通道的跨度
                    0,                  // 处理的开始位置(这里从图像开头处理)
                    frame->height,   // 处理的范围(这里处理的范围是整个图像)
                    picture->data,      // 输出图像数据位置
                    picture->linesize); // 输出图像每个颜色通道的跨度

    
   
    CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, picture->data[0], picture->linesize[0]*height,kCFAllocatorNull);
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CGDataProviderRef provider = CGDataProviderCreateWithCFData(data);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGImageRef cgImage = CGImageCreate(width,
                                       height,
                                       8,
                                       24,
                                       picture->linesize[0],
                                       colorSpace,
                                       bitmapInfo,
                                       provider,
                                       NULL,
                                       NO,
                                       kCGRenderingIntentDefault);
    
    CIImage *image = [CIImage imageWithCGImage:cgImage];
    
    id result = nil;
    if (type == 1) {
        result = [UIImage imageWithCGImage:cgImage];
        UIImage *uimage = (UIImage *)result;
        CGFloat zoomWidth = kScreenWidth/3 * 2;
        // 转一下,才能保证后续在使用的时候不报错,缩小尺寸,减少内存占用
        uimage = [uimage transformWidth:zoomWidth Height:zoomWidth*kPreviewImageScale];
        NSData *imageData = UIImageJPEGRepresentation(uimage, 0.5);
        result = [UIImage imageWithData:imageData];
    } else {
    // CIDetector 屏幕左下角是坐标原点,需要进行坐标系转换
#warning TODO 识别度不高,需要坐标系转换
        result = [self.detector featuresInImage:image];
    }
    
#warning TODO frame #0: 0x00000001ab5175fc CoreGraphics`ERROR_CGDataProvider_BufferIsNotReadable
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(cgImage);
    CGDataProviderRelease(provider);
    CFRelease(data);
     
    sws_freeContext(sws_ctx);
    if(picture){
        av_freep(&picture->data[0]);
        av_frame_free(&picture);
    }
    return result;
}

以上,就是我在处理AVFrame转UIImage时遇到的问题的一些解决思路,如有不妥或者更好的方式,欢迎留言探讨指正!

相关文章

网友评论

      本文标题:AVFrame转UIImage导致ERROR_CGDataPro

      本文链接:https://www.haomeiwen.com/subject/wnexfdtx.html