[Mplayer-cvslog] CVS: main/libmpdemux tvi_v4l.c,1.54,1.55
Jindrich Makovicka CVS
henry at mplayerhq.hu
Sat Mar 15 23:03:25 CET 2003
Update of /cvsroot/mplayer/main/libmpdemux
In directory mail:/var/tmp.root/cvs-serv8465
Modified Files:
tvi_v4l.c
Log Message:
correct small framerate fluctuations directly in the capture thread
Index: tvi_v4l.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/tvi_v4l.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -r1.54 -r1.55
--- tvi_v4l.c 2 Feb 2003 02:36:35 -0000 1.54
+++ tvi_v4l.c 15 Mar 2003 22:02:54 -0000 1.55
@@ -60,6 +60,7 @@
#define MAX_AUDIO_CHANNELS 10
#define VID_BUF_SIZE_IMMEDIATE 2
+#define VIDEO_AVG_BUFFER_SIZE 300
typedef struct {
/* general */
@@ -111,6 +112,9 @@
volatile int video_buffer_size_current;
unsigned char **video_ringbuffer;
long long *video_timebuffer;
+ long long *video_avg_buffer;
+ int video_avg_ptr;
+ int video_interval_sum;
volatile int video_head;
volatile int video_tail;
volatile int video_cnt;
@@ -404,6 +408,7 @@
priv->video_ringbuffer = NULL;
priv->video_timebuffer = NULL;
+ priv->video_avg_buffer = NULL;
priv->audio_ringbuffer = NULL;
priv->audio_skew_buffer = NULL;
@@ -582,6 +587,8 @@
if (priv->video_timebuffer)
free(priv->video_timebuffer);
+ if (priv->video_avg_buffer)
+ free(priv->video_avg_buffer);
if (!tv_param_noaudio) {
if (priv->audio_ringbuffer)
free(priv->audio_ringbuffer);
@@ -762,6 +769,18 @@
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate time buffer: %s\n", strerror(errno));
return 0;
}
+ priv->video_avg_buffer = (long long*)malloc(sizeof(long long) * VIDEO_AVG_BUFFER_SIZE);
+ if (!priv->video_avg_buffer) {
+ mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate period buffer: %s\n", strerror(errno));
+ return 0;
+ }
+ priv->video_interval_sum = (1e6/priv->fps)*VIDEO_AVG_BUFFER_SIZE;
+ for (i = 0; i < VIDEO_AVG_BUFFER_SIZE; i++) {
+ priv->video_avg_buffer[i] = 1e6/priv->fps;
+ }
+
+ priv->video_avg_ptr = 0;
+
priv->video_head = 0;
priv->video_tail = 0;
priv->video_cnt = 0;
@@ -1243,6 +1262,7 @@
int i;
int first = 1;
int framecount;
+ int tolerance;
/* start the capture process */
@@ -1256,6 +1276,8 @@
prev_interval = 0;
prev_skew = 0;
+ tolerance = priv->nbuf*2;
+
for (framecount = 0; !priv->shutdown;)
{
for (i = 0; i < priv->nbuf && !priv->shutdown; i++, framecount++) {
@@ -1302,6 +1324,25 @@
mp_msg(MSGT_TV, MSGL_V, "\nvideo capture thread: frame delta ~ %.1lf fps\n",
(double)1e6/(interval - prev_interval));
}
+
+ // correct the rate fluctuations on a small scale
+ if ((interval - prev_interval < (long long)0.95e6/priv->fps)
+ || (interval - prev_interval > (long long)1.05e6/priv->fps) ) {
+ if (tolerance > 0) {
+ mp_msg(MSGT_TV, MSGL_DBG3, "correcting timestamp\n");
+ interval = prev_interval + priv->video_interval_sum/VIDEO_AVG_BUFFER_SIZE;
+ tolerance--;
+ } else {
+ mp_msg(MSGT_TV, MSGL_DBG3, "bad - frames were dropped\n");
+ tolerance = priv->nbuf*2;
+ }
+ } else {
+ if (tolerance < priv->nbuf*2) {
+ mp_msg(MSGT_TV, MSGL_DBG3, "fluctuation overcome\n");
+ }
+ tolerance = priv->nbuf*2;
+ }
+
}
// interpolate the skew in time
@@ -1323,9 +1364,14 @@
(double)1e-6*interval, (double)1e-6*xskew, (double)1e-6*skew);
mp_msg(MSGT_TV, MSGL_DBG3, "vcnt = %d, acnt = %d\n", priv->video_cnt, priv->audio_cnt);
+ priv->video_interval_sum -= priv->video_avg_buffer[priv->video_avg_ptr];
+ priv->video_avg_buffer[priv->video_avg_ptr++] = interval-prev_interval;
+ priv->video_interval_sum += interval-prev_interval;
+ if (priv->video_avg_ptr >= VIDEO_AVG_BUFFER_SIZE) priv->video_avg_ptr = 0;
+
prev_skew = skew;
prev_interval = interval;
-
+
/* allocate a new buffer, if needed */
pthread_mutex_lock(&priv->video_buffer_mutex);
if (priv->video_buffer_size_current < priv->video_buffer_size_max) {
More information about the MPlayer-cvslog
mailing list