diff options
Diffstat (limited to 'source/gameengine/VideoTexture/VideoFFmpeg.cpp')
-rw-r--r-- | source/gameengine/VideoTexture/VideoFFmpeg.cpp | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 6f7e9b82911..5a80522ea7d 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -23,7 +23,9 @@ http://www.gnu.org/copyleft/lesser.txt. #ifdef WITH_FFMPEG // INT64_C fix for some linux machines (C99ism) +#ifndef __STDC_CONSTANT_MACROS #define __STDC_CONSTANT_MACROS +#endif #include <stdint.h> @@ -56,7 +58,7 @@ m_frame(NULL), m_frameDeinterlaced(NULL), m_frameRGB(NULL), m_imgConvertCtx(NULL m_deinterlace(false), m_preseek(0), m_videoStream(-1), m_baseFrameRate(25.0), m_lastFrame(-1), m_eof(false), m_externTime(false), m_curPosition(-1), m_startTime(0), m_captWidth(0), m_captHeight(0), m_captRate(0.f), m_isImage(false), -m_isThreaded(false), m_stopThread(false), m_cacheStarted(false) +m_isThreaded(false), m_isStreaming(false), m_stopThread(false), m_cacheStarted(false) { // set video format m_format = RGB24; @@ -306,6 +308,7 @@ void *VideoFFmpeg::cacheThread(void *data) int frameFinished = 0; double timeBase = av_q2d(video->m_formatCtx->streams[video->m_videoStream]->time_base); int64_t startTs = video->m_formatCtx->streams[video->m_videoStream]->start_time; + if (startTs == AV_NOPTS_VALUE) startTs = 0; @@ -544,8 +547,10 @@ void VideoFFmpeg::openFile (char * filename) #endif ) { - // the file is in fact a streaming source, prevent seeking + // the file is in fact a streaming source, treat as cam to prevent seeking m_isFile = false; + // but it's not handled exactly like a camera. + m_isStreaming = true; // for streaming it is important to do non blocking read m_formatCtx->flags |= AVFMT_FLAG_NONBLOCK; } @@ -811,12 +816,12 @@ void VideoFFmpeg::calcImage (unsigned int texId, double ts) // close the file as we don't need it anymore release(); } - } else if (!m_isFile) + } else if (m_isStreaming) { // we didn't get a frame and we are streaming, this may be due to // a delay in the network or because we are getting the frame too fast. // In the later case, shift time by a small amount to compensate for a drift - m_startTime += 0.01; + m_startTime += 0.001; } } } @@ -878,14 +883,18 @@ AVFrame *VideoFFmpeg::grabFrame(long position) } // for streaming, always return the next frame, // that's what grabFrame does in non cache mode anyway. - if (!m_isFile || frame->framePosition == position) + if (m_isStreaming || frame->framePosition == position) { return frame->frame; } - if (frame->framePosition > position) + // for cam, skip old frames to keep image realtime. + // There should be no risk of clock drift since it all happens on the same CPU + if (frame->framePosition > position) + { // this can happen after rewind if the seek didn't find the first frame // the frame in the buffer is ahead of time, just leave it there return NULL; + } // this frame is not useful, release it pthread_mutex_lock(&m_cacheMutex); BLI_remlink(&m_frameCacheBase, frame); @@ -930,7 +939,6 @@ AVFrame *VideoFFmpeg::grabFrame(long position) if (position != m_curPosition + 1) { int64_t pos = (int64_t)((position - m_preseek) / (m_baseFrameRate*timeBase)); - int seekres; if (pos < 0) pos = 0; |