Mercurial > mplayer.hg
changeset 37126:6db1f7a10803
Use correct type of timestamps when recording from v4l2. Fix #2176
Patch by Jarek Czekalski <jarekczek at poczta onet pl>.
author | iive |
---|---|
date | Tue, 10 Jun 2014 15:41:02 +0000 |
parents | 1236e38abf90 |
children | ca7e13830a05 |
files | stream/tvi_v4l2.c |
diffstat | 1 files changed, 28 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/stream/tvi_v4l2.c Tue Jun 10 13:37:20 2014 +0000 +++ b/stream/tvi_v4l2.c Tue Jun 10 15:41:02 2014 +0000 @@ -63,6 +63,11 @@ #include "tv.h" #include "audio_in.h" +// flag introduced in kernel 3.10 +#ifndef V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC +#define V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC 0x2000 +#endif + #define info tvi_info_v4l2 static tvi_handle_t *tvi_init_v4l2(tv_param_t* tv_param); /* information about this file */ @@ -109,8 +114,10 @@ struct map *map; int mapcount; int frames; - volatile long long first_frame; - long long curr_frame; + volatile long long first_frame; ///< number of useconds + long long curr_frame; ///< usec, using kernel timestamps + int clk_id; /**< clk_id from clock_gettime + used in frame timestamps */ /* audio video interleaving ;-) */ volatile int streamon; pthread_t audio_grabber_thread; @@ -488,6 +495,17 @@ return 0; } +/* +** Gets current timestamp, using specified clock id. +** @return number of microseconds. +*/ +static long long get_curr_timestamp(int clk_id) +{ + struct timespec ts; + clock_gettime(clk_id, &ts); + return (long long)ts.tv_sec * 1000000 + ts.tv_nsec / 1000; +} + /***********************************************************************\ * * * * @@ -1531,6 +1549,8 @@ return 0; } priv->map[i].len = priv->map[i].buf.length; + priv->clk_id = (priv->map[i].buf.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC) + ? CLOCK_MONOTONIC : CLOCK_REALTIME; /* count up to make sure this is correct everytime */ priv->mapcount++; @@ -1834,13 +1854,11 @@ static void *audio_grabber(void *data) { priv_t *priv = (priv_t*)data; - struct timeval tv; int i, audio_skew_ptr = 0; long long current_time, prev_skew = 0, prev_skew_uncorr = 0; - long long start_time_avg; + long long start_time_avg, curr_timestamp; - gettimeofday(&tv, NULL); - start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec; + start_time_avg = priv->audio_start_time = get_curr_timestamp(priv->clk_id); audio_in_start_capture(&priv->audio_in); for (i = 0; i < priv->aud_skew_cnt; i++) priv->audio_skew_buffer[i] = 0; @@ -1858,21 +1876,19 @@ pthread_mutex_lock(&priv->skew_mutex); if (priv->first_frame == 0) { // there is no first frame yet (unlikely to happen) - gettimeofday(&tv, NULL); - start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec; + start_time_avg = priv->audio_start_time = get_curr_timestamp(priv->clk_id); // fprintf(stderr, "warning - first frame not yet available!\n"); pthread_mutex_unlock(&priv->skew_mutex); continue; } pthread_mutex_unlock(&priv->skew_mutex); - gettimeofday(&tv, NULL); - priv->audio_recv_blocks_total++; - current_time = (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_start_time; + curr_timestamp = get_curr_timestamp(priv->clk_id); + current_time = curr_timestamp - priv->audio_start_time; if (priv->audio_recv_blocks_total < priv->aud_skew_cnt*2) { - start_time_avg += (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_usecs_per_block*priv->audio_recv_blocks_total; + start_time_avg += curr_timestamp - priv->audio_usecs_per_block*priv->audio_recv_blocks_total; priv->audio_start_time = start_time_avg/(priv->audio_recv_blocks_total+1); }