天天看點

【C/C++開發】ffplay中的FrameQueue的自我了解

最近在研究ffplay,以下是本人今天在研究FrameQueue的時候整理的筆記,如有錯誤還請有心人指出來~

//這個隊列是一個循環隊列,windex是指其中的首元素,rindex是指其中的尾部元素.

typedef struct FrameQueue {

                 Frame queue[FRAME_QUEUE_SIZE ];

                 int rindex;//表示循環隊列的結尾處

                 int windex;//表示循環隊列的開始處

                 int size;

                 int max_size;

                 int keep_last;

                 int rindex_shown;//一開始為0,之後一直為1

                 SDL_mutex *mutex;

                 SDL_cond *cond;

                 PacketQueue *pktq;

} FrameQueue;

//表示FrameQueue的初始化主要是針對記憶體的處理,針對視訊來說,keep_last為1

static int frame_queue_init(FrameQueue *f, PacketQueue *pktq, int max_size, int keep_last)

{

int i;

memset(f, 0, sizeof(FrameQueue));

if (!(f->mutex = SDL_CreateMutex()))

return AVERROR(ENOMEM);

if (!(f->cond = SDL_CreateCond()))

f->pktq = pktq;

f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);

f->keep_last = !!keep_last;

for (i = 0; i < f->max_size; i++)

if (!(f->queue[i].frame = av_frame_alloc()))

return 0;

}

//表示從循環隊列幀裡面取出目前需要顯示的一幀視訊

static Frame *frame_queue_peek(FrameQueue * f)

                 return &f ->queue[(f->rindex

+ f->rindex_shown) % f ->max_size];

//表示從循環隊列幀裡面取出目前需要顯示的下哦i一幀視訊

static Frame *frame_queue_peek_next( FrameQueue * f )

                 return &f ->queue[( f->rindex

+ f ->rindex_shown + 1) % f ->max_size];

//傳回要填充的frame_queue中的Frame。

static Frame *frame_queue_peek_writable( FrameQueue * f )

                 /* wait until

we have space to put a new frame */

                SDL_LockMutex( f ->mutex);

                 while (f ->size

>= f->max_size &&

                       ! f ->pktq->abort_request)

                                SDL_CondWait( f ->cond, f ->mutex);

                }

                SDL_UnlockMutex( f ->mutex);

                 if (f ->pktq->abort_request)

                                 return NULL ;

                 return &f ->queue[ f->windex];

//放幀到隊列中(frame_queue_peek_writable)之後的參數操作,windex++

static void frame_queue_push( FrameQueue * f )

                 if (++f ->windex

== f->max_size)

                                 f ->windex

= 0;

                 f ->size++;

                SDL_CondSignal( f ->cond);

//從幀隊列中取出幀之後的參數操作,當rindex_show為0的時候使其變為1,否則--rindex

static void frame_queue_next( FrameQueue * f )

                 if (f ->keep_last

&& ! f->rindex_shown) {

                                 f ->rindex_shown

= 1;

                                 return ;

                frame_queue_unref_item(& f ->queue[f ->rindex]);

                 if (++f ->rindex

                                 f ->rindex

                 f ->size--;

其中size-rindex_shown為現在隊列中的幀數目