Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c9f10e0d1 | ||
|
|
5b0d06ca74 | ||
|
|
a410451463 | ||
|
|
3152eed6d8 | ||
|
|
02260882ce | ||
|
|
cd5f0a8612 | ||
|
|
23959eb5b4 | ||
|
|
21a95f5ed9 | ||
|
|
6dc2a23cda | ||
|
|
f94318babc | ||
|
|
b476d21d0a | ||
|
|
16c7de4aab | ||
|
|
8fdd688d48 | ||
|
|
63304b95a1 | ||
|
|
f4263a811f | ||
|
|
a6bf8e7c36 | ||
|
|
6488e77d8a | ||
|
|
34a856f465 | ||
|
|
db218a8d25 | ||
|
|
e3064c3cb7 | ||
|
|
df4d15be7b | ||
|
|
cb5adf4d72 | ||
|
|
440ba33639 | ||
|
|
e4eb9c5469 | ||
|
|
4387919753 | ||
|
|
94123474a4 | ||
|
|
50a7aac4d7 | ||
|
|
2051243a0f | ||
|
|
a21d09d9f8 | ||
|
|
b95a0bfa77 | ||
|
|
43f831b6ba | ||
|
|
b3eba216b7 | ||
|
|
0668c82da5 | ||
|
|
c1e8f3b479 | ||
|
|
64a45f972c | ||
|
|
d4207c64e6 | ||
|
|
abf1fc9a77 | ||
|
|
da8e573b45 | ||
|
|
25c0097c67 | ||
|
|
20d5efb419 | ||
|
|
a18b4b2b19 | ||
|
|
a468e2869d | ||
|
|
cb9975b942 |
No files matched your search
+3
-3
@@ -565,9 +565,9 @@ Available filters are:
|
||||
Scale tempo in sync with speed (default).
|
||||
pitch
|
||||
Reverses effect of filter. Scales pitch without altering tempo.
|
||||
Add ``[ speed_mult 0.9438743126816935`` and ``] speed_mult
|
||||
1.059463094352953`` to your ``input.conf`` to step by musical
|
||||
semi-tones.
|
||||
Add ``[ multiply speed 0.9438743126816935`` and
|
||||
``] multiply speed 1.059463094352953`` to your ``input.conf``
|
||||
to step by musical semi-tones.
|
||||
|
||||
.. warning::
|
||||
|
||||
|
||||
+2
-3
@@ -618,9 +618,8 @@ Input Commands that are Possibly Subject to Change
|
||||
unseekable streams that are going out of sync.
|
||||
This command might be changed or removed in the future.
|
||||
|
||||
Undocumented commands: ``tv_last_channel`` (TV/DVB only), ``get_property`` (?),
|
||||
``ao_reload`` (experimental/internal).
|
||||
|
||||
Undocumented commands: ``tv_last_channel`` (TV/DVB only),
|
||||
``get_property`` (deprecated), ``ao_reload`` (experimental/internal).
|
||||
|
||||
Hooks
|
||||
~~~~~
|
||||
|
||||
@@ -107,12 +107,17 @@ Playback Control
|
||||
If ``--audio-pitch-correction`` is used, playing with a speed higher than
|
||||
normal automatically inserts the ``scaletempo`` audio filter.
|
||||
|
||||
``--loop=<N|inf|no>``
|
||||
``--loop=<N|inf|force|no>``
|
||||
Loops playback ``N`` times. A value of ``1`` plays it one time (default),
|
||||
``2`` two times, etc. ``inf`` means forever. ``no`` is the same as ``1`` and
|
||||
disables looping. If several files are specified on command line, the
|
||||
entire playlist is looped.
|
||||
|
||||
The ``force`` mode is like ``inf``, but does not skip playlist entries
|
||||
which have been marked as failing. This means the player might waste CPU
|
||||
time trying to loop a file that doesn't exist. But it might be useful for
|
||||
playing webradios under very bad network conditions.
|
||||
|
||||
``--pause``
|
||||
Start the player in paused state.
|
||||
|
||||
|
||||
+3
-4
@@ -301,10 +301,6 @@ Available filters are:
|
||||
``uniform``
|
||||
uniform noise (Gaussian otherwise)
|
||||
|
||||
``hq``
|
||||
high quality (slightly better looking, slightly slower) - not available
|
||||
when using libavfilter
|
||||
|
||||
``hqdn3d[=luma_spatial:chroma_spatial:luma_tmp:chroma_tmp]``
|
||||
This filter aims to reduce image noise producing smooth images and making
|
||||
still images really still (This should enhance compressibility.).
|
||||
@@ -653,6 +649,9 @@ Available filters are:
|
||||
|
||||
Useful for some filters which insist on having a FPS.
|
||||
|
||||
``display_fps``
|
||||
Refresh rate of the current display. Note that this value can be 0.
|
||||
|
||||
``vapoursynth-lazy``
|
||||
The same as ``vapoursynth``, but doesn't load Python scripts. Instead, a
|
||||
custom backend using Lua and the raw VapourSynth API is used. The syntax
|
||||
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
Release 0.8.0
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
Changes that may break users' config files have been annotated with a `(!)`.
|
||||
|
||||
- `(!)` vo_opengl_old has been removed. OpenGL rendering now requires hardware
|
||||
that can do at least OpenGL 2.1, the oldest version supported by vo_opengl.
|
||||
- `(!)` vf_pp has been removed. A version of it can still be accessed through
|
||||
lavfilter (e.g. --vf=lavfi=[pp...]), but it receives no QP information.
|
||||
Also, vf_dlopen no longer passes QP information to its loaded plugin either
|
||||
(it's always 0).
|
||||
- `(!)` vf_softpulldown, vf_swapuv, vf_phase, vf_divtc and vf_ilpack have all
|
||||
been removed. Ports or alternative versions of these filters are available
|
||||
through libavfilter (vf_lavfi).
|
||||
- vf_pullup and vf_noise now are simply wrappers to their libavfilter
|
||||
equivalents. Both are only currently available on FFmpeg (not Libav).
|
||||
- `(!)` ao_portaudio has been removed. There is good support for the native
|
||||
audio drivers of all major desktop platforms, as well as ao_sdl and
|
||||
ao_openal as fallbacks.
|
||||
- `(!)` vo_opengl's `lscale` suboption has been renamed to `scale`; `lradius`
|
||||
is now `scale-radius`, `lparam1` and `lparam2` are now respectively
|
||||
`scale-param1` and `scale-param2`; `lscale-down` is now `scale-down`.
|
||||
The `cscale` suboption remains as is.
|
||||
- `(!)` Several of the `vo_opengl` radius-preset aliases supported by `scale`
|
||||
have been removed; use `scale-radius` to set if needed. For example, use
|
||||
`--vo=opengl:scale=lanczos:scale-radius=2` instead of `scale=lanczos2`.
|
||||
The default radius is recommended for most filters.
|
||||
- `(!)` vo_opengl no longer supports the `stereo` suboption. The anaglyph
|
||||
effect can be reproduced with the stereo3d filter. The quadbuffer support,
|
||||
which requires expensive specialized hardware to begin with, is removed.
|
||||
- `(!)` The `approx-gamma` suboption to vo_opengl has been removed. The
|
||||
BT.1886 specification says that it's actually how it's supposed to be done
|
||||
so it is now the default when `srgb` or `icc-profile` are enabled. This does
|
||||
not include BT.1886's gamma drop.
|
||||
- `(!)` The `no-scale-sep` and `indirect` suboptions to vo_opengl have been
|
||||
removed. These are now autodetected and enabled whenever they would have
|
||||
benefit.
|
||||
- `(!)` The `--lua` and `--lua-opts` parameters / options are now called
|
||||
`--script` and `--script-opts`, respectively. The `lua` subdir of the mpv
|
||||
config dir is also now expected to be called `scripts` instead.
|
||||
- `(!)` The `--fixed-vo` option has been removed. It has been the default for
|
||||
a long time anyway, and disabling fixed-vo is not useful.
|
||||
- vo_opengl_hq has been updated to take into account new features.
|
||||
`fancy-downscaling` and `sigmoid-upscaling` are enabled,
|
||||
"mitchell" is now the default for `scale-down`.
|
||||
- The `sub-visibility` OSD message is now clearer about whether subtitles
|
||||
are hidden or just not available / selected.
|
||||
- The device IDs given to `--audio-device` for use with ao_coreaudio now use
|
||||
UIDs, so they don't change when devices are added/removed or after reboots.
|
||||
- `--msg-level` now also accepts ',' as separator.
|
||||
- (Client API) The client API now refuses to initialize if the LC_NUMERIC
|
||||
locale is not "C".
|
||||
- (Client API) The native type of the `msg-level` parameter is now a key-value
|
||||
list. Setting or reading it as a string still works.
|
||||
- (Slave API) The `get_property` command is now deprecated.
|
||||
- Documentation updates.
|
||||
- PDF documentation is now disabled by default due to rst2pdf being fickle,
|
||||
causing weird build errors.
|
||||
- Print desync messages with negative A/V sync as well. While rare, it could
|
||||
happen with some uses of `--autosync`.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- (Windows) Avoid resizing the video window when player is minimized, might
|
||||
address bug #1547.
|
||||
- (NetBSD) Fix build with v4l2.
|
||||
- (Linux) Attempt to address conflicts with the pulseaudio mixer. (bug #1578)
|
||||
- Multiple cdda:// fixes. (bugs #1555, #1560)
|
||||
- VP9 timestamps no longer cause "missing PTS" warnings with new enough FFmpeg
|
||||
builds.
|
||||
- Fix a crash when using H.264 hardware decoding on new enough libavcodecs.
|
||||
(bug #1587)
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
- vo_opengl now supports frame blending to eliminate stuttering when the video
|
||||
framerate does not nicely match the display framerate through the
|
||||
`smoothmotion` suboption. This is not meant to artificially increase the
|
||||
video's FPS, so there is no "soap opera effect" or difficulties with some
|
||||
video types (e.g. anime).
|
||||
- vo_opengl now supports sigmoidal upscaling (e.g. for fullscreen), which
|
||||
reduces ringing induced by upscaling, enabled through the
|
||||
`sigmoid-upscaling` suboption.
|
||||
- vo_opengl now supports ewa_lanczos (Jinc) scaling, which provides higher
|
||||
quality with less aliasing. It supports an experimental `scale-antiringing`
|
||||
parameter, which tries to further reduce video ringing.
|
||||
- vo_opengl now has a `linear-scaling` suboption, that makes the scalers work
|
||||
in linear light. Implied by the `srgb`, `icc-profile` or the new
|
||||
`sigmoid-upscaling` suboption.
|
||||
- vo_opengl has improved downscaling for higher downscale ratios when
|
||||
`fancy-downscaling` is enabled.
|
||||
- Add `--keep-open=always` to make `--keep-open` apply to all files instead of
|
||||
only the last.
|
||||
- mpv now filters the tags that are printed on the console to try to hide
|
||||
useless metadata. The filter works as a whitelist, and can be configured
|
||||
with the `--display-tags` option.
|
||||
- Add a `--sub-scale-by-window` option that, when set to 'no', prevents
|
||||
subtitles from changing their pixel size when the window changes sizes.
|
||||
- vo_opengl now technically has GLES 2 and 3 support (but not GLES 1). GLES 3
|
||||
support is only tested on Mesa's software emulation. GLES 2 has been tested
|
||||
on nvidia drivers. Both GLES modes are feature deficient and inefficient due
|
||||
to GLES limitations, so they should not be preferred over the standard
|
||||
OpenGL mode.
|
||||
- (X11) vo_opengl now supports the `icc-profile-auto` option on X11 hosts.
|
||||
- The 'A' key now by default cycles through a list of preset aspect ratios.
|
||||
Meant to be used to work around broken files.
|
||||
- There is now a "force" mode for `--loop`. Works like "inf", but tries to
|
||||
open files/streams even if there was an error on the previous attempt.
|
||||
- There is now a `--log-file` option to write mpv's log messages to a specifed
|
||||
file.
|
||||
- There is now a `--audio-file-auto` option to automatically load an external
|
||||
audio file with certain constraints. Will only load external audio if the
|
||||
playing file has a video stream. Set to "exact" by default. (bug #967)
|
||||
- There is now a `--network-timeout` option to specify a timeout in seconds
|
||||
for network access. If 0 (default), uses the libavformat default. If a
|
||||
protocol that doesn't support timeouts is used, this option is ignored.
|
||||
- (X11) The XF86 special keys are now all mappable in `input.conf`. All keys
|
||||
documented in `XF86keysym.h` are available, but only as their numeric codes.
|
||||
- (Linux) The DVB implementation now supports DVB-S2 through S2API.
|
||||
- (Linux) The VDR format for `channels.conf` is now supported and preferred.
|
||||
See http://linuxtv.org/vdrwiki/index.php/Syntax_of_channels.conf for the
|
||||
syntax. Tuning to DVB-S2 channels requires the VDR-format `channels.conf`.
|
||||
- (Linux) There is now a `--dvbin-full-transponder` option for handling
|
||||
special broadcast cases where PIDs switch, or just to work around incomplete
|
||||
PID data.
|
||||
- (Client API) There is now an opengl_cb VO, which receives the OpenGL context
|
||||
from the libmpv client. This allows a client to render libmpv video directly
|
||||
to a provided OpenGL context without having to use --wid embedding.
|
||||
- (Client API) The aforementioned --wid parameter can now be set at any time,
|
||||
but has no effect if a file is already loaded.
|
||||
- (Client API) The list of DVD titles can now be queried.
|
||||
- (Client API) There is now a `filtered-metadata` property, containing only
|
||||
the tags allowed by `--display-tags`.
|
||||
- (Client API) There is now support for XEmbed `--wid` targets, such as a
|
||||
`GtkSocket`'s `gtk_socket_get_id()`.
|
||||
- (Client API) There is now a `file-format` property with a symbolic name
|
||||
for the file format. In some cases this might be a comma separated list
|
||||
of various different extensions due to libavformat idiosyncrasies.
|
||||
- (Client API) There is now a `mouse` command for generating mouse events
|
||||
over the video window.
|
||||
- (Client API) There is now a `partially-seekable` property that indicates
|
||||
whether a file is only considered `seekable` because of the stream cache,
|
||||
but would not be seekable otherwise (e.g. realtime stream, or HTTP with
|
||||
no resume support). Small relative seeks may be fine, but larger seeks
|
||||
will likely fail.
|
||||
- (Client API) There is now an MPV_EVENT_QUEUE_OVERFLOW event that is posted
|
||||
whenever events have to be dropped because the queue is full. No further
|
||||
events are posted until the MPV_EVENT_QUEUE_OVERFLOW is consumed to avoid
|
||||
duplicated posting.
|
||||
- (Client API) There is now a helper `mpv_wait_async_requests()` function
|
||||
that blocks until all known async requests have completed. (bug #1542)
|
||||
- (Client API) There is now a `detected-hwdec` property that returns the
|
||||
detected hardware decoder when one is successfully opened. This probably
|
||||
only returns a valid value after playback has started.
|
||||
- (Client API) There are now `audio_add`, `audio_remove` and `audio_reload`
|
||||
counterparts to the equivalent `sub_` commands for handling external audio
|
||||
files.
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.7.0..` in the git repository.
|
||||
File renamed without changes.
+2
-1
@@ -370,7 +370,8 @@ struct mp_audio *mp_audio_pool_get(struct mp_audio_pool *pool,
|
||||
if (alloc >= INT_MAX)
|
||||
return NULL;
|
||||
av_buffer_pool_uninit(&pool->avpool);
|
||||
pool->avpool = av_buffer_pool_init(alloc, NULL);
|
||||
pool->element_size = alloc;
|
||||
pool->avpool = av_buffer_pool_init(pool->element_size, NULL);
|
||||
if (!pool->avpool)
|
||||
return NULL;
|
||||
talloc_set_destructor(pool, mp_audio_pool_destructor);
|
||||
|
||||
@@ -743,6 +743,8 @@ double af_calc_delay(struct af_stream *s)
|
||||
double delay = 0.0;
|
||||
while (af) {
|
||||
delay += af->delay;
|
||||
for (int n = 0; n < af->num_out_queued; n++)
|
||||
delay += af->out_queued[n]->samples / (double)af->data->rate;
|
||||
af = af->next;
|
||||
}
|
||||
return delay;
|
||||
|
||||
+3
-4
@@ -143,6 +143,7 @@ static struct ao *ao_alloc(bool probing, struct mpv_global *global,
|
||||
.input_ctx = input_ctx,
|
||||
.log = mp_log_new(ao, log, name),
|
||||
.def_buffer = opts->audio_buffer,
|
||||
.client_name = talloc_strdup(ao, opts->audio_client_name),
|
||||
};
|
||||
struct m_config *config = m_config_from_obj_desc(ao, ao->log, &desc);
|
||||
if (m_config_apply_defaults(config, name, opts->ao_defs) < 0)
|
||||
@@ -162,7 +163,6 @@ static struct ao *ao_init(bool probing, struct mpv_global *global,
|
||||
int samplerate, int format, struct mp_chmap channels,
|
||||
char *dev, char *name, char **args)
|
||||
{
|
||||
struct MPOpts *opts = global->opts;
|
||||
struct ao *ao = ao_alloc(probing, global, input_ctx, name, args);
|
||||
if (!ao)
|
||||
return NULL;
|
||||
@@ -178,7 +178,6 @@ static struct ao *ao_init(bool probing, struct mpv_global *global,
|
||||
af_fmt_to_str(ao->format));
|
||||
|
||||
ao->device = talloc_strdup(ao, dev);
|
||||
ao->client_name = talloc_strdup(ao, opts->audio_client_name);
|
||||
|
||||
ao->api = ao->driver->play ? &ao_api_push : &ao_api_pull;
|
||||
ao->api_priv = talloc_zero_size(ao, ao->api->priv_size);
|
||||
@@ -275,8 +274,8 @@ struct ao *ao_init_best(struct mpv_global *global,
|
||||
ao_list[n].name, ao_list[n].attribs);
|
||||
if (ao)
|
||||
goto done;
|
||||
mp_warn(log, "Failed to initialize audio driver '%s'\n",
|
||||
ao_list[n].name);
|
||||
mp_err(log, "Failed to initialize audio driver '%s'\n",
|
||||
ao_list[n].name);
|
||||
if (forced_dev) {
|
||||
mp_err(log, "This audio driver/device was forced with the "
|
||||
"--audio-device option.\n"
|
||||
|
||||
+2
-2
@@ -224,8 +224,8 @@ void print_libav_versions(struct mp_log *log, int v)
|
||||
if (broken) {
|
||||
mp_fatal(log, "mpv was compiled and linked against a mixture of Libav "
|
||||
"and FFmpeg versions. This won't work and will most likely "
|
||||
"crash at some point. Exiting.\n");
|
||||
exit(42);
|
||||
"crash at some point. Aborting.\n");
|
||||
abort();
|
||||
}
|
||||
// We don't "really" support mismatched libraries, but if you like to
|
||||
// suffer, you're free to enjoy the terrible aspects of dynamic linking.
|
||||
|
||||
+6
-1
@@ -5,8 +5,12 @@ Name[ca]=Reproductor multimèdia mpv
|
||||
Name[cs]=mpv přehrávač
|
||||
Name[pl]=mpv odtwarzacz multimedialny
|
||||
Name[ru]=Проигрыватель mpv
|
||||
Name[zh-CN]=mpv 媒体播放器
|
||||
Name[zh-TW]=mpv 媒體播放器
|
||||
GenericName=Multimedia player
|
||||
GenericName[cs]=Multimediální přehrávač
|
||||
GenericName[zh-CN]=多媒体播放器
|
||||
GenericName[zh-TW]=多媒體播放器
|
||||
Comment=Play movies and songs
|
||||
Comment[ca]=Reproduïu vídeos i cançons
|
||||
Comment[cs]=Přehrává filmy a hudbu
|
||||
@@ -16,7 +20,8 @@ Comment[fr]=Lecteur multimédia
|
||||
Comment[it]=Lettore multimediale
|
||||
Comment[pl]=Odtwarzaj filmy i muzykę
|
||||
Comment[ru]=Воспроизвести фильмы и музыку
|
||||
Comment[zh]=多媒体播放器
|
||||
Comment[zh-CN]=播放电影和歌曲
|
||||
Comment[zh-TW]=播放電影和歌曲
|
||||
Icon=mpv
|
||||
TryExec=mpv
|
||||
Exec=mpv --no-terminal --force-window -- %U
|
||||
|
||||
+7
-1
@@ -531,9 +531,15 @@ static void *client_thread(void *p)
|
||||
};
|
||||
|
||||
fcntl(arg->client_fd, F_SETFL, fcntl(arg->client_fd, F_GETFL, 0) | O_NONBLOCK);
|
||||
mpv_suspend(arg->client);
|
||||
|
||||
while (1) {
|
||||
rc = poll(fds, 2, -1);
|
||||
rc = poll(fds, 2, 0);
|
||||
if (rc == 0) {
|
||||
mpv_resume(arg->client);
|
||||
rc = poll(fds, 2, -1);
|
||||
mpv_suspend(arg->client);
|
||||
}
|
||||
if (rc < 0) {
|
||||
MP_ERR(arg, "Poll error\n");
|
||||
continue;
|
||||
|
||||
@@ -194,6 +194,7 @@ static const struct key_name key_names[] = {
|
||||
{ MP_KEY_FAVORITES, "FAVORITES" },
|
||||
{ MP_KEY_SEARCH, "SEARCH" },
|
||||
{ MP_KEY_SLEEP, "SLEEP" },
|
||||
{ MP_KEY_CANCEL, "CANCEL" },
|
||||
|
||||
// These are kept for backward compatibility
|
||||
{ MP_KEY_PAUSE, "XF86_PAUSE" },
|
||||
|
||||
+7
-1
@@ -75,6 +75,7 @@
|
||||
#define MP_KEY_FAVORITES (MP_KEY_MM_BASE+16)
|
||||
#define MP_KEY_SEARCH (MP_KEY_MM_BASE+17)
|
||||
#define MP_KEY_SLEEP (MP_KEY_MM_BASE+18)
|
||||
#define MP_KEY_CANCEL (MP_KEY_MM_BASE+19)
|
||||
|
||||
/* Function keys */
|
||||
#define MP_KEY_F (MP_KEY_BASE+0x40)
|
||||
@@ -210,8 +211,13 @@
|
||||
#define MP_AXIS_LEFT (MP_AXIS_BASE+2)
|
||||
#define MP_AXIS_RIGHT (MP_AXIS_BASE+3)
|
||||
|
||||
// Reserved area. Can be used for keys that have no explicit names assigned,
|
||||
// but should be mappable by the user anyway.
|
||||
#define MP_KEY_UNKNOWN_RESERVED_START (MP_KEY_BASE+0x10000)
|
||||
#define MP_KEY_UNKNOWN_RESERVED_LAST (MP_KEY_BASE+0x20000-1)
|
||||
|
||||
/* Special keys */
|
||||
#define MP_KEY_INTERN (MP_KEY_BASE+0x1000)
|
||||
#define MP_KEY_INTERN (MP_KEY_BASE+0x20000)
|
||||
#define MP_KEY_CLOSE_WIN (MP_KEY_INTERN+0)
|
||||
// Generated by input.c (VOs use mp_input_set_mouse_pos())
|
||||
#define MP_KEY_MOUSE_MOVE ((MP_KEY_INTERN+1)|MP_NO_REPEAT_KEY)
|
||||
|
||||
@@ -121,6 +121,27 @@ extern "C" {
|
||||
* process (such as ffmpeg OpenSSL support, or the mpv IPC code).
|
||||
* - On memory exhaustion, mpv will kill the process.
|
||||
*
|
||||
* Encoding of filenames
|
||||
* ---------------------
|
||||
*
|
||||
* mpv uses UTF-8 everywhere.
|
||||
*
|
||||
* On some platforms (like Linux), filenames actually do not have to be UTF-8;
|
||||
* for this reason libmpv supports non-UTF-8 strings. libmpv uses what the
|
||||
* kernel uses and does not recode filenames. At least on Linux, passing a
|
||||
* string to libmpv is like passing a string to the fopen() function.
|
||||
*
|
||||
* On Windows, filenames are always UTF-8, libmpv converts between UTF-8 and
|
||||
* UTF-16 when using win32 API functions. libmpv never uses or accepts
|
||||
* filenames in the local 8 bit encoding. It does not use fopen() either;
|
||||
* it uses _wfopen().
|
||||
*
|
||||
* On OS X, filenames and other strings taken/returned by libmpv can have
|
||||
* inconsistent unicode normalization. This can sometimes lead to problems.
|
||||
* You have to hope for the best.
|
||||
*
|
||||
* Also see the remarks for MPV_FORMAT_STRING.
|
||||
*
|
||||
* Embedding the video window
|
||||
* --------------------------
|
||||
*
|
||||
@@ -502,6 +523,9 @@ typedef enum mpv_format {
|
||||
* and even filenames don't necessarily have to be in UTF-8 (at
|
||||
* least on Linux). If you pass the strings to code that requires
|
||||
* valid UTF-8, you have to sanitize it in some way.
|
||||
* On Windows, filenames are always UTF-8, and libmpv converts
|
||||
* between UTF-8 and UTF-16 when using win32 API functions. See
|
||||
* the "Encoding of filenames" section for details.
|
||||
*
|
||||
* Example for reading:
|
||||
*
|
||||
|
||||
+8
-8
@@ -99,6 +99,14 @@ SOURCES-$(WAYLAND) += video/out/vo_wayland.c \
|
||||
video/out/wayland/memfile.c
|
||||
|
||||
SOURCES-$(LIBAVFILTER) += video/filter/vf_lavfi.c \
|
||||
video/filter/vf_delogo.c \
|
||||
video/filter/vf_gradfun.c \
|
||||
video/filter/vf_hqdn3d.c \
|
||||
video/filter/vf_noise.c \
|
||||
video/filter/vf_pullup.c \
|
||||
video/filter/vf_rotate.c \
|
||||
video/filter/vf_unsharp.c \
|
||||
video/filter/vf_yadif.c \
|
||||
audio/filter/af_lavfi.c
|
||||
|
||||
SOURCES-$(LUA) += player/lua.c
|
||||
@@ -250,25 +258,17 @@ SOURCES = audio/audio.c \
|
||||
video/filter/vf.c \
|
||||
video/filter/vf_buffer.c \
|
||||
video/filter/vf_crop.c \
|
||||
video/filter/vf_delogo.c \
|
||||
video/filter/vf_dsize.c \
|
||||
video/filter/vf_eq.c \
|
||||
video/filter/vf_expand.c \
|
||||
video/filter/vf_flip.c \
|
||||
video/filter/vf_format.c \
|
||||
video/filter/vf_gradfun.c \
|
||||
video/filter/vf_hqdn3d.c \
|
||||
video/filter/vf_mirror.c \
|
||||
video/filter/vf_noformat.c \
|
||||
video/filter/vf_noise.c \
|
||||
video/filter/vf_pullup.c \
|
||||
video/filter/vf_rotate.c \
|
||||
video/filter/vf_scale.c \
|
||||
video/filter/vf_screenshot.c \
|
||||
video/filter/vf_stereo3d.c \
|
||||
video/filter/vf_sub.c \
|
||||
video/filter/vf_unsharp.c \
|
||||
video/filter/vf_yadif.c \
|
||||
video/out/bitmap_packer.c \
|
||||
video/out/aspect.c \
|
||||
video/out/filter_kernels.c \
|
||||
|
||||
+5
-4
@@ -500,9 +500,10 @@ const m_option_t mp_opts[] = {
|
||||
|
||||
OPT_FLAG("stop-playback-on-init-failure", stop_playback_on_init_failure, 0),
|
||||
|
||||
OPT_CHOICE_OR_INT("loop", loop_times, M_OPT_GLOBAL, 2, 10000,
|
||||
({"no", -1}, {"1", -1},
|
||||
{"inf", 0})),
|
||||
OPT_CHOICE_OR_INT("loop", loop_times, M_OPT_GLOBAL, 1, 10000,
|
||||
({"no", 1},
|
||||
{"inf", -1},
|
||||
{"force", -2})),
|
||||
OPT_CHOICE_OR_INT("loop-file", loop_file, M_OPT_OPTIONAL_PARAM, 0, 10000,
|
||||
({"yes", -1}, {"", -1}, {"no", 0}, // compat
|
||||
{"inf", -1})),
|
||||
@@ -712,7 +713,7 @@ const struct MPOpts mp_default_opts = {
|
||||
.lua_ytdl_format = NULL,
|
||||
#endif
|
||||
.auto_load_scripts = 1,
|
||||
.loop_times = -1,
|
||||
.loop_times = 1,
|
||||
.ordered_chapters = 1,
|
||||
.chapter_merge_threshold = 100,
|
||||
.chapter_seek_threshold = 5.0,
|
||||
|
||||
+8
-5
@@ -147,12 +147,15 @@ char **mp_find_all_config_files(void *talloc_ctx, struct mpv_global *global,
|
||||
|
||||
char **dirs = mp_config_dirs(NULL, global);
|
||||
for (int i = 0; dirs && dirs[i]; i++) {
|
||||
char *file = talloc_asprintf(ret, "%s/%s", dirs[i], filename);
|
||||
bstr s = bstr0(filename);
|
||||
while (s.len) {
|
||||
bstr fn;
|
||||
bstr_split_tok(s, "|", &fn, &s);
|
||||
|
||||
if (!mp_path_exists(file) || num_ret >= MAX_CONFIG_PATHS)
|
||||
continue;
|
||||
|
||||
ret[num_ret++] = file;
|
||||
char *file = talloc_asprintf(ret, "%s/%.*s", dirs[i], BSTR_P(fn));
|
||||
if (mp_path_exists(file) && num_ret < MAX_CONFIG_PATHS)
|
||||
ret[num_ret++] = file;
|
||||
}
|
||||
}
|
||||
talloc_free(dirs);
|
||||
|
||||
|
||||
+2
-1
@@ -33,7 +33,8 @@ char *mp_find_config_file(void *talloc_ctx, struct mpv_global *global,
|
||||
const char *filename);
|
||||
|
||||
// Find all instances of the given config file. Paths are returned in order
|
||||
// from lowest to highest priority.
|
||||
// from lowest to highest priority. filename can contain multiple names
|
||||
// separated with '|', with the first having highest priority.
|
||||
char **mp_find_all_config_files(void *talloc_ctx, struct mpv_global *global,
|
||||
const char *filename);
|
||||
|
||||
|
||||
@@ -261,21 +261,15 @@ static void cocoa_run_runloop(void)
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
static void cocoa_stop_runloop(void)
|
||||
{
|
||||
[NSApp performSelectorOnMainThread:@selector(stop:)
|
||||
withObject:nil
|
||||
waitUntilDone:true];
|
||||
}
|
||||
|
||||
static void *playback_thread(void *ctx_obj)
|
||||
{
|
||||
mpthread_set_name("playback core (OSX)");
|
||||
@autoreleasepool {
|
||||
struct playback_thread_ctx *ctx = (struct playback_thread_ctx*) ctx_obj;
|
||||
ctx->mpv_main(*ctx->argc, *ctx->argv);
|
||||
cocoa_stop_runloop();
|
||||
pthread_exit(NULL);
|
||||
int r = ctx->mpv_main(*ctx->argc, *ctx->argv);
|
||||
terminate_cocoa_application();
|
||||
// normally never reached - unless the cocoa mainloop hasn't started yet
|
||||
exit(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4329,6 +4329,10 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
||||
}
|
||||
MP_INFO(mpctx, "ANS_%s=%s\n", cmd->args[0].v.s, tmp);
|
||||
talloc_free(tmp);
|
||||
MP_WARN(mpctx, "The get_property command is deprecated and "
|
||||
"will be removed in the next release.\n"
|
||||
"Use libmpv or the JSON IPC. "
|
||||
"(Or print_text, if you must.)");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,8 +84,7 @@ void mp_parse_cfgfiles(struct MPContext *mpctx)
|
||||
talloc_free(cf);
|
||||
#endif
|
||||
|
||||
load_all_cfgfiles(mpctx, section, "config");
|
||||
load_all_cfgfiles(mpctx, section, "mpv.conf");
|
||||
load_all_cfgfiles(mpctx, section, "mpv.conf|config");
|
||||
|
||||
if (encoding)
|
||||
m_config_set_profile(conf, m_config_add_profile(conf, SECT_ENCODE), 0);
|
||||
|
||||
+5
-7
@@ -1317,26 +1317,24 @@ struct playlist_entry *mp_next_file(struct MPContext *mpctx, int direction,
|
||||
while (next && next->playback_short)
|
||||
next = next->prev;
|
||||
// Always allow jumping to first file
|
||||
if (!next && mpctx->opts->loop_times < 0)
|
||||
if (!next && mpctx->opts->loop_times == 1)
|
||||
next = mpctx->playlist->first;
|
||||
}
|
||||
if (!next && mpctx->opts->loop_times >= 0) {
|
||||
if (!next && mpctx->opts->loop_times != 1) {
|
||||
if (direction > 0) {
|
||||
if (mpctx->opts->shuffle)
|
||||
playlist_shuffle(mpctx->playlist);
|
||||
next = mpctx->playlist->first;
|
||||
if (next && mpctx->opts->loop_times > 1) {
|
||||
if (next && mpctx->opts->loop_times > 1)
|
||||
mpctx->opts->loop_times--;
|
||||
if (mpctx->opts->loop_times == 1)
|
||||
mpctx->opts->loop_times = -1;
|
||||
}
|
||||
} else {
|
||||
next = mpctx->playlist->last;
|
||||
// Don't jump to files that would immediately go to next file anyway
|
||||
while (next && next->playback_short)
|
||||
next = next->prev;
|
||||
}
|
||||
if (!force && next && next->init_failed) {
|
||||
bool ignore_failures = mpctx->opts->loop_times == -2;
|
||||
if (!force && next && next->init_failed && !ignore_failures) {
|
||||
// Don't endless loop if no file in playlist is playable
|
||||
bool all_failed = true;
|
||||
struct playlist_entry *cur;
|
||||
|
||||
+12
-27
@@ -71,9 +71,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_COCOA_APPLICATION
|
||||
#include "osdep/macosx_application.h"
|
||||
#endif
|
||||
#if HAVE_COCOA
|
||||
#include "osdep/macosx_events.h"
|
||||
#endif
|
||||
@@ -167,6 +164,10 @@ void mp_destroy(struct MPContext *mpctx)
|
||||
|
||||
osd_free(mpctx->osd);
|
||||
|
||||
#if HAVE_COCOA
|
||||
cocoa_set_input_context(NULL);
|
||||
#endif
|
||||
|
||||
if (cas_terminal_owner(mpctx, mpctx)) {
|
||||
terminal_uninit();
|
||||
cas_terminal_owner(mpctx, NULL);
|
||||
@@ -184,13 +185,8 @@ void mp_destroy(struct MPContext *mpctx)
|
||||
talloc_free(mpctx);
|
||||
}
|
||||
|
||||
static MP_NORETURN void exit_player(struct MPContext *mpctx,
|
||||
enum exit_reason how)
|
||||
static int prepare_exit_cplayer(struct MPContext *mpctx, enum exit_reason how)
|
||||
{
|
||||
#if HAVE_COCOA_APPLICATION
|
||||
cocoa_set_input_context(NULL);
|
||||
#endif
|
||||
|
||||
int rc = 0;
|
||||
const char *reason = NULL;
|
||||
|
||||
@@ -228,15 +224,7 @@ static MP_NORETURN void exit_player(struct MPContext *mpctx,
|
||||
rc = mpctx->quit_custom_rc;
|
||||
|
||||
mp_destroy(mpctx);
|
||||
|
||||
#if HAVE_COCOA_APPLICATION
|
||||
terminate_cocoa_application();
|
||||
// never reach here:
|
||||
// terminate calls exit itself, just silence compiler warning
|
||||
exit(0);
|
||||
#else
|
||||
exit(rc);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool handle_help_options(struct MPContext *mpctx)
|
||||
@@ -413,7 +401,6 @@ int mp_initialize(struct MPContext *mpctx)
|
||||
}
|
||||
m_config_set_option0(mpctx->mconfig, "vo", "lavc");
|
||||
m_config_set_option0(mpctx->mconfig, "ao", "lavc");
|
||||
m_config_set_option0(mpctx->mconfig, "fixed-vo", "yes");
|
||||
m_config_set_option0(mpctx->mconfig, "keep-open", "no");
|
||||
m_config_set_option0(mpctx->mconfig, "force-window", "no");
|
||||
m_config_set_option0(mpctx->mconfig, "gapless-audio", "yes");
|
||||
@@ -457,7 +444,6 @@ int mp_initialize(struct MPContext *mpctx)
|
||||
"the selected video_out (-vo) device.\n");
|
||||
return -1;
|
||||
}
|
||||
handle_force_window(mpctx, false);
|
||||
mpctx->mouse_cursor_visible = true;
|
||||
}
|
||||
|
||||
@@ -508,21 +494,21 @@ int mpv_main(int argc, char *argv[])
|
||||
mpctx->global, argc, argv);
|
||||
if (r < 0) {
|
||||
if (r <= M_OPT_EXIT) {
|
||||
exit_player(mpctx, EXIT_NONE);
|
||||
return prepare_exit_cplayer(mpctx, EXIT_NONE);
|
||||
} else {
|
||||
exit_player(mpctx, EXIT_ERROR);
|
||||
return prepare_exit_cplayer(mpctx, EXIT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
mp_msg_update_msglevels(mpctx->global);
|
||||
|
||||
if (handle_help_options(mpctx))
|
||||
exit_player(mpctx, EXIT_NONE);
|
||||
return prepare_exit_cplayer(mpctx, EXIT_NONE);
|
||||
|
||||
if (!mpctx->playlist->first && !opts->player_idle_mode) {
|
||||
mp_print_version(mpctx->log, true);
|
||||
MP_INFO(mpctx, "%s", mp_help_text);
|
||||
exit_player(mpctx, EXIT_NONE);
|
||||
return prepare_exit_cplayer(mpctx, EXIT_NONE);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -531,9 +517,8 @@ int mpv_main(int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
if (mp_initialize(mpctx) < 0)
|
||||
exit_player(mpctx, EXIT_ERROR);
|
||||
return prepare_exit_cplayer(mpctx, EXIT_ERROR);
|
||||
|
||||
mp_play_files(mpctx);
|
||||
exit_player(mpctx, EXIT_NORMAL);
|
||||
return 1;
|
||||
return prepare_exit_cplayer(mpctx, EXIT_NORMAL);
|
||||
}
|
||||
+1
-1
@@ -813,7 +813,7 @@ static void handle_keep_open(struct MPContext *mpctx)
|
||||
struct MPOpts *opts = mpctx->opts;
|
||||
if (opts->keep_open && mpctx->stop_play == AT_END_OF_FILE &&
|
||||
(opts->keep_open == 2 || !playlist_get_next(mpctx->playlist, 1)) &&
|
||||
opts->loop_times < 0)
|
||||
opts->loop_times == 1)
|
||||
{
|
||||
mpctx->stop_play = KEEP_PLAYING;
|
||||
if (mpctx->d_video) {
|
||||
|
||||
@@ -180,6 +180,8 @@ static void recreate_video_filters(struct MPContext *mpctx)
|
||||
d_video->vfilter->wakeup_callback = wakeup_playloop;
|
||||
d_video->vfilter->wakeup_callback_ctx = mpctx;
|
||||
d_video->vfilter->container_fps = d_video->fps;
|
||||
vo_control(mpctx->video_out, VOCTRL_GET_DISPLAY_FPS,
|
||||
&d_video->vfilter->display_fps);
|
||||
|
||||
vf_append_filter_list(d_video->vfilter, opts->vf_settings);
|
||||
|
||||
|
||||
+1
-1
@@ -498,7 +498,7 @@ static int tune_it(dvb_priv_t *priv, int fd_frontend, int fd_sec,
|
||||
MP_VERBOSE(priv, "Tuning via DVB-API version 3.\n");
|
||||
if (is_dvb_s2) {
|
||||
MP_ERR(priv, "ERROR: Can not tune to S2 channel, S2-API not "
|
||||
"available, will tune to DVB-S!\n")
|
||||
"available, will tune to DVB-S!\n");
|
||||
}
|
||||
if (ioctl(fd_frontend, FE_SET_FRONTEND, &feparams) < 0) {
|
||||
MP_ERR(priv, "ERROR tuning channel\n");
|
||||
|
||||
@@ -436,12 +436,6 @@ static void uninit_avctx(struct dec_video *vd)
|
||||
vd_ffmpeg_ctx *ctx = vd->priv;
|
||||
AVCodecContext *avctx = ctx->avctx;
|
||||
|
||||
if (avctx && avcodec_is_open(avctx))
|
||||
avcodec_flush_buffers(avctx);
|
||||
|
||||
if (ctx->hwdec && ctx->hwdec->uninit)
|
||||
ctx->hwdec->uninit(ctx);
|
||||
|
||||
if (avctx) {
|
||||
if (avctx->codec && avcodec_close(avctx) < 0)
|
||||
MP_ERR(vd, "Could not close codec.\n");
|
||||
@@ -450,6 +444,9 @@ static void uninit_avctx(struct dec_video *vd)
|
||||
av_freep(&avctx->slice_offset);
|
||||
}
|
||||
|
||||
if (ctx->hwdec && ctx->hwdec->uninit)
|
||||
ctx->hwdec->uninit(ctx);
|
||||
|
||||
av_freep(&ctx->avctx);
|
||||
|
||||
av_frame_free(&ctx->pic);
|
||||
|
||||
+8
-8
@@ -77,25 +77,25 @@ static const vf_info_t *const filter_list[] = {
|
||||
&vf_info_format,
|
||||
&vf_info_noformat,
|
||||
&vf_info_flip,
|
||||
&vf_info_rotate,
|
||||
&vf_info_mirror,
|
||||
|
||||
#if HAVE_LIBAVFILTER
|
||||
&vf_info_lavfi,
|
||||
&vf_info_rotate,
|
||||
&vf_info_noise,
|
||||
&vf_info_gradfun,
|
||||
&vf_info_unsharp,
|
||||
&vf_info_hqdn3d,
|
||||
&vf_info_pullup,
|
||||
&vf_info_delogo,
|
||||
&vf_info_yadif,
|
||||
#endif
|
||||
|
||||
&vf_info_screenshot,
|
||||
|
||||
&vf_info_noise,
|
||||
&vf_info_eq,
|
||||
&vf_info_gradfun,
|
||||
&vf_info_unsharp,
|
||||
&vf_info_hqdn3d,
|
||||
&vf_info_dsize,
|
||||
&vf_info_pullup,
|
||||
&vf_info_delogo,
|
||||
&vf_info_sub,
|
||||
&vf_info_yadif,
|
||||
&vf_info_stereo3d,
|
||||
&vf_info_buffer,
|
||||
#if HAVE_DLOPEN
|
||||
|
||||
@@ -122,6 +122,7 @@ struct vf_chain {
|
||||
uint8_t allowed_output_formats[IMGFMT_END - IMGFMT_START];
|
||||
|
||||
double container_fps;
|
||||
double display_fps;
|
||||
|
||||
struct mp_log *log;
|
||||
struct MPOpts *opts;
|
||||
|
||||
@@ -48,7 +48,7 @@ static int vf_open(vf_instance_t *vf){
|
||||
return 1;
|
||||
}
|
||||
|
||||
MP_FATAL(vf, "Requires libavfilter.\n");
|
||||
MP_FATAL(vf, "This version of libavfilter has no 'delogo' filter.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ static int vf_open(vf_instance_t *vf)
|
||||
return 1;
|
||||
}
|
||||
|
||||
MP_FATAL(vf, "Requires libavfilter.\n");
|
||||
MP_FATAL(vf, "This version of libavfilter has no 'gradfun' filter.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ static int vf_open(vf_instance_t *vf)
|
||||
return 1;
|
||||
}
|
||||
|
||||
MP_FATAL(vf, "Requires libavfilter.\n");
|
||||
MP_FATAL(vf, "This version of libavfilter has no 'hqdn3' filter.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "common/av_common.h"
|
||||
#include "common/msg.h"
|
||||
#include "options/m_option.h"
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
#ifndef MP_VF_LAVFI_H_
|
||||
#define MP_VF_LAVFI_H_
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "common/common.h"
|
||||
#include "vf.h"
|
||||
|
||||
struct vf_lw_opts;
|
||||
|
||||
#if HAVE_LIBAVFILTER
|
||||
|
||||
extern const struct m_sub_options vf_lw_conf;
|
||||
|
||||
int vf_lw_set_graph(struct vf_instance *vf, struct vf_lw_opts *lavfi_opts,
|
||||
@@ -21,28 +17,5 @@ void vf_lw_set_reconfig_cb(struct vf_instance *vf,
|
||||
int (*reconfig)(struct vf_instance *vf,
|
||||
struct mp_image_params *in,
|
||||
struct mp_image_params *out));
|
||||
#else
|
||||
static inline
|
||||
int vf_lw_set_graph(struct vf_instance *vf, struct vf_lw_opts *lavfi_opts,
|
||||
char *filter, char *opts, ...)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static void *vf_lw_old_priv(struct vf_instance *vf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static void vf_lw_update_graph(struct vf_instance *vf, char *filter, char *opts, ...)
|
||||
{
|
||||
}
|
||||
static void vf_lw_set_reconfig_cb(struct vf_instance *vf,
|
||||
int (*reconfig)(struct vf_instance *vf,
|
||||
struct mp_image_params *in,
|
||||
struct mp_image_params *out))
|
||||
{
|
||||
}
|
||||
#include "options/m_option.h"
|
||||
static const struct m_sub_options vf_lw_conf = {0};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+8
-239
@@ -20,253 +20,25 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <libavutil/mem.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "common/msg.h"
|
||||
#include "options/m_option.h"
|
||||
|
||||
#include "video/img_format.h"
|
||||
#include "video/mp_image.h"
|
||||
#include "vf.h"
|
||||
#include "video/memcpy_pic.h"
|
||||
|
||||
#include "vf_lavfi.h"
|
||||
|
||||
#define MAX_NOISE 4096
|
||||
#define MAX_SHIFT 1024
|
||||
#define MAX_RES (MAX_NOISE-MAX_SHIFT)
|
||||
|
||||
//===========================================================================//
|
||||
|
||||
static inline void lineNoise(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift);
|
||||
static inline void lineNoiseAvg(uint8_t *dst, uint8_t *src, int len, int8_t **shift);
|
||||
|
||||
typedef struct FilterParam{
|
||||
int strength;
|
||||
int uniform;
|
||||
int temporal;
|
||||
int quality;
|
||||
int averaged;
|
||||
int pattern;
|
||||
int shiftptr;
|
||||
int8_t *noise;
|
||||
int8_t *prev_shift[MAX_RES][3];
|
||||
int nonTempRandShift[MAX_RES];
|
||||
}FilterParam;
|
||||
|
||||
struct vf_priv_s {
|
||||
FilterParam lumaParam;
|
||||
FilterParam chromaParam;
|
||||
int strength;
|
||||
int averaged;
|
||||
int pattern;
|
||||
int temporal;
|
||||
int uniform;
|
||||
int hq;
|
||||
struct vf_lw_opts *lw_opts;
|
||||
int strength;
|
||||
int averaged;
|
||||
int pattern;
|
||||
int temporal;
|
||||
int uniform;
|
||||
struct vf_lw_opts *lw_opts;
|
||||
};
|
||||
|
||||
static const int patt[4] = {
|
||||
-1,0,1,0
|
||||
};
|
||||
|
||||
#define RAND_N(range) ((int) ((double)range*rand()/(RAND_MAX+1.0)))
|
||||
static int8_t *initNoise(FilterParam *fp){
|
||||
int strength= fp->strength;
|
||||
int uniform= fp->uniform;
|
||||
int averaged= fp->averaged;
|
||||
int pattern= fp->pattern;
|
||||
int8_t *noise= av_malloc(MAX_NOISE*sizeof(int8_t));
|
||||
int i, j;
|
||||
|
||||
srand(123457);
|
||||
|
||||
for(i=0,j=0; i<MAX_NOISE; i++,j++)
|
||||
{
|
||||
if(uniform) {
|
||||
if (averaged) {
|
||||
if (pattern) {
|
||||
noise[i]= (RAND_N(strength) - strength/2)/6
|
||||
+patt[j%4]*strength*0.25/3;
|
||||
} else {
|
||||
noise[i]= (RAND_N(strength) - strength/2)/3;
|
||||
}
|
||||
} else {
|
||||
if (pattern) {
|
||||
noise[i]= (RAND_N(strength) - strength/2)/2
|
||||
+ patt[j%4]*strength*0.25;
|
||||
} else {
|
||||
noise[i]= RAND_N(strength) - strength/2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
double x1, x2, w, y1;
|
||||
do {
|
||||
x1 = 2.0 * rand()/(float)RAND_MAX - 1.0;
|
||||
x2 = 2.0 * rand()/(float)RAND_MAX - 1.0;
|
||||
w = x1 * x1 + x2 * x2;
|
||||
} while ( w >= 1.0 );
|
||||
|
||||
w = sqrt( (-2.0 * log( w ) ) / w );
|
||||
y1= x1 * w;
|
||||
y1*= strength / sqrt(3.0);
|
||||
if (pattern) {
|
||||
y1 /= 2;
|
||||
y1 += patt[j%4]*strength*0.35;
|
||||
}
|
||||
if (y1<-128) y1=-128;
|
||||
else if(y1> 127) y1= 127;
|
||||
if (averaged) y1 /= 3.0;
|
||||
noise[i]= (int)y1;
|
||||
}
|
||||
if (RAND_N(6) == 0) j--;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < MAX_RES; i++)
|
||||
for (j = 0; j < 3; j++)
|
||||
fp->prev_shift[i][j] = noise + (rand()&(MAX_SHIFT-1));
|
||||
|
||||
for(i=0; i<MAX_RES; i++){
|
||||
fp->nonTempRandShift[i]= rand()&(MAX_SHIFT-1);
|
||||
}
|
||||
|
||||
fp->noise= noise;
|
||||
fp->shiftptr= 0;
|
||||
return noise;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static inline void lineNoise(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift){
|
||||
int i;
|
||||
noise+= shift;
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
int v= src[i]+ noise[i];
|
||||
if(v>255) dst[i]=255; //FIXME optimize
|
||||
else if(v<0) dst[i]=0;
|
||||
else dst[i]=v;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static inline void lineNoiseAvg(uint8_t *dst, uint8_t *src, int len, int8_t **shift){
|
||||
int i;
|
||||
int8_t *src2= (int8_t*)src;
|
||||
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
const int n= shift[0][i] + shift[1][i] + shift[2][i];
|
||||
dst[i]= src2[i]+((n*src2[i])>>7);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
static void donoise(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int width, int height, FilterParam *fp){
|
||||
int8_t *noise= fp->noise;
|
||||
int y;
|
||||
int shift=0;
|
||||
|
||||
if(!noise)
|
||||
{
|
||||
if(src==dst) return;
|
||||
|
||||
if(dstStride==srcStride) memcpy(dst, src, srcStride*height);
|
||||
else
|
||||
{
|
||||
for(y=0; y<height; y++)
|
||||
{
|
||||
memcpy(dst, src, width);
|
||||
dst+= dstStride;
|
||||
src+= srcStride;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for(y=0; y<height; y++)
|
||||
{
|
||||
if(fp->temporal) shift= rand()&(MAX_SHIFT -1);
|
||||
else shift= fp->nonTempRandShift[y];
|
||||
|
||||
if(fp->quality==0) shift&= ~7;
|
||||
if (fp->averaged) {
|
||||
lineNoiseAvg(dst, src, width, fp->prev_shift[y]);
|
||||
fp->prev_shift[y][fp->shiftptr] = noise + shift;
|
||||
} else {
|
||||
lineNoise(dst, src, noise, width, shift);
|
||||
}
|
||||
dst+= dstStride;
|
||||
src+= srcStride;
|
||||
}
|
||||
fp->shiftptr++;
|
||||
if (fp->shiftptr == 3) fp->shiftptr = 0;
|
||||
}
|
||||
|
||||
static struct mp_image *filter(struct vf_instance *vf, struct mp_image *mpi)
|
||||
{
|
||||
struct mp_image *dmpi = mpi;
|
||||
if (!mp_image_is_writeable(mpi)) {
|
||||
dmpi = vf_alloc_out_image(vf);
|
||||
if (!dmpi)
|
||||
return NULL;
|
||||
mp_image_copy_attributes(dmpi, mpi);
|
||||
}
|
||||
|
||||
donoise(dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, &vf->priv->lumaParam);
|
||||
donoise(dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w/2, mpi->h/2, &vf->priv->chromaParam);
|
||||
donoise(dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w/2, mpi->h/2, &vf->priv->chromaParam);
|
||||
|
||||
if (dmpi != mpi)
|
||||
talloc_free(mpi);
|
||||
return dmpi;
|
||||
}
|
||||
|
||||
static void uninit(struct vf_instance *vf){
|
||||
if(!vf->priv) return;
|
||||
|
||||
av_free(vf->priv->chromaParam.noise);
|
||||
vf->priv->chromaParam.noise= NULL;
|
||||
|
||||
av_free(vf->priv->lumaParam.noise);
|
||||
vf->priv->lumaParam.noise= NULL;
|
||||
}
|
||||
|
||||
//===========================================================================//
|
||||
|
||||
static int query_format(struct vf_instance *vf, unsigned int fmt){
|
||||
switch(fmt)
|
||||
{
|
||||
case IMGFMT_420P:
|
||||
return vf_next_query_format(vf,IMGFMT_420P);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void parse(FilterParam *fp, struct vf_priv_s *p){
|
||||
fp->strength= p->strength;
|
||||
fp->uniform=p->uniform;
|
||||
fp->temporal=p->temporal;
|
||||
fp->quality=p->hq;
|
||||
fp->pattern=p->pattern;
|
||||
fp->averaged=p->averaged;
|
||||
|
||||
if(fp->strength) initNoise(fp);
|
||||
}
|
||||
|
||||
static int vf_open(vf_instance_t *vf){
|
||||
vf->filter=filter;
|
||||
vf->query_format=query_format;
|
||||
vf->uninit=uninit;
|
||||
|
||||
#define CH(f) ((f) ? '+' : '-')
|
||||
struct vf_priv_s *p = vf->priv;
|
||||
if (vf_lw_set_graph(vf, p->lw_opts, "noise", "-1:%d:%ca%cp%ct%cu",
|
||||
@@ -276,10 +48,8 @@ static int vf_open(vf_instance_t *vf){
|
||||
return 1;
|
||||
}
|
||||
|
||||
parse(&vf->priv->lumaParam, vf->priv);
|
||||
parse(&vf->priv->chromaParam, vf->priv);
|
||||
|
||||
return 1;
|
||||
MP_FATAL(vf, "This version of libavfilter has no 'noise' filter.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct vf_priv_s
|
||||
@@ -294,7 +64,6 @@ const vf_info_t vf_info_noise = {
|
||||
OPT_FLAG("pattern", pattern, 0),
|
||||
OPT_FLAG("temporal", temporal, 0),
|
||||
OPT_FLAG("uniform", uniform, 0),
|
||||
OPT_FLAG("hq", hq, 0),
|
||||
OPT_SUBSTRUCT("", lw_opts, vf_lw_conf, 0),
|
||||
{0}
|
||||
},
|
||||
|
||||
@@ -48,7 +48,7 @@ static int vf_open(vf_instance_t *vf)
|
||||
return 1;
|
||||
}
|
||||
|
||||
MP_FATAL(vf, "Requires libavfilter.\n");
|
||||
MP_FATAL(vf, "This version of libavfilter has no 'pullup' filter.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,8 +66,7 @@ static int vf_open(vf_instance_t *vf)
|
||||
return 1;
|
||||
}
|
||||
|
||||
MP_FATAL(vf, "Requires libavfilter.\n");
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct vf_priv_s
|
||||
|
||||
+29
-12
@@ -510,6 +510,8 @@ static bool handle_auto_in(struct vf_instance *vf)
|
||||
return true;
|
||||
}
|
||||
|
||||
#if HAVE_LIBAVFILTER
|
||||
|
||||
static int lavfi_reconfig(struct vf_instance *vf,
|
||||
struct mp_image_params *in,
|
||||
struct mp_image_params *out)
|
||||
@@ -528,6 +530,32 @@ static int lavfi_reconfig(struct vf_instance *vf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lavfi_init(vf_instance_t *vf)
|
||||
{
|
||||
if (vf->priv->in.fmt == STEREO_AUTO &&
|
||||
vf_lw_set_graph(vf, vf->priv->lw_opts, "stereo3d", "null") >= 0)
|
||||
{
|
||||
vf_lw_set_reconfig_cb(vf, lavfi_reconfig);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vf_lw_set_graph(vf, vf->priv->lw_opts, "stereo3d", "%s:%s",
|
||||
rev_map_name(vf->priv->in.fmt),
|
||||
rev_map_name(vf->priv->out.fmt)) >= 0)
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
const struct m_sub_options vf_lw_conf = {0};
|
||||
|
||||
static void lavfi_init(vf_instance_t *vf)
|
||||
{
|
||||
// doing nothing will make it use the internal implementation
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int vf_open(vf_instance_t *vf)
|
||||
{
|
||||
vf->config = config;
|
||||
@@ -541,18 +569,7 @@ static int vf_open(vf_instance_t *vf)
|
||||
if (vf->priv->in.fmt == STEREO_AUTO)
|
||||
vf->priv->auto_in = 1;
|
||||
|
||||
if (vf->priv->in.fmt == STEREO_AUTO &&
|
||||
vf_lw_set_graph(vf, vf->priv->lw_opts, "stereo3d", "null") >= 0)
|
||||
{
|
||||
vf_lw_set_reconfig_cb(vf, lavfi_reconfig);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vf_lw_set_graph(vf, vf->priv->lw_opts, "stereo3d", "%s:%s",
|
||||
rev_map_name(vf->priv->in.fmt),
|
||||
rev_map_name(vf->priv->out.fmt)) >= 0)
|
||||
return 1;
|
||||
|
||||
lavfi_init(vf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ static int vf_open(vf_instance_t *vf)
|
||||
return 1;
|
||||
}
|
||||
|
||||
MP_FATAL(vf, "Requires libavfilter.\n");
|
||||
MP_FATAL(vf, "This version of libavfilter has no 'unsharp' filter.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -592,6 +592,7 @@ static int reinit_vs(struct vf_instance *vf)
|
||||
p->vsapi->propSetInt(vars, "video_in_dw", p->fmt_in.d_w, 0);
|
||||
p->vsapi->propSetInt(vars, "video_in_dh", p->fmt_in.d_h, 0);
|
||||
p->vsapi->propSetFloat(vars, "container_fps", vf->chain->container_fps, 0);
|
||||
p->vsapi->propSetFloat(vars, "display_fps", vf->chain->display_fps, 0);
|
||||
|
||||
if (p->drv->load(vf, vars) < 0)
|
||||
goto error;
|
||||
|
||||
@@ -52,7 +52,7 @@ static int vf_open(vf_instance_t *vf)
|
||||
return 1;
|
||||
}
|
||||
|
||||
MP_FATAL(vf, "Requires libavfilter.\n");
|
||||
MP_FATAL(vf, "This version of libavfilter has no 'yadif' filter.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1749,15 +1749,11 @@ static void gl_video_interpolate_frame(struct gl_video *p,
|
||||
gl->ActiveTexture(GL_TEXTURE0 + 1);
|
||||
gl->BindTexture(p->gl_target, p->surfaces[p->surface_idx].fbotex.texture);
|
||||
gl->ActiveTexture(GL_TEXTURE0);
|
||||
MP_DBG(p, "frame ppts: %lld, pts: %lld, vsync: %lld, DIFF: %lld\n",
|
||||
(long long)prev_pts, (long long)t->pts,
|
||||
(long long)t->next_vsync, (long long)t->next_vsync - t->pts);
|
||||
if (prev_pts < t->next_vsync && t->pts > t->next_vsync) {
|
||||
double N = t->next_vsync - prev_pts;
|
||||
double P = t->pts - prev_pts;
|
||||
double prev_pts_component = N / P;
|
||||
double N = t->next_vsync - t->prev_vsync;
|
||||
double P = t->pts - t->prev_vsync;
|
||||
float ts = p->opts.smoothmotion_threshold;
|
||||
inter_coeff = 1 - prev_pts_component;
|
||||
inter_coeff = 1 - (N / P);
|
||||
inter_coeff = inter_coeff < 0.0 + ts ? 0.0 : inter_coeff;
|
||||
inter_coeff = inter_coeff > 1.0 - ts ? 1.0 : inter_coeff;
|
||||
MP_DBG(p, "inter frame ppts: %lld, pts: %lld, "
|
||||
|
||||
@@ -617,6 +617,7 @@ static bool render_frame(struct vo *vo)
|
||||
struct frame_timing t = (struct frame_timing) {
|
||||
.pts = pts,
|
||||
.next_vsync = next_vsync,
|
||||
.prev_vsync = prev_vsync,
|
||||
};
|
||||
vo->driver->draw_image_timed(vo, img, &t);
|
||||
} else {
|
||||
|
||||
@@ -155,6 +155,7 @@ struct vo_extra {
|
||||
struct frame_timing {
|
||||
int64_t pts;
|
||||
int64_t next_vsync;
|
||||
int64_t prev_vsync;
|
||||
};
|
||||
|
||||
struct vo_driver {
|
||||
|
||||
+20
-9
@@ -541,6 +541,8 @@ int vo_x11_init(struct vo *vo)
|
||||
|
||||
xrandr_read(x11);
|
||||
|
||||
vo_x11_update_geometry(vo);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -549,6 +551,7 @@ static const struct mp_keymap keymap[] = {
|
||||
{XK_Pause, MP_KEY_PAUSE}, {XK_Escape, MP_KEY_ESC},
|
||||
{XK_BackSpace, MP_KEY_BS}, {XK_Tab, MP_KEY_TAB}, {XK_Return, MP_KEY_ENTER},
|
||||
{XK_Menu, MP_KEY_MENU}, {XK_Print, MP_KEY_PRINT},
|
||||
{XK_Cancel, MP_KEY_CANCEL},
|
||||
|
||||
// cursor keys
|
||||
{XK_Left, MP_KEY_LEFT}, {XK_Right, MP_KEY_RIGHT}, {XK_Up, MP_KEY_UP},
|
||||
@@ -611,6 +614,13 @@ static int vo_x11_lookupkey(int key)
|
||||
if (!mpkey)
|
||||
mpkey = lookup_keymap_table(keymap, key);
|
||||
|
||||
// XFree86 keysym range; typically contains obscure "extra" keys
|
||||
if (!mpkey && key >= 0x10080001 && key <= 0x1008FFFF) {
|
||||
mpkey = MP_KEY_UNKNOWN_RESERVED_START + (key - 0x10080000);
|
||||
if (mpkey > MP_KEY_UNKNOWN_RESERVED_LAST)
|
||||
mpkey = 0;
|
||||
}
|
||||
|
||||
return mpkey;
|
||||
}
|
||||
|
||||
@@ -1532,15 +1542,16 @@ static void vo_x11_update_geometry(struct vo *vo)
|
||||
int dummy_int;
|
||||
Window dummy_win;
|
||||
Window win = x11->parent ? x11->parent : x11->window;
|
||||
if (!win)
|
||||
return;
|
||||
XGetGeometry(x11->display, win, &dummy_win, &dummy_int, &dummy_int,
|
||||
&w, &h, &dummy_int, &dummy_uint);
|
||||
if (w > INT_MAX || h > INT_MAX)
|
||||
w = h = 0;
|
||||
XTranslateCoordinates(x11->display, win, x11->rootwin, 0, 0,
|
||||
&x, &y, &dummy_win);
|
||||
x11->winrc = (struct mp_rect){x, y, x + w, y + h};
|
||||
x11->winrc = (struct mp_rect){0, 0, 0, 0};
|
||||
if (win) {
|
||||
XGetGeometry(x11->display, win, &dummy_win, &dummy_int, &dummy_int,
|
||||
&w, &h, &dummy_int, &dummy_uint);
|
||||
if (w > INT_MAX || h > INT_MAX)
|
||||
w = h = 0;
|
||||
XTranslateCoordinates(x11->display, win, x11->rootwin, 0, 0,
|
||||
&x, &y, &dummy_win);
|
||||
x11->winrc = (struct mp_rect){x, y, x + w, y + h};
|
||||
}
|
||||
double fps = 1000.0;
|
||||
for (int n = 0; n < x11->num_displays; n++) {
|
||||
struct xrandr_display *disp = &x11->displays[n];
|
||||
|
||||
+8
-8
@@ -297,30 +297,30 @@ def build(ctx):
|
||||
( "video/filter/vf.c" ),
|
||||
( "video/filter/vf_buffer.c" ),
|
||||
( "video/filter/vf_crop.c" ),
|
||||
( "video/filter/vf_delogo.c" ),
|
||||
( "video/filter/vf_delogo.c", "libavfilter"),
|
||||
( "video/filter/vf_dlopen.c", "dlopen" ),
|
||||
( "video/filter/vf_dsize.c" ),
|
||||
( "video/filter/vf_eq.c" ),
|
||||
( "video/filter/vf_expand.c" ),
|
||||
( "video/filter/vf_flip.c" ),
|
||||
( "video/filter/vf_format.c" ),
|
||||
( "video/filter/vf_gradfun.c" ),
|
||||
( "video/filter/vf_hqdn3d.c" ),
|
||||
( "video/filter/vf_gradfun.c", "libavfilter"),
|
||||
( "video/filter/vf_hqdn3d.c", "libavfilter"),
|
||||
( "video/filter/vf_lavfi.c", "libavfilter"),
|
||||
( "video/filter/vf_mirror.c" ),
|
||||
( "video/filter/vf_noformat.c" ),
|
||||
( "video/filter/vf_noise.c" ),
|
||||
( "video/filter/vf_pullup.c" ),
|
||||
( "video/filter/vf_rotate.c" ),
|
||||
( "video/filter/vf_noise.c", "libavfilter"),
|
||||
( "video/filter/vf_pullup.c", "libavfilter"),
|
||||
( "video/filter/vf_rotate.c", "libavfilter"),
|
||||
( "video/filter/vf_scale.c" ),
|
||||
( "video/filter/vf_screenshot.c" ),
|
||||
( "video/filter/vf_stereo3d.c" ),
|
||||
( "video/filter/vf_sub.c" ),
|
||||
( "video/filter/vf_unsharp.c" ),
|
||||
( "video/filter/vf_unsharp.c", "libavfilter"),
|
||||
( "video/filter/vf_vapoursynth.c", "vapoursynth-core" ),
|
||||
( "video/filter/vf_vavpp.c", "vaapi-vpp"),
|
||||
( "video/filter/vf_vdpaupp.c", "vdpau" ),
|
||||
( "video/filter/vf_yadif.c" ),
|
||||
( "video/filter/vf_yadif.c", "libavfilter"),
|
||||
( "video/out/aspect.c" ),
|
||||
( "video/out/bitmap_packer.c" ),
|
||||
( "video/out/cocoa/video_view.m", "cocoa" ),
|
||||
|
||||
Reference in new issue
Block a user