Give scripting backends a proper name, instead of calling everything
"scripts".
Log client exit directly in client.c, as that is more general (doesn't
change actual output).
Cover art handling is a disgusting hack that causes a mess in all
components. And this will stay this way. This is the Xth time I've
changed cover art handling, and that will probably also continue.
But change the code such that cover art is injected into the demux
packet stream, instead of having an explicit special case it in the
decoder glue code. (This is somewhat more similar to the cover art hack
in libavformat.)
To avoid that the over art picture is decoded again on each seek, we
need some additional "caching" in player/video.c. Decoding it after each
seek would work as well, but since cover art pictures can be pretty
huge, it's probably ok to invest some lines of code into caching it.
One weird thing is that the cover art packet will remain queued after
seeks, but that is probably not an issue.
In exchange, we can drop the dec_video.c code, which is pretty
convenient for one of the following commits. This code duplicates a
bunch of lower-level decode calls and does icky messing with this weird
state stuff, so I'm glad it goes away.
Was intended to show a "nice" message on edition switching. In practice,
the message was never visible. The OSD code checks whether a demuxer is
loaded, and if not, discards the message - meaning if the OSD code
happened to run before the demuxer was fully loaded, no message was
shown. This is apparently a regression due to extensions to the OSD and
the situations in which it can be used.
Remove the broken code since it's too annoying to fix. Instead, a
default property message will be shown, which is a bit uglier, but
actually not too unuseful.
Helps with gif, probably does unwanted things with other formats.
This doesn't handle --end quite correctly, but this could be added
later.
Fixes#3924.
As threatened by the API changes document.
This commit also removes or stubs equivalent calls in IPC and Lua
scripting.
The stubs are left to maintain ABI compatibility. The semantics of the
API functions have been close enough to doing nothing that this probably
won't even break existing API users. Probably.
Now a reload requested by an AO behaves in exactly the same way as
changing an AO-related options (like --audio-channels or
--audio-exclusive). This is good for testing and uniform behavior. (You
could go as far as saying it's a necessity, because the spotty and
obscure AO reload behavior is hard to reproduce and thus hard to test at
all.)
Move the screensaver enable/disable determination to a central place,
and call it if the stop-screensaver property is changed.
Also, do not stop the screensaver when in idle mode (i.e. no file is
loaded).
Fixes#3615.
The intention is to give libmpv users as much flexibility to load
scripts as using mpv from CLI, but without restricting libmpv users from
having to decide everything on creation time, or having to go through
hacks like recreating the libmpv context to update state.
Setting the osc or ytdl properties will now load/unload the associated
scripts. (For ytdl this does not mean the currently played URL will be
reloaded.)
Also add a changelog entry for this, which also covers the preceding
work for --terminal.
Move the MPV_LEAK_REPORT env query to mp_create(), where it will also be
used by the client API (it might be helpful, so why not). The same
applies to MPV_VERBOSE.
The prepare_playlist() call doesn't need to be in mp_initialize() and
can just be in mp_play_files() to reduce the size of mp_initialize().
Also, remove wakeup_playloop(), which is 100% redundant with
mp_wakeup_core_cb().
So client API users don't have to care about whether to set this before
or after mpv_initialize().
We still don't enable terminal at any point before mpv_initialize(),
because reasons.
This also subtly changes some behavior how terminal options are applied
while parsing. This essentially reverts the behavior as it was reported
in issue #2588. Originally, I was hoping to get rid of the pre-parse
option pass, but it seems this is absolutely not possible due to the way
config and command line parsing are entangled. Command line options take
priority over configfile options, so they have to be applied later - but
we also want to apply logging and terminal options as specified on the
command-line, but _before_ parsing the config files. It has to be this
way to see config file error messages on the terminal, or to hide them
if --no-terminal is used. libmpv considerations also factor into this.
Some properties had a different type from their equivalent options (such
as mute, volume, deinterlace, edition). This wasn't really sane, as raw
option values should be always within their bounds. On the other hand,
these properties use a different type to reflect runtime limits (such as
range of available editions), or simply to improve the "UI" (you don't
want to cycle throuhg the completely useless "auto" value when cycling
the "mute" property).
Handle this by making them always return the option type, but also
allowing them to provide a "constricted" type, which is used for UI
purposes. All M_PROPERTY_GET_CONSTRICTED_TYPE changes are related to
this.
One consequence is that you can set the volume property to arbitrary
high values just like with the --volume option, but using the "add"
command it still restricts it to the --volume-max range.
Also deprecate --chapter, as it is grossly incompatible to the chapter
property. We pondered renaming it to --chapters, or introducing a more
powerful --range option, but concluded that --start --end is actually
enough.
These changes appear to take care of the last gross property/option
incompatibilities, although there might still be a few lurking.
Instead of using input_ctx for waiting, use the dispatch queue directly.
One big change is that the dispatch queue will just process commands
that come in (e.g. from client API) without returning. This should
reduce unnecessary playloop excutions (which is good since the playloop
got a bit fat from rechecking a lot of conditions every iteration).
Since this doesn't force a new playloop iteration on every access, this
has to be enforced manually in some cases.
Normal input (via terminal or VO window) still wakes up the playloop
every time, though that's not too important. It makes testing this
harder, though. If there are missing wakeup calls, it will be noticed
only when using the client API in some form.
At this point we could probably use a normal lock instead of the
dispatch queue stuff.
This does 3 kinds of changes:
- change sleeptime=x to mp_set_timeout()
- change sleeptime=0 to mp_wakeup_core() calls (to be more explicit)
- change commands etc. to call mp_wakeup_core() if they do changes that
require the playloop to be rerun
This is preparation for the following changes. The goal is to process
client API requests without having to rerun the playloop every time. As
of this commit, the changes should not change behavior. In particular,
the playloop is still implicitly woken up on every command.
Currently, calling mp_input_wakeup() will wake up the core thread (also
called the playloop). This seems odd, but currently the core indeed
calls mp_input_wait() when it has nothing more to do. It's done this way
because MPlayer used input_ctx as central "mainloop".
This is probably going to change. Remove direct calls to this function,
and replace it with mp_wakeup_core() calls. ao and vo are changed to use
opaque callbacks and not use input_ctx for this purpose. Other code
already uses opaque callbacks, or has legitimate reasons to use
input_ctx directly (such as sending actual user input).
This has all been made unnecessary recently. The change not to copy the
global option struct in particular can be made because now nothing
accesses the global options anymore in the demux and stream layers.
Some code that was accidentally added/changed in commit 5e30e7a0 is also
removed, because it was simply committed accidentally, and was never
used.
Why do these API calls even still exist? I don't know, and maybe they
don't make any sense anymore. But whether they should be removed or not
is not a decision I want to make now. I want to get rid of
mp_dispatch_suspend/resume(), though. So implement the client APIs
slightly differently.
This affects A-B loops and --loop-file, and audio. Instead of dropping
audio by resetting the AO, try to make it seamless by not sending data
after the loop point, and after the seek send new data without a reset.
Change the last parameter from a bool to an int, which is supposed to
take bit-flags. The at this point only flag is MPSEEK_FLAG_DELAY, which
replaces the previous bool parameter. The old false parameter becomes 0,
the old true parameter becomes MPSEEK_FLAG_DELAY.
Since the old "immediate" parameter is now essentially inverted, two
coalesced immediate and delayed seeks end up as delayed instead of
immediate. This change doesn't matter, since there are no relative
immediate seeks anyway.
Relative seeks backwards with external audio tracks does not always work
well: it tends to happen that video seek back further than audio, so
audio will remain silent until the audio's after-seek position is
reached. This happens because we strictly seek both video and audio
demuxer to the approximate desirted target PTS, and then start decoding
from that.
Commit 81358380 removes an older method that was supposed to deal with
this. It was sort of bad, because it could lead to the playback core
freezing by waiting on network.
Ideally, the demuxer layer would probably somehow deal with such seeks,
and do them in a way the audio is seeked after video. Currently this is
infeasible, because the demuxer layer assumes a single demuxer, and
external tracks simply use separate demuxer layers. (MPlayer actually
had a pseudo-demuxer that joined external tracks into a single demuxer,
but this is not flexible enough - and also, the demuxer layer as it
currently exists can't deal with dynamically removing external tracks
either. Maybe some time in the future.)
Instead, add a gross hack, that essentially reseeks the audio if it
detects that it's too far off. The result is actually not too bad,
because we can reuse the mechanism that is used for instant track
switching. This way we can make sure of the right position, without
having to care about certain other issues.
It should be noted that if the audio demuxer is used for other tracks
too, and the demuxer does not support refresh seeking, audio will
probably be off by even a higher amount. But this should be rare.
Assume you use a large value like --audio-delay=20. Then until now the
player would just have seeked normally to a "too late" position, and
played silence for about 20 seconds until audio in the correct time
range is coming again.
Change this by offsetting seeks by the right amount. This works for both
external and muxed files. If a seek isn't precise, then it works only
for external files.
This might cause issues with very large delay options. Hr-seek skipping
could take a lot of time (especially because it affects video too), the
demuxer queue could overflow, and other weird corner cases could appear.
But we just try this on best-effort basis, and if the user uses extreme
values we don't guarantee good behavior.
mixer.c didn't really deserve to be separate anymore, as half of its
contents were unnecessary glue code after recent changes. It also
created a weird split between audio.c and af.c due to the fact that
mixer.c could insert audio filters. With the code being in audio.c
directly, together with other code that unserts filters during runtime,
it will be possible to cleanup this code a bit and make it work like the
video filter code.
As part of this change, make the balance code work like the volume code,
and add an option to back the current balance value. Also, since the
balance semantics are unexpected for most users (panning between the
audio channels, instead of just changing the relative volume), and there
are some other volumes, formally deprecate both the old property and the
new option.
Instead of using the "vf" command code (which changes filters at runtime
on user input), use the general filter-insertion code. The latter was
added later, and is more suitable for automatically inserted filters.
The old code failed in particular when using watch-later saving, which
stored the filter list in the resume config file. If a user changed the
hardware decoding mode via command line, the stored filter chain was out
of date and could cause failure due to not working with hardware or
software decoding mode. Storing the deinterlace filter in the filter
list was unavoidable, because it was part of the user state. (The new
code only edits the actually instantiated filters.)
Normally, OSD is updated every time the playloop is run. This has to be
done, because the OSD may implicitly reference various properties,
without knowing whether they really need to be updated or not. (There's
a property update mechanism, but it's mostly unavailable, because OSD is
special-cased and can not use the client API mechanism properly.)
Normally, these updates are no problem, because the OSD is only actually
printed when the OSD text actually changes.
But commit d23ffd24 added a rate-limiting mechanism, which tries to
limit OSD updates at most every 50ms (or the next video frame). Since it
can't know in advance whether the OSD is going to change or not, this
simply waked up the player every 50ms.
Change this so that the player is updated only as part of general
updates determined through mp_notify(). (This function also notifies the
client API of changed properties.) The desired result is that the player
will not wake up at all in normal idle mode, but still update properties
that can change when paused, such as the cache.
This is mostly a cosmetic change (in the sense of making runtime
behavior just slightly better). It has the slightly more negative
consequence that properties which update implicitly (such as "clock")
will not update periodically anymore.
The main change is with video/hwdec.h. mp_hwdec_info is made opaque (and
renamed to mp_hwdec_devices). Its accessors are mainly thread-safe (or
documented where not), which makes the whole thing saner and cleaner. In
particular, thread-safety rules become less subtle and more obvious.
The new internal API makes it easier to support multiple OpenGL interop
backends. (Although this is not done yet, and it's not clear whether it
ever will.)
This also removes all the API-specific fields from mp_hwdec_ctx and
replaces them with a "ctx" field. For d3d in particular, we drop the
mp_d3d_ctx struct completely, and pass the interfaces directly.
Remove the emulation checks from vaapi.c and vdpau.c; they are
pointless, and the checks that matter are done on the VO layer.
The d3d hardware decoders might slightly change behavior: dxva2-copy
will not use the VO device anymore if the VO supports proper interop.
This pretty much assumes that any in such cases the VO will not use any
form of exclusive mode, which makes using the VO device in copy mode
unnecessary.
This is a big refactor. Some things may be untested and could be broken.
Calculate the buffering percentage in the same code which determines
whether the player is or should be buffering. In particular it can't
happen that percentage and buffering state are slightly out of sync due
to calling DEMUXER_CTRL_GET_READER_STATE and reusing it with the
previously determined buffering state.
Now it's also easier to guarantee that the buffering state is updated
properly.
Add some more verbose output as well.
(Damn I hate this code, why did I write it?)
Subtitles can be preloaded, which means they're fully read and copied
into ASS_Track. This in turn is mainly for the sake of being able to do
subtitle seeking (when it comes down to it, subtitle seeking is the
cause for most trouble here).
Commit a714f8e92 broke preloaded subtitles which have events with
unknown duration, such as some MicroDVD samples. The event list gets
cleared on every seek, so the property of being preloaded obviously gets
lost.
Fix this by moving most of the preloading logic to dec_sub.c. If the
subtitle list gets cleared, they are not considered preloaded anymore,
and the logic for demuxed subtitles is used.
As another minor thing, preloadeding subtitles did neither disable the
demux stream, nor did it discard packets. Thus you could get queue
overflows in theory (harmless, but annoying). Fix this by explicitly
discarding packets in preloaded mode.
In summary, now the only difference between preloaded and normal
demuxing are:
1. a seek is issued, and all packets are read on start
2. during playback, discard the packets instead of feeding them to the
subtitle decoder
This is still petty annoying. It would be nice if maintaining the
subtitle index (and maybe a subtitle packet cache for instant subtitle
presentation when seeking back) could be maintained in the demuxer
instead. Half of all file formats with interleaved subtitles have
this anyway (mp4, mkv muxed with newer mkvmerge).
Some oddity that is not needed anymore. The only thing which still
referenced them was avoiding loading external files more than once,
which is now prevented by checking the list of tracks instead.
See --lavfi-complex option.
This is still quite rough. There's no support for dynamic configuration
of any kind. There are probably corner cases where playback might freeze
or burn 100% CPU (due to dataflow problems when interaction with
libavfilter).
Future possible plans might include:
- freely switch tracks by providing some sort of default track graph
label
- automatically enabling audio visualization
- automatically mix audio or stack video when multiple tracks are
selected at once (similar to how multiple sub tracks can be selected)
Regression caused by commit 3b95dd47. Also see commit 4c25b000. We can
either use video_next_pts and add "delay", or we just use video_pts. Any
other combination breaks. The reason why the assumption that delay==0 at
this point was wrong exactly because after displaying the first video
frame (usually done before audio resync) a new frame might be "added"
immediately, resulting in a new video_next_pts and "delay", which will
still amount to video_pts.
Fixes#2770. (The reason why display-sync was blamed in this issue is
because enabling display-sync in the options forces a prefetch by 2
instead of 1 frames for seeks/playback restart, which triggers the
issue, even if display-sync is not actually enabled. In this case,
display-sync is never enabled because the frames have a unusually high
frame duration. This is also what exposed the initial desync issue.)
It doesn't need to be part of the big context, but is strictly part of
shuffling data from the audio filters to audio output, and thus belongs
into ao_chain.
It also turns out that clearing it in clear_audio_output_buffers() is
completely redundant.
(Of course ao_buffer is an abomination in the first place and shouldn't
exist at all.)
Similar to the video path. dec_audio.c now handles decoding only. It
also looks very similar to dec_video.c, and actually contains some of
the rewritten code from it. (A further goal might be unifying the
decoders, I guess.)
High potential for regressions.
This covers source files which were added in mplayer2 and mpv times
only, and where all code is covered by LGPL relicensing agreements.
There are probably more files to which this applies, but I'm being
conservative here.
A file named ao_sdl.c exists in MPlayer too, but the mpv one is a
complete rewrite, and was added some time after the original ao_sdl.c
was removed. The same applies to vo_sdl.c, for which the SDL2 API is
radically different in addition (MPlayer supports SDL 1.2 only).
common.c contains only code written by me. But common.h is a strange
case: although it originally was named mp_common.h and exists in MPlayer
too, by now it contains only definitions written by uau and me. The
exceptions are the CONTROL_ defines - thus not changing the license of
common.h yet.
codec_tags.c contained once large tables generated from MPlayer's
codecs.conf, but all of these tables were removed.
From demux_playlist.c I'm removing a code fragment from someone who was
not asked; this probably could be done later (see commit 15dccc37).
misc.c is a bit complicated to reason about (it was split off mplayer.c
and thus contains random functions out of this file), but actually all
functions have been added post-MPlayer. Except get_relative_time(),
which was written by uau, but looks similar to 3 different versions of
something similar in each of the Unix/win32/OSX timer source files. I'm
not sure what that means in regards to copyright, so I've just moved it
into another still-GPL source file for now.
screenshot.c once had some minor parts of MPlayer's vf_screenshot.c, but
they're all gone.
Eventually we want the VO be driven by a A->V filter, so a decoder
doesn't even have to exist. Some features definitely require a decoder
though (like reporting the decoder in use, hardware decoding, etc.), so
for each thing which accessed d_video, it has to be redecided if and how
it can access decoder state.
At least the "framedrop" property slightly changes semantics: you can
now always set this property, even if no video is active.
Some untested changes in this commit, but our bio-based distributed
test suite has to take care of this.
This moves some code related to decoding from video.c to dec_video.c,
and also removes some accesses to dec_video.c from the filtering code.
dec_video.ch is starting to make sense, and simply returns video frames
from a demuxer stream. The API exposed is also somewhat intended to be
easily changeable to move decoding to a separate thread, if we ever want
this (due to libavcodec already being threaded, I don't see much of a
reason, but it might still be helpful).
Channel switching is treated inside the global DVB state
by now. Anyways the last switching direction is not really useful
and of no interest inside the player.
Lots of noise to remove the vfilter/vo fields from dec_video.
From now on, video filtering and output will still be done together,
summarized under struct vo_chain.
There is the question where exactly the vf_chain should go in such a
decoupled architecture. The end goal is being able to place a "complex"
filter between video decoders and output (which will culminate in
natural integration of A->V filters for natural integration of
libavfilter audio visualizations). The vf_chain is still useful for
"final" processing, such as format conversions and deinterlacing. Also,
there's only 1 VO and 1 --vf option. So having 1 vf_chain for a VO seems
ideal, since otherwise there would be no natural way to handle all these
existing options and mechanisms.
There is still some work required to truly decouple decoding.
Basically reimplement it. The old implementation was quite stupid, and
was probably done this way because video filtering and output used to be
way less decoupled. Now we can reimplement it in a very simple way: when
backstepping, seek to current time, but keep the last frame that was
supposed to be discarded when reaching the target time. When the seek
finishes, prepend the saved frame to the video frame queue.
A disadvantage is that the new implementation fails to skip over
timeline boundaries (ordered chapters etc.), but this never worked
properly anyway. It's possible that this will be fixed some time in the
future.
This slightly changes behavior when seeking with external audio/subtitle
tracks if transport streams and mpeg files are played, as well as
behavior when seeking with such external tracks.
get_main_demux_pts() is evil because it always blocks on the demuxer (if
there isn't already a packet queued). Thus it could lock up the player,
which is a shame because all other possible causes have been removed.
The reduced "precision" when seeking in the ts/mpeg cases (where
SEEK_FACTOR is used, resulting in byte seeks instead of timestamp seeks)
might lead to issues. We should probably drop this heuristic. (It was
introduced because there is no other way to seek in files with PTS
resets with libavformat, but its value is still questionable.)
Slightly change how it is decided when a new packet should be read.
Switch to demux_read_packet_async(), and let the player "wait properly"
until required subtitle packets arrive, instead of blocking everything.
Move distinguishing the cases of passive and active reading into the
demuxer, where it belongs.
This includes the case of switching ordered chapter boundaries. It will
now be recreated on each timeline part switch. This shouldn't be much of
a problem with modern libass. (Older libass versions use fontconfig for
memory fonts, and will be very slow to reinitialize memory fonts.)
Since commit 6d9cb893, subtitle state doesn't survive timeline switches
(ordered chapters etc.). So there is no point in caching the state per
sh_stream anymore (which would be required to deal with multiple
segments). Move the cache to struct track.
(Whether it's worth caching the subtitle state just for the situation
when subtitle tracks get reselected is questionable. But for now, it's
nice to have the subtitles immediately show up when reselecting a
subtitle.)
Instead of periodically trying to enable it again. There are two cases
that can happen:
1. A random discontinuity messed everything up,
2. Things are just broken and will desync all the time
Until now, it tried to deal with case 1 - but maybe this is really rare,
and we don't really need to care about it. On the other hand, case 2 is
kind of hard to diagnose if the user doesn't use the terminal.
Seeking will reenable display-sync, so you can fix playback if case 1
happens, but still get predictable behavior in case 2.
This was used with --no-sub-ass (aka --no-ass). This option (which is
not yet removed) strips all styling from the subtitles, and renders them
as plaintext only. For some reason, it originally seemed convenient to
reuse all the OSD text rendering code (osd_libass.c). While this was
indeed simple, it had a bad influence on the rest of the code. For
example, it had to decide whether to go through the OSD code path, or
the proper subtitle renderer in sd_ass.c.
Kill the OSD subtitle renderer. Reimplement --no-sub-ass and also
"secondary" subtitles in sd_ass.c. fill_plaintext() contains some rather
minor code duplication with osd_libass.c for setting up a dummy
ASS_Event and escaping the stripped text. Since sd_ass.c already has to
handle "normal" text subtitles, and has code for stripping ASS tags,
this remains all relatively simple.
Remove all the unnecessary crap from the rest of the code.
Use the demux_set_ts_offset() added in the previous commit to base each
timeline segment to use timestamps according to its relative position
within the overall timeline. As a consequence we don't need to care
about these timestamps anymore, and everything becomes simpler.
(Another minor but delicious nugget of sanity.)
Most of this is explained in the DOCS additions.
This gives us slightly more sanity, because there is less interaction
between the various parts. The goal is getting rid of the video_offset
entirely.
The simplification extends to the user API. In particular, we don't need
to fix missing parts in the API, such as the lack for a seek command
that seeks relatively to the start time. All these things are now
transparent.
(If someone really wants to know the real timestamps/start time, new
properties would have to be added.)
This adds support for the progress indicator taskbar extension
that was introduced with Windows 7 and Windows Server 2008 R2.
I don’t like this solution because it keeps its own state and
introduces another VOCTRL, but I couldn’t come up with anything
less messy.
closes#2399
We always let audio slowly desync until a threshold is reached, and then
pushed it back by applying a maximum compensation speed. Refine what
comes afterwards: instead of playing with the nominal video speed, use
the actual required audio speed for keeping sync as measured by the A/V
difference. (The "actual" speed is the ideal speed with A/V differences
added.)
Although this works in theory, it's somewhat questionable how much this
works in practice. The ideal time value is actually not exact, but is
the time at which the frame is scheduled (could be compensated by using
the time_left calculations in handle_display_sync_frame()). It doesn't
account for speed changes or catastrophic discontinuities. It uses only
10 past frames.
This is very "illustrative", unlike the video-speed-correction
property, and thus useful. It can also be used to observe scheduling
errors, which are not detected by the core. (These happen due to
rounding errors; possibly not evne our fault, but coming from
files with rounded timestamps and so on.)
Get rid of get_past_frame_durations(), which was a bit too messy. Add
a past_frames array, which contains the same information in a more
reasonable way. This also means that we can get the exact current and
past frame durations without going through awful stuff. (The main
problem is that vo_pts_history contains future frames as well, which is
needed for frame backstepping etc., but gets in the way here.)
Also disable the automatic disabling of display-sync if the frame
duration changes, and extend the frame durations allowed for display
sync. To allow arbitrarily high durations, vo.c needs to be changed
to pause and potentially redraw OSD while showing a single frame, so
they're still limited.
In an attempt to deal with VFR, calculate the overall speed using the
average FPS. The frame scheduling itself does not use the average FPS,
but the duration of the current frame. This does not work too well,
but provides a good base for further improvements.
Where this commit actually helps a lot is dealing with rounded
timestamps, e.g. if the container framerate is wrong or unknown, or
if the muxer wrote incorrectly rounded timestamps. While the rounding
errors apparently can't be get rid of completely in the general case,
this is still much better than e.g. disabling display-sync completely
just because some frame durations go out of bounds.
Discontinuities (like toggling fullscreen) can cause multiple frames to
be dropped in succession, which sounds very weird. It's better to drop
some video frames instead to compensate for larger desyncs.
We roughly base it on the maximum allowed speed changes (audio change is
"additional" to the video change to account for deviations when playing
at max. video speed change).
Sigh... After the recent changes, another regression appeared. This
time, the VO window wasn't cleared when changing from video to a non-
video file (such as audio-only with no cover art). Fix this by properly
taking the handle_force_window() bool parameter into account.
Also, the info message could be printed twice, which is harmless but
ugly. So just remove the message.
Also, do some more minor cleanups (like fixing the comment, which was
completely outdated).
The previous commit was incomplete (and I didn't notice due to a broken
test procedure).
The annoying part is that actually creating the VO was separate; redo
this and merge the code for this into handle_force_window() as well.
This will also make implementing proper reaction to runtime option
changes easier. (Only the part for actually listening to option changes
is missing.)
If this mode is enabled, the player tries to strictly synchronize video
to display refresh. It will adjust playback speed to match the display,
so if you play 23.976 fps video on a 24 Hz screen, playback speed is
increased by approximately 1/1000. Audio wll be resampled to keep up
with playback.
This is different from the default sync mode, which will sync video to
audio, with the consequence that video might skip or repeat a frame once
in a while to make video keep up with audio.
This is still unpolished. There are some major problems as well; in
particular, mkv VFR files won't work well. The reason is that Matroska
is terrible and rounds timestamps to milliseconds. This makes it rather
hard to guess the framerate of a section of video that is playing. We
could probably fix this by just accepting jittery timestamps (instead
of explicitly disabling the sync code in this case), but I'm not ready
to accept such a solution yet.
Another issue is that we are extremely reliant on OS video and audio
APIs working in an expected manner, which of course is not too often
the case. Consequently, the new sync mode is a bit fragile.
For video sync, we want separate playback speed controls for user-
requested speed and the "correction" speed for video timing. Further, we
use this separation to make sure only a resampler is inserted if
playback speed is only changed for video sync correction.
As of this commit, this is basically inactive code. It's just
preparation for the video sync code (the following commit).
Additionally to taking the average, this tries to use the demuxer FPS to
eliminate jitter, and applies some other heuristics to check if the
result is sane.
This code will also be used for the display sync code (it will actually
make use of the require_exact parameter).
(The value of doing this over keeping the simpler demux_mkv hack is
somewhat questionable. But at least it allows us to deal with other
container formats that use jittery timestamps, such as mp4 remuxed
from mkv.)
Nobody wanted to restore this, so it gets the boot.
If anyone still wants to volunteer to restore menu support, this would
be welcome. (I might even try it myself if I feel masochistic and like
wasting a lot of time for nothing.) But if it does get restored, it
should be done differently. There were many stupid things about how it
was done. For example, it somehow tried to pull mp_nav_events through
all the layers (including needing to "buffer" them in the demuxer),
which was needlessly complicated. It could be done simpler.
This code was already inactive, so this commit actually changes nothing.
Also keep in mind that normal DVD/BD playback still works.
Instead of calling it "future frames" and adding or subtracting 1 from
it, always call it "requested frames". This simplifies it a bit.
MPContext.next_frames had 2 added to it; this was mainly to ensure a
minimum size of 2. Drop it and assume VO_MAX_REQ_FRAMES is at least 2;
together with the other changes, this can be the exact size of the
array.
mp_seek_chapter() had only 1 caller. Also the code was rather
roundabout; the entire function can be compressed to 5 lines of code.
(The new code is functionally the same - "mpctx->last_chapter_seek =
-2;" was effectively a dead assingment.)
Each subtitle track gets its own decoder instance (sd_ass). But they use
a shared ASS_Renderer. This is done mainly because of fontconfig.
Initializing fontconfig is very slow when using it with memory fonts, so
there's a practical need to cache this memory font state, which is done
by not creating separate ASS_Renderers. This is very dirty and very
evil, but we probably can't get rid of it any time soon.
The shared ASS_Renderer was not properly synchronized. While the program
logic guarantees that only one sd_ass instance is visible at a time,
there are other interactions that require synchronization. In
particular, I suspect concurrent execution of mp_ass_configure_fonts()
and sd_ass.get_bitmaps cause issues in a newer libass development
branch.
So here's a shitty hack that hopefully fixes things, hopefully only
until libass becomes less dependent on fontconfig.
The final goal is making opening the demuxer and opening the stream the
same operation.
Stream dumping is a rather uninteresting feature, but has a small
number of vocal users, and it's easy to keep.
Now the VO can request a number of future frames with the last parameter
of vo_set_queue_params(). This will be helpful to fix the interpolation
code.
Note that the first frame (after playback start or seeking) will usually
not have any future frames (to make seeking fast). Near the end of the
file, the number of future frames will become lower as well.
At least Matroska files have a "forced" flag (in addition to the
"default" flag). Export this flag. Treat it almost like the default
flag, but with slightly higher priority.
Adding an external audio track before loading the main file didn't work
right. For one, mp_switch_track() assumes it is called after the main
file is loaded. (The difference is that decoders are only initialized
once the main file is loaded, and we avoid doing this before that for
whatever reason.)
To avoid further messiness, just allow mp_switch_track() to be called at
any time. Also make it do what mp_mark_user_track_selection() did, since
the latter requires current_track to be set. (One could probably simply
allow current_track to be set at this point, but it'd interfere with
default track selection anyway and thus would be pointless.)
Fixes#1984.
mp_find_config_file() will print the filename lookup and its result in
verbose mode. This is wanted, but gets inconvenient when it is done for
every playlist entry (for resuming).
Lookup the watch_later subdir only once and cache the result instead.
This drops the logic for loading the resume file from other locations,
which should generally be unnecessary, though might lead to confusion if
the user has mixed old and new config paths (which the user shouldn't).
Also add a mp_find_user_config_file() function for a more
straightforward and reliable way to get actual local configpaths,
instead of possibly global and unwritable locations.
Also, for symmetry, check the resume option in mp_load_playback_resume()
just like mp_check_playlist_resume() does.
And split the Cocoa and Unix cases. Simplify the Cocoa case slightly by
calling mpv_main directly, instead of passing a function pointer. Also
add a comment explaining why Cocoa needs a special case at all.
Should help with debugging, and might be slightly more userfriendly.
Note that this is called manually in multiple entry-points, instead of
the functions doing the actual work (like mp_remove_track()). This is
done so that exiting the player or calling the sub_reload command won't
print redundant in-between states.
Move the command line parsing and some other things to the common init
routine shared between command line player and client API. This means
they're using almost exactly the same code now.
The main intended side effect is that the client API will load mpv.conf;
though still only if config loading is enabled.
(The cplayer still avoids creating an extra thread, passes a command
line, and prints an exit status to the terminal. It also has some
different defaults.)
Commit f54220d9 attempted to improve this, but it got worse. Now there
was a crash when ytdl_hook.lua added external tracks. This happened
because close_unused_demuxers() assumed that sources[0] was the main
demuxer (so that it didn't close it). This assumption failed, because
the ytdl script can add external tracks before the main file is loaded.
The easy fix would have been to check for master_demuxer, and not i==0.
But instead give up on the old idea, make some stricter assumptions how
demuxers and external tracks map, and simplify the code.
These functions do blocking work on a separate thread, but wait until
they return. So they are not async or non-blocking. But they do react to
user-input and client API accesses, which makes them reentrant.
Instead of accessing MPContext in player/timeline/*, create a separate
context struct, which the timeline loaders fill out. It turns out that
there's not much in the way too big MPContext that these need to access.
One major PITA is managing (and closing) the set of open demuxers. The
problem is that we need a list of all demuxers to make sure no unneeded
streams are enabled.
This adds a callback to the demuxer_desc struct, with the intention of
leaving to to the demuxer to call the right loader, instead of
explicitly checking the demuxer type and dispatching manually in common
code. I also considered making the timeline part of the demuxer state,
but decided against: it's too much of a mess wrt. memory management and
threading, and also doesn't make it clear who owns the child demuxers.
With the struct timeline decoupled from the demuxer state, it's at least
somewhat clear that the child demuxers are independent from the "main"
demuxer.
The actual changes to player/timeline/* are separated in the following
commits, because they're quite verbose. Some artifacts will be removed
later as soon as there's only 1 timeline loading mechanism.
These commands are counterparts of sub_add/sub_remove/sub_reload which
work for external audio file.
Signed-off-by: wm4 <wm4@nowhere>
(minor simplification)
mpctx->audio_delay always has the same value as opts->audio_delay. (This
was not the case a long time ago, when the audio-delay property didn't
actually write to opts->audio_delay. I think.)
This is for the ordered chapters case only. In theory this could have
resulted in initial audio, video or subs missing, although it didn't
happen in practice (because no streams were selected, thus the demuxer
thread didn't actually try to read anything). It's still better to make
this explicit.
Also, timeline_set_part() can be private to loadfile.c.
Most of this is explained in the code comments. This change should
improve performance with vapoursynth, especially if concurrent requests
are used.
This should change nothing if vf_vapoursynth is not in the filter chain,
since non-threaded filters obviously can not asynchronously finish
filtering of frames.
This attempts to increase user-friendliness by excluding useless tags.
It should be especially helpful with mp4 files, because the FFmpeg mp4
demuxer adds tons of completely useless information to the metadata.
Fixes#1403.
Until now, these options took effect only at program start. This could
be confusing when e.g. doing "mpv list.m3u --shuffle". Make them always
take effect when a playlist is loaded either via a playlist file, or
with the "loadlist" command.
The code in the demuxer etc. was changed to update all metadata/tags at
once, instead of changing each metadata field. As a consequence,
printing of the tags to the terminal was also changed to print
everything on each change.
Some users didn't like this. Add a very primitive way to avoid printing
fields with the same value again if metadata is marked as changed. This
is not always correct (could print unchanged fields anyway), but usually
works.
(In general, a rather roundabout way to reflect a changed title with ICY
streaming...)
Fixes#813 (let's call it a "policy change").
This adds API to libmpv that lets host applications use the mpv opengl
renderer. This is a more flexible (and possibly more portable) option to
foreign window embedding (via --wid).
This assumes that methods like context sharing and multithreaded OpenGL
rendering are infeasible, and that a way is needed to integrate it with
an application that uses a single thread to render everything.
Add an example that does this with QtQuick/qml. The example is
relatively lazy, but still shows how relatively simple the integration
is. The FBO indirection could probably be avoided, but would require
more work (and would probably lead to worse QtQuick integration, because
it would have to ignore transformations like rotation).
Because this makes mpv directly use the host application's OpenGL
context, there is no platform specific code involved in mpv, except
for hw decoding interop.
main.qml is derived from some Qt example.
The following things are still missing:
- a way to do better video timing
- expose GL renderer options, allow changing them at runtime
- support for color equalizer controls
- support for screenshots
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.
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.
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.
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.
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.
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).
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.
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
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.
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)
This reverts commit 45c8b97efb.
Some else complained (github issue #1163).
The feature requested in #1148 will be implemented differently in
the following commit.
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 ).
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.
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().
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.
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.
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.
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.
This mechanism originates from MPlayer's way of dealing with blocking
network, but it's still useful. On opening and closing, mpv waits for
network synchronously, and also some obscure commands and use-cases can
lead to such blocking. In these situations, the stream is asynchronously
forced to stop by "interrupting" it.
The old design interrupting I/O was a bit broken: polling with a
callback, instead of actively interrupting it. Change the direction of
this. There is no callback anymore, and the player calls
mp_cancel_trigger() to force the stream to return.
libavformat (via stream_lavf.c) has the old broken design, and fixing it
would require fixing libavformat, which won't happen so quickly. So we
have to keep that part. But everything above the stream layer is
prepared for a better design, and more sophisticated methods than
mp_cancel_test() could be easily introduced.
There's still one problem: commands are still run in the central
playback loop, which we assume can block on I/O in the worst case.
That's not a problem yet, because we simply mark some commands as being
able to stop playback of the current file ("quit" etc.), so input.c
could abort playback as soon as such a command is queued. But there are
also commands abort playback only conditionally, and the logic for that
is in the playback core and thus "unreachable". For example,
"playlist_next" aborts playback only if there's a next file. We don't
want it to always abort playback.
As a quite ugly hack, abort playback only if at least 2 abort commands
are queued - this pretty much happens only if the core is frozen and
doesn't react to input.
The purpose is making accessing the current playlist entry saner when
commands are executed during initialization, termination, or after
playlist navigation commands.
For example, the "playlist_remove current" command will invalidate
playlist->current - but some things still access the playlist entry even
on uninit. Until now, checking stop_play implicitly took care of it, so
it worked, but it was still messy.
Introduce the mpctx->playing field, which points to the current playlist
entry, even if the entry was removed and/or the playlist's current entry
was moved (e.g. due to playlist navigation).
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.
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.