李芳芳,蘇凱雄
(福州大學(xué) 物理與信息工程學(xué)院,福建 福州 350108)
?
基于FFmpeg的H.264格式轉(zhuǎn)換器的設(shè)計(jì)與實(shí)現(xiàn)
李芳芳,蘇凱雄
(福州大學(xué) 物理與信息工程學(xué)院,福建 福州 350108)
針對(duì)視頻編碼壓縮傳輸需要,給出了一種基于FFmpeg的H.264格式轉(zhuǎn)換器的設(shè)計(jì)方法,實(shí)現(xiàn)了對(duì)H.264碼流數(shù)據(jù)的快速解碼、壓縮、再編碼的功能。該轉(zhuǎn)換器具有工作效率較高等特點(diǎn),適合于實(shí)時(shí)傳輸應(yīng)用。實(shí)驗(yàn)結(jié)果表明,轉(zhuǎn)換后的碼流經(jīng)過(guò)一系列處理之后,在客戶端接收到的視頻畫(huà)面穩(wěn)定無(wú)抖動(dòng)、播放流暢。
FFmpeg;格式轉(zhuǎn)換器;H.264;實(shí)時(shí)傳輸;移植;壓縮
隨著信息技術(shù)的迅速發(fā)展,網(wǎng)絡(luò)視頻監(jiān)控技術(shù)已經(jīng)廣泛地應(yīng)用于各個(gè)領(lǐng)域。目前視頻數(shù)據(jù)產(chǎn)生的數(shù)據(jù)量也是越來(lái)越大,如何在有限的資源下更好地利用這些數(shù)據(jù),成為了大家研究的重點(diǎn)[1]。視頻壓縮與視頻格式轉(zhuǎn)換是解決上述問(wèn)題的重要手段。H.264是近年來(lái)被廣泛應(yīng)用的視頻壓縮編碼標(biāo)準(zhǔn),具有壓縮率高、網(wǎng)絡(luò)適應(yīng)性強(qiáng)、抗干擾性能好等優(yōu)點(diǎn)。傳統(tǒng)的遠(yuǎn)程視頻監(jiān)控系統(tǒng)所需軟硬件資源大,系統(tǒng)傳輸帶寬要求高、時(shí)延長(zhǎng)、實(shí)時(shí)性不高[2],本文給出了一種適用于實(shí)時(shí)視頻監(jiān)控系統(tǒng)采集端軟件,在Windows系統(tǒng)上基于FFmpeg的H.264格式轉(zhuǎn)換器的解決方法,著重介紹了FFmpeg的移植與實(shí)時(shí)視頻編碼模塊的實(shí)現(xiàn)。
1.1H.264編碼標(biāo)準(zhǔn)
H.264是一種新的視頻編碼標(biāo)準(zhǔn),它在保留原有視頻編碼優(yōu)點(diǎn)的基礎(chǔ)上,提出了以往視頻編解碼無(wú)法比擬的一些優(yōu)點(diǎn),如低誤碼率、網(wǎng)絡(luò)適應(yīng)能力強(qiáng)、容錯(cuò)能力強(qiáng)等[3]。H.264分為視頻編解碼層(VCL)和網(wǎng)絡(luò)抽象層(NAL),VCL包含codec的信令處理功能如轉(zhuǎn)換、量化、運(yùn)動(dòng)補(bǔ)償預(yù)測(cè)機(jī)制以及循環(huán)過(guò)濾器,NAL封裝VCL編碼器輸出的片段到網(wǎng)絡(luò)抽象層單元(NAL Units),它適用于通過(guò)包網(wǎng)路傳輸或面向包的多路復(fù)用環(huán)境中,用于實(shí)際的傳輸[4]。NALU的頭結(jié)構(gòu)由一個(gè)字節(jié)組成,主要包含以下3種信息:
forbidden_zero_bit:1個(gè)比特,在H.264中這一位必須為0。
nal_ref_idc:2個(gè)比特,取值范圍是00~11,用來(lái)表示NAL的優(yōu)先級(jí)。取值越大表示該NAL越重要,需要優(yōu)先受到保護(hù)。如果NAL是屬于參考幀的片或序列參數(shù)集(SPS)、圖像參數(shù)集(PPS)這些重要的單位時(shí),nal_ref_idc的值必須為0。
nal_unit_type:5個(gè)比特,用來(lái)表示NALU單元的類(lèi)型。
1.2FFmpeg簡(jiǎn)介
FFmpeg是一套基于Linux操作系統(tǒng)的,集音視頻錄制、格式轉(zhuǎn)換與編解碼為一體的開(kāi)源解決方案,也可在大多數(shù)操作系統(tǒng)中編譯和使用[5]。它不僅包含了多種音視頻編解碼庫(kù),同時(shí)還支持基于流媒體的實(shí)時(shí)流的傳送。FFmpeg包含了幾個(gè)與視頻處理相關(guān)的結(jié)構(gòu)體,其中,AVFrame是數(shù)據(jù)流在視頻編解碼過(guò)程中用來(lái)保存數(shù)據(jù)緩存的結(jié)構(gòu)體,從數(shù)據(jù)流讀出的數(shù)據(jù)首先保存在AVPacket中。結(jié)構(gòu)體AVPacket中定義有包的大小、流索引(決定該流為視頻流還是音頻流)、顯示時(shí)間戳(Presentation Time Stamp,PTS)、解碼時(shí)間戳(Decoding Time Stamp,DTS)等與音視頻相關(guān)的屬性值[6]。
基于FFmpeg的H.264格式轉(zhuǎn)換器是視頻監(jiān)控系統(tǒng)中PC采集端軟件的一個(gè)功能模塊,需要將FFmpeg編譯成DLL(動(dòng)態(tài)鏈接庫(kù))文件供PC采集端編解碼和壓縮時(shí)使用。移植過(guò)程是在Windows XP、已安裝VS2008軟件的計(jì)算機(jī)上進(jìn)行的,編譯過(guò)程中采用的是ffmpeg-1.2.1,x264-snapshot-20141218-2245,mysy-1.0版本。移植流程主要分為以下幾個(gè)步驟:
1)MinGW編譯
將yasm.exe以及c99wrap.exe、c99conv.exe的路徑添加到計(jì)算機(jī)環(huán)境變量PATH中;修改MinGW解壓路徑下的fstab文件。如果不存在fstab文件,則復(fù)制一份fstab.sample到當(dāng)前目錄,然后改名為fstab,再修改其內(nèi)容為相對(duì)應(yīng)的解壓路徑與安裝路徑;修改MinGWmsys1.0路徑下的msys.bat文件,在文件開(kāi)頭加入VS2008的安裝路徑。
2)x264編譯
由于FFmpge不支持H.264格式編碼,因此要用FFmpeg庫(kù)的函數(shù)和數(shù)據(jù)結(jié)構(gòu)進(jìn)行H.264格式編解碼,需要結(jié)合x(chóng)264庫(kù)使用[7]。首先下載last_x264.tar.bz2,運(yùn)行msys.bat,并切換到x264所在目錄,運(yùn)行以下命令:
./configure --enable-shared --enable-static --disable-asm --prefix=/mingw/x264_build
/mingw/x264_build是最后生成文件的保存目錄,需要事先創(chuàng)建x264_build文件夾??稍趚264目錄中的config.log查看運(yùn)行日志。接著運(yùn)行make和make install,完成后會(huì)在x264_build的lib文件夾中生成庫(kù)文件。
3)FFmpeg編譯
下載ffmpeg-1.2.1.tar.bz2并且解壓縮,運(yùn)行msys.bat,切換到ffmpeg目錄下,運(yùn)行相應(yīng)的./configure命令。/mingw/ffmpeg_build是生成文件的保存目錄,需要事先定義;/mingw/x264_build/include和/mingw/x264_build/lib是編譯x264生成的頭文件和庫(kù)文件路徑。configure成功后,運(yùn)行make和make install,完成后在ffmpeg_build文件夾中生成所需文件。
視頻格式轉(zhuǎn)換器主要實(shí)現(xiàn)的功能是將前端攝像頭實(shí)時(shí)采集的H.264格式的視頻流解碼成YUV格式的數(shù)據(jù),然后對(duì)YUV數(shù)據(jù)進(jìn)行再壓縮編碼形成新的視頻數(shù)據(jù)流,最后將碼流數(shù)據(jù)發(fā)送給實(shí)時(shí)視頻監(jiān)控系統(tǒng)的客戶端。該過(guò)程主要調(diào)用上一節(jié)封裝好的FFmpeg的動(dòng)態(tài)鏈接庫(kù)的接口,完成對(duì)輸入視頻的解碼、壓縮與再編碼的功能。如圖1所示,前端攝像頭輸出的H.264視頻數(shù)據(jù)傳送給采集端,采集端的格式轉(zhuǎn)換器通過(guò)調(diào)用On_RecvRalu()回調(diào)函數(shù)獲得H.264數(shù)據(jù)格式的原始碼流,再實(shí)例化一個(gè)FfmpegVideoDec類(lèi)的對(duì)象,該類(lèi)的主要功能是對(duì)H.264格式碼流數(shù)據(jù)解碼成YUV數(shù)據(jù)格式,然后將解碼得到的YUV數(shù)據(jù)傳入VideoEncCallback()函數(shù)中,通過(guò)實(shí)例化FfmpegVideoResize類(lèi),調(diào)用該方法對(duì)YUV數(shù)據(jù)進(jìn)行壓縮,最后對(duì)FfmpegVid-eoEnc類(lèi)進(jìn)行實(shí)例化并對(duì)壓縮后的YUV數(shù)據(jù)再一次編碼成H.264格式數(shù)據(jù)的碼流。
圖1 格式轉(zhuǎn)換器的設(shè)計(jì)與實(shí)現(xiàn)流程
3.1解碼模塊
解碼模塊主要功能是將H.264格式的視頻數(shù)據(jù)解碼成YUV格式的數(shù)據(jù),相比RGB色彩空間要求3個(gè)獨(dú)立的視頻信號(hào)同時(shí)傳輸,YUV占用的傳輸帶寬更少,并且易于實(shí)現(xiàn)與壓縮,方便傳輸與處理,所以更加適合于在實(shí)時(shí)視頻監(jiān)控系統(tǒng)中使用。
解碼模塊的實(shí)現(xiàn)如圖2所示,首先通過(guò)調(diào)用Ffmpeg庫(kù)中的avcodec_register_all()對(duì)編解碼器進(jìn)行注冊(cè),再向avcodec_find_decoder() 函數(shù)中傳入相應(yīng)的參數(shù)信息AVCodecID選擇H.264解碼器。通過(guò)avcodec_alloc_context3()函數(shù)分配一個(gè)AVCodecContext上下文環(huán)境,并調(diào)用avcodec_open2()對(duì)其進(jìn)行初始化。AVCodecContext是描述編解碼器上下文的數(shù)據(jù)結(jié)構(gòu),它可以向編解碼器提供許多需要的參數(shù)信息,是一個(gè)十分重要的數(shù)據(jù)結(jié)構(gòu)類(lèi)型。通過(guò)調(diào)用avcodec_alloc_frame()為AVFrame類(lèi)型的數(shù)據(jù)結(jié)構(gòu)pFrame分配空間以便用于存儲(chǔ)解碼后的數(shù)據(jù)。在進(jìn)行解碼前需要判斷數(shù)據(jù)是否為一幀的開(kāi)頭,H.264的一幀數(shù)據(jù)是通過(guò)觀察二進(jìn)制碼流分析出來(lái)的,它是由一個(gè)AU(Access Unit)構(gòu)成,一個(gè)AU是由多個(gè)連續(xù)的NALU組成。每一幀圖像一般在開(kāi)頭有一個(gè)單元分隔符,兩個(gè)單元分隔符之間的數(shù)據(jù)包就是一幀圖像。如果NALU對(duì)應(yīng)為一幀的開(kāi)始,則用4個(gè)字節(jié)表示,即0x00000001。在H.264規(guī)定有一種類(lèi)型為09的NALU,即編碼器在完成一個(gè)AU編碼后,會(huì)在碼流中插入一個(gè)類(lèi)型為09的NALU。如果使用了該標(biāo)識(shí)符,幀將由0x0000000109作為結(jié)尾。所以解碼器只需要從碼流中搜索類(lèi)型為09的NALU即可判斷一個(gè)AU。判斷數(shù)據(jù)為一幀的開(kāi)始后再調(diào)用av_init_packet()對(duì)AVPacket類(lèi)型的數(shù)據(jù)進(jìn)行初始化。然后通過(guò)調(diào)用avcodec_decode_video2()函數(shù)解碼一幀數(shù)據(jù),輸入AVPacket類(lèi)型的數(shù)據(jù),輸出后的數(shù)據(jù)存入AVFrame類(lèi)型的結(jié)構(gòu)體,函數(shù)的返回值即解碼所使用的碼流字節(jié)數(shù)。最后再判斷got_pic的值是否為1,其中g(shù)ot_pic是avcodec_decode_video2()的第三個(gè)參數(shù)int*got_picture_ptr數(shù)據(jù)類(lèi)型的變量,該變量指示是否有解碼數(shù)據(jù)輸出。當(dāng)got_pic為1時(shí)拷貝保存解碼出來(lái)的數(shù)據(jù)完成解碼功能。
圖2 解碼模塊實(shí)現(xiàn)流程
3.2壓縮及編碼模塊
在壓縮編碼過(guò)程中,主要是將YUV數(shù)據(jù)進(jìn)行壓縮,再將壓縮后的數(shù)據(jù)編碼成H.264格式的視頻數(shù)據(jù)。壓縮及編碼模塊的實(shí)現(xiàn)流程如圖3所示,首先調(diào)用sws_getContext()函數(shù)返回上下文句柄,并設(shè)置原始圖像的寬和高以及輸出圖像的寬和高,然后通過(guò)執(zhí)行函數(shù)sws_scale()函數(shù)對(duì)原始YUV視頻數(shù)據(jù)進(jìn)行壓縮,初始圖像的分辨率為1 280×720,設(shè)定輸出的圖像分辨率為352×288。使用avcodec_find_encoder()函數(shù)選擇設(shè)定的ID相應(yīng)的編碼器。在初始化上下文環(huán)境并對(duì)其設(shè)置默認(rèn)值以后,初始化一個(gè)數(shù)據(jù)類(lèi)型AVFrame的變量并設(shè)置參數(shù),然后調(diào)用av_init_packet()函數(shù)對(duì)AVPakcet類(lèi)型的變量進(jìn)行初始化,用于編碼存儲(chǔ)數(shù)據(jù)使用。然后通過(guò)調(diào)用ret=avcodec_encode_video2()編碼一幀視頻數(shù)據(jù),最后判斷ret的值,如果大于或者等于0即將指針指向下一幀數(shù)據(jù)等待編碼。
圖3 壓縮及編碼模塊實(shí)現(xiàn)流程
測(cè)試環(huán)境是在一臺(tái)內(nèi)存為2 Gbyte并在裝有XP系統(tǒng)的PC上,前端攝像頭型號(hào)為??低旸S-2CD3210D-13,運(yùn)行環(huán)境是VS2008。經(jīng)測(cè)試,解碼器解碼一次最長(zhǎng)時(shí)間約16 ms,編碼器編碼速率為10 f/s(幀/秒),碼率為120 kbit/s,原始分辨率是1 280×720,壓縮后分辨率為352×288,即cif編碼分辨率。原始攝像頭采集的視頻圖像與經(jīng)過(guò)格式轉(zhuǎn)換器處理后接收的圖像如圖4和圖5所示,原始圖像較為清晰,傳輸后的圖像相比圖4較為模糊,具體可見(jiàn)兩圖中的“Camera 01”字樣和小電視邊緣等細(xì)節(jié)部分。實(shí)現(xiàn)的格式轉(zhuǎn)換器在視頻監(jiān)控系統(tǒng)中正常使用,效果良好。
圖4 前端攝像頭采集的原始視頻圖像
圖5 經(jīng)壓縮編碼傳輸后的視頻圖像
本文論述了基于FFmpeg開(kāi)源視頻解決方案在Windows平臺(tái)上的H.264格式轉(zhuǎn)換器的設(shè)計(jì)與實(shí)現(xiàn)。為了提高編解碼效率,將FFmpeg移植到Windows平臺(tái)上,便于格式轉(zhuǎn)換器的開(kāi)發(fā)與使用。文中主要實(shí)現(xiàn)了將前端攝像頭采集的H.264格式視頻數(shù)據(jù)進(jìn)行解碼、壓縮并再編碼,最后傳送到客戶端。本文實(shí)現(xiàn)的H.264格式轉(zhuǎn)換器可以很好地適用于實(shí)時(shí)傳輸系統(tǒng)當(dāng)中,并且經(jīng)轉(zhuǎn)換器處理后的畫(huà)面較為清晰,編解碼速率快,在Windows平臺(tái)上移植的FFmpeg動(dòng)態(tài)鏈接庫(kù)使用方便,大大提高開(kāi)發(fā)效率。
[1]李薔.H.264視頻編碼碼率控制技術(shù)研究[D].上海:上海交通大學(xué),2005.
[2]肖遠(yuǎn)東,蔡聲鎮(zhèn).基于iOS平臺(tái)的移動(dòng)視頻監(jiān)控軟件設(shè)計(jì)[J].計(jì)算機(jī)工程,2015,41(2):268-271.
[3]SRINIVASAN K S.The effects of priority levels and buffering on the statistical multiplexing of singe-layer H.264/AVC and SVC en-coded video stream[J].IEEE transactions on broadcasting,2011,56(3):281-286.
[4]陳陽(yáng).基于ffmpeg內(nèi)核的H.264實(shí)時(shí)視頻解碼器開(kāi)發(fā)[J].四川兵工學(xué)報(bào),2014,35(9):103-104.
[5]胡聰,周甜,唐璐丹.基于FFMPEG的跨平臺(tái)視頻編解碼研究[J].武漢理工大學(xué)學(xué)報(bào),2011,33(11):139-142.
[6]梁發(fā)云,陳志文,王婧,等.基于FFmpeg的立體視頻播放技術(shù)研究[J].電視技術(shù),2013,37(11):27-29.
[7]韋崇嶺,裴海龍.基于無(wú)人機(jī)H264視頻傳輸系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)測(cè)量與控制,2012,20(1):209-211.
責(zé)任編輯:閆雯雯
Design and implementation of H.264 format converter based on FFmpeg
LI Fangfang,SU Kaixiong
(CollegeofPhysicsandInformationEngineering,FuzhouUniversity,Fuzhou350108,China)
For the need of video coding compression and transmission,the method of H.264 format converter based on FFmpeg to achieve the fast decoding,compression,re-encoding functions to the H.264 data stream is given.The converter has high efficiency and other charecteristics which is suitable for the real time transmission applications.The result shows that the converted data stream after a series of processes,the video images which is client received are stable and playback smoothly.
FFmpeg; format converter;H.264; real-time transmission;transplant;compression
TN919.8
ADOI:10.16280/j.videoe.2016.07.008
福建省產(chǎn)學(xué)重大項(xiàng)目(2015H6014)
2015-10-21
文獻(xiàn)引用格式:李芳芳,蘇凱雄. 基于FFmpeg的H.264格式轉(zhuǎn)換器的設(shè)計(jì)與實(shí)現(xiàn)[J].電視技術(shù),2016,40(7):32-35.
LI F F,SU K X. Design and implementation of H.264 format converter based on FFmpeg [J].Video engineering,2016,40(7):32-35.