161 lines
3.2 KiB
C++
Raw Normal View History

2023-07-15 03:07:19 +08:00
#include "FFMPEGFrameQueue.h"
#include "FFMPEGFrame.h"
FFMPEGFrameQueue::FFMPEGFrameQueue()
{
for ( int i = 0; i < FRAME_QUEUE_SIZE; i++) {
queue[i] = new FFMPEGFrame();
}
rindex = 0;
windex = 0;
size = 0;
max_size = 0;
keep_last = 0;
rindex_shown = 0;
pktq = NULL;
}
FFMPEGFrameQueue::~FFMPEGFrameQueue()
{
Destroy();
for (int i = 0; i < FRAME_QUEUE_SIZE; i++) {
if ( queue[i] ) delete queue[i];
queue[i] = NULL;
}
}
int FFMPEGFrameQueue::Init( FFMPEGPacketQueue *_pktq, int _max_size, int _keep_last) {
this->pktq = _pktq;
this->max_size = FFMIN(_max_size, FRAME_QUEUE_SIZE);
this->keep_last = !!_keep_last;
for (int i = 0; i < this->max_size; i++)
if (!(queue[i]->Init()))
return AVERROR(ENOMEM);
return 0;
}
void FFMPEGFrameQueue::Destroy() {
for (int i = 0; i < max_size; i++) {
FFMPEGFrame *vp = queue[i];
if ( vp) vp->Destroy();
}
rindex = 0;
windex = 0;
size = 0;
max_size = 0;
keep_last = 0;
rindex_shown = 0;
pktq = NULL;
}
void FFMPEGFrameQueue::Signal() {
mutex.Lock();
cond.signal();
mutex.Unlock();
}
FFMPEGFrame *FFMPEGFrameQueue::Peek() {
return queue[(rindex + rindex_shown) % max_size];
}
FFMPEGFrame *FFMPEGFrameQueue::PeekNext() {
return queue[(rindex + rindex_shown + 1) % max_size];
}
FFMPEGFrame *FFMPEGFrameQueue::PeekLast() {
return queue[rindex];
}
FFMPEGFrame *FFMPEGFrameQueue::PeekWritable() {
mutex.Lock();
while (size >= max_size &&
!pktq->IsAbortRequest()) {
cond.wait(mutex);
}
mutex.Unlock();
if (pktq->IsAbortRequest())
return NULL;
return queue[windex];
}
FFMPEGFrame *FFMPEGFrameQueue::PeekReadable() {
mutex.Lock();
while (size - rindex_shown <= 0 &&
!pktq->IsAbortRequest()) {
cond.wait(mutex);
}
mutex.Unlock();
if (pktq->IsAbortRequest())
return NULL;
return queue[(rindex + rindex_shown) % max_size];
}
int FFMPEGFrameQueue::QueuePicture( AVFrame *src_frame, double pts, double duration, int64_t pos, int serial) {
FFMPEGFrame *vp = PeekWritable();
if (!vp )
return -1;
vp->UpdateFrame(src_frame, pts, duration, pos, serial);
av_frame_move_ref(vp->GetFrame(), src_frame);
Push();
return 0;
}
void FFMPEGFrameQueue::Push() {
if (++windex == max_size)
windex = 0;
mutex.Lock();
size++;
cond.signal();
mutex.Unlock();
}
void FFMPEGFrameQueue::Next() {
if (keep_last && !rindex_shown) {
rindex_shown = 1;
return;
}
queue[rindex]->UnRef();
if (++rindex == max_size)
rindex = 0;
mutex.Lock();
size--;
cond.signal();
mutex.Unlock();
}
void FFMPEGFrameQueue::Lock() {
mutex.Lock();
}
void FFMPEGFrameQueue::Unlock() {
mutex.Unlock();
}
int FFMPEGFrameQueue::GetNumRemaining() {
return size - rindex_shown;
}
int64_t FFMPEGFrameQueue::GetQueueLastPos() {
FFMPEGFrame *fp = queue[rindex];
if (rindex_shown && fp->GetSerial() == pktq->GetSerial())
return fp->GetPos();
else
return -1;
}
int FFMPEGFrameQueue::GetIndexShown() {
return rindex_shown;
}