summaryrefslogtreecommitdiffstats
path: root/audio
Commit message (Collapse)AuthorAgeFilesLines
* audio: react to --ao and --audio-buffer runtime changeswm42019-12-271-3/+3
| | | | | | Before this commit, runtime changes were only applied if something else caused audio to be reinitialized. Now setting them reinitializes audio explicitly.
* options: get rid of GLOBAL_CONFIG hackwm42019-11-291-1/+1
| | | | | | | Just an implementation detail that can be cleaned up now. Internally, m_config maintains a tree of m_sub_options structs, except for the root it was not defined explicitly. GLOBAL_CONFIG was a hack to get access to it anyway. Define it explicitly instead.
* audio: add ao_audiotrack for androidAman Gupta2019-11-192-0/+721
|
* audio: fix minor whitespace issue in out/internal.hAman Gupta2019-11-191-1/+1
|
* audio: more alignment nonsensewm42019-11-101-1/+5
| | | | | | | | | | | It's hard to see what FFmpeg does or what its API requires. It looks like the alignment in our own allocation code might be slightly too lenient, but who knows. Even if this is not needed, upping the alignment only wastes memory and doesn't do anything bad. (Note that the only reason why we have our own code is because FFmpeg doesn't even provide it as API. API users are forced to recreate this, even if they have no need for custom allocation!)
* audio: work around ffmpeg being a piece of shitwm42019-11-101-2/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The "amultiply" filter crashes in AVX mode on unaligned access if an audio pointer is unaligned (on 32 or 64 bytes I assume). A requirement that audio data needs to be aligned isn't documented anywhere. In our case, the data is still sample- and channel-aligned, which is completely sane. Sure, you can imagine optimizations which make some algorithms even faster by requiring higher alignment. But, and this is a big but, you shouldn't crash api users because you just invented a new undocumented requirement. And even more importantly, your user-crashing optimization won't matter because it's just a trivial algorithm working on audio. You don't need to pretend to be an optimization devil, and nobody will give you a prize for this. But no, lets random make API users crash (and then probably blame them for it!) for something that wouldn't matter at all. Not to mention that they do "document" some requirements on _video_ data, yet their vf_crop probably can still produce unaligned video pointers. Oh how hilarious that the same documentation also talks about libswscale alignment requirements. (This is weird because libswscale is just one of many, many things which consume video data. Also did you know that zimg, written in C++ and using intrinsics, i.e. the antithesis to FFmpeg development, is much faster than libswscale, easier to use, and produces more correct results, even if you ignore that libswscale flat out doesn't support some very important features?) Fucking tired of this bullshit. Can't wait until someone comes up with a better framework than this... (well let's not write this out). Fix this by copying instead of adjusting the start pointer when skipping samples. This makes general operations slower just to fix interoperating with a single filter. Thank you for your "optimization", FFmpeg. Go die in a fire. Didn't check whether this is correct. It probably is? If the frame needs to be copied (due to COW), and memory allocation fails, it just silently (or audibly lol) doesn't skip samples, because a never-fail function can suddenly fail. Well, who cares. Fixes: #7141
* Replace uses of FFMIN/MAX with MPMIN/MAXwm42019-10-311-2/+2
| | | | And remove libavutil includes where possible.
* ad_lavc, vd_lavc: return full error codes to shared decoder loopwm42019-10-241-14/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
* input: add gamepad support through SDL2Stefano Pigozzi2019-10-231-1/+1
| | | | | | | | | | | | | | | The code is very basic: - only handles gamepads, could be extended for generic joysticks in the future. - only has button mappings for controllers natively supported by SDL2. I heard more can be added through env vars, there's also ways to load mappings from text files, but I'd rather not go there yet. Common ones like Dualshock are supported natively. - analog buttons (TRIGGER and AXIS) are mapped to discrete buttons using an activation threshold. - only supports one gamepad at a time. the feature is intented to use gamepads as evolved remote controls, not play multiplayer games in mpv :)
* audio/out: rip out old unused app/softvolume reportingwm42019-10-117-21/+0
| | | | | | | | | | | This was all dead code. Commit 995c47da9a (over 3 years ago) removed all uses of the controls. It would be nice if AOs could apply a linear gain volume, that only affects the AO's audio stream for low-latency volume adjust and muting. AOCONTROL_HAS_SOFT_VOLUME was supposed to signal this, but to use it, we'd have to thoroughly check whether it really uses the expected semantics, so there's really nothing useful left in this old code.
* audio/out/pull, ao_sdl: implement new underrun reportingwm42019-10-112-2/+8
| | | | | | | | | | | | | | | | See previous commits. ao_sdl is worthless, but it might be a good test for pull-based AOs. This stops using the old underrun reporting if the new one is enabled. Also, since the AO's behavior can in theory not be according to expectations, this needs to be enabled for every single pull AO separately. For some reason, in certain cases I get multiple underrun warnings while cache-pausing is active. It fills the cache, restarts the AO, immediately underruns again, and then fills the cache again. I'm not sure why this happens; maybe ao_sdl tries to catch up when it shouldn't. Who knows.
* audio/out/pull: fix underflow reportingwm42019-10-111-2/+2
| | | | | | | | I think this was _always_ wrong. Due to the line above the first changed line, buffered_bytes==bytes always. I can only hope I broke this in a less under-tested edit when I originally wrote this. Fixes: c5a82f729bd097
* ao_alsa: use AO underrun reportingwm42019-10-111-1/+3
| | | | This enables the change introduced in the previous commit for ao_alsa.
* ao: add API for underrun reportingwm42019-10-113-1/+23
| | | | | | | | | | | | | | 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.)
* ao_alsa: handle underruns in get_space() toowm42019-10-111-0/+2
| | | | | This is essentially optional. But it will give the higher level code a better guarantee that underruns were tested.
* ao_alsa: mess with underrun handling againwm42019-10-111-6/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit tries to prepare for better underrun reporting. The goal is to report underruns relatively immediately. Until now, this happened only when play() was called. Change this, and abuse that get_delay() is called "relatively often" - this reports the underrun immediately in practice. Background: In commit 81e51a15f7e1 (and also e38b0b245ed4), we were quite confused about ALSA underrun handling. The commit message showed uncertainty how case 3 happened, but it's blindingly obvious and simple. Actually reading the code shows that ALSA does not have a concept of a "final chunk" (or we don't use it). It's obvious we never pass the AOPLAY_FINAL_CHUNK flag along to the ALSA API in any way. The only thing we do is simply writing a partial fragment. Of course this will cause an underrun. Doing a partial write saves us the trouble to pad the last frame with silence, or so. The main reason why the underrun message was avoided was that play() was never called with a non-0 sample count again (except if reset() was called before that). That was OK, at least the goal of avoiding the unwanted message was reached. (And the original "bogus" message at end of playback was perfectly correct, as far as ALSA goes.) If network stalls, play() will called again only once new data is available. Obviously, this could take a long time, thus it's too late.
* ao_alsa: don't silence legitimate underrun if final chunk underrunswm42019-10-061-4/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | It turns out that case 2) mentioned in the previous commit happened quite often when playback ended normally. There is probably a legitimate underrun with normal buffer sizes (100 ms, 4 fragments, gapless audio in "weak" mode). This is a result of the player waiting for video to end, and/or the time needed to kill the video window. The former case means that it depends on your test case whether it happens (a file where video ends slightly before audio is less likely to trigger it). This in turn is due to how gapless playback works. Achieving not having a "gap" requires queuing the audio of the next file without playing a partial chunk (as AOPLAY_FINAL_CHUNK would do). The partial chunk is then played as part of the first chunk played from the next file. But if it detects "later" that there is no next file, it still needs to get rid of the last fragment with AOPLAY_FINAL_CHUNK. At this point it's too late, and an underrun may have actually happened. The way the player uninits and reinits the entire playback engine for the next file in a "serial" manner means it cannot know in advance whether this works. This is the reason why the idiot who added the underrun exception for the last chunk in play() was wrong (I wrote that btw., before you accuse me of being rude). Yes, it's a real underrun, and you could probably hear it.
* ao_alsa: remove sometimes bogus XRUN messagewm42019-10-061-9/+2
| | | | | | | | | | | | | | | | | | | This XRUN (aka underrun) message was printed in the following situations: 1) legitimate underrun during playback 2) legitimate underrun when playing final chunk 3) bogus underrun when playing final chunk The old underrun case (in play()) happens in cases 1) and 2) as well, but 3) did not happen. It appears 3) is indeed something that happens, although it's not known for sure. It's still pretty annoying, so remove the new XRUN message. When testing, care should be taken to play with buffer sizes, video versus no video, and gapless enabled/disabled. Also, suspending the player with Ctrl+Z in the terminal (SIGSTOP) and then resuming is a good way to trigger a "normal" underrun.
* audio/filter: remove no longer used headerPaul B Mahol2019-10-051-47/+0
|
* audio: fix copy&paste errorwm42019-09-271-1/+1
| | | | | | | This wasn't used at all in my tests, because it simply passed the frame directly to libswsresample. (And, by the way, will always do that, because s64 is so obscure literally NOTHING uses it except a sample specifically created to test this code. Screw FFmpeg.)
* ad_lavc: log on failure to read AVFramewm42019-09-271-1/+3
| | | | | | | | This can be due to unsupported sample formats (see previous commits), minor allocation failures, and similar things. For identifying the exact cause it's buried too deep in abstractions. But most time it doesn't happen anyway, since it's extremely rare that new audio formats are added.
* audio: add support for AV_SAMPLE_FMT_S64*wm42019-09-273-0/+8
| | | | | | | | | | What an idiotic format. It makes no sense, and should have been converted to S32 in the demuxer, rather than plague everyone with another extremely obscure nonsense format. Why doesn't ffmpeg add S24 instead? That's an actually useful format. May cause compilation failure with old FFmpeg or Libav libs, but I don't care.
* options: add M_OPT_FILE to some more options that take filesPhilip Sequeira2019-09-271-1/+1
|
* ao_pulse: add the newly added mappings for TrueHD/DTS-HD formatsJan Ekström2019-09-271-6/+11
| | | | | Originally DTS-HD was mapped to PA_ENCODING_DTS_IEC61937 which I'm actually not sure if it ever worked.
* ao_oss: Fallback to stereo when the device does not support >2 channelsLeonardo Taccari2019-09-211-6/+10
| | | | | | | | ioctl(..., SNDCTL_DSP_CHANNELS, &nchannels) for not supported nchannels does not return an error and instead set nchannels to the default value. Instead of failing with no audio, fallback to stereo.
* ao_pulse: add --pulse-allow-suspendedTérence Clastres2019-09-211-1/+3
| | | | | | | | | | This flag makes mpv continue using the PulseAudio driver even if the sink is suspended. This can be useful if JACK is running with PulseAudio in bridge mode and the sink-input assigned to mpv is the one JACK controls, thus being suspended. By forcing mpv to still use PulseAudio in this case, the user can now adjust the sink to an unsuspended one.
* audio: remove unreferenced af_lavrresamplewm42019-09-191-112/+0
| | | | | | | | | | | | | | This filter wasn't referenced anywhere and thus was dead code. It should have been in the audio filter list in user_filters.c. This was intended as compatibility wrapper (to avoid breaking old command lines and config files), and has no real use. Apparently I forgot to add it to the filter list (did I even test this shit?), and so it was rotting around for 1.5 years doing nothing (just like myself). Note that users can just use the libavfilter provided filter to force resampling, just that it has a different name and different options. There's also af_format to force inserting auto conversion through the internal f_swsresample filter.
* audio_buffer: fix some more theoretical UBwm42019-09-191-0/+3
| | | | | | | This may call memmove() with size==0 and a NULL data pointer. In addition to this being UB with memmove(), I think it's UB to do arithmetic on a NULL pointer too. Of course, this doesn't matter in practice at all, and is just stupidity to torture programmers.
* ad_lavc: skip fully skipped frameswm42019-09-191-1/+5
| | | | | | | | | | | Fixes stupid messages with a opus/mkv test file that had an absurdly huge codec delay. This file fully skips several frames at the start. ad_lavc.c trimmed these frames to 0 samples and returned them. The next layer (f_decoder_wrapper.c) saw discontinuous PTS values, because the PTS values increased by a frame, but amounted to 0 audio samples. This was harmless, but logged PTS discontinuity errors.
* Implement backwards playbackwm42019-09-192-0/+54
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | See manpage additions. This is a huge hack. You can bet there are shit tons of bugs. It's literally forcing square pegs into round holes. Hopefully, the manpage wall of text makes it clear enough that the whole shit can easily crash and burn. (Although it shouldn't literally crash. That would be a bug. It possibly _could_ start a fire by entering some sort of endless loop, not a literal one, just something where it tries to do work without making progress.) (Some obvious bugs I simply ignored for this initial version, but there's a number of potential bugs I can't even imagine. Normal playback should remain completely unaffected, though.) How this works is also described in the manpage. Basically, we demux in reverse, then we decode in reverse, then we render in reverse. The decoding part is the simplest: just reorder the decoder output. This weirdly integrates with the timeline/ordered chapter code, which also has special requirements on feeding the packets to the decoder in a non-straightforward way (it doesn't conflict, although a bugmessmass breaks correct slicing of segments, so EDL/ordered chapter playback is broken in backward direction). Backward demuxing is pretty involved. In theory, it could be much easier: simply iterating the usual demuxer output backward. But this just doesn't fit into our code, so there's a cthulhu nightmare of shit. To be specific, each stream (audio, video) is reversed separately. At least this means we can do backward playback within cached content (for example, you could play backwards in a live stream; on that note, it disables prefetching, which would lead to losing new live video, but this could be avoided). The fuckmess also meant that I didn't bother trying to support subtitles. Subtitles are a problem because they're "sparse" streams. They need to be "passively" demuxed: you don't try to read a subtitle packet, you demux audio and video, and then look whether there was a subtitle packet. This means to get subtitles for a time range, you need to know that you demuxed video and audio over this range, which becomes pretty messy when you demux audio and video backwards separately. Backward display is the most weird (and potentially buggy) part. To avoid that we need to touch a LOT of timing code, we negate all timestamps. The basic idea is that due to the navigation, all comparisons and subtractions of timestamps keep working, and you don't need to touch every single of them to "reverse" them. E.g.: bool before = pts_a < pts_b; would need to be: bool before = forward ? pts_a < pts_b : pts_a > pts_b; or: bool before = pts_a * dir < pts_b * dir; or if you, as it's implemented now, just do this after decoding: pts_a *= dir; pts_b *= dir; and then in the normal timing/renderer code: bool before = pts_a < pts_b; Consequently, we don't need many changes in the latter code. But some assumptions inhererently true for forward playback may have been broken anyway. What is mainly needed is fixing places where values are passed between positive and negative "domains". For example, seeking and timestamp user display always uses positive timestamps. The main mess is that it's not obvious which domain a given variable should or does use. Well, in my tests with a single file, it suddenly started to work when I did this. I'm honestly surprised that it did, and that I didn't have to change a single line in the timing code past decoder (just something minor to make external/cached text subtitles display). I committed it immediately while avoiding thinking about it. But there really likely are subtle problems of all sorts. As far as I'm aware, gstreamer also supports backward playback. When I looked at this years ago, I couldn't find a way to actually try this, and I didn't revisit it now. Back then I also read talk slides from the person who implemented it, and I'm not sure if and which ideas I might have taken from it. It's possible that the timestamp reversal is inspired by it, but I didn't check. (I think it claimed that it could avoid large changes by changing a sign?) VapourSynth has some sort of reverse function, which provides a backward view on a video. The function itself is trivial to implement, as VapourSynth aims to provide random access to video by frame numbers (so you just request decreasing frame numbers). From what I remember, it wasn't exactly fluid, but it worked. It's implemented by creating an index, and seeking to the target on demand, and a bunch of caching. mpv could use it, but it would either require using VapourSynth as demuxer and decoder for everything, or replacing the current file every time something is supposed to be played backwards. FFmpeg's libavfilter has reversal filters for audio and video. These require buffering the entire media data of the file, and don't really fit into mpv's architecture. It could be used by playing a libavfilter graph that also demuxes, but that's like VapourSynth but worse.
* ao_opensles: fix delayed audiosfan52019-09-021-1/+1
| | | | | This was forgotten in commit 5a8c48fde2a26fe00c3552e3ccf83a965b6d3576 when the number of buffers was reduced to 1.
* ao/audiounit: include AVAudioSession buffer in latency calcAman Gupta2019-04-051-1/+1
| | | | Signed-off-by: Aman Gupta <aman@tmm1.net>
* ao/audiounit: improve a/v syncAman Gupta2019-04-053-4/+18
| | | | | | | This more closely mimics ao_coreaudio, on which this driver was originally based. Signed-off-by: Aman Gupta <aman@tmm1.net>
* Merge commit '559a400ac36e75a8d73ba263fd7fa6736df1c2da' into ↵Anton Kindestam2018-12-053-5/+33
|\ | | | | | | | | | | wm4-commits--merge-edition This bumps libmpv version to 1.103
| * player: get rid of mpv_global.optswm42018-05-241-2/+4
| | | | | | | | | | | | | | | | This was always a legacy thing. Remove it by applying an orgy of mp_get_config_group() calls, and sometimes m_config_cache_alloc() or mp_read_option_raw(). win32 changes untested.
| * ao: use a local option structwm42018-05-242-3/+29
| | | | | | | | Instead of accessing MPOpts.
* | ad_spdif: cosmetic alignmentJan Ekström2018-10-301-1/+1
| |
* | ad_spdif: fix DTS-HD HRA handlingJan Ekström2018-10-301-2/+10
| | | | | | | | | | | | | | | | | | | | | | | | Apparently, for bit streaming DTS-HD MA is specified to be handled as an eight channel (7.1) bit stream, while DTS-HD HRA is specified to be handled as a stereo bit stream. Define a variable for this, and utilize it to set the correct values for both the DTS-HD bit streaming rate, as well as the channel count for the SPDIF encoder. Fixes #6148
* | ao_audiounit: rename pause function to resetJosh Lehman2018-09-301-1/+1
| | | | | | | | | | AudioUnit output driver uses the pull based api so it should have a reset function instead of a pause function.
* | ao_alsa: log the ALSA state if we get a non-XRUN errorJan Ekström2018-09-291-2/+4
| | | | | | | | | | The ALSA state generally can tell us more information in case we get an unexpected error.
* | ao_alsa: handle XRUNs separately from other errorsJan Ekström2018-09-291-2/+7
| | | | | | | | | | | | | | | | | | According to ALSA doxy, EPIPE is a synonym to SND_PCM_STATE_XRUN, and that is a state that we should attempt to automatically recover from. In case recovery fails, log an error and return zero. A warning message will still be output for each XRUN since those are not something we should generally be receiving.
* | ao_alsa: early exit get_space if paused or ALSA is not readyJan Ekström2018-09-291-0/+5
| | | | | | | | | | | | | | | | | | | | | | This has been way too long coming, and for me to notice that a whole lot of ao_alsa functions do an early return if the AO is paused. For the STATE_SETUP case, I had this reproduced once, and never since. Still, seems like we can start calling this function before the ALSA device has been fully initialized so we might as well early exit in that case.
* | ao_jack: only auto-connect to audio portsNiklas Haas2018-09-261-1/+2
| | | | | | | | | |