真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

ios開(kāi)發(fā)ffmpeg,IOS開(kāi)發(fā)工程師最新招聘

MAC/iOS利用FFmpeg解析音視頻數(shù)據(jù)流

利用FFmpeg解析音視頻流,音視頻流可以來(lái)自一個(gè)標(biāo)準(zhǔn)的RTMP的URL或者是一個(gè)文件. 通過(guò)解析得到音視頻流,進(jìn)一步就可以解碼, 然后視頻渲染在屏幕上,音頻通過(guò)揚(yáng)聲器輸出.

在西峽等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作定制網(wǎng)站建設(shè),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,成都全網(wǎng)營(yíng)銷,成都外貿(mào)網(wǎng)站制作,西峽網(wǎng)站建設(shè)費(fèi)用合理。

利用FFmpeg框架中l(wèi)ibavformat模塊可以通過(guò)函數(shù) av_read_frame 解析出音視頻流的音視頻數(shù)據(jù),如果直接使用FFmpeg硬解,僅需要解析到AVPacket即可傳給解碼模塊使用,如果使用VideoToolbox中的硬解, 對(duì)于視頻數(shù)據(jù),還需要獲取其NALU Header中的(vps)sps, pps以便后續(xù)使用.

使用流程

FFmpeg parse流程

下面的鏈接中包含搭建iOS需要的FFmpeg環(huán)境的詳細(xì)步驟,需要的可以提前閱讀.

iOS手動(dòng)編譯并搭建FFmpeg

導(dǎo)入FFmpeg框架后,首先需要將用到FFmpeg的文件改名為.mm, 因?yàn)樯婕癈,C++混編,所以需要更改文件名

然后在頭文件中導(dǎo)入FFmpeg頭文件.

注意: FFmpeg是一個(gè)廣為流傳的框架,其結(jié)構(gòu)復(fù)雜,一般導(dǎo)入都按照如上格式,以文件夾名為根目錄進(jìn)行導(dǎo)入,具體設(shè)置,請(qǐng)參考上文鏈接.

2.1. 注冊(cè)FFmpeg

一般在程序中的main函數(shù)或是主程序啟動(dòng)的代理方法 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 中初始化FFmpeg,執(zhí)行一次即可.

2.2. 利用視頻文件生成格式上下文對(duì)象

C++音視頻開(kāi)發(fā)學(xué)習(xí)資料 :點(diǎn)擊領(lǐng)取 音視頻開(kāi)發(fā)(資料文檔+視頻教程+面試題)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)

2.3. 獲取Audio / Video流的索引值.

通過(guò)遍歷format context對(duì)象可以從 nb_streams 數(shù)組中找到音頻或視頻流索引,以便后續(xù)使用

2.4. 是否支持音視頻流

目前視頻僅支持H264, H265編碼的格式.實(shí)際過(guò)程中,解碼得到視頻的旋轉(zhuǎn)角度可能是不同的,以及不同機(jī)型可以支持的解碼文件格式也是不同的,所以可以用這個(gè)方法手動(dòng)過(guò)濾一些不支持的情況.具體請(qǐng)下載代碼觀看,這里僅列出實(shí)戰(zhàn)中測(cè)試出支持的列表.

音頻本例中僅支持AAC格式.其他格式可根據(jù)需求自行更改.

使用AVPacket這個(gè)結(jié)構(gòu)體來(lái)存儲(chǔ)壓縮數(shù)據(jù).對(duì)于視頻而言, 它通常包含一個(gè)壓縮幀,對(duì)音頻而言,可能包含多個(gè)壓縮幀,該結(jié)構(gòu)體類型通過(guò) av_malloc() 函數(shù)分配內(nèi)存,通過(guò) av_packet_ref() 函數(shù)拷貝,通過(guò) av_packet_unref(). 函數(shù)釋放內(nèi)存.

解析數(shù)據(jù)

int av_read_frame(AVFormatContext *s, AVPacket *pkt); : 此函數(shù)返回存儲(chǔ)在文件中的內(nèi)容,并且不驗(yàn)證解碼器的有效幀是什么。它會(huì)將存儲(chǔ)在文件中的內(nèi)容分成幀,并為每次調(diào)用返回一個(gè)。它不會(huì)在有效幀之間省略無(wú)效數(shù)據(jù),以便為解碼器提供解碼時(shí)可能的最大信息。

獲取sps, pps等NALU Header信息

通過(guò)調(diào)用av_bitstream_filter_filter可以從碼流中過(guò)濾得到sps, pps等NALU Header信息.

av_bitstream_filter_init: 通過(guò)給定的比特流過(guò)濾器名詞創(chuàng)建并初始化一個(gè)比特流過(guò)濾器上下文.

av_bitstream_filter_filter: 此函數(shù)通過(guò)過(guò)濾buf參數(shù)中的數(shù)據(jù),將過(guò)濾后的數(shù)據(jù)放在poutbuf參數(shù)中.輸出的buffer必須被調(diào)用者釋放.

此函數(shù)使用buf_size大小過(guò)濾緩沖區(qū)buf,并將過(guò)濾后的緩沖區(qū)放在poutbuf指向的緩沖區(qū)中。

注意: 下面使用new_packet是為了解決av_bitstream_filter_filter會(huì)產(chǎn)生內(nèi)存泄漏的問(wèn)題.每次使用完后將用new_packet釋放即可.

可以根據(jù)自己的需求自定義時(shí)間戳生成規(guī)則.這里使用當(dāng)前系統(tǒng)時(shí)間戳加上數(shù)據(jù)包中的自帶的pts/dts生成了時(shí)間戳.

本例將獲取到的數(shù)據(jù)放在自定義的結(jié)構(gòu)體中,然后通過(guò)block回調(diào)傳給方法的調(diào)用者,調(diào)用者可以在回調(diào)函數(shù)中處理parse到的視頻數(shù)據(jù).

獲取parse到的音頻數(shù)據(jù)

因?yàn)槲覀円呀?jīng)將packet中的關(guān)鍵數(shù)據(jù)拷貝到自定義的結(jié)構(gòu)體中,所以使用完后需要釋放packet.

parse完成后釋放相關(guān)資源

C++音視頻開(kāi)發(fā)學(xué)習(xí)資料 :點(diǎn)擊領(lǐng)取 音視頻開(kāi)發(fā)(資料文檔+視頻教程+面試題)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)

注意: 如果使用FFmpeg硬解,則僅僅需要獲取到AVPacket數(shù)據(jù)結(jié)構(gòu)即可.不需要再將數(shù)據(jù)封裝到自定義的結(jié)構(gòu)體中

【iOS】FFMpeg SDK 開(kāi)發(fā)手冊(cè)

FFmpeg是一套可以用來(lái)記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開(kāi)源計(jì)算機(jī)程序。采用LGPL或GPL許可證。它提供了錄制、轉(zhuǎn)換以及流化音視頻的完整解決方案。它包含了非常先進(jìn)的音頻/視頻編解碼庫(kù)libavcodec,為了保證高可移植性和編解碼質(zhì)量,libavcodec里很多codec都是從頭開(kāi)發(fā)的。

FFmpeg在Linux平臺(tái)下開(kāi)發(fā),但它同樣也可以在其它操作系統(tǒng)環(huán)境中編譯運(yùn)行,包括Windows、Mac OS X等。這個(gè)項(xiàng)目最早由Fabrice Bellard發(fā)起,現(xiàn)在由Michael Niedermayer維護(hù)。許多FFmpeg的開(kāi)發(fā)人員都來(lái)自MPlayer項(xiàng)目,而且當(dāng)前FFmpeg也是放在MPlayer項(xiàng)目組的服務(wù)器上。項(xiàng)目的名稱來(lái)自MPEG視頻編碼標(biāo)準(zhǔn),前面的"FF"代表"Fast Forward"。

libavformat:用于各種音視頻封裝格式的生成和解析,包括獲取解碼所需信息以生成解碼上下文結(jié)構(gòu)和讀取音視頻幀等功能;

libavcodec:用于各種類型聲音/圖像編解碼;

libavutil:包含一些公共的工具函數(shù);

libswscale:用于視頻場(chǎng)景比例縮放、色彩映射轉(zhuǎn)換;

libpostproc:用于后期效果處理;

ffmpeg:該項(xiàng)目提供的一個(gè)工具,可用于格式轉(zhuǎn)換、解碼或電視卡即時(shí)編碼等;

ffsever:一個(gè) HTTP 多媒體即時(shí)廣播串流服務(wù)器;

ffplay:是一個(gè)簡(jiǎn)單的播放器,使用ffmpeg 庫(kù)解析和解碼,通過(guò)SDL顯示;

三種幀的說(shuō)明

I幀:幀內(nèi)編碼幀 ,I幀表示關(guān)鍵幀,你可以理解為這一幀畫(huà)面的完整保留;解碼時(shí)只需要本幀數(shù)據(jù)就可以完成(因?yàn)榘暾?huà)面)

I幀特點(diǎn):

1.它是一個(gè)全幀壓縮編碼幀。它將全幀圖像信息進(jìn)行JPEG壓縮編碼及傳輸;

2.解碼時(shí)僅用I幀的數(shù)據(jù)就可重構(gòu)完整圖像;

3.I幀描述了圖像背景和運(yùn)動(dòng)主體的詳情;

4.I幀不需要參考其他畫(huà)面而生成;

5.I幀是P幀和B幀的參考幀(其質(zhì)量直接影響到同組中以后各幀的質(zhì)量);

6.I幀是幀組GOP的基礎(chǔ)幀(第一幀),在一組中只有一個(gè)I幀;

7.I幀不需要考慮運(yùn)動(dòng)矢量;

8.I幀所占數(shù)據(jù)的信息量比較大。

P幀:前向預(yù)測(cè)編碼幀。P幀表示的是這一幀跟之前的一個(gè)關(guān)鍵幀(或P幀)的差別,解碼時(shí)需要用之前緩存的畫(huà)面疊加上本幀定義的差別,生成最終畫(huà)面。(也就是差別幀,P幀沒(méi)有完整畫(huà)面數(shù)據(jù),只有與前一幀的畫(huà)面差別的數(shù)據(jù))

P幀的預(yù)測(cè)與重構(gòu):P幀是以I幀為參考幀,在I幀中找出P幀“某點(diǎn)”的預(yù)測(cè)值和運(yùn)動(dòng)矢量,取預(yù)測(cè)差值和運(yùn)動(dòng)矢量一起傳送。在接收端根據(jù)運(yùn)動(dòng)矢量從I幀中找出P幀“某點(diǎn)”的預(yù)測(cè)值并與差值相加以得到P幀“某點(diǎn)”樣值,從而可得到完整的P幀。

P幀特點(diǎn):

1.P幀是I幀后面相隔1~2幀的編碼幀;

2.P幀采用運(yùn)動(dòng)補(bǔ)償?shù)姆椒▊魉退c前面的I或P幀的差值及運(yùn)動(dòng)矢量(預(yù)測(cè)誤差);

3.解碼時(shí)必須將I幀中的預(yù)測(cè)值與預(yù)測(cè)誤差求和后才能重構(gòu)完整的P幀圖像;

4.P幀屬于前向預(yù)測(cè)的幀間編碼。它只參考前面最靠近它的I幀或P幀;

5.P幀可以是其后面P幀的參考幀,也可以是其前后的B幀的參考幀;

6.由于P幀是參考幀,它可能造成解碼錯(cuò)誤的擴(kuò)散;

7.由于是差值傳送,P幀的壓縮比較高。

B幀:雙向預(yù)測(cè)內(nèi)插編碼幀。B幀是雙向差別幀,也就是B幀記錄的是本幀與前后幀的差別(具體比較復(fù)雜,有4種情況,但我這樣說(shuō)簡(jiǎn)單些),換言之,要解碼B幀,不僅要取得之前的緩存畫(huà)面,還要解碼之后的畫(huà)面,通過(guò)前后畫(huà)面的與本幀數(shù)據(jù)的疊加取得最終的畫(huà)面。B幀壓縮率高,但是解碼時(shí)CPU會(huì)比較累。

B幀的預(yù)測(cè)與重構(gòu)

B幀以前面的I或P幀和后面的P幀為參考幀,“找出”B幀“某點(diǎn)”的預(yù)測(cè)值和兩個(gè)運(yùn)動(dòng)矢量,并取預(yù)測(cè)差值和運(yùn)動(dòng)矢量傳送。接收端根據(jù)運(yùn)動(dòng)矢量在兩個(gè)參考幀中“找出(算出)”預(yù)測(cè)值并與差值求和,得到B幀“某點(diǎn)”樣值,從而可得到完整的B幀。

B幀特點(diǎn)

1.B幀是由前面的I或P幀和后面的P幀來(lái)進(jìn)行預(yù)測(cè)的;

2.B幀傳送的是它與前面的I或P幀和后面的P幀之間的預(yù)測(cè)誤差及運(yùn)動(dòng)矢量;

3.B幀是雙向預(yù)測(cè)編碼幀;

4.B幀壓縮比最高,因?yàn)樗环从潮麉⒖紟g運(yùn)動(dòng)主體的變化情況,預(yù)測(cè)比較準(zhǔn)確;

5.B幀不是參考幀,不會(huì)造成解碼錯(cuò)誤的擴(kuò)散。

注:I、B、P各幀是根據(jù)壓縮算法的需要,是人為定義的,它們都是實(shí)實(shí)在在的物理幀。一般來(lái)說(shuō),I幀的壓縮率是7(跟JPG差不多),P幀是20,B幀可以達(dá)到50??梢?jiàn)使用B幀能節(jié)省大量空間,節(jié)省出來(lái)的空間可以用來(lái)保存多一些I幀,這樣在相同碼率下,可以提供更好的畫(huà)質(zhì)。

1.分組:把幾幀圖像分為一組(GOP,也就是一個(gè)序列),為防止運(yùn)動(dòng)變化,幀數(shù)不宜取多。

2.定義幀:將每組內(nèi)各幀圖像定義為三種類型,即I幀、B幀和P幀;

3.預(yù)測(cè)幀:以I幀做為基礎(chǔ)幀,以I幀預(yù)測(cè)P幀,再由I幀和P幀預(yù)測(cè)B幀;

4.數(shù)據(jù)傳輸:最后將I幀數(shù)據(jù)與預(yù)測(cè)的差值信息進(jìn)行存儲(chǔ)和傳輸。幀內(nèi)(Intraframe)壓縮也稱為空間壓縮(Spatial compression)。當(dāng)壓縮一幀圖像時(shí),僅考慮本幀的數(shù)據(jù)而不考慮相鄰幀之間的冗余信息,這實(shí)際上與靜態(tài)圖像壓縮類似。幀內(nèi)一般采用有損壓縮算法,由于幀內(nèi)壓縮是編碼一個(gè)完整的圖像,所以可以獨(dú)立的解碼、顯示。幀內(nèi)壓縮一般達(dá)不到很高的壓縮,跟編碼jpeg差不多。

幀間(Interframe)壓縮的原理是:相鄰幾幀的數(shù)據(jù)有很大的相關(guān)性,或者說(shuō)前后兩幀信息變化很小的特點(diǎn)。也即連續(xù)的視頻其相鄰幀之間具有冗余信息,根據(jù)這一特性,壓縮相鄰幀之間的冗余量就可以進(jìn)一步提高壓縮量,減小壓縮比。幀間壓縮也稱為時(shí)間壓縮(Temporal compression),它通過(guò)比較時(shí)間軸上不同幀之間的數(shù)據(jù)進(jìn)行壓縮。幀間壓縮一般是無(wú)損的。幀差值(Frame differencing)算法是一種典型的時(shí)間壓縮法,它通過(guò)比較本幀與相鄰幀之間的差異,僅記錄本幀與其相鄰幀的差值,這樣可以大大減少數(shù)據(jù)量。

順便說(shuō)下有損(Lossy )壓縮和無(wú)損(Lossy less)壓縮。無(wú)損壓縮也即壓縮前和解壓縮后的數(shù)據(jù)完全一致。多數(shù)的無(wú)損壓縮都采用RLE行程編碼算法。有損壓縮意味著解壓縮后的數(shù)據(jù)與壓縮前的數(shù)據(jù)不一致。在壓縮的過(guò)程中要丟失一些人眼和人耳所不敏感的圖像或音頻信息,而且丟失的信息不可恢復(fù)。幾乎所有高壓縮的算法都采用有損壓縮,這樣才能達(dá)到低數(shù)據(jù)率的目標(biāo)。丟失的數(shù)據(jù)率與壓縮比有關(guān),壓縮比越小,丟失的數(shù)據(jù)越多,解壓縮后的效果一般越差。此外,某些有損壓縮算法采用多次重復(fù)壓縮的方式,這樣還會(huì)引起額外的數(shù)據(jù)丟失。

如果NALU對(duì)應(yīng)的Slice為一幀的開(kāi)始,則用4字節(jié)表示,即0x00000001;否則用3字節(jié)表示,0x000001。

NAL Header:forbidden_bit,nal_reference_bit(優(yōu)先級(jí))2bit,nal_unit_type(類型)5bit。 標(biāo)識(shí)NAL單元中的RBSP數(shù)據(jù)類型,其中,nal_unit_type為1, 2, 3, 4, 5的NAL單元稱為VCL的NAL單元,其他類型的NAL單元為非VCL的NAL單元。

0:未規(guī)定

1:非IDR圖像中不采用數(shù)據(jù)劃分的片段

2:非IDR圖像中A類數(shù)據(jù)劃分片段

3:非IDR圖像中B類數(shù)據(jù)劃分片段

4:非IDR圖像中C類數(shù)據(jù)劃分片段

5:IDR圖像的片段

6:補(bǔ)充增強(qiáng)信息(SEI)

7:序列參數(shù)集(SPS)

8:圖像參數(shù)集(PPS)

9:分割符

10:序列結(jié)束符

11:流結(jié)束符

12:填充數(shù)據(jù)

13:序列參數(shù)集擴(kuò)展

14:帶前綴的NAL單元

15:子序列參數(shù)集

16 – 18:保留

19:不采用數(shù)據(jù)劃分的輔助編碼圖像片段

20:編碼片段擴(kuò)展

21 – 23:保留

24 – 31:未規(guī)定

H.264的SPS和PPS串,包含了初始化H.264解碼器所需要的信息參數(shù),包括編碼所用的profile,level,圖像的寬和高,deblock濾波器等。

碼率:256~512 kb/s

幀率:15~20fps

分辨率:1280x720(HD) 640x368(VGA) 1920x1080(UHD)

中文名:高級(jí)音頻編碼,出現(xiàn)于1997年,基于MPEG-2的音頻編碼技術(shù)。由Fraunhofer IIS、杜比實(shí)驗(yàn)室、ATT、Sony等公司共同開(kāi)發(fā),目的是取代MP3格式。2000年,MPEG-4標(biāo)準(zhǔn)出現(xiàn)后,AAC重新集成了其特性,加入了SBR技術(shù)和PS技術(shù),為了區(qū)別于傳統(tǒng)的MPEG-2 AAC又稱為MPEG-4 AAC。

優(yōu)點(diǎn):相對(duì)于mp3,AAC格式的音質(zhì)更佳,文件更小。

不足:AAC屬于有損壓縮的格式,與時(shí)下流行的APE、FLAC等無(wú)損格式相比音質(zhì)存在“本質(zhì)上”的差距。加之,傳輸速度更快的USB3.0和16G以上大容量MP3正在加速普及,也使得AAC頭上“小巧”的光環(huán)不復(fù)存在了。

音頻采樣率是指錄音設(shè)備在一秒鐘內(nèi)對(duì)聲音信號(hào)的采樣次數(shù),采樣頻率越高聲音的還原就越真實(shí)越自然。在當(dāng)今的主流采集卡上,采樣頻率一般共分為22.05KHz、44.1KHz、48KHz三個(gè)等級(jí),22.05KHz只能達(dá)到FM廣播的聲音品質(zhì),44.1KHz則是理論上的CD音質(zhì)界限,48KHz則更加精確一些。

比特率是指每秒傳送的比特(bit)數(shù)。單位為 bps(Bit Per Second),比特率越高,傳送數(shù)據(jù)速度越快。聲音中的比特率是指將模擬聲音信號(hào)轉(zhuǎn)換成數(shù)字聲音信號(hào)后,單位時(shí)間內(nèi)的二進(jìn)制數(shù)據(jù)量,是間接衡量音頻質(zhì)量的一個(gè)指標(biāo)。 視頻中的比特率(碼率)原理與聲音中的相同,都是指由模擬信號(hào)轉(zhuǎn)換為數(shù)字信號(hào)后,單位時(shí)間內(nèi)的二進(jìn)制數(shù)據(jù)量。

信道編碼中,K符號(hào)大小的信源數(shù)據(jù)塊通過(guò)編碼映射為N符號(hào)大小的碼字,則K/N成為碼率,其中假設(shè)編碼前后的符號(hào)表沒(méi)有變化。

FFMPEG中結(jié)構(gòu)體很多。最關(guān)鍵的結(jié)構(gòu)體可以分成以下幾類:

解協(xié)議(http,rtsp,rtmp,mms)

AVIOContext,URLProtocol,URLContext主要存儲(chǔ)視音頻使用的協(xié)議的類型以及狀態(tài)。URLProtocol存儲(chǔ)輸入視音頻使用的封裝格式。每種協(xié)議都對(duì)應(yīng)一個(gè)URLProtocol結(jié)構(gòu)。(注意:FFMPEG中文件也被當(dāng)做一種協(xié)議“file”)

解封裝(flv,avi,rmvb,mp4)

AVFormatContext主要存儲(chǔ)視音頻封裝格式中包含的信息;AVInputFormat存儲(chǔ)輸入視音頻使用的封裝格式。每種視音頻封裝格式都對(duì)應(yīng)一個(gè)AVInputFormat 結(jié)構(gòu)。

解碼(h264,mpeg2,aac,mp3)

每個(gè)AVStream存儲(chǔ)一個(gè)視頻/音頻流的相關(guān)數(shù)據(jù);每個(gè)AVStream對(duì)應(yīng)一個(gè)AVCodecContext,存儲(chǔ)該視頻/音頻流使用解碼方式的相關(guān)數(shù)據(jù);每個(gè)AVCodecContext中對(duì)應(yīng)一個(gè)AVCodec,包含該視頻/音頻對(duì)應(yīng)的解碼器。每種解碼器都對(duì)應(yīng)一個(gè)AVCodec結(jié)構(gòu)。

存數(shù)據(jù)

視頻的話,每個(gè)結(jié)構(gòu)一般是存一幀;音頻可能有好幾幀

解碼前數(shù)據(jù):AVPacket

解碼后數(shù)據(jù):AVFrame

AVCodec是存儲(chǔ)編解碼器信息的結(jié)構(gòu)體

const char *name:編解碼器的名字,比較短

const char *long_name:編解碼器的名字,全稱,比較長(zhǎng)

enum AVMediaType type:指明了類型,是視頻,音頻,還是字幕

enum AVCodecID id:ID,不重復(fù)

const AVRational *supported_framerates:支持的幀率(僅視頻)

const enum AVPixelFormat *pix_fmts:支持的像素格式(僅視頻)

const int *supported_samplerates:支持的采樣率(僅音頻)

const enum AVSampleFormat *sample_fmts:支持的采樣格式(僅音頻)

const uint64_t channel_layouts:支持的聲道數(shù)(僅音頻)

int priv_data_size:私有數(shù)據(jù)的大小

1.注冊(cè)所有編解碼器:av_register_all();

2.聲明一個(gè)AVCodec類型的指針,比如說(shuō)AVCodec first_c;

3.調(diào)用av_codec_next()函數(shù),即可獲得指向鏈表下一個(gè)解碼器的指針,循環(huán)往復(fù)可以獲得所有解碼器的信息。注意,如果想要獲得指向第一個(gè)解碼器的指針,則需要將該函數(shù)的參數(shù)設(shè)置為NULL。

這是一個(gè)描述編解碼器上下文的數(shù)據(jù)結(jié)構(gòu),包含了眾多編解碼器需要的參數(shù)信息

如果是單純使用libavcodec,這部分信息需要調(diào)用者進(jìn)行初始化;如果是使用整個(gè)FFMPEG庫(kù),這部分信息在調(diào)用 av_open_input_file和av_find_stream_info的過(guò)程中根據(jù)文件的頭信息及媒體流內(nèi)的頭部信息完成初始化。其中幾個(gè)主要 域的釋義如下:

extradata/extradata_size: 這個(gè)buffer中存放了解碼器可能會(huì)用到的額外信息,在av_read_frame中填充。一般來(lái)說(shuō),首先,某種具體格式的demuxer在讀取格式頭 信息的時(shí)候會(huì)填充extradata,其次,如果demuxer沒(méi)有做這個(gè)事情,比如可能在頭部壓根兒就沒(méi)有相關(guān)的編解碼信息,則相應(yīng)的parser會(huì)繼 續(xù)從已經(jīng)解復(fù)用出來(lái)的媒體流中繼續(xù)尋找。在沒(méi)有找到任何額外信息的情況下,這個(gè)buffer指針為空。

time_base:

width/height:視頻的寬和高。

sample_rate/channels:音頻的采樣率和信道數(shù)目。

sample_fmt: 音頻的原始采樣格式。

codec_name/codec_type/codec_id/codec_tag:編解碼器的信息。

該結(jié)構(gòu)體描述一個(gè)媒體流

主要域的釋義如下,其中大部分域的值可以由av_open_input_file根據(jù)文件頭的信息確定,缺少的信息需要通過(guò)調(diào)用av_find_stream_info讀幀及軟解碼進(jìn)一步獲?。?/p>

index/id:index對(duì)應(yīng)流的索引,這個(gè)數(shù)字是自動(dòng)生成的,根據(jù)index可以從AVFormatContext::streams表中索引到該流;而id則是流的標(biāo)識(shí),依賴于具體的容器格式。比如對(duì)于MPEG TS格式,id就是pid。

time_base:流的時(shí)間基準(zhǔn),是一個(gè)實(shí)數(shù),該流中媒體數(shù)據(jù)的pts和dts都將以這個(gè)時(shí)間基準(zhǔn)為粒度。通常,使用av_rescale/av_rescale_q可以實(shí)現(xiàn)不同時(shí)間基準(zhǔn)的轉(zhuǎn)換。

start_time:流的起始時(shí)間,以流的時(shí)間基準(zhǔn)為單位,通常是該流中第一個(gè)幀的pts。

duration:流的總時(shí)間,以流的時(shí)間基準(zhǔn)為單位。

need_parsing:對(duì)該流parsing過(guò)程的控制域。

nb_frames:流內(nèi)的幀數(shù)目。

r_frame_rate/framerate/avg_frame_rate:幀率相關(guān)。

codec:指向該流對(duì)應(yīng)的AVCodecContext結(jié)構(gòu),調(diào)用av_open_input_file時(shí)生成。

parser:指向該流對(duì)應(yīng)的AVCodecParserContext結(jié)構(gòu),調(diào)用av_find_stream_info時(shí)生成。

這個(gè)結(jié)構(gòu)體描述了一個(gè)媒體文件或媒體流的構(gòu)成和基本信息

這是FFMpeg中最為基本的一個(gè)結(jié)構(gòu),是其他所有結(jié)構(gòu)的根,是一個(gè)多媒體文件或流的根本抽象。其中:nb_streams和streams所表示的AVStream結(jié)構(gòu)指針數(shù)組包含了所有內(nèi)嵌媒體流的描述;iformat和oformat指向?qū)?yīng)的demuxer和muxer指針;pb則指向一個(gè)控制底層數(shù)據(jù)讀寫(xiě)的ByteIOContext結(jié)構(gòu)。

start_time和duration是從streams數(shù)組的各個(gè)AVStream中推斷出的多媒體文件的起始時(shí)間和長(zhǎng)度,以微妙為單位。

通常,這個(gè)結(jié)構(gòu)由av_open_input_file在內(nèi)部創(chuàng)建并以缺省值初始化部分成員。但是,如果調(diào)用者希望自己創(chuàng)建該結(jié)構(gòu),則需要顯式為該結(jié)構(gòu)的一些成員置缺省值——如果沒(méi)有缺省值的話,會(huì)導(dǎo)致之后的動(dòng)作產(chǎn)生異常。以下成員需要被關(guān)注:

probesize

mux_rate

packet_size

flags

max_analyze_duration

key

max_index_size

max_picture_buffer

max_delay

AVPacket定義在avcodec.h中

FFMPEG使用AVPacket來(lái)暫存解復(fù)用之后、解碼之前的媒體數(shù)據(jù)(一個(gè)音/視頻幀、一個(gè)字幕包等)及附加信息(解碼時(shí)間戳、顯示時(shí)間戳、時(shí)長(zhǎng)等)。其中:

dts 表示解碼時(shí)間戳,pts表示顯示時(shí)間戳,它們的單位是所屬媒體流的時(shí)間基準(zhǔn)。

stream_index 給出所屬媒體流的索引;

data 為數(shù)據(jù)緩沖區(qū)指針,size為長(zhǎng)度;

duration 為數(shù)據(jù)的時(shí)長(zhǎng),也是以所屬媒體流的時(shí)間基準(zhǔn)為單位;

pos 表示該數(shù)據(jù)在媒體流中的字節(jié)偏移量;

destruct 為用于釋放數(shù)據(jù)緩沖區(qū)的函數(shù)指針;

flags 為標(biāo)志域,其中,最低為置1表示該數(shù)據(jù)是一個(gè)關(guān)鍵幀。

AVPacket 結(jié)構(gòu)本身只是個(gè)容器,它使用data成員指向?qū)嶋H的數(shù)據(jù)緩沖區(qū),這個(gè)緩沖區(qū)可以通過(guò)av_new_packet創(chuàng)建,可以通過(guò) av_dup_packet 拷貝,也可以由FFMPEG的API產(chǎn)生(如av_read_frame),使用之后需要通過(guò)調(diào)用av_free_packet釋放。

av_free_packet調(diào)用的是結(jié)構(gòu)體本身的destruct函數(shù),它的值有兩種情況:(1)av_destruct_packet_nofree或 0;(2)av_destruct_packet,其中,前者僅僅是將data和size的值清0而已,后者才會(huì)真正地釋放緩沖區(qū)。FFMPEG內(nèi)部使用 AVPacket結(jié)構(gòu)建立緩沖區(qū)裝載數(shù)據(jù),同時(shí)提供destruct函數(shù),如果FFMPEG打算自己維護(hù)緩沖區(qū),則將destruct設(shè)為 av_destruct_packet_nofree,用戶調(diào)用av_free_packet清理緩沖區(qū)時(shí)并不能夠?qū)⑵溽尫牛蝗绻鸉FMPEG不會(huì)再使用 該緩沖區(qū),則將destruct設(shè)為av_destruct_packet,表示它能夠被釋放。對(duì)于緩沖區(qū)不能夠被釋放的AVPackt,用戶在使用之前 最好調(diào)用av_dup_packet進(jìn)行緩沖區(qū)的克隆,將其轉(zhuǎn)化為緩沖區(qū)能夠被釋放的AVPacket,以免對(duì)緩沖區(qū)的不當(dāng)占用造成異常錯(cuò)誤。而 av_dup_packet會(huì)為destruct指針為av_destruct_packet_nofree的AVPacket新建一個(gè)緩沖區(qū),然后將原 緩沖區(qū)的數(shù)據(jù)拷貝至新緩沖區(qū),置data的值為新緩沖區(qū)的地址,同時(shí)設(shè)destruct指針為av_destruct_packet。

構(gòu)體保存的是解碼后和原始的音視頻信息。AVFrame通過(guò)函數(shù)av_frame_alloc()初始化,該函數(shù)僅僅分配AVFrame實(shí)例本身,而沒(méi)有分配其內(nèi)部的緩存。AVFrame實(shí)例由av_frame_free()釋放;AVFrame實(shí)例通常分配一次,重復(fù)使用,如分配一個(gè)AVFrame實(shí)例來(lái)保留解碼器中輸出的視頻幀(此時(shí)應(yīng)在恰當(dāng)?shù)臅r(shí)候使用av_frame_unref()清理參考幀并將AVFrame歸零)。該類所描述的數(shù)據(jù)通常由AVBuffer的API來(lái)保存一個(gè)引用計(jì)數(shù),并保存于AVFrame.buf

/AVFrame.extended_buf,在至少存在一個(gè)參考的時(shí)候(如AVFrame.buf[0] != NULL),則該對(duì)象被標(biāo)記為“被引用”。在此情況下,AVFrame所包含的每一組數(shù)據(jù)必須包含于AVFrame的緩存中。

ADTS流 跟Raw流,

1.ADTS是個(gè)啥

ADTS全稱是(Audio Data Transport Stream),是AAC的一種十分常見(jiàn)的傳輸格式。

AAC解碼器都需要把AAC的ES流打包成ADTS的格式,一般是在AAC ES流前添加7個(gè)字節(jié)的ADTS header。也就是說(shuō)你可以吧ADTS這個(gè)頭看作是AAC的frameheader。

ffmpeg寫(xiě) mp4+aac時(shí)呢,音頻有兩個(gè)值得注意的地方。

1 寫(xiě)aac音頻時(shí),要添加兩個(gè)字節(jié)的信息到AVCodecContext.

2 ffmpeg 寫(xiě)AAC音頻數(shù)據(jù)不能含有ADTS頭

在AAC ES流前添加7個(gè)字節(jié)的ADTS header。也就是說(shuō)你可以吧ADTS這個(gè)頭看作是AAC的frameheader。

tvOS必須要支持 bitcode. (iOS bitcode項(xiàng)可選的) 所以在編譯的時(shí)候Makefile要加上 CFLAGS= -fembed-bitcode 。 如果用xcode編譯lib,要在Build Settings—custom compiler flags —cflags 加上OTHER_CFLAGS="-fembed-bitcode" 。

1 內(nèi)存優(yōu)化。內(nèi)存往上漲。沒(méi)能及時(shí)回收。最好能夠使用手動(dòng)管理內(nèi)存。

解碼優(yōu)化,看ffmpeg文檔,最新的解碼庫(kù),解碼效率,穩(wěn)定性,綜合性考慮。

YUV-RGB OpenGLES shader來(lái)顯示。

1.分離視頻音頻流

ffmpeg -i input_file -vcodec copy -an output_file_video//分離視頻流

ffmpeg -i input_file -acodec copy -vn output_file_audio//分離音頻流

2.視頻解復(fù)用

ffmpeg –i test.mp4 –vcodec copy –an –f m4v test.264

ffmpeg –i test.avi –vcodec copy –an –f m4v test.264

3.視頻轉(zhuǎn)碼

ffmpeg –i test.mp4 –vcodec h264 –s 352 278 –an –f m4v test.264 //轉(zhuǎn)碼為碼流原始文件

ffmpeg –i test.mp4 –vcodec h264 –bf 0 –g 25 –s 352 278 –an –f m4v test.264 //轉(zhuǎn)碼為碼流原始文件

ffmpeg –i test.avi -vcodec mpeg4 –vtag xvid –qsame test_xvid.avi //轉(zhuǎn)碼為封裝文件

//-bf B幀數(shù)目控制,-g 關(guān)鍵幀間隔控制,-s 分辨率控制

4.視頻封裝

ffmpeg –i video_file –i audio_file –vcodec copy –acodec copy output_file

5.視頻剪切

ffmpeg –i test.avi –r 1 –f image2 image-%3d.jpeg //提取圖片

ffmpeg -ss 0:1:30 -t 0:0:20 -i input.avi -vcodec copy -acodec copy output.avi //剪切視頻

//-r 提取圖像的頻率,-ss 開(kāi)始時(shí)間,-t 持續(xù)時(shí)間

6.視頻錄制

ffmpeg –i rtsp://192.168.3.205:5555/test –vcodec copy out.avi

7.YUV序列播放

ffplay -f rawvideo -video_size 1920x1080 input.yuv

8.YUV序列轉(zhuǎn)AVI

ffmpeg –s w*h –pix_fmt yuv420p –i input.yuv –vcodec mpeg4 output.avi

ios 怎么配置編譯ffmpeg

IOS上編譯ffmpeg需要先下載兩個(gè)程序:iFrameExractor和ffmpeg

編譯步驟:

1、在終端下: cd /iFrameExtractor/ffmpeg 建議開(kāi)始就執(zhí)行 sudo -s (獲取權(quán)限命令)

2、在終端下輸入 ./configure --prefix=/iFrameExtractor/ffmpeg --libdir=iFrameExtractor/ffmpeg/lib --enable-gpl --enable-static --disable-shared --enable-swscale --enable-zlib --enable-bzlib --disable-ffmpeg --disable-ffplay --disable-ffserver --enable-pthreads

3、執(zhí)行make 這里會(huì)有一堆的編譯情況。

注:最好先升級(jí)Command Line Tools,避免編譯錯(cuò)誤

4、執(zhí)行make install。 (執(zhí)行完后 到iFrameExtractor/ffmpeg/lib文件上去看看)

出現(xiàn) libavcodec libavdevice libavformat libavutil libswscale5個(gè).a文件

5、用xcode 打開(kāi)iFrameExractor工程,確認(rèn)Header Search Paths里有:"$(SRCROOT)/ffmpeg"路徑。 $(SRCROOT)表示工程路徑。同時(shí)可以看到iFrameExractor工程下ffmpeg文件下的.a文件都不是紅色的了。

6、真機(jī)上編譯(模擬器上i386,真機(jī)上是arm的,真機(jī)還分arm6 和arm7 )

以下是針對(duì)arm7的

/configure --disable-doc --disable-ffmpeg --disable-ffplay --disable-ffserver --enable-cross-compile --arch=arm --target-os=darwin --cc=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc --as='gas-preprocessor/gas-preprocessor.pl /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc' -- sysroot=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk --cpu=cortex-a8 --extra-cflags='-arch armv7' --extra-ldflags='-arch armv7 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk' --enable-pic

7、執(zhí)行 make 和make install 就有上面的幾個(gè).a文件,至此編譯結(jié)束。

iOS利用FFmpeg解碼音頻數(shù)據(jù)并播放

利用FFmepg解析并解碼音頻流數(shù)據(jù),然后將解碼后的音頻數(shù)據(jù)送給Audio Queue以實(shí)現(xiàn)播放.

利用FFmpeg解析音頻數(shù)據(jù)流, 利用FFmpeg解碼音頻數(shù)據(jù)為PCM格式. 利用Audio Queue Player實(shí)現(xiàn)音頻數(shù)據(jù)播放.

本例以一個(gè)蘋(píng)果原生相機(jī)錄制的.MOV文件為例, 將該文件使用FFmpeg解析并解碼,將解碼后的數(shù)據(jù)放入傳輸隊(duì)列中,然后開(kāi)啟audio queue player, 播放器在回調(diào)函數(shù)中輪循取出隊(duì)列中的數(shù)據(jù)實(shí)現(xiàn)播放.

FFmpeg parse流程

FFmpeg解碼流程

為了每次能夠重新播放,這里需要標(biāo)記當(dāng)前是否為解碼的第一幀數(shù)據(jù),以重新啟動(dòng)播放器. 另一點(diǎn)是使用NSTimer等待音頻數(shù)據(jù)放入隊(duì)列再開(kāi)始播放,因?yàn)閍udio queue是驅(qū)動(dòng)播放模式,所以必須等音頻數(shù)據(jù)放入傳輸隊(duì)列再開(kāi)始播放.

從Parse模塊中可以獲取當(dāng)前文件對(duì)應(yīng)FFmepg的上下文對(duì)象 AVFormatContext .因此音頻流解碼器信息可以直接獲取.

AVFrame 作為解碼后原始的音視頻數(shù)據(jù)的容器.AVFrame通常被分配一次然后多次重復(fù)(例如,單個(gè)AVFrame以保持從解碼器接收的幀)。在這種情況下,av_frame_unref()將釋放框架所持有的任何引用,并在再次重用之前將其重置為其原始的清理狀態(tài)。

調(diào)用avcodec_send_packet將壓縮數(shù)據(jù)發(fā)送給解碼器.最后利用循環(huán)接收avcodec_receive_frame解碼后的音視頻數(shù)據(jù).

iOS語(yǔ)音對(duì)講(三)FFmpeg實(shí)時(shí)解碼AAC并播放PCM

具體過(guò)程如下:

初始化解碼器

解碼AAC,block中返回解碼后的PCM

釋放解碼器

播放PCM使用 AudioQueue ,具體流程:

通過(guò)上圖可以得知,Audio Queue的播放流程即是一個(gè) 生產(chǎn)者與消費(fèi)者 的模式:

創(chuàng)建多個(gè)Buffer容器,依次填充(生產(chǎn))Buffer后插入隊(duì)列中,開(kāi)始播放(消費(fèi)),然后通過(guò)回調(diào)將消費(fèi)過(guò)的Buffer reuse,循環(huán)整個(gè)過(guò)程。

創(chuàng)建Buffer和Queue,設(shè)置參數(shù)并開(kāi)始執(zhí)行隊(duì)列

填充Buffer

在回調(diào)中將容器狀態(tài)設(shè)置為空,用于循環(huán)復(fù)用


分享題目:ios開(kāi)發(fā)ffmpeg,IOS開(kāi)發(fā)工程師最新招聘
網(wǎng)站路徑:http://weahome.cn/article/dsdodpd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部