mirror of
https://github.com/mpv-player/mpv
synced 2025-01-17 04:22:41 +00:00
tv: use correct timestamps
Squashed from the following mplayer-svn commits. The '#' is removed from the bug ID to prevent github from doing something stupid. Instead of adding the mplayer configure check for clock_gettime(), the POSIX identifiers are used for checking presence of the function. Use correct type of timestamps when recording from v4l2. Fix 2176 Patch by Jarek Czekalski <jarekczek at poczta onet pl>. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@37222 b3059339-0415-0410-9bf9-f77b7e298cf2 Allow building of v4l2 without clock_gettime(). Add overly verbose message in case monotone timestamps are required by the kernel. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@37223 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
8f60de98be
commit
e302e1da58
@ -68,6 +68,13 @@ known issues:
|
||||
#define v4l2_munmap munmap
|
||||
#endif
|
||||
|
||||
// flag introduced in kernel 3.10
|
||||
#ifndef V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
|
||||
#define V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC 0x2000
|
||||
#endif
|
||||
|
||||
#define HAVE_CLOCK_GETTIME (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0)
|
||||
|
||||
#define info tvi_info_v4l2
|
||||
static tvi_handle_t *tvi_init_v4l2(struct mp_log *log, tv_param_t* tv_param);
|
||||
/* information about this file */
|
||||
@ -107,8 +114,10 @@ typedef struct priv {
|
||||
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;
|
||||
@ -495,6 +504,30 @@ static int getstd(priv_t *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if HAVE_CLOCK_GETTIME
|
||||
/*
|
||||
** 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;
|
||||
}
|
||||
#else
|
||||
/*
|
||||
** Gets current timestamp, using system time.
|
||||
** @return number of microseconds.
|
||||
*/
|
||||
static long long get_curr_timestamp(int clk_id)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return (long long)tv.tv_sec * 1000000 + tv.tv_usec;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************\
|
||||
* *
|
||||
* *
|
||||
@ -1366,6 +1399,13 @@ static int start(priv_t *priv)
|
||||
return 0;
|
||||
}
|
||||
priv->map[i].len = priv->map[i].buf.length;
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
priv->clk_id = (priv->map[i].buf.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC)
|
||||
? CLOCK_MONOTONIC : CLOCK_REALTIME;
|
||||
#else
|
||||
if (priv->map[i].buf.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC)
|
||||
mp_msg(MSGT_TV, MSGL_WARN, "MPlayer compiled without clock_gettime() that is needed to handle monotone video timestamps from the kernel. Expect desync.\n");
|
||||
#endif
|
||||
/* count up to make sure this is correct everytime */
|
||||
priv->mapcount++;
|
||||
|
||||
@ -1641,13 +1681,11 @@ static int get_video_framesize(priv_t *priv)
|
||||
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;
|
||||
@ -1661,21 +1699,19 @@ static void *audio_grabber(void *data)
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user