summaryrefslogtreecommitdiffstats
path: root/player/audio.c
Commit message (Collapse)AuthorAgeFilesLines
* player/video: subtract frame_time from delay when ao_chain starts audioDudemanguy2024-03-031-0/+1
| | | | | | | This seems more robust than relying on the audio status to actually be playing. For files where there is no audio or the audio start is delayed, this guards against that but it allows the subtraction to always occur otherwise on normal files with audio.
* player/audio: also adjust apts by audio speed in audio_start_aoDudemanguy2024-03-031-1/+2
| | | | Fixes 7051e94e4bacd00e53e88835d28e9d9082de3bb3
* Revert "player: add ao-volume option, to set the system volume at startup"Dudemanguy2024-03-011-17/+1
| | | | | | | | Ended up being a bad idea. As a property, this inherently has more functionality and the tradeoff of being able to do --ao-volume wasn't worth it. This reverts commit 58ed620c064971535e60778612777750aa5e2f4d.
* player/audio: remove misleading comment about delayDudemanguy2024-02-261-1/+1
| | | | | | | | | | | This came up in #13571. playing_audio_pts does not include mpctx->delay contray to what that implies. The function is meant to only offset the written audio pts by whatever the internal AO buffer may be. mpctx->delay is a combination from both the audio and video code, so it should not be used here. What is wanted is purely the audio pts. b74c09efbf7c6969fc053265f72cc0501b840ce1, a very controversial commit to say the least, was what introduced this comment, so removing is probably OK.
* player: remove speed adjustment from playing_audio_ptsDudemanguy2024-02-261-1/+1
| | | | | | | | | | | | When calculating the audio pts, mpv multiplies the ao delay by the current audio speed and subtracts it from the written audio pts. This doesn't really make sense though. mpctx->video_pts is never affected by the playback speed, and this leads to weird behavior like the audio-pts property changing values while paused merely because the playback speed changes. Remove the multiplication and simply subtract the delay by a factor of 1 instead. When updating the av_diff in player/video, this does actually need to take in account the audio speed so we do the calculation there.
* player: add ao-volume option, to set the system volume at startupLeonardo Boss2024-02-251-1/+17
| | | | closes #12353
* audio: add --volume-gain options to control volume in decibelsnanahi2024-01-201-0/+1
| | | | | | This adds volume-gain, volume-gain-max, volume-gain-min options, which can be used to control audio volume and target dynamic range in decibels. The gain is applied on top of the existing volume setting.
* player/audio: fix incorrect check on adding delayDudemanguy2023-10-261-1/+1
| | | | | | | | | | | | dac977193cccbf7e2e999cf0c4b0292314839c4c changed adding delay to only when the video is playing but this isn't correct. The video frames adjust themselves based on the audio, so if we still have audio processing while the video itself happens to be in some non-playing state (such as STATUS_READY), the delay still needs to be taken into account. The correct thing to check is to make sure that it is not STATUS_EOF. STATUS_EOF covers the case where we have still image, and of course no video at all is STATUS_EOF. So having a massive bogus delay value is still avoided.
* player: don't calculate av delay if there's no audio or videoDudemanguy2023-10-251-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The point of the mpctx->delay field is for calculating a/v sync and adjusting the frame timings appropriately. However, the frame_time was always subtracted from mpctx->delay regardless of the audio status. This meant that for a video with no audio, every single frame had a subtraction with nothing ever added to it meaning that you get massive negative delay times. For weird videos where the audio starts way later, the massive delay leads to the VO sleeping for basically about as long as the video was previously playing without audio. This results in nothing being rendered during that brief period of time and just overall badness. When using display-sync, it happens to work since the video doesn't adjust itself based on audio and it renders anyway. The fix is to simply not touch mpctx->delay in player/video.c unless there's actually audio playing. This is what the rest of the code already does aside from setting it to 0 on resets or EOFs. Move the calculation into adjust_sync after the audio status check. It works exactly the same as before except that we don't constantly subtract bogus values when there's no audio playing. The reverse situation in player/audio.c also has the same issue. For something that is only audio, mpctx->delay is always added to but nothing will ever subtract from it. It's not really clear if this particular version could ever cause a real bug, but logically it needs to be guarded in the same way. The field here should only be updated if the video is actually playing. Fixes #12025.
* audio: drain ao before setting pauseDudemanguy2023-08-111-1/+2
| | | | | | | | | 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.
* audio: add AO_INIT_MEDIA_ROLE_MUSICThomas Weißschuh2023-07-311-0/+17
| | | | This allows the AO to set the media role directly during init().
* Revert "audio: add AOCONTROL_UPDATE_MEDIA_ROLE"Thomas Weißschuh2023-07-301-26/+0
| | | | | | | The only user of these APIs was ao_pipewire and the logic there got converted so drop the now dead code. This reverts commit 3167a77aa38b3700c9a4459fa5fe2f65eef080a8.
* audio: remove a duplicate clearing of a struct variableder richter2023-02-271-1/+0
| | | | Fixes #8301
* various: drop unused #include "config.h"Thomas Weißschuh2023-02-201-1/+0
| | | | | | Most sources don't need config.h. The inclusion only leads to lots of unneeded recompilation if the configuration is changed.
* various: replace if + abort() with MP_HANDLE_OOM()sfan52023-01-121-4/+2
| | | | | MP_HANDLE_OOM also aborts but calls assert() first, which will result in an useful message if compiled in debug mode.
* player: add video-sync=display-tempoChristoph Heinrich2023-01-091-3/+11
| | | | | | | | So far there was no way to sync video to display and have audio sync to video without changes in pitch. With this option the audio does not get resampled (pitch change) and instead the corrected audio speed is applied to audio filters.
* audio: add AOCONTROL_UPDATE_MEDIA_ROLEThomas Weißschuh2022-09-101-0/+26
| | | | | | This is used to notify an AO about the type of media that is being played. Either a movie or music.
* player/audio: remove explicit drain on EOFPhilip Langdale2022-08-231-2/+0
| | | | | | | | | | | | | | | We have previously had a problem where pull AOs (such as pipewire) would not reinitialize on a format change when going between two audio-only files. In such a situation, playback would stop after the first file. We initially attempted to fix this by explicitly draining on EOF, which solves that problem but introduces a blocking step where we don't actually want one, breaking gapless audio, and causing dropped frames at the end of playback for files with video in them too. So, let's undo these changes and do something better in the next commit.
* audio: don't try to drain non-existent AOThomas Weißschuh2022-08-211-1/+2
| | | | | | | | 52aed495cb ("audio: drain ao on EOF") introduced logic to drain an AO when EOF of the input has been reached. When no AO however is present this leads to a NULL-dereference. Fixes #10556
* audio: drain ao on EOFThomas Weißschuh2022-08-091-0/+1
| | | | | | | | | | This gives pull-based AOs the chance to play all queued audio. Also it will make sure that the audio has finished playing so we can reinitialize the AO if format changes are necessary. Fixes #10018 Fixes #9835 Fixes #8904
* player: rearrange video sync opts/enums/definesDudemanguy2022-04-111-1/+1
| | | | | | | | | | | | | | | | | The video sync logic for mpv lies completely within its core at essentially the highest layer of abstraction. The problem with this is that it is impossible for VOs to know what video sync mode mpv is currently using since it has no access to the opts. Because different video sync modes completely changes how mpv's render loop operates, it's reasonable that a VO may want to change how it renders based on the current mode (see the next commit for an example). Let's just move the video sync option to mp_vo_opts. MPContext, of course, can still access the value of the option so it only requires minor changes in player/video.c. Additionally, move the VS_IS_DISP define from to player/core.h to common/common.h. All VOs already have access to common/common.h, and there's no need for them to gain access to everything that's in player/core.h.
* audio: fix typoAman Karmani2021-12-031-1/+1
|
* audio: check ao driver init failure to avoid use after freeShreesh Adiga2021-07-131-9/+12
| | | | | | | | reinit_audio_filters_and_output function will free mpctx->ao_chain when there is a failure during audio initialization. So modify it to return -1 in case of init failure. The return value is checked to avoid use after free. Reported by Address Sanitizer when manually specifying --ao which triggers "Failed to initialize audio driver" error.
* audio: fix replaygain being completely brokenYour Name2021-05-071-0/+1
| | | | | | | | | | | | | | | | | | Switching to a new file while keeping the AO didn't update the volume. While there's an explicit audio_update_volume() call in reinit_audio_chain_src(), it doesn't work, because at that point ao_chain->ao is still NULL, and it does nothing. That's pretty weird and might cause other problems (what happens if you try to mute while the AO is "floating"?). Regarding gapless, trying to use the AO gain for replaygain is also gross nonsense, because the new replaygain computed gain would affect audio from the previous file. It looks like replaygain should be in an af_volume filter maybe. On the other hand, I enjoy setting ridiculous replaygain-preamp values and compensating with a low volume setting, which would not work well if both gains were applied to the audio independently. For now, just add the missing call. This is orthogonal to fixing replaygain "properly".
* Revert "audio: set audio chain ao on reinit"Your Name2021-05-071-3/+1
| | | | | | | | | | | | This reverts commit 3239e41277173bace5ecc2a22910c4660642429c. I'm fairly sure this is wrong, and my next commit should fix it properly. I'm not really sure, though. Normally, the AO is set again by reinit_audio_filters_and_output() after the new audio chain has decoded a frame and knows the new format. The reason replaygain (and apparently the thing the reverted commit tried to fix) didn't work is because they work asynchronously to the audio played by the AO (i.e. buggy and hard to fix).
* audio: add two minor log messagessfan52021-04-291-2/+6
| | | | | This would have made the problem fixed in the previous commit a bit more obvious from the log output.
* audio: set audio chain ao on reinitDudemanguy2021-04-181-1/+3
| | | | | | | | | Seems to be a slight corner case with the audio API rewrite. When switching from one file to another one, the volume of the ao would never be set because the audio chain's ao wasn't set. This caused a bug with the reset-set-on-file option. The volume/property would be correctly set internally, but the gain was not actually set when the file switched. Fixes #8287.
* audio: prevent uninit_audio_out during encodingTom Wilson2021-03-151-1/+2
| | | | | | | | | | | There was a simple oversight that meant audio outputs were uninitialized during an encoding, which is not allowed, the encoding would stop with numerous errors. I added a single line to prevent the call of uninit_audio_out in reinit_audio_chain if the encoder was active and this appears to have fixed the problem without breaking anything else. Fixes #8568
* player: fix another nightmarish corner casewm42020-10-081-3/+14
| | | | Pretty much fuck this shit.
* encode: remove early EOF failure handlingwm42020-09-031-1/+0
| | | | | | | I don't see the point of this. Not doing it may defer an error to later. That's OK? For now, it seems better to reduce the encoding internal API. If someone can demonstrate that this is needed, I might reimplement it in a different way.
* audio: slightly simplify audio_start_ao()wm42020-09-031-10/+4
| | | | Get rid of an indirection; no behavior change.
* audio: reduce excessive logging of delayed audio startwm42020-09-031-2/+7
| | | | | | | Since this is a messy and fragile mechanism, I want it logged (even if it's somewhat in conflict with the verbose logging policy). On the other hand, it's unconditionally logged on every playloop iteration. So add some nonsense to log it only on progress.
* audio: do not show audio draining message when it does not make sensewm42020-09-011-1/+3
| | | | | | Just for the redundant message. The function which is called here, ao_drain(), does not care in which state it is called, and already handled this gracefully.
* audio: do not wake up player when waiting for audio state and pausedwm42020-09-011-1/+2
| | | | Bullshit.
* audio: refactor how data is passed to AOwm42020-08-291-356/+313
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This replaces the two buffers (ao_chain.ao_buffer in the core, and buffer_state.buffers in the AO) with a single queue. Instead of having a byte based buffer, the queue is simply a list of audio frames, as output by the decoder. This should make dataflow simpler and reduce copying. It also attempts to simplify fill_audio_out_buffers(), the function I always hated most, because it's full of subtle and buggy logic. Unfortunately, I got assaulted by corner cases, dumb features (attempt at seamless looping, really?), and other crap, so it got pretty complicated again. fill_audio_out_buffers() is still full of subtle and buggy logic. Maybe it got worse. On the other hand, maybe there really is some progress. Who knows. Originally, the data flow parts was meant to be in f_output_chain, but due to tricky interactions with the playloop code, it's now in the dummy filter in audio.c. At least this improves the way the audio PTS is passed to the encoder in encoding mode. Now it attempts to pass frames directly, along with the pts, which should minimize timestamp problems. But to be honest, encoder mode is one big kludge that shouldn't exist in this way. This commit should be considered pre-alpha code. There are lots of bugs still hiding.
* audio: remove delay debug loggingwm42020-08-231-25/+0
| | | | Some absurd useless stuff.
* audio: redo internal AO APIwm42020-06-011-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | This affects "pull" AOs only: ao_alsa, ao_pulse, ao_openal, ao_pcm, ao_lavc. There are changes to the other AOs too, but that's only about renaming ao_driver.resume to ao_driver.start. ao_openal is broken because I didn't manage to fix it, so it exits with an error message. If you want it, why don't _you_ put effort into it? I see no reason to waste my own precious lifetime over this (I realize the irony). ao_alsa loses the poll() mechanism, but it was mostly broken and didn't really do what it was supposed to. There doesn't seem to be anything in the ALSA API to watch the playback status without polling (unless you want to use raw UNIX signals). No idea if ao_pulse is correct, or whether it's subtly broken now. There is no documentation, so I can't tell what is correct, without reverse engineering the whole project. I recommend using ALSA. This was supposed to be just a simple fix, but somehow it expanded scope like a train wreck. Very high chance of regressions, but probably only for the AOs listed above. The rest you can figure out from reading the diff.
* player: remove some display-adrop leftoverswm42020-05-231-5/+0
| | | | | Forgotten in one of the previous commits. Also undeprecates display-adrop since it's out of sight now.
* audio: redo video-sync=display-adropwm42020-05-231-34/+7
| | | | | | | | | | | | | | | | | This mode drops or repeats audio data to adapt to video speed, instead of resampling it or such. It was added to deal with SPDIF. The implementation was part of fill_audio_out_buffers() - the entire function is something whose complexity exploded in my face, and which I want to clean up, and this is hopefully a first step. Put it in a filter, and mess with the shitty glue code. It's all sort of roundabout and illogical, but that can be rectified later. The important part is that it works much like the resample or scaletempo filters. For PCM audio, this does not work on samples anymore. This makes it much worse. But for PCM you can use saner mechanisms that sound better. Also, something about PTS tracking is wrong. But not wasting more time on this.
* f_decoder_wrapper: replace most public fields with setters/getterswm42020-02-291-5/+5
| | | | | | | | | | | | | | | | | | | I may (optionally) move decoding to a separate thread in a future change. It's a bit attractive to move the entire decoder wrapper to there, so if the demuxer has a new packet, it doesn't have to wake up the main thread, and can directly wake up the decoder. (Although that's bullshit, since there's a queue in between, and libavcodec's multi-threaded decoding plays cross-threads ping pong with packets anyway. On the other hand, the main thread would still have to shuffle the packets around, so whatever, just seems like better design.) As preparation, there shouldn't be any mutable state exposed by the wrapper. But there's still a large number of corner-caseish crap, so just use setters/getters for them. This recorder thing will inherently not work, so it'll have to be disabled if threads are used. This is a bit painful, but probably still the right thing. Like speculatively pulling teeth.
* player: dumb seeking related stuff, make audio hr-seek defaultwm42020-02-281-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | Try to deal with various corner cases. But when I fix one thing, another thing breaks. (And it's 50/50 whether I find the breakage immediately or a few months later.) So results may vary. The default for--hr-seek is changed to "default" (not creative enough to find a better name). In this mode, audio seeking is exact if there is no video, or if the video has only a single frame. This change is actually pretty dumb, since audio frames are usually small enough that exact seeking does not really add much. But it gets rid of some weird special cases. Internally, the most important change is that is_coverart and is_sparse handling is merged. is_sparse was originally just a special case for weird .ts streams that have the corresponding low-level flag set. The idea is that they're pretty similar anyway, so this would reduce the number of corner cases. But I'm not sure if this doesn't break the original intended use case for it (I don't have a sample anyway). This changes last-frame handling, and respects the duration of the last frame only if audio is disabled. This is mostly "coincidental" due to the need to make seeking past EOF trigger player exit, and is caused by setting STATUS_EOF early. On the other hand, this might have been this way before (see removed chunk close to it).
* audio: remove outdated commentwm42020-02-191-2/+0
| | | | | | Neither does it (directly) mess with filters, nor does it return a bool. As noticed by a comment in #6333.
* audio: slightly simplify pull underrun message printingwm42020-02-131-1/+4
| | | | | | | | | | | | | | | A previous commit moved the underrun reporting to report_underruns(), and called it from get_space(). One reason was that I worried about printing a log message from a "realtime" callback, so I tried to move it out of the way. (Though there's little justification other than a bad feeling. While an older version of the pull code tried to avoid any mutexes at all in the callback to accommodate "requirements" from APIs like jackaudio, we gave up on that. Nobody has complained yet.) Simplify this and move underrun reporting back to the callback. But instead of printing the message from there, move the message into the playloop. Change the message slightly, because ao->log is inaccessible, and without the log prefix (e.g. "[ao/alsa]"), some context is missing.
* command: shuffle some crap aroundwm42019-11-251-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | This is preparation to get rid of the option-to-property bridge (mp_on_set_option). This is a pretty insane thing that redirects accesses to options to properties. It was needed in the ever ongoing transition from something to... something else. A good example for the need of this bridge is applying profiles at runtime. This obviously goes through the config parser, but should also make all changes effective, for which traditionally the property layer is used. There isn't much left that needs this bridge. This commit changes a bunch of options (which also have a property implementation) to use option change notifications instead. Many of the properties are still left, but perform unrelated functions like OSD formatting. This should be mostly compatible. There may be some subtle behavior changes. For example, "hwdec" and "record-file" do not check for changes anymore before applying them, so writing the current value to them suddenly does something, while it was ignored before. DVB changes untested, but should work.
* player: remove some unnecessary coverart special caseswm42019-11-171-2/+1
| | | | | | | | These should not be needed, since video is in EOF mode in this case anyway. Not too sure about the video.c case to be honest, well, here goes nothing.
* audio: log A/V initial sync statuswm42019-11-171-0/+3
|
* player: partially rework --cache-pausewm42019-10-111-1/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The --cache-pause feature (enabled by default) will pause playback for a while if network runs out of data. If this is not done, then playback will go on frame-wise (as packets are slowly read from the network and then instantly decoded and displayed). This feature is actually useless, as you won't get nice playback no matter what if network is too slow, but I guess I still prefer this behavior for some reason. This commit changes this behavior from using the demuxer cache state only, to trying to use underrun information from the AO/VO. This means if you have a very large audio buffer, then cache-pausing will trigger once that buffer is depleted, which will be some time _after_ the demuxer cache has run out. This requires explicit support from the AO. Otherwise, the behavior should be mostly the same as before this commit. This does not care about the AO buffer. In theory, the AO may underrun, then the player will write some data to the AO buffer, then the AO will recover and play this bit of data, then the player will probably trigger the cache-pause behavior. The probability of this happening should be pretty low, so I will hold off fixing this until the next refactor of the AO chain (if ever). The VO underflow detection was devised and tested in 5 minutes, and may not be correct. At least I'm fairly sure that the combination of all the factors should make incorrect behavior relatively unlikely, but problems are possible. Also, the demux_reader_state.underrun field may be inaccurate. It's only the present state at the time demux_get_reader_state() was called, and may exclude past underruns. In theory, this could cause "close" cases to be missed. Then you might get an audio underrun without cache-pausing acting on it. If the stars align, this could happen multiple times in the row, effectively making this feature not work. The most user-visible consequence of this change is that the user will now see an AO underrun warning every time the cache runs out. Maybe this cache-pause feature should just be removed...
* ao: add API for underrun reportingwm42019-10-111-0/+2
| | | | | | | | | | | | | | AOs can now call ao_underrun_event() (in any context) if an underrun has happened. It will print a message. This will be used in the following commits. But for now, audio.c only clears the underrun bit, so that subsequent underruns still print the warning message. Since the underrun flag will be used in fragile ways by the playback state machine, there is the "reports_underruns" field that signals strong support for underrun reporting. (Otherwise, underrun events will not be used by it.)
* audio: raise log level of playback reset on audio timestampwm42019-10-061-1/+1