tv: remove some differences between immediate/normal mode

The immediate mode (which is the default) uses a tiny ringbuffer and
doesn't grab timestamps. This leads to quite bad behavior due to the
fact that there's an additional buffer between playloop and TV code (the
demuxer thread, which doesn't exist in MPlayer).

Always grab the timestamps and use a decently-sized buffer. I still have
no clue what I'm doing, and hacked it until it appeared to work. Report
regressions if you experience any.
This commit is contained in:
wm4 2014-10-25 17:56:29 +02:00
parent c6a1b8ebcc
commit 34f2970157
1 changed files with 23 additions and 38 deletions

View File

@ -1243,12 +1243,7 @@ static int start(priv_t *priv)
init_audio(priv); init_audio(priv);
if (priv->tv_param->audio && !priv->audio_initialized) return 0; if (priv->tv_param->audio && !priv->audio_initialized) return 0;
/* we need this to size the audio buffer properly */ priv->video_buffer_size_max = get_capture_buffer_size(priv);
if (priv->immediate_mode) {
priv->video_buffer_size_max = 2;
} else {
priv->video_buffer_size_max = get_capture_buffer_size(priv);
}
if (priv->tv_param->audio) { if (priv->tv_param->audio) {
setup_audio_buffer_sizes(priv); setup_audio_buffer_sizes(priv);
@ -1319,11 +1314,7 @@ static int start(priv_t *priv)
priv->video_cnt = 0; priv->video_cnt = 0;
/* request buffers */ /* request buffers */
if (priv->immediate_mode) { request.count = BUFFER_COUNT;
request.count = 2;
} else {
request.count = BUFFER_COUNT;
}
request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
request.memory = V4L2_MEMORY_MMAP; request.memory = V4L2_MEMORY_MMAP;
@ -1435,12 +1426,10 @@ static void *video_grabber(void *data)
{ {
int ret; int ret;
if (priv->immediate_mode) { while (priv->video_cnt == priv->video_buffer_size_max) {
while (priv->video_cnt == priv->video_buffer_size_max) { usleep(10000);
usleep(10000); if (priv->shutdown) {
if (priv->shutdown) { return NULL;
return NULL;
}
} }
} }
@ -1513,19 +1502,17 @@ static void *video_grabber(void *data)
interval = priv->curr_frame - priv->first_frame; interval = priv->curr_frame - priv->first_frame;
delta = interval - prev_interval; delta = interval - prev_interval;
if (!priv->immediate_mode) { // interpolate the skew in time
// interpolate the skew in time if (priv->tv_param->audio) pthread_mutex_lock(&priv->skew_mutex);
if (priv->tv_param->audio) pthread_mutex_lock(&priv->skew_mutex); xskew = priv->audio_skew + (interval - priv->audio_skew_measure_time)*priv->audio_skew_factor;
xskew = priv->audio_skew + (interval - priv->audio_skew_measure_time)*priv->audio_skew_factor; if (priv->tv_param->audio) pthread_mutex_unlock(&priv->skew_mutex);
if (priv->tv_param->audio) pthread_mutex_unlock(&priv->skew_mutex); // correct extreme skew changes to avoid (especially) moving backwards in time
// correct extreme skew changes to avoid (especially) moving backwards in time if (xskew - prev_skew > delta*MAX_SKEW_DELTA) {
if (xskew - prev_skew > delta*MAX_SKEW_DELTA) { skew = prev_skew + delta*MAX_SKEW_DELTA;
skew = prev_skew + delta*MAX_SKEW_DELTA; } else if (xskew - prev_skew < -delta*MAX_SKEW_DELTA) {
} else if (xskew - prev_skew < -delta*MAX_SKEW_DELTA) { skew = prev_skew - delta*MAX_SKEW_DELTA;
skew = prev_skew - delta*MAX_SKEW_DELTA; } else {
} else { skew = xskew;
skew = xskew;
}
} }
MP_TRACE(priv, "\nfps = %f, interval = %f, a_skew = %f, corr_skew = %f\n", MP_TRACE(priv, "\nfps = %f, interval = %f, a_skew = %f, corr_skew = %f\n",
@ -1553,17 +1540,15 @@ static void *video_grabber(void *data)
pthread_mutex_unlock(&priv->video_buffer_mutex); pthread_mutex_unlock(&priv->video_buffer_mutex);
if (priv->video_cnt == priv->video_buffer_size_current) { if (priv->video_cnt == priv->video_buffer_size_current) {
if (!priv->immediate_mode) { MP_ERR(priv, "\nvideo buffer full - dropping frame\n");
MP_ERR(priv, "\nvideo buffer full - dropping frame\n"); if (!priv->immediate_mode || priv->audio_insert_null_samples) {
if (priv->audio_insert_null_samples) { pthread_mutex_lock(&priv->audio_mutex);
pthread_mutex_lock(&priv->audio_mutex); priv->dropped_frames_timeshift += delta;
priv->dropped_frames_timeshift += delta; pthread_mutex_unlock(&priv->audio_mutex);
pthread_mutex_unlock(&priv->audio_mutex);
}
} }
} else { } else {
if (priv->immediate_mode) { if (priv->immediate_mode) {
priv->video_ringbuffer[priv->video_tail].timestamp = -1; priv->video_ringbuffer[priv->video_tail].timestamp = interval - skew;
} else { } else {
// compensate for audio skew // compensate for audio skew
// negative skew => there are more audio samples, increase interval // negative skew => there are more audio samples, increase interval