Commit ca4846fe authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

aout: factor out mdate() from the time_get() callback

parent 2d66a357
...@@ -150,11 +150,10 @@ struct audio_output ...@@ -150,11 +150,10 @@ struct audio_output
/**< Stops the existing stream (optional, may be NULL). /**< Stops the existing stream (optional, may be NULL).
* \note A stream must have been started when called. * \note A stream must have been started when called.
*/ */
int (*time_get)(audio_output_t *, mtime_t *write_pts); int (*time_get)(audio_output_t *, mtime_t *delay);
/**< Estimates the date/time of the playback buffer write offset /**< Estimates playback buffer latency (optional, may be NULL).
* (optional, may be NULL). The read offset is not returned since it is * \param delay pointer to the delay until the next sample to be written
* always implicitly equal to the current time (mdate()). * to the playback buffer is rendered [OUT]
* \param write_pts timestamp of the write offset [OUT]
* \return 0 on success, non-zero on failure or lack of data * \return 0 on success, non-zero on failure or lack of data
* \note A stream must have been started when called. * \note A stream must have been started when called.
*/ */
......
...@@ -520,7 +520,7 @@ error: ...@@ -520,7 +520,7 @@ error:
return VLC_EGENERIC; return VLC_EGENERIC;
} }
static int TimeGet (audio_output_t *aout, mtime_t *restrict pts) static int TimeGet (audio_output_t *aout, mtime_t *restrict delay)
{ {
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
snd_pcm_sframes_t frames; snd_pcm_sframes_t frames;
...@@ -531,7 +531,7 @@ static int TimeGet (audio_output_t *aout, mtime_t *restrict pts) ...@@ -531,7 +531,7 @@ static int TimeGet (audio_output_t *aout, mtime_t *restrict pts)
msg_Err (aout, "cannot estimate delay: %s", snd_strerror (val)); msg_Err (aout, "cannot estimate delay: %s", snd_strerror (val));
return -1; return -1;
} }
*pts = mdate () + (frames * CLOCK_FREQ / sys->format.i_rate); *delay = frames * CLOCK_FREQ / sys->format.i_rate;
return 0; return 0;
} }
......
...@@ -149,8 +149,7 @@ static int TimeGet(audio_output_t* p_aout, mtime_t* restrict drift) ...@@ -149,8 +149,7 @@ static int TimeGet(audio_output_t* p_aout, mtime_t* restrict drift)
return -1; return -1;
} }
if (delay && st.count) *drift = (delay && st.count) ? delay : 0;
*drift = mdate() + delay;
return 0; return 0;
} }
......
...@@ -324,8 +324,8 @@ static int TimeGet (audio_output_t *aout, mtime_t *restrict pts) ...@@ -324,8 +324,8 @@ static int TimeGet (audio_output_t *aout, mtime_t *restrict pts)
return -1; return -1;
} }
*pts = mdate () + ((delay * CLOCK_FREQ * sys->format.i_frame_length) *pts = (delay * CLOCK_FREQ * sys->format.i_frame_length)
/ (sys->format.i_rate * sys->format.i_bytes_per_frame)); / (sys->format.i_rate * sys->format.i_bytes_per_frame);
return 0; return 0;
} }
......
...@@ -157,18 +157,20 @@ void aout_PacketDestroy (audio_output_t *aout) ...@@ -157,18 +157,20 @@ void aout_PacketDestroy (audio_output_t *aout)
vlc_mutex_destroy (&p->lock); vlc_mutex_destroy (&p->lock);
} }
int aout_PacketTimeGet (audio_output_t *aout, mtime_t *restrict pts) int aout_PacketTimeGet (audio_output_t *aout, mtime_t *restrict delay)
{ {
aout_packet_t *p = aout_packet (aout); aout_packet_t *p = aout_packet (aout);
mtime_t time_report; mtime_t time_report;
/* Problem: This measurement is imprecise and prone to jitter.
* Solution: Do not use aout_Packet...(). */
vlc_mutex_lock (&p->lock); vlc_mutex_lock (&p->lock);
time_report = date_Get (&p->fifo.end_date); time_report = date_Get (&p->fifo.end_date);
vlc_mutex_unlock (&p->lock); vlc_mutex_unlock (&p->lock);
if (time_report == VLC_TS_INVALID) if (time_report == VLC_TS_INVALID)
return -1; return -1;
*pts = time_report; *delay = time_report - mdate ();
return 0; return 0;
} }
......
...@@ -426,7 +426,7 @@ static void sink_input_info_cb(pa_context *ctx, const pa_sink_input_info *i, ...@@ -426,7 +426,7 @@ static void sink_input_info_cb(pa_context *ctx, const pa_sink_input_info *i,
/*** VLC audio output callbacks ***/ /*** VLC audio output callbacks ***/
static int TimeGet(audio_output_t *aout, mtime_t *restrict write_pts) static int TimeGet(audio_output_t *aout, mtime_t *restrict delay)
{ {
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
pa_stream *s = sys->stream; pa_stream *s = sys->stream;
...@@ -438,7 +438,7 @@ static int TimeGet(audio_output_t *aout, mtime_t *restrict write_pts) ...@@ -438,7 +438,7 @@ static int TimeGet(audio_output_t *aout, mtime_t *restrict write_pts)
if (delta == VLC_TS_INVALID) if (delta == VLC_TS_INVALID)
return -1; return -1;
*write_pts = mdate() + delta; *delay = delta;
return 0; return 0;
} }
......
...@@ -197,7 +197,7 @@ static void PositionChanged (void *arg, int delta) ...@@ -197,7 +197,7 @@ static void PositionChanged (void *arg, int delta)
sys->read_offset += delta; sys->read_offset += delta;
} }
static int TimeGet (audio_output_t *aout, mtime_t *restrict pts) static int TimeGet (audio_output_t *aout, mtime_t *restrict delay)
{ {
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
long long frames = sys->write_offset - sys->read_offset; long long frames = sys->write_offset - sys->read_offset;
...@@ -205,7 +205,7 @@ static int TimeGet (audio_output_t *aout, mtime_t *restrict pts) ...@@ -205,7 +205,7 @@ static int TimeGet (audio_output_t *aout, mtime_t *restrict pts)
if (frames == 0) if (frames == 0)
return -1; return -1;
*pts = mdate () + (frames * CLOCK_FREQ / sys->rate); *delay = frames * CLOCK_FREQ / sys->rate;
return 0; return 0;
} }
......
...@@ -135,7 +135,7 @@ struct aout_sys_t ...@@ -135,7 +135,7 @@ struct aout_sys_t
/*** VLC audio output callbacks ***/ /*** VLC audio output callbacks ***/
static int TimeGet(audio_output_t *aout, mtime_t *restrict pts) static int TimeGet(audio_output_t *aout, mtime_t *restrict delay)
{ {
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
UINT64 pos, qpcpos; UINT64 pos, qpcpos;
...@@ -159,10 +159,8 @@ static int TimeGet(audio_output_t *aout, mtime_t *restrict pts) ...@@ -159,10 +159,8 @@ static int TimeGet(audio_output_t *aout, mtime_t *restrict pts)
return -1; return -1;
} }
mtime_t delay = ((GetQPC() - qpcpos) / (10000000 / CLOCK_FREQ)); *delay = ((GetQPC() - qpcpos) / (10000000 / CLOCK_FREQ));
static_assert((10000000 % CLOCK_FREQ) == 0, "Frequency conversion broken"); static_assert((10000000 % CLOCK_FREQ) == 0, "Frequency conversion broken");
*pts = mdate() + delay;
return 0; return 0;
} }
......
...@@ -267,7 +267,7 @@ static void aout_DecSynchronize (audio_output_t *aout, mtime_t dec_pts, ...@@ -267,7 +267,7 @@ static void aout_DecSynchronize (audio_output_t *aout, mtime_t dec_pts,
int input_rate) int input_rate)
{ {
aout_owner_t *owner = aout_owner (aout); aout_owner_t *owner = aout_owner (aout);
mtime_t aout_pts, drift; mtime_t drift;
/** /**
* Depending on the drift between the actual and intended playback times, * Depending on the drift between the actual and intended playback times,
...@@ -285,9 +285,9 @@ static void aout_DecSynchronize (audio_output_t *aout, mtime_t dec_pts, ...@@ -285,9 +285,9 @@ static void aout_DecSynchronize (audio_output_t *aout, mtime_t dec_pts,
* all samples in the buffer will have been played. Then: * all samples in the buffer will have been played. Then:
* pts = mdate() + delay * pts = mdate() + delay
*/ */
if (aout_OutputTimeGet (aout, &aout_pts) != 0) if (aout_OutputTimeGet (aout, &drift) != 0)
return; /* nothing can be done if timing is unknown */ return; /* nothing can be done if timing is unknown */
drift = aout_pts - dec_pts; drift += mdate () - dec_pts;
/* Late audio output. /* Late audio output.
* This can happen due to insufficient caching, scheduling jitter * This can happen due to insufficient caching, scheduling jitter
...@@ -311,9 +311,9 @@ static void aout_DecSynchronize (audio_output_t *aout, mtime_t dec_pts, ...@@ -311,9 +311,9 @@ static void aout_DecSynchronize (audio_output_t *aout, mtime_t dec_pts,
owner->sync.discontinuity = true; owner->sync.discontinuity = true;
/* Now the output might be too early... Recheck. */ /* Now the output might be too early... Recheck. */
if (aout_OutputTimeGet (aout, &aout_pts) != 0) if (aout_OutputTimeGet (aout, &drift) != 0)
return; /* nothing can be done if timing is unknown */ return; /* nothing can be done if timing is unknown */
drift = aout_pts - dec_pts; drift += mdate () - dec_pts;
} }
/* Early audio output. /* Early audio output.
......
...@@ -404,13 +404,13 @@ void aout_OutputDelete (audio_output_t *aout) ...@@ -404,13 +404,13 @@ void aout_OutputDelete (audio_output_t *aout)
aout->stop (aout); aout->stop (aout);
} }
int aout_OutputTimeGet (audio_output_t *aout, mtime_t *pts) int aout_OutputTimeGet (audio_output_t *aout, mtime_t *delay)
{ {
aout_assert_locked (aout); aout_assert_locked (aout);
if (aout->time_get == NULL) if (aout->time_get == NULL)
return -1; return -1;
return aout->time_get (aout, pts); return aout->time_get (aout, delay);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment