|
|
|
@ -15,8 +15,9 @@ VideoBuffer::~VideoBuffer()
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool VideoBuffer::init()
|
|
|
|
bool VideoBuffer::init(bool renderExpiredFrames)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
m_renderExpiredFrames = renderExpiredFrames;
|
|
|
|
m_decodingFrame = av_frame_alloc();
|
|
|
|
m_decodingFrame = av_frame_alloc();
|
|
|
|
if (!m_decodingFrame) {
|
|
|
|
if (!m_decodingFrame) {
|
|
|
|
goto error;
|
|
|
|
goto error;
|
|
|
|
@ -71,17 +72,17 @@ void VideoBuffer::offerDecodedFrame(bool& previousFrameSkipped)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_mutex.lock();
|
|
|
|
m_mutex.lock();
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef SKIP_FRAMES
|
|
|
|
if (m_renderExpiredFrames) {
|
|
|
|
// if SKIP_FRAMES is disabled, then the decoder must wait for the current
|
|
|
|
// if m_renderExpiredFrames is enable, then the decoder must wait for the current
|
|
|
|
// frame to be consumed
|
|
|
|
// frame to be consumed
|
|
|
|
while (!m_renderingFrameConsumed && !m_interrupted) {
|
|
|
|
while (!m_renderingFrameConsumed && !m_interrupted) {
|
|
|
|
m_renderingFrameConsumedCond.wait(&m_mutex);
|
|
|
|
m_renderingFrameConsumedCond.wait(&m_mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (m_fpsCounter.isStarted() && !m_renderingFrameConsumed) {
|
|
|
|
|
|
|
|
m_fpsCounter.addSkippedFrame();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
|
|
|
|
if (m_fpsCounter.isStarted() && !m_renderingFrameConsumed) {
|
|
|
|
|
|
|
|
m_fpsCounter.addSkippedFrame();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
swap();
|
|
|
|
swap();
|
|
|
|
previousFrameSkipped = !m_renderingFrameConsumed;
|
|
|
|
previousFrameSkipped = !m_renderingFrameConsumed;
|
|
|
|
@ -96,23 +97,23 @@ const AVFrame *VideoBuffer::consumeRenderedFrame()
|
|
|
|
if (m_fpsCounter.isStarted()) {
|
|
|
|
if (m_fpsCounter.isStarted()) {
|
|
|
|
m_fpsCounter.addRenderedFrame();
|
|
|
|
m_fpsCounter.addRenderedFrame();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#ifndef SKIP_FRAMES
|
|
|
|
if (m_renderExpiredFrames) {
|
|
|
|
// if SKIP_FRAMES is disabled, then notify the decoder the current frame is
|
|
|
|
// if m_renderExpiredFrames is enable, then notify the decoder the current frame is
|
|
|
|
// consumed, so that it may push a new one
|
|
|
|
// consumed, so that it may push a new one
|
|
|
|
m_renderingFrameConsumedCond.wakeOne();
|
|
|
|
m_renderingFrameConsumedCond.wakeOne();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
return m_renderingframe;
|
|
|
|
return m_renderingframe;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void VideoBuffer::interrupt()
|
|
|
|
void VideoBuffer::interrupt()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
#ifndef SKIP_FRAMES
|
|
|
|
if (m_renderExpiredFrames) {
|
|
|
|
m_mutex.lock();
|
|
|
|
m_mutex.lock();
|
|
|
|
m_interrupted = true;
|
|
|
|
m_interrupted = true;
|
|
|
|
m_mutex.unlock();
|
|
|
|
m_mutex.unlock();
|
|
|
|
// wake up blocking wait
|
|
|
|
// wake up blocking wait
|
|
|
|
m_renderingFrameConsumedCond.wakeOne();
|
|
|
|
m_renderingFrameConsumedCond.wakeOne();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void VideoBuffer::swap()
|
|
|
|
void VideoBuffer::swap()
|
|
|
|
|