Commit Graph

1866 Commits

Author SHA1 Message Date
llyyr 2033a3c93e af_scaletempo2: raise max playback rate to 8.0
4.0 was too low and copied from Chromium defaults when the filter was
initially written, there's no good reason for it to be so low, so
double it.
2023-09-27 14:03:30 +00:00
Dudemanguy 36ea5d7b5c options: remove a few options marked with .deprecation_message
A bit different from the OPT_REPLACED/OPT_REMOVED ones in that the
options still possibly do something but they have a deprecation
message. Most of these are old and have no real usage. The only
potentially controversial ones are the removal of --oaffset and
--ovoffset which were deprecated years ago and seemingly have no real
replacement. There's a cryptic message about --audio-delay but who
knows. The less encoding mode code we have, the better so just chuck
it.
2023-09-21 16:06:29 +00:00
ferreum 95157bb0a5 af_scaletempo2: fix missing variable init, remove redundant init 2023-09-20 14:36:23 +02:00
ferreum e05591ef59 af_scaletempo2: truncate final packet to expected length
Avoid generating too much audio after EOF.

Note: This often has no effect, because less audio is produced than
required.

Usually this comes to effect with the userspeed filter at high speed
(4x) and going back to 1x speed to remove the filter.
2023-09-20 14:36:23 +02:00
ferreum 8080d00d7f af_scaletempo2: fix processing of final packet
After the final input packet, the filter padded with silence to allow
one more iteration. That was not enough to process the final frames.

Continue padding the end of `input_buffer` with silence until the final
frames have been processed.

Implementation: Instead of padding when adding final samples, pad before
running WSOLA iteration. Count number of added silent frames and
remaining input frames for time keeping.
2023-09-20 14:36:23 +02:00
ferreum cf8b7ff0d6 af_scaletempo2: calculate latency by center of search block
This changes the emitted pts values from the start of the search block
to the center of the search block. Change initial `output_time`
accordingly. Initial `search_block_index` is irrelevant, because it's
overwritten before the first iteration.

Using the `output_time` removes the rounding of `search_block_index`,
which also fixes the <20 microsecond gaps in timestamps between output
packets.

Rationale:

The variance in audio position was in the range `0..search-interval`.

With this change, the range is

    (- search-interval / 2)..(search-interval / 2)`

which ensures lower maximum offset.
2023-09-20 14:36:23 +02:00
ferreum c0728249a1 af_scaletempo2: restore exact audio sync on return to 1x speed
Target block can be anywhere in the previous search-block, varying by
`search-interval` while the filter is active. This resulted in constant
audio offset when returning to 1x playback speed.

- Move the search block to the target block to sync up exactly.
- Drop old frames to minimize input_buffer usage.
2023-09-20 14:36:23 +02:00
ferreum f52cf90fed af_scaletempo2: fix speed change latency and pts spikes
The internal time update function involved multiple problems:

- Time was updated after WSOLA iteration. The means speed was updated
  one iteration later than it could be.
- The update functions caused spikes of too many or too few samples
  advanced, leading to audio glitches on speed changes.
- The inconsistent updates made it very difficult to produce gapless
  audio packets.
- The `output_time` update function involved complicated feedback:
  `search_block_index` influenced how many frames from `input_buffer`
  are retained, which influenced how much `output_time` is changed,
  which influenced `search_block_index`.

With these changes:

- Time is updated before WSOLA iterations. Speed changes are effective
  instantly.
- There are no spikes in playback speed during speed changes.
- No significant gaps are introduced in output packets.
- The time update function becomes (function calls omitted for brevity)

    output_time += ola_hop_size * playback_rate

Functions received a `playback_rate` parameter to check how many samples
are needed before iteration. Internal state is only updated when the
iteration is actually run, so the speed is allowed to change until
enough data is received.
2023-09-20 14:36:23 +02:00
ferreum 33d6d0f311 af_scaletempo2: fix audio artifact on initial WSOLA iteration
The first WSOLA iteration overlapped audio with whatever was in the
`wsola_output` buffer. This was either silence (if not run before), or
old frames (if switching to 1x and back to a different speed).

Track the state of the output buffer and memcpy the whole window for the
first iteration instead.
2023-09-20 14:36:23 +02:00
ferreum c3bceb3243 af_scaletempo2: fix audio offset when playing back at 1x speed
`read_input_buffer` needs to respect the `target_block_index`, otherwise
the audio resumes at the wrong position.
2023-09-20 14:36:23 +02:00
ferreum de09ec9ea4 af_scaletempo2: fix inconsistent search block position after init
`output_time` is used to set the center of the search block. Init of
both `search_block_index` and `output_time` with 0 caused inconsistent
search block movement for the first iterations.

Initialize with `search_block_center_offset` for consistency with initial
`search_block_index`.
2023-09-20 14:36:23 +02:00
ferreum 87cc7ed955 af_scaletempo2: move latency calculation to internal function 2023-09-20 14:36:23 +02:00
ferreum 0d64f795c7 af_scaletempo2: fix missing dereference when processing final packet
Missing dereference was not noticed because assigning 0 to pointer is
allowed.
2023-09-20 14:36:23 +02:00
ferreum 05395205dd af_scaletempo2: fix audio-video de-sync caused by speed changes
Fixes #12028

There was an additional issue that audio was always delayed by half the
configured search-interval. This was caused by the `out` buffer length
not being included in the delay calculation.

Notes:
- Every WSOLA iteration advances the input buffer by _some amount_, and
  produces data in the output buffer always of size `ola_hop_size`.
- `mp_scaletempo2_fill_buffer` is always called with `ola_hop_size`
- Thus, the rendered frames are always cleared immediately after
  processing, and `num_complete_frames` is 0 in the delay calculation.
- The factors contributing to delay are:
  - the pending samples in the input buffer according to the search
    block position, and
  - the pending rendered samples in the output buffer (always empty in
    practice).

The frame_delay code looked like that of the rubberband filter, which
might not work for scaletempo2. Sometimes a different amount of input
audio was consumed by scaletempo2 than expected. It may have been caused
by speed changes being a more dynamic process in scaletempo2. This can
be seen by where `playback_rate` is used in `run_one_wsola_iteration`:
`playback_rate` is only referenced after the iteration, when updating
the time and removing old data from buffers.

In scaletempo2, the playback speed is applied by changing the amount the
search block is moved. That apparently averages out correctly at
constant playback speed, but when the speed changes, the error in this
assumption probably spikes. This error accumulated across all speed
changes because of the persistent `frame_delay` value.

With the removal of the persistent `frame_delay`, there should be no way
for the audio to drift off. By deriving the delay from filter buffer
positions, and the buffers are filled only as much as needed, the delay
always stays within buffer bounds.
2023-09-20 14:36:23 +02:00
sfan5 817c281c7c Revert "ao/pulse: implement period_size"
This is why you don't merge three year old contributions
without checking that they're even applicable anymore.

This reverts commit 5a94c86029.
2023-08-20 20:49:10 +02:00
Nicolas F 5a94c86029 ao/pulse: implement period_size
The idea behind period_size is that it's the minimum amount of data
that your audio subsystem wants to fetch.

For PulseAudio, this is given by the minreq buffer attribute, which
is in bytes for all channels. Hence the divisions.
2023-08-20 20:31:24 +02:00
Nicolas F 9ba8b921cf ao/jack: set device_buffer to JACK buffer size
This change sets the device_buffer member of the ao struct for
the JACK ao to whatever value we read during init.

While JACK allows changing the audio buffer size on-the-fly
(you can do this for example through DBus), having it somehow
reconfigure the entire audio buffer logic of mpv that depends
on device_buffer in some way when that happens only leads to
audio dropout and weird code. device_buffer's role is mostly for
prebuffer from what I understand, which means that simply setting
it to its current value in the init function is fine.
2023-08-20 20:30:53 +02:00
rim f2453b60ee ao_oss: add "spdif" passthrough support for high bitrate codecs (e.g. Dolby Atmos, DTS-HD, etc.) over HDMI
In addition to the patch, appropriate additions to the mpv.conf file
will of course be needed for this to work. For example on my system:

audio-device=oss//dev/dsp4
audio-spdif=ac3,dts,dts-hd,eac3,truehd

   This has been tested using recent FreeBSD-13.1-stable, using external
surround processors (both a Trinnov Altitude 16 and an LG OLED that
supports Dolby Atmos, and connected with HDMI to an NVidia RTX 2070).

Author and tester: David G Lawrence <dg1007@dglawrence.com>
2023-08-20 20:02:40 +02:00
Dudemanguy 41c0321208 audio: drain ao before setting pause
There's an edge cause with gapless audio and pausing. Since, gapless
audio works by sending an EOF immediately, it's possible to pause on the
next file before audio actually finishes playing and thus the sound gets
cut off. The fix is to simply just always do an ao_drain if the ao is
about to set a pause on EOF and we still have audio playing.
Fixes #8898.
2023-08-11 22:28:50 +00:00
sfan5 bc52159cb9 ao_audiotrack: enable pcm-float by default
Since recent commits this should work 100% as well as s16.
2023-08-08 20:15:20 +02:00
sfan5 862011942f ao_audiotrack: support more channel layouts 2023-08-08 20:15:20 +02:00
sfan5 dae0340620 ao_audiotrack: support media role
maybe this is good for something, who knows
2023-08-08 20:15:20 +02:00
sfan5 9faf9932a4 ao_audiotrack: don't ignore ao_read_data return value
The difference this makes is that the OS API will notice
when we underrun (as opposed to being fed silence).
Other AOs mostly seem to not do this because they've committed
to filling a buffer of a certain size no matter what, but I have
not observed any ill effects for AudioTrack in my testing.
2023-08-08 20:15:20 +02:00
sfan5 8b7904618e ao_audiotrack: allow byte buffer data transfer for float samples 2023-08-08 20:15:20 +02:00
sfan5 36bea732fb ao_audiotrack: align buffer size to sample size
This looks like a pretty bad bug but only became a problem
with the last commit that allows rates like 22.5kHz to pass through
directly instead of being resampled.
2023-08-08 20:15:20 +02:00
sfan5 d9072fef2a ao_audiotrack: do not needlessly resample
Resampling when the driver says it isn't outputting more than
a certain rate anyway makes sense, the inverse does not.
2023-08-08 20:15:20 +02:00
sfan5 a949e58362 ao_audiotrack: fix broken exception checks
The exception always has to be checked and cleared even if we
can already see that no valid value was returned.
2023-08-08 20:15:20 +02:00
sfan5 efebd50a6c ao_audiotrack: remove unused writeV23
The piece of code where it would make sense to use this
never runs with API 21 or newer, so calling it there would be useless.
2023-08-08 20:15:20 +02:00
sfan5 a9c0ad149f ad_spdif: fix this not working at all
fixes 4c3ed843dc
closes #12102
2023-08-07 23:15:00 +02:00
Thomas Weißschuh b3b7ee8f4c ao_pipewire: set media role during init()
wireplumber uses the media role when the node is first created.
To have the property available at this point reliably we need to set it
directly when creating the stream/node.
2023-07-31 14:01:44 +02:00
Thomas Weißschuh 6e023547ea audio: add AO_INIT_MEDIA_ROLE_MUSIC
This allows the AO to set the media role directly during init().
2023-07-31 14:01:44 +02:00
Alexandre Ratchov 1bbc7a2cd0 ao_sndio: use sio_flush() to improve controls responsiveness
Use sio_flush() instead of sio_stop() to improve controls responsiveness.
2023-07-30 19:28:14 +00:00
Thomas Weißschuh 1608059d64 Revert "audio: add AOCONTROL_UPDATE_MEDIA_ROLE"
The only user of these APIs was ao_pipewire and the logic there got
converted so drop the now dead code.

This reverts commit 3167a77aa3.
2023-07-30 19:48:35 +02:00
Thomas Weißschuh 0fb7ab62c5 Revert "ao_pipewire: handle AOCONTROL_UPDATE_MEDIA_ROLE"
As the role property is interpreted by wireplumber it can only be
evaluated when creating the stream. The current, dynamic mechanism is
racy so revert it.

See: #11253
Fixes: #12041
This reverts commit 535cd6f313.
2023-07-30 19:48:35 +02:00
sfan5 4c3ed843dc ad_spdif: fix segfault due to early deallocation
The avpkt was created once on decoder init but destroyed each time the
filter was destroyed, this obviously can't work. Move the packet alloc
to the filter init function instead.

fixes: 4574dd5dc6
2023-07-27 22:56:37 +02:00
Thomas Weißschuh 007019a303 ao_pipewire: for_each_sink: properly check termination condition
Doing a pw_thread_loop_wait() without checking conditions is invalid.
The thread loop could be signalled for other reasons and in this case
the wait needs to continue.

PipeWire added such additional signaling in
commit 33be898130f0 ("thread-loop: signal when started").

This meant that for_each_sink would return before the callbacks have
fired and session_has_sink() would incorrectly return "false", failing
the initialization of ao_pipewire.

Fixes #11995
2023-07-23 13:31:03 +02:00
Thomas Weißschuh c9064b57c0 ao_pipewire: use native buffersize by default
Instead of trying to guess the correct number in mpv let the pipewire
server choose.

Fixes #9992
2023-07-22 12:16:21 +02:00
rcombs 0463096b3c osdep: move cfstr<->cstr conversions to a new apple_utils.c file 2023-06-25 11:01:58 +02:00
NRK 32147956ca ad_lavc: check for allocation failure
Fixes: https://github.com/mpv-player/mpv/issues/11792
2023-06-22 18:13:11 +02:00
Thomas Weißschuh 594458838e ao_pipewire: bump dependency to 0.3.48
Now that Debian 12 is release bump the minium required version to what
is provided in Ubuntu Jammy (22.04).
The same as has been done for the wayland dependencies.

Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
2023-06-21 17:33:31 +02:00
Kacper Michajłow 71c80826f1 ao_wasapi: use client name instead of hardcoded string 2023-06-21 17:31:59 +02:00
Kacper Michajłow 3dc661fe8e ao_wasapi: remove infinite loop hack in AOCONTROL_UPDATE_STREAM_TITLE
Instead of brute forcing the name until it is set, without any error
checking and expecting it would start to work, fallback to client name
if initial request fails.

Fixes player going into infinite loop with very long title names. The
API rejects unreasonably long names, which make sense.

As for alleged "weird race condition in the IAudioSessionControl itself"
I cannot comment. It works on my end and even if it fails, it is not a
critical error or even something that we should care about... and
obviously not hang the whole player for that.

Fixes: #11803
2023-06-21 17:31:59 +02:00
rim 5afc0da530 ao_oss: return actual OSS playing state
fix: https://github.com/mpv-player/mpv/issues/10640
2023-05-11 01:53:55 +00:00
Thomas Weißschuh cb6b4af1d7 ao_pipewire: let sound server determine latency
Fixes #11467
2023-04-23 21:03:58 -07:00
Thomas Weißschuh eafd0e5fad ao_pipewire: give sound server more flexibility for buffers 2023-04-23 21:03:58 -07:00
Thomas Weißschuh c0ca5f1a37 ao_pipewire: use realtime scheduling for data thread
By making the data thread realtime it is able to serve requests faster
and more reliable reducing crackling in certain situations.

As the mpv callbacks that are running on the data thread are all
non-blocking and very short this should be safe.

The same mechanism is also used by pw-cat and the alsa plugin shipped by
pipewire.
2023-03-05 11:23:01 -08:00
Christoph Heinrich c0807e98fb options: remove explicit initialization of integers to 0 2023-02-21 17:15:17 +00:00
Christoph Heinrich 4ebfe9851c options: transition commands from OPT_FLAG to OPT_BOOL 2023-02-21 17:15:17 +00:00
Christoph Heinrich 91cc0d8cf6 options: transition options from OPT_FLAG to OPT_BOOL
c784820454 introduced a bool option type
as a replacement for the flag type, but didn't actually transition and
remove the flag type because it would have been too much mundane work.
2023-02-21 17:15:17 +00:00
Thomas Weißschuh 9efce6d4ae various: drop unused #include "config.h"
Most sources don't need config.h.
The inclusion only leads to lots of unneeded recompilation if the
configuration is changed.
2023-02-20 14:21:18 +00:00