Commit graph

7 commits

Author SHA1 Message Date
Zaggy1024
ae5e200dfc LibMedia: Move overlapping audio block correction to the data provider
This prevents PlaybackManager's seek while enabling an audio track from
causing the AudioMixingSink to push audio blocks forward unnecessarily.
Previously, the seek would cause the initial block or blocks to repeat
from the perspective of AudioMixingSink, so it would think that it
needs to shift the first block after the seek forward by a few samples.
By moving this to the AudioDataProvider, we can clear the last sample
index every time the decoder is flushed, ensuring that the block
shifting always makes sense.

By doing this in AudioMixingSink instead of the Decoder
implementations, we avoid having to duplicate this shifting logic
across multiple implementations.

This also fixes an issue where multiple audio blocks occupying the same
timestamp would be skipped while seeking, causing a significant break
in audio.
2025-11-17 16:51:18 +01:00
Zaggy1024
7e325d64f5 LibMedia: Use [from/to]_time_units in FFmpegDemuxer and AudioMixingSink 2025-11-17 16:51:18 +01:00
Zaggy1024
7845b22c5f LibMedia: Stop recursively locking in AudioMixingSink initialization
We already hold a lock in deferred_create_playback_stream, so we can
just skip taking a lock in create_playback_stream.
2025-11-03 16:39:24 -06:00
Zaggy1024
7745d9209d LibMedia: Sync AudioMixingSink::set_time onto the stream thread
With the previous setup setting the time directly on the main thread,
the following could occur:

- HTMLMediaElement temporarily pauses playback to begin a seek.
- AudioMixingSink starts an audio task to drain audio and suspend.
- HTMLMediaElement starts PlaybackManager seeking to a new position.
- AudioDataProvider completes the seek to the new position.
- The PlaybackManager tells AudioMixingSink to set the media time,
  which it does so synchronously on the main thread.
- At this point, the time provider corresponds to the new position.
- The pause completes, and a deferred invocation sets media time to
  its old position again.

This would result in the timeline showing the wrong position after a
seek on rare occasions.

Instead, always queue up a drain and suspend when setting the sink's
media time. This ensures that updating the time always occurs after the
pause has completed.

Also, since setting the time is asynchronous now, we need to store the
target time until the seeking drain completes. Otherwise, we still
briefly see the previous playback position after a seek.
2025-10-27 17:28:49 -07:00
Zaggy1024
8d9a493b1b LibMedia+LibWeb: Implement media volume/muting 2025-10-27 17:28:49 -07:00
Zaggy1024
e176249db8 LibMedia: Use AudioMixingSink as a time provider when it is available 2025-10-27 17:28:49 -07:00
Zaggy1024
0ff330c906 LibMedia: Play audio through PlaybackManager using Providers/Sinks
This commit implements the functionality to play back audio through
PlaybackManager.

To decode the audio data, AudioDataProviders are created for each track
in the provided media data. These providers will fill their audio block
queue, then sit idle until their corresponding tracks are enabled.

In order to output the audio, one AudioMixingSink is created which
manages a PlaybackStream which requests audio blocks from multiple
AudioDataProviders and mixes them into one buffer with sample-perfect
precision.
2025-10-27 17:28:49 -07:00