AVFrame轉(zhuǎn)UIImage導(dǎo)致ERROR_CGDataProvider_BufferIsNotReadable

在處理視頻的時(shí)候,有個(gè)畫中畫的需求抗果,需要展示視頻的一張靜態(tài)圖,作為占位;所以選擇把AVFrame轉(zhuǎn)成UIImage供后面需要調(diào)用的地方使用葵擎,當(dāng)然如果截屏的操作也可以這么做;但是后面在使用UIImage過程中會遇到一個(gè)問題码撰,如下所示谭期;



分析原因大概就是要訪問的這片內(nèi)存空間不可被讀取,結(jié)合之前使用UIImage做視頻渲染所遇到的問題:
即AVFrame->UIImage->render->release;
也是遇到同樣的問題兆旬,報(bào)錯(cuò)定位在Release假抄;
CGColorSpaceRelease(colorSpace);

現(xiàn)在的步驟是:
即AVFrame->UIImage->saveCache->release->waitRender;
所以分析原因還是圖片在使用之前時(shí)候已經(jīng)被釋放掉了,所以此時(shí)考慮對圖片做一次深拷貝丽猬,保證圖片顏色內(nèi)存空間跟數(shù)據(jù)緩存區(qū)不被釋放宿饱;

處理方法是,對圖片進(jìn)行縮放(因?yàn)檎嘉恍D不需要那么大的size)脚祟,再對圖片信息進(jìn)行壓縮谬以,最后再轉(zhuǎn)成image緩存起來;

result = [UIImage imageWithCGImage:cgImage];
        UIImage *uimage = (UIImage *)result;
        CGFloat zoomWidth = kScreenWidth/3 * 2;
        // 轉(zhuǎn)一下由桌,才能保證后續(xù)在使用的時(shí)候不報(bào)錯(cuò)为黎,縮小尺寸,減少內(nèi)存占用
        uimage = [uimage transformWidth:zoomWidth Height:zoomWidth*kPreviewImageScale];
        NSData *imageData = UIImageJPEGRepresentation(uimage, 0.5);
        result = [UIImage imageWithData:imageData];

完整的AVFrame轉(zhuǎn)UIImage的代碼

// type:0沥寥、獲取識別到的人臉數(shù)組 1碍舍、獲取轉(zhuǎn)碼的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,         // 轉(zhuǎn)換格式上下文
                    frame->data,     // 輸入圖像每個(gè)顏色AV_PIX_FMT_YUV420通道數(shù)據(jù)的指針
                    frame->linesize, // 輸入圖像每個(gè)顏色通道的跨度
                    0,                  // 處理的開始位置(這里從圖像開頭處理)
                    frame->height,   // 處理的范圍(這里處理的范圍是整個(gè)圖像)
                    picture->data,      // 輸出圖像數(shù)據(jù)位置
                    picture->linesize); // 輸出圖像每個(gè)顏色通道的跨度

    
   
    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;
        // 轉(zhuǎn)一下,才能保證后續(xù)在使用的時(shí)候不報(bào)錯(cuò)邑雅,縮小尺寸片橡,減少內(nèi)存占用
        uimage = [uimage transformWidth:zoomWidth Height:zoomWidth*kPreviewImageScale];
        NSData *imageData = UIImageJPEGRepresentation(uimage, 0.5);
        result = [UIImage imageWithData:imageData];
    } else {
    // CIDetector 屏幕左下角是坐標(biāo)原點(diǎn),需要進(jìn)行坐標(biāo)系轉(zhuǎn)換
#warning TODO 識別度不高淮野,需要坐標(biāo)系轉(zhuǎn)換
        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轉(zhuǎn)UIImage時(shí)遇到的問題的一些解決思路吹泡,如有不妥或者更好的方式,歡迎留言探討指正经瓷!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末爆哑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子舆吮,更是在濱河造成了極大的恐慌揭朝,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件色冀,死亡現(xiàn)場離奇詭異潭袱,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)锋恬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門屯换,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人与学,你說我怎么就攤上這事彤悔。” “怎么了索守?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵晕窑,是天一觀的道長。 經(jīng)常有香客問我蕾盯,道長幕屹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任级遭,我火速辦了婚禮望拖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘挫鸽。我一直安慰自己说敏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布丢郊。 她就那樣靜靜地躺著盔沫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪枫匾。 梳的紋絲不亂的頭發(fā)上架诞,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天,我揣著相機(jī)與錄音干茉,去河邊找鬼谴忧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的沾谓。 我是一名探鬼主播委造,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼均驶!你這毒婦竟也來了昏兆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤妇穴,失蹤者是張志新(化名)和其女友劉穎爬虱,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伟骨,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饮潦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年燃异,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了携狭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡回俐,死狀恐怖逛腿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情仅颇,我是刑警寧澤单默,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站忘瓦,受9級特大地震影響搁廓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜耕皮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一境蜕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧凌停,春花似錦粱年、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赐俗,卻和暖如春拉队,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背阻逮。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工粱快, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓皆尔,卻偏偏與公主長得像呐舔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子慷蠕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1.設(shè)計(jì)模式是什么流炕? 你知道哪些設(shè)計(jì)模式澎现,并簡要敘述?設(shè)計(jì)模式是一種編碼經(jīng)驗(yàn)每辟,就是用比較成熟的邏輯去處理某一種類型...
    龍飝閱讀 2,151評論 0 12
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 29,385評論 8 265
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,101評論 1 32
  • *面試心聲:其實(shí)這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,140評論 30 470
  • 設(shè)計(jì)模式是什么剑辫? 你知道哪些設(shè)計(jì)模式,并簡要敘述渠欺? 設(shè)計(jì)模式是一種編碼經(jīng)驗(yàn)妹蔽,就是用比較成熟的邏輯去處理某一種類型的...
    卑微的戲子閱讀 623評論 0 1