Improve audio player behavior by rom1v · Pull Request #4572 · Genymobile/scrcpy (original) (raw)

@rom1v

This avoids unreasonable values which could lead to integer overflow.

PR #4572 <#4572>

@rom1v

The audio output thread only reads samples from the buffer, and most of the time, the audio receiver thread only writes samples to the buffer. In these cases, using atomics avoids lock contention.

There are still corner cases where the audio receiver thread needs to "read" samples (and drop them), so lock only in these cases.

PR #4572 <#4572>

@rom1v

Use different thresholds for enabling and disabling compensation.

Concretely, enable compensation if the difference between the average and the target buffering levels exceeds 4 ms (instead of 1 ms). This avoids unnecessary compensation due to small noise in buffering level estimation.

But keep a smaller threshold (1 ms) for disabling compensation, so that the buffering level is restored closer to the target value. This avoids to keep the actual level close to the compensation threshold.

PR #4572 <#4572>

@rom1v

The buffering level does not change continuously: it increases abruptly when a packet is received, and decreases abruptly when an audio block is consumed.

To estimate the buffering level, a rolling average is used.

To make the buffering more stable, increase the smoothness of this rolling average. This decreases the risk of enabling audio compensation due to an estimation error.

PR #4572 <#4572>

@rom1v

@rom1v

@rom1v

If playback starts too early, insert silence until the buffer is filled up to at least target_buffering before playing.

PR #4572 <#4572>

@rom1v

The assumption that underflow and overbuffering are caused by jitter (and that the delay between the producer and consumer will be caught up) does not always hold.

For example, if the consumer does not consume at the expected rate (the SDL callback is not called often enough, which is an audio output issue), many samples will be dropped due to overbuffering, decreasing the average buffering indefinitely.

Prevent the average buffering to become negative to limit the consequences of an unexpected behavior.

PR #4572 <#4572>

armm29393 added a commit to armm29393/scrcpy-root that referenced this pull request

May 24, 2024

@armm29393

rom1v added a commit that referenced this pull request

May 27, 2024

@rom1v

PR #4752 removed the need for locks except for corner cases. Now replace the remaining lock sections by atomics.

Refs #4572 <#4572>

rom1v added a commit that referenced this pull request

May 28, 2024

@rom1v

PR #4752 removed the need for locks except for corner cases. Now replace the remaining lock sections by atomics.

Refs #4572 <#4572>

rom1v added a commit that referenced this pull request

May 29, 2024

@rom1v

PR #4572 removed the need for locks except for corner cases. Now replace the remaining lock sections by atomics.

Refs #4572 <#4572>

rom1v added a commit that referenced this pull request

May 30, 2024

@rom1v

PR #4572 removed the need for locks except for corner cases. Now replace the remaining lock sections by atomics.

Refs #4572 <#4572>

bartsaintgermain pushed a commit to bartsaintgermain/scrcpy that referenced this pull request

Apr 11, 2025

@rom1v

bartsaintgermain pushed a commit to bartsaintgermain/scrcpy that referenced this pull request

Apr 11, 2025

@rom1v

The audio output thread only reads samples from the buffer, and most of the time, the audio receiver thread only writes samples to the buffer. In these cases, using atomics avoids lock contention.

There are still corner cases where the audio receiver thread needs to "read" samples (and drop them), so lock only in these cases.

PR Genymobile#4572 <Genymobile#4572>

bartsaintgermain pushed a commit to bartsaintgermain/scrcpy that referenced this pull request

Apr 11, 2025

@rom1v

Use different thresholds for enabling and disabling compensation.

Concretely, enable compensation if the difference between the average and the target buffering levels exceeds 4 ms (instead of 1 ms). This avoids unnecessary compensation due to small noise in buffering level estimation.

But keep a smaller threshold (1 ms) for disabling compensation, so that the buffering level is restored closer to the target value. This avoids to keep the actual level close to the compensation threshold.

PR Genymobile#4572 <Genymobile#4572>

bartsaintgermain pushed a commit to bartsaintgermain/scrcpy that referenced this pull request

Apr 11, 2025

@rom1v

The buffering level does not change continuously: it increases abruptly when a packet is received, and decreases abruptly when an audio block is consumed.

To estimate the buffering level, a rolling average is used.

To make the buffering more stable, increase the smoothness of this rolling average. This decreases the risk of enabling audio compensation due to an estimation error.

PR Genymobile#4572 <Genymobile#4572>

bartsaintgermain pushed a commit to bartsaintgermain/scrcpy that referenced this pull request

Apr 11, 2025

@rom1v

bartsaintgermain pushed a commit to bartsaintgermain/scrcpy that referenced this pull request

Apr 11, 2025

@rom1v

bartsaintgermain pushed a commit to bartsaintgermain/scrcpy that referenced this pull request

Apr 11, 2025

@rom1v

If playback starts too early, insert silence until the buffer is filled up to at least target_buffering before playing.

PR Genymobile#4572 <Genymobile#4572>

bartsaintgermain pushed a commit to bartsaintgermain/scrcpy that referenced this pull request

Apr 11, 2025

@rom1v

The assumption that underflow and overbuffering are caused by jitter (and that the delay between the producer and consumer will be caught up) does not always hold.

For example, if the consumer does not consume at the expected rate (the SDL callback is not called often enough, which is an audio output issue), many samples will be dropped due to overbuffering, decreasing the average buffering indefinitely.

Prevent the average buffering to become negative to limit the consequences of an unexpected behavior.

PR Genymobile#4572 <Genymobile#4572>

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})