最近在研究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()))
return AVERROR(ENOMEM);
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 AVERROR(ENOMEM);
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;
SDL_LockMutex(
f
->mutex);
f
->size++;
SDL_CondSignal(
f
->cond);
SDL_UnlockMutex(
f
->mutex);
}
//从帧队列中取出帧之后的参数操作,当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
->max_size)
f
->rindex = 0;
SDL_LockMutex(
f
->mutex);
f
->size--;
SDL_CondSignal(
f
->cond);
SDL_UnlockMutex(
f
->mutex);
}
其中size-rindex_shown为现在队列中的帧数目