国产91免费_国产精品电影一区_日本s色大片在线观看_中文在线免费看视频

您現(xiàn)在的位置: 通信界 >> 通信政策 >> 技術(shù)正文  
 
嵌入式Linux下基于FFmpeg的視頻硬件編解碼[圖]
[ 通信界 / 佚名 / www.6611o.com / 2012/3/25 10:56:39 ]
 

摘要: 對FFmpeg多媒體解決方案中的視頻編解碼流程進行研究。結(jié)合對S3C6410處理器視頻硬件編解碼方法的分析,闡述了嵌入式Linux下基于FFmpeg的H.264視頻硬件編解碼在S3C6410處理器上的實現(xiàn)方法,為嵌入式多媒體開發(fā)提供參考。

引言

目前,智能手機、PDA和平板電腦等越來越多的嵌入式設(shè)備支持高清視頻采集和播放功能,高清視頻的采集或播放功能正廣泛用于游戲設(shè)備、監(jiān)控設(shè)備、視頻會議設(shè)備和數(shù)字網(wǎng)絡(luò)電視等嵌入式系統(tǒng)中。這些功能的實現(xiàn)建立在高性能視頻硬件編解碼技術(shù)基礎(chǔ)之上。本文闡述了基于FFmpeg的H.264視頻硬件編解碼在S3C6410處理器上的實現(xiàn)方法,為數(shù)字娛樂、視頻監(jiān)控和視頻通信系統(tǒng)開發(fā)過程中的高清視頻硬件編解碼的實現(xiàn)提供參考。

FFmpeg[1]是一個開源免費跨平臺的視頻和音頻流方案,屬于自由軟件。它包含非常先進的音頻/視頻編解碼庫libavcodec,提供了錄制、轉(zhuǎn)換以及流化音視頻的完整解決方案。FFmpeg支持MPEG4、FLV等40多種編碼,以及AVI、ASF等90多種解碼。目前國內(nèi)較為流行的播放器暴風(fēng)影音和國外較為流行的Mplayer在音頻/視頻編解碼方面都用到了FFmpeg。

S3C6410[2]是三星公司推出的應(yīng)用處理器芯片,基于ARM11架構(gòu),主頻最高可達800 MHz。它具有多媒體硬件加速功能,其中包括大于30 fps的MPEG4 SP、H.264/263 BP和VC1(WMV9)多種視頻硬件編解碼,可用于手機、平板電腦和游戲機等手持移動設(shè)備和其他高性能嵌入式設(shè)備。國產(chǎn)手機魅族M8的處理器使用的就是S3C6410。

雖然FFmpeg提供了簡單的應(yīng)用程序編程接口(API),可以很方便地實現(xiàn)多種格式的視頻軟件編解碼[3],但是軟件編解碼在處理復(fù)雜視頻編解碼(如H.264)時無法運用到處理速度不快、內(nèi)存空間不多的嵌入式環(huán)境中。為了在資源有限的嵌入式環(huán)境下使用FFmpeg實現(xiàn)復(fù)雜視頻編解碼,下面在分析FFmpeg視頻編碼流程和S3C6410處理器視頻編解碼方法的基礎(chǔ)上,闡述嵌入式Linux操作系統(tǒng)下基于FFmpeg的H.264硬件編解碼在S3C6410處理器上的實現(xiàn)方法。

1 FFmpeg視頻編解碼流程

FFmpeg主要有encode/decode、muxer/demuxer和內(nèi)存操作3個模塊。encode/decode模塊用于音視頻的編碼和解碼,存放在libavcodec子目錄中;muxer/demuxer模塊用于音頻和視頻的合并與分離(也稱混合器模塊),存放在libavformat目錄中;內(nèi)存等常用模塊存放于libavutil目錄中。下面以解碼過程為例分析FFmpeg視頻編解碼流程。

解碼基本流程共分4步:

① 注冊所有可能用到的編解碼器和混合器。av_register_all(void)函數(shù)中通過執(zhí)行 REGISTER_MUXDEMUX(X,x)和REGISTER_ENCDEC(X,x),把所有FFmpeg支持的混合器和編解碼器相關(guān)信息以鏈?zhǔn)降慕Y(jié)構(gòu)存放在內(nèi)存中。

② 打開視頻文件。av_open_input_file(AVFormatContext **ic_ptr,const char *filename,AVInputFormat *fmt,int buf_size,AVFormatParameters *ap)函數(shù)中偵測文件的格式,根據(jù)文件格式從鏈?zhǔn)降幕旌掀髦姓业较鄬?yīng)的混合器(demuxer)并分離出視頻信息

③ 獲取視頻信息。通過av_find_stream_info(AVFormatContext *ic)函數(shù)獲取視頻格式。根據(jù)視頻格式,在鏈?zhǔn)降囊曨l解碼器中找到相應(yīng)的視頻解碼器,并通過avcodec_open(AVCodecContext *avctx,AVCodec *codec)函數(shù)將解碼器打開用于下一步視頻的解碼。

④ 解碼一幀視頻,通過 avcodec_decode_video(AVCodecContext *avctx,AVFrame *picture,int *got_picture_ptr,const uint8_t *buf,int buf_size)函數(shù)解碼一幀視頻。

FFmpeg的編碼過程與解碼過程類似,不同的是第3步根據(jù)要求編碼的格式在鏈?zhǔn)降囊曨l編碼器中找到相應(yīng)的視頻編碼器,并執(zhí)行編碼過程。

通過以上對FFmpeg視頻編解碼流程分析可以知道,為了在FFmpeg中添加自定義的視頻編解碼器,并在程序運行時使用這個編解碼器,關(guān)鍵在于如下兩點:

① 根據(jù)FFmpeg對編解碼器的描述,實現(xiàn)自定義編解碼器。

② 通過REGISTER_ENCDEC(X,x)函數(shù)將自定義的視頻編解碼器添加到視頻編解碼器鏈中。在獲取視頻信息時,保證需要編碼或解碼的視頻能找到視頻編解碼器鏈中自定義的視頻編解碼器。

2 S3C6410處理器視頻編解碼方法

S3C6410視頻編解碼軟件架構(gòu)[4]如圖1所示。底層為操作系統(tǒng)空間,上層為用戶空間,視頻編解碼器通過驅(qū)動和操作系統(tǒng)以設(shè)備文件的形式使用,使用的方法和普通文件一樣,包括文件打開和關(guān)閉、文件讀寫和輸入/輸出控制(ioctl,input/output control)。

圖1 S3C6410視頻編解碼軟件架構(gòu)

具體操作方法如下:

① 通過open函數(shù)打開編解碼器設(shè)備文件;

② 使用mmap方法在用戶空間和驅(qū)動空間之間映射輸入/輸出緩存空間,這樣做的好處是可以快速進行數(shù)據(jù)輸入/輸出;

③ 通過ioctl設(shè)備編解碼參數(shù),初始化編解碼器;

④ 輸入數(shù)據(jù),通過ioctl執(zhí)行編解碼過程,輸出數(shù)據(jù);

⑤ 通過close方法關(guān)閉編解碼器設(shè)備文件。

值得注意的是,無論編碼還是解碼,處理的數(shù)據(jù)都是以一幀幀的形式操作的,所以第4步是一個不斷循環(huán)的過程,直到所有數(shù)據(jù)處理完成。另外,雖然編解碼器以設(shè)備文件的形式使用,但是它不能使用標(biāo)準(zhǔn)的文件讀寫操作,查看編解碼的設(shè)備驅(qū)動可以發(fā)現(xiàn),其文件讀寫函數(shù)是空的,這一點三星公司的開發(fā)文檔并沒有說明。

3 H.264硬件編解碼實現(xiàn)

FFmpeg的H.264硬件編解碼[5]實現(xiàn)就是自定義一個視頻編解碼器,加入到FFmpeg庫中。這個視頻編解碼器使用S3C6410處理視頻硬件編解碼功能來實現(xiàn)H.264的視頻編碼和解碼過程,這樣使用FFmpeg庫的多媒體程序可以用訪問FFmpeg其他編解碼器一樣的方法使用這個自定義的編解碼器。添加自定義編解碼器的關(guān)鍵是根據(jù)FFmpeg中對編解碼的描述定義編解碼器,并實現(xiàn)定義中的相關(guān)函數(shù)。

在libavcodec/avcodec.h中的AVCodec結(jié)構(gòu)體是定義FFmpeg編解碼器的關(guān)鍵結(jié)構(gòu)體,包括編解碼器的名字、類型(聲音/視頻)、編解碼器的識別號(CodecID)、支持格式和一些用于初始化、編碼、解碼和關(guān)閉的函數(shù)指針。

typedef struct AVCodec {

const char *name;

enum CodecType type;

enum CodecID id;

int priv_data_size;

int (*init)(AVCodecContext *);

int (*encode)(AVCodecContext *,uint8_t *buf,int buf_size,void *data);

int (*close)(AVCodecContext *);

int (*decode)(AVCodecContext *,void *outdata,int *outdata_size,

uint8_t *buf,int buf_size);

int capabilities;

struct AVCodec *next;

void (*flush)(AVCodecContext *);

const AVRational *supported_framerates;

const enum PixelFormat *pix_fmts;

} AVCodec;

H.264硬件編解碼器定義如下:

AVCodec s3cx264_encoder = {

.name="s3cx264",

.type=AVMEDIA_TYPE_VIDEO,

.id=CODEC_ID_H264,

.init=X264_init,

.encode=X264_frame,

.decode=X264_decode,

.close=X264_close,

};

解碼器的名字為s3cx264,類型為視頻。CodecID為H264,表示這個解碼器用于H.264視頻編解碼。初始化、編碼、解碼和關(guān)閉函數(shù)指針分別指向X264_init、X264_frame、X264_decodec和X264_close函數(shù)。

添加s3cx264編解碼器到編解器鏈中,關(guān)鍵是通過修改libavcodec/allcodecs.c文件實現(xiàn),修改如下:

REGISTER_ENCDEC (ASV1,asv1);

REGISTER_ENCDEC (S3CX264,s3cx264);

//添加s3cx264編解碼器

REGISTER_ENCDEC (ASV2,asv2);

這樣,在程序運行時調(diào)用av_register_all(void)函數(shù)后,就可以把自定義的編解碼器s3cx264添加到FFmpeg存放在內(nèi)存中的解編碼器鏈中。值得提出的是,對同一個視頻格式FFmpeg有多個編解碼器與之相對應(yīng)。如H.264格式的視頻,F(xiàn)Fmpeg本身就帶有對應(yīng)的軟解碼器,現(xiàn)在添加了硬解碼器,為了避免不確定是哪一個解碼器在執(zhí)行,可以把自定義的硬件編解碼器在注冊時放在注冊過程的最前面,這樣編解碼器在添加到解編器鏈中時就會放在靠前的位置,查找時就可以優(yōu)于軟件解碼器找到硬解碼器。

把硬件編解碼器s3cx264注冊到編解碼器鏈后,還要完成X264_init、X264_frame、X264_decodec和X264_close函數(shù),編解碼器才能正常工作。以下結(jié)合前面對S3C6410視頻編解碼過程的分析,以編碼為例詳細闡述實現(xiàn)過程。

定義X264Context結(jié)構(gòu)體,保存設(shè)備文件描述符、編碼參數(shù)和輸入/輸出地址等信息,用于FFmpeg模塊間數(shù)據(jù)的傳遞:

typedef struct X264Context {

int dev_fd;

uint8_t *addr;

s3c_mfc_enc_init_arg_t enc_init;

s3c_mfc_enc_exe_arg_t enc_exe;

s3c_mfc_get_buf_addr_arg_t get_buf_addr;

uint8_t *in_buf,*out_buf;

AVFrame out_pic;

} X264Context;

X264_init實現(xiàn)的是編碼器初始化過程, 用于編碼器設(shè)備文件的打開、內(nèi)存空間的映射、編碼參數(shù)設(shè)置和獲取編解碼數(shù)據(jù)輸入/輸出地址。

static av_cold int X264_init(AVCodecContext *avctx){

X264Context *x4 = avctx>priv_data;

//打開編碼器設(shè)備文件

x4>dev_fd = open(MFC_DEV_NAME,O_RDWR|O_NDELAY);

//內(nèi)存空間映射

x4>addr = (uint8_t *) mmap(0,BUF_SIZE,PROT_READ |PROT_WRITE,MAP_SHARED,x4>dev_fd,0);

//編碼參數(shù)設(shè)置

ioctl(x4>dev_fd,S3C_MFC_IOCTL_MFC_H264_ENC_INIT,&x4>enc_init);

//獲取輸入/輸出地址

x4>get_buf_addr.in_usr_data = (int)x4>addr;

ioctl(x4>dev_fd,S3C_MFC_IOCTL_MFC_GET_YUV_BUF_ADDR,&x4>get_buf_addr);

x4>in_buf = (uint8_t *)x4>get_buf_addr.out_buf_addr;

x4>get_buf_addr.in_usr_data = (int)x4>addr;

ioctl(x4>dev_fd,S3C_MFC_IOCTL_MFC_GET_LINE_BUF_ADDR,&x4>get_buf_addr);

x4>out_buf = (uint8_t *)x4>get_buf_addr.out_buf_addr;

return 0;

}

ioctl的參數(shù)為S3C_MFC_IOCTL_MFC_H264_ENC_INIT,表示使用H.264編碼。

X264_frame函數(shù)執(zhí)行編碼過程。需要注意的是data參數(shù)保存了需要編碼的數(shù)據(jù),是一個四維的數(shù)組,要把它轉(zhuǎn)換成一維數(shù)組用于S3C6410編碼器輸入。另外,編碼數(shù)據(jù)存在空的情況,也就是空幀。這是需要處理的,方法是返回“0”,表示沒有輸出數(shù)據(jù),否則程序運行時會出現(xiàn)段錯誤。

static int X264_frame(AVCodecContext *ctx,uint8_t *buf,int bufsize,void *data){

……

//空間轉(zhuǎn)換

if(frame){

memcpy(x4>in_buf,frame>data[0],ctx>width*ctx>height);

memcpy(x4>in_buf+ctx>width*ctx>height,frame>data[1],ctx>width*ctx>height/4);

memcpy(x4>in_buf+ctx>width*ctx>height+ctx>width*ctx>height/4,frame>data[2],

ctx>width*ctx>height/4);

}

else

return 0;//空幀,返回

//執(zhí)行編碼過程

ioctl(x4>dev_fd,S3C_MFC_IOCTL_MFC_H264_ENC_EXE,&x4>enc_exe);

//編碼數(shù)據(jù)輸出

bufsize = x4>enc_exe.out_encoded_size;

memcpy(buf,x4>out_buf,bufsize);

……

return bufsize;

}

X264_close關(guān)閉函數(shù)用于編碼結(jié)束后的資源釋放,包括取消空間映射和關(guān)閉設(shè)備文件。

static av_cold int X264_close(AVCodecContext *avctx){

//取消空間映射

munmap(x4>addr,BUF_SIZE);

//關(guān)閉設(shè)備文件

close(x4>dev_fd);

return 0;

}

解碼函數(shù)的實現(xiàn)過程類似于編碼函數(shù),包括空間轉(zhuǎn)換、執(zhí)行解碼和解碼數(shù)據(jù)輸出。初始化時使用S3C_MFC_IOCTL_MFC_H264_DEC_INIT參數(shù),執(zhí)行時使用S3C_MFC_IOCTL_MFC_H264_ENC_EXE參數(shù)。

4 運行測試

s3cx264編解碼器添加到FFmpeg后,可以通過以下方式測試:

① 用如下命令編譯FFmpeg。

./configure enablecrosscompile

arch=armv6 cpu=armv6

targetos=linux crossprefix

=/usr/local/arm/4.3.2/bin/

armlinux

② 運行 ./ffmpeg codecs查看可以找到s3cx264編解碼器,如圖2所示。

圖2 FFmpeg顯示s3cx264編解碼器信息

③ 結(jié)合USB攝像頭測試s3cx264編碼。運行 ./ffmpeg s 320x240 r 50 f video4linux2 i /dev/video2 vcodec s3cx264 test.mp4 可以看到FFmpegg正使用s3cx264編碼器將USB攝像頭采集的數(shù)據(jù)編碼壓縮成test.mp4文件。test.mp4能夠正常播放顯示。

以上測試說明已經(jīng)成功地將s3cx264硬件視頻編碼器添加到了FFmpeg中,能夠編碼視頻數(shù)據(jù),可以運用到其他使用FFmpeg庫的多媒體程序中。

結(jié)語

對于多媒體開發(fā)來說,編解碼時使用FFmpeg多媒體庫是一個不錯的選擇,支持較多的音視頻編解碼,編程接口簡單易用。了解FFmpeg編解碼過程,熟悉FFmpeg硬件編解碼器添加方法,對多媒體開發(fā),尤其是資源有限的嵌入式多媒體開發(fā)有很大幫助。本文通過分析FFmpeg視頻編解碼過程和三星S3C6410處理器視頻硬件編解碼方法,在FFmpeg庫中成功添加S3C6410硬件編解碼器,使FFmpeg庫具有H.264視頻格式的硬件編解碼能力,可運用于游戲設(shè)備、監(jiān)控設(shè)備、視頻會議設(shè)備和數(shù)字網(wǎng)絡(luò)電視等嵌入式系統(tǒng)中,同時也為其他嵌入式設(shè)備添加別的視頻格式的編解碼器到FFmpeg多媒體庫提供了參考。

參考文獻

[1] http://www.ffmpeg.org/.

[2] Samsung.S3C6410 Datasheet,2010.

[3] 李少春.基于FFMPEG的嵌入式視頻監(jiān)控系統(tǒng)[J].電子技術(shù),2007(3):3437.

[4] API Document S3C6400/6410 MultiFormat Codec,2008.

[5] FFmpeg codec HOWTO[EB/OL].2010[201101].http://wiki.multimedia.cx/index.php?title=FFmpeg_codec_HOWTO/.

劉建敏(碩士生)、楊斌(教授),主要研究方向為單片機與嵌入式系統(tǒng)及應(yīng)用。

 

作者:佚名 合作媒體:不詳 編輯:顧北

 

 

 
 熱點技術(shù)
普通技術(shù) “5G”,真的來了!牛在哪里?
普通技術(shù) 5G,是偽命題嗎?
普通技術(shù) 云視頻會議關(guān)鍵技術(shù)淺析
普通技術(shù) 運營商語音能力開放集中管理方案分析
普通技術(shù) 5G網(wǎng)絡(luò)商用需要“無憂”心
普通技術(shù) 面向5G應(yīng)運而生的邊緣計算
普通技術(shù) 簡析5G時代四大關(guān)鍵趨勢
普通技術(shù) 國家網(wǎng)信辦就《數(shù)據(jù)安全管理辦法》公開征求意見
普通技術(shù) 《車聯(lián)網(wǎng)(智能網(wǎng)聯(lián)汽車)直連通信使用5905-5925MHz頻段管理規(guī)定(
普通技術(shù) 中興通訊混合云解決方案,滿足5G多元業(yè)務(wù)需求
普通技術(shù) 大規(guī)模MIMO將帶來更多無線信道,但也使無線信道易受攻擊
普通技術(shù) 蜂窩車聯(lián)網(wǎng)的標(biāo)準(zhǔn)及關(guān)鍵技術(shù)及網(wǎng)絡(luò)架構(gòu)的研究
普通技術(shù) 4G與5G融合組網(wǎng)及互操作技術(shù)研究
普通技術(shù) 5G中CU-DU架構(gòu)、設(shè)備實現(xiàn)及應(yīng)用探討
普通技術(shù) 無源光網(wǎng)絡(luò)承載5G前傳信號可行性的研究概述
普通技術(shù) 面向5G中傳和回傳網(wǎng)絡(luò)承載解決方案
普通技術(shù) 數(shù)據(jù)中心布線系統(tǒng)可靠性探討
普通技術(shù) 家庭互聯(lián)網(wǎng)終端價值研究
普通技術(shù) 鎏信科技CEO劉舟:從連接層構(gòu)建IoT云生態(tài),聚焦CMP是關(guān)鍵
普通技術(shù) SCEF引入需求分析及部署應(yīng)用
  版權(quán)與免責(zé)聲明: ① 凡本網(wǎng)注明“合作媒體:通信界”的所有作品,版權(quán)均屬于通信界,未經(jīng)本網(wǎng)授權(quán)不得轉(zhuǎn)載、摘編或利用其它方式使用。已經(jīng)本網(wǎng)授權(quán)使用作品的,應(yīng)在授權(quán)范圍內(nèi)使用,并注明“來源:通信界”。違反上述聲明者,本網(wǎng)將追究其相關(guān)法律責(zé)任。 ② 凡本網(wǎng)注明“合作媒體:XXX(非通信界)”的作品,均轉(zhuǎn)載自其它媒體,轉(zhuǎn)載目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點和對其真實性負責(zé)。 ③ 如因作品內(nèi)容、版權(quán)和其它問題需要同本網(wǎng)聯(lián)系的,請在一月內(nèi)進行。
通信視界
華為余承東:Mate30總體銷量將會超過兩千萬部
趙隨意:媒體融合需積極求變
普通對話 苗圩:建設(shè)新一代信息基礎(chǔ)設(shè)施 加快制造業(yè)數(shù)字
普通對話 華為余承東:Mate30總體銷量將會超過兩千萬部
普通對話 趙隨意:媒體融合需積極求變
普通對話 韋樂平:5G給光纖、光模塊、WDM光器件帶來新機
普通對話 安筱鵬:工業(yè)互聯(lián)網(wǎng)——通向知識分工2.0之路
普通對話 庫克:蘋果不是壟斷者
普通對話 華為何剛:挑戰(zhàn)越大,成就越大
普通對話 華為董事長梁華:盡管遇到外部壓力,5G在商業(yè)
普通對話 網(wǎng)易董事局主席丁磊:中國正在引領(lǐng)全球消費趨
普通對話 李彥宏:無人乘用車時代即將到來 智能交通前景
普通對話 中國聯(lián)通研究院院長張云勇:雙輪驅(qū)動下,工業(yè)
普通對話 “段子手”楊元慶:人工智能金句頻出,他能否
普通對話 高通任命克里斯蒂安諾·阿蒙為公司總裁
普通對話 保利威視謝曉昉:深耕視頻技術(shù) 助力在線教育
普通對話 九州云副總裁李開:幫助客戶構(gòu)建自己的云平臺
通信前瞻
楊元慶:中國制造高質(zhì)量發(fā)展的未來是智能制造
對話亞信科技CTO歐陽曄博士:甘為橋梁,攜"電
普通對話 楊元慶:中國制造高質(zhì)量發(fā)展的未來是智能制造
普通對話 對話亞信科技CTO歐陽曄博士:甘為橋梁,攜"電
普通對話 對話倪光南:“中國芯”突圍要發(fā)揮綜合優(yōu)勢
普通對話 黃宇紅:5G給運營商帶來新價值
普通對話 雷軍:小米所有OLED屏幕手機均已支持息屏顯示
普通對話 馬云:我挑戰(zhàn)失敗心服口服,他們才是雙11背后
普通對話 2018年大數(shù)據(jù)產(chǎn)業(yè)發(fā)展試點示范項目名單出爐 2
普通對話 陳志剛:提速又降費,中國移動的兩面精彩
普通對話 專訪華為終端何剛:第三代nova已成為爭奪全球
普通對話 中國普天陶雄強:物聯(lián)網(wǎng)等新經(jīng)濟是最大機遇
普通對話 人人車李健:今年發(fā)力金融 拓展汽車后市場
普通對話 華為萬飚:三代出貴族,PC產(chǎn)品已走在正確道路
普通對話 共享退潮單車入冬 智享單車卻走向盈利
普通對話 Achronix發(fā)布新品單元塊 推動eFPGA升級
普通對話 金柚網(wǎng)COO邱燕:天吳系統(tǒng)2.0真正形成了社保管