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?)
And remove the same thing from the client API code.
The command.c code has to deal with many specialized M_PROPERTY_SET_*
actions, and we bother with a subset only.
Instead of having a separate for each, which also requires separate
additional caching in the demuxer. (The demuxer adds an indirection,
since STREAM_CTRLs are not thread-safe.)
Since this includes the cache speed, this should fix#3003.
Should reflect I/O speed.
This could go into the terminal status line. But I'm not sure how to put
it there, since it already uses too much space, so it's not there yet.
This pause stuff is bothersome and is needed only for a few corner-
cases. This commit removes it from the demuxer public API and replaces
it with a demux_run_on_thread() function and refactors the code which
needed demux_pause(). The next commit will change the implementation.
Changing the byte stream position without cooperation of the demuxer
seems a bit insane, and is certainly useless. A user should do factor
seeks instead. For formats like ts, this will actually translate to byte
seeks, while treating the rest of the playback chain a bit more
gracefully. With this argument, remove write access to this property.
If someone really complains, proper byte seeks could be added as seek
mode (although I'm going to need a convincing argument for this).
Read access changes too, but in a more subtle way.
No need to have them everywhere. The only exception/annoyance is
MAX_OSD_PARTS, which is now basically duplicated (and at runtime
initialization is checked with an assert()).
Was only available via --vd=help and --ad=help (i.e. not at all via
client API). Not bothering with separating audio and video codecs, since
this list isn't all that useful anyway in general. If someone complains,
a type field could be added.
Export a number of container fields, which may or may not be useful in
some scenarios. They are explicitly marked as originating from the
demuxer, in order to make it explicit that they might be unreliable.
I'd actually like to remove all other cases where container information
is exported, but those numerous cases are going to be somewhat hard to
deprecate.
Also, not directly related, export the description of the currently
active decoder. (This has been requested before.)
Unfortunately I see no better solution.
The refresh seek is skipped if the amount of buffered audio is not
overly huge.
Unfortunately softvol af_volume insertion still can cause this issue,
because it's outside of the normal dynamic filter chain changing code.
Move the video refresh call to reinit_video_filters() to make it more
uniform along with the audio code.
We just need to provide an entrypoint for it, and move the main init
code to a separate function. This gets rid of the messy video chain full
reinit in command.c, which completely destroyed and recreated the video
state for the purpose of mid-stream hw/sw switching.
This seems generally easier when using libmpv (and was already requested
and implemented before: see commit 327a779a; it was reverted some time
later).
With the weird internal logic we have to deal with, in particular the
--softvol=no case (using system volume), and using the audio API's mixer
(--softvol=auto on some systems), we still can't avoid all glitches and
corner cases that complicate this issue so much. The API user is either
recommended to use --softvol=yes or auto, or to watch the new
mixer-active property, and assume the volume/mute properties have
significant values if the mixer is active.
Remaining glitches:
- changing the volume/mute properties has no effect if no internal mixer
is used (--softvol=no) and the mixer is not active; the actual mixer
controls do not change, only the property values
- --volume/--mute do not have an effect on the volume/mute properties
before mixer initialization (the options strictly are only applied
during mixer init)
- volume-max is 100 while the mixer is not active
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.
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).
The aspect ratio calculations are cached (mainly so that aspect ratio
related messages are not logged on every frame). The cache is not clared
anymore when video filters are reconfigured, but changing the
video-aspect-ratio property relied on it. Make it explicit.
Fixes#2714.
The binding is similar to the tv-binding, just with capital letters.
Switching the dvb-channel-name property compared to dvb-channel
means the channel-name is shown on-screen when switching instead of
"dvb-channel (error)" otherwise,
and switching anyways happens without changing the card.
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.
On read, it returns the name of the current DVB program,
on write, it triggers a channel-switch to the program
if it is found in the channel list of the currently active card.
Compared to the dvb-channel property which already exists
and is a pair of integers (card + channel number) this has the limitation
of not switching the card, but is probably of much more common use.
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.
Instead of handling this on filter chain reinit, do it directly after
the decoder. This makes the code less entangled. In particular, this
gets rid of the really weird "override params" concept in the video
filter code.
The last_format/fixed_formats have some redundance with decoder_output,
but unfortunately the latter has a slightly different use.
This is mainly a refactor. I'm hoping it will make some things easier
in the future due to cleanly separating codec metadata and stream
metadata.
Also, declare that the "codec" field can not be NULL anymore. demux.c
will set it to "" if it's NULL when added. This gets rid of a corner
case everything had to handle, but which rarely happened.
For files with only 1 chapter, the "cycle" command was ignored. Reenable
it, but don't let it terminate playback of the file.
For the full story, see #2550.
Fixes#2550.
See #2609:
"When eof is reached it would be shown on the OSD and in the console.
Next try seeking to the middle. Seeking to the middle of the file will
only result in the OSD message being updated. Lua seems to fail to
observe the change in the property until the video is unpaused."
The "script-binding" command is used by the Lua scripting wrapper to
register key bindings on the fly. It's also the only way to get fine-
grained information about key events (such as separate key up/down
events). This information is sent via a "key-binding" message when the
state of a key changes.
Extend it to send name of the mapped key itself. Previously, it was
assumed that the user just uses an unique identifier for the binding's
name, so it wasn't needed. With this change, a user can map exactly the
same command to multiple keys, which is useful especially with the next
commit.
Part of #2612.
This is for the sake of command.c and the "deinterlace" option/property.
Instead of forcing certain "better" defaults when inserting yadif,
change the actual "yadif" defaults.
I pondered not changing vf_yadif, and instead adding a trivial "yadif-
auto" wrapper filter, which would merely have different defaults. But
thinking about it, it doesn't make any sense for "deinterlace" to have
different defaults from vf_yadif, with vf_yadif having the "worse"
defaults. If someone wants the old behavior, the old behavior can be
forced in a backward and forward compatible way by setting the
suboptions.
Fixes#2539 (kind of).
MPlayer traditionally always used the display aspect ratio, e.g. 16:9,
while FFmpeg uses the sample (aka pixel) aspect ratio.
Both have a bunch of advantages and disadvantages. Actually, it seems
using sample aspect ratio is generally nicer. The main reason for the
change is making mpv closer to how FFmpeg works in order to make life
easier. It's also nice that everything uses integer fractions instead
of floats now (except --video-aspect option/property).
Note that there is at least 1 user-visible change: vf_dsize now does
not set the display size, only the display aspect ratio. This is
because the image_params d_w/d_h fields did not just set the display
aspect, but also the size (except in encoding mode).
This is simply the average refresh rate. Including "bad" samples is
actually an advantage, because the property exists only for
informational purposes, and will reflect problems such as the driver
skipping a vsync.
Also export the standard deviation of the vsync frame duration
(normalized to the range 0-1) as vsync-jitter property.
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 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.
"Missed" implies the frame was dropped, but what really happens is that
the following frame will be shown later than intended (due to the
current frame skipping a vsync).
(As of this commit, this property is still inactive and always
returns 0. See git blame for details.)
Has the same function as setting the option.
This commit changes the property in a bunch of other ways. For example
if the VO is not created, it will return the option value.
This makes the bitrate properties unavailable, instead of
returning 0 when:
1. No track is selected, or
2. Not enough packets have been read to have a bitrate estimate yet
Let's hope this doesn't confuse client API users too much. It's still
the best solution to get rid of corner cases where it actually return
the wrong timestamp on start, and then suddenly jump.
The stop command didn't always stop. In this case, opening a HLS URL and
then sending "stop" during loading would actually make it fallback to
parsing it as a playlist, and then continued to play the playlist items.
(This corner case makes several unfortunate factors come together to
produce this really odd behavior.)
Another issue is that the "stop" was not always explicitly set. This
could be a problem when sending several commands at once. Only the
"quit" command should have priority over the "stop" command, so this is
still checked.
Useless. Sometimes it might be useful to make some extremely broken
files work, but on the other hand --no-correct-pts is sufficient for
these cases.
While we still need some of the code for AVI, the "auto" mode in
particular inflated the size of the code.
The vf_format suboption is replaced with --video-output-levels (a global
option and property). In particular, the parameter is removed from
mp_image_params. The mechanism is moved to the "video equalizer", which
also handles common video output customization like brightness and
contrast controls.
The new code is slightly cleaner, and the top-level option is slightly
more user-friendly than as vf_format sub-option.
The value 0 was treated specially, and effectively forced the increment
to 1. Interestingly, passing 0 or no value also does not include the
scale (from touchpads etc.), but this is probably an accidental behavior
that was never intentionally added.
Simplify it and make the default increment 1. 0 now means what it
should: the value will not be changed. This is not particularly useful,
but on the other hand there is no need for surprising and unintuitive
semantics.
OARG_CYCLEDIR() failed to apply the default value, because
m_option_type_cycle_dir was missing a copy handler - add this too.
Provides a simplistic way to seek without having to care about weird
situations like timestamp vs. playback time. This is good, because the
seek command is currently timestamp based, so when using the seek
command the user _does_ have to care.
Instead, force everyone to use the metadata struct and set a "title"
field. This is only a problem for the timeline producers, which set up
chapters manually. (They do this because a timeline is a separate
struct.)
This fixes the behavior of the chapter-metadata property, which never
returned a "title" property for e.g. ordered chapters.
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.)
Removes some more internal API calls from the Lua scripting backend.
Which is good, because ideally the scripting backend would use libmpv
functions only.
One awkwardness is that mouse sections are still not supported by the
public commands (and probably will never), so flags like allow-hide-
cursor make no sense to an outside user.
Also, the way flags are passed to the Lua function changes. But that's
ok, because they're only undocumented internal functions, and not
supposed to be used by script users. osc.lua only does due to historical
reasons.
This was requested. It was more or less present internally already and
used for Lua scripting. Lua will switch to the "public" functions in
the following commits.
Now it can always be read. Normally returns the value of the video-
aspect option. Writing it sets the option. If the aspect is not forced,
it will attempt to return whatever is the current video aspect.
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.
If filters are disabled or reconfigured, attempt to remove and probe the
deinterlace filter again. This fixes behavior if e.g. a software deint
filter was automatically inserted, and then hardware decoding is enabled
during playback. Without this commit, initializing hw decoding would
fail because of the software filter; with this commit, it'll replace it
with the hw deinterlacer instead.
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.)
This is a real pain: if a quit command is received, it's set to PT_QUIT.
And then other code could overwrite it, making it not quit. The annoying
bit is that stop_play is written and read in many places. Just not
overwriting it unconditionally seems to be the best course of action.
Some window managers let you change the fullscreen state of any window
using a key combination. For example, on XFWM you can use Alt+F11 and
on Compiz you can configure a key combination with the
"Extra WM actions" plugin.
With this change mpv will handle these fullscreen state changes. So, if
you enter into fullscreen mode using the WM's shortcut and then you use
mpv's fullscreen toggle, you will get back into window mode.
Merges PR #2081.
Signed-off-by: wm4 <wm4@nowhere>
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.
The previous behavior is confusing if the B point is near EOF (consider
B being the duration of the file, which is strictly speaking past the
last video timestamp). The new behavior is fine as well for B being far
past EOF.
Achieve this by checking the EOF state in addition to whether playback
has reached the B point. Also, move the A-B loop code out of
command_event(). It just isn't useful anymore, and obfuscates the code
more than it makes it loop simple.
Fixes#2046.
Used a wrong condition, and I suppose it could crash in some situations.
Change it to lazily initialize the hotplug stuff, like the
audio-device-list property does.
This was matching e.g. both "foo/bar" and "foobar" against "foo", when
only the former should match. This could cause more property
notifications than necessary.
There's a short time during loading where external commands can add
external streams even before the main file is loaded (like during ytdl
hook execution). The track list is printed every time an external track
is added via commands. This was quite awkward when ytdl was adding
multiple streams, so don't print it in this stage. They are printed
anyway at the end of the loading process.
This command has been deprecated in the 0.8.x and 0.9.x releases - get
rid of it. Its only point ever was MPlayer compatibility, which broke
years ago anyway.
For certain reasons, we allow adding external tracks even before the
main file is loaded. This somewhat breaks in old assumption, which uses
mpctx->num_sources to determine whether a command can be applied in the
current state. Use the newer playback_initialized instead, which is a
much better choice for this purpose.
The previous commit removed this. Although mp_switch_track() can now be
called in all situations, we still don't want it to be called here.
Setting a track property while no file is loaded would simply deselect
the track instead of setting the underlying option to the requested
value.
Likewise, if the "cycle" command (M_PROPERTY_SWITCH) is used, don't just
deselect the track.
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.
Now it simply changes the options, i.e. what will be requested, instead
of returning M_PROPERTY_UNAVAILABLE.
This is another minor step towards unifying options and properties.
Still a bit weird: it will always return "no" if no file is loaded, and
disregards the option value.
Also replace their implementation with the recently introduced
properties. One significant difference is that audio-channels using OSD
formatting does not print the channel layout. The user can just use the
replacement property instead.
Now --volume takes an absolute volume, meaning it doesn't depend on
--softvol-max. 0 is still silence, and 100 now always means unchanged
volume. The OSD and the "volume" property are changed accordingly.
Also raise the minimum value of --softvol-max. A value below 100 makes
no sense and breaks the OSD.
The code checking for the type of seeking contained some if else
statements. To improve readability, I decided to refactor those
statements to a switch statement.
The OSD symbol for seeking to an absolute percentage was always OSD_FFW,
even when it should be OSD_REW. It uses the correct OSD symbols now, by
checking the current position ratio.
Note: The symbol is still incorrectly given when the absolute percentage
is very close to the current position ratio. Fortunately, that's a rare
use case.
Only absolute percentage seeking was permitted first. It is now also
possible to seek by relative percentage.
MPSEEK_FACTOR is used as seek_type.
Fixes#1950.
Signed-off-by: wm4 <wm4@nowhere>
In the most simple case, this prevents the track ID from changing. One
disadvantage is that if the file fails loading, the track is gone for
good and would have to be re-added explicitly by the user.
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.
Approximate time of video buffered in the demuxer, in seconds. Same as
`demuxer-cache-duration` but returns the last timestamp of bufferred
data in demuxer.
Signed-off-by: wm4 <wm4@nowhere>
Remove the old implementation for these properties. It was never very
good, often returned very innaccurate values or just 0, and was static
even if the source was variable bitrate. Replace it with the
implementation of "packet-video-bitrate". Mark the "packet-..."
properties as deprecated. (The effective difference is different
formatting, and returning the raw value in bits instead of kilobits.)
Also extend the documentation a little.
It appears at least some decoders (sipr?) need the
AVCodecContext.bit_rate field set, so this one is still passed through.
Remove the colorspace-related top-level options, add them to vf_format.
They are rather obscure and not needed often, so it's better to get them
out of the way. In particular, this gets rid of the semi-complicated
logic in command.c (most of which was needed for OSD display and the
direct feedback from the VO). It removes the duplicated color-related
name mappings.
This removes the ability to write the colormatrix and related
properties. Since filters can be changed at runtime, there's no loss of
functionality, except that you can't cycle automatically through the
color constants anymore (but who needs to do this).
This also changes the type of the mp_csp_names and related variables, so
they can directly be used with OPT_CHOICE. This probably ended up a bit
awkward, for the sake of not adding a new option type which would have
used the previous format.
There was a somewhat obscure optimization in the OSD and subtitle
rendering path: if only the position of the sub-images changed, and not
the actual image data, uploading of the image data could be skipped. In
theory, this could speed up things like scrolling subtitles.
But it turns out that even in the rare cases subtitles have such scrolls
or axis-aligned movement, modern libass rarely signals this kind of
change. Possibly this is because of sub-pixel handling and such, which
break this.
As such, it's a worthless optimization and just introduces additional
complexity and subtle bugs (especially in cases libass does the
opposite: incorrectly signaling a position change only, which happened
before). Remove this optimization, and rename bitmap_pos_id to
change_id.
This caused complaints because the fps was basically rounded on
microsecond boundaries in the vsync interval (it seemed convenient to
store only the vsync interval). So store the fps as float too, and let
the "display-fps" property return it directly.
Requested change in behavior.
Note that we set the assumed "infinite" display_fps to 1e6, which
conveniently lets vo_get_vsync_interval() return a dummy value of 1,
which can be easily checked against, and still avoids doing math with
float INFs.
Instead of refusing to set properties like "fullscreen" if no VO was
created, always allow it. So if no VO is created, setting the property
merely changes the options (and will be applied once the VO is created).
This is consistent with similar behavior changes to some other
properties.
Improves the behavior reported in #1676.
Also, we shouldn't check the config_ok variable - the VO should do this.