summaryrefslogtreecommitdiffstats
path: root/player/playloop.c
Commit message (Collapse)AuthorAgeFilesLines
* player: avoid busy looping during reinit_subDudemanguy10 days1-2/+18
| | | | | | | | | | | | | | | | | | If the player is paused, switching subtitle track requires us to read subs packets for an indefinite amount of time in order to actually display the subtitles. The problem with this is that it puts a blocking loop in the play thread which can be slow in cases where it takes a long time to fetch the subtitle (e.g. over a network). 9e27b1f523071db184443d78f7144cb599dd0829 alleviates this when a pause happens because of buffering, but it's not complete. One could encounter this if the user pauses the video first manually and then switches the subtitle track. To solve this better, make it so the loop has a time out (totally arbitrary number) so the player isn't blocked forever. If subtitles are not fetched within that time, we flag the track and try again later in the playloop.
* options: add --input-commands optionDudemanguy2024-03-211-0/+1
| | | | | | | Basically a simple way to perform any command/property action from the command line. This takes the exact same syntax as input.conf but not including the key naturally. Potentially useful for weird properties that don't map well to options (like ao-volume). Fixes #12353.
* player/sub: avoid wasteful subtitle redrawsDudemanguy2024-02-151-0/+4
| | | | | | | | | | | | | | | | | This only affects two special cases: printing subtitles to the terminal and printing subtitles on a still picture. Previously, mpv was very dumb here and spammed this logic on every single loop. For terminal subtitles, this isn't as big of a deal, but for the image case this is pretty bad. The entire VO constantly redrew even when there was no need to which can be very expensive depending on user settings. Instead, let's rework sub_read_packets so that it also tells us whether or not the subtitle packets update in some way in addition to telling us whether or not to read more. Since we cache all packets thanks to the previous commit, we can leverage this information to make a guess whether or not the current subtitle packet is supposed to be visible on the screen. Because the redraw now only happens when it is needed, the mp_set_timeout_hack can be removed.
* playloop: use a 16:9 ratio with --force-windowGuido Cella2023-11-301-1/+5
| | | | | | | | | ca2b05c0fb changed the window size with --force-window and no video tracks to be closer to 16:9, but I don't see why we shouldn't have an actual 16:9 ratio. The advantage is that subtitles with fullscreen and no video tracks will have the same size and position (depending on the values of --sub-scale-with-window and --sub-use-margins) as with 16:9 videos, because there will be no (invisible) black bars.
* dispatch: change mp_dispatch_queue_process timer to nanosecondsDudemanguy2023-10-161-1/+1
| | | | | The playloop is the only thing that adjusts the timeout with a value other than 0, so nothing else needs to be changed.
* player: store last_time timestamp in nanosecondsDudemanguy2023-10-101-2/+2
|
* Revert "demux: improve stream selection state"Dudemanguy2023-09-301-9/+0
| | | | | | | | The stream selection state wasn't improved. I didn't realize this messed with caches. All in all, just not a good idea. Back to drawing board I guess. This reverts commit f40bbfec4fcd2d9a787a4d98ec7698a646e5607e.
* timer: rename mp_add_timeout to reflect what it actually doesKacper Michajłow2023-09-291-1/+1
|
* playloop: make chapter property more accurate when seeking chaptersMike Will2023-09-291-5/+10
| | | | | | | | | | | | | | | | | | | | | | When seeking chapters, `last_chapter_seek` acts as a projection of what the current chapter will be once mpv has a chance to seek to it. This allows for more accurate results from the `chapter` property. It works by comparing the projection to the actual current chapter and returning the larger of the two indexes, but this only works when seeking forward. If we want it to work for both forward and backward chapter seeking, we can instead use a boolean called `last_chapter_flag`, which gets switched on when a chapter seek request is made, and then switched off when the seek has been performed. We should also check to ensure that we don't allow the chapter index to be set to -1 unless there is a span of time between the very beginning of the track and the start of the first chapter. Since the new approach to resetting `last_chapter_seek` no longer depends on `last_chapter_pts`, that member variable can be removed.
* playloop: don't refresh seek on external sub streamsDudemanguy2023-09-281-1/+1
| | | | | | External subtitles are always read as eager, so they do not need to be changed on pause/unpause. Don't do the refresh seek since it will just buffer forever. Fixes f40bbfec4fcd2d9a787a4d98ec7698a646e5607e.
* demux: improve stream selection stateDudemanguy2023-09-271-0/+9
| | | | | | | | | | | | | | | | | | | | | | | This replaces the previous commit and makes more sense. The internal demux marked tracks as eager depending on their type and for subtitles it would always lazily read them unless there happened to be no available av stream. However, we want the sub stream to be eager if the player is paused. The existing subtitle is still preserved on the screen, but if the user changes tracks that's when the problem occurs. So to handle this case, propagate the mpctx->paused down to the stream selection logic. This modifies both demuxer_refresh_track and demuxer_select_track to take that boolean value. A few other parts of the player use this, but we can just assume false there (no change in behavior from before) since they should never be related to subtitles. The core player code is aware of its own state naturally, and can always pass the appropriate value so go ahead and do so. When we change the pause state, a refresh seek is done on all existing subtitle tracks to make sure their eager state is the appropriate value (i.e. so it's not still set to eager after a pause and a track switch). Slightly invasive change, but it works with the existing logic instead of going around it so ultimately it should be a better approach. We can additionally remove the old force boolean from sub_read_packets since it is no longer needed.
* options: remove deprecated --record-file optionDudemanguy2023-09-211-3/+0
| | | | | | No wonder wm4 wanted to get rid of this. This option requires touching a bunch of crap in the core player code. --stream-record works perfectly fine and is a lot nicer so there's no need for this to exist anymore.
* mp_image: add force_window fieldDudemanguy2023-09-211-0/+1
| | | | | | It's useful for some VOs (dmabuf-wayland) to know if the image params are actually real or fake ones sent by the core for the purpose of force_window.
* player: use audio pts corresponding to playing audio on EOFllyyr2023-08-251-2/+1
| | | | | | | | | We should account for ao queue when setting playback position on EOF, previously we were using the pts value corresponding to the start of the ao queue, rather than the currently playing audio. This fixes time-remaining being a negative number when mpv seeks to EOF while playback is paused.
* audio: drain ao before setting pauseDudemanguy2023-08-111-2/+4
| | | | | | | | | 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.
* 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 abort() with MP_ASSERT_UNREACHABLE() where appropriatesfan52023-01-121-2/+2
| | | | | | | | In debug mode the macro causes an assertion failure. In release mode it works differently and tells the compiler that it can assume the codepath will never execute. For this reason I was conversative in replacing it, e.g. in mpv-internal code that exhausts all valid values of an enum or when a condition is clear from directly preceding code.
* player/video: add VOCTRL_CONTENT_TYPEDudemanguy2022-11-151-0/+2
| | | | | | | | | | | | mpv's core already keeps track of whether or not it thinks a track is an image. Some VOs (i.e. wayland) would benefit from knowing if what is currently being displayed is an image or not so add a new VOCTRL that signals this anytime we load a new file with a VO. Additionally, let's add a helper enum for signaling the kind of content that is being displayed. There is now MP_CONTENT_NONE (strictly for force window being used on a track with no image/video), MP_CONTENT_IMAGE, and MP_CONTENT_VIDEO. See the next commit for the actual usage of this (with wayland).
* player: set EOF when seeking to end with keep-openDudemanguy2022-05-141-1/+4
| | | | | | | | | | | | | | | Normally with the keep-open option, mpv is supposed to set the eof-reached property to true so clients can possibly do interesting things at this step. However, there was actually an edge case where this property notification did not occur. If you use keep-open and then seek in the file past the end (so mpv stops), property notification is not actually sent in this case. Internally, mpv does a very exact seek at this step which also ends playback, but it does not set STATUS_EOF to the ao and vo before the core idle state is updated. To fix this edge case, it's simply just a matter of explictly setting STATUS_EOF after seek_to_last_frame in handle_keep_open. This logic will only ever trigger if keep-open is being used and the seek goes past the end of the file, so we know that there will always be an EOF here.
* options: add osd-playing-msg-durationGuido Cella2022-04-071-1/+3
|
* options: add always to stop-screensaverDudemanguy2022-02-181-1/+2
| | | | | | | | | | The stop-screensaver option is currently limited to a simple yes/no option. While the no option does always disable mpv trying to stop the screensaver, yes does not mean the screensaver is always stopped. The screensaver will be enabled again depending on certain conditions (like if the player is paused). Simply introduce a new value for this option, always, which does exactly what the name implies: the screensaver will always be disabled.
* player: fix parentheses warning with &&LaserEyess2022-01-181-2/+2
| | | | | | Was tripping -Wparantheses as the && after the || was not explicitly wrapped. However, due to operator precedence the intended effect was still correct.
* player: make deprecated track/chapter/metadata events internalsfan52021-12-151-1/+1
| | | | | We still need these to track or notify of modifications to certain properties, but they're now gone from the libmpv ABI.
* libmpv: remove opengl_cb API and other deprecated symbolssfan52021-12-151-4/+0
| | | | | | Not all deprecated symbols were removed. Only three events were removed for now since these are not used internally. This bumps the library version to 2.0.
* player: make --keep-open=always work with --loop-playlistLeo Izen2021-11-281-2/+2
| | | | | | | | Allow --keep-open=always to work with --loop-playlist, where before this patch it would work only on the last playthrough of the playlist. This patch allows it to work on all playthroughs. Fixes #9470.
* player: fix missed pause state update during reset in some casessfan52021-07-181-0/+4
| | | | | | | | When playing a new file, if paused_for_cache was true before being reset the AO would never be unpaused because that state was thrown away, leaving it stuck. Fix this by updating the pause state before resetting that variable. Note that this does not make the second update_internal_pause_state() call redundant. This fixes the same bug fb5d976cb0 was supposed to.
* command: add internal INPUT_PROCESSED eventAvi Halachmi (:avih)2020-11-161-0/+4
| | | | | | Fires after a non-empty input queue was processed. Currently yet unused, but the next commit will use it.
* player: add pause state to playback start messagewm42020-09-211-2/+3
| | | | | Now the player tells you that audio or video are playing while paused, or something.
* player: fix inconsistent AO pause state in certain situationswm42020-09-121-1/+1
| | | | | | | | | | | | | | | | | | Pause can be changed during a file change, such as with for example --reset-on-next-file=pause, or in hooks, or by being quick, and in this case the AO's pause state was not updated correctly. mpctx->ao_chain is only set if playback is fully initialized, while the AO itself in mpctx->ao can be reused across files. Fix this by always running set_pause_state() if the pause option is changed. Could cause new bugs since running this used to be explicitly avoided outside of the loaded state. The handling of time_frame is potentially worrisome. Regression due to recent audio refactor; before that, the AO didn't have a separate/persistent pause state. Fixes: #8079
* player: some minor code golfwm42020-09-101-11/+6
|
* player: clamp relative seek base time to nominal durationwm42020-09-101-1/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since b74c09efbf7, audio-only files let you seek to arbitrary points beyond the end of the file (but still displayed the time clamped to the nominal file duration). This was confusing and just not wanted. The reason is probably that the commit removed setting the audio PTS for data before the seek target, so if you seek past the end of the file, the audio PTS is never set. This in turn means the logic to determine the current playback time has no PTS at all, and thus falls back to the seek PTS. This happened in the past for other reasons (like efe43d768f). I have enough of this, so I'm just changing the code to clamp the seek timestamp to a "known" range. Do this when seeking ends, because in the fallback case, the playback time shouldn't be stuck at e.g. "end + seek_argument". Also do it when initiating a new seek (mp_seek), because if the previous seek hasn't finished yet, it shouldn't add them up and allow it to go "out of range" either. The latter is especially relevant for hr-seeks. Doing this clamping is problematic because the duration is a possibly invalid value from the demuxer, or just missing. Especially with timestamp resets, fun sometimes happens, and in these situations it might be better not to clamp. One could argue you should just use the last audio timestamp returned by the decoder or demuxer (even if that directly conflicts with --end), but that sounds even more hairy. In summary: what a dumb waste of time, what the fuck.
* command: add read-only focused propertyGuido Cella2020-09-081-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Add a property that returns whether the window is focused, currently only for X11 and Wayland. My use cause for this is having an equivalent of pause-when-minimize.lua for tiling window managers: make mpv play only while it's in the current workspace or is focused (I'm fine with either one but prefer focus). On X I do this by observing display-names, which is empty when the rectangles of the display and mpv don't intersect, but on Wayland its value doesn't change when mpv leaves the current workspace (and the same check doesn't work since the geometries still intersect). This could later be made writable as requested in #6252. Note that on Wayland se shouldn't consider an unactivated window with keyboard input focused. The wlroots compositors I tested set activated after changing the keyboard focus, so if you set wl->focused only in keyboard_handle_enter() and keyboard_handle_leave() to avoid adding the "has_keyboard_input" member, focused isn't set to true when first opening mpv until you focus another window and focus mpv again. Conversely, if that order can't be assumed for all compositors, we should toggle wl->focused when necessary in keyboard_handle_enter() and keyboard_handle_leave() as well as in handle_toplevel_config().
* encode: propagate errors to exit status properlywm42020-09-031-1/+1
| | | | | Don't just let mpv CLI return 0 (success) as exit status if encoding failed somehow.
* player/playloop.c: reorder included headers per contribute.mdLeo Izen2020-08-311-17/+14
| | | | | This commit sorts the included headers alphabetically and puts them in sections, as described by DOCS/contribute.md.
* audio: refactor how data is passed to AOwm42020-08-291-13/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* player: fix video paused condition on VO creationwm42020-08-271-1/+6
| | | | | Doesn't take paused_for_cache into account. For consistency; unlikely to matter at all in practice.
* player: fix swapped debug outputwm42020-08-271-2/+2
| | | | Such failure.
* player: do not loop if there's nothing to loopwm42020-08-221-0/+5
| | | | | | | | | | | | | | | | | This can happen if a file contains headers only, or if decoding of all data failed, and such. Interestingly, it also happened when doing "mpv --loop emptyfile.png", because demux_mf still detects file formats by file extension. In this situation, the player burned a lot of CPU by restarting playback after doing nothing. Although such "degenerate" behavior can't be avoided in all situations (what if you loop a file with 1 audio sample?), detecting this seems to make sense. For now, this actually decrements the loop count by 1, and then errors out with a warning. Works for --loop and --ab-loop, while --loop-playlist already avoids this situation with an existing mechanism.
* player: make unpausing directly after seek work with --keep-open (again)wm42020-06-101-0/+3
| | | | | | | | | | | | Commit fcf0b80dc9dd3 fixed this the first time. Commit 85576f31a9cc2 "accidentally" removed this code again. The commit message justifying the removal is correct, except it doesn't take other side-effects of the state machine into account. I obviously didn't remember what exactly this was about. So add a comment explaining it this time. Just apply it again; the thing the latter commit fixed still works. Fixes: #7819
* player: round position percentage to the nearest integerRicardo Garcia2020-05-011-1/+1
| | | | | | This brings the displayed percentage closer to the exact number and allows mpv to more frequently display 100% when it finishes playing a typical video or audio file.
* player, stats: more silly debug stuffwm42020-04-101-0/+3
| | | | | In addition to stats.c being gross, I don't think master branch code should be littered with debug code. But it's a helpful abomination.
* player: make a function staticwm42020-04-031-1/+1
|
* player: fix subtle idle mode differences on early program startwm42020-03-211-3/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the user manages to run a "loadfile x append" command before the loop in mp_play_files() is entered, then the player could start playing these. This isn't expected, because appending files to the playlist in idle mode does not normally start playback. It could happen because there is a short time window where commands are processed before the loop is entered (such as running the command when a script is loaded). The idle mode semantics are pretty weird: if files were provided in advance (on the command line), then these should be played immediately. But if idle mode was already entered, and something is appended to the playlist using "append", i.e. without explicitly triggering playback, then it should remain in idle mode. Try to follow this by redefining PT_STOP to strictly mean idle mode. Remove the playlist->current check from idle_loop(), since only the stop_play field counts now (cf. what mp_set_playlist_entry() does). This actually introduces the possibility that playlist->current, and with it playlist-pos, are set to something, even though playback is not active or being started. Previously, this was only possible during state transitions, such as when changing playlist entries. Very annoyingly, this means the current way MPV_EVENT_IDLE was sent doesn't work anymore. Logically, idle mode can be "active" even if idle_loop() was not entered yet (between the time after mp_initialize() and before the loop in mp_play_files()). Instead of worrying about this, redo the "idle-active" property, and deprecate the event. See: #7543
* options: split m_config.c/hwm42020-03-131-1/+1
| | | | | | | | | | | | | | | | | Move the "old" mostly command line parsing and option management related code to m_config_frontend.c/h. Move the the code that enables other part of the player to access options to m_config_core.c/h. "frontend" is out of lack of creativity for a better name. Unfortunately, the separation isn't quite clean yet. m_config_frontend.c still references some m_config_core.c implementation details, and m_config_new() is even left in m_config_core.c for now. There some odd functions that should be removed as well (marked as "Bad functions"). Fixing these things requires more changes and will be done separately. struct m_config is left with the current name to reduce diff noise. Also, since there are a _lot_ source files that include m_config.h, add a replacement m_config.h that "redirects" to m_config_core.h.
* filter: minor cosmetic naming issuewm42020-03-081-1/+1
| | | | | Just putting some more lipstick on the pig, maybe it looks a bit nicer now.
* player: force update of cache properties even on inactive demuxer cachewm42020-03-051-1/+6
| | | | | | | | | | | | | | | | | | | | | | | | | When the demuxer cache read until the end of the stream, and was finished and completely inactive, the cache properties were not updated anymore via MP_EVENT_CACHE_UPDATE. Unfortunately, many cache properties depend on the current playback position, such as cache-duration or fw-bytes. This is especially visible on the OSC. If everything was cached, seeking around didn't update the displayed forward cache duration. That means checking demuxer_reader_state.idle is not enough. You also need to check whether the current playback position changed. Fix this by explicitly using the current playback position, and update the properties if it changed "enough". "Enough" is 1 second of media time in this example, which may or may not be appropriate. In general, this could probably be done better. There are many other triggers that change the cache state and that are not covered. For now I'm content with getting rid of the obvious problems. I think the OSC problem in particular was caused by changing it from polling to using property change notifications.
* options: make decoder options local to decoder wrapperwm42020-03-011-2/+1
| | | | | | | | | | | | | | | Instead of having f_decoder_wrapper create its own copy of the entire mpv option tree, create a struct local to that file and move all used options to there. movie_aspect is used by the "video-aspect" deprecated property code. I think it's probably better not to remove the property yet, but fortunately it's easy to work around without needing special handling for this option or so. correct_pts is used to prevent use of hr-seek in playloop.c. Ignore that, if you use --no-correct-pts you're asking for trouble anyway. This is the only behavior change.
* player: add optional separate video decoding threadwm42020-02-291-1/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | |