FFmpeg結(jié)構(gòu)體: AVPacket

AVPacket 是什么羞反?

AVPacket是存儲壓縮編碼數(shù)據(jù)相關(guān)信息的結(jié)構(gòu)體

/**
 * 該結(jié)構(gòu)用來存儲壓縮數(shù)據(jù). 這是典型的解復(fù)合器的輸出然后塞入解碼器科吭,或者是接收編碼器的輸出然后塞入復(fù)合器
 *
 * 解復(fù)合器 --> AVPacket --> 解碼器 --> YUV/RGB --> 編碼器 --> AVPacket -->復(fù)合器
 *
 * 對視頻而言, 它通常包含一個壓縮幀. 對音頻而言,則它可能包含多個壓縮幀. 
 * 編碼器允許輸出一個空包, 沒有壓縮數(shù)據(jù), 僅包含側(cè)數(shù)據(jù)浑此。
 * (例如在編碼結(jié)束時更新一些流參數(shù))
 *
 * AVPacket是FFmpeg少數(shù)幾個結(jié)構(gòu)之一, 其大小是公共ABI的一部分.
 *
 * 數(shù)據(jù)所有權(quán)的語義取決于buf域.
 * 如果被設(shè)置, 分組數(shù)據(jù)動態(tài)分配累颂,且永遠(yuǎn)有效,直到一個叫av_packet_unref()減少引用計數(shù)為0時才被釋放
 *
 * 如果buf域沒有被設(shè)置凛俱,那么av_packet_ref()將做一個復(fù)制而不會增加引用計數(shù)
 *
 * 附加數(shù)據(jù)始終由av_malloc()分配內(nèi)存, 由av_packet_ref()進(jìn)行拷貝紊馏,由av_packet_unref()執(zhí)行釋放.
 *
 * @瀏覽 av_packet_ref()
 * @瀏覽 av_packet_unref()
 */
typedef struct AVPacket 
{
    // 用來管理data指針引用的數(shù)據(jù)緩存的
    // 為NULL時,那么數(shù)據(jù)包是不計數(shù)的
    AVBufferRef *buf;
 
    // 顯示時間戳, 對應(yīng)時間戳AVStream->time_base單元; 這個時間點(diǎn), 解壓縮的數(shù)據(jù)包將被提交給用戶
    // 如果時間不被存儲在文件里, 則可以寫成AV_NOPTS_VALUE
    // pts必須大于或等于dts, 因?yàn)轱@示不能在解壓縮之前被發(fā)生, 除非有人想查看十六進(jìn)制存儲最冰。
    // 某些格式誤用了這個名詞dts或者是pts/cts那是意味著別的意思, 所以時間戳必須在被存儲到AVPacket之前轉(zhuǎn)換成真正的PTS/DTS瘦棋。
    int64_t pts;
 
    // 解碼時間戳, 對應(yīng)時間戳AVStream->time_base單元; 這個時間點(diǎn), 數(shù)據(jù)包被解碼
    // 如果時間不被存儲在文件里, 則可以寫成AV_NOPTS_VALUE
    int64_t dts;
 
    // 存儲的數(shù)據(jù),指向一個緩存,這是AVPacket實(shí)際的數(shù)據(jù)
    uint8_t *data;
 
    // 數(shù)據(jù)的大小
    int size;
    
    // 標(biāo)識該AVPacket所屬的音頻/視頻流的索引
    int stream_index;
    
    // 一個AV_PKT_FLAG標(biāo)識值, 最低為置1表示關(guān)鍵幀
    int flags;
 
    // 容器可以提供的附加數(shù)據(jù)
    // 包可以包含幾種AVPacketSideDataType類型的側(cè)信息
    AVPacketSideData *side_data;
 
    // 附加信息元素
    int side_data_elems;
 
    // 數(shù)據(jù)的時長,以所屬媒體流的時間基準(zhǔn)為單位
    int64_t duration;
 
    // 該數(shù)據(jù)在媒體流中的字節(jié)偏移量
    int64_t pos;
 
    // 該字段不再使用
#if FF_API_CONVERGENCE_DURATION
    attribute_deprecated
    int64_t convergence_duration;
#endif
 
} AVPacket;

重要的變量
在AVPacket結(jié)構(gòu)體中,重要的變量有以下幾個:

  1. uint8_t *data:壓縮編碼的數(shù)據(jù)暖哨。
    例如對于H.264來說赌朋。1個AVPacket的data通常對應(yīng)一個NAL。
    注意:在這里只是對應(yīng)篇裁,而不是一模一樣沛慢。他們之間有微小的差別:使用FFMPEG類庫分離出多媒體文件中的H.264碼流
    因此在使用FFMPEG進(jìn)行視音頻處理的時候,常炒锊迹可以將得到的AVPacket的data數(shù)據(jù)直接寫成文件团甲,從而得到視音頻的碼流文件。
  2. int size:data的大小
  3. int64_t pts:顯示時間戳
  4. int64_t dts:解碼時間戳
  5. int stream_index:標(biāo)識該AVPacket所屬的視頻/音頻流黍聂。

容器
AVPacket實(shí)際上可用看作一個容器躺苦,它本身并不包含壓縮的媒體數(shù)據(jù),而是通過data指針引用數(shù)據(jù)的緩存空間产还。
所以將一個Packet作為參數(shù)傳遞的時候匹厘,就要根據(jù)具體的需要,對data引用的這部分?jǐn)?shù)據(jù)緩存空間進(jìn)行特殊的處理脐区。

當(dāng)從一個Packet去創(chuàng)建另一個Packet的時候愈诚,有兩種情況:

  1. 兩個Packet的data引用的是同一數(shù)據(jù)緩存空間,這時候要注意數(shù)據(jù)緩存空間的釋放問題牛隅;
  2. 兩個Packet的data引用不同的數(shù)據(jù)緩存空間炕柔,每個Packet都有數(shù)據(jù)緩存空間的copy;

第二種情況媒佣,數(shù)據(jù)空間的管理比較簡單匕累,但是數(shù)據(jù)實(shí)際上有多個copy造成內(nèi)存空間的浪費(fèi)。
所以要根據(jù)具體的需要默伍,來選擇到底是兩個Packet共享一個數(shù)據(jù)緩存空間欢嘿,還是每個Packet擁有自己獨(dú)自的緩存空間授霸。

引用計數(shù)
對于多個Packet共享同一個緩存空間,F(xiàn)Fmpeg使用的引用計數(shù)的機(jī)制(reference-count):
當(dāng)有新的Packet引用共享的緩存空間時际插,就將引用計數(shù)+1碘耳;
當(dāng)釋放了引用共享空間的Packet,就將引用計數(shù)-1框弛;引用計數(shù)為0時辛辨,就釋放掉引用的緩存空間。

而類AVBufferRef就是用來管理引用機(jī)制的:

typedef struct AVBufferRef {
    AVBuffer *buffer;
 
    /**
     * The data buffer. It is considered writable if and only if
     * this is the only reference to the buffer, in which case
     * av_buffer_is_writable() returns 1.
     */
    uint8_t *data;
    /**
     * Size of data in bytes.
     */
    int      size;
} AVBufferRef;

其中瑟枫,AVPacket會使用兩個函數(shù):

  1. int av_packet_ref(AVPacket *dst, const AVPacket *src):
    可以理解為使用引用計數(shù)的淺拷貝斗搞。
    該函數(shù)會先拷貝所有非緩存類數(shù)據(jù),
    然后創(chuàng)建一個src->data的新的引用計數(shù)慷妙。如果src已經(jīng)設(shè)置了引用計數(shù)發(fā)(src->buffer不為空)僻焚,則直接將其引用計數(shù)+1;
    如果src沒有設(shè)置引用計數(shù)(src->buffer為空)膝擂,則為dst創(chuàng)建一個新的引用計數(shù)buf虑啤,并復(fù)制src->data到buf->buffer中。最后架馋,復(fù)制src的其他字段到dst中狞山。所以av_packet_ref()是將2個AVPacket共用一個緩存的。

  2. void av_packet_unref(AVPacket *pkt):
    可以理解為使用引用計數(shù)的數(shù)據(jù)清理叉寂。
    將緩存空間的引用計數(shù)-1萍启,并將Packet中的其他字段設(shè)為初始值。如果引用計數(shù)為0屏鳍,自動的釋放緩存空間勘纯。所以,有兩個Packet共享同一個數(shù)據(jù)緩存空間的時候可用這么做钓瞭。

參考

https://blog.csdn.net/leixiaohua1020/article/details/14215755
https://blog.csdn.net/davidsguo008/article/details/72628675

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末驳遵,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子降淮,更是在濱河造成了極大的恐慌超埋,老刑警劉巖搏讶,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佳鳖,死亡現(xiàn)場離奇詭異,居然都是意外死亡媒惕,警方通過查閱死者的電腦和手機(jī)系吩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妒蔚,“玉大人穿挨,你說我怎么就攤上這事月弛。” “怎么了科盛?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵帽衙,是天一觀的道長。 經(jīng)常有香客問我贞绵,道長厉萝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任榨崩,我火速辦了婚禮谴垫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘母蛛。我一直安慰自己翩剪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布彩郊。 她就那樣靜靜地躺著前弯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪秫逝。 梳的紋絲不亂的頭發(fā)上博杖,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機(jī)與錄音筷登,去河邊找鬼剃根。 笑死,一個胖子當(dāng)著我的面吹牛前方,可吹牛的內(nèi)容都是我干的狈醉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼惠险,長吁一口氣:“原來是場噩夢啊……” “哼苗傅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起班巩,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤渣慕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后抱慌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逊桦,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年抑进,在試婚紗的時候發(fā)現(xiàn)自己被綠了强经。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡寺渗,死狀恐怖匿情,靈堂內(nèi)的尸體忽然破棺而出兰迫,到底是詐尸還是另有隱情,我是刑警寧澤炬称,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布汁果,位于F島的核電站,受9級特大地震影響玲躯,放射性物質(zhì)發(fā)生泄漏须鼎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一府蔗、第九天 我趴在偏房一處隱蔽的房頂上張望晋控。 院中可真熱鬧,春花似錦姓赤、人聲如沸赡译。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蝌焚。三九已至,卻和暖如春誓斥,著一層夾襖步出監(jiān)牢的瞬間只洒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工劳坑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毕谴,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓距芬,卻偏偏與公主長得像涝开,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子框仔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容