2010-01-30 23:24:23 +00:00
|
|
|
/*
|
2015-04-13 07:36:54 +00:00
|
|
|
* This file is part of mpv.
|
2010-01-30 23:24:23 +00:00
|
|
|
*
|
player: change license of most core files to LGPL
These files have all in common that they were fully or mostly taken from
mplayer.c. (mplayer.c was a huge file that contains almost all of the
playback core, until it was split into multiple parts.) This was
probably the hardest part to relicense, because so much code was moved
around all the time.
player/audio.c still does not compile. We'll have to redo audio
filtering. Once that is done, we can probably actually provide an
actual LGPL configure switch.
Here is a relatively detailed list of potential issues:
8d190244: author did not reply, parts were made GPL-only in a previous
commit.
7882ea9b: author could not be reached, but the code is gone. wscript
still has --datadir switch, but I don't think this is relevant to
copyright.
f197efd5: unclear origin, but I consider the code gone anyway (replaced
with generic OSD mechanisms).
8337d9c2: author did not reply, but only the option still exists (under
a different name), other code was removed.
d8fd7131: did not reply. Disabled in a previous commit.
05258251: same author as above. Both fields actually seem to have
vanished (even when tracking renames), so no action taken.
d459e644, 268b2c1a: author did not reply, but we reuse only the options
(with different names and slightly or fully different semantics, and
completely different implementations), so I don't think this is relevant
for copyright.
09e742fe, 17c39c4e: same as above.
e8a173de, bff4b3ee: author could not be reached. The commands were
reworked to properties, and the code outside of the TV code were moved
back to the TV code. So I don't think copyright applies to the current
command.c parts (mp_property_tv_color, mp_property_tv_freq,
mp_property_tv_scan). The TV parts remain GPL.
0810e427: could not be reached. Disabled in a previous commit.
43744a2d: unknown author, but this was replaced by dynamic alloc (if the
change is even copyrightable).
116ca0c7: unknown author; reasoning see input.c relicensing commit.
e7e4d1d8: these semantics still exist, but as generic code, and this
code was fully removed.
f1175cd9: the author of the cited patch is unknown, and upon inspection
it turns out that I was only using the idea to pause the player on EOF,
so I claim it's not copyright relevant.
25affdcc: author could not be reached (yet) - but it's only a function
rename, not copyrightable.
5728504c was committed by Arpi (who agreed), but hints that it might be
by a different author. In fact it seems to be mostly this patch:
http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2001-November/002041.html
The author did not respond, but it all seems to have been removed later.
It's a terrible mess though. Arpi reverted the A-V sync code at first,
but left the RTC code for a while. The following commits remove these
changes 100%: 14b35442, 7181a091, 31482783, 614f8475, df58e822.
cehoyos did explicitly not agree to LGPL, but was involved in the
following changes:
c99d8fc8: applied a patch and didn't modify it, the original author
agreed.
40ac0d31: author could not be reached, but all code is gone anyway. The
"af" command has a similar function, but works completely different and
actually reuses a mechanism older than this patch.
54350436: applied a patch, but didn't modify it, except for adding a
German translation, which was removed later.
a2dda036: same situation as above
240b743e: this was made GPL-only in a previous commit
7b25afd7: same as above (for now)
kirijua could not be reached, but was a regular patch contributor:
c2c997fd: video equalizer code move; probably not copyrightable. Is GPL
due to Nick anyway.
be54f481: technically, this became the audio track property later. But
all what is left is the fact that you pass a track ID to it, so consider
the original coypright non-relevant.
2f376d1b: this was rewritten in b7052b43, but for now we can afford to
be careful, so this was marked as GPL only in a previous commit.
43844d09: remaining parts in main.c were reverted in a previous commit.
anders has mostly disagreed with the LGPL relicensing. Does not want
libaf to become LGPL, but made some concessions. In particular, he
granted us permission to relicense 4943e9c52c and 242aa6ebd4. We also
consider some of his changes remaining in mpv not relevant for copyright
(such as 735de602 - we won't remove the this option completely). We will
completely remove his other contributions, including the entire audio
filter chain. For now, this stuff is marked as GPL only. The remaining
question is how much code in player/audio.c (based on the former
mplayer.c and dec_audio.c) is under his copyright. I made claims about
this in a previous commit.
Nick(ols) Kurshev, svn username "nick" and "nickols_k", could not be
reached. He had a lot of changes in early MPlayer. It seems all of that
was removed, at least in mpv. His main work, like VIDIX or libswscale
work, does not exist in mpv anymore, but the changes to mplayer.c and
other core parts still deserve attention:
a4119f6b, fb927549, ad3529b8, e11b23dc, 5f2178be, 93c371d5: removed in
b43d67e0, d1628d12, 24ed01fe, df58e822.
0a83c6ec, 104c125e, 4e067f62, aec5dcc8, b587a3d6, f3de6e6b: DR, VAA, and
"tune" stuff was fully removed later on or replaced with other
mechanisms.
340183b0: screenshots were redone later (the VOCTRL was even removed,
with an independent implementation using the same VOCTRL a few years
later), so not relevant anymore. Basically only the 's' shortcut remains
(but not its implementation).
92c5c274, bffd4007, 555c6766: for now marked as GPL only in a previous
commit.
Might contain some trace amounts of "michael"'s copyright, who agreed to
LGPL only once the core is relicensed. This will still be respected, but
I don't think it matters at this in this case. (Some code touched by him
was merged into mplayer.c, and then disappeared after heavy
refactoring.)
I tried to be as careful and as complete as possible. It can't be
excluded that amends to this will be made later.
This does not make the player LGPL yet.
2017-06-23 13:53:41 +00:00
|
|
|
* mpv is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2010-01-30 23:24:23 +00:00
|
|
|
*
|
2015-04-13 07:36:54 +00:00
|
|
|
* mpv is distributed in the hope that it will be useful,
|
2010-01-30 23:24:23 +00:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
player: change license of most core files to LGPL
These files have all in common that they were fully or mostly taken from
mplayer.c. (mplayer.c was a huge file that contains almost all of the
playback core, until it was split into multiple parts.) This was
probably the hardest part to relicense, because so much code was moved
around all the time.
player/audio.c still does not compile. We'll have to redo audio
filtering. Once that is done, we can probably actually provide an
actual LGPL configure switch.
Here is a relatively detailed list of potential issues:
8d190244: author did not reply, parts were made GPL-only in a previous
commit.
7882ea9b: author could not be reached, but the code is gone. wscript
still has --datadir switch, but I don't think this is relevant to
copyright.
f197efd5: unclear origin, but I consider the code gone anyway (replaced
with generic OSD mechanisms).
8337d9c2: author did not reply, but only the option still exists (under
a different name), other code was removed.
d8fd7131: did not reply. Disabled in a previous commit.
05258251: same author as above. Both fields actually seem to have
vanished (even when tracking renames), so no action taken.
d459e644, 268b2c1a: author did not reply, but we reuse only the options
(with different names and slightly or fully different semantics, and
completely different implementations), so I don't think this is relevant
for copyright.
09e742fe, 17c39c4e: same as above.
e8a173de, bff4b3ee: author could not be reached. The commands were
reworked to properties, and the code outside of the TV code were moved
back to the TV code. So I don't think copyright applies to the current
command.c parts (mp_property_tv_color, mp_property_tv_freq,
mp_property_tv_scan). The TV parts remain GPL.
0810e427: could not be reached. Disabled in a previous commit.
43744a2d: unknown author, but this was replaced by dynamic alloc (if the
change is even copyrightable).
116ca0c7: unknown author; reasoning see input.c relicensing commit.
e7e4d1d8: these semantics still exist, but as generic code, and this
code was fully removed.
f1175cd9: the author of the cited patch is unknown, and upon inspection
it turns out that I was only using the idea to pause the player on EOF,
so I claim it's not copyright relevant.
25affdcc: author could not be reached (yet) - but it's only a function
rename, not copyrightable.
5728504c was committed by Arpi (who agreed), but hints that it might be
by a different author. In fact it seems to be mostly this patch:
http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2001-November/002041.html
The author did not respond, but it all seems to have been removed later.
It's a terrible mess though. Arpi reverted the A-V sync code at first,
but left the RTC code for a while. The following commits remove these
changes 100%: 14b35442, 7181a091, 31482783, 614f8475, df58e822.
cehoyos did explicitly not agree to LGPL, but was involved in the
following changes:
c99d8fc8: applied a patch and didn't modify it, the original author
agreed.
40ac0d31: author could not be reached, but all code is gone anyway. The
"af" command has a similar function, but works completely different and
actually reuses a mechanism older than this patch.
54350436: applied a patch, but didn't modify it, except for adding a
German translation, which was removed later.
a2dda036: same situation as above
240b743e: this was made GPL-only in a previous commit
7b25afd7: same as above (for now)
kirijua could not be reached, but was a regular patch contributor:
c2c997fd: video equalizer code move; probably not copyrightable. Is GPL
due to Nick anyway.
be54f481: technically, this became the audio track property later. But
all what is left is the fact that you pass a track ID to it, so consider
the original coypright non-relevant.
2f376d1b: this was rewritten in b7052b43, but for now we can afford to
be careful, so this was marked as GPL only in a previous commit.
43844d09: remaining parts in main.c were reverted in a previous commit.
anders has mostly disagreed with the LGPL relicensing. Does not want
libaf to become LGPL, but made some concessions. In particular, he
granted us permission to relicense 4943e9c52c and 242aa6ebd4. We also
consider some of his changes remaining in mpv not relevant for copyright
(such as 735de602 - we won't remove the this option completely). We will
completely remove his other contributions, including the entire audio
filter chain. For now, this stuff is marked as GPL only. The remaining
question is how much code in player/audio.c (based on the former
mplayer.c and dec_audio.c) is under his copyright. I made claims about
this in a previous commit.
Nick(ols) Kurshev, svn username "nick" and "nickols_k", could not be
reached. He had a lot of changes in early MPlayer. It seems all of that
was removed, at least in mpv. His main work, like VIDIX or libswscale
work, does not exist in mpv anymore, but the changes to mplayer.c and
other core parts still deserve attention:
a4119f6b, fb927549, ad3529b8, e11b23dc, 5f2178be, 93c371d5: removed in
b43d67e0, d1628d12, 24ed01fe, df58e822.
0a83c6ec, 104c125e, 4e067f62, aec5dcc8, b587a3d6, f3de6e6b: DR, VAA, and
"tune" stuff was fully removed later on or replaced with other
mechanisms.
340183b0: screenshots were redone later (the VOCTRL was even removed,
with an independent implementation using the same VOCTRL a few years
later), so not relevant anymore. Basically only the 's' shortcut remains
(but not its implementation).
92c5c274, bffd4007, 555c6766: for now marked as GPL only in a previous
commit.
Might contain some trace amounts of "michael"'s copyright, who agreed to
LGPL only once the core is relicensed. This will still be respected, but
I don't think it matters at this in this case. (Some code touched by him
was merged into mplayer.c, and then disappeared after heavy
refactoring.)
I tried to be as careful and as complete as possible. It can't be
excluded that amends to this will be made later.
This does not make the player LGPL yet.
2017-06-23 13:53:41 +00:00
|
|
|
* GNU Lesser General Public License for more details.
|
2010-01-30 23:24:23 +00:00
|
|
|
*
|
player: change license of most core files to LGPL
These files have all in common that they were fully or mostly taken from
mplayer.c. (mplayer.c was a huge file that contains almost all of the
playback core, until it was split into multiple parts.) This was
probably the hardest part to relicense, because so much code was moved
around all the time.
player/audio.c still does not compile. We'll have to redo audio
filtering. Once that is done, we can probably actually provide an
actual LGPL configure switch.
Here is a relatively detailed list of potential issues:
8d190244: author did not reply, parts were made GPL-only in a previous
commit.
7882ea9b: author could not be reached, but the code is gone. wscript
still has --datadir switch, but I don't think this is relevant to
copyright.
f197efd5: unclear origin, but I consider the code gone anyway (replaced
with generic OSD mechanisms).
8337d9c2: author did not reply, but only the option still exists (under
a different name), other code was removed.
d8fd7131: did not reply. Disabled in a previous commit.
05258251: same author as above. Both fields actually seem to have
vanished (even when tracking renames), so no action taken.
d459e644, 268b2c1a: author did not reply, but we reuse only the options
(with different names and slightly or fully different semantics, and
completely different implementations), so I don't think this is relevant
for copyright.
09e742fe, 17c39c4e: same as above.
e8a173de, bff4b3ee: author could not be reached. The commands were
reworked to properties, and the code outside of the TV code were moved
back to the TV code. So I don't think copyright applies to the current
command.c parts (mp_property_tv_color, mp_property_tv_freq,
mp_property_tv_scan). The TV parts remain GPL.
0810e427: could not be reached. Disabled in a previous commit.
43744a2d: unknown author, but this was replaced by dynamic alloc (if the
change is even copyrightable).
116ca0c7: unknown author; reasoning see input.c relicensing commit.
e7e4d1d8: these semantics still exist, but as generic code, and this
code was fully removed.
f1175cd9: the author of the cited patch is unknown, and upon inspection
it turns out that I was only using the idea to pause the player on EOF,
so I claim it's not copyright relevant.
25affdcc: author could not be reached (yet) - but it's only a function
rename, not copyrightable.
5728504c was committed by Arpi (who agreed), but hints that it might be
by a different author. In fact it seems to be mostly this patch:
http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2001-November/002041.html
The author did not respond, but it all seems to have been removed later.
It's a terrible mess though. Arpi reverted the A-V sync code at first,
but left the RTC code for a while. The following commits remove these
changes 100%: 14b35442, 7181a091, 31482783, 614f8475, df58e822.
cehoyos did explicitly not agree to LGPL, but was involved in the
following changes:
c99d8fc8: applied a patch and didn't modify it, the original author
agreed.
40ac0d31: author could not be reached, but all code is gone anyway. The
"af" command has a similar function, but works completely different and
actually reuses a mechanism older than this patch.
54350436: applied a patch, but didn't modify it, except for adding a
German translation, which was removed later.
a2dda036: same situation as above
240b743e: this was made GPL-only in a previous commit
7b25afd7: same as above (for now)
kirijua could not be reached, but was a regular patch contributor:
c2c997fd: video equalizer code move; probably not copyrightable. Is GPL
due to Nick anyway.
be54f481: technically, this became the audio track property later. But
all what is left is the fact that you pass a track ID to it, so consider
the original coypright non-relevant.
2f376d1b: this was rewritten in b7052b43, but for now we can afford to
be careful, so this was marked as GPL only in a previous commit.
43844d09: remaining parts in main.c were reverted in a previous commit.
anders has mostly disagreed with the LGPL relicensing. Does not want
libaf to become LGPL, but made some concessions. In particular, he
granted us permission to relicense 4943e9c52c and 242aa6ebd4. We also
consider some of his changes remaining in mpv not relevant for copyright
(such as 735de602 - we won't remove the this option completely). We will
completely remove his other contributions, including the entire audio
filter chain. For now, this stuff is marked as GPL only. The remaining
question is how much code in player/audio.c (based on the former
mplayer.c and dec_audio.c) is under his copyright. I made claims about
this in a previous commit.
Nick(ols) Kurshev, svn username "nick" and "nickols_k", could not be
reached. He had a lot of changes in early MPlayer. It seems all of that
was removed, at least in mpv. His main work, like VIDIX or libswscale
work, does not exist in mpv anymore, but the changes to mplayer.c and
other core parts still deserve attention:
a4119f6b, fb927549, ad3529b8, e11b23dc, 5f2178be, 93c371d5: removed in
b43d67e0, d1628d12, 24ed01fe, df58e822.
0a83c6ec, 104c125e, 4e067f62, aec5dcc8, b587a3d6, f3de6e6b: DR, VAA, and
"tune" stuff was fully removed later on or replaced with other
mechanisms.
340183b0: screenshots were redone later (the VOCTRL was even removed,
with an independent implementation using the same VOCTRL a few years
later), so not relevant anymore. Basically only the 's' shortcut remains
(but not its implementation).
92c5c274, bffd4007, 555c6766: for now marked as GPL only in a previous
commit.
Might contain some trace amounts of "michael"'s copyright, who agreed to
LGPL only once the core is relicensed. This will still be respected, but
I don't think it matters at this in this case. (Some code touched by him
was merged into mplayer.c, and then disappeared after heavy
refactoring.)
I tried to be as careful and as complete as possible. It can't be
excluded that amends to this will be made later.
This does not make the player LGPL yet.
2017-06-23 13:53:41 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
|
2010-01-30 23:24:23 +00:00
|
|
|
*/
|
|
|
|
|
2008-02-22 09:09:46 +00:00
|
|
|
#ifndef MPLAYER_MP_CORE_H
|
|
|
|
#define MPLAYER_MP_CORE_H
|
2008-01-01 21:35:58 +00:00
|
|
|
|
2015-07-06 20:28:28 +00:00
|
|
|
#include <pthread.h>
|
2023-10-19 12:18:52 +00:00
|
|
|
#include <stdatomic.h>
|
2023-10-19 14:26:26 +00:00
|
|
|
#include <stdbool.h>
|
2016-09-16 12:25:50 +00:00
|
|
|
|
2014-02-17 01:52:26 +00:00
|
|
|
#include "libmpv/client.h"
|
|
|
|
|
2013-12-17 01:39:45 +00:00
|
|
|
#include "common/common.h"
|
video: rewrite filtering glue code
Get rid of the old vf.c code. Replace it with a generic filtering
framework, which can potentially handle more than just --vf. At least
reimplementing --af with this code is planned.
This changes some --vf semantics (including runtime behavior and the
"vf" command). The most important ones are listed in interface-changes.
vf_convert.c is renamed to f_swscale.c. It is now an internal filter
that can not be inserted by the user manually.
f_lavfi.c is a refactor of player/lavfi.c. The latter will be removed
once --lavfi-complex is reimplemented on top of f_lavfi.c. (which is
conceptually easy, but a big mess due to the data flow changes).
The existing filters are all changed heavily. The data flow of the new
filter framework is different. Especially EOF handling changes - EOF is
now a "frame" rather than a state, and must be passed through exactly
once.
Another major thing is that all filters must support dynamic format
changes. The filter reconfig() function goes away. (This sounds complex,
but since all filters need to handle EOF draining anyway, they can use
the same code, and it removes the mess with reconfig() having to predict
the output format, which completely breaks with libavfilter anyway.)
In addition, there is no automatic format negotiation or conversion.
libavfilter's primitive and insufficient API simply doesn't allow us to
do this in a reasonable way. Instead, filters can use f_autoconvert as
sub-filter, and tell it which formats they support. This filter will in
turn add actual conversion filters, such as f_swscale, to perform
necessary format changes.
vf_vapoursynth.c uses the same basic principle of operation as before,
but with worryingly different details in data flow. Still appears to
work.
The hardware deint filters (vf_vavpp.c, vf_d3d11vpp.c, vf_vdpaupp.c) are
heavily changed. Fortunately, they all used refqueue.c, which is for
sharing the data flow logic (especially for managing future/past
surfaces and such). It turns out it can be used to factor out most of
the data flow. Some of these filters accepted software input. Instead of
having ad-hoc upload code in each filter, surface upload is now
delegated to f_autoconvert, which can use f_hwupload to perform this.
Exporting VO capabilities is still a big mess (mp_stream_info stuff).
The D3D11 code drops the redundant image formats, and all code uses the
hw_subfmt (sw_format in FFmpeg) instead. Although that too seems to be a
big mess for now.
f_async_queue is unused.
2018-01-16 10:53:44 +00:00
|
|
|
#include "filters/filter.h"
|
|
|
|
#include "filters/f_output_chain.h"
|
2013-12-17 01:02:25 +00:00
|
|
|
#include "options/options.h"
|
2014-01-18 00:19:20 +00:00
|
|
|
#include "sub/osd.h"
|
audio: introduce a new type to hold audio frames
This is pretty pointless, but I believe it allows us to claim that the
new code is not affected by the copyright of the old code. This is
needed, because the original mp_audio struct was written by someone who
has disagreed with LGPL relicensing (it was called af_data at the time,
and was defined in af.h).
The "GPL'ed" struct contents that surive are pretty trivial: just the
data pointer, and some metadata like the format, samplerate, etc. - but
at least in this case, any new code would be extremely similar anyway,
and I'm not really sure whether it's OK to claim different copyright. So
what we do is we just use AVFrame (which of course is LGPL with 100%
certainty), and add some accessors around it to adapt it to mpv
conventions.
Also, this gets rid of some annoying conventions of mp_audio, like the
struct fields that require using an accessor to write to them anyway.
For the most part, this change is only dumb replacements of mp_audio
related functions and fields. One minor actual change is that you can't
allocate the new type on the stack anymore.
Some code still uses mp_audio. All audio filter code will be deleted, so
it makes no sense to convert this code. (Audio filters which are LGPL
and which we keep will have to be ported to a new filter infrastructure
anyway.) player/audio.c uses it because it interacts with the old filter
code. push.c has some complex use of mp_audio and mp_audio_buffer, but
this and pull.c will most likely be rewritten to do something else.
2017-08-16 19:00:20 +00:00
|
|
|
#include "audio/aframe.h"
|
2016-01-16 20:19:52 +00:00
|
|
|
#include "video/mp_image.h"
|
2015-07-01 17:22:40 +00:00
|
|
|
#include "video/out/vo.h"
|
2008-01-30 07:21:05 +00:00
|
|
|
|
2007-02-21 00:49:24 +00:00
|
|
|
// definitions used internally by the core player code
|
|
|
|
|
2008-08-13 05:06:26 +00:00
|
|
|
enum stop_play_reason {
|
2018-05-19 16:25:54 +00:00
|
|
|
KEEP_PLAYING = 0, // playback of a file is actually going on
|
|
|
|
// must be 0, numeric values of others do not matter
|
mplayer: attempt to skip playlist entries which can't be played
This is for situations when repeated attempts at playing a playlist
entry failed, and playlist navigation becomes impossible due to that.
For example, it wasn't possible to skip backwards past an unplayable
playlist entry:
mpv file1.mkv doesntexist.mkv file3.mkv
You couldn't skip back to file1.mkv from file3.mkv. When running a
single "playlist_prev" command, doesntexist.mkv would be played, which
would fail to load. As reaction to the failure to load it, the next file
would be played, which is file3.mkv.
To make this even worse, the file could successfully load, but run only
for a split second. So just loading successfully isn't good enough.
Attempt to solve this by marking problematic playlist entries as failed,
and by having playlist_prev skip past such playlist entries. We define
failure as not being able to play more than 3 seconds (or failing to
initialize to begin with). (The 3 seconds are in real time, not file
duration.)
"playlist_prev force" still exhibits the old behavior.
Additionally, use the same mechanism to prevent pointless infinite
reloading if none of the files on the playlist exist. (See github issue
All in all, this is a heuristic, and later adjustments might be
necessary.
Note: forward skips (playlist_next) are not affected at all. (Except for
the interaction with --loop.)
2013-09-15 03:03:37 +00:00
|
|
|
AT_END_OF_FILE, // file has ended, prepare to play next
|
|
|
|
// also returned on unrecoverable playback errors
|
mplayer: turn playtree into a list, and change per-file option handling
Summary:
- There is no playtree anymore. It's reduced to a simple list.
- Options are now always global. You can still have per-file options,
but these are optional and require special syntax.
- The slave command pt_step has been removed, and playlist_next
and playlist_prev added. (See etc/input.conf changes.)
This is a user visible incompatible change, and will break slave-mode
applications.
- The pt_clear slave command is renamed to playlist_clear.
- Playtree entries could have multiple files. This is not the case
anymore, and playlist entries have always exactly one entry. Whenever
something adds more than one file (like ASX playlists or dvd:// or
dvdnav:// on the command line), all files are added as separate
playlist entries.
Note that some of the changes are quite deep and violent. Expect
regressions.
The playlist parsing code in particular is of low quality. I didn't try
to improve it, and merely spent to least effort necessary to keep it
somehow working. (Especially ASX playlist handling.)
The playtree code was complicated and bloated. It was also barely used.
Most users don't even know that mplayer manages the playlist as tree,
or how to use it. The most obscure features was probably specifying a
tree on command line (with '{' and '}' to create/close tree nodes). It
filled the player code with complexity and confused users with weird
slave commands like pt_up.
Replace the playtree with a simple flat playlist. Playlist parsers that
actually return trees are changed to append all files to the playlist
pre-order.
It used to be the responsibility of the playtree code to change per-file
config options. Now this is done by the player core, and the playlist
code is free of such details.
Options are not per-file by default anymore. This was a very obscure and
complicated feature that confused even experienced users. Consider the
following command line:
mplayer file1.mkv file2.mkv --no-audio file3.mkv
This will disable the audio for file2.mkv only, because options are
per-file by default. To make the option affect all files, you're
supposed to put it before the first file.
This is bad, because normally you don't need per-file options. They are
very rarely needed, and the only reasonable use cases I can imagine are
use of the encode backend (mplayer encode branch), or for debugging. The
normal use case is made harder, and the feature is perceived as bug.
Even worse, correct usage is hard to explain for users.
Make all options global by default. The position of an option isn't
significant anymore (except for options that compensate each other,
consider --shuffle --no-shuffle).
One other important change is that no options are reset anymore if a
new file is started. If you change settings with slave mode commands,
they will not be changed by playing a new file. (Exceptions include
settings that are too file specific, like audio/subtitle stream
selection.)
There is still some need for per-file options. Debugging and encoding
are use cases that profit from per-file options. Per-file profiles (as
well as per-protocol and per-VO/AO options) need the implementation
related mechanisms to backup and restore options when the playback file
changes.
Simplify the save-slot stuff, which is possible because there is no
hierarchical play tree anymore. Now there's a simple backup field.
Add a way to specify per-file options on command line. Example:
mplayer f1.mkv -o0 --{ -o1 f2.mkv -o2 f3.mkv --} f4.mkv -o3
will have the following options per file set:
f1.mkv, f4.mkv: -o0 -o3
f2.mkv, f3.mkv: -o0 -o3 -o1 -o2
The options --{ and --} start and end per-file options. All files inside
the { } will be affected by the options equally (similar to how global
options and multiple files are handled). When playback of a file starts,
the per-file options are set according to the command line. When
playback ends, the per-file options are restored to the values when
playback started.
2012-07-31 19:33:26 +00:00
|
|
|
PT_NEXT_ENTRY, // prepare to play next entry in playlist
|
|
|
|
PT_CURRENT_ENTRY, // prepare to play mpctx->playlist->current
|
player: fix subtle idle mode differences on early program start
If the user manages to run a "loadfile x append" command before the loop
in mp_play_files() is entered, then the player could start playing
these. This isn't expected, because appending files to the playlist in
idle mode does not normally start playback. It could happen because
there is a short time window where commands are processed before the
loop is entered (such as running the command when a script is loaded).
The idle mode semantics are pretty weird: if files were provided in
advance (on the command line), then these should be played immediately.
But if idle mode was already entered, and something is appended to the
playlist using "append", i.e. without explicitly triggering playback,
then it should remain in idle mode.
Try to follow this by redefining PT_STOP to strictly mean idle mode.
Remove the playlist->current check from idle_loop(), since only the
stop_play field counts now (cf. what mp_set_playlist_entry() does).
This actually introduces the possibility that playlist->current, and
with it playlist-pos, are set to something, even though playback is not
active or being started. Previously, this was only possible during state
transitions, such as when changing playlist entries.
Very annoyingly, this means the current way MPV_EVENT_IDLE was sent
doesn't work anymore. Logically, idle mode can be "active" even if
idle_loop() was not entered yet (between the time after mp_initialize()
and before the loop in mp_play_files()). Instead of worrying about this,
redo the "idle-active" property, and deprecate the event.
See: #7543
2020-03-21 13:01:38 +00:00
|
|
|
PT_STOP, // stop playback / idle mode
|
2012-08-04 01:46:11 +00:00
|
|
|
PT_QUIT, // stop playback, quit player
|
2014-10-28 15:19:07 +00:00
|
|
|
PT_ERROR, // play next playlist entry (due to an error)
|
2008-08-13 05:06:26 +00:00
|
|
|
};
|
2007-02-21 00:49:24 +00:00
|
|
|
|
2012-09-25 01:24:38 +00:00
|
|
|
enum mp_osd_seek_info {
|
|
|
|
OSD_SEEK_INFO_BAR = 1,
|
|
|
|
OSD_SEEK_INFO_TEXT = 2,
|
|
|
|
OSD_SEEK_INFO_CHAPTER_TEXT = 4,
|
2017-01-04 23:07:28 +00:00
|
|
|
OSD_SEEK_INFO_CURRENT_FILE = 8,
|
2012-09-25 01:24:38 +00:00
|
|
|
};
|
|
|
|
|
2013-10-30 20:47:14 +00:00
|
|
|
|
|
|
|
enum {
|
|
|
|
// other constants
|
|
|
|
OSD_LEVEL_INVISIBLE = 4,
|
|
|
|
OSD_BAR_SEEK = 256,
|
2014-07-30 21:24:08 +00:00
|
|
|
|
|
|
|
MAX_NUM_VO_PTS = 100,
|
2013-10-30 20:47:14 +00:00
|
|
|
};
|
|
|
|
|
2013-08-19 20:29:55 +00:00
|
|
|
enum seek_type {
|
|
|
|
MPSEEK_NONE = 0,
|
|
|
|
MPSEEK_RELATIVE,
|
|
|
|
MPSEEK_ABSOLUTE,
|
|
|
|
MPSEEK_FACTOR,
|
2016-01-12 22:49:00 +00:00
|
|
|
MPSEEK_BACKSTEP,
|
2023-09-27 12:00:14 +00:00
|
|
|
MPSEEK_CHAPTER,
|
2013-08-19 20:29:55 +00:00
|
|
|
};
|
|
|
|
|
2015-03-04 16:21:05 +00:00
|
|
|
enum seek_precision {
|
|
|
|
// The following values are numerically sorted by increasing precision
|
2017-08-14 12:02:13 +00:00
|
|
|
MPSEEK_DEFAULT = 0,
|
2015-03-04 16:21:05 +00:00
|
|
|
MPSEEK_KEYFRAME,
|
|
|
|
MPSEEK_EXACT,
|
|
|
|
MPSEEK_VERY_EXACT,
|
|
|
|
};
|
|
|
|
|
2016-08-15 19:07:32 +00:00
|
|
|
enum seek_flags {
|
|
|
|
MPSEEK_FLAG_DELAY = 1 << 0, // give player chance to coalesce multiple seeks
|
2016-08-18 18:40:23 +00:00
|
|
|
MPSEEK_FLAG_NOFLUSH = 1 << 1, // keeping remaining data for seamless loops
|
2016-08-15 19:07:32 +00:00
|
|
|
};
|
|
|
|
|
2017-08-14 12:02:13 +00:00
|
|
|
struct seek_params {
|
|
|
|
enum seek_type type;
|
|
|
|
enum seek_precision exact;
|
|
|
|
double amount;
|
|
|
|
unsigned flags; // MPSEEK_FLAG_*
|
|
|
|
};
|
|
|
|
|
player: refactor display-sync frame duration calculations
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.
2015-11-13 21:45:40 +00:00
|
|
|
// Information about past video frames that have been sent to the VO.
|
|
|
|
struct frame_info {
|
|
|
|
double pts;
|
|
|
|
double duration; // PTS difference to next frame
|
|
|
|
double approx_duration; // possibly fixed/smoothed out duration
|
2015-11-13 21:51:39 +00:00
|
|
|
double av_diff; // A/V diff at time of scheduling
|
2015-11-13 21:48:32 +00:00
|
|
|
int num_vsyncs; // scheduled vsyncs, if using display-sync
|
player: refactor display-sync frame duration calculations
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.
2015-11-13 21:45:40 +00:00
|
|
|
};
|
|
|
|
|
2012-08-19 16:01:30 +00:00
|
|
|
struct track {
|
|
|
|
enum stream_type type;
|
2013-12-23 19:14:54 +00:00
|
|
|
|
|
|
|
// Currently used for decoding.
|
|
|
|
bool selected;
|
|
|
|
|
2012-08-19 16:01:30 +00:00
|
|
|
// The type specific ID, also called aid (audio), sid (subs), vid (video).
|
|
|
|
// For UI purposes only; this ID doesn't have anything to do with any
|
|
|
|
// IDs coming from demuxers or container files.
|
|
|
|
int user_tid;
|
|
|
|
|
2014-10-21 11:16:48 +00:00
|
|
|
int demuxer_id; // same as stream->demuxer_id. -1 if not set.
|
|
|
|
int ff_index; // same as stream->ff_index, or 0.
|
2023-02-21 21:26:25 +00:00
|
|
|
int hls_bitrate; // same as stream->hls_bitrate. 0 if not set.
|
|
|
|
int program_id; // same as stream->program_id. -1 if not set.
|
2012-08-19 16:01:30 +00:00
|
|
|
|
|
|
|
char *title;
|
2018-04-16 01:39:45 +00:00
|
|
|
bool default_track, forced_track, dependent_track;
|
2018-07-26 19:53:14 +00:00
|
|
|
bool visual_impaired_track, hearing_impaired_track;
|
2021-10-14 14:36:57 +00:00
|
|
|
bool image;
|
2012-12-10 17:52:06 +00:00
|
|
|
bool attached_picture;
|
2012-08-19 16:01:30 +00:00
|
|
|
char *lang;
|
|
|
|
|
|
|
|
// If this track is from an external file (e.g. subtitle file).
|
|
|
|
bool is_external;
|
2014-01-05 15:15:30 +00:00
|
|
|
bool no_default; // pretend it's not external for auto-selection
|
2018-01-06 16:49:37 +00:00
|
|
|
bool no_auto_select;
|
2012-11-15 19:26:52 +00:00
|
|
|
char *external_filename;
|
2013-04-20 21:48:26 +00:00
|
|
|
bool auto_loaded;
|
2012-08-19 16:01:30 +00:00
|
|
|
|
|
|
|
struct demuxer *demuxer;
|
2013-09-07 18:21:11 +00:00
|
|
|
// Invariant: !stream || stream->demuxer == demuxer
|
2012-08-19 16:01:30 +00:00
|
|
|
struct sh_stream *stream;
|
|
|
|
|
2015-12-26 17:32:27 +00:00
|
|
|
// Current subtitle state (or cached state if selected==false).
|
2016-01-17 15:56:32 +00:00
|
|
|
struct dec_sub *d_sub;
|
2015-12-26 17:32:27 +00:00
|
|
|
|
2016-01-21 21:24:20 +00:00
|
|
|
// Current decoding state (NULL if selected==false)
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
struct mp_decoder_wrapper *dec;
|
2016-01-17 17:07:50 +00:00
|
|
|
|
2016-02-05 22:19:56 +00:00
|
|
|
// Where the decoded result goes to (one of them is not NULL if active)
|
|
|
|
struct vo_chain *vo_c;
|
|
|
|
struct ao_chain *ao_c;
|
2018-01-26 03:36:47 +00:00
|
|
|
struct mp_pin *sink;
|
2012-08-19 16:01:30 +00:00
|
|
|
};
|
|
|
|
|
2016-01-13 23:18:48 +00:00
|
|
|
// Summarizes video filtering and output.
|
|
|
|
struct vo_chain {
|
|
|
|
struct mp_log *log;
|
|
|
|
|
video: rewrite filtering glue code
Get rid of the old vf.c code. Replace it with a generic filtering
framework, which can potentially handle more than just --vf. At least
reimplementing --af with this code is planned.
This changes some --vf semantics (including runtime behavior and the
"vf" command). The most important ones are listed in interface-changes.
vf_convert.c is renamed to f_swscale.c. It is now an internal filter
that can not be inserted by the user manually.
f_lavfi.c is a refactor of player/lavfi.c. The latter will be removed
once --lavfi-complex is reimplemented on top of f_lavfi.c. (which is
conceptually easy, but a big mess due to the data flow changes).
The existing filters are all changed heavily. The data flow of the new
filter framework is different. Especially EOF handling changes - EOF is
now a "frame" rather than a state, and must be passed through exactly
once.
Another major thing is that all filters must support dynamic format
changes. The filter reconfig() function goes away. (This sounds complex,
but since all filters need to handle EOF draining anyway, they can use
the same code, and it removes the mess with reconfig() having to predict
the output format, which completely breaks with libavfilter anyway.)
In addition, there is no automatic format negotiation or conversion.
libavfilter's primitive and insufficient API simply doesn't allow us to
do this in a reasonable way. Instead, filters can use f_autoconvert as
sub-filter, and tell it which formats they support. This filter will in
turn add actual conversion filters, such as f_swscale, to perform
necessary format changes.
vf_vapoursynth.c uses the same basic principle of operation as before,
but with worryingly different details in data flow. Still appears to
work.
The hardware deint filters (vf_vavpp.c, vf_d3d11vpp.c, vf_vdpaupp.c) are
heavily changed. Fortunately, they all used refqueue.c, which is for
sharing the data flow logic (especially for managing future/past
surfaces and such). It turns out it can be used to factor out most of
the data flow. Some of these filters accepted software input. Instead of
having ad-hoc upload code in each filter, surface upload is now
delegated to f_autoconvert, which can use f_hwupload to perform this.
Exporting VO capabilities is still a big mess (mp_stream_info stuff).
The D3D11 code drops the redundant image formats, and all code uses the
hw_subfmt (sw_format in FFmpeg) instead. Although that too seems to be a
big mess for now.
f_async_queue is unused.
2018-01-16 10:53:44 +00:00
|
|
|
struct mp_output_chain *filter;
|
|
|
|
|
2016-01-13 23:18:48 +00:00
|
|
|
struct vo *vo;
|
2016-01-16 20:19:52 +00:00
|
|
|
|
2016-02-05 22:19:56 +00:00
|
|
|
struct track *track;
|
2018-01-26 03:36:47 +00:00
|
|
|
struct mp_pin *filter_src;
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
struct mp_pin *dec_src;
|
2016-02-01 21:14:32 +00:00
|
|
|
|
|
|
|
// - video consists of a single picture, which should be shown only once
|
|
|
|
// - do not sync audio to video in any way
|
|
|
|
bool is_coverart;
|
2018-05-03 02:29:11 +00:00
|
|
|
// - video consists of sparse still images
|
|
|
|
bool is_sparse;
|
2023-08-10 16:31:56 +00:00
|
|
|
bool sparse_eof_signalled;
|
player: partially rework --cache-pause
The --cache-pause feature (enabled by default) will pause playback for a
while if network runs out of data. If this is not done, then playback
will go on frame-wise (as packets are slowly read from the network and
then instantly decoded and displayed). This feature is actually useless,
as you won't get nice playback no matter what if network is too slow,
but I guess I still prefer this behavior for some reason.
This commit changes this behavior from using the demuxer cache state
only, to trying to use underrun information from the AO/VO. This means
if you have a very large audio buffer, then cache-pausing will trigger
once that buffer is depleted, which will be some time _after_ the
demuxer cache has run out.
This requires explicit support from the AO. Otherwise, the behavior
should be mostly the same as before this commit.
This does not care about the AO buffer. In theory, the AO may underrun,
then the player will write some data to the AO buffer, then the AO will
recover and play this bit of data, then the player will probably trigger
the cache-pause behavior. The probability of this happening should be
pretty low, so I will hold off fixing this until the next refactor of
the AO chain (if ever).
The VO underflow detection was devised and tested in 5 minutes, and may
not be correct. At least I'm fairly sure that the combination of all the
factors should make incorrect behavior relatively unlikely, but problems
are possible.
Also, the demux_reader_state.underrun field may be inaccurate. It's only
the present state at the time demux_get_reader_state() was called, and
may exclude past underruns. In theory, this could cause "close" cases to
be missed. Then you might get an audio underrun without cache-pausing
acting on it. If the stars align, this could happen multiple times in
the row, effectively making this feature not work.
The most user-visible consequence of this change is that the user
will now see an AO underrun warning every time the cache runs out.
Maybe this cache-pause feature should just be removed...
2019-10-11 17:34:04 +00:00
|
|
|
|
|
|
|
bool underrun;
|
2019-12-16 00:15:43 +00:00
|
|
|
bool underrun_signaled;
|
2016-01-13 23:18:48 +00:00
|
|
|
};
|
|
|
|
|
2016-01-21 21:10:15 +00:00
|
|
|
// Like vo_chain, for audio.
|
|
|
|
struct ao_chain {
|
|
|
|
struct mp_log *log;
|
audio: refactor how data is passed to AO
This replaces the two buffers (ao_chain.ao_buffer in the core, and
buffer_state.buffers in the AO) with a single queue. Instead of having a
byte based buffer, the queue is simply a list of audio frames, as output
by the decoder. This should make dataflow simpler and reduce copying.
It also attempts to simplify fill_audio_out_buffers(), the function I
always hated most, because it's full of subtle and buggy logic.
Unfortunately, I got assaulted by corner cases, dumb features (attempt
at seamless looping, really?), and other crap, so it got pretty
complicated again. fill_audio_out_buffers() is still full of subtle and
buggy logic. Maybe it got worse. On the other hand, maybe there really
is some progress. Who knows.
Originally, the data flow parts was meant to be in f_output_chain, but
due to tricky interactions with the playloop code, it's now in the dummy
filter in audio.c.
At least this improves the way the audio PTS is passed to the encoder in
encoding mode. Now it attempts to pass frames directly, along with the
pts, which should minimize timestamp problems. But to be honest, encoder
mode is one big kludge that shouldn't exist in this way.
This commit should be considered pre-alpha code. There are lots of bugs
still hiding.
2020-08-28 18:23:54 +00:00
|
|
|
struct MPContext *mpctx;
|
2016-01-21 21:10:15 +00:00
|
|
|
|
|
|
|
bool spdif_passthrough, spdif_failed;
|
|
|
|
|
2018-01-18 13:44:20 +00:00
|
|
|
struct mp_output_chain *filter;
|
|
|
|
|
2016-01-21 21:10:15 +00:00
|
|
|
struct ao *ao;
|
audio: refactor how data is passed to AO
This replaces the two buffers (ao_chain.ao_buffer in the core, and
buffer_state.buffers in the AO) with a single queue. Instead of having a
byte based buffer, the queue is simply a list of audio frames, as output
by the decoder. This should make dataflow simpler and reduce copying.
It also attempts to simplify fill_audio_out_buffers(), the function I
always hated most, because it's full of subtle and buggy logic.
Unfortunately, I got assaulted by corner cases, dumb features (attempt
at seamless looping, really?), and other crap, so it got pretty
complicated again. fill_audio_out_buffers() is still full of subtle and
buggy logic. Maybe it got worse. On the other hand, maybe there really
is some progress. Who knows.
Originally, the data flow parts was meant to be in f_output_chain, but
due to tricky interactions with the playloop code, it's now in the dummy
filter in audio.c.
At least this improves the way the audio PTS is passed to the encoder in
encoding mode. Now it attempts to pass frames directly, along with the
pts, which should minimize timestamp problems. But to be honest, encoder
mode is one big kludge that shouldn't exist in this way.
This commit should be considered pre-alpha code. There are lots of bugs
still hiding.
2020-08-28 18:23:54 +00:00
|
|
|
struct mp_async_queue *ao_queue;
|
|
|
|
struct mp_filter *queue_filter;
|
|
|
|
struct mp_filter *ao_filter;
|
2016-08-09 14:26:44 +00:00
|
|
|
double ao_resume_time;
|
2016-01-21 21:10:15 +00:00
|
|
|
|
2018-01-29 05:18:33 +00:00
|
|
|
bool out_eof;
|
2018-01-18 13:44:20 +00:00
|
|
|
double last_out_pts;
|
2017-09-21 10:48:30 +00:00
|
|
|
|
audio: refactor how data is passed to AO
This replaces the two buffers (ao_chain.ao_buffer in the core, and
buffer_state.buffers in the AO) with a single queue. Instead of having a
byte based buffer, the queue is simply a list of audio frames, as output
by the decoder. This should make dataflow simpler and reduce copying.
It also attempts to simplify fill_audio_out_buffers(), the function I
always hated most, because it's full of subtle and buggy logic.
Unfortunately, I got assaulted by corner cases, dumb features (attempt
at seamless looping, really?), and other crap, so it got pretty
complicated again. fill_audio_out_buffers() is still full of subtle and
buggy logic. Maybe it got worse. On the other hand, maybe there really
is some progress. Who knows.
Originally, the data flow parts was meant to be in f_output_chain, but
due to tricky interactions with the playloop code, it's now in the dummy
filter in audio.c.
At least this improves the way the audio PTS is passed to the encoder in
encoding mode. Now it attempts to pass frames directly, along with the
pts, which should minimize timestamp problems. But to be honest, encoder
mode is one big kludge that shouldn't exist in this way.
This commit should be considered pre-alpha code. There are lots of bugs
still hiding.
2020-08-28 18:23:54 +00:00
|
|
|
double start_pts;
|
|
|
|
bool start_pts_known;
|
|
|
|
|
2016-02-05 22:19:56 +00:00
|
|
|
struct track *track;
|
2018-01-26 03:36:47 +00:00
|
|
|
struct mp_pin *filter_src;
|
2018-01-29 05:18:33 +00:00
|
|
|
struct mp_pin *dec_src;
|
player: partially rework --cache-pause
The --cache-pause feature (enabled by default) will pause playback for a
while if network runs out of data. If this is not done, then playback
will go on frame-wise (as packets are slowly read from the network and
then instantly decoded and displayed). This feature is actually useless,
as you won't get nice playback no matter what if network is too slow,
but I guess I still prefer this behavior for some reason.
This commit changes this behavior from using the demuxer cache state
only, to trying to use underrun information from the AO/VO. This means
if you have a very large audio buffer, then cache-pausing will trigger
once that buffer is depleted, which will be some time _after_ the
demuxer cache has run out.
This requires explicit support from the AO. Otherwise, the behavior
should be mostly the same as before this commit.
This does not care about the AO buffer. In theory, the AO may underrun,
then the player will write some data to the AO buffer, then the AO will
recover and play this bit of data, then the player will probably trigger
the cache-pause behavior. The probability of this happening should be
pretty low, so I will hold off fixing this until the next refactor of
the AO chain (if ever).
The VO underflow detection was devised and tested in 5 minutes, and may
not be correct. At least I'm fairly sure that the combination of all the
factors should make incorrect behavior relatively unlikely, but problems
are possible.
Also, the demux_reader_state.underrun field may be inaccurate. It's only
the present state at the time demux_get_reader_state() was called, and
may exclude past underruns. In theory, this could cause "close" cases to
be missed. Then you might get an audio underrun without cache-pausing
acting on it. If the stars align, this could happen multiple times in
the row, effectively making this feature not work.
The most user-visible consequence of this change is that the user
will now see an AO underrun warning every time the cache runs out.
Maybe this cache-pause feature should just be removed...
2019-10-11 17:34:04 +00:00
|
|
|
|
2019-11-24 23:26:36 +00:00
|
|
|
double delay;
|
audio: refactor how data is passed to AO
This replaces the two buffers (ao_chain.ao_buffer in the core, and
buffer_state.buffers in the AO) with a single queue. Instead of having a
byte based buffer, the queue is simply a list of audio frames, as output
by the decoder. This should make dataflow simpler and reduce copying.
It also attempts to simplify fill_audio_out_buffers(), the function I
always hated most, because it's full of subtle and buggy logic.
Unfortunately, I got assaulted by corner cases, dumb features (attempt
at seamless looping, really?), and other crap, so it got pretty
complicated again. fill_audio_out_buffers() is still full of subtle and
buggy logic. Maybe it got worse. On the other hand, maybe there really
is some progress. Who knows.
Originally, the data flow parts was meant to be in f_output_chain, but
due to tricky interactions with the playloop code, it's now in the dummy
filter in audio.c.
At least this improves the way the audio PTS is passed to the encoder in
encoding mode. Now it attempts to pass frames directly, along with the
pts, which should minimize timestamp problems. But to be honest, encoder
mode is one big kludge that shouldn't exist in this way.
This commit should be considered pre-alpha code. There are lots of bugs
still hiding.
2020-08-28 18:23:54 +00:00
|
|
|
bool untimed_throttle;
|
2019-11-24 23:26:36 +00:00
|
|
|
|
audio: refactor how data is passed to AO
This replaces the two buffers (ao_chain.ao_buffer in the core, and
buffer_state.buffers in the AO) with a single queue. Instead of having a
byte based buffer, the queue is simply a list of audio frames, as output
by the decoder. This should make dataflow simpler and reduce copying.
It also attempts to simplify fill_audio_out_buffers(), the function I
always hated most, because it's full of subtle and buggy logic.
Unfortunately, I got assaulted by corner cases, dumb features (attempt
at seamless looping, really?), and other crap, so it got pretty
complicated again. fill_audio_out_buffers() is still full of subtle and
buggy logic. Maybe it got worse. On the other hand, maybe there really
is some progress. Who knows.
Originally, the data flow parts was meant to be in f_output_chain, but
due to tricky interactions with the playloop code, it's now in the dummy
filter in audio.c.
At least this improves the way the audio PTS is passed to the encoder in
encoding mode. Now it attempts to pass frames directly, along with the
pts, which should minimize timestamp problems. But to be honest, encoder
mode is one big kludge that shouldn't exist in this way.
This commit should be considered pre-alpha code. There are lots of bugs
still hiding.
2020-08-28 18:23:54 +00:00
|
|
|
bool ao_underrun; // last known AO state
|
|
|
|
bool underrun; // for cache pause logic
|
2016-01-21 21:10:15 +00:00
|
|
|
};
|
|
|
|
|
2014-07-28 18:40:43 +00:00
|
|
|
/* Note that playback can be paused, stopped, etc. at any time. While paused,
|
|
|
|
* playback restart is still active, because you want seeking to work even
|
|
|
|
* if paused.
|
|
|
|
* The main purpose of distinguishing these states is proper reinitialization
|
|
|
|
* of A/V sync.
|
|
|
|
*/
|
|
|
|
enum playback_status {
|
|
|
|
// code may compare status values numerically
|
|
|
|
STATUS_SYNCING, // seeking for a position to resume
|
|
|
|
STATUS_READY, // buffers full, playback can be started any time
|
|
|
|
STATUS_PLAYING, // normal playback
|
|
|
|
STATUS_DRAINING, // decoding has ended; still playing out queued buffers
|
|
|
|
STATUS_EOF, // playback has ended, or is disabled
|
|
|
|
};
|
|
|
|
|
player: dumb seeking related stuff, make audio hr-seek default
Try to deal with various corner cases. But when I fix one thing, another
thing breaks. (And it's 50/50 whether I find the breakage immediately or
a few months later.) So results may vary.
The default for--hr-seek is changed to "default" (not creative enough to
find a better name). In this mode, audio seeking is exact if there is no
video, or if the video has only a single frame. This change is actually
pretty dumb, since audio frames are usually small enough that exact
seeking does not really add much. But it gets rid of some weird special
cases.
Internally, the most important change is that is_coverart and is_sparse
handling is merged. is_sparse was originally just a special case for
weird .ts streams that have the corresponding low-level flag set. The
idea is that they're pretty similar anyway, so this would reduce the
number of corner cases. But I'm not sure if this doesn't break the
original intended use case for it (I don't have a sample anyway).
This changes last-frame handling, and respects the duration of the last
frame only if audio is disabled. This is mostly "coincidental" due to
the need to make seeking past EOF trigger player exit, and is caused by
setting STATUS_EOF early. On the other hand, this might have been this
way before (see removed chunk close to it).
2020-02-28 16:15:07 +00:00
|
|
|
const char *mp_status_str(enum playback_status st);
|
|
|
|
|
2020-04-15 15:03:37 +00:00
|
|
|
extern const int num_ptracks[STREAM_TYPE_COUNT];
|
|
|
|
|
|
|
|
// Maximum of all num_ptracks[] values.
|
|
|
|
#define MAX_PTRACKS 2
|
2013-12-24 16:46:08 +00:00
|
|
|
|
2007-02-21 00:49:24 +00:00
|
|
|
typedef struct MPContext {
|
2014-02-10 20:01:35 +00:00
|
|
|
bool initialized;
|
2018-03-09 03:46:09 +00:00
|
|
|
bool is_cli;
|
2013-07-31 19:40:30 +00:00
|
|
|
struct mpv_global *global;
|
2013-07-27 19:24:54 +00:00
|
|
|
struct MPOpts *opts;
|
2013-07-31 19:40:30 +00:00
|
|
|
struct mp_log *log;
|
2020-04-09 22:55:39 +00:00
|
|
|
struct stats_ctx *stats;
|
2008-04-26 07:44:59 +00:00
|
|
|
struct m_config *mconfig;
|
2008-04-30 04:15:52 +00:00
|
|
|
struct input_ctx *input;
|
2014-02-10 20:01:35 +00:00
|
|
|
struct mp_client_api *clients;
|
|
|
|
struct mp_dispatch_queue *dispatch;
|
stream: redo playback abort handling
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.
2014-09-13 12:23:08 +00:00
|
|
|
struct mp_cancel *playback_abort;
|
player: make screenshot commands honor the async flag
And also change input.conf to make all screenshots async. (Except the
every-frame mode, which always uses synchronous mode and ignores the
flag.) By default, the "screenshot" command is still asynchronous,
because scripts etc. might depend on this behavior.
This is only partially async. The code for determining the filename is
still always run synchronously. Only encoding the screenshot and writing
it to disk is asynchronous. We explicitly document the exact behavior as
undefined, so it can be changed any time.
Some of this is a bit messy, because I wanted to avoid duplicating the
message display code between sync and async mode. In async mode, this is
called from a worker thread, which is not safe because showing a message
accesses the thread-unsafe OSD code. So the core has to be locked during
this, which implies accessing the core and all that. So the code has
weird locking calls, and we need to do core destruction in a more
"controlled" manner (thus the outstanding_async field).
(What I'd really want would be the OSD simply showing log messages
instead.)
This is pretty untested, so expect bugs.
Fixes #4250.
2017-04-01 18:45:20 +00:00
|
|
|
// Number of asynchronous tasks that still need to finish until MPContext
|
|
|
|
// destruction is ok. It's implied that the async tasks call
|
|
|
|
// mp_wakeup_core() each time this is decremented.
|
|
|
|
// As using an atomic+wakeup would be racy, this is a normal integer, and
|
|
|
|
// mp_dispatch_lock must be called to change it.
|
|
|
|
int64_t outstanding_async;
|
2014-02-10 20:01:35 +00:00
|
|
|
|
2018-05-06 16:27:18 +00:00
|
|
|
struct mp_thread_pool *thread_pool; // for coarse I/O, often during loading
|
|
|
|
|
2014-02-10 20:01:35 +00:00
|
|
|
struct mp_log *statusline;
|
2008-06-23 22:53:58 +00:00
|
|
|
struct osd_state *osd;
|
player: redo terminal OSD and status line handling
The terminal OSD code includes the handling of the terminal status line,
showing player OSD messages on the terminal, and showing subtitles on
terminal (the latter two only if there is no video window, or if
terminal OSD is forced).
This didn't handle some corner cases correctly. For example, showing an
OSD message on the terminal always cleared the previous line, even if
the line was an important message (or even just the command prompt, if
most other messages were silenced).
Attempt to handle this correctly by keeping track of how many lines the
terminal OSD currently consists of. Since there could be race conditions
with other messages being printed, implement this in msg.c. Now msg.c
expects that MSGL_STATUS messages rewrite the status line, so the caller
is forced to use a single mp_msg() call to set the status line.
Instead of littering print_status() all over the place, update the
status only once per playloop iteration in update_osd_msg(). In audio-
only mode, the status line might now be a little bit off, but it's
perhaps ok.
Print the status line only if it has changed, or if another message was
printed. This might help with extremely slow terminals, although in
audio+video mode, it'll still be updated very often (A-V sync display
changes on every frame).
Instead of hardcoding the terminal sequences, use
terminfo/termcap to get the sequences. Remove the --term-osd-esc option,
which allowed to override the hardcoded escapes - it's useless now.
The fallback for terminals with no escape sequences for moving the
cursor and clearing a line is removed. This somewhat breaks status line
display on these terminals, including the MS Windows console: instead of
querying the terminal size and clearing the line manually by padding the
output with spaces, the line is simply not cleared. I don't expect this
to be a problem on UNIX, and on MS Windows we could emulate escape
sequences. Note that terminal OSD (other than the status line) was
broken anyway on these terminals.
In osd.c, the function get_term_width() is not used anymore, so remove
it. To remind us that the MS Windows console apparently adds a line
break when writint the last column, adjust screen_width in terminal-
win.c accordingly.
2014-01-13 19:05:41 +00:00
|
|
|
char *term_osd_text;
|
|
|
|
char *term_osd_status;
|
2014-01-17 20:55:23 +00:00
|
|
|
char *term_osd_subs;
|
player: redo terminal OSD and status line handling
The terminal OSD code includes the handling of the terminal status line,
showing player OSD messages on the terminal, and showing subtitles on
terminal (the latter two only if there is no video window, or if
terminal OSD is forced).
This didn't handle some corner cases correctly. For example, showing an
OSD message on the terminal always cleared the previous line, even if
the line was an important message (or even just the command prompt, if
most other messages were silenced).
Attempt to handle this correctly by keeping track of how many lines the
terminal OSD currently consists of. Since there could be race conditions
with other messages being printed, implement this in msg.c. Now msg.c
expects that MSGL_STATUS messages rewrite the status line, so the caller
is forced to use a single mp_msg() call to set the status line.
Instead of littering print_status() all over the place, update the
status only once per playloop iteration in update_osd_msg(). In audio-
only mode, the status line might now be a little bit off, but it's
perhaps ok.
Print the status line only if it has changed, or if another message was
printed. This might help with extremely slow terminals, although in
audio+video mode, it'll still be updated very often (A-V sync display
changes on every frame).
Instead of hardcoding the terminal sequences, use
terminfo/termcap to get the sequences. Remove the --term-osd-esc option,
which allowed to override the hardcoded escapes - it's useless now.
The fallback for terminals with no escape sequences for moving the
cursor and clearing a line is removed. This somewhat breaks status line
display on these terminals, including the MS Windows console: instead of
querying the terminal size and clearing the line manually by padding the
output with spaces, the line is simply not cleared. I don't expect this
to be a problem on UNIX, and on MS Windows we could emulate escape
sequences. Note that terminal OSD (other than the status line) was
broken anyway on these terminals.
In osd.c, the function get_term_width() is not used anymore, so remove
it. To remind us that the MS Windows console apparently adds a line
break when writint the last column, adjust screen_width in terminal-
win.c accordingly.
2014-01-13 19:05:41 +00:00
|
|
|
char *term_osd_contents;
|
2020-05-25 18:37:37 +00:00
|
|
|
char *term_osd_title;
|
2013-11-09 23:49:13 +00:00
|
|
|
char *last_window_title;
|
2015-11-15 22:03:48 +00:00
|
|
|
struct voctrl_playback_state vo_playback_state;
|
2009-03-30 00:13:17 +00:00
|
|
|
|
2012-09-25 01:24:38 +00:00
|
|
|
int add_osd_seek_info; // bitfield of enum mp_osd_seek_info
|
2013-05-25 16:31:06 +00:00
|
|
|
double osd_visible; // for the osd bar only
|
2007-02-21 00:49:24 +00:00
|
|
|
int osd_function;
|
2013-05-25 16:31:06 +00:00
|
|
|
double osd_function_visible;
|
2014-09-25 19:14:00 +00:00
|
|
|
double osd_msg_visible;
|
2014-10-06 20:19:24 +00:00
|
|
|
double osd_msg_next_duration;
|
2013-05-25 16:31:06 +00:00
|
|
|
double osd_last_update;
|
player: do not update OSD all the time when paused
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.
2016-06-11 16:40:08 +00:00
|
|
|
bool osd_force_update, osd_idle_update;
|
2014-09-25 19:14:00 +00:00
|
|
|
char *osd_msg_text;
|
|
|
|
bool osd_show_pos;
|
2014-01-18 00:19:20 +00:00
|
|
|
struct osd_progbar_state osd_progbar;
|
2012-11-20 16:20:45 +00:00
|
|
|
|
mplayer: turn playtree into a list, and change per-file option handling
Summary:
- There is no playtree anymore. It's reduced to a simple list.
- Options are now always global. You can still have per-file options,
but these are optional and require special syntax.
- The slave command pt_step has been removed, and playlist_next
and playlist_prev added. (See etc/input.conf changes.)
This is a user visible incompatible change, and will break slave-mode
applications.
- The pt_clear slave command is renamed to playlist_clear.
- Playtree entries could have multiple files. This is not the case
anymore, and playlist entries have always exactly one entry. Whenever
something adds more than one file (like ASX playlists or dvd:// or
dvdnav:// on the command line), all files are added as separate
playlist entries.
Note that some of the changes are quite deep and violent. Expect
regressions.
The playlist parsing code in particular is of low quality. I didn't try
to improve it, and merely spent to least effort necessary to keep it
somehow working. (Especially ASX playlist handling.)
The playtree code was complicated and bloated. It was also barely used.
Most users don't even know that mplayer manages the playlist as tree,
or how to use it. The most obscure features was probably specifying a
tree on command line (with '{' and '}' to create/close tree nodes). It
filled the player code with complexity and confused users with weird
slave commands like pt_up.
Replace the playtree with a simple flat playlist. Playlist parsers that
actually return trees are changed to append all files to the playlist
pre-order.
It used to be the responsibility of the playtree code to change per-file
config options. Now this is done by the player core, and the playlist
code is free of such details.
Options are not per-file by default anymore. This was a very obscure and
complicated feature that confused even experienced users. Consider the
following command line:
mplayer file1.mkv file2.mkv --no-audio file3.mkv
This will disable the audio for file2.mkv only, because options are
per-file by default. To make the option affect all files, you're
supposed to put it before the first file.
This is bad, because normally you don't need per-file options. They are
very rarely needed, and the only reasonable use cases I can imagine are
use of the encode backend (mplayer encode branch), or for debugging. The
normal use case is made harder, and the feature is perceived as bug.
Even worse, correct usage is hard to explain for users.
Make all options global by default. The position of an option isn't
significant anymore (except for options that compensate each other,
consider --shuffle --no-shuffle).
One other important change is that no options are reset anymore if a
new file is started. If you change settings with slave mode commands,
they will not be changed by playing a new file. (Exceptions include
settings that are too file specific, like audio/subtitle stream
selection.)
There is still some need for per-file options. Debugging and encoding
are use cases that profit from per-file options. Per-file profiles (as
well as per-protocol and per-VO/AO options) need the implementation
related mechanisms to backup and restore options when the playback file
changes.
Simplify the save-slot stuff, which is possible because there is no
hierarchical play tree anymore. Now there's a simple backup field.
Add a way to specify per-file options on command line. Example:
mplayer f1.mkv -o0 --{ -o1 f2.mkv -o2 f3.mkv --} f4.mkv -o3
will have the following options per file set:
f1.mkv, f4.mkv: -o0 -o3
f2.mkv, f3.mkv: -o0 -o3 -o1 -o2
The options --{ and --} start and end per-file options. All files inside
the { } will be affected by the options equally (similar to how global
options and multiple files are handled). When playback of a file starts,
the per-file options are set according to the command line. When
playback ends, the per-file options are restored to the values when
playback started.
2012-07-31 19:33:26 +00:00
|
|
|
struct playlist *playlist;
|
2014-09-08 22:38:38 +00:00
|
|
|
struct playlist_entry *playing; // currently playing file
|
2014-10-06 19:20:38 +00:00
|
|
|
char *filename; // immutable copy of playing->filename (or NULL)
|
command: add a mechanism to allow scripts to intercept file loads
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)
2014-10-15 21:09:53 +00:00
|
|
|
char *stream_open_filename;
|
2023-08-14 19:13:02 +00:00
|
|
|
char **playlist_paths; // used strictly for playlist validation
|
|
|
|
int playlist_paths_len;
|
2008-08-13 05:06:26 +00:00
|
|
|
enum stop_play_reason stop_play;
|
2014-10-03 17:57:49 +00:00
|
|
|
bool playback_initialized; // playloop can be run/is running
|
2014-10-30 22:54:06 +00:00
|
|
|
int error_playing;
|
2007-02-21 00:49:24 +00:00
|
|
|
|
2012-08-04 01:46:11 +00:00
|
|
|
// Return code to use with PT_QUIT
|
2013-08-02 08:32:38 +00:00
|
|
|
int quit_custom_rc;
|
|
|
|
bool has_quit_custom_rc;
|
2012-08-04 01:46:11 +00:00
|
|
|
|
2014-10-30 22:54:06 +00:00
|
|
|
// Global file statistics
|
|
|
|
int files_played; // played without issues (even if stopped by user)
|
|
|
|
int files_errored; // played, but errors happened at one point
|
|
|
|
int files_broken; // couldn't be played at all
|
|
|
|
|
|
|
|
// Current file statistics
|
2013-09-29 19:10:36 +00:00
|
|
|
int64_t shown_vframes, shown_aframes;
|
|
|
|
|
2014-11-02 16:20:04 +00:00
|
|
|
struct demux_chapter *chapters;
|
2009-04-02 02:00:22 +00:00
|
|
|
int num_chapters;
|
2009-03-29 19:45:06 +00:00
|
|
|
|
2016-02-15 20:03:51 +00:00
|
|
|
struct demuxer *demuxer;
|
2014-12-29 21:51:18 +00:00
|
|
|
struct mp_tags *filtered_tags;
|
2012-08-19 16:01:30 +00:00
|
|
|
|
|
|
|
struct track **tracks;
|
|
|
|
int num_tracks;
|
|
|
|
|
Add initial Lua scripting support
This is preliminary. There are still tons of issues, and any aspect
of scripting may change in the future. I decided to merge this
(preliminary) work now because it makes it easier to develop it, not
because it's done. lua.rst is clear enough about it (plus some
sarcasm).
This requires linking to Lua. Lua has no official pkg-config file, but
there are distribution specific .pc files, all with different names.
Adding a non-pkg-config based configure test was considered, but we'd
rather not.
One major complication is that libquvi links against Lua too, and if
the Lua version is different from mpv's, you will get a crash as soon
as libquvi uses Lua. (libquvi by design always runs when a file is
opened.) I would consider this the problem of distros and whoever
builds mpv, but to make things easier for users, we add a terrible
runtime test to the configure script, which probes whether libquvi
will crash. This is disabled when cross-compiling, but in that case
we hope the user knows what he is doing.
2013-09-25 22:41:14 +00:00
|
|
|
char *track_layout_hash;
|
|
|
|
|
2012-08-19 16:01:30 +00:00
|
|
|
// Selected tracks. NULL if no track selected.
|
2020-04-15 15:03:37 +00:00
|
|
|
// There can be num_ptracks[type] of the same STREAM_TYPE selected at once.
|
2013-12-24 16:46:08 +00:00
|
|
|
// Currently, this is used for the secondary subtitle track only.
|
2020-04-15 15:03:37 +00:00
|
|
|
struct track *current_track[MAX_PTRACKS][STREAM_TYPE_COUNT];
|
2012-08-19 16:01:30 +00:00
|
|
|
|
video: rewrite filtering glue code
Get rid of the old vf.c code. Replace it with a generic filtering
framework, which can potentially handle more than just --vf. At least
reimplementing --af with this code is planned.
This changes some --vf semantics (including runtime behavior and the
"vf" command). The most important ones are listed in interface-changes.
vf_convert.c is renamed to f_swscale.c. It is now an internal filter
that can not be inserted by the user manually.
f_lavfi.c is a refactor of player/lavfi.c. The latter will be removed
once --lavfi-complex is reimplemented on top of f_lavfi.c. (which is
conceptually easy, but a big mess due to the data flow changes).
The existing filters are all changed heavily. The data flow of the new
filter framework is different. Especially EOF handling changes - EOF is
now a "frame" rather than a state, and must be passed through exactly
once.
Another major thing is that all filters must support dynamic format
changes. The filter reconfig() function goes away. (This sounds complex,
but since all filters need to handle EOF draining anyway, they can use
the same code, and it removes the mess with reconfig() having to predict
the output format, which completely breaks with libavfilter anyway.)
In addition, there is no automatic format negotiation or conversion.
libavfilter's primitive and insufficient API simply doesn't allow us to
do this in a reasonable way. Instead, filters can use f_autoconvert as
sub-filter, and tell it which formats they support. This filter will in
turn add actual conversion filters, such as f_swscale, to perform
necessary format changes.
vf_vapoursynth.c uses the same basic principle of operation as before,
but with worryingly different details in data flow. Still appears to
work.
The hardware deint filters (vf_vavpp.c, vf_d3d11vpp.c, vf_vdpaupp.c) are
heavily changed. Fortunately, they all used refqueue.c, which is for
sharing the data flow logic (especially for managing future/past
surfaces and such). It turns out it can be used to factor out most of
the data flow. Some of these filters accepted software input. Instead of
having ad-hoc upload code in each filter, surface upload is now
delegated to f_autoconvert, which can use f_hwupload to perform this.
Exporting VO capabilities is still a big mess (mp_stream_info stuff).
The D3D11 code drops the redundant image formats, and all code uses the
hw_subfmt (sw_format in FFmpeg) instead. Although that too seems to be a
big mess for now.
f_async_queue is unused.
2018-01-16 10:53:44 +00:00
|
|
|
struct mp_filter *filter_root;
|
|
|
|
|
2018-01-26 03:36:47 +00:00
|
|
|
struct mp_filter *lavfi;
|
|
|
|
char *lavfi_graph;
|
|
|
|
|
2011-04-09 00:03:22 +00:00
|
|
|
struct ao *ao;
|
2018-01-18 13:44:20 +00:00
|
|
|
struct mp_aframe *ao_filter_fmt; // for weak gapless audio check
|
2016-01-21 21:10:15 +00:00
|
|
|
struct ao_chain *ao_chain;
|
2014-03-07 14:24:32 +00:00
|
|
|
|
2016-01-13 23:18:48 +00:00
|
|
|
struct vo_chain *vo_chain;
|
|
|
|
|
2008-04-03 03:25:41 +00:00
|
|
|
struct vo *video_out;
|
video: fix and simplify video format changes and last frame display
The previous commit broke these things, and fixing them is separate in
this commit in order to reduce the volume of changes.
Move the image queue from the VO to the playback core. The image queue
is a remnant of the old way how vdpau was implemented, and increasingly
became more and more an artifact. In the end, it did only one thing:
computing the duration of the current frame. This was done by taking the
PTS difference between the current and the future frame. We keep this,
but by moving it out of the VO, we don't have to special-case format
changes anymore. This simplifies the code a lot.
Since we need the queue to compute the duration only, a queue size
larger than 2 makes no sense, and we can hardcode that.
Also change how the last frame is handled. The last frame is a bit of a
problem, because video timing works by showing one frame after another,
which makes it a special case. Make the VO provide a function to notify
us when the frame is done, instead. The frame duration is used for that.
This is not perfect. For example, changing playback speed during the
last frame doesn't update the end time. Pausing will not stop the clock
that times the last frame. But I don't think this matters for such a
corner case.
2014-08-12 21:17:35 +00:00
|
|
|
// next_frame[0] is the next frame, next_frame[1] the one after that.
|
2016-01-12 22:49:00 +00:00
|
|
|
// The +1 is for adding 1 additional frame in backstep mode.
|
|
|
|
struct mp_image *next_frames[VO_MAX_REQ_FRAMES + 1];
|
2015-07-01 17:22:40 +00:00
|
|
|
int num_next_frames;
|
2016-01-12 22:49:00 +00:00
|
|
|
struct mp_image *saved_frame; // for hrseek_lastframe and hrseek_backstep
|
2007-02-21 00:49:24 +00:00
|
|
|
|
2014-07-28 18:40:43 +00:00
|
|
|
enum playback_status video_status, audio_status;
|
|
|
|
bool restart_complete;
|
Implement backwards playback
See manpage additions. This is a huge hack. You can bet there are shit
tons of bugs. It's literally forcing square pegs into round holes.
Hopefully, the manpage wall of text makes it clear enough that the whole
shit can easily crash and burn. (Although it shouldn't literally crash.
That would be a bug. It possibly _could_ start a fire by entering some
sort of endless loop, not a literal one, just something where it tries
to do work without making progress.)
(Some obvious bugs I simply ignored for this initial version, but
there's a number of potential bugs I can't even imagine. Normal playback
should remain completely unaffected, though.)
How this works is also described in the manpage. Basically, we demux in
reverse, then we decode in reverse, then we render in reverse.
The decoding part is the simplest: just reorder the decoder output. This
weirdly integrates with the timeline/ordered chapter code, which also
has special requirements on feeding the packets to the decoder in a
non-straightforward way (it doesn't conflict, although a bugmessmass
breaks correct slicing of segments, so EDL/ordered chapter playback is
broken in backward direction).
Backward demuxing is pretty involved. In theory, it could be much
easier: simply iterating the usual demuxer output backward. But this
just doesn't fit into our code, so there's a cthulhu nightmare of shit.
To be specific, each stream (audio, video) is reversed separately. At
least this means we can do backward playback within cached content (for
example, you could play backwards in a live stream; on that note, it
disables prefetching, which would lead to losing new live video, but
this could be avoided).
The fuckmess also meant that I didn't bother trying to support
subtitles. Subtitles are a problem because they're "sparse" streams.
They need to be "passively" demuxed: you don't try to read a subtitle
packet, you demux audio and video, and then look whether there was a
subtitle packet. This means to get subtitles for a time range, you need
to know that you demuxed video and audio over this range, which becomes
pretty messy when you demux audio and video backwards separately.
Backward display is the most weird (and potentially buggy) part. To
avoid that we need to touch a LOT of timing code, we negate all
timestamps. The basic idea is that due to the navigation, all
comparisons and subtractions of timestamps keep working, and you don't
need to touch every single of them to "reverse" them.
E.g.:
bool before = pts_a < pts_b;
would need to be:
bool before = forward
? pts_a < pts_b
: pts_a > pts_b;
or:
bool before = pts_a * dir < pts_b * dir;
or if you, as it's implemented now, just do this after decoding:
pts_a *= dir;
pts_b *= dir;
and then in the normal timing/renderer code:
bool before = pts_a < pts_b;
Consequently, we don't need many changes in the latter code. But some
assumptions inhererently true for forward playback may have been broken
anyway. What is mainly needed is fixing places where values are passed
between positive and negative "domains". For example, seeking and
timestamp user display always uses positive timestamps. The main mess is
that it's not obvious which domain a given variable should or does use.
Well, in my tests with a single file, it suddenly started to work when I
did this. I'm honestly surprised that it did, and that I didn't have to
change a single line in the timing code past decoder (just something
minor to make external/cached text subtitles display). I committed it
immediately while avoiding thinking about it. But there really likely
are subtle problems of all sorts.
As far as I'm aware, gstreamer also supports backward playback. When I
looked at this years ago, I couldn't find a way to actually try this,
and I didn't revisit it now. Back then I also read talk slides from the
person who implemented it, and I'm not sure if and which ideas I might
have taken from it. It's possible that the timestamp reversal is
inspired by it, but I didn't check. (I think it claimed that it could
avoid large changes by changing a sign?)
VapourSynth has some sort of reverse function, which provides a backward
view on a video. The function itself is trivial to implement, as
VapourSynth aims to provide random access to video by frame numbers (so
you just request decreasing frame numbers). From what I remember, it
wasn't exactly fluid, but it worked. It's implemented by creating an
index, and seeking to the target on demand, and a bunch of caching. mpv
could use it, but it would either require using VapourSynth as demuxer
and decoder for everything, or replacing the current file every time
something is supposed to be played backwards.
FFmpeg's libavfilter has reversal filters for audio and video. These
require buffering the entire media data of the file, and don't really
fit into mpv's architecture. It could be used by playing a libavfilter
graph that also demuxes, but that's like VapourSynth but worse.
2019-05-18 00:10:51 +00:00
|
|
|
int play_dir;
|
2015-08-10 16:40:16 +00:00
|
|
|
// Factors to multiply with opts->playback_speed to get the total audio or
|
|
|
|
// video speed (usually 1.0, but can be set to by the sync code).
|
|
|
|
double speed_factor_v, speed_factor_a;
|
|
|
|
// Redundant values set from opts->playback_speed and speed_factor_*.
|
|
|
|
// update_playback_speed() updates them from the other fields.
|
|
|
|
double audio_speed, video_speed;
|
2015-08-10 16:43:25 +00:00
|
|
|
bool display_sync_active;
|
|
|
|
int display_sync_drift_dir;
|
|
|
|
// Timing error (in seconds) due to rounding on vsync boundaries
|
|
|
|
double display_sync_error;
|
2015-10-30 13:05:41 +00:00
|
|
|
// Number of mistimed frames.
|
|
|
|
int mistimed_frames_total;
|
2014-12-07 01:47:09 +00:00
|
|
|
bool hrseek_active; // skip all data until hrseek_pts
|
|
|
|
bool hrseek_lastframe; // drop everything until last frame reached
|
2016-01-12 22:49:00 +00:00
|
|
|
bool hrseek_backstep; // go to frame before seek target
|
2010-12-14 23:09:47 +00:00
|
|
|
double hrseek_pts;
|
2017-08-14 12:02:13 +00:00
|
|
|
struct seek_params current_seek;
|
2016-08-18 18:40:23 +00:00
|
|
|
bool ab_loop_clip; // clip to the "b" part of an A-B loop if available
|
2007-03-11 06:16:14 +00:00
|
|
|
// AV sync: the next frame should be shown when the audio out has this
|
|
|
|
// much (in seconds) buffered data left. Increased when more data is
|
2014-08-25 19:28:56 +00:00
|
|
|
// written to the ao, decreased when moving to the next video frame.
|
2007-03-11 06:16:14 +00:00
|
|
|
double delay;
|
2014-08-25 19:28:56 +00:00
|
|
|
// AV sync: time in seconds until next frame should be shown
|
2013-05-25 16:31:06 +00:00
|
|
|
double time_frame;
|
2008-12-08 18:04:08 +00:00
|
|
|
// How much video timing has been changed to make it match the audio
|
|
|
|
// timeline. Used for status line information only.
|
|
|
|
double total_avsync_change;
|
|
|
|
// A-V sync difference when last frame was displayed. Kept to display
|
|
|
|
// the same value if the status line is updated at a time where no new
|
|
|
|
// video frame is shown.
|
|
|
|
double last_av_difference;
|
2010-12-14 20:31:39 +00:00
|
|
|
/* timestamp of video frame currently visible on screen
|
|
|
|
* (or at least queued to be flipped by VO) */
|
|
|
|
double video_pts;
|
player: set playback_pts in hr-seek past EOF case
Hr-seek past the last frame instantly enters EOF, which means
handle_playback_time() will not set playback_pts to the video PTS (as
all video frames are skipped), which leads to the playback time being
taken from the last seek target. This results in confusing behavior,
especially since the seek time will be clipped to the file duration for
display, but not for further relative seeks.
Obviously, the time should be set to the last video frame, so use the
last video frame as fallback if both audio and video have ended. Also,
since the same problem exists with audio-only playback, add a fallback
for audio PTS too. We don't know which was the "last" fragment of media
played (to decide whether to use the audio or video PTS as the
fallback), but it doesn't matter since the maximum works.
This could lead to some undesired effects. In particular the audio PTS
is basically a bad guess, and is for example not clipped against --end.
(But the ridiculous way audio syncing and clamping currently works, I'm
not going to touch that shit unless I rewrite it completely.) The cover
art case is slightly broken: using --keep-open with keyframe seeks will
result in 0 as playback PTS (the video PTS). OK, who cares, it got late.
Also casually get rid of last_vo_pts, since that barely made any sense
at all.
Fixes: #7487
2020-02-28 00:37:41 +00:00
|
|
|
// Last seek target.
|
2011-07-30 22:05:17 +00:00
|
|
|
double last_seek_pts;
|
2016-12-21 17:18:24 +00:00
|
|
|
// Frame duration field from demuxer. Only used for duration of the last
|
|
|
|
// video frame.
|
|
|
|
double last_frame_duration;
|
2013-04-03 23:18:19 +00:00
|
|
|
// Video PTS, or audio PTS if video has ended.
|
|
|
|
double playback_pts;
|
2020-09-03 10:18:42 +00:00
|
|
|
// For logging only.
|
|
|
|
double logged_async_diff;
|
2007-03-11 06:16:14 +00:00
|
|
|
|
2014-04-27 20:28:07 +00:00
|
|
|
int last_chapter;
|
|
|
|
|
2016-01-12 22:49:00 +00:00
|
|
|
// Past timestamps etc.
|
player: refactor display-sync frame duration calculations
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.
2015-11-13 21:45:40 +00:00
|
|
|
// The newest frame is at index 0.
|
|
|
|
struct frame_info *past_frames;
|
|
|
|
int num_past_frames;
|
core: add backstep support
Allows stepping back one frame via the frame_back_step inout command,
bound to "," by default.
This uses the precise seeking facility, and a perfect frame index built
on the fly. The index is built during playback and precise seeking, and
contains (as of this commit) the last 100 displayed or skipped frames.
This index is used to find the PTS of the previous frame, which is then
used as target for a precise seek. If no PTS is found, the core attempts
to do a seek before the current frame, and skip decoded frames until the
current frame is reached; this will create a sufficient index and the
normal backstep algorithm can be applied.
This can be rather slow. The worst case for backstepping is about the
same as the worst case for precise seeking if the previous frame can be
deduced from the index. If not, the worst case will be twice as slow.
There's also some minor danger that the index is incorrect in case
framedropping is involved. For framedropping due to --framedrop, this
problem is ignored (use of --framedrop is discouraged anyway). For
framedropping during precise seeking (done to make it faster), we try
to not add frames to the index that are produced when this can happen.
I'm not sure how well that works (or if the logic is sane), and it's
sure to break with some video filters. In the worst case, backstepping
might silently skip frames if you backstep after a user-initiated
precise seek. (Precise seeks to do indexing are not affected.)
Likewise, video filters that somehow change timing of frames and do not
do this in a deterministic way (i.e. if you seek to a position, frames
with different timings are produced than when the position is reached
during normal playback) will make backstepping silently jump to the
wrong frame. Enabling/disabling filters during playback (like for
example deinterlacing) will have similar bad effects.
2013-04-24 17:31:48 +00:00
|
|
|
|
2014-03-01 20:27:37 +00:00
|
|
|
double last_idle_tick;
|
2014-07-31 02:19:41 +00:00
|
|
|
double next_cache_update;
|
2013-05-16 21:17:46 +00:00
|
|
|
|
2014-07-18 13:04:46 +00:00
|
|
|
double sleeptime; // number of seconds to sleep before next iteration
|
|
|
|
|
2013-05-25 16:31:06 +00:00
|
|
|
double mouse_timer;
|
|
|
|
unsigned int mouse_event_ts;
|
2013-09-08 00:46:19 +00:00
|
|
|
bool mouse_cursor_visible;
|
2013-05-16 21:17:46 +00:00
|
|
|
|
2010-12-14 23:02:14 +00:00
|
|
|
// used to prevent hanging in some error cases
|
2013-05-25 16:31:06 +00:00
|
|
|
double start_timestamp;
|
2007-03-11 06:16:14 +00:00
|
|
|
|
2008-04-28 09:09:31 +00:00
|
|
|
// Timestamp from the last time some timing functions read the
|
2023-09-18 01:05:16 +00:00
|
|
|
// current time, in nanoseconds.
|
video: display last frame, drain frames on video reconfig
Until now, the player didn't care to drain frames on video reconfig.
Instead, the VO was reconfigured (i.e. resized) before the queued frames
finished displaying. This can for example be observed by passing
multiple images with different size as mf:// filename. Then the window
would resize one frame before image with the new size is displayed. With
--vo=vdpau, the effect is worse, because this VO queues more than 1
frame internally.
Fix this by explicitly draining buffered frames before video reconfig.
Raise the display time of the last frame. Otherwise, the last frame
would be shown for a very short time only. This usually doesn't matter,
but helps when playing image files. This is a byproduct of frame
draining, because normally, video timing is based on the frames queued
to the VO, and we can't do that with frames of different size or format.
So we pretend that the frame before the change is the last frame in
order to time it. This code is incorrect though: it tries to use the
framerate, which often doesn't make sense. But it's good enough to test
this code with mf://.
2013-12-10 18:33:11 +00:00
|
|
|
// Used to turn a new time value to a delta from last time.
|
2013-05-25 16:31:06 +00:00
|
|
|
int64_t last_time;
|
2008-04-28 09:09:31 +00:00
|
|
|
|
2017-08-14 12:02:13 +00:00
|
|
|
struct seek_params seek;
|
2008-04-21 03:17:22 +00:00
|
|
|
|
2010-04-25 20:20:34 +00:00
|
|
|
/* Heuristic for relative chapter seeks: keep track which chapter
|
|
|
|
* the user wanted to go to, even if we aren't exactly within the
|
|
|
|
* boundaries of that chapter due to an inaccurate seek. */
|
|
|
|
int last_chapter_seek;
|
2023-09-27 12:00:14 +00:00
|
|
|
bool last_chapter_flag;
|
2010-04-25 20:20:34 +00:00
|
|
|
|
2017-04-14 16:56:03 +00:00
|
|
|
bool paused; // internal pause state
|
|
|
|
bool playback_active; // not paused, restarting, loading, unloading
|
2017-04-14 17:06:13 +00:00
|
|
|
bool in_playloop;
|
2017-04-14 16:56:03 +00:00
|
|
|
|
2008-11-29 06:09:57 +00:00
|
|
|
// step this many frames, then pause
|
|
|
|
int step_frames;
|
2013-03-08 01:08:02 +00:00
|
|
|
// Counted down each frame, stop playback if 0 is reached. (-1 = disable)
|
|
|
|
int max_frames;
|
2013-03-25 22:44:32 +00:00
|
|
|
bool playing_msg_shown;
|
2008-01-26 11:51:34 +00:00
|
|
|
|
2013-04-25 18:38:22 +00:00
|
|
|
bool paused_for_cache;
|
player: partially rework --cache-pause
The --cache-pause feature (enabled by default) will pause playback for a
while if network runs out of data. If this is not done, then playback
will go on frame-wise (as packets are slowly read from the network and
then instantly decoded and displayed). This feature is actually useless,
as you won't get nice playback no matter what if network is too slow,
but I guess I still prefer this behavior for some reason.
This commit changes this behavior from using the demuxer cache state
only, to trying to use underrun information from the AO/VO. This means
if you have a very large audio buffer, then cache-pausing will trigger
once that buffer is depleted, which will be some time _after_ the
demuxer cache has run out.
This requires explicit support from the AO. Otherwise, the behavior
should be mostly the same as before this commit.
This does not care about the AO buffer. In theory, the AO may underrun,
then the player will write some data to the AO buffer, then the AO will
recover and play this bit of data, then the player will probably trigger
the cache-pause behavior. The probability of this happening should be
pretty low, so I will hold off fixing this until the next refactor of
the AO chain (if ever).
The VO underflow detection was devised and tested in 5 minutes, and may
not be correct. At least I'm fairly sure that the combination of all the
factors should make incorrect behavior relatively unlikely, but problems
are possible.
Also, the demux_reader_state.underrun field may be inaccurate. It's only
the present state at the time demux_get_reader_state() was called, and
may exclude past underruns. In theory, this could cause "close" cases to
be missed. Then you might get an audio underrun without cache-pausing
acting on it. If the stars align, this could happen multiple times in
the row, effectively making this feature not work.
The most user-visible consequence of this change is that the user
will now see an AO underrun warning every time the cache runs out.
Maybe this cache-pause feature should just be removed...
2019-10-11 17:34:04 +00:00
|
|
|
bool demux_underrun;
|
2018-01-03 20:28:28 +00:00
|
|
|
double cache_stop_time;
|
2016-04-19 20:01:30 +00:00
|
|
|
int cache_buffer;
|
2020-03-05 21:23:43 +00:00
|
|
|
double cache_update_pts;
|
2012-12-01 23:22:54 +00:00
|
|
|
|
2008-12-08 18:04:08 +00:00
|
|
|
// Set after showing warning about decoding being too slow for realtime
|
|
|
|
// playback rate. Used to avoid showing it multiple times.
|
|
|
|
bool drop_message_shown;
|
|
|
|
|
2011-10-06 18:46:01 +00:00
|
|
|
struct screenshot_ctx *screenshot_ctx;
|
Add initial Lua scripting support
This is preliminary. There are still tons of issues, and any aspect
of scripting may change in the future. I decided to merge this
(preliminary) work now because it makes it easier to develop it, not
because it's done. lua.rst is clear enough about it (plus some
sarcasm).
This requires linking to Lua. Lua has no official pkg-config file, but
there are distribution specific .pc files, all with different names.
Adding a non-pkg-config based configure test was considered, but we'd
rather not.
One major complication is that libquvi links against Lua too, and if
the Lua version is different from mpv's, you will get a crash as soon
as libquvi uses Lua. (libquvi by design always runs when a file is
opened.) I would consider this the problem of distros and whoever
builds mpv, but to make things easier for users, we add a terrible
runtime test to the configure script, which probes whether libquvi
will crash. This is disabled when cross-compiling, but in that case
we hope the user knows what he is doing.
2013-09-25 22:41:14 +00:00
|
|
|
struct command_ctx *command_ctx;
|
2012-09-14 15:51:26 +00:00
|
|
|
struct encode_lavc_context *encode_lavc_ctx;
|
2014-10-16 09:48:18 +00:00
|
|
|
|
2014-10-19 14:44:33 +00:00
|
|
|
struct mp_ipc_ctx *ipc_ctx;
|
2014-12-09 16:47:02 +00:00
|
|
|
|
2020-08-05 20:37:47 +00:00
|
|
|
int64_t builtin_script_ids[5];
|
2020-03-26 22:58:09 +00:00
|
|
|
|
2018-05-12 14:51:53 +00:00
|
|
|
pthread_mutex_t abort_lock;
|
2017-01-18 16:13:26 +00:00
|
|
|
|
2018-05-12 14:51:53 +00:00
|
|
|
// --- The following fields are protected by abort_lock
|
2018-05-12 16:46:37 +00:00
|
|
|
struct mp_abort_entry **abort_list;
|
|
|
|
int num_abort_list;
|
2018-05-13 11:48:47 +00:00
|
|
|
bool abort_all; // during final termination
|
2017-01-18 18:02:50 +00:00
|
|
|
|
|
|
|
// --- Owned by MPContext
|
|
|
|
pthread_t open_thread;
|
|
|
|
bool open_active; // open_thread is a valid thread handle, all setup
|
|
|
|
atomic_bool open_done;
|
|
|
|
// --- All fields below are immutable while open_active is true.
|
|
|
|
// Otherwise, they're owned by MPContext.
|
|
|
|
struct mp_cancel *open_cancel;
|
|
|
|
char *open_url;
|
|
|
|
char *open_format;
|
|
|
|
int open_url_flags;
|
2019-09-29 00:24:29 +00:00
|
|
|
bool open_for_prefetch;
|
2017-01-18 18:02:50 +00:00
|
|
|
// --- All fields below are owned by open_thread, unless open_done was set
|
|
|
|
// to true.
|
|
|
|
struct demuxer *open_res_demuxer;
|
|
|
|
int open_res_error;
|
2007-02-21 00:49:24 +00:00
|
|
|
} MPContext;
|
|
|
|
|
2018-05-12 16:46:37 +00:00
|
|
|
// Contains information about an asynchronous work item, how it can be aborted,
|
|
|
|
// and when. All fields are protected by MPContext.abort_lock.
|
|
|
|
struct mp_abort_entry {
|
|
|
|
// General conditions.
|
|
|
|
bool coupled_to_playback; // trigger when playback is terminated
|
demux, command: add a third stream recording mechanism
That's right, and it's probably not the end of it. I'll just claim that
I have no idea how to create a proper user interface for this, so I'm
creating multiple partially-orthogonal, of which some may work better in
each of its special use cases.
Until now, there was --record-file. You get relatively good control
about what is muxed, and it can use the cache. But it sucks that it's
bound to playback. If you pause while it's set, muxing stops. If you
seek while it's set, the output will be sort-of trashed, and that's by
design.
Then --stream-record was added. This is a bit better (especially for
live streams), but you can't really control well when muxing stops or
ends. In particular, it can't use the cache (it just dumps whatever the
underlying demuxer returns).
Today, the idea is that the user should just be able to select a time
range to dump to a file, and it should not affected by the user seeking
around in the cache. In addition, the stream may still be running, so
there's some need to continue dumping, even if it's redundant to
--stream-record.
One notable thing is that it uses the async command shit. Not sure
whether this is a good idea. Maybe not, but whatever. Also, a user can
always use the "async" prefix to pretend it doesn't.
Much of this was barely tested (especially the reinterleaving crap),
let's just hope it mostly works. I'm sure you can tolerate the one or
other crash?
2019-07-07 18:38:22 +00:00
|
|
|
// Actual trigger to abort the work. Pointer immutable, owner may access
|
|
|
|
// without holding the abort_lock.
|
2018-05-12 16:46:37 +00:00
|
|
|
struct mp_cancel *cancel;
|
|
|
|
// For client API.
|
|
|
|
struct mpv_handle *client; // non-NULL if done by a client API user
|
|
|
|
int client_work_type; // client API type, e.h. MPV_EVENT_COMMAND_REPLY
|
|
|
|
uint64_t client_work_id; // client API user reply_userdata value
|
|
|
|
// (only valid if client_work_type set)
|
|
|
|
};
|
|
|
|
|
2013-10-30 20:38:30 +00:00
|
|
|
// audio.c
|
2014-07-30 21:01:55 +00:00
|
|
|
void reset_audio_state(struct MPContext *mpctx);
|
2013-10-30 20:38:30 +00:00
|
|
|
void reinit_audio_chain(struct MPContext *mpctx);
|
2016-02-05 20:50:37 +00:00
|
|
|
int init_audio_decoder(struct MPContext *mpctx, struct track *track);
|
2013-10-30 20:38:30 +00:00
|
|
|
int reinit_audio_filters(struct MPContext *mpctx);
|
|
|
|
double playing_audio_pts(struct MPContext *mpctx);
|
2016-02-27 19:02:51 +00:00
|
|
|
void fill_audio_out_buffers(struct MPContext *mpctx);
|
2013-10-30 20:38:30 +00:00
|
|
|
double written_audio_pts(struct MPContext *mpctx);
|
2013-11-08 19:02:09 +00:00
|
|
|
void clear_audio_output_buffers(struct MPContext *mpctx);
|
2015-08-10 16:40:16 +00:00
|
|
|
void update_playback_speed(struct MPContext *mpctx);
|
2014-10-03 17:57:49 +00:00
|
|
|
void uninit_audio_out(struct MPContext *mpctx);
|
|
|
|
void uninit_audio_chain(struct MPContext *mpctx);
|
2017-08-12 21:08:48 +00:00
|
|
|
void reinit_audio_chain_src(struct MPContext *mpctx, struct track *track);
|
2016-07-17 17:21:28 +00:00
|
|
|
void audio_update_volume(struct MPContext *mpctx);
|
2016-10-05 14:42:43 +00:00
|
|
|
void reload_audio_output(struct MPContext *mpctx);
|
audio: refactor how data is passed to AO
This replaces the two buffers (ao_chain.ao_buffer in the core, and
buffer_state.buffers in the AO) with a single queue. Instead of having a
byte based buffer, the queue is simply a list of audio frames, as output
by the decoder. This should make dataflow simpler and reduce copying.
It also attempts to simplify fill_audio_out_buffers(), the function I
always hated most, because it's full of subtle and buggy logic.
Unfortunately, I got assaulted by corner cases, dumb features (attempt
at seamless looping, really?), and other crap, so it got pretty
complicated again. fill_audio_out_buffers() is still full of subtle and
buggy logic. Maybe it got worse. On the other hand, maybe there really
is some progress. Who knows.
Originally, the data flow parts was meant to be in f_output_chain, but
due to tricky interactions with the playloop code, it's now in the dummy
filter in audio.c.
At least this improves the way the audio PTS is passed to the encoder in
encoding mode. Now it attempts to pass frames directly, along with the
pts, which should minimize timestamp problems. But to be honest, encoder
mode is one big kludge that shouldn't exist in this way.
This commit should be considered pre-alpha code. There are lots of bugs
still hiding.
2020-08-28 18:23:54 +00:00
|
|
|
void audio_start_ao(struct MPContext *mpctx);
|
2007-02-21 00:49:24 +00:00
|
|
|
|
2013-10-30 20:38:30 +00:00
|
|
|
// configfiles.c
|
2014-06-26 15:56:47 +00:00
|
|
|
void mp_parse_cfgfiles(struct MPContext *mpctx);
|
2013-12-21 19:45:19 +00:00
|
|
|
void mp_load_auto_profiles(struct MPContext *mpctx);
|
2023-07-07 16:09:36 +00:00
|
|
|
bool mp_load_playback_resume(struct MPContext *mpctx, const char *file);
|
2013-10-30 20:38:30 +00:00
|
|
|
void mp_write_watch_later_conf(struct MPContext *mpctx);
|
command: add delete-watch-later-config
This introduces the delete-watch-later-config command, to complement
write-watch-later-config. This is an alternative to #8141.
The general problem that this change is attempting to help solve has
been described in #336, #3169 and #6574. Though persistent playback
position of a single file is generally a solved problem, this is not
the case for playlists, as described in #8138.
The motivation is facilitating intermittent playback of very large
playlists, consisting of hundreds of entries each many hours
long. Though the current "watch later" mechanism works well - provided
that the files each occur only once in that playlist, and are played
only via that playlist - the biggest issue is that the position is
lost completely should mpv exit uncleanly (e.g. due to a power
failure). Existing workarounds (in the form of Lua scripts which call
write-watch-later-config periodically) fail in the playlist case, due
to the mechanism used by mpv to determine where within a playlist to
resume playback from.
The missing puzzle piece needed to allow scripts to implement a
complete solution to this problem is simply a way to clean up the
watch-later configuration that the script asked mpv to write using
write-watch-later-config. With that in place, scripts can then
register an end-file event listener, check the stop playback reason,
and in the "eof" and "stop" case, invoke delete-watch-later-config to
delete any saved positions written by write-watch-later-config. The
script can then proceed to immediately write a new one when the next
file is loaded, which altogether allows mpv to resume from the correct
playlist and file position upon next startup.
Because events are delivered and executed asynchronously,
delete-watch-later-config takes an optional filename argument, to
allow scripts to clear watch-later configuration for files after mpv
had already moved on from playing them and proceeded to another file.
A Lua script which makes use of this change can be found here:
https://gist.github.com/CyberShadow/2f71a97fb85ed42146f6d9f522bc34ef
(A modification of the one written by @Hakkin, in that this one takes
advantage of the new command, and also saves the state immediately
when a new file is loaded.)
2020-10-22 16:25:20 +00:00
|
|
|
void mp_delete_watch_later_conf(struct MPContext *mpctx, const char *file);
|
2013-12-21 19:45:19 +00:00
|
|
|
struct playlist_entry *mp_check_playlist_resume(struct MPContext *mpctx,
|
|
|
|
struct playlist *playlist);
|
2007-02-21 00:49:24 +00:00
|
|
|
|
2013-10-30 20:38:30 +00:00
|
|
|
// loadfile.c
|
2017-01-18 16:13:26 +00:00
|
|
|
void mp_abort_playback_async(struct MPContext *mpctx);
|
2018-05-12 16:46:37 +00:00
|
|
|
void mp_abort_add(struct MPContext *mpctx, struct mp_abort_entry *abort);
|
|
|
|
void mp_abort_remove(struct MPContext *mpctx, struct mp_abort_entry *abort);
|
|
|
|
void mp_abort_recheck_locked(struct MPContext *mpctx,
|
|
|
|
struct mp_abort_entry *abort);
|
|
|
|
void mp_abort_trigger_locked(struct MPContext *mpctx,
|
|
|
|
struct mp_abort_entry *abort);
|
2018-01-27 20:27:58 +00:00
|
|
|
int mp_add_external_file(struct MPContext *mpctx, char *filename,
|
2021-03-07 21:53:19 +00:00
|
|
|
enum stream_type filter, struct mp_cancel *cancel,
|
|
|
|
bool cover_art);
|
2020-04-15 15:10:01 +00:00
|
|
|
void mark_track_selection(struct MPContext *mpctx, int order,
|
|
|
|
enum stream_type type, int value);
|
2015-05-26 12:01:23 +00:00
|
|
|
#define FLAG_MARK_SELECTION 1
|
2013-10-30 20:38:30 +00:00
|
|
|
void mp_switch_track(struct MPContext *mpctx, enum stream_type type,
|
2015-05-26 12:01:23 +00:00
|
|
|
struct track *track, int flags);
|
2013-12-24 16:46:08 +00:00
|
|
|
void mp_switch_track_n(struct MPContext *mpctx, int order,
|
2015-05-26 12:01:23 +00:00
|
|
|
enum stream_type type, struct track *track, int flags);
|
2013-12-23 19:14:54 +00:00
|
|
|
void mp_deselect_track(struct MPContext *mpctx, struct track *track);
|
2013-10-30 20:38:30 +00:00
|
|
|
struct track *mp_track_by_tid(struct MPContext *mpctx, enum stream_type type,
|
|
|
|
int tid);
|
|
|
|
void add_demuxer_tracks(struct MPContext *mpctx, struct demuxer *demuxer);
|
|
|
|
bool mp_remove_track(struct MPContext *mpctx, struct track *track);
|
|
|
|
struct playlist_entry *mp_next_file(struct MPContext *mpctx, int direction,
|
2023-10-03 21:45:02 +00:00
|
|
|
bool force);
|
2013-10-30 20:38:30 +00:00
|
|
|
void mp_set_playlist_entry(struct MPContext *mpctx, struct playlist_entry *e);
|
|
|
|
void mp_play_files(struct MPContext *mpctx);
|
2014-07-16 20:40:21 +00:00
|
|
|
void update_demuxer_properties(struct MPContext *mpctx);
|
2015-06-03 19:50:37 +00:00
|
|
|
void print_track_list(struct MPContext *mpctx, const char *msg);
|
2020-11-19 14:12:04 +00:00
|
|
|
void reselect_demux_stream(struct MPContext *mpctx, struct track *track,
|
|
|
|
bool refresh_only);
|
2014-12-29 21:08:22 +00:00
|
|
|
void prepare_playlist(struct MPContext *mpctx, struct playlist *pl);
|
player: make various commands for managing external tracks abortable
Until now, they could be aborted only by ending playback, and calling
mpv_abort_async_command didn't do anything.
This requires furthering the mess how playback abort is done. The main
reason why mp_cancel exists at all is to avoid that a "frozen" demuxer
(blocked on network I/O or whatever) cannot freeze the core. The core
should always get its way. Previously, there was a single mp_cancel
handle, that could be signaled, and all demuxers would unfreeze. With
external files, we might want to abort loading of a certain external
file, which automatically means they need a separate mp_cancel. So give
every demuxer its own mp_cancel, and "slave" it to whatever parent
mp_cancel handles aborting.
Since the mpv demuxer API conflates creating the demuxer and reading the
file headers, mp_cancel strictly need to be created before the demuxer
is created (or we couldn't abort loading). Although we give every
demuxer its own mp_cancel (as "enforced" by cancel_and_free_demuxer),
it's still rather messy to create/destroy it along with the demuxer.
2018-05-18 19:38:17 +00:00
|
|
|
void autoload_external_files(struct MPContext *mpctx, struct mp_cancel *cancel);
|
2015-05-22 19:00:24 +00:00
|
|
|
struct track *select_default_track(struct MPContext *mpctx, int order,
|
|
|
|
enum stream_type type);
|
2017-01-18 18:02:50 +00:00
|
|
|
void prefetch_next(struct MPContext *mpctx);
|
2017-08-12 21:08:48 +00:00
|
|
|
void update_lavfi_complex(struct MPContext *mpctx);
|
2013-10-30 20:38:30 +00:00
|
|
|
|
|
|
|
// main.c
|
2015-03-05 10:17:22 +00:00
|
|
|
int mp_initialize(struct MPContext *mpctx, char **argv);
|
2014-02-10 20:01:35 +00:00
|
|
|
struct MPContext *mp_create(void);
|
|
|
|
void mp_destroy(struct MPContext *mpctx);
|
2013-12-21 18:45:42 +00:00
|
|
|
void mp_print_version(struct mp_log *log, int always);
|
2016-09-29 14:26:54 +00:00
|
|
|
void mp_update_logging(struct MPContext *mpctx, bool preinit);
|
2017-08-14 12:02:13 +00:00
|
|
|
void issue_refresh_seek(struct MPContext *mpctx, enum seek_precision min_prec);
|
2013-10-30 20:38:30 +00:00
|
|
|
|
|
|
|
// misc.c
|
player: modify/simplify AB-loop behavior
This changes the behavior of the --ab-loop-a/b options. In addition, it
makes it work with backward playback mode.
The most obvious change is that the both the A and B point need to be
set now before any looping happens. Unlike before, unset points don't
implicitly use the start or end of the file. I think the old behavior
was a feature that was explicitly added/wanted. Well, it's gone now.
This is because of 2 reasons:
1. I never liked this feature, and it always got in my way (as user).
2. It's inherently annoying with backward playback mode.
In backward playback mode, the user wants to set A/B in the wrong order.
The ab-loop command will first set A, then B, so if you use this command
during backward playback, A will be set to a higher timestamps than B.
If you switch back to forward playback mode, the loop would stop
working. I want the loop to just continue to work, and the chosen
solution conflicts with the removed feature.
The order issue above _could_ be fixed by also switching the AB-loop
user option values around on direction switch. But there are no other
instances of option changes magically affecting other options, and doing
this would probably lead to unexpected misery (dying from corner cases
and such).
Another solution is sorting the A/B points by timestamps after copying
them from the user options. Then A/B options set in backward mode will
work in forward mode. This is the chosen solution. If you sort the
points, you don't know anymore whether the unset point is supposed to
signify the end or the start of the file.
The AB-loop code is slightly better abstracted now, so it should be easy
to restore the removed feature. It would still require coming up with a
solution for backwards playback, though.
A minor change is that if one point is set and the other is unset, I'm
rendering both the chapter markers and the marker for the set point.
Why? I don't know. My test file had chapters, and I guess I decided this
looked better.
This commit also fixes some subtle and obvious issues that I already
forgot about when I wrote this commit message. It cleans up some minor
code duplication and nonsense too.
Regarding backward playback, the code uses an unsanitary mix of internal
("transformed") and user timestamps. So the play_dir variable appears
more than usual.
To mention one unfixed issue: if you set an AB-loop that is completely
past the end of the file, it will get stuck in an infinite seeking loop
once playback reaches the end of the file. Fixing this reliably seemed
annoying, so the fix is "just don't do this". It's not a hard freeze
anyway.
2019-05-26 23:24:22 +00:00
|
|
|
double rel_time_to_abs(struct MPContext *mpctx, struct m_rel_time t);
|
2013-10-30 20:38:30 +00:00
|
|
|
double get_play_end_pts(struct MPContext *mpctx);
|
2017-12-04 01:26:42 +00:00
|
|
|
double get_play_start_pts(struct MPContext *mpctx);
|
player: modify/simplify AB-loop behavior
This changes the behavior of the --ab-loop-a/b options. In addition, it
makes it work with backward playback mode.
The most obvious change is that the both the A and B point need to be
set now before any looping happens. Unlike before, unset points don't
implicitly use the start or end of the file. I think the old behavior
was a feature that was explicitly added/wanted. Well, it's gone now.
This is because of 2 reasons:
1. I never liked this feature, and it always got in my way (as user).
2. It's inherently annoying with backward playback mode.
In backward playback mode, the user wants to set A/B in the wrong order.
The ab-loop command will first set A, then B, so if you use this command
during backward playback, A will be set to a higher timestamps than B.
If you switch back to forward playback mode, the loop would stop
working. I want the loop to just continue to work, and the chosen
solution conflicts with the removed feature.
The order issue above _could_ be fixed by also switching the AB-loop
user option values around on direction switch. But there are no other
instances of option changes magically affecting other options, and doing
this would probably lead to unexpected misery (dying from corner cases
and such).
Another solution is sorting the A/B points by timestamps after copying
them from the user options. Then A/B options set in backward mode will
work in forward mode. This is the chosen solution. If you sort the
points, you don't know anymore whether the unset point is supposed to
signify the end or the start of the file.
The AB-loop code is slightly better abstracted now, so it should be easy
to restore the removed feature. It would still require coming up with a
solution for backwards playback, though.
A minor change is that if one point is set and the other is unset, I'm
rendering both the chapter markers and the marker for the set point.
Why? I don't know. My test file had chapters, and I guess I decided this
looked better.
This commit also fixes some subtle and obvious issues that I already
forgot about when I wrote this commit message. It cleans up some minor
code duplication and nonsense too.
Regarding backward playback, the code uses an unsanitary mix of internal
("transformed") and user timestamps. So the play_dir variable appears
more than usual.
To mention one unfixed issue: if you set an AB-loop that is completely
past the end of the file, it will get stuck in an infinite seeking loop
once playback reaches the end of the file. Fixing this reliably seemed
annoying, so the fix is "just don't do this". It's not a hard freeze
anyway.
2019-05-26 23:24:22 +00:00
|
|
|
bool get_ab_loop_times(struct MPContext *mpctx, double t[2]);
|
2013-11-19 21:36:33 +00:00
|
|
|
void merge_playlist_files(struct playlist *pl);
|
2022-11-15 21:50:38 +00:00
|
|
|
void update_content_type(struct MPContext *mpctx, struct track *track);
|
2015-11-15 22:03:48 +00:00
|
|
|
void update_vo_playback_state(struct MPContext *mpctx);
|
2013-11-09 23:49:13 +00:00
|
|
|
void update_window_title(struct MPContext *mpctx, bool force);
|
2014-10-23 16:31:43 +00:00
|
|
|
void error_on_track(struct MPContext *mpctx, struct track *track);
|
2015-07-02 12:02:32 +00:00
|
|
|
int stream_dump(struct MPContext *mpctx, const char *source_filename);
|
2016-08-04 09:26:57 +00:00
|
|
|
double get_track_seek_offset(struct MPContext *mpctx, struct track *track);
|
2013-10-30 20:38:30 +00:00
|
|
|
|
|
|
|
// osd.c
|
2014-09-21 21:40:45 +00:00
|
|
|
void set_osd_bar(struct MPContext *mpctx, int type,
|
2014-06-08 21:52:58 +00:00
|
|
|
double min, double max, double neutral, double val);
|
2014-09-25 19:14:00 +00:00
|
|
|
bool set_osd_msg(struct MPContext *mpctx, int level, int time,
|
2014-01-17 21:34:47 +00:00
|
|
|
const char* fmt, ...) PRINTF_ATTRIBUTE(4,5);
|
2013-10-30 20:47:14 +00:00
|
|
|
void set_osd_function(struct MPContext *mpctx, int osd_function);
|
2015-11-17 00:54:02 +00:00
|
|
|
void term_osd_set_subs(struct MPContext *mpctx, const char *text);
|
2014-09-17 22:12:59 +00:00
|
|
|
void get_current_osd_sym(struct MPContext *mpctx, char *buf, size_t buf_size);
|
2014-11-18 19:28:54 +00:00
|
|
|
void set_osd_bar_chapters(struct MPContext *mpctx, int type);
|
2013-10-30 20:38:30 +00:00
|
|
|
|
|
|
|
// playloop.c
|
2016-09-16 12:25:50 +00:00
|
|
|
void mp_wait_events(struct MPContext *mpctx);
|
2016-09-16 12:24:15 +00:00
|
|
|
void mp_set_timeout(struct MPContext *mpctx, double sleeptime);
|
2016-09-16 12:23:54 +00:00
|
|
|
void mp_wakeup_core(struct MPContext *mpctx);
|
|
|
|
void mp_wakeup_core_cb(void *ctx);
|
2018-05-06 16:27:18 +00:00
|
|
|
void mp_core_lock(struct MPContext *mpctx);
|
|
|
|
void mp_core_unlock(struct MPContext *mpctx);
|
Relicense some non-MPlayer source files to LGPL 2.1 or later
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.
2016-01-19 17:36:06 +00:00
|
|
|
double get_relative_time(struct MPContext *mpctx);
|
2014-07-30 21:01:55 +00:00
|
|
|
void reset_playback_state(struct MPContext *mpctx);
|
2017-04-14 16:22:45 +00:00
|
|
|
void set_pause_state(struct MPContext *mpctx, bool user_pause);
|
|
|
|
void update_internal_pause_state(struct MPContext *mpctx);
|
2017-04-14 16:56:03 +00:00
|
|
|
void update_core_idle_state(struct MPContext *mpctx);
|
core: add backstep support
Allows stepping back one frame via the frame_back_step inout command,
bound to "," by default.
This uses the precise seeking facility, and a perfect frame index built
on the fly. The index is built during playback and precise seeking, and
contains (as of this commit) the last 100 displayed or skipped frames.
This index is used to find the PTS of the previous frame, which is then
used as target for a precise seek. If no PTS is found, the core attempts
to do a seek before the current frame, and skip decoded frames until the
current frame is reached; this will create a sufficient index and the
normal backstep algorithm can be applied.
This can be rather slow. The worst case for backstepping is about the
same as the worst case for precise seeking if the previous frame can be
deduced from the index. If not, the worst case will be twice as slow.
There's also some minor danger that the index is incorrect in case
framedropping is involved. For framedropping due to --framedrop, this
problem is ignored (use of --framedrop is discouraged anyway). For
framedropping during precise seeking (done to make it faster), we try
to not add frames to the index that are produced when this can happen.
I'm not sure how well that works (or if the logic is sane), and it's
sure to break with some video filters. In the worst case, backstepping
might silently skip frames if you backstep after a user-initiated
precise seek. (Precise seeks to do indexing are not affected.)
Likewise, video filters that somehow change timing of frames and do not
do this in a deterministic way (i.e. if you seek to a position, frames
with different timings are produced than when the position is reached
during normal playback) will make backstepping silently jump to the
wrong frame. Enabling/disabling filters during playback (like for
example deinterlacing) will have similar bad effects.
2013-04-24 17:31:48 +00:00
|
|
|
void add_step_frame(struct MPContext *mpctx, int dir);
|
2010-12-18 08:13:45 +00:00
|
|
|
void queue_seek(struct MPContext *mpctx, enum seek_type type, double amount,
|
2016-08-15 19:07:32 +00:00
|
|
|
enum seek_precision exact, int flags);
|
2010-11-07 22:54:32 +00:00
|
|
|
double get_time_length(struct MPContext *mpctx);
|
2019-05-26 23:46:34 +00:00
|
|
|
double get_start_time(struct MPContext *mpctx, int dir);
|
2010-11-07 22:54:32 +00:00
|
|
|
double get_current_time(struct MPContext *mpctx);
|
2014-06-29 17:27:46 +00:00
|
|
|
double get_playback_time(struct MPContext *mpctx);
|
2010-11-07 22:54:32 +00:00
|
|
|
int get_percent_pos(struct MPContext *mpctx);
|
2013-06-20 10:15:36 +00:00
|
|
|
double get_current_pos_ratio(struct MPContext *mpctx, bool use_range);
|
2009-04-02 02:00:22 +00:00
|
|
|
int get_current_chapter(struct MPContext *mpctx);
|
|
|
|
char *chapter_display_name(struct MPContext *mpctx, int chapter);
|
2011-10-23 02:51:44 +00:00
|
|
|
char *chapter_name(struct MPContext *mpctx, int chapter);
|
|
|
|
double chapter_start_time(struct MPContext *mpctx, int chapter);
|
|
|
|
int get_chapter_count(struct MPContext *mpctx);
|
2016-04-19 20:01:30 +00:00
|
|
|
int get_cache_buffering_percentage(struct MPContext *mpctx);
|
2013-10-29 21:38:29 +00:00
|
|
|
void execute_queued_seek(struct MPContext *mpctx);
|
|
|
|
void run_playloop(struct MPContext *mpctx);
|
2014-10-06 19:20:38 +00:00
|
|
|
void mp_idle(struct MPContext *mpctx);
|
2013-10-29 21:38:29 +00:00
|
|
|
void idle_loop(struct MPContext *mpctx);
|
2015-09-21 19:22:20 +00:00
|
|
|
int handle_force_window(struct MPContext *mpctx, bool force);
|
2014-12-08 16:27:07 +00:00
|
|
|
void seek_to_last_frame(struct MPContext *mpctx);
|
2016-10-02 10:33:34 +00:00
|
|
|
void update_screensaver_state(struct MPContext *mpctx);
|
player: modify/simplify AB-loop behavior
This changes the behavior of the --ab-loop-a/b options. In addition, it
makes it work with backward playback mode.
The most obvious change is that the both the A and B point need to be
set now before any looping happens. Unlike before, unset points don't
implicitly use the start or end of the file. I think the old behavior
was a feature that was explicitly added/wanted. Well, it's gone now.
This is because of 2 reasons:
1. I never liked this feature, and it always got in my way (as user).
2. It's inherently annoying with backward playback mode.
In backward playback mode, the user wants to set A/B in the wrong order.
The ab-loop command will first set A, then B, so if you use this command
during backward playback, A will be set to a higher timestamps than B.
If you switch back to forward playback mode, the loop would stop
working. I want the loop to just continue to work, and the chosen
solution conflicts with the removed feature.
The order issue above _could_ be fixed by also switching the AB-loop
user option values around on direction switch. But there are no other
instances of option changes magically affecting other options, and doing
this would probably lead to unexpected misery (dying from corner cases
and such).
Another solution is sorting the A/B points by timestamps after copying
them from the user options. Then A/B options set in backward mode will
work in forward mode. This is the chosen solution. If you sort the
points, you don't know anymore whether the unset point is supposed to
signify the end or the start of the file.
The AB-loop code is slightly better abstracted now, so it should be easy
to restore the removed feature. It would still require coming up with a
solution for backwards playback, though.
A minor change is that if one point is set and the other is unset, I'm
rendering both the chapter markers and the marker for the set point.
Why? I don't know. My test file had chapters, and I guess I decided this
looked better.
This commit also fixes some subtle and obvious issues that I already
forgot about when I wrote this commit message. It cleans up some minor
code duplication and nonsense too.
Regarding backward playback, the code uses an unsanitary mix of internal
("transformed") and user timestamps. So the play_dir variable appears
more than usual.
To mention one unfixed issue: if you set an AB-loop that is completely
past the end of the file, it will get stuck in an infinite seeking loop
once playback reaches the end of the file. Fixing this reliably seemed
annoying, so the fix is "just don't do this". It's not a hard freeze
anyway.
2019-05-26 23:24:22 +00:00
|
|
|
void update_ab_loop_clip(struct MPContext *mpctx);
|
2020-08-27 09:43:06 +00:00
|
|
|
bool get_internal_paused(struct MPContext *mpctx);
|
2011-02-14 07:34:39 +00:00
|
|
|
|
2014-05-12 23:14:07 +00:00
|
|
|
// scripting.c
|
scripting: load scripts from directories
The intention is to provide a slightly nicer way to distribute scripts.
For example, you could put multiple source files into the directory, and
then import them from the actual script file (this is still
unimplemented).
At first I wanted to require a config file (because you need to know at
least which scripting backend it should use). This wouldn't have been
too hard (could have reused/abused the mpv config file parsing
mechanism, and I already had working code that was just 2 function
calls). But probably better to do this without new config files, because
it might become a pain in the distant future.
So this just probes for "main.lua", "main.js", etc., until an existing
file is found.
Another important change is that this skips all directory entries whose
name starts with ".". This automatically excludes the "." and ".."
special directories, and is probably useful to exclude random crap that
might be lying around in the directory (such as editor temporary files,
or OSX, in its usual hrmful, annoying, and idiotic modus operandi,
sharting all over any directories opened by "Finder").
Although the changelog mentions the docs, they're added only in a later
commit.
2020-02-01 17:09:40 +00:00
|
|
|
struct mp_script_args {
|
|
|
|
const struct mp_scripting *backend;
|
|
|
|
struct MPContext *mpctx;
|
|
|
|
struct mp_log *log;
|
|
|
|
struct mpv_handle *client;
|
|
|
|
const char *filename;
|
|
|
|
const char *path;
|
|
|
|
};
|
2014-05-12 23:14:07 +00:00
|
|
|
struct mp_scripting {
|
2017-01-14 15:47:53 +00:00
|
|
|
const char *name; // e.g. "lua script"
|
2014-05-12 23:14:07 +00:00
|
|
|
const char *file_ext; // e.g. "lua"
|
2020-02-19 21:18:15 +00:00
|
|
|
bool no_thread; // don't run load() on dedicated thread
|
scripting: load scripts from directories
The intention is to provide a slightly nicer way to distribute scripts.
For example, you could put multiple source files into the directory, and
then import them from the actual script file (this is still
unimplemented).
At first I wanted to require a config file (because you need to know at
least which scripting backend it should use). This wouldn't have been
too hard (could have reused/abused the mpv config file parsing
mechanism, and I already had working code that was just 2 function
calls). But probably better to do this without new config files, because
it might become a pain in the distant future.
So this just probes for "main.lua", "main.js", etc., until an existing
file is found.
Another important change is that this skips all directory entries whose
name starts with ".". This automatically excludes the "." and ".."
special directories, and is probably useful to exclude random crap that
might be lying around in the directory (such as editor temporary files,
or OSX, in its usual hrmful, annoying, and idiotic modus operandi,
sharting all over any directories opened by "Finder").
Although the changelog mentions the docs, they're added only in a later
commit.
2020-02-01 17:09:40 +00:00
|
|
|
int (*load)(struct mp_script_args *args);
|
2014-05-12 23:14:07 +00:00
|
|
|
};
|
2020-01-19 18:25:54 +00:00
|
|
|
bool mp_load_scripts(struct MPContext *mpctx);
|
2016-09-19 22:59:54 +00:00
|
|
|
void mp_load_builtin_scripts(struct MPContext *mpctx);
|
2020-03-26 22:58:09 +00:00
|
|
|
int64_t mp_load_user_script(struct MPContext *mpctx, const char *fname);
|
2014-05-12 23:14:07 +00:00
|
|
|
|
2013-10-30 20:38:30 +00:00
|
|
|
// sub.c
|
2014-07-30 21:01:55 +00:00
|
|
|
void reset_subtitle_state(struct MPContext *mpctx);
|
2016-01-17 15:56:32 +00:00
|
|
|
void reinit_sub(struct MPContext *mpctx, struct track *track);
|
|
|
|
void reinit_sub_all(struct MPContext *mpctx);
|
|
|
|
void uninit_sub(struct MPContext *mpctx, struct track *track);
|
2014-10-03 17:57:49 +00:00
|
|
|
void uninit_sub_all(struct MPContext *mpctx);
|
2013-10-30 20:38:30 +00:00
|
|
|
void update_osd_msg(struct MPContext *mpctx);
|
2015-12-29 00:35:52 +00:00
|
|
|
bool update_subtitles(struct MPContext *mpctx, double video_pts);
|
2013-06-07 20:57:00 +00:00
|
|
|
|
2013-10-30 20:38:30 +00:00
|
|
|
// video.c
|
2014-07-30 21:01:55 +00:00
|
|
|
void reset_video_state(struct MPContext *mpctx);
|
2016-02-05 20:50:37 +00:00
|
|
|
int init_video_decoder(struct MPContext *mpctx, struct track *track);
|
2017-08-12 21:08:48 +00:00
|
|
|
void reinit_video_chain(struct MPContext *mpctx);
|
|
|
|
void reinit_video_chain_src(struct MPContext *mpctx, struct track *track);
|
2013-10-30 20:38:30 +00:00
|
|
|
int reinit_video_filters(struct MPContext *mpctx);
|
2016-02-27 19:02:51 +00:00
|
|
|
void write_video(struct MPContext *mpctx);
|
2013-10-30 20:38:30 +00:00
|
|
|
void mp_force_video_refresh(struct MPContext *mpctx);
|
2014-10-03 17:57:49 +00:00
|
|
|
void uninit_video_out(struct MPContext *mpctx);
|
|
|
|
void uninit_video_chain(struct MPContext *mpctx);
|
player: refactor display-sync frame duration calculations
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.
2015-11-13 21:45:40 +00:00
|
|
|
double calc_average_frame_duration(struct MPContext *mpctx);
|
2013-10-30 20:38:30 +00:00
|
|
|
|
2008-02-22 09:09:46 +00:00
|
|
|
#endif /* MPLAYER_MP_CORE_H */
|