最近在研究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為現在隊列中的幀數目