iOS 視頻采集編碼前后顯示匯總

1.AVCaptureVideoPreviewLayer->視頻預(yù)覽layer

#import <AVFoundation/AVFoundation.h>

// AVCaptureSession 初始化即可
    self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.avSession];
    [self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    [self.previewLayer setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    [self.view.layer insertSublayer:self.previewLayer above:0];

2.AVSampleBufferDisplayLayer ->視頻輸出對(duì)象CMSampleBufferRef顯示layer

// - (void)enqueueSampleBuffer:(CMSampleBufferRef)sampleBuffer;

- (void)addAVSampleBufferDisplayLayer {
    AVSampleBufferDisplayLayer * layer = [[AVSampleBufferDisplayLayer alloc] init];
    layer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    [layer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    self.sampleDisplayLayer = layer;
    [self.view.layer addSublayer:layer];
}

3. CMSampleBufferRef和CVPixelBufferRef相互轉(zhuǎn)換

CMSampleBufferRef-> CVPixelBufferRef

CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

CVPixelBufferRef-> CMSampleBufferRef

- (CMSampleBufferRef)getCMSampleBufferFromPixelBuffer:(CVPixelBufferRef)pixelBuffer
{
    if (!pixelBuffer){
        return NULL;
    }
    @synchronized(self) {
        if (_previousPixelBuffer) {
            CVPixelBufferRelease(_previousPixelBuffer);
        }
        _previousPixelBuffer = CVPixelBufferRetain(pixelBuffer);
    }
    
    //不設(shè)置具體時(shí)間信息
    CMSampleTimingInfo timing = {kCMTimeInvalid, kCMTimeInvalid, kCMTimeInvalid};
    //獲取視頻信息
    CMVideoFormatDescriptionRef videoInfo = NULL;
    OSStatus result = CMVideoFormatDescriptionCreateForImageBuffer(NULL, _previousPixelBuffer, &videoInfo);
    NSParameterAssert(result == 0 && videoInfo != NULL);
    
    CMSampleBufferRef sampleBuffer = NULL;
    result = CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault,_previousPixelBuffer, true, NULL, NULL, videoInfo, &timing, &sampleBuffer);
    NSParameterAssert(result == 0 && sampleBuffer != NULL);
    if (_previousPixelBuffer) {
        CFRelease(_previousPixelBuffer);
    }
    if (videoInfo) {
        CFRelease(videoInfo);
    }
    
    CFArrayRef attachments = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, YES);
    CFMutableDictionaryRef dict = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(attachments, 0);
    CFDictionarySetValue(dict, kCMSampleAttachmentKey_DisplayImmediately, kCFBooleanTrue);
    return CFAutorelease(sampleBuffer);
}

4. 編碼前輸入CMSampleBufferRef组贺, 編碼后輸出 CVPixelBufferRef

//AVCaptureVideoDataOutputSampleBufferDelegate,AVCaptureAudioDataOutputSampleBufferDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
}

// 解碼回調(diào)函數(shù)
static void didDecompress( void *decompressionOutputRefCon, void *sourceFrameRefCon, OSStatus status, VTDecodeInfoFlags infoFlags, CVImageBufferRef pixelBuffer, CMTime presentationTimeStamp, CMTime presentationDuration ){
    CVPixelBufferRef *outputPixelBuffer = (CVPixelBufferRef *)sourceFrameRefCon;
    *outputPixelBuffer = CVPixelBufferRetain(pixelBuffer);
    VideoH264Decoder *decoder = (__bridge VideoH264Decoder *)decompressionOutputRefCon;
    
    if ([decoder.delegate respondsToSelector:@selector(decoder:didDecodingFrame:)]) {
        [decoder.delegate decoder: decoder didDecodingFrame:pixelBuffer];
    }
}

5. CVOpenGLESTextureCacheCreateTextureFromImage生成紋理

CVOpenGLESTextureCacheCreateTextureFromImage ->CVImageBufferRef->Texture
CVOpenGLESTextureCacheCreateTextureFromImage -> CVPixelBufferRef->Texture
CVOpenGLESTextureCacheCreateTextureFromImage -> CMSampleBufferRef-> CVPixelBufferRef ->Texture

CVImageBufferRef==CVPixelBufferRef等價(jià)
CVPixelBufferRef-> Texture-> OpenGL ES 或 Metal渲染
CMSampleBufferRef->Texture-> OpenGL ES 或 Metal渲染

CIImage * ciImage = [CIImage imageWithCVImageBuffer:pixelBuffer];
CIContext * context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:ciImage fromRect:CGRectMake(0, 0, 100, 100)];
UIImage * uiImage = [[UIImage alloc] initWithCIImage:ciImage];
UIImage * uiImage2 = [[UIImage alloc] initWithCGImage:cgImage];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末凸舵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子失尖,更是在濱河造成了極大的恐慌啊奄,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掀潮,死亡現(xiàn)場(chǎng)離奇詭異菇夸,居然都是意外死亡状共,警方通過(guò)查閱死者的電腦和手機(jī)础废,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)房资,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)草巡,“玉大人征冷,你說(shuō)我怎么就攤上這事剑鞍∠杓剑” “怎么了摊阀?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵人断,是天一觀(guān)的道長(zhǎng)吭从。 經(jīng)常有香客問(wèn)我,道長(zhǎng)恶迈,這世上最難降的妖魔是什么涩金? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮暇仲,結(jié)果婚禮上步做,老公的妹妹穿的比我還像新娘。我一直安慰自己奈附,他們只是感情好全度,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著斥滤,像睡著了一般将鸵。 火紅的嫁衣襯著肌膚如雪勉盅。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,165評(píng)論 1 299
  • 那天顶掉,我揣著相機(jī)與錄音草娜,去河邊找鬼。 笑死痒筒,一個(gè)胖子當(dāng)著我的面吹牛宰闰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播簿透,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼移袍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了萎战?” 一聲冷哼從身側(cè)響起咐容,我...
    開(kāi)封第一講書(shū)人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蚂维,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體路狮,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡虫啥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奄妨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涂籽。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖砸抛,靈堂內(nèi)的尸體忽然破棺而出评雌,到底是詐尸還是另有隱情,我是刑警寧澤直焙,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布景东,位于F島的核電站,受9級(jí)特大地震影響奔誓,放射性物質(zhì)發(fā)生泄漏斤吐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一厨喂、第九天 我趴在偏房一處隱蔽的房頂上張望和措。 院中可真熱鬧,春花似錦蜕煌、人聲如沸派阱。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)贫母。三九已至故响,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間颁独,已是汗流浹背彩届。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留誓酒,地道東北人樟蠕。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像靠柑,于是被迫代替她去往敵國(guó)和親寨辩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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