`core-idle` depends on seeking state `mpctx->restart_complete`,
so make `core-idle` notified whenever `seeking` is notified, too.
`paused-for-cache` can be changed on MPV_EVENT_CACHE_UPDATE obviously.
Finally, `MPV_EVENT_PLAYBACK_RESTART` should be notified after
`mpctx->restart_complete` changed.
Conflicts:
player/command.c
The percent-pos property normally goes by time, except for file formats
like .ts or .ogg, where you can't trust the timestamps and duration info
to compute the position in the overall files. These use the byte
position and size instead.
When the file position was unavailable (e.g. due to an ongoing seek),
the percent-pos was unknown. Change it to use the time position instead.
In most cases, it's actually accurate enough, and the temporary
unavailability of the property can be annoying, e.g. on the terminal
status line.
I don't know why this done; most likely it had no real reason.
Remove it because it breaks "refresh seeks" to the same position.
(Although the refresh seeks mpv sometimes does were fine.)
Ordered chapter EOF was handled as special-case of ending the last
segment. This broke --kee-open, because it set AT_END_OF_FILE in an
"inconvenient" place (after checking for --keep-open, and before the
code that exits playback if EOF is reached).
We don't actually need to handle the last segment specially. Instead, we
remain in the same segment if it ends. The normal playback logic will
recognize EOF, because the end of the segment "cuts off" the file.
Now timeline_set_from_time() never "fails", and we can remove the old
segment EOF handling code in mp_seek().
Add a generic mechanism to the VO to relay "extra" events from VO to
player. Use it to notify the core of window resizes, which in turn will
be used to mark all affected properties ("window-scale" in this case) as
changed.
(I refrained from hacking this as internal command into input_ctx, or to
poll the state change, etc. - but in the end, maybe it would be best to
actually pass the client API context directly to the places where events
can happen.)
Instead of defining a separate data structure in the core.
For some odd reason, demux_chapter exported the chapter time in
nano-seconds. Change that to the usual timestamps (rename the field
to make any code relying on this to fail compilation), and also remove
the unused chapter end time.
Without --force-window, this is called on every iteration or so, and
calling uninit_video_out() sends the video-reconfig event. Avoid sending
redundant events.
Fixes#1225 (using an alternative patch).
This could produce an extra frame, because reaching the maximum merely
signals the playloop to exit, without strictly enforcing the limit.
Fixes#1181.
CC: @mpv-player/stable
Manually setting can break things forever, because it puts the VO cursor
state out of sync with the remembered state by handle_cursor_autohide().
Use the normal autohide code during idle mode too instead. (Originally
the idea was to make the cursor always visible in idle mode, but not so
important.)
Regression since e1e8b07c. Fixes#1166.
CC: @mpv-player/stable
This was added with commit 3cbd79b3, but it turns out this
unintentionally enables "real" pausing when seeking while buffering. It
was done for ensuring correct state of the "cache-buffering-state"
property, but it also turns out that this was unneeded (another variable
that is reset when seeking happens to take care of this).
Run opening the stream and opening the demuxer in a separate thread.
This should remove the last code paths in which the player can normally
get blocked on network.
When the stream is opened, the player will still react to input and so
on. Commands to abort opening can also be handled properly, instead of
using some of the old hacks in input.c. The only thing the user can
really do is aborting loading by navigating the playlist or quitting.
Whether playback abort works depends on the stream implementation; with
normal network, this will depend on what libavformat (via "interrupt"
callback) does.
Some pain is caused by DVD/BD/DVB. These want to reload the demuxer
sometimes. DVB wants it in order to discard old, inactive streams.
DVD/BD for the same reason, and also for reloading stream languages
and similar metadata. This means the stream and the demuxer have to
be loaded separately.
One minor detail is that we now need to copy all global options. This
wasn't really needed before, because the options were accessed on
opening only, but since opening is now on a separate thread, this
obviously becomes a necessity.
When the VO was moved it its own thread, responsibility for redrawing
was given to the VO thread itself. So if there was a condition that
indicated that redrawing was required, like expose events or certain
VOCTRLs, the VO thread was redrawing itself.
This worked fine, but there are some corner cases where this works
rather badly. E.g. if I fullscreen the player and hit panscan controls
with mpv's default autorepeat rate, playback stops. This happens because
the VO redraws itself after every panscan change command. Running each
(repeated) command takes so long due to redrawing and (involuntary)
waiting on vsync, that it never leaves the input processing loop while
the key is held down. I suspect that in my case, redrawing in fullscreen
mode just gets slow enough that it takes 2 vsyncs instead of 1 on
average, and the processing time gets larger than the autorepeat delay.
Fix this by taking redraw control from the VO, and instead let the
playloop issue a "real" redraw command to the VO if needed. This
basically reverts redraw handling to what it was before moving the VO to
a thread.
CC: @mpv-player/stable
Each subsystem (or similar thing) had an INITIALIZED_ flag assigned. The
main use of this was that you could pass a bitmask of these flags to
uninit_player(). Except in some situations where you wanted to
uninitialize nearly everything, this wasn't really useful. Moreover, it
was quite annoying that subsystems had most of the code in a specific
file, but the uninit code in loadfile.c (because that's where
uninit_player() was implemented).
Simplify all this. Remove the flags; e.g. instead of testing for the
INITIALIZED_AO flag, test whether mpctx->ao is set. Move uninit code
to separate functions, e.g. uninit_audio_out().
There's no need to update OSD messages and the terminal status if nobody
is going to see it. Since the player doesn't block on video display
anymore, this update happens to often and probably burns slightly more
CPU than necessary. (OSD redrawing is handled separately, so it's just
mostly useless text processing and such.)
Change it so that it's updated only on every video frame or all 50ms
(whatever comes first).
For VO OSD, we could in theory try to lock to the OSD redraw heuristic
or the display refresh rate, but that's more complicated and doesn't
work for the terminal status.
When using --force-window (and no video or cover art), this heuristic
prevents any redrawing during seeking. It should be applied only if
there is any form of video.
E.g. --loop-file=2 will play the file 3 times (one time normally, and 2
repeats).
Minor syntax issue: "--loop-file 5" won't work, you have to use
"--loop-file=5". This is because "--loop-file" still has to work for
compatibility, so the "old" syntax with a space between option name and
value can't work.
Idle mode went to sleep too early, e.g. just pressing "ESC" did nothing,
until the next event happened. This was because it directly went to
sleep after processing commands. What we should do instead is rechecking
all state after processing commands, redraw OSD, and then go to sleep.
This also fixes some strange OSD-related behavior.
Also move some other code around to separate idle mode initialization
from the normal run loop.
Do terminal input with a thread, instead of using the central select()
loop. This also changes some details how SIGTERM is handled.
Part of my crusade against mp_input_add_fd().
Continues commit 348dfd93. Replace other places where input was manually
fetched with common code.
demux_was_interrupted() was a weird function; I'm not entirely sure
about its original purpose, but now we can just replace it with simpler
code as well. One difference is that we always look at the command
queue, rather than just when cache initialization failed. Also, instead
of discarding all but quit/playlist commands (aka abort command), run
all commands. This could possibly lead to unwanted side-effects, like
just ignoring commands that have no effect (consider pressing 'f' for
fullscreen right on start: since the window is not created yet, it would
get discarded). But playlist navigation still works as intended, and
some if not all these problems already existed before that in some
forms, so it should be ok.
Expose the central event handling functions explicitly, so that other
parts of the player can use them.
No functional changes. Preparation for the next commit.
The player didn't quit when seeking past EOF in audio-only mode while
paused. The only case when we don't want to quit is when the last video
frame is displayed while paused.
This logic was probably broken a while ago, but I'm not exactly sure.
CC: @mpv-player/stable
Add a mechanism to the client API code, which allows the player core to
query whether a client API event is needed at all. Use it for the cache
update.
In this case, this is probably a pure microoptimization; but the
mechanism will be useful for other things too.
Remove the hardcoded wait time of 2 seconds. Instead, adjust the wait
time each time we unpause: if downloading the data took longer than its
estimated playback time, increase the amount of data we wait for. If
it's shorter, decrease it.
The +/- is supposed to avoid oscillating between two values if the
elapsed time and the wait time are similar. It's not sure if this
actually helps with anything, but it can't harm.
Use the "native" underrun detection, instead of guessing by a low cache
duration. The new underrun detection (which was added with the original
commit) might have the problem that it's easy for the playloop to miss
the underrun event. The underrun is actually not stored as state, so if
the demuxer thread adds a new packet before the playloop happens to see
the state, it's as if it never happened. On the other hand, this means
that network was fast enough, so it should be just fine.
Also, should it happen that we don't know the cached range (the
ts_duration < 0 case), just wait until the demuxer goes idle (i.e.
read_packet() decides to stop). This pretty much should affect broken or
unusual files only, and there might be various things that could go
wrong. But it's more robust in the normal case: this situation also
happens when no packets have been read yet, and we don't want to
consider this as reason to resume playback.
The cache percentage was useless. It showed how much of the total stream
cache was in use, but since the cache size is something huge and
unrelated to the bitrate or network speed, the information content of
the percentage was rather low.
Replace this with printing the duration of the demuxer-cached data, and
the size of the stream cache in KB.
I'm not completely sure about the formatting; suggestions are welcome.
Note that it's not easy to know how much playback time the stream cache
covers, so it's always in bytes.
The "buffering" logic was active even if the stream cache was disabled.
This is contrary to what the manpage says. It also breaks playback
because of another bug: the demuxer cache is smaller than 2 seconds,
and thus the resume condition never becomes true.
Explicitly run this code only if the stream cache is enabled. Also, fix
the underlying problem of the breakage, and resume when the demuxer
thread stops reading in any case, not just on EOF.
Broken by previous commit. Unbreaks playback of local files.
Add the --cache-secs option, which literally overrides the value of
--demuxer-readahead-secs if the stream cache is active. The default
value is very high (10 seconds), which means it can act as network
cache.
Remove the old behavior of trying to pause once the byte cache runs
low. Instead, do something similar wit the demuxer cache. The nice
thing is that we can guess how many seconds of video it has cached,
and we can make better decisions. But for now, apply a relatively
naive heuristic: if the cache is below 0.5 secs, pause, and wait
until at least 2 secs are available.
Note that due to timestamp reordering, the estimated cached duration
of video might be inaccurate, depending on the file format. If the
file format has DTS, it's easy, otherwise the duration will seemingly
jump back and forth.
When video format changes, the frame before the frame with the new
format sets video_status briefly to STATUS_DRAINING. This caused the
code to handle the EOF case to kick in, which just pauses the player
when trying to step past the last frame. As a result, trying to
framestep over format changes resulted in pausing the player.
Fix by testing against the correct status.
In theory, timestamps can be negative, so we shouldn't just return -1
as special value.
Remove the separate code for clearing decode buffers; use the same code
that is used for normal seek reset.