[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [27806] trunk/blender/source/gameengine/ VideoTexture: VideoTexture: fix video capture lagging when CPU is busy.

Benoit Bolsee benoit.bolsee at online.be
Sun Mar 28 19:50:45 CEST 2010


Revision: 27806
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27806
Author:   ben2610
Date:     2010-03-28 19:50:45 +0200 (Sun, 28 Mar 2010)

Log Message:
-----------
VideoTexture: fix video capture lagging when CPU is busy. This problem was caused by special frame handling that was appropriate for video streaming but not for video capture: drift compensation and no frame skipping.  Disable that for video capture to take into account the realtime nature of video.

Modified Paths:
--------------
    trunk/blender/source/gameengine/VideoTexture/VideoFFmpeg.cpp
    trunk/blender/source/gameengine/VideoTexture/VideoFFmpeg.h

Modified: trunk/blender/source/gameengine/VideoTexture/VideoFFmpeg.cpp
===================================================================
--- trunk/blender/source/gameengine/VideoTexture/VideoFFmpeg.cpp	2010-03-28 17:46:10 UTC (rev 27805)
+++ trunk/blender/source/gameengine/VideoTexture/VideoFFmpeg.cpp	2010-03-28 17:50:45 UTC (rev 27806)
@@ -56,7 +56,7 @@
 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;
@@ -298,6 +298,7 @@
  */
 void *VideoFFmpeg::cacheThread(void *data)
 {
+	static int count=0;
 	VideoFFmpeg* video = (VideoFFmpeg*)data;
 	// holds the frame that is being decoded
 	CacheFrame *currentFrame = NULL;
@@ -306,6 +307,8 @@
 	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;
+	long pts;
+
 	if (startTs == AV_NOPTS_VALUE)
 		startTs = 0;
 
@@ -396,6 +399,7 @@
 						// move frame to queue, this frame is necessarily the next one
 						video->m_curPosition = (long)((cachePacket->packet.dts-startTs) * (video->m_baseFrameRate*timeBase) + 0.5);
 						currentFrame->framePosition = video->m_curPosition;
+						pts = (long)((cachePacket->packet.pts-startTs) * (video->m_baseFrameRate*timeBase) + 0.5);
 						pthread_mutex_lock(&video->m_cacheMutex);
 						BLI_addtail(&video->m_frameCacheBase, currentFrame);
 						pthread_mutex_unlock(&video->m_cacheMutex);
@@ -544,8 +548,10 @@
 #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 +817,12 @@
 					// 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 +884,18 @@
 			}
 			// 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);

Modified: trunk/blender/source/gameengine/VideoTexture/VideoFFmpeg.h
===================================================================
--- trunk/blender/source/gameengine/VideoTexture/VideoFFmpeg.h	2010-03-28 17:46:10 UTC (rev 27805)
+++ trunk/blender/source/gameengine/VideoTexture/VideoFFmpeg.h	2010-03-28 17:50:45 UTC (rev 27806)
@@ -61,7 +61,7 @@
 
 #include "VideoBase.h"
 
-#define CACHE_FRAME_SIZE	5
+#define CACHE_FRAME_SIZE	10
 #define CACHE_PACKET_SIZE	30
 
 // type VideoFFmpeg declaration
@@ -153,6 +153,9 @@
 	/// is image loading done in a separate thread?
 	bool m_isThreaded;
 
+	/// is streaming or camera?
+	bool m_isStreaming;
+
 	/// keep last image name
 	STR_String m_imageName;
 





More information about the Bf-blender-cvs mailing list