There were complaints that a chapter seek past the last chapter was
quitting the player. Change the behavior to what is expected: the last
frame.
If no chapters are available, this still does nothing.
This should clearly be impossible, but it seems to happen with ordered
chapters for a user.
Since I can't tell what the actual bug is and it seems impossible to
know the details without downloading possibly huge files, this is
probably the best we can do.
Should at least partially fix#1319.
It feels strange that seeking past EOF with --keep-open actually leaves
the player at a random position. You can't even unpause, because the
demuxer is in the EOF state, and what you see on screen is just what was
around before the seek.
Improve this by attempting to seek to the last video frame if EOF
happens. We explicitly don't do this if EOF was reached normally to
increase robustness (if the VO got a frame since the last seek, it
obviously means we had normal playback before EOF).
If an error happens when trying to find the last frame (such as not
actually finding a last frame because e.g. the demuxer misbehaves), this
will probably turn your CPU into a heater. There is no logic to prevent
reinitiating the last-frame search if the last-frame search reached EOF.
(Pausing usually prevents that EOF is reached again after a successful
last-frame search.)
Fixes#819.
This was completely breaking any low-level caching. Change it so that at
least demuxer caching will work.
Do this by using the metadata cache mechanism to funnel through the menu
commands.
For some incomprehensible reason, I had to reorder the events (which
affects their delivery priority), or they would be ignored. Probably
some crap about the event state being cleared before it could be
delivered. I don't give a shit.
All this code sucks. It would probably be better to let discnav.c access
the menu event "queue" directly, and to synchronize access with a mutex,
instead of going through all the caching layers, making things
complicated and slow.
This is simply not allowed, and doing it triggered an assertion. It's
still not allowed, because the terminal and related functionality is a
global resource, and there doesn't seem to be a sane way to manage the
signal handlers.
But be a bit nicer, and just the terminal if it's already in use.
Note that terminal _output_ happens anyway. This becomes usable with
this commit. To facilitate logging-only usage further, also explicitly
disable terminal input, so that "terminal=yes" can be used for logging
without much interference with other things. (It'll still overwrite some
signal handlers, though.)
So the OSC will still appear when using --no-input-default-bindings. It
also means it may override a user's mouse_move binding, but I guess
users who don't want the OSC should just use the --no-osc option.
The player thinks an error happened because no audio or video was played
after finishing the file, but this obviously makes no sense with stream
dumping. (error_playing follows the client API convention that negative
values are errors.)
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.)
Yep, Lua is so crappy that the stdlib doesn't provide anything like
this.
Repurposes the undocumented mp.format_table() function and moves it to
mp.utils.
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().
Running "sub_add file.srt auto" during hook execution automatically
selected the first added track. This happened because all tracks added
with sub_add are marked as "external", and external subtitles are always
selected by default.
Fix this by negating the "external" flag when autoselecting subtitles
during loading. The no_default flag exists for this purpose; it was
probably added for libquvi originally, where we had the same issue.
This is a somewhat obscure situation, and happens only if audio starts
again after it has ended (in particular can happens with files where
audio starts later). It doesn't matter much whether audio starts
immediately or some milliseconds later, so simplify it.
When playing paused, the amount of decoded audio is limited to a small
amount (1 sample), because we don't write any audio to the AO when
paused. The small amount could trigger the case of the wanted audio
being too far in the future in the PTS sync code, which set the audio
status to STATUS_DRAINING, which in turn triggered the EOF code in the
next iteration. This was ok, but unfortunately, this triggered another
retry in order to check resuming from EOF by setting the status to
STATUS_SYNCING, which in turn lead to the busy loop by alternating
between the 2 states. So don't try resyncing while paused.
Since the PTS syncing code also calls ao_reset(), this could cause the
pulseaudio daemon to consume some CPU time as well.
This was caused by commit 33b57f55. Before that, the playloop was merely
run more often, but didn't cause any problems.
Fixes#1288.
this currently uses a sketchy but apparently working workaround,
which will be removed once the neccessary changes in youtube-dl
are implemented
Fixes#1277
Currently, --ytdl is off by default, but even if this is changed, never
enable it by default for the client API. It would be inappropriate to
start an intrusive external subprocess behind the host application's
back.
Simpler, and leaves the decision to repeat or not fully to the script
(instead of requiring the user to care about it when remapping a script
binding).
Use a fixed size array for the client name, which also limits the client
name in size. Sanitize the client name string, and replace characters
that are not in [A-Za-z0-9] with '_'.
Otherwise, mouse button bindings added by mp.add_key_binding() would be
ignored.
It's possible that this "breaks" some older scripts using undocumented
Lua script functions, but it should be safe otherwise.
Fixes#1283.
The subprocess code was already split into fairly general functions,
separate from the Lua code. It's getting pretty big though, especially
the Windows-specific parts, so move it into its own files.
Normally, when creating a process with inherited handles on Windows, the
process inherits all inheritable handles from the parent, including ones
that were created on other threads. This can cause a race condition,
where unintended handles are copied into the new process, preventing
them from being closed correctly while the process is running. The only
way to prevent this on Windows XP was to serialise the creation of all
inheritable handles, which is clearly unacceptable for libmpv.
Windows Vista solves this problem by allowing programs to specify
exactly which handles are inherited, so do that on Vista and up.
See http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx
The CREATE_NO_WINDOW flag is used to prevent the subprocess from
creating an empty console window when mpv is not running in a console.
When mpv is running in a console, it causes the subprocess to detach
itself, and prevents it from seeing Ctrl+C events, so it hangs around in
the background after mpv is killed.
Fix this by only specifying CREATE_NO_WINDOW when mpv is not attached to
a console. When it is attached to a console, subprocesses will
automatically inherit the console and correctly receive Ctrl+C events.
I'm not sure if this is necessary, but it can't hurt, and it's what
you're supposed to do before leaving the stack frame that contains the
OVERLAPPED object and the buffer. If there is no pending I/O, CancelIo
will do nothing and GetOverlappedResult will silently fail.
In all of these situations, NULL is logically not allowed, making the
checks redundant.
Coverity complained about accessing the pointers before checking them
for NULL later.
Does the same thing as the drop_buffers command. When implementing that
command, it turned out that resetting the higher level playback state
was more effective for achieving smooth recovery.
Untested; I don't even have any DVDs or DVD images with multiple angles.
This command was actually requested on IRC ages ago, but I forgot about
it.
The main purpose is that the decoding state can be reset without issuing
a seek, in particular in situations where you can't seek.
This restarts decoding from the middle of the packet stream; since it
discards the packet buffer intentionally, and the decoder will typically
not output "incomplete" frames until it has recovered, it can skip a
large amount of data.
It doesn't clear the byte stream cache - I'm not sure if it should.
It's passed with the '--format' option to youtube-dl.
If it isn't set, we don't pass '--format best' so that youtube-dl can
use the options from its configuration file.
Signed-off-by: wm4 <wm4@nowhere>
Instead of threads, use overlapped (asynchronous) I/O to read from both
stdout and stderr. Like in d0643fa, stdout and stderr could be closed at
different times, so a sparse_wait function is added to wrap
WaitForMultipleObjects and skip NULL handles.
Probably needs to be polished a bit more. Also, might require a key
binding that can set/clear the loop points in a more intuitive way.
For now, something like this can be put into input.conf to use it:
ctrl+y set ab-loop-a ${time-pos} # set A
ctrl+x set ab-loop-b ${time-pos} # set B
ctrl+c set ab-loop-a no # clear (mostly)
Fixes#1241.
Due to the current code structure, the "current" entry and the entry
which is playing can be different. This is probably silly, but still
try to mark the entries correctly.
Refs #1260.
This actually doesn't even write/return the new sub-property, because
I dislike the idea of dumping that field for every single playlist
entry, even though it's "needed" only for one.
Fixes#1260.
Now that the code for stderr and stdout does exactly the same things,
and the specialization is in the callbacks, this is blatantly
duplicated.
Also, define a typedef for those callbacks to reduce the verbosity.
libass won't use embedded fonts, unless ass_set_fonts() (called by
mp_ass_configure_fonts()) is called. However, we call this function when
the ASS_Renderer is initialized, which is long before the .ass file is
actually loaded. (I'm not sure why it tries to keep 1 ASS_Renderer, but
it always did this.)
Fix by calling mp_ass_configure_fonts() after loading them. This also
means this function will be called multiple times - hopefully this is
harmless (it will reinit fontconfig every time, though).
While we're at it, also initialize the ASS_Renderer lazily.
Fixes#1244.
This might be interesting for GUIs and such.
It's probably still a little bit insufficient. For example, the filter
and audio/video output lists are not available through this.
The purpose of temporarily setting stop_play was to make the audio
uninit code to explicitly drain audio if needed. This was the only way
to do it before ao_drain() was made a separate function; now we can just
do it explicitly instead.
We absolutely need to clear the AO reference in the mixer.
The audio_status must be changed to a state where no code assumes that
the AO is available. (It's allowed to do this blindly.)
This rewrites the audio decode loop to some degree. Audio filters don't
do refcounted frames yet, so af.c contains a hacky "emulation".
Remove some of the weird heuristic-heavy code in dec_audio.c. Instead of
estimating how much audio we need to filter, we always filter full
frames. Maybe this should be adjusted later: in case filtering increases
the volume of the audio data, we should try not to buffer too much
filter output by reducing the input that is fed at once.
For ad_spdif.c and ad_mpg123.c, we don't avoid extra copying yet - it
doesn't seem worth the trouble.
Use a pseudo-filter when changing speed with resampling, instead of
somehow changing a samplerate somewhere. This uses the same underlying
mechanism, but is a bit more structured and cleaner. It also makes some
of the following changes easier.
Since we now always use filters to change audio speed, move most of the
work set_playback_speed() does to recreate_audio_filters().
Causes the player to reload the demuxer and to relist the found
streams. Probably slightly dangerous/broken, because the demuxer
thread and possibly even the decoders will keep reading data from
the new title before the new demuxer takes over.
Fixes#1250.
This is what you would expect. Before this commit, each
ao_request_reload() call would just queue a reload command, and then
recreate the AO for the number of times the function was called.
Instead of sending a command, introduce some sort of event retrieval
mechanism. At least for the reload case, use atomics, because we're too
lazy to setup an extra mutex.
This commit fixes a "cosmetic" user interface issue. Instead of
displaying the interpolated seek time on OSD, show the actual audio
time.
This is rather silly: when seeking in audio-only mode, it takes some
iterations until audio is "ready", but on the other hand, the audio
state machine is rather fickle, and fixing this cosmetic issue would be
intrusive. So just add a hack that paints over the ugly behavior as
perceived by the user. Probably the lesser evil.
It doesn't happen if video is enabled, because that mode sets the
current time immediately to video PTS. (Audio has to be synced to video,
so the code is a bit more complex.)
Fixes#1233.
The values compared here happen to be of unsigned enum types - but the
test is not supposed to break if we somehow force the enum to signed, or
if the compiler happens to use a signed type (as far as I remember, the
exact integer type the compiler can use is implementation-defined).
Call VOCTRL_GET_DISPLAY_NAMES it when the property is
requested. The vo should return the names of the displays that the mpv
window is covering. For example, with x11 vos, xrandr names LVDS1,
HDMI1, etc.
update_subtitle() already uees playback_pts to make subtitles work
better in no-audio mode. Using get_current_time() usually gets
playback_pts, but also has the advantage that it will use the seek
target time during seeks. This will result in multiple sub_seek commands
doing the right thing (at least as long as they're far enough apart so
that seeking is actually initiated when the second command is run).
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.
Note that you can't pass .cue or .edl files to it, at least not yet.
Requested in context of allowing to specify custom chapters. For that
to work well, we probably need to add some sort of chapter metadata
pseudo-demuxer.
This was shown only if decoder-framedropping was enabled, and only if at
least 50 frames were dropped by it. Since drop_frame_cnt used to mean
"number of late frames", this code made sense, but this is not the case
anymore: drop_frame_cnt can be even 0, all while video gets hopelessly
behind audio.
One problem with this is that short desync spikes (which usually can
probably dealt with) will also cause this message to be shown. If it
gets triggered too often, the code will need to be adjusted.
For example, if --force-window is used, and video is switched off during
playback, then you need to redecide the rendering method to get subs
displayed correctly.
Do this by moving the state setup code into a function, and call it on
every frame.
If you played e.g. an audio-only file and something bad happened that
interrupted playback, the exit message could say "No files played".
This was awkward, so show a different message in this case.
Also overhaul how the exit status is reported in order to make this
easier. This includes things such as not reporting a playback error
when loading playlists (playlists contain no video or audio, which
was considered an error).
Not sure if I'm happy with this, but for now it seems like a slight
improvement.
This is probably what libmpv users want; and it also improves error
reporting (or we'd have to add a way to communicate such mid-playback
failures as events).
This was probably done incorrectly in cases when the currently selected
channel had no data. I'm not sure if this codepath is functional at all,
though. Maybe not.
Untested due to lack of DVB hardware.
Using magic integer values was an attempt to keep the API less verbose.
But it was probably not a good idea.
Reason 1 (restart) is not made explicit, because it is not used anymore
starting with the previous commit. For ABI compatibility, the value is
left as a hole in the enum.
Use the codepath that is normally used for DVD/BD title switching and
DVB channel switching. Removes some extra artifacts from the client API:
now MPV_EVENT_END_FILE will never be called on reloads (and neither is
MPV_EVENT_START_FILE).
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).
Pretty much a fringe-feature, but also it's awkward if something appears
on the terminal with no indication for the source.
This is made quite awkward by the fact that stderr and stdout could be
closed at different times, and that poll() doesn't accept "holes" in its
FD list. Invalid (.e.g negative) FDs just make it return immediately, as
required by the standard. So sparse_poll() takes care of the messy
details.
What was the purpose of that? Probably none.
Also simplify another thing: if we get the cancel signal through FD,
there's no reason to check it separately.
No development activity (or even any sign of life) for almost a year.
A replacement based on youtube-dl will probably be provided before the
next mpv release. Ask on the IRC channel if you want to test.
Simplify the Lua check too: libquvi linking against a different Lua
version than mpv was a frequent issue, but with libquvi gone, no
direct dependency uses Lua, and such a clash is rather unlikely.
So a client API user can know when a window is created or destroyed.
Also might be useful for the OSC: it could disable itself if video is
disabled.
Before this commit, there were only indirect ways of detecting this.
Most things should be allowed to access the client API unconditionally
(for example for sending events), so move destroying the client API
down. Also, mp_uninit_ipc() should happen before the point at which all
clients are shutdown, or there will be a small time window in which new
clients can be created after destroying them all.
Wether and when the text of a button should be squeezed when it
gets too long can now be configured in the layout:
lo.button.maxchars = <number>
nil = no squeezing (default)
If the button text has more than <maxchars> characters, it will
be squeezed to the estimated width of <maxchars>.
The player was supposed to exit playback if both video and audio failed
to initialize (or if one of the streams was not selected when the other
stream failed). This didn't work; for one this check was missing from
one of the failure paths. And more importantly, both checked the
current_track array incorrectly.
Fix these issues, and move the failure handling code into a common
function.
CC: @mpv-player/stable
Because Lua is so terrible, it's easy to confuse temporary values pushed
to the Lua stack with arguments if the arguments are checked after that.
Add a hack that should fix this.
The behavior of reverse cycling (with the "!reverse" magic value) was a
bit weird and acted with a "delay". This was because the command set the
value the _next_ command should use. Change this and make each command
invocation select and use the next command directly. This requires an
"uninitialized" special index in the counter, but that is no problem at
all.
Due to the way video-rotate currently works, the state will be
automatically updated once new video is decoded. So the filter chain
doesn't need to be reinitialized automatically, but there is a need to
trigger the video instant refresh code path instead.
Also move the support function closer to an annoying similar yet
different function. They probably can be unified next time major changes
are done to this code.
Allows properly changing/updating the cursor state. Useful for client
API window embedding, because the host application may not want the mpv
window to grab mouse input, and this has to manually handle the cursor.
Changing the cursor of foreign windows is usually not sane.
It might make sense to allow changing the cursor icon, but that would be
much more complicated, so I won't add it unless someone actually
requests it.
Apparently using the stream index is the best way to refer to the same
streams across multiple FFmpeg-using programs, even if the stream index
itself is rarely meaningful in any way.
For Matroska, there are some possible problems, depending how FFmpeg
actually adds streams. Normally they seem to match though.
Getting subtitle scaling and positioning right even if there are video
filters, which completely change the image (like cropping), doesn't seem
to have a single, correct solution. To some degree, the results are
arbitrary, so we may as well do what is most useful to the user.
In this case, if the PGS resolution aspect ratio and the video output
aspect ratio mismatch, letter-box it, instead of stretching the subs
over the video frame. (This will require additional fixes, should it
turn out that there are PGS subtitles which are stretched by design.)
Fixes#1205.
It turns out the glibc people are very clever and return an error if the
thread name exceeds the maximum supported kernel length, instead of
truncating the name. So everyone has to hardcode the currently allowed
Linux kernel name length limit, even if it gets extended later.
Also the Lua script filenames could get too long; use the client name
instead.
Another strange thing is that on Linux, unrelated threads "inherit" the
name by the thread they were created. This leads to random thread names,
because there's not necessarily a strong relation between these threads
(e.g. script command leads to filter recreation -> the filter's threads
are tagged with the script's thread name). Unfortunate.
Especially with other components (libavcodec, OSX stuff), the thread
list can get quite populated. Setting the thread name helps when
debugging.
Since this is not portable, we check the OS variants in waf configure.
old-configure just gets a special-case for glibc, since doing a full
check here would probably be a waste of effort.
Thanks to the recently introduced mp_lua_PITA(), this is "simple" now.
It fixes leaks on Lua errors. The hack to avoid stack overflows
manually isn't needed anymore, and the Lua error handler will take
care of this.
The JSON parser was introduced for the IPC protocol, but I guess it's
useful here too.
The motivation for this commit is the same as with 8e4fa5fc (again).
Because 1) Lua is terrible, and 2) popen() is terrible. Unfortunately,
since Unix is also terrible, this turned out more complicated than I
hoped. As a consequence and to avoid that this code has to be maintained
forever, add a disclaimer that any function in Lua's utils module can
disappear any time. The complexity seems a bit ridiculous, especially
for a feature so far removed from actual video playback, so if it turns
out that we don't really need this function, it will be dropped again.
The motivation for this commit is the same as with 8e4fa5fc.
Note that there is an "#ifndef __GLIBC__". The GNU people are very
special people and thought it'd be convenient to actually declare
"environ", even though the POSIX people, which are also very special
people, state that no header declares this and that the user has to
declare this manually. Since the GNU people overtook the Unix world with
their very clever "embrace, extend, extinguish" strategy, but not 100%,
and trying to build without _GNU_SOURCE is hopeless; but since there
might be Unix environments which support _GNU_SOURCE features partially,
this means that in practice "environ" will be randomly declared or not
declared by system headers. Also, gcc was written by very clever people
too, and prints a warning if an external variable is declared twice (I
didn't check, but I suppose redeclaring is legal C, and not even the gcc
people are clever enough to only warn against a definitely not legal C
construct, although sometimes they do this), ...and since we at mpv hate
compiler warnings, we seek to silence them all. Adding a configure test
just for a warning seems too radical, so we special-case this against
__GLIBC__, which is hopefully not defined on other libcs, especially not
libcs which don't implement all aspects of _GNU_SOURCE, and redefine
"environ" on systems even if the headers define it already (because they
support _GNU_SOURCE - as I mentioned before, the clever GNU people wrote
software THAT portable that other libcs just gave up and implemented
parts of _GNU_SOURCE, although probably not all), which means that
compiling mpv will print a warning about "environ" being redefined, but
at least this won't happen on my system, so all is fine. However, should
someone complain about this warning, I will force whoever complained
about this warning to read this ENTIRE commit message, and if possible,
will also force them to eat a printed-out copy of the GNU Manifesto, and
if that is not enough, maybe this person could even be forced to
convince the very clever POSIX people of not doing crap like this:
having the user to manually declare somewhat central symbols - but I
doubt it's possible, because the POSIX people are too far gone and only
care about maintaining compatibility with old versions of AIX and HP-UX.
Oh, also, this code contains some subtle and obvious issues, but writing
about this is not fun.
Using the Lua API is a big PITA because it uses longjmp() error
handling. That is, a Lua API function could any time raise an error and
longjmp() to a lower part of the stack. This kind of "exception
handling" is completely foreign to C, and there are no proper ways to
clean up the "skipped" stack frames.
Other than avoiding such situations entirely, the only way to deal with
this is using Lua "userdata", which is basically a malloc'ed data block
managed by the Lua GC, and which can have a destructor function
associated (__gc metamethod).
This requires an awful lot of code (because the Lua API is just so
terrible), so I avoided this utnil now. But it looks like this will make
some of the following commits much easier, so here we go.
mp_stat() instead of stat() was used in the normal code (i.e. even
on Unix), because MinGW-w64 has an unbelievable macro-mess in place,
which prevents solving this elegantly.
Add some dirty workarounds to hide mp_stat() from the normal code
properly. This now requires replacing all functions that use the
struct stat type. This includes fstat, lstat, fstatat, and possibly
others. (mpv currently uses stat and fstat only.)
It possibly goes to sleep without actually starting to decode audio.
Possibly fixes a problem with --no-osc --no-video reported on IRC.
CC: @mpv-player/stable
This was probably commented as an oversight. Since the subtitle renderer
was uninitialized on reinitialization anyway, this had no negative
consequences, except a memory on exit.
A vague idea to get something similar what libquvi did.
Undocumented because it might change a lot, or even be removed. To give
an idea what it does, a Lua script could do the following:
-- type ID priority
mp.commandv("hook_add", "on_load", 0, 0)
mp.register_script_message("hook_run", function(param, param2)
-- param is "0", the user-chosen ID from the hook_add command
-- param2 is the magic value that has to be passed to finish
-- the hook
mp.resume_all()
-- do something, maybe set options that are reset on end:
mp.set_property("file-local-options/name", "value")
-- or change the URL that's being opened:
local url = mp.get_property("stream-open-filename")
mp.set_property("stream-open-filename", url .. ".png")
-- let the player (or the next script) continue
mp.commandv("hook_ack", param2)
end)
OSD cycling attempted to remove the current message by setting an empty
message with duration 0. Duration 0 tripped up a corner case causing no
OSD to be displayed (until the next message was set), so exclude this
explicitly.
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
Showed "Volume: (unavailable)%". That was dumb.
The message string is now a bit convoluted; mostly because the property
expand syntax can't do "if-else", just "if".
CC: @mpv-player/stable
This does nothing good. This reverts a change made over a year ago - I
don't remember why this was originally done this way.
The main problem is that even if the volume option is set (something
like "--volume=75"), the volume property will always return "100" until
audio is initialized. If audio is uninitialized again, the volume
property will remain frozen at its last value.
Allows passing native types as arguments.
Also some minor doc improvements, including giving some (natural)
improvements to mpv_free_node_contents().
Note: mpv_command_node_async() is completely untested.
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
Seems logical. For some reason, the player allows deselecting both audio
and video stream without quitting (a deliberate feature of which I have
no idea why it was added years ago), so this is needed.
This reverts commit 45c8b97efb.
Some else complained (github issue #1163).
The feature requested in #1148 will be implemented differently in
the following commit.
The event monitor is used to get keyboard events when there is no window, but
since it is a global monitor to the current process, we don't want it in a
library setting.
After @frau's split of macosx_events from macosx_application, `is_cplayer' is
not needed anymore. At the moment only global events such as Media Keys and
Apple Remote work, because the VO-level ones were hardcoded to be disabled.
(that will be fix in a later commit ).
For cover art, we pretend that the video stream is infinite, but also
stop decoding once we have an image on the VO (this seems advantageous
for the case when strange filters are inserted or the VO image gets
lost). Since a while ago, the video chain started decoding 2 images
though ("Non-monotonic video pts: 0.000000 <= 0.000000"), which is
annoying and wasteful.
Improve this by handling a certain corner case at initialization, which
will decode a second image while the first one is still stuck in the
filter chain. Also, just in case there are filters which buffer a lot,
also force EOF filtering (which means we tell the filters to flush
buffered frames).
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).
Maybe using strings for log levels was a mistake (too broad and too
impractical), so I'm adding numeric log level at least for the receiver
side. This makes it easier to map mpv log levels to other logging
systems.
I'm still too stingy to add a function to set the log level by a numeric
value, though.
The numeric values are not directly mapped to the internal mpv values,
because then almost every file in mpv would have to include the client
API header.
Coalesce this into API version 1.6, since 1.6 was bumped just yesterday.
Whether you consider the semantics weird or not depends on your use
case, but I suppose it's a bit confusing anyway. At this point, we keep
MPV_EVENT_PAUSE/UNPAUSE for compatibility only.
Make the "core-idle" property somewhat more useful in this context.
For segment linking (this mechanism matches file extensions to avoid
opening files which are most likely not Matroska files in order to speed
up scanning).
Now any action that stops playback of a file (even playlist navigation)
will save the position. Normal EOF is of course excluded from this, as
well as commands that just reload the current file.
The option name is now slightly off, although you could argue what the
word "quit" means.
Fixes#1148 (or at least this is how I understood it).
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.
Also recreate ASS_Library on every file played. This means we can move
the code out of main.c as well.
Recreating the ASS_Library object has no disadvantages, because it
literally stores only the message callback, the (per-file) font
attachment as byte arrays, and the set of style overrides. Hopefully
this thing can be removed from the libass API entirely at some point.
The only reason why the player core creates the ASS_Renderer, instead
of the subtitle renderer, is because we want to cache the loaded fonts
across ordered chapter transitions, so this probably still has to stay
around for now.
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().
For the sake of libmpv. Might make things much easier for the user,
especially on Windows. On the other hand, it's a bit sketchy that a
command exists that makes the player access arbitrary memory regions.
(But do note that input commands are not meant to be "secure" and never
were - for example, there's the "run" command, which obviously allows
running random shell commands.)
Somewhat more flexible: now there's a separate overlay struct, and you
don't need to coerce all state into struct sub_bitmap. Also, removing
the previous mapping (munmap call) is now all in one place, the
replace_overlay function.
Makes the next commit easier to implement.
The messages "Audio: no audio" and "Video: no video" could be printed
twice each if initializing them failed. Prevent his silliness.
CC: @mpv-player/stable
Apparently this is what users want. When playing with normal speed,
nothing is done. When playing slower than normal, resampling is used
instead, because scaletempo (which does the pitch correction) adds
too many artifacts.
There's no real reason why audio_init_filter() should exist. Just use
af_init or af_reinit directly. (We lose a useless message; the same
information is printed in a quite close place with more details.)
Requires less code, and the way the filter chain is marked as having
failed to initialize allows just switching off audio instead of
crashing if trying to insert a volume filter in mixer.c fails, and
recreating the old filter chain fails too.
This would play some silence in case video was slower than audio. If
framedropping is already enabled, there's no other way to keep A/V
sync, short of changing audio playback speed (which would give worse
results). The --audiodrop option inserted silence if there was more
than 500ms desync.
This worked somewhat, but I think it was a silly idea after all. Whether
the playback experience is really bad or slightly worse doesn't really
matter. There also was a subtle bug with PTS handling, that apparently
caused A/V desync anyway at ridiculous playback speeds.
Just remove this feature; nobody is going to use it anyway.
Commit 64b7811c tried to do the "right thing" with respect to whether
keyboard input should be enabled or not. It turns out that X11 does
something stupid by design. All modern toolkits work around this native
X11 behavior, but embedding breaks these workarounds.
The only way to handle this correctly is the XEmbed protocol. It needs
to be supported by the toolkit, and probably also some mpv support. But
Qt has inconsistent support for it. In Qt 4, a X11 specific embedding
widget was needed. Qt 5.0 doesn't support it at all. Qt 5.1 apparently
supports it via QWindow, but if it really does, I couldn't get it to
work.
So add a hack instead. The new --input-x11-keyboard option controls
whether mpv should enable keyboard input on the X11 window or not. In
the command line player, it's enabled by default, but in libmpv it's
disabled.
This hack has the same problem as all previous embedding had: move the
mouse outside of the window, and you don't get keyboard input anymore.
Likewise, mpv will steal all keyboard input from the parent application
as long as the mouse is inside of the mpv window.
Also see issue #1090.
We inserted these filters with fixed parameters, which was ok. But this
also didn't change image parameters for the filters down the filter
chain and the VO. For example, if rotation by 90° was requested by the
file, we would insert a filter and rotate the video, but the VO would
still receive image parameters that direct rotation by 90°.
This wasn't a problem, but it could become one.
Fix this by letting the filters automatically pick up the image params.
The image params are reset on application. (We could probably also
always try to apply and reset image params in a filter, instead of
having special "auto" parameters. This would probably work, and video.c
would insert a "rotate=0" filter. But I'm afraid this would be confusing
and the current solution is cosmetically slightly nicer.)
Unfortunately, the vf_stereo3d.c change turned out a big mess, but once
the "internal" filter is fully replaced with libavfilter, most of this
can be radically simplified.
Until now, creating the input_ctx was delayed until the command line
and config files were parsed. Separate creation and loading so that
input_ctx is available from start.
This should make it possible to simplify some things. For example,
some complications with Cocoa were apparently only because input_ctx
was available only "later". (Although I'm not sure if this is still
relevant, or if the Cocoa code should even be organized this way.)
This warning makes absolutely no sense. Passing an empty string to
printf-like functions is perfectly fine. In the OSD case, it just sets
an empty message, practically clearing the OSD.
set_osd_bar_chapters() always cleared the OSD bar stops, even if the
current bar was not the seek bar. Obviously it should leave the state of
the bar alone in this case.
Also change the function control flow so that we can drop one
indentation level, and do the equivalent change for the other OSD bar
functions.
Eliminate the remains of the OSD message stack. Another simplification
comes from the fact that we do not need to care about time going
backwards (we always use a monotonic time source, and wrapping time
values are practically impossible). What this code was pretty trivial,
and by now unnecessarily roundabout.
Merge get_osd_msg() into update_osd_msg(), and add_osd_msg() into
set_osd_msg_va().
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.
This makes subtitle display somewhat work if no video is displayed, but
a VO window exists (--force-window or cover art display).
The main problem with normal subtitle display is that it's locked to
video: it uses the video PTS as reference, and the subtitles advance
only if a new video frame is displayed. In audio-only mode on the other
hand, no video frame is ever displayed (or only 1 in the cover art
case). You would need a workaround to adjust the subtitle PTS, and you
would have to decide with what frequency to update the display. In
general, there is no "right" display FPS for subtitles. Some formats
(ASS) have animations parameterized by time, and any refresh rate could
be used.
Sidestep these problems by enabling the text OSD-based subtitle
mechanism. This is similar to --no-sub-ass, and updates and renders
subtitles with plain OSD. It has some caveats: no bitmap subs, somewhat
incorrect timing, no formatting. Timing in particular is a bit strange
and depends how often the audio output asks for new data, or other
events that happen to wakeup the playloop.
Before this commit, there was AF_FORMAT_AC3 (the original spdif format,
used for AC3 and DTS core), and AF_FORMAT_IEC61937 (used for AC3, DTS
and DTS-HD), which was handled as some sort of superset for
AF_FORMAT_AC3. There also was AF_FORMAT_MPEG2, which used
IEC61937-framing, but still was handled as something "separate".
Technically, all of them are pretty similar, but may use different
bitrates. Since digital passthrough pretends to be PCM (just with
special headers that wrap digital packets), this is easily detectable by
the higher samplerate or higher number of channels, so I don't know why
you'd need a separate "class" of sample formats (AF_FORMAT_AC3 vs.
AF_FORMAT_IEC61937) to distinguish them. Actually, this whole thing is
just a mess.
Simplify this by handling all these formats the same way.
AF_FORMAT_IS_IEC61937() now returns 1 for all spdif formats (even MP3).
All AOs just accept all spdif formats now - whether that works or not is
not really clear (seems inconsistent due to earlier attempts to make
DTS-HD work). But on the other hand, enabling spdif requires manual user
interaction, so it doesn't matter much if initialization fails in
slightly less graceful ways if it can't work at all.
At a later point, we will support passthrough with ao_pulse. It seems
the PulseAudio API wants to know the codec type (or maybe not - feeding
it DTS while telling it it's AC3 works), add separate formats for each
codecs. While this reminds of the earlier chaos, it's stricter, and most
code just uses AF_FORMAT_IS_IEC61937().
Also, modify AF_FORMAT_TYPE_MASK (renamed from AF_FORMAT_POINT_MASK) to
include special formats, so that it always describes the fundamental
sample format type. This also ensures valid AF formats are never 0 (this
was probably broken in one of the earlier commits from today).
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.
We generally want 2 things:
1. minimal wakeups for decoding each frame
2. minimal number of frames decoded on continuous seeking
Commit 35810cb8 changed this a bit, and fixed 1. But it broke 2., and
now it decodes 2 frames instead of 1 when you keep seeking (arrow key
held down or such). This made seeking appear slower.
Fix this by making the logic more explicit. In particular, call the
filters only if we actually try to get a new frame.
When playing with --no-audio and all other distractions disabled (like
OSC), it still wakes up 2 times per frame - but the second time is
merely because the VO didn't accept the new frame yet.
Be less annoying, print the actual OSD level instead of something
meaningless, but still clear the OSD if OSD level 0 (no OSD) is set.
Remove the special handling for terminal OSD, that was just dumb.
This means that if a property not listed in property_osd_display[] is
changed, it will be shown on the OSD as "name: ${name}".
Properties that are listed in property_osd_display[] and have osd_name
not set stay invisible by default. This is used for "pause" and
"fullscreen", which (like before this commit) are not shown by default,
because it would be annoying.
The defaults still can be changed with command prefixes (osd-msg,
no-osd, others).
Probably not many user-visible changes. One notable change is that the
terminal OSD code for OSD bar fallback handling is removed with no
replacement. Instead, terminal OSD gets the same text message as normal
OSD. For volume, this is ok, because the text message is reasonable.
Other properties will look worse, but could be adjusted, and there are
in fact no other such properties that would be useful in audio-only
mode.
The fallback message for seeking falls away as well, but that message
was useless anyway - the terminal status line provides all information
anyway.
I believe the show_property_osd() code is now much easier to follow.
If no VO was open, these options couldn't be changed or even queried.
Although these properties are nearly useless if no VO exists, there's
actually no good reason to forbid querying or setting them. Also, even
if the VO is created, it doesn't mean the VO window was created.
Why bother?
Also, since now some properties could be mapped to non-existing options,
but mp_property_generic_option() is used, deal with this case and return
a not-found error code.
If there's a command that uses the OSD by default, then always print the
associated message (or a fallback made of name + value), even if the
command has an associated OSD bar.
This means volume, gamma, panscan, etc. all show both a message and a
OSD bar.
Also, add a '%' to the volume message. The extra_msg thing is not needed
anymore.
See issue #1103.
It's just confusing; users are encouraged to edit input.conf instead
(changing the argument to the "add" command).
Update input.conf to keep the old behavior.
Follow up to previous commit.
This is probably confusing from a user point of view, since this field
shouldn't show up normally anymore. (Before this commit, it could show
up sporadically when a slow operation was performed during playback,
such as switching fullscreen.)
Normally, feeding a packet to the decoder should always return a frame
_if_ we received a frame before. So while we can't know exactly whether
a frame was dropped, at least the normal case is easily detectable.
This means we display something closer to the actual framedrop count,
instead of a bad guess.
This is the "old" framedropping mode (derived from MPlayer). At least in
the mplayer2/mpv source base, it stopped working properly years ago (or
maybe it never worked properly). For one, it depends on the video
framerate, which assume constant framerate. Another problem was that it
could lead to freezing video display: video could get so much behind
that it couldn't recover from framedrop.
Make some small changes to improve this.
Don't use the current audio position to check how much we are behind.
Instead, use the last known A/V difference. last_av_difference is
updated only when a video frame is scheduled for display. This means we
can keep stop dropping once we're done catching up, even if video is
technically still behind. What helps us here that this forces a video
frame to be displayed after a while. Likewise, we reset the
dropped_frames count only when scheduling a new frame for display as
well.
Some inspiration was taken from earlier work by xnor (see issue #620),
although the implementation turned out quite different.
This still uses the demuxer-reported (possibly broken) FPS value. It
also doesn't account for filters changing FPS. We can't do much about
this, because without decoding _and_ filtering, we just can't know how
long a frame is. In theory, you could derive that from the raw packet
timestamps and the filter chain contents, but actually doing this is
too involved. Fortunately, the main thing the FPS affects is actually
the displayed framedrop count.