buffer.c中的AVBufferPool閱讀筆記

調用av_buffer_pool_init函數

得到AVBufferPool指針pool, pool的refcount爲1,pool的pool變量值爲NULL,pool的nb_allocated爲0。


調用av_buffer_pool_get函數
    調用get_pool返回NULL
    !buf 成立,但refcount = 1 不小等於 nb_allocated (0),所以不進入if內。
    由於!buf成立,返回pool_alloc_buffer返回值。在pool_alloc_buffer函數中創建一個
    BufferPoolEntry實例,此實例的data指向新申請的內存空間,pool指針指向AVBufferPool。
    pool的refcount爲2,pool的nb_allocated爲1。BufferPoolEntry指針賦值給AVBufferRef的buffer->opaque。
    ret->buffer->free   = pool_release_buffer;此句是關鍵,在buffer被free的時候,其又將free數據項的操作
    交給了pool_release_buffer,而pool正是在此將申請的實際數據緩存存放到了pool的鏈表中。


調用av_buffer_unref函數
    將AVBuffer及AVBufferRef結構體對應的內存空間都釋放掉,在釋放數據時,實際調用pool_release_buffer函數。
    pool_release_buffer函數中,又調用add_to_pool將BufferPoolEntry(指向的數據)指針存放到pool中。
    add_to_pool函數在代碼avpriv_atomic_ptr_cas((void * volatile *)&pool->pool, NULL, buf)中處理當pool爲NULL,則
    使pool->pool指向buf。如果pool->pool不爲NULL,則進入while內操作,如果此data buffer是新申請出的,則最後完成的
    鏈表連接順序是  1    2->1    3->2->1    4->3->2->1     其中pool->pool指向最後一次使用的BufferPoolEntry。
 
再調用av_buffer_pool_get函數
    get_pool返回不爲NULL,然後調用add_to_pool(buf->next)將pool設置爲buf的next。如原來如果是4->3->2->1 則get_pool函數返回了4,
    然後順序變成3->2->1。然後調用av_buffer_create函數使用此數據創建AVBuffer及AVBufferRef,然後返回。




pool的總體思路是:
如果pool中沒有buf數據,則新建。
buf使用完後,實際數據返回到pool中,由pool將buf鏈接起來。
如果再取數據,如果pool中有buf,則使用pool中的數據buf創建。




巧妙點:
1、將buffer的釋放數據的操作由指針函數完成,平時此指針函數默認爲av_buffer_default_free,用在pool時,此值爲pool_release_buffer。
2、通過給AVBuffer結構體定義一個opaque(模糊不確定)變量,然後將BufferPoolEntry指針存放在此opaque中,在調用AVBuffer的free函數時再
   作爲參數傳遞。所以AVBuffer結構體的設計很巧妙。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章