2008-03-31 03:19:29 +00:00
|
|
|
#ifndef MPLAYER_OPTIONS_H
|
|
|
|
#define MPLAYER_OPTIONS_H
|
|
|
|
|
2013-03-04 16:40:21 +00:00
|
|
|
#include <stdbool.h>
|
2013-03-08 01:08:02 +00:00
|
|
|
#include <stdint.h>
|
2013-12-17 01:02:25 +00:00
|
|
|
#include "m_option.h"
|
2015-05-22 19:00:24 +00:00
|
|
|
#include "common/common.h"
|
2012-11-15 17:49:17 +00:00
|
|
|
|
2013-03-04 21:41:27 +00:00
|
|
|
typedef struct mp_vo_opts {
|
2016-11-25 20:00:39 +00:00
|
|
|
struct m_obj_settings *video_driver_list;
|
2013-03-04 21:41:27 +00:00
|
|
|
|
2016-05-05 05:56:21 +00:00
|
|
|
int taskbar_progress;
|
2016-12-09 18:22:33 +00:00
|
|
|
int snap_window;
|
2013-03-04 21:41:27 +00:00
|
|
|
int ontop;
|
2017-02-13 19:08:43 +00:00
|
|
|
int ontop_level;
|
options: introduce bool option type, use it for --fullscreen
The option code is very old and was added to MPlayer in the early 2000s,
when C99 was still new. MPlayer did not use the "bool" type anywhere,l
and the logical option equivalent to bool, the "flag" option type, used
int, with the convention that only the values 0 and 1 are allowed.
mpv may have hammered many, many additional tentacles to the option
code, but some of the basics never changed, and m_option_type_flag still
uses int. This seems a bit weird, since mpv uses bool for booleans. So
finally introduce an m_option_type_bool. To avoid duplicating too much
code, change the flag code to bool, and "reimplement" m_option_type_flag
on top of m_option_type_bool.
As a "demonstration", change the --fullscreen option to this new type.
Ideally, all options would be changed too bool, and m_option_type_flag
would be removed. But that is a lot of monotonous thankless work, so I'm
not doing it, and making it a painful years long transition.
At the same time, I'm introducing a new concept for option declarations.
Instead of OPT_BOOL(), which define the full m_option struct contents,
there's OPTF_BOOL(), which only takes the option field name itself. The
name is provided via a normal struct field initializer. Other fields
(such as flags) can be provided via designated initializers.
The advantage of this is that we don't need tons of nested vararg
macros. We also don't need to deal with 0-sized varargs being a pain
(and in fact they are not a thing in standard C99 and probably C11).
There is no need to provide a mandatory flags argument either, which is
the reason why so many OPT_ macros are used with a "0" argument. (The
flag argument seems to confuse other developers; they either don't
immediately recognize what it is, and sometimes it's supposed to be the
option's default value.)
Not having to mess with the flag argument in such option macros is also
a reason for the removal of M_OPT_RANGE etc., for the better or worse.
The only place that special-cased the _flag option type was in
command.c; change it to use something effectively very similar that
automatically includes the new _bool option type. Everything else should
be transparent to the change. The fullscreen option change should be
transparent too, as C99 bool is basically an integer type that is
clamped to 0/1 (except in Swift, Swift sucks).
2020-03-14 01:07:35 +00:00
|
|
|
bool fullscreen;
|
2015-01-16 22:38:47 +00:00
|
|
|
int border;
|
2016-04-26 01:46:49 +00:00
|
|
|
int fit_border;
|
2015-01-16 22:38:47 +00:00
|
|
|
int all_workspaces;
|
2019-11-29 12:49:33 +00:00
|
|
|
int window_minimized;
|
|
|
|
int window_maximized;
|
2015-01-16 22:38:47 +00:00
|
|
|
|
2013-03-04 21:41:27 +00:00
|
|
|
int screen_id;
|
|
|
|
int fsscreen_id;
|
|
|
|
char *winname;
|
2014-05-15 22:47:13 +00:00
|
|
|
int x11_netwm;
|
2015-11-18 20:37:38 +00:00
|
|
|
int x11_bypass_compositor;
|
2013-04-03 23:13:56 +00:00
|
|
|
int native_keyrepeat;
|
2013-03-04 21:41:27 +00:00
|
|
|
|
|
|
|
float panscan;
|
2013-06-14 22:15:32 +00:00
|
|
|
float zoom;
|
|
|
|
float pan_x, pan_y;
|
|
|
|
float align_x, align_y;
|
2019-06-15 15:53:59 +00:00
|
|
|
float margin_x[2];
|
|
|
|
float margin_y[2];
|
2013-09-01 01:27:03 +00:00
|
|
|
int unscaled;
|
2013-03-04 21:41:27 +00:00
|
|
|
|
|
|
|
struct m_geometry geometry;
|
|
|
|
struct m_geometry autofit;
|
|
|
|
struct m_geometry autofit_larger;
|
2015-01-16 21:30:32 +00:00
|
|
|
struct m_geometry autofit_smaller;
|
2016-09-19 23:20:22 +00:00
|
|
|
double window_scale;
|
2013-03-04 21:41:27 +00:00
|
|
|
|
|
|
|
int keepaspect;
|
2014-10-04 20:17:36 +00:00
|
|
|
int keepaspect_window;
|
2016-10-25 13:59:13 +00:00
|
|
|
int hidpi_window_scale;
|
2017-07-27 19:28:33 +00:00
|
|
|
int native_fs;
|
2013-03-04 21:41:27 +00:00
|
|
|
|
|
|
|
int64_t WinID;
|
|
|
|
|
|
|
|
float force_monitor_aspect;
|
|
|
|
float monitor_pixel_aspect;
|
|
|
|
int force_window_position;
|
2013-05-10 22:22:23 +00:00
|
|
|
|
2015-12-06 18:20:23 +00:00
|
|
|
char *mmcss_profile;
|
|
|
|
|
2018-03-13 11:34:26 +00:00
|
|
|
double override_display_fps;
|
2018-03-13 10:23:23 +00:00
|
|
|
double timing_offset;
|
|
|
|
|
2016-10-04 20:07:19 +00:00
|
|
|
// vo_drm
|
2017-10-23 06:59:58 +00:00
|
|
|
struct drm_opts *drm_opts;
|
2019-09-28 08:26:23 +00:00
|
|
|
|
|
|
|
int swapchain_depth; // max number of images to render ahead
|
2013-03-04 21:41:27 +00:00
|
|
|
} mp_vo_opts;
|
|
|
|
|
2017-12-29 16:19:25 +00:00
|
|
|
// Subtitle options needed by the subtitle decoders/renderers.
|
|
|
|
struct mp_subtitle_opts {
|
|
|
|
int sub_visibility;
|
|
|
|
int sub_pos;
|
|
|
|
float sub_delay;
|
|
|
|
float sub_fps;
|
|
|
|
float sub_speed;
|
|
|
|
int forced_subs_only;
|
|
|
|
int stretch_dvd_subs;
|
|
|
|
int stretch_image_subs;
|
|
|
|
int image_subs_video_res;
|
|
|
|
int sub_fix_timing;
|
|
|
|
int sub_scale_by_window;
|
|
|
|
int sub_scale_with_window;
|
|
|
|
int ass_scale_with_window;
|
|
|
|
struct osd_style_opts *sub_style;
|
|
|
|
float sub_scale;
|
|
|
|
float sub_gauss;
|
|
|
|
int sub_gray;
|
|
|
|
int ass_enabled;
|
|
|
|
float ass_line_spacing;
|
|
|
|
int ass_use_margins;
|
|
|
|
int sub_use_margins;
|
|
|
|
int ass_vsfilter_aspect_compat;
|
|
|
|
int ass_vsfilter_color_compat;
|
|
|
|
int ass_vsfilter_blur_compat;
|
|
|
|
int use_embedded_fonts;
|
|
|
|
char **ass_force_style_list;
|
|
|
|
char *ass_styles_file;
|
|
|
|
int ass_style_override;
|
|
|
|
int ass_hinting;
|
|
|
|
int ass_shaper;
|
|
|
|
int ass_justify;
|
|
|
|
int sub_clear_on_seek;
|
|
|
|
int teletext_page;
|
|
|
|
};
|
|
|
|
|
sub: make filter_sdh a "proper" filter, allow runtime changes
Until now, filter_sdh was simply a function that was called by sd_ass
directly (if enabled).
I want to add another filter, so it's time to turn this into a somewhat
more general subtitle filtering infrastructure.
I pondered whether to reuse the audio/video filtering stuff - but better
not. Also, since subtitles are horrible and tend to refuse proper
abstraction, it's still messed into sd_ass, instead of working on the
dec_sub.c level. Actually mpv used to have subtitle "filters" and even
made subtitle converters part of it, but it was fairly horrible, so
don't do that again.
In addition, make runtime changes possible. Since this was supposed to
be a quick hack, I just decided to put all subtitle filter options into
a separate option group (=> simpler change notification), to manually
push the change through the playloop (like it was sort of before for OSD
options), and to recreate the sub filter chain completely in every
change. Should be good enough.
One strangeness is that due to prefetching and such, most subtitle
packets (or those some time ahead) are actually done filtering when we
change, so the user still needs to manually seek to actually refresh
everything. And since subtitle data is usually cached in ASS_Track (for
other terrible but user-friendly reasons), we also must clear the
subtitle data, but of course only on seek, since otherwise all subtitles
would just disappear. What a fucking mess, but such is life. We could
trigger a "refresh seek" to make this more automatic, but I don't feel
like it currently.
This is slightly inefficient (lots of allocations and copying), but I
decided that it doesn't matter. Could matter slightly for crazy ASS
subtitles that render with thousands of events.
Not very well tested. Still seems to work, but I didn't have many test
cases.
2020-02-16 00:02:17 +00:00
|
|
|
struct mp_sub_filter_opts {
|
|
|
|
int sub_filter_SDH;
|
|
|
|
int sub_filter_SDH_harder;
|
2020-02-16 01:03:36 +00:00
|
|
|
int rf_enable;
|
|
|
|
char **rf_items;
|
|
|
|
int rf_warn;
|
sub: make filter_sdh a "proper" filter, allow runtime changes
Until now, filter_sdh was simply a function that was called by sd_ass
directly (if enabled).
I want to add another filter, so it's time to turn this into a somewhat
more general subtitle filtering infrastructure.
I pondered whether to reuse the audio/video filtering stuff - but better
not. Also, since subtitles are horrible and tend to refuse proper
abstraction, it's still messed into sd_ass, instead of working on the
dec_sub.c level. Actually mpv used to have subtitle "filters" and even
made subtitle converters part of it, but it was fairly horrible, so
don't do that again.
In addition, make runtime changes possible. Since this was supposed to
be a quick hack, I just decided to put all subtitle filter options into
a separate option group (=> simpler change notification), to manually
push the change through the playloop (like it was sort of before for OSD
options), and to recreate the sub filter chain completely in every
change. Should be good enough.
One strangeness is that due to prefetching and such, most subtitle
packets (or those some time ahead) are actually done filtering when we
change, so the user still needs to manually seek to actually refresh
everything. And since subtitle data is usually cached in ASS_Track (for
other terrible but user-friendly reasons), we also must clear the
subtitle data, but of course only on seek, since otherwise all subtitles
would just disappear. What a fucking mess, but such is life. We could
trigger a "refresh seek" to make this more automatic, but I don't feel
like it currently.
This is slightly inefficient (lots of allocations and copying), but I
decided that it doesn't matter. Could matter slightly for crazy ASS
subtitles that render with thousands of events.
Not very well tested. Still seems to work, but I didn't have many test
cases.
2020-02-16 00:02:17 +00:00
|
|
|
};
|
|
|
|
|
2017-12-29 16:19:25 +00:00
|
|
|
struct mp_osd_render_opts {
|
|
|
|
float osd_bar_align_x;
|
|
|
|
float osd_bar_align_y;
|
|
|
|
float osd_bar_w;
|
|
|
|
float osd_bar_h;
|
|
|
|
float osd_scale;
|
|
|
|
int osd_scale_by_window;
|
|
|
|
struct osd_style_opts *osd_style;
|
|
|
|
int force_rgba_osd;
|
|
|
|
};
|
|
|
|
|
2013-03-04 21:41:27 +00:00
|
|
|
typedef struct MPOpts {
|
2016-09-01 18:00:43 +00:00
|
|
|
int property_print_help;
|
2014-02-06 15:49:50 +00:00
|
|
|
int use_terminal;
|
2014-04-17 19:47:00 +00:00
|
|
|
char *dump_stats;
|
2013-12-21 22:11:12 +00:00
|
|
|
int verbose;
|
2017-06-23 18:42:20 +00:00
|
|
|
int msg_really_quiet;
|
2015-02-06 15:48:52 +00:00
|
|
|
char **msg_levels;
|
2013-12-21 22:11:12 +00:00
|
|
|
int msg_color;
|
|
|
|
int msg_module;
|
2014-02-28 21:45:34 +00:00
|
|
|
int msg_time;
|
2015-01-26 10:31:02 +00:00
|
|
|
char *log_file;
|
2013-12-18 18:04:30 +00:00
|
|
|
|
test: make tests part of the mpv binary
Until now, each .c file in test/ was built as separate, self-contained
binary. Each binary could be run to execute the tests it contained.
Change this and make them part of the normal mpv binary. Now the tests
have to be invoked via the --unittest option. Do this for two reasons:
- Tests now run within a "properly" initialized mpv instance, so all
services are available.
- Possibly simplifying the situation for future build systems.
The first point is the main motivation. The mpv code is entangled with
mp_log and the option system. It feels like a bad idea to duplicate some
of the initialization of this just so you can call code using them.
I'm also getting rid of cmocka. There wouldn't be any problem to keep it
(it's a perfectly sane set of helpers), but NIH calls. I would have had
to aggregate all tests into a CMUnitTest list, and I don't see how I'd
get different types of entry points easily. Probably easily solvable,
but since we made only pretty basic use of this library, NIH-ing this is
actually easier (I needed a list of tests with custom metadata anyway,
so all what was left was reimplement the assert_* helpers).
Unit tests now don't output anything, and if they fail, they'll simply
crash and leave a message that typically requires inspecting the test
code to figure out what went wrong (and probably editing the test code
to get more information). I even merged the various test functions into
single ones. Sucks, but here you go.
chmap_sel.c is merged into chmap.c, because I didn't see the point of
this being separate. json.c drops the print_message() to go along with
the new silent-by-default idea, also there's a memory leak fix unrelated
to the rest of this commit.
The new code is enabled with --enable-tests (--enable-test goes away).
Due to waf's option parser, --enable-test still works, because it's a
unique prefix to --enable-tests.
2019-11-07 21:42:14 +00:00
|
|
|
char *test_mode;
|
2016-09-23 19:24:50 +00:00
|
|
|
int operation_mode;
|
|
|
|
|
2013-04-10 19:06:00 +00:00
|
|
|
char **reset_options;
|
2014-12-14 23:31:30 +00:00
|
|
|
char **script_files;
|
|
|
|
char **script_opts;
|
2013-09-25 22:56:41 +00:00
|
|
|
int lua_load_osc;
|
2014-11-19 17:51:53 +00:00
|
|
|
int lua_load_ytdl;
|
2014-11-19 22:33:28 +00:00
|
|
|
char *lua_ytdl_format;
|
2015-02-22 20:32:42 +00:00
|
|
|
char **lua_ytdl_raw_options;
|
2017-09-26 23:17:47 +00:00
|
|
|
int lua_load_stats;
|
2019-12-07 16:16:10 +00:00
|
|
|
int lua_load_console;
|
2014-11-19 22:33:28 +00:00
|
|
|
|
2014-02-28 21:25:48 +00:00
|
|
|
int auto_load_scripts;
|
2013-04-10 19:06:00 +00:00
|
|
|
|
2016-09-05 19:07:34 +00:00
|
|
|
int audio_exclusive;
|
2015-10-05 16:53:02 +00:00
|
|
|
int ao_null_fallback;
|
2016-08-09 14:22:06 +00:00
|
|
|
int audio_stream_silence;
|
2016-08-09 14:26:44 +00:00
|
|
|
float audio_wait_open;
|
2013-10-01 23:15:59 +00:00
|
|
|
int force_vo;
|
2016-07-09 16:31:18 +00:00
|
|
|
float softvol_volume;
|
2017-04-26 22:21:17 +00:00
|
|
|
int rgain_mode;
|
2017-04-26 19:45:50 +00:00
|
|
|
float rgain_preamp; // Set replaygain pre-amplification
|
|
|
|
int rgain_clip; // Enable/disable clipping prevention
|
|
|
|
float rgain_fallback;
|
2016-07-09 16:31:18 +00:00
|
|
|
int softvol_mute;
|
2012-01-21 07:28:07 +00:00
|
|
|
float softvol_max;
|
2010-11-12 12:06:37 +00:00
|
|
|
int gapless_audio;
|
2013-03-04 16:40:21 +00:00
|
|
|
|
2016-08-30 21:50:57 +00:00
|
|
|
mp_vo_opts *vo;
|
2018-05-21 13:11:19 +00:00
|
|
|
struct ao_opts *ao_opts;
|
2013-03-04 16:40:21 +00:00
|
|
|
|
|
|
|
char *wintitle;
|
2014-09-02 20:28:11 +00:00
|
|
|
char *media_title;
|
2013-03-04 16:40:21 +00:00
|
|
|
|
video: redo video equalizer option handling
I really wouldn't care much about this, but some parts of the core code
are under HAVE_GPL, so there's some need to get rid of it. Simply turn
the video equalizer from its current fine-grained handling with vf/vo
fallbacks into global options. This makes updating them much simpler.
This removes any possibility of applying video equalizers in filters,
which affects vf_scale, and the previously removed vf_eq. Not a big
loss, since the preferred VOs have this builtin.
Remove video equalizer handling from vo_direct3d, vo_sdl, vo_vaapi, and
vo_xv. I'm not going to waste my time on these legacy VOs.
vo.eq_opts_cache exists _only_ to send a VOCTRL_SET_EQUALIZER, which
exists _only_ to trigger a redraw. This seems silly, but for now I feel
like this is less of a pain. The rest of the equalizer using code is
self-updating.
See commit 96b906a51d5 for how some video equalizer code was GPL only.
Some command line option names and ranges can probably be traced back to
a GPL only committer, but we don't consider these copyrightable.
2017-08-22 15:01:35 +00:00
|
|
|
struct mp_csp_equalizer_opts *video_equalizer;
|
2013-03-04 16:40:21 +00:00
|
|
|
|
2013-06-13 22:24:41 +00:00
|
|
|
int stop_screensaver;
|
2020-01-12 00:32:13 +00:00
|
|
|
int cursor_autohide_delay;
|
|
|
|
int cursor_autohide_fs;
|
2013-09-08 00:07:20 +00:00
|
|
|
|
2017-12-29 16:19:25 +00:00
|
|
|
struct mp_subtitle_opts *subs_rend;
|
sub: make filter_sdh a "proper" filter, allow runtime changes
Until now, filter_sdh was simply a function that was called by sd_ass
directly (if enabled).
I want to add another filter, so it's time to turn this into a somewhat
more general subtitle filtering infrastructure.
I pondered whether to reuse the audio/video filtering stuff - but better
not. Also, since subtitles are horrible and tend to refuse proper
abstraction, it's still messed into sd_ass, instead of working on the
dec_sub.c level. Actually mpv used to have subtitle "filters" and even
made subtitle converters part of it, but it was fairly horrible, so
don't do that again.
In addition, make runtime changes possible. Since this was supposed to
be a quick hack, I just decided to put all subtitle filter options into
a separate option group (=> simpler change notification), to manually
push the change through the playloop (like it was sort of before for OSD
options), and to recreate the sub filter chain completely in every
change. Should be good enough.
One strangeness is that due to prefetching and such, most subtitle
packets (or those some time ahead) are actually done filtering when we
change, so the user still needs to manually seek to actually refresh
everything. And since subtitle data is usually cached in ASS_Track (for
other terrible but user-friendly reasons), we also must clear the
subtitle data, but of course only on seek, since otherwise all subtitles
would just disappear. What a fucking mess, but such is life. We could
trigger a "refresh seek" to make this more automatic, but I don't feel
like it currently.
This is slightly inefficient (lots of allocations and copying), but I
decided that it doesn't matter. Could matter slightly for crazy ASS
subtitles that render with thousands of events.
Not very well tested. Still seems to work, but I didn't have many test
cases.
2020-02-16 00:02:17 +00:00
|
|
|
struct mp_sub_filter_opts *subs_filt;
|
2017-12-29 16:19:25 +00:00
|
|
|
struct mp_osd_render_opts *osd_rend;
|
|
|
|
|
2009-03-29 23:06:58 +00:00
|
|
|
int osd_level;
|
|
|
|
int osd_duration;
|
2011-04-12 15:11:12 +00:00
|
|
|
int osd_fractions;
|
2018-01-21 23:36:08 +00:00
|
|
|
int osd_on_seek;
|
2016-08-28 16:15:37 +00:00
|
|
|
int video_osd;
|
|
|
|
|
2012-07-29 22:27:50 +00:00
|
|
|
int untimed;
|
2013-05-11 20:40:46 +00:00
|
|
|
char *stream_dump;
|
2017-02-07 16:05:17 +00:00
|
|
|
char *record_file;
|
2014-10-28 18:51:44 +00:00
|
|
|
int stop_playback_on_init_failure;
|
2008-04-21 02:18:40 +00:00
|
|
|
int loop_times;
|
2014-04-17 21:55:04 +00:00
|
|
|
int loop_file;
|
2013-08-18 22:50:39 +00:00
|
|
|
int shuffle;
|
2009-04-07 23:37:27 +00:00
|
|
|
int ordered_chapters;
|
2013-12-14 20:52:37 +00:00
|
|
|
char *ordered_chapters_files;
|
2010-11-26 14:56:05 +00:00
|
|
|
int chapter_merge_threshold;
|
2013-08-14 01:25:50 +00:00
|
|
|
double chapter_seek_threshold;
|
2014-11-02 15:47:23 +00:00
|
|
|
char *chapter_file;
|
2013-11-19 21:36:33 +00:00
|
|
|
int merge_files;
|
2010-11-12 20:04:16 +00:00
|
|
|
int quiet;
|
2013-02-08 22:52:06 +00:00
|
|
|
int load_config;
|
2014-02-25 20:04:04 +00:00
|
|
|
char *force_configdir;
|
2013-03-08 01:08:02 +00:00
|
|
|
int use_filedir_conf;
|
2014-09-01 21:47:27 +00:00
|
|
|
int hls_bitrate;
|
2009-12-01 12:28:34 +00:00
|
|
|
int edition_id;
|
2010-11-13 17:27:01 +00:00
|
|
|
int initial_audio_sync;
|
2015-08-10 16:43:25 +00:00
|
|
|
int video_sync;
|
|
|
|
double sync_max_video_change;
|
|
|
|
double sync_max_audio_change;
|
2015-10-27 19:56:46 +00:00
|
|
|
double sync_audio_drop_size;
|
2010-12-14 23:09:47 +00:00
|
|
|
int hr_seek;
|
2011-11-06 14:54:57 +00:00
|
|
|
float hr_seek_demuxer_offset;
|
2014-05-07 20:01:17 +00:00
|
|
|
int hr_seek_framedrop;
|
2013-03-08 01:08:02 +00:00
|
|
|
float audio_delay;
|
|
|
|
float default_max_pts_correction;
|
2010-11-12 20:04:16 +00:00
|
|
|
int autosync;
|
2012-09-17 06:38:19 +00:00
|
|
|
int frame_dropping;
|
2018-03-02 14:37:34 +00:00
|
|
|
int video_latency_hacks;
|
2010-11-13 21:10:58 +00:00
|
|
|
int term_osd;
|
2014-01-15 15:14:37 +00:00
|
|
|
int term_osd_bar;
|
|
|
|
char *term_osd_bar_chars;
|
2010-11-13 21:10:58 +00:00
|
|
|
char *playing_msg;
|
2014-09-01 22:09:03 +00:00
|
|
|
char *osd_playing_msg;
|
2012-10-02 01:12:09 +00:00
|
|
|
char *status_msg;
|
2013-02-16 21:14:33 +00:00
|
|
|
char *osd_status_msg;
|
2014-09-17 23:19:27 +00:00
|
|
|
char *osd_msg[3];
|
2010-11-13 21:10:58 +00:00
|
|
|
int player_idle_mode;
|
|
|
|
int consolecontrols;
|
2015-08-22 20:08:17 +00:00
|
|
|
int playlist_pos;
|
2012-11-15 17:49:17 +00:00
|
|
|
struct m_rel_time play_start;
|
|
|
|
struct m_rel_time play_end;
|
|
|
|
struct m_rel_time play_length;
|
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-11-16 21:47:17 +00:00
|
|
|
int rebase_start_time;
|
2013-03-08 01:08:02 +00:00
|
|
|
int play_frames;
|
2014-11-17 23:09:42 +00:00
|
|
|
double ab_loop[2];
|
2020-02-08 13:57:45 +00:00
|
|
|
int ab_loop_count;
|
2013-03-08 01:08:02 +00:00
|
|
|
double step_sec;
|
core: add playback resume feature (manual/opt-in)
A "watch later" command is now mapped to Shift+Q. This quits the player
and stores the playback state in a config file in ~/.mpv/watch_later/.
When calling the player with the same file again, playback is resumed
at that time position.
It's also possible to make mpv save playback state always on quit with
the --save-position-on-quit option. Likewise, resuming can be disabled
with the --no-resume-playback option.
This also attempts to save some playback parameters, like fullscreen
state or track selection. This will unconditionally override config
settings and command line options (which is probably not what you would
expect, but in general nobody will really care about this). Some things
are not backed up, because that would cause various problems. Additional
subtitle files, video filters, etc. are not stored because that would be
too hard and fragile. Volume/mute state are not stored because it would
mess up if the system mixer is used, or if the system mixer was
readjusted in the meantime.
Basically, the tradeoff between perfect state restoration and
complexity/fragility makes it not worth to attempt to implement
it perfectly, even if the result is a little bit inconsistent.
2013-05-05 17:37:29 +00:00
|
|
|
int position_resume;
|
player: Optionally validate st_mtime when restoring playback state
I often watch sporting events. On many occasions I get files with the
same filename for each session. For example, for F1 I might have the
following directory structure:
F1/
FP1.mkv
FP2.mkv
FP3.mkv
Qualification.mkv
Race.mkv
Since usually one simply watches one race after the other, I usually
just rsync the new event's files over the old ones, so, for example,
Race.mkv will be replaced from the file for the last event with the file
from the new event.
One problem with this is that I like to use --resume-playback for other
kinds of media, so I have it on by default. That works great for, say, a
movie, but doesn't work so well with this scheme, because you can
trivially forget to pass --no-resume-playback on the command line and
end up 2 hours in, watching spoilers as the race results scroll down the
screen :-)
This patch adds a new option, --resume-playback-check-mtime, which
validates that the file's mtime hasn't changed since the watch_later
configuration was saved. It does this by setting the watch_later
configuration to have the same mtime as the file after it is saved.
Switching back and forth between checking mtime and not checking mtime
works fine, as we only choose whether to compare based on it, but we
update the watch_later configuration mtime regardless of its value.
2019-11-09 18:24:16 +00:00
|
|
|
int position_check_mtime;
|
core: add playback resume feature (manual/opt-in)
A "watch later" command is now mapped to Shift+Q. This quits the player
and stores the playback state in a config file in ~/.mpv/watch_later/.
When calling the player with the same file again, playback is resumed
at that time position.
It's also possible to make mpv save playback state always on quit with
the --save-position-on-quit option. Likewise, resuming can be disabled
with the --no-resume-playback option.
This also attempts to save some playback parameters, like fullscreen
state or track selection. This will unconditionally override config
settings and command line options (which is probably not what you would
expect, but in general nobody will really care about this). Some things
are not backed up, because that would cause various problems. Additional
subtitle files, video filters, etc. are not stored because that would be
too hard and fragile. Volume/mute state are not stored because it would
mess up if the system mixer is used, or if the system mixer was
readjusted in the meantime.
Basically, the tradeoff between perfect state restoration and
complexity/fragility makes it not worth to attempt to implement
it perfectly, even if the result is a little bit inconsistent.
2013-05-05 17:37:29 +00:00
|
|
|
int position_save_on_quit;
|
2014-06-01 16:25:21 +00:00
|
|
|
int write_filename_in_watch_later_config;
|
2014-12-12 22:57:49 +00:00
|
|
|
int ignore_path_in_watch_later_config;
|
2016-09-08 14:50:39 +00:00
|
|
|
char *watch_later_directory;
|
2013-04-25 18:38:22 +00:00
|
|
|
int pause;
|
core: add --keep-open, which doesn't close the file on EOF
The --keep-open option causes mpv not to close the current file.
Instead, it will pause, and allow the user to seek around. When
seeking beyond the end of the file, mpv does a precise seek back to
the previous last known position that produced video output.
In some corner cases, mpv might not be able to produce video output at
all, despite having created a VO. (Possibly when only 1 frame could be
decoded, but the video filter chain queues frames. Then a VO would be
created, without sending an actual video frame to the VO.) In these
cases, the VO window will not redraw, not even OSD.
Based on a patch by coax [1].
[1] http://devel.mplayer2.org/ticket/210#comment:4
2012-11-12 23:56:20 +00:00
|
|
|
int keep_open;
|
2017-03-27 09:34:02 +00:00
|
|
|
int keep_open_pause;
|
2016-08-17 20:45:44 +00:00
|
|
|
double image_display_duration;
|
2016-02-05 22:19:56 +00:00
|
|
|
char *lavfi_complex;
|
2015-05-22 19:00:24 +00:00
|
|
|
int stream_id[2][STREAM_TYPE_COUNT];
|
|
|
|
char **stream_lang[STREAM_TYPE_COUNT];
|
2017-08-12 21:43:05 +00:00
|
|
|
int stream_auto_sel;
|
2012-12-10 17:52:06 +00:00
|
|
|
int audio_display;
|
2014-12-29 21:51:18 +00:00
|
|
|
char **display_tags;
|
2013-04-28 23:49:20 +00:00
|
|
|
|
2014-06-17 23:40:20 +00:00
|
|
|
char **audio_files;
|
2010-11-11 14:24:17 +00:00
|
|
|
char *demuxer_name;
|
2014-07-16 20:40:21 +00:00
|
|
|
int demuxer_thread;
|
player: make playback termination asynchronous
Until now, stopping playback aborted the demuxer and I/O layer violently
by signaling mp_cancel (bound to libavformat's AVIOInterruptCB
mechanism). Change it to try closing them gracefully.
The main purpose is to silence those libavformat errors that happen when
you request termination. Most of libavformat barely cares about the
termination mechanism (AVIOInterruptCB), and essentially it's like the
network connection is abruptly severed, or file I/O suddenly returns I/O
errors. There were issues with dumb TLS warnings, parsers complaining
about incomplete data, and some special protocols that require server
communication to gracefully disconnect.
We still want to abort it forcefully if it refuses to terminate on its
own, so a timeout is required. Users can set the timeout to 0, which
should give them the old behavior.
This also removes the old mechanism that treats certain commands (like
"quit") specially, and tries to terminate the demuxers even if the core
is currently frozen. This is for situations where the core synchronized
to the demuxer or stream layer while network is unresponsive. This in
turn can only happen due to the "program" or "cache-size" properties in
the current code (see one of the previous commits). Also, the old
mechanism doesn't fit particularly well with the new one. We wouldn't
want to abort playback immediately on a "quit" command - the new code is
all about giving it a chance to end it gracefully. We'd need some sort
of watchdog thread or something equally complicated to handle this. So
just remove it.
The change in osd.c is to prevent that it clears the status line while
waiting for termination. The normal status line code doesn't output
anything useful at this point, and the code path taken clears it, both
of which is an annoying behavior change, so just let it show the old
one.
2018-05-19 16:41:13 +00:00
|
|
|
double demux_termination_timeout;
|
2019-05-16 14:29:45 +00:00
|
|
|
int demuxer_cache_wait;
|
2017-01-18 18:02:50 +00:00
|
|
|
int prefetch_open;
|
2010-11-11 14:24:17 +00:00
|
|
|
char *audio_demuxer_name;
|
|
|
|
char *sub_demuxer_name;
|
|
|
|
|
2018-01-03 20:50:04 +00:00
|
|
|
int cache_pause;
|
2018-01-03 20:48:42 +00:00
|
|
|
int cache_pause_initial;
|
2018-01-03 20:28:28 +00:00
|
|
|
float cache_pause_wait;
|
player: redo how stream caching and pausing on low cache works
Add the --cache-secs option, which literally overrides the value of
--demuxer-readahead-secs if the stream cache is active. The default
value is very high (10 seconds), which means it can act as network
cache.
Remove the old behavior of trying to pause once the byte cache runs
low. Instead, do something similar wit the demuxer cache. The nice
thing is that we can guess how many seconds of video it has cached,
and we can make better decisions. But for now, apply a relatively
naive heuristic: if the cache is below 0.5 secs, pause, and wait
until at least 2 secs are available.
Note that due to timestamp reordering, the estimated cached duration
of video might be inaccurate, depending on the file format. If the
file format has DTS, it's easy, otherwise the duration will seemingly
jump back and forth.
2014-08-26 23:13:20 +00:00
|
|
|
|
2012-08-06 15:48:30 +00:00
|
|
|
struct image_writer_opts *screenshot_image_opts;
|
screenshot: make screenshot filenames configurable
This adds the --screenshot-template option, which specifies a template
for the filename used for a screenshot. The '%' character is parsed as
format specifier. These format specifiers insert metadata into the
filename. For example, '%f' is replaced with the filename of the
currently played file.
The following format specifiers are available:
%n Insert sequence number (padded with 4 zeros), e.g. "0002".
%0Nn Like %n, but pad to N zeros (N = 0 to 9).
%n behaves like %04n.
%#n Like %n, but reset the sequence counter on every screenshot.
(Useful if other parts in the template make the resulting
filename already mostly unique.)
%#0Nn Use %0Nn and %#n at the same time.
%f Insert filename of the currently played video.
%F Like %f, but with stripped file extension ("." and rest).
%p Insert current playback time, in HH:MM:SS format.
%P Like %p, but adds milliseconds: HH:MM:SS.mmmm
%tX Insert the current local date/time, using the date format X.
X is a single letter and is passed to strftime() as "%X".
E.g. "%td" inserts the number of the current day.
%{prop} Insert the value of the slave property 'prop'.
E.g. %{filename} is the same as %f. If the property doesn't
exist or is not available, nothing is inserted, unless a
fallback is specified as in %{prop:fallback text}.
%% Insert the character '%'.
The strings inserted by format specifiers will be checked for
characters not allowed in filenames (including '/' and '\'), and
replaced with the placeholder '_'. (This doesn't happen for text that
was passed with the --screenshot-template option, and allows specifying
a screenshot target directory by prefixing the template with a relative
or absolute path.)
2012-02-29 02:46:25 +00:00
|
|
|
char *screenshot_template;
|
2015-05-03 12:44:42 +00:00
|
|
|
char *screenshot_directory;
|
2011-10-06 18:46:02 +00:00
|
|
|
|
2014-06-13 00:05:37 +00:00
|
|
|
int index_mode;
|
2013-03-08 01:08:02 +00:00
|
|
|
|
2016-08-04 18:49:20 +00:00
|
|
|
struct m_channels audio_output_channels;
|
2010-10-31 05:26:40 +00:00
|
|
|
int audio_output_format;
|
2013-03-08 01:08:02 +00:00
|
|
|
int force_srate;
|
2013-08-04 21:56:20 +00:00
|
|
|
double playback_speed;
|
2014-10-02 00:58:52 +00:00
|
|
|
int pitch_correction;
|
2013-11-30 23:12:10 +00:00
|
|
|
struct m_obj_settings *vf_settings, *vf_defs;
|
|
|
|
struct m_obj_settings *af_settings, *af_defs;
|
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 filter_opts *filter_opts;
|
2020-02-29 23:28:09 +00:00
|
|
|
struct dec_wrapper_opts *dec_wrapper;
|
2011-02-07 23:35:51 +00:00
|
|
|
char **sub_name;
|
2011-03-03 10:31:12 +00:00
|
|
|
char **sub_paths;
|
2015-12-25 12:17:11 +00:00
|
|
|
char **audiofile_paths;
|
2016-02-08 20:18:35 +00:00
|
|
|
char **external_files;
|
2016-08-10 20:22:50 +00:00
|
|
|
int autoload_files;
|
2011-02-07 23:35:51 +00:00
|
|
|
int sub_auto;
|
2015-02-02 20:23:12 +00:00
|
|
|
int audiofile_auto;
|
2013-02-16 20:17:59 +00:00
|
|
|
int osd_bar_visible;
|
2012-12-11 17:16:42 +00:00
|
|
|
|
2014-06-11 22:34:20 +00:00
|
|
|
int w32_priority;
|
|
|
|
|
2014-06-10 18:46:15 +00:00
|
|
|
struct cdda_params *stream_cdda_opts;
|
2014-06-10 19:44:50 +00:00
|
|
|
struct dvb_params *stream_dvb_opts;
|
2014-07-29 23:15:42 +00:00
|
|
|
struct stream_lavf_params *stream_lavf_opts;
|
2014-06-10 18:46:15 +00:00
|
|
|
|
|
|
|
char *cdrom_device;
|
2014-07-14 23:49:02 +00:00
|
|
|
char *bluray_device;
|
2014-06-09 21:54:45 +00:00
|
|
|
|
2014-06-10 20:48:11 +00:00
|
|
|
double mf_fps;
|
|
|
|
char *mf_type;
|
|
|
|
|
2014-06-10 21:06:42 +00:00
|
|
|
struct demux_rawaudio_opts *demux_rawaudio;
|
|
|
|
struct demux_rawvideo_opts *demux_rawvideo;
|
2014-06-10 23:46:20 +00:00
|
|
|
struct demux_lavf_opts *demux_lavf;
|
2015-04-23 17:21:17 +00:00
|
|
|
struct demux_mkv_opts *demux_mkv;
|
2019-04-07 13:10:52 +00:00
|
|
|
struct demux_cue_opts *demux_cue;
|
2014-06-10 21:06:42 +00:00
|
|
|
|
2016-09-06 18:09:56 +00:00
|
|
|
struct demux_opts *demux_opts;
|
demux: add a on-disk cache
Somewhat similar to the old --cache-file, except for the demuxer cache.
Instead of keeping packet data in memory, it's written to disk and read
back when needed.
The idea is to reduce main memory usage, while allowing fast seeking in
large cached network streams (especially live streams). Keeping the
packet metadata on disk would be rather hard (would use mmap or so, or
rewrite the entire demux.c packet queue handling), and since it's
relatively small, just keep it in memory.
Also for simplicity, the disk cache is append-only. If you're watching
really long livestreams, and need pruning, you're probably out of luck.
This still could be improved by trying to free unused blocks with
fallocate(), but since we're writing multiple streams in an interleaved
manner, this is slightly hard.
Some rather gross ugliness in packet.h: we want to store the file
position of the cached data somewhere, but on 32 bit architectures, we
don't have any usable 64 bit members for this, just the buf/len fields,
which add up to 64 bit - so the shitty union aliases this memory.
Error paths untested. Side data (the complicated part of trying to
serialize ffmpeg packets) untested.
Stream recording had to be adjusted. Some minor details change due to
this, but probably nothing important.
The change in attempt_range_joining() is because packets in cache
have no valid len field. It was a useful check (heuristically
finding broken cases), but not a necessary one.
Various other approaches were tried. It would be interesting to list
them and to mention the pros and cons, but I don't feel like it.
2019-06-13 17:10:32 +00:00
|
|
|
struct demux_cache_opts *demux_cache_opts;
|
stream: turn into a ring buffer, make size configurable
In some corner cases (see #6802), it can be beneficial to use a larger
stream buffer size. Use this as argument to rewrite everything for no
reason.
Turn stream.c itself into a ring buffer, with configurable size. The
latter would have been easily achievable with minimal changes, and the
ring buffer is the hard part. There is no reason to have a ring buffer
at all, except possibly if ffmpeg don't fix their awful mp4 demuxer, and
some subtle issues with demux_mkv.c wanting to seek back by small
offsets (the latter was handled with small stream_peek() calls, which
are unneeded now).
In addition, this turns small forward seeks into reads (where data is
simply skipped). Before this commit, only stream_skip() did this (which
also mean that stream_skip() simply calls stream_seek() now).
Replace all stream_peek() calls with something else (usually
stream_read_peek()). The function was a problem, because it returned a
pointer to the internal buffer, which is now a ring buffer with
wrapping. The new function just copies the data into a buffer, and in
some cases requires callers to dynamically allocate memory. (The most
common case, demux_lavf.c, required a separate buffer allocation anyway
due to FFmpeg "idiosyncrasies".) This is the bulk of the demuxer_*
changes.
I'm not happy with this. There still isn't a good reason why there
should be a ring buffer, that is complex, and most of the time just
wastes half of the available memory. Maybe another rewrite soon.
It also contains bugs; you're an alpha tester now.
2019-11-06 20:36:02 +00:00
|
|
|
struct stream_opts *stream_opts;
|
2016-09-06 18:09:56 +00:00
|
|
|
|
2014-06-10 23:35:39 +00:00
|
|
|
struct vd_lavc_params *vd_lavc_params;
|
2014-06-10 23:39:51 +00:00
|
|
|
struct ad_lavc_params *ad_lavc_params;
|
2013-03-31 02:24:53 +00:00
|
|
|
|
2014-06-10 23:54:03 +00:00
|
|
|
struct input_opts *input_opts;
|
2012-09-14 15:51:26 +00:00
|
|
|
|
2014-06-11 00:04:02 +00:00
|
|
|
// may be NULL if encoding is not compiled-in
|
|
|
|
struct encode_opts *encode_opts;
|
2014-10-16 09:48:18 +00:00
|
|
|
|
|
|
|
char *ipc_path;
|
2020-04-08 23:05:51 +00:00
|
|
|
char *ipc_client;
|
2016-09-02 13:59:40 +00:00
|
|
|
|
2017-01-20 13:02:17 +00:00
|
|
|
int wingl_dwm_flush;
|
|
|
|
|
2018-01-12 03:02:55 +00:00
|
|
|
struct mp_resample_opts *resample_opts;
|
|
|
|
|
2016-09-02 13:59:40 +00:00
|
|
|
struct gl_video_opts *gl_video_opts;
|
2017-01-20 12:38:28 +00:00
|
|
|
struct angle_opts *angle_opts;
|
vo_opengl: refactor into vo_gpu
This is done in several steps:
1. refactor MPGLContext -> struct ra_ctx
2. move GL-specific stuff in vo_opengl into opengl/context.c
3. generalize context creation to support other APIs, and add --gpu-api
4. rename all of the --opengl- options that are no longer opengl-specific
5. move all of the stuff from opengl/* that isn't GL-specific into gpu/
(note: opengl/gl_utils.h became opengl/utils.h)
6. rename vo_opengl to vo_gpu
7. to handle window screenshots, the short-term approach was to just add
it to ra_swchain_fns. Long term (and for vulkan) this has to be moved to
ra itself (and vo_gpu altered to compensate), but this was a stop-gap
measure to prevent this commit from getting too big
8. move ra->fns->flush to ra_gl_ctx instead
9. some other minor changes that I've probably already forgotten
Note: This is one half of a major refactor, the other half of which is
provided by rossy's following commit. This commit enables support for
all linux platforms, while his version enables support for all non-linux
platforms.
Note 2: vo_opengl_cb.c also re-uses ra_gl_ctx so it benefits from the
--opengl- options like --opengl-early-flush, --opengl-finish etc. Should
be a strict superset of the old functionality.
Disclaimer: Since I have no way of compiling mpv on all platforms, some
of these ports were done blindly. Specifically, the blind ports included
context_mali_fbdev.c and context_rpi.c. Since they're both based on
egl_helpers, the port should have gone smoothly without any major
changes required. But if somebody complains about a compile error on
those platforms (assuming anybody actually uses them), you know where to
complain.
2017-09-14 06:04:55 +00:00
|
|
|
struct opengl_opts *opengl_opts;
|
vo_gpu: vulkan: initial implementation
This time based on ra/vo_gpu. 2017 is the year of the vulkan desktop!
Current problems / limitations / improvement opportunities:
1. The swapchain/flipping code violates the vulkan spec, by assuming
that the presentation queue will be bounded (in cases where rendering
is significantly faster than vsync). But apparently, there's simply
no better way to do this right now, to the point where even the
stupid cube.c examples from LunarG etc. do it wrong.
(cf. https://github.com/KhronosGroup/Vulkan-Docs/issues/370)
2. The memory allocator could be improved. (This is a universal
constant)
3. Could explore using push descriptors instead of descriptor sets,
especially since we expect to switch descriptors semi-often for some
passes (like interpolation). Probably won't make a difference, but
the synchronization overhead might be a factor. Who knows.
4. Parallelism across frames / async transfer is not well-defined, we
either need to use a better semaphore / command buffer strategy or a
resource pooling layer to safely handle cross-frame parallelism.
(That said, I gave resource pooling a try and was not happy with the
result at all - so I'm still exploring the semaphore strategy)
5. We aggressively use pipeline barriers where events would offer a much
more fine-grained synchronization mechanism. As a result of this, we
might be suffering from GPU bubbles due to too-short dependencies on
objects. (That said, I'm also exploring the use of semaphores as a an
ordering tactic which would allow cross-frame time slicing in theory)
Some minor changes to the vo_gpu and infrastructure, but nothing
consequential.
NOTE: For safety, all use of asynchronous commands / multiple command
pools is currently disabled completely. There are some left-over relics
of this in the code (e.g. the distinction between dev_poll and
pool_poll), but that is kept in place mostly because this will be
re-extended in the future (vulkan rev 2).
The queue count is also currently capped to 1, because of the lack of
cross-frame semaphores means we need the implicit synchronization from
the same-queue semantics to guarantee a correct result.
2016-09-14 18:54:18 +00:00
|
|
|
struct vulkan_opts *vulkan_opts;
|
2017-09-13 01:09:48 +00:00
|
|
|
struct spirv_opts *spirv_opts;
|
vo_gpu: d3d11: initial implementation
This is a new RA/vo_gpu backend that uses Direct3D 11. The GLSL
generated by vo_gpu is cross-compiled to HLSL with SPIRV-Cross.
What works:
- All of mpv's internal shaders should work, including compute shaders.
- Some external shaders have been tested and work, including RAVU and
adaptive-sharpen.
- Non-dumb mode works, even on very old hardware. Most features work at
feature level 9_3 and all features work at feature level 10_0. Some
features also work at feature level 9_1 and 9_2, but without high-bit-
depth FBOs, it's not very useful. (Hardware this old is probably not
fast enough for advanced features anyway.)
Note: This is more compatible than ANGLE, which requires 9_3 to work
at all (GLES 2.0,) and 10_1 for non-dumb-mode (GLES 3.0.)
- Hardware decoding with D3D11VA, including decoding of 10-bit formats
without truncation to 8-bit.
What doesn't work / can be improved:
- PBO upload and direct rendering does not work yet. Direct rendering
requires persistent-mapped PBOs because the decoder needs to be able
to read data from images that have already been decoded and uploaded.
Unfortunately, it seems like persistent-mapped PBOs are fundamentally
incompatible with D3D11, which requires all resources to use driver-
managed memory and requires memory to be unmapped (and hence pointers
to be invalidated) when a resource is used in a draw or copy
operation.
However it might be possible to use D3D11's limited multithreading
capabilities to emulate some features of PBOs, like asynchronous
texture uploading.
- The blit() and clear() operations don't have equivalents in the D3D11
API that handle all cases, so in most cases, they have to be emulated
with a shader. This is currently done inside ra_d3d11, but ideally it
would be done in generic code, so it can take advantage of mpv's
shader generation utilities.
- SPIRV-Cross is used through a NIH C-compatible wrapper library, since
it does not expose a C interface itself.
The library is available here: https://github.com/rossy/crossc
- The D3D11 context could be made to support more modern DXGI features
in future. For example, it should be possible to add support for
high-bit-depth and HDR output with DXGI 1.5/1.6.
2017-09-07 10:18:06 +00:00
|
|
|
struct d3d11_opts *d3d11_opts;
|
2017-11-01 11:38:41 +00:00
|
|
|
struct d3d11va_opts *d3d11va_opts;
|
2017-02-20 19:34:57 +00:00
|
|
|
struct cocoa_opts *cocoa_opts;
|
2018-02-16 12:07:15 +00:00
|
|
|
struct macos_opts *macos_opts;
|
2017-12-25 15:04:09 +00:00
|
|
|
struct android_opts *android_opts;
|
2019-10-14 17:16:42 +00:00
|
|
|
struct wayland_opts *wayland_opts;
|
2016-09-08 19:46:48 +00:00
|
|
|
struct dvd_opts *dvd_opts;
|
2018-03-29 21:23:27 +00:00
|
|
|
struct vaapi_opts *vaapi_opts;
|
2019-10-31 14:18:57 +00:00
|
|
|
struct sws_opts *sws_opts;
|
|
|
|
struct zimg_opts *zimg_opts;
|
2017-05-29 16:48:10 +00:00
|
|
|
|
|
|
|
int cuda_device;
|
2008-03-31 03:19:29 +00:00
|
|
|
} MPOpts;
|
|
|
|
|
2016-09-08 19:46:48 +00:00
|
|
|
struct dvd_opts {
|
|
|
|
int angle;
|
|
|
|
int speed;
|
|
|
|
char *device;
|
|
|
|
};
|
|
|
|
|
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 filter_opts {
|
|
|
|
int deinterlace;
|
|
|
|
};
|
|
|
|
|
2016-09-02 13:50:54 +00:00
|
|
|
extern const struct m_sub_options vo_sub_opts;
|
2016-09-08 19:46:48 +00:00
|
|
|
extern const struct m_sub_options dvd_conf;
|
2017-12-29 16:19:25 +00:00
|
|
|
extern const struct m_sub_options mp_subtitle_sub_opts;
|
sub: make filter_sdh a "proper" filter, allow runtime changes
Until now, filter_sdh was simply a function that was called by sd_ass
directly (if enabled).
I want to add another filter, so it's time to turn this into a somewhat
more general subtitle filtering infrastructure.
I pondered whether to reuse the audio/video filtering stuff - but better
not. Also, since subtitles are horrible and tend to refuse proper
abstraction, it's still messed into sd_ass, instead of working on the
dec_sub.c level. Actually mpv used to have subtitle "filters" and even
made subtitle converters part of it, but it was fairly horrible, so
don't do that again.
In addition, make runtime changes possible. Since this was supposed to
be a quick hack, I just decided to put all subtitle filter options into
a separate option group (=> simpler change notification), to manually
push the change through the playloop (like it was sort of before for OSD
options), and to recreate the sub filter chain completely in every
change. Should be good enough.
One strangeness is that due to prefetching and such, most subtitle
packets (or those some time ahead) are actually done filtering when we
change, so the user still needs to manually seek to actually refresh
everything. And since subtitle data is usually cached in ASS_Track (for
other terrible but user-friendly reasons), we also must clear the
subtitle data, but of course only on seek, since otherwise all subtitles
would just disappear. What a fucking mess, but such is life. We could
trigger a "refresh seek" to make this more automatic, but I don't feel
like it currently.
This is slightly inefficient (lots of allocations and copying), but I
decided that it doesn't matter. Could matter slightly for crazy ASS
subtitles that render with thousands of events.
Not very well tested. Still seems to work, but I didn't have many test
cases.
2020-02-16 00:02:17 +00:00
|
|
|
extern const struct m_sub_options mp_sub_filter_opts;
|
2017-12-29 16:19:25 +00:00
|
|
|
extern const struct m_sub_options mp_osd_render_sub_opts;
|
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
|
|
|
extern const struct m_sub_options filter_conf;
|
2018-01-18 13:44:20 +00:00
|
|
|
extern const struct m_sub_options resample_conf;
|
stream: turn into a ring buffer, make size configurable
In some corner cases (see #6802), it can be beneficial to use a larger
stream buffer size. Use this as argument to rewrite everything for no
reason.
Turn stream.c itself into a ring buffer, with configurable size. The
latter would have been easily achievable with minimal changes, and the
ring buffer is the hard part. There is no reason to have a ring buffer
at all, except possibly if ffmpeg don't fix their awful mp4 demuxer, and
some subtle issues with demux_mkv.c wanting to seek back by small
offsets (the latter was handled with small stream_peek() calls, which
are unneeded now).
In addition, this turns small forward seeks into reads (where data is
simply skipped). Before this commit, only stream_skip() did this (which
also mean that stream_skip() simply calls stream_seek() now).
Replace all stream_peek() calls with something else (usually
stream_read_peek()). The function was a problem, because it returned a
pointer to the internal buffer, which is now a ring buffer with
wrapping. The new function just copies the data into a buffer, and in
some cases requires callers to dynamically allocate memory. (The most
common case, demux_lavf.c, required a separate buffer allocation anyway
due to FFmpeg "idiosyncrasies".) This is the bulk of the demuxer_*
changes.
I'm not happy with this. There still isn't a good reason why there
should be a ring buffer, that is complex, and most of the time just
wastes half of the available memory. Maybe another rewrite soon.
It also contains bugs; you're an alpha tester now.
2019-11-06 20:36:02 +00:00
|
|
|
extern const struct m_sub_options stream_conf;
|
2020-02-29 23:28:09 +00:00
|
|
|
extern const struct m_sub_options dec_wrapper_conf;
|
2019-11-28 23:16:52 +00:00
|
|
|
extern const struct m_sub_options mp_opt_root;
|
2013-06-07 20:57:00 +00:00
|
|
|
|
2008-03-31 03:19:29 +00:00
|
|
|
#endif
|