ffmpeg的內部Video Buffer管理和傳送機制

本文主要介紹ffmpeg解碼器內部管理Video Buffer的原理和過程,ffmpeg的Videobuffer為內部管理,其流程大致為:注冊處理函數->幀級釋放->幀級申請->清空。

1?注冊get_buffer()和release_buffer()

FFAPI_InitCodec()

avcodec_alloc_context()

avcodec_alloc_context2()

avcodec_get_context_default2(AVCodecContext *s,...){

......

s->get_buffer = avcodec_default_get_buffer;

s->release_buffer = avcodec_default_release_buffer;

......

}

2幀級的內存申請和釋放調用

圖1幀級內存申請和釋放的函數調用

2.1 FFAPI函數調用libavcodec相應的codec(WMV3對應的Codec是VC1)函數進行解碼,過程中調用內部buffer處理函數。其中buffer管理被統一封裝到Mpegvideo接口中(包括的codec有H.261, H.263, H.264, mpeg12, rv10,rv34, svq1和VC1)

FFAPI_Decode()

???????avcodec_decode_video2()

??????????????avctx->codec->decode()//初始化過程中注冊codec,wmv3的解碼函數是

??????????????vc1_decode_frame(){

???????decode_vc1_header;

???????MPV_frame_start();?????????????????????????????????????//2.2.2

???????vc1_decode_blocks();

???????MPV_frame_end();?????????????????????????????????????//2.2.3

}

2.2 MPV_frame_start()//通過調用get_buffer()申請當前幀的video buffer。

MPV_frame_start()

???????//首先調用release_buffer()釋放非參考幀的video buffer

???????for(i=0; i<MAX_PICTURE_COUNT; i++)

if(s->picture[i].data[0] && !s->picture[i].reference)

free_frame_buffer(s, &s->picture[i]); //調用s->avctx->get_buffer(),回調avcodec_default_release_buffer()

?

???????ff_alloc_picture()

??????????????alloc_frame_buffer()

?????????????????????s->avctx->get_buffer()??????//回調avcodec_default_get_buffer()

2.3MPV_frame_end()??????????????????????????????????????????//完成視頻加邊等操作

?

3幀級的內存申請和釋放處理方法

3.1內部buffer數據結構

–???typedef struct InternalBuffer{

–???????int last_pic_num;??????????????

–???????uint8_t *base[4];?????????????

–???????uint8_t *data[4];?????????????

–???????int linesize[4];???????????

–???????int width, height;????????????

–???????enum PixelFormat pix_fmt;???

–???}InternalBuffer;

–???typedef struct AVCodecContext {

–??????????……

–???int internal_buffer_count;?//記錄當前內部buffer的個數,get_buffer和release_buffer時均需要對其進行維護。

–???void *internal_buffer;//初始化為數組InternalBuffer [INTERNAL_BUFFER_SIZE]

–???……

–???}?AVCodecContext;

Codec通過維護internal_buffer_count和internal_buffer實現高效的內存管理。

3.2參考幀管理相關數據結構

–???typedef??struct Picture{

–???????uint8_t *data[4];

–???????int linesize[4];

–???????uint8_t *base[4];

–???????int reference;

–???????……

–???}?Picture;

–???typedef??struct MpegEncContext{

–???????……

–???????Picture* picture;???//初始化為數組Picture[INTERNAL_BUFFER_SIZE]

–???????Picture* last_picture_ptr;??????//指向前一幀

–???????Picture* next_picture_ptr;;????//雙向預測時,指向后一幀

–???????Picture* current_picture_ptr;//指向當前幀

–???……

–???}?MpegEncContext;?

3.3申請和釋放原理

圖2?內存申請和釋放原理

(1)初始化時將internal_buffer全部清零

(2)釋放buffer時,將釋放的buffer與最后一個有效buffer交換,而不是用av_free()釋放內存。

avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){

s->internal_buffer_count--;

????last = &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];

????//將last buffer和要釋放的buffer交換,使last buffer變成無效buffer,在下次get_buffer時能被申請到。

FFSWAP(InternalBuffer, *buf, *last);

????for(i=0; i<4; i++){

????????pic->data[i]=NULL;

????}

}

(3)申請buffer時,檢查internal_buffer[internal_buffer_count]的基址是否非空,若非空則直接使用internal_buffer[internal_buffer_count];若空,使用av_malloc()函數進行申請。

這樣處理的好處是避免了頻繁的調用malloc()和free(),從而提升了效率。

avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){

???????……

???????buf= &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];

???????get_size_info(size[]);

???????buf->base[0, 1, 2] = av_malloc(size[0, 1, 2]);

???????buf->data[0, 1, 2] = buf->base[0, 1, 2] + padding_offset[0, 1, 2];

???????……

}

(4)決定輸出幀是在每幀解碼后,根據當前幀的類型和參考信息決定輸出幀。

if (s->pict_type == FF_B_TYPE || s->low_delay) {

*pict= *(AVFrame*)s->current_picture_ptr;

} else if (s->last_picture_ptr != NULL) {

*pict= *(AVFrame*)s->last_picture_ptr;

}

3.4舉例——假設解碼IPBPB的非H.264碼流。

(1)初始化后的狀態如所示,IBC為ctx->internal_buffer_count,CurPtr為s->current_picture_ptr,LastPtr為s->last_picture_ptr,NextPtr為s->next_picture_ptr。

gpAVPicture指針為輸出圖像的指針。

圖3?初始化狀態

(2)解碼第一個I幀,過程中不會不調用release_buffer(),get_buffer()得到picture[0]?,此時不輸出任何圖像。

圖4解碼第一個I幀后的狀態

(3)解碼第一個P幀,過程中不調用release_buffer(),get_buffer()得到picture[1]?,輸出picture[0]。

圖5解碼第一個P幀后的狀態

(4)解碼第一個B幀,過程中不調用release_buffer(),get_buffer()得到picture[2]?,輸出picture[2]。

圖6解碼第一個B幀后的狀態

(5)解碼第二個P幀,調用release_buffer(&picture[2]),再調用get_buffer(),得到picture[2],?輸出picture[1]。

圖7解碼第二個P幀的狀態

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/447365.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/447365.shtml
英文地址,請注明出處:http://en.pswp.cn/news/447365.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

springBoot的模版引擎

模版引擎 常見的模版引擎有JSP、Velocity、Freemarker和Thymeleaf Thymeleaf模版 使用時需要把html頁面放在classpath&#xff1a;/templates/文件夾下&#xff0c;thymeleaf就能自動渲染創建模版文件&#xff0c;并需要導入thymeleaf的名稱空間 <html lang"en"…

FFmepg 多線程解碼歷程

FFmepg 多線程解碼歷程 - 1:validate_thread_parameters /** * Set the threading algorithms used.//設置線程的使用算法 * Threading requires more than one thread.//需要一個以上的線程 * Frame threading requires entire frames to be passed to the codec,//幀線程…

SpringMVC自動配置

springboot為SpringMVC配置了自動配置&#xff0c;以下是SpringBoot對SpringMVC的默認配置 org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration 自動配置在Spring的默認配置之上添加了以下功能 包含ContentNegotiatingViewResolver和BeanNameView…

做一名合格的生意人

偶然的成功&#xff0c;包含著某種必然的因素&#xff0c;那就是一個生意人本身的素質。作為一名現代生意人&#xff0c;要想使自己所從事的事業取得新的成功&#xff0c;就要加強自身的修養&#xff0c;不斷掌握新知識&#xff0c;努力使自己成為“全才”。 □ 事業成功的十個…

restful風格的增刪改查

注意 如果靜態資源放到了靜態資源文件夾下卻無法訪問&#xff0c;請檢查一下是不是在自定義的配置類上加了EnableWebMvc注解templete文件夾不是靜態資源的文件夾&#xff0c;默認是無法訪問的&#xff0c;所以要添加視圖映射 package cn.xxxxxx.hellospringbootweb.config;imp…

歷史上最有影響力的10款開源項目

開源是大趨勢&#xff0c;開源軟件也在越來越多的出現在日常電腦桌面上&#xff0c;如Firefox瀏覽器、Ubuntu操作系統等。人們選擇開源軟件的原因&#xff0c;主要有低成本、安全無病毒侵害、更加透明和開放等。按照大多數的開源協議如GPL&#xff0c;開源軟件允許自由分發。在…

SpringBoot默認的錯誤處理機制

錯誤處理機制&#xff1a; 訪問一個不存在的頁面時&#xff0c;或者程序拋出異常時 默認效果 瀏覽器返回一個錯誤的頁面&#xff0c;注意查看瀏覽器發送請求的請求頭可以使用專業的軟件比如postman分析返回的json數據 springboot錯誤處理的自動配置信息 主要給日容器中注冊…

GitHub政府用戶破萬:開源成重塑政府新手段

據GitHub官方博客介紹&#xff0c;目前GitHub上的各地政府用戶數量已經達到1萬個&#xff01; 2009年&#xff0c;紐約參議院正式入駐GitHub公開部分技術資料與文檔&#xff0c;成為GitHub上的第一個政府組織。隨后&#xff0c;美國華盛頓特區、邁阿密、芝加哥、紐約&#xff…

配置嵌入式Servlet容器

如何定制和修改Servlet容器的相關配置 修改定制和修改Servlet容器的相關配置 server.port8081 server.context-path/crudserver.tomcat.uri-encodingUTF-8//通用的Servlet容器設置 server.xxx //Tomcat的設置 server.tomcat.xxx 編寫一個EmbeddedServletContainerCustomizer&…

云OS:Linux在桌面打翻身仗的機會?

不可否認&#xff0c;Chrome OS取得了驚人的增長。Chromebook自發行以來&#xff0c;迅速席卷全球&#xff0c;常年位居最暢銷筆記本榜首。這款基于Linux的筆記本在合適時間提供了合適的解決方案。很多情況下&#xff0c;云不僅僅是一個可選項&#xff0c;而是一個最優選項。Li…

Docker容器基本使用

Dcoker Docker是一個開源的應用容器引擎&#xff0c;是一個輕量級別的容器技術Dcoker支持將軟件編譯成一個鏡像&#xff1b;然后在鏡像中對各種軟件做好配置&#xff0c;再將鏡像發布出去&#xff0c;供別人使用運行中的鏡像稱為容器&#xff0c;容器的啟動是非常快速的核心概…

為什么35歲的C++依然能主導編程世界

早在1979年&#xff0c;Bjarne Stroustrup設計了C編程語言&#xff0c;并且C很快成為了無處不在的通用系統編程語言。現在盡管有Java、Javascript、Python、Go&#xff0c;甚至是蘋果的Swift和它競爭&#xff0c;但C依然處于主導編程世界的地位。 今天在Morgan Stanley的科技訪…

SpringBoot整合JPA

添加依賴 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId&…

為什么說選擇正確的編程語言很重要,以及如何正確的選擇

幾個月前&#xff0c;一個同事問我&#xff0c;應該如何選擇編程語言&#xff0c;或者有沒有什么固定的選擇模式&#xff0c;當時我便打算寫點什么。上周在硅谷開會&#xff0c;這我是第一次跟“hack3rs”的創業狂以及技術狂們打交道。我學會了很多前所未聞的臟話&#xff0c;也…

細數開源歷史上的十個重大事件

開放源碼&#xff08;開源&#xff09;的精神在于使用者可以使用、復制、散布、研究和改進軟件。這可以追溯到20世紀60年代&#xff0c;至今已有半個世紀了。雖然下面所列舉的不都是專門的開源產品&#xff0c;但還是在開源發展的進程中有著巨大的影響。開放源碼&#xff08;開…

科研必備學士搜索引擎推薦

綜合性學術搜索引擎 中國知網萬方數據百度學術谷歌學術谷歌學術鏡像Web of ScienceEiVillage2EIsevier電子期刊SpringerSemanticScholar 圖片文獻檢索方法 CNKI 期刊查詢 DOAJSocolarOpenDOAROALIB開放存取圖書館 碩博論文搜索下載 上海交大鏡像網站歐洲學位論文庫 國外電子…

如何寫一篇論文

文獻綜述的地位 體現了學術研究的繼承性 文獻綜述的寫作是由學術研究的繼承性決定的&#xff0c;因為繼承是創新的基礎和前提。文獻綜述部分要澄清所研究問題“從哪里來&#xff0c;到哪里去” 。這部分主要是繼承&#xff0c;是梳理前人的成果并找出其內在的邏輯關系和演進的規…

深度卷積神經網絡CNNs的多GPU并行框架及其應用

摘要&#xff1a;本文是騰訊深度學習系列文章之一&#xff0c;主要聚焦于騰訊深度學習平臺&#xff08;Tencent Deep Learning Platform&#xff09;中深度卷積神經網絡Deep CNNs的多GPU模型并行和數據并行框架。 【編者按】深度卷積神經網絡有著廣泛的應用場景&#xff0c;本…

如果誤刪谷歌瀏覽器的書簽,怎么恢復

如果是Mac用戶&#xff0c;command和z一直恢復就可以 同理&#xff0c;windows用戶&#xff0c;也可以使用撤銷鍵&#xff0c;ctrlz即可

55分鐘學會正則表達式

正則表達式是一種查找以及字符串替換操作。正則表達式在文本編輯器中廣泛使用&#xff0c;比如正則表達式被用于&#xff1a; 檢查文本中是否含有指定的特征詞找出文中匹配特征詞的位置從文本中提取信息&#xff0c;比如&#xff1a;字符串的子串修改文本 與文本編輯器相似&a…