mirror of
https://code.videolan.org/videolan/vlc
synced 2024-10-03 01:31:53 +02:00
coreaudio: disable resampling when latency is too high
On iOS, the render callback is called by default with 1024 frames, and 4096
when the screen is OFF. 4096 frames @ 44.1Hhz is around 88ms, which is higher
than AOUT_MAX_PTS_DELAY (60ms). This caused the resampler to be started/stopped
very often when the screen was OFF due to the imprecision of 88ms from the
TimeGet callback.
To fix this issue, this commit disable the TimeGet callback when the latency is
too high.
This will also save some CPU time by disabling any synchronisation when the
screen is OFF. From my tests, high latency is only triggered by switching OFF
the display.
Fixes #18939
(cherry picked from commit f18fef325a
)
Signed-off-by: Thomas Guillem <thomas@gllm.fr>
This commit is contained in:
parent
b83976bcf5
commit
bab4c8269e
@ -984,7 +984,7 @@ RenderCallbackSPDIF(AudioDeviceID inDevice, const AudioTimeStamp * inNow,
|
||||
uint8_t *p_output = outOutputData->mBuffers[p_sys->i_stream_index].mData;
|
||||
size_t i_size = outOutputData->mBuffers[p_sys->i_stream_index].mDataByteSize;
|
||||
|
||||
ca_Render(p_aout, p_output, i_size);
|
||||
ca_Render(p_aout, 0, p_output, i_size);
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ ca_Open(audio_output_t *p_aout)
|
||||
atomic_init(&p_sys->i_underrun_size, 0);
|
||||
atomic_init(&p_sys->b_paused, false);
|
||||
atomic_init(&p_sys->b_do_flush, false);
|
||||
atomic_init(&p_sys->b_highlatency, true);
|
||||
vlc_sem_init(&p_sys->flush_sem, 0);
|
||||
vlc_mutex_init(&p_sys->lock);
|
||||
|
||||
@ -70,10 +71,17 @@ ca_Close(audio_output_t *p_aout)
|
||||
|
||||
/* Called from render callbacks. No lock, wait, and IO here */
|
||||
void
|
||||
ca_Render(audio_output_t *p_aout, uint8_t *p_output, size_t i_requested)
|
||||
ca_Render(audio_output_t *p_aout, uint32_t i_nb_samples, uint8_t *p_output,
|
||||
size_t i_requested)
|
||||
{
|
||||
struct aout_sys_common *p_sys = (struct aout_sys_common *) p_aout->sys;
|
||||
|
||||
const bool b_highlatency = CLOCK_FREQ * (uint64_t)i_nb_samples / p_sys->i_rate
|
||||
> AOUT_MAX_PTS_DELAY;
|
||||
|
||||
if (b_highlatency)
|
||||
atomic_store(&p_sys->b_highlatency, true);
|
||||
|
||||
bool expected = true;
|
||||
if (atomic_compare_exchange_weak(&p_sys->b_do_flush, &expected, false))
|
||||
{
|
||||
@ -109,6 +117,11 @@ ca_Render(audio_output_t *p_aout, uint8_t *p_output, size_t i_requested)
|
||||
atomic_fetch_add(&p_sys->i_underrun_size, i_requested - i_tocopy);
|
||||
memset(&p_output[i_tocopy], 0, i_requested - i_tocopy);
|
||||
}
|
||||
|
||||
/* Set high delay to false (re-enabling ca_Timeget) after consuming the
|
||||
* circular buffer */
|
||||
if (!b_highlatency)
|
||||
atomic_store(&p_sys->b_highlatency, false);
|
||||
}
|
||||
|
||||
int
|
||||
@ -116,6 +129,10 @@ ca_TimeGet(audio_output_t *p_aout, mtime_t *delay)
|
||||
{
|
||||
struct aout_sys_common *p_sys = (struct aout_sys_common *) p_aout->sys;
|
||||
|
||||
/* Too high delay: TimeGet will be too imprecise */
|
||||
if (atomic_load(&p_sys->b_highlatency))
|
||||
return -1;
|
||||
|
||||
int32_t i_bytes;
|
||||
TPCircularBufferTail(&p_sys->circular_buffer, &i_bytes);
|
||||
|
||||
@ -239,6 +256,7 @@ ca_Initialize(audio_output_t *p_aout, const audio_sample_format_t *fmt,
|
||||
|
||||
atomic_store(&p_sys->i_underrun_size, 0);
|
||||
atomic_store(&p_sys->b_paused, false);
|
||||
atomic_store(&p_sys->b_highlatency, true);
|
||||
p_sys->i_rate = fmt->i_rate;
|
||||
p_sys->i_bytes_per_frame = fmt->i_bytes_per_frame;
|
||||
p_sys->i_frame_length = fmt->i_frame_length;
|
||||
@ -346,9 +364,8 @@ RenderCallback(void *p_data, AudioUnitRenderActionFlags *ioActionFlags,
|
||||
VLC_UNUSED(ioActionFlags);
|
||||
VLC_UNUSED(inTimeStamp);
|
||||
VLC_UNUSED(inBusNumber);
|
||||
VLC_UNUSED(inNumberFrames);
|
||||
|
||||
ca_Render(p_data, ioData->mBuffers[0].mData,
|
||||
ca_Render(p_data, inNumberFrames, ioData->mBuffers[0].mData,
|
||||
ioData->mBuffers[0].mDataByteSize);
|
||||
|
||||
return noErr;
|
||||
|
@ -55,6 +55,7 @@ struct aout_sys_common
|
||||
atomic_uint i_underrun_size;
|
||||
atomic_bool b_paused;
|
||||
atomic_bool b_do_flush;
|
||||
atomic_bool b_highlatency;
|
||||
vlc_sem_t flush_sem;
|
||||
vlc_mutex_t lock;
|
||||
int i_rate;
|
||||
@ -70,7 +71,8 @@ void ca_Open(audio_output_t *p_aout);
|
||||
|
||||
void ca_Close(audio_output_t *p_aout);
|
||||
|
||||
void ca_Render(audio_output_t *p_aout, uint8_t *p_output, size_t i_requested);
|
||||
void ca_Render(audio_output_t *p_aout, uint32_t i_nb_samples, uint8_t *p_output,
|
||||
size_t i_requested);
|
||||
|
||||
int ca_TimeGet(audio_output_t *p_aout, mtime_t *delay);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user