VideoToolBox硬編碼(h264)
H264編碼分為兩層:
視頻編碼層(VCL:Video Coding Layer)負(fù)責(zé)高效的視頻內(nèi)容表示
網(wǎng)絡(luò)提取層(NAL:Network Abstraction Layer)負(fù)責(zé)以網(wǎng)絡(luò)所要求的恰當(dāng)?shù)姆绞綄?shù)據(jù)進(jìn)行打包和傳送(根據(jù)不同的網(wǎng)絡(luò)把數(shù)據(jù)打包成相應(yīng)的格式娶桦,將VCL產(chǎn)生的比特字符串適配到各種各樣的網(wǎng)絡(luò)和多元環(huán)境中)
NALU:NAL unit,NAL單元
I幀贾节、P幀、B幀都是被封裝成一個(gè)或者多個(gè)NALU進(jìn)行傳輸或者存儲(chǔ)的
I幀開始之前也有非VCL的NAL單元衷畦,用于保存其他信息憎乙,比如:PPS杆怕、SPS
PPS(Picture Parameter Sets):圖像參數(shù)集
SPS(Sequence Parameter Set):序列參數(shù)集
在實(shí)際的H264數(shù)據(jù)幀中,往往幀前面帶有00 00 00 01 或 00 00 01分隔符,一般來說編碼器編出的首幀數(shù)據(jù)為PPS與SPS奠蹬,接著為I幀叹誉,后續(xù)是B幀弱贼、P幀等數(shù)據(jù)戚炫。
GOP:Group of picture圖像組,一組中包含一個(gè)i幀多個(gè)bp幀墨吓,每個(gè)i幀都是 IDR 圖像(立即刷新圖像)球匕,當(dāng)解碼器解碼到 IDR 圖像時(shí),立即將參考幀隊(duì)列清空帖烘,將已解碼的數(shù)據(jù)全部輸出或拋棄亮曹,重新查找參數(shù)集,開始一個(gè)新的序列秘症。這樣照卦,如果前一個(gè)序列出現(xiàn)重大錯(cuò)誤,在這里可以獲得重新同步的機(jī)會(huì)乡摹。
H.264編碼流程:
1役耕、通過攝像頭采集畫面,通過- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 方法傳回sampleBuffer聪廉,sampleBuffer中存放了視頻畫面信息瞬痘。
2、初始化文件寫入對象(NSFileHandle)板熊,設(shè)置文件存儲(chǔ)路徑.
3框全、初始化壓縮會(huì)話(VTCompressionSessionRef),設(shè)置視頻的壓縮轉(zhuǎn)換格式(h.264)干签,幀率津辩、碼率,幀間隔等轉(zhuǎn)換信息(配置轉(zhuǎn)換器)。
4喘沿、將攝像頭采集到的畫面?zhèn)魅胝⒍龋凑説.264的壓縮算法進(jìn)行壓縮,轉(zhuǎn)換完成后會(huì)通過創(chuàng)建VTCompressionSessionRef是的方法中的回調(diào)方法 傳出壓縮轉(zhuǎn)換后的sampleBuffer蚜印。
5莺禁、獲取到轉(zhuǎn)換后的sampleBuffer,按照h.264的編碼格式進(jìn)行編碼寫入文件。
關(guān)鍵幀
1>判斷是否為關(guān)鍵幀(一個(gè)新的GOP),i幀前存放sps和pps(寫入sps和pps時(shí)要在前面添加‘00 00 00 01’分隔)晒哄。
2>圖像數(shù)據(jù)區(qū)域(i,b,p)是被封裝成一個(gè)個(gè)NAL Unit睁宰。但是前面通過h.264壓縮算法后傳回的sampleBuffer肪获,每一幀錢存放的不是‘00 00 00 01’寝凌,所以需要跳過讀取,需要在每一幀前添加‘00 00 00 01’孝赫,然后寫入文件较木。
VideoToolBox硬解碼(h264):
1、讀取數(shù)據(jù)到buffer中青柄,通過startCode“00 00 00 01”定位起始位置
伐债,繼續(xù)移動(dòng)指針查找到下一個(gè)startCode,來確定當(dāng)前數(shù)據(jù)集合的長度致开,并拷貝數(shù)據(jù)信息峰锁。
2、解析獲取的數(shù)據(jù)信息双戳,startCode之后的第一個(gè)字節(jié)保存的是NALU的類型信息虹蒋。將其轉(zhuǎn)為二進(jìn)制后:
第1位:值為1,表示語法出錯(cuò)飒货。
第2~3位:參考級(jí)別魄衅。
第4~8位:NALU類型。
NALU類型如下圖:
3塘辅、通過上一步解析出來的sps和pps的信息晃虫,創(chuàng)建視頻描述CMFormatDescriptionRef,再根據(jù)CMFormatDescriptionRef創(chuàng)建生成解碼會(huì)話VTDecompressionSessionRef扣墩。
4哲银、讀取到視頻數(shù)據(jù)信息后,進(jìn)行解碼呻惕。創(chuàng)建CMBlockBufferRef(存放視頻圖像數(shù)據(jù))荆责,使用解碼會(huì)話進(jìn)行解碼,獲取解碼后的信息存放到CVPixelBufferRef中蟆融,通過系統(tǒng)的AVSampleBufferDisplayLayer預(yù)覽草巡,或者生成圖像,通過imageView顯示,或者使用OpenGL顯示山憨。