Compare commits

..
19 Commits
Author SHA1 Message Date
Martin Herkt 1e00bcc14c Release 0.18.1 2016-07-10 02:20:08 +02:00
Martin Herkt 7635438592 Merge branch 'master' into release/current 2016-07-10 01:06:17 +02:00
Martin Herkt 69e7b0d3ea Release 0.18.0 2016-06-25 03:23:40 +02:00
Martin Herkt ad56f2c46a Merge branch 'master' into release/current 2016-06-25 02:25:44 +02:00
Martin Herkt 0536841647 Release 0.17.0 2016-04-11 19:10:54 +02:00
Martin Herkt 0803f4ad21 Merge branch 'master' into release/current 2016-04-11 17:42:55 +02:00
Martin Herkt 9d2980dab7 Release 0.16.0 2016-02-29 00:22:04 +01:00
Martin Herkt 21cd4ff05b Merge branch 'master' into release/current 2016-02-28 23:31:51 +01:00
Martin Herkt d1d6257731 Release 0.15.0 2016-01-18 07:28:12 +01:00
Martin Herkt ba9b2f1e49 Merge branch 'master' into release/current 2016-01-18 07:27:03 +01:00
Martin Herkt e1993d5ad2 Release 0.14.0 2015-12-11 19:20:29 +01:00
Martin Herkt 0607dcebff Merge branch 'master' into release/current 2015-12-11 18:33:38 +01:00
Martin Herkt a33a44cf4e Release 0.13.0 2015-11-10 19:14:14 +01:00
Martin Herkt 273607c1c6 Merge branch 'master' into release/current 2015-11-10 18:45:08 +01:00
Martin Herkt 5b7d0fbab3 Release 0.12.0 2015-10-29 03:49:43 +01:00
Martin Herkt ec567d8a77 Merge branch 'master' into release/current 2015-10-29 02:56:49 +01:00
Martin Herkt f8c57433b9 Release 0.11.0 2015-09-23 01:13:22 +02:00
Martin Herkt ead2933792 Merge branch 'master' into release/current 2015-09-23 01:12:42 +02:00
Martin Herkt 181e1377b2 Release 0.10.0 2015-09-03 19:59:59 +02:00
478 changed files with 15384 additions and 28023 deletions

No files matched your search

+3 -12
View File
@@ -8,16 +8,7 @@ If you're not using git master or the latest release, update.
### Actual behavior
### Log file
### Log files
Make a log file made with -v or --log-file=output.txt, paste it to
http://sprunge.us or a similar site, and replace this text with a link to it.
Providing a log file is strongly encouraged. It is very helpful for reproducing
bugs or getting important technical context. Without a log it might not be
possible to analyze and fix certain bugs.
### Sample files
Sample files needed to reproduce this issue can be uploaded to https://0x0.st/
or similar sites. (Only needed if the issue cannot be reproduced without it.)
Make a log file made with -v or --log-file=output.txt, paste it to sprunge.us,
and replace this text with a link to it.
-1
View File
@@ -19,7 +19,6 @@
/demux/ebml_types.h
/sub/osd_font.h
/player/lua/*.inc
/player/builtin_conf.inc
/DOCS/man/mpv.1
/DOCS/man/mpv.aux
/DOCS/man/mpv.log
+1 -4
View File
@@ -2,7 +2,7 @@ language: c
os:
- linux
#- osx
- osx
env:
matrix:
- LIBAV=libav-stable
@@ -12,8 +12,6 @@ env:
global:
# Coverity token
- secure: "H21mSRlMhk4BKS0xHZvCFGJxteCP0hRVUxTuNfM2Z9HBsyutuLEYMtViLO86VtM+Tqla3xXPzUdS4ozLwI72Ax/5ZUDXACROj73yW6QhFB5D6rLut12+FjqC7M33Qv2hl0xwgNBmR5dsm1ToP37+Wn+ecJQNvN8fkTXF+HVzOEw="
# Travis token for mpv.io
- secure: "nlTVLJK6kRhtXvhKCoJ3YdFGHuKaq/eHowfPw25hqRWuBOZd+HjHY5KIYjV7SxuKFDpJE4GpNcvA3Q31nsqomxpkLYgrwjg6TSazN7ZP+x85ZgV1QGFebrPfGm2n5UR5CAPAwFoeF3pZheLi4bajVzwq1fWW+x3grS188P9OZso="
compiler:
- clang
- gcc
@@ -44,7 +42,6 @@ script:
- ./bootstrap.py
- ./waf configure
- ./waf build
after_script: TOOLS/travis-rebuild-website
notifications:
email: false
+1 -10
View File
@@ -4,9 +4,7 @@ mpv as a whole is licensed as GPL version 2 or later (see LICENSE). Most source
files are GPLv2+, but some files are available under a more liberal license,
such as LGPLv2.1+, BSD, MIT, ISC, and possibly others. Look at the copyright
header of each source file, and grep the sources for "Copyright" if you need
to know details. C source files without Copyright notice are licensed as
LGPLv2.1+. Also see the list of files with specific licenses below (not all
files can have a standard license header).
to know details. Files without Copyright notice are licensed as LGPLv2.1+.
All new contributions must be LGPLv2.1+ licensed, or if the changes are done on
GPL code, must come with the implicit agreement that the project can relicense
@@ -27,10 +25,3 @@ In particular, this affects the file libmpdemux/demux_ty_osd.c. It is disabled
under mplayer2, and has been removed from mpv.
"v2.1+" in this context means "version 2.1 or later".
Source files with specific licenses:
- everything under etc/ is unknown
- everything under DOCS/man/ is GPLv2+
- sub/osd_font.otf is LGPLv2.1+
- some tests under waftools/fragments/ might be GPLv2+
- version.sh is GPLv2+
-26
View File
@@ -32,32 +32,6 @@ API changes
::
--- mpv 0.25.0 ---
1.24 - add a MPV_ENABLE_DEPRECATED preprocessor symbol, which can be defined
by the user to exclude deprecated API symbols from the C headers
--- mpv 0.23.0 ---
1.24 - the deprecated mpv_suspend() and mpv_resume() APIs now do nothing.
--- mpv 0.22.0 ---
1.23 - deprecate setting "no-" options via mpv_set_option*(). For example,
instead of "no-video=" you should set "video=no".
- do not override the SIGPIPE signal handler anymore. This was done as
workaround for the FFmpeg TLS code, which has been fixed long ago.
- deprecate mpv_suspend() and mpv_resume(). They will be stubbed out
in mpv 0.23.0.
- make mpv_set_property() work to some degree before mpv_initialize().
It can now be used instead of mpv_set_option().
- semi-deprecate mpv_set_option()/mpv_set_option_string(). You should
use mpv_set_property() instead. There are some deprecated properties
which conflict with some options (see client.h remarks on
mpv_set_option()), for which mpv_set_option() might still be required.
In future mpv releases, the conflicting deprecated options/properties
will be removed, and mpv_set_option() will internally translate API
calls to mpv_set_property().
- qthelper.hpp: deprecate get_property_variant, set_property_variant,
set_option_variant, command_variant, and replace them with
get_property, set_property, command.
--- mpv 0.19.0 ---
1.22 - add stream_cb API for custom protocols
--- mpv 0.18.1 ---
---- - remove "status" log level from mpv_request_log_messages() docs. This
is 100% equivalent to "v". The behavior is still the same, thus no
+15 -29
View File
@@ -104,10 +104,10 @@ Installing MSYS2
It doesn't matter whether the i686 or the x86_64 version is used. Both can
build 32-bit and 64-bit binaries when running on a 64-bit version of Windows.
2. Start a MinGW-w64 shell (``mingw64.exe``). Note that this is different
2. Start a MinGW-w64 shell (``mingw64_shell.bat``). Note that this is different
from the MSYS2 shell that is started from the final installation dialog.
For a 32-bit build, use ``mingw32.exe``.
For a 32-bit build, use ``mingw32_shell.bat``.
Updating MSYS2
--------------
@@ -118,7 +118,7 @@ separately.
```bash
# Check for core updates. If instructed, close the shell window and reopen it
# before continuing.
pacman -Syu
update-core
# Update everything else
pacman -Su
@@ -166,28 +166,13 @@ Or, compile and install both libmpv and mpv:
./waf configure CC=gcc.exe --check-c-compiler=gcc --enable-libmpv-shared --prefix=/mingw64
./waf install
# waf installs libmpv dll to the wrong directory, so fix it up
mv -f /mingw64/lib/mpv-1.dll /mingw64/bin/
# waf installs libmpv to the wrong directory, so fix it up
mv -f /mingw64/bin/pkgconfig/mpv.pc /mingw64/lib/pkgconfig/
mv -f /mingw64/bin/libmpv.dll.a /mingw64/lib/
sed -i 's_/mingw64/bin_/mingw64/lib_' /mingw64/lib/pkgconfig/mpv.pc
rmdir /mingw64/bin/pkgconfig
```
Linking libmpv with MSVC programs
---------------------------------
You can build C++ programs in Visual Studio and link them with libmpv. To do
this, you need a Visual Studio which supports ``stdint.h`` (recent ones do),
and you need to create a import library for the mpv DLL:
```bash
lib /def:mpv.def /name:mpv-1.dll /out:mpv.lib /MACHINE:X64
```
The string in the ``/name:`` parameter must match the filename of the DLL (this
is simply the filename the MSVC linker will use). The ``mpv.def`` can be
retrieved from the mpv build directory, or can be produced by MingGW's
gendef.exe helper from the mpv DLL.
Static linking is not possible.
Running mpv
-----------
@@ -205,10 +190,11 @@ DLLs in that folder. The simplest solution is to add ``C:\msys64\mingw64\bin``
to the windows system ``%PATH%``. Beware though that this can cause problems or
confusion in Cygwin if that is also installed on the machine.
Use of the ANGLE OpenGL backend requires a copy of the D3D compiler DLL that
matches the version of the D3D SDK that ANGLE was built with
(``d3dcompiler_43.dll`` in case of MinGW-built ANGLE) in the path or in the
same folder as mpv. It must be of the same architecture (x86_64 / i686) as the
mpv you compiled. You can find copies here:
Use of the ANGLE OpenGL backend requires a copy of ``d3dcompiler_43.dll`` (yes,
exactly 43) in the path or in the same folder as mpv. It must be of the same
architecture (x86_64 / i686) as the mpv you compiled. You can find a copy in the
official mpv builds:
https://mpv.srsfckn.biz/d3dcompiler.7z
https://mpv.srsfckn.biz/mpv-x86_64-20160118.7z
https://mpv.srsfckn.biz/mpv-i686-20160118.7z
+6 -4
View File
@@ -101,16 +101,18 @@ mpv uses C99 with K&R formatting, with some exceptions.
do_something();
}
```
- If the if has an else branch, both branches should use braces, even if they're
technically redundant.
- If the body of an if statement uses braces, the else branch should also
use braces (and reverse).
Example:
```C
if (a) {
one_line();
// do something
something();
something_else();
} else {
one_other_line();
one_line();
}
```
- If an if condition spans multiple physical lines, then put the opening brace
+3 -40
View File
@@ -51,8 +51,7 @@ The rest of the lines belong to one of these classes:
1) An empty or commented line. A comment starts with ``#``, which must be the
first character in the line. The rest of the line (up until the next line
break) is ignored. An empty line has 0 bytes between two line feed bytes.
2) A header entry if the line starts with ``!``.
3) A segment entry in all other cases.
2) A segment entry in all other cases.
Each segment entry consists of a list of named or unnamed parameters.
Parameters are separated with ``,``. Named parameters consist of a name,
@@ -64,8 +63,8 @@ Syntax::
segment_entry ::= <param> ( <param> ',' )*
param ::= [ <name> '=' ] ( <value> | '%' <number> '%' <valuebytes> )
The ``name`` string can consist of any characters, except ``=%,;\n!``. The
``value`` string can consist of any characters except of ``,;\n!``.
The ``name`` string can consist of any characters, except ``=%,;\n``. The
``value`` string can consist of any characters except of ``,;\n``.
The construct starting with ``%`` allows defining any value with arbitrary
contents inline, where ``number`` is an integer giving the number of bytes in
@@ -95,42 +94,6 @@ to ``20``, ``param3`` to ``value,escaped``, ``param4`` to ``value2``.
Instead of line breaks, the character ``;`` can be used. Line feed bytes and
``;`` are treated equally.
Header entries start with ``!`` as first character after a line break. Header
entries affect all other file entries in the EDL file. Their format is highly
implementation specific. They should generally follow the file header, and come
before any file entries.
MP4 DASH
========
This is a header that helps implementing DASH, although it only provides a low
level mechanism.
If this header is set, the given url designates an mp4 init fragment. It's
downloaded, and every URL in the EDL is prefixed with the init fragment on the
byte stream level. This is mostly for use by mpv's internal ytdl support. The
ytdl script will call youtube-dl, which in turn actually processes DASH
manifests. It may work only for this very specific purpose and fail to be
useful in other scenarios. It can be removed or changed in incompatible ways
at any times.
Example::
!mp4_dash,init=url
The ``url`` is encoded as parameter value as defined in the general EDL syntax.
It's expected to point to an "initialization fragment", which will be prefixed
to every entry in the EDL on the byte stream level.
The current implementation will
- ignore stream start times
- use durations as hint for seeking only
- not adjust source timestamps
- open and close segments (i.e. fragments) as needed
- not add segment boundaries as chapter points
- require full compatibility between all segments (same codec etc.)
Timestamp format
================
+1 -169
View File
@@ -19,179 +19,11 @@ Interface changes
::
--- mpv 0.25.0 ---
- remove opengl-cb dxva2 dummy hwdec interop
(see git "vo_opengl: remove dxva2 dummy hwdec backend")
- remove ppm, pgm, pgmyuv, tga choices from the --screenshot-format and
--vo-image-format options
- the "jpeg" choice in the option above now leads to a ".jpg" file extension
- --af=drc is gone (you can use e.g. lavfi/acompressor instead)
- remove image_size predefined uniform from OpenGL user shaders. Use
input_size instead
- add --sub-filter-sdh
- add --sub-filter-sdh-harder
- remove --input-app-events option (macOS)
- deprecate most --vf and --af filters. Only some filters not in libavfilter
will be kept.
Also, you can use libavfilter filters directly (e.g. you can use
--vf=name=opts instead of --vf=lavfi=[name=opts]), as long as the
libavfilter filter's name doesn't clash with a mpv builtin filter.
In the long term, --vf/--af syntax might change again, but if it does, it
will switch to libavfilter's native syntax. (The above mentioned direct
support for lavfi filters still has some differences, such as how strings
are escaped.) If this happens, the non-deprecated builtin filters might be
moved to "somewhere else" syntax-wise.
- deprecate --loop - after a deprecation period, it will be undeprecated,
but changed to alias --loop-file
- add --keep-open-pause=no
- deprecate --demuxer-max-packets
- change --audio-file-auto default from "exact" to "no" (mpv won't load
files with the same filename as the video, but different extension, as
audio track anymore)
--- mpv 0.24.0 ---
- deprecate --hwdec-api and replace it with --opengl-hwdec-interop.
The new option accepts both --hwdec values, as well as named backends.
A minor difference is that --hwdec-api=no (which used to be the default)
now actually does not preload any interop layer, while the new default
("") uses the value of --hwdec.
- drop deprecated --ad/--vd features
- drop deprecated --sub-codepage syntax
- rename properties:
- "drop-frame-count" to "decoder-frame-drop-count"
- "vo-drop-frame-count" to "frame-drop-count"
The old names still work, but are deprecated.
- remove the --stream-capture option and property. No replacement.
(--record-file might serve as alternative)
- add --sub-justify
- add --sub-ass-justify
- internally there's a different way to enable the demuxer cache now
it can be auto-enabled even if the stream cache remains disabled
--- mpv 0.23.0 ---
- remove deprecated vf_vdpaurb (use "--hwdec=vdpau-copy" instead)
- the following properties now have new semantics:
- "demuxer" (use "current-demuxer")
- "fps" (use "container-fps")
- "idle" (use "idle-active")
- "cache" (use "cache-percent")
- "audio-samplerate" (use "audio-params/samplerate")
- "audio-channels" (use "audio-params/channel-count")
- "audio-format" (use "audio-codec-name")
(the properties equivalent to the old semantics are in parentheses)
- remove deprecated --vo and --ao sub-options (like --vo=opengl:...), and
replace them with global options. A somewhat complete list can be found
here: https://github.com/mpv-player/mpv/wiki/Option-replacement-list#mpv-0210
- remove --vo-defaults and --ao-defaults as well
- remove deprecated global sub-options (like -demuxer-rawaudio format=...),
use flat options (like --demuxer-rawaudio-format=...)
- the --sub-codepage option changes in incompatible ways:
- detector-selection and fallback syntax is deprecated
- enca/libguess are removed and deprecated (behaves as if they hadn't
been compiled-in)
- --sub-codepage=<codepage> does not force the codepage anymore
(this requires different and new syntax)
- remove --fs-black-out-screens option for macOS
- change how spdif codecs are selected. You can't enable spdif passthrough
with --ad anymore. This was deprecated; use --audio-spdif instead.
- deprecate the "family" selection with --ad/--vd
forcing/excluding codecs with "+", "-", "-" is deprecated as well
- explicitly mark --ad-spdif-dtshd as deprecated (it was done so a long time
ago, but it didn't complain when using the option)
--- mpv 0.22.0 ---
- the "audio-device-list" property now sets empty device description to the
device name as a fallback
- add --hidpi-window-scale option for macOS
- add audiounit audio output for iOS
- make --start-time work with --rebase-start-time=no
- add --opengl-early-flush=auto mode
- add --hwdec=vdpau-copy, deprecate vf_vdpaurb
- add tct video output for true-color and 256-color terminals
--- mpv 0.21.0 ---
- unlike in older versions, setting options at runtime will now take effect
immediately (see for example issue #3281). On the other hand, it will also
do runtime verification and reject option changes that do not work
(example: setting the "vf" option to a filter during playback, which fails
to initialize - the option value will remain at its old value). In general,
"set name value" should be mostly equivalent to "set options/name value"
in cases where the "name" property is not deprecated and "options/name"
exists - deviations from this are either bugs, or documented as caveats
in the "Inconsistencies between options and properties" manpage section.
- deprecate _all_ --vo and --ao suboptions. Generally, all suboptions are
replaced by global options, which do exactly the same. For example,
"--vo=opengl:scale=nearest" turns into "--scale=nearest". In some cases,
the global option is prefixed, e.g. "--vo=opengl:pbo" turns into
"--opengl-pbo".
Most of the exact replacements are documented here:
https://github.com/mpv-player/mpv/wiki/Option-replacement-list
- remove --vo=opengl-hq. Set --profile=opengl-hq instead. Note that this
profile does not force the VO. This means if you use the --vo option to
set another VO, it won't work. But this also means it can be used with
opengl-cb.
- remove the --vo=opengl "pre-shaders", "post-shaders" and "scale-shader"
sub-options: they were deprecated in favor of "user-shaders"
- deprecate --vo-defaults (no replacement)
- remove the vo-cmdline command. You can set OpenGL renderer options
directly via properties instead.
- deprecate the device/sink options on all AOs. Use --audio-device instead.
- deprecate "--ao=wasapi:exclusive" and "--ao=coreaudio:exclusive",
use --audio-exclusive instead.
- subtle changes in how "--no-..." options are treated mean that they are
not accessible under "options/..." anymore (instead, these are resolved
at parsing time). This does not affect options which start with "--no-",
but do not use the mechanism for negation options.
(Also see client API change for API version 1.23.)
- rename the following properties
- "demuxer" -> "current-demuxer"
- "fps" -> "container-fps"
- "idle" -> "idle-active"
- "cache" -> "cache-percent"
the old names are deprecated and will change behavior in mpv 0.23.0.
- remove deprecated "hwdec-active" and "hwdec-detected" properties
- deprecate the ao and vo auto-profiles (they never made any sense)
- deprecate "--vo=direct3d_shaders" - use "--vo=direct3d" instead.
Change "--vo=direct3d" to always use shaders by default.
- deprecate --playlist-pos option, renamed to --playlist-start
- deprecate the --chapter option, as it is redundant with --start/--end,
and conflicts with the semantics of the "chapter" property
- rename --sub-text-* to --sub-* and --ass-* to --sub-ass-* (old options
deprecated)
- incompatible change to cdda:// protocol options: the part after cdda://
now always sets the device, not the span or speed to be played. No
separating extra "/" is needed. The hidden --cdda-device options is also
deleted (it was redundant with the documented --cdrom-device).
- deprecate --vo=rpi. It will be removed in mpv 0.23.0. Its functionality
was folded into --vo=opengl, which now uses RPI hardware decoding by
treating it as a hardware overlay (without applying GL filtering). Also
to be changed in 0.23.0: the --fs flag will be reset to "no" by default
(like on the other platforms).
- deprecate --mute=auto (informally has been since 0.18.1)
- deprecate "resume" and "suspend" IPC commands. They will be completely
removed in 0.23.0.
- deprecate mp.suspend(), mp.resume(), mp.resume_all() Lua scripting
commands, as well as setting mp.use_suspend. They will be completely
removed in 0.23.0.
- the "seek" command's absolute seek mode will now interpret negative
seek times as relative from the end of the file (and clamps seeks that
still go before 0)
- add almost all options to the property list, meaning you can change
options without adding "options/" to the property name (a new section
has been added to the manpage describing some conflicting behavior
between options and properties)
- implement changing sub-speed during playback
- make many previously fixed options changeable at runtime (for example
--terminal, --osc, --ytdl, can all be enable/disabled after
mpv_initialize() - this can be extended to other still fixed options
on user requests)
--- mpv 0.20.0 ---
- add --image-display-duration option - this also means that image duration
is not influenced by --mf-fps anymore in the general case (this is an
incompatible change)
--- mpv 0.19.0 ---
- deprecate "balance" option/property (no replacement)
--- mpv 0.18.1 ---
- deprecate --heartbeat-cmd
- remove --softvol=no capability:
- deprecate --softvol, it now does nothing
- --volume, --mute, and the corresponding properties now always control
- --volume, --mute, and the corrsponding properties now always control
softvol, and behave as expected without surprises (e.g. you can set
them normally while no audio is initialized)
- rename --softvol-max to --volume-max (deprecated alias is added)
+14
View File
@@ -0,0 +1,14 @@
Client API (libmpv) documentation and examples
==============================================
libmpv lets you embed mpv as a library. It is meant to enable development of
GUI frontends.
Since libmpv merely allows access to underlying mechanisms that can control
mpv, documentation is spread over a few places:
- https://github.com/mpv-player/mpv/blob/master/libmpv/client.h
- http://mpv.io/manual/master/#options
- http://mpv.io/manual/master/#list-of-input-commands
- http://mpv.io/manual/master/#properties
- https://github.com/mpv-player/mpv-examples/tree/master/libmpv
+78 -22
View File
@@ -4,8 +4,8 @@ AUDIO FILTERS
Audio filters allow you to modify the audio stream and its properties. The
syntax is:
``--af=...``
Setup a chain of audio filters. See ``--vf`` for the syntax.
``--af=<filter1[=parameter1:parameter2:...],filter2,...>``
Setup a chain of audio filters.
.. note::
@@ -15,8 +15,27 @@ syntax is:
wrapper, which gives you access to most of libavfilter's filters. This
includes all filters that have been ported from MPlayer to libavfilter.
See ``--vf`` group of options for info on how ``--af-defaults``, ``--af-add``,
``--af-pre``, ``--af-del``, ``--af-clr``, and possibly others work.
You can also set defaults for each filter. The defaults are applied before the
normal filter parameters.
``--af-defaults=<filter1[=parameter1:parameter2:...],filter2,...>``
Set defaults for each filter.
Audio filters are managed in lists. There are a few commands to manage the
filter list:
``--af-add=<filter1[,filter2,...]>``
Appends the filters given as arguments to the filter list.
``--af-pre=<filter1[,filter2,...]>``
Prepends the filters given as arguments to the filter list.
``--af-del=<index1[,index2,...]>``
Deletes the filters at the given indexes. Index numbers start at 0,
negative numbers address the end of the list (-1 is the last).
``--af-clr``
Completely empties the filter list.
Available filters are:
@@ -293,12 +312,56 @@ Available filters are:
``mpv '--af=format=channels=5.1' '--audio-channels=5.1'`` would always force
remixing audio to 5.1 and output it like this.
This filter supports the following ``af-command`` commands:
``delay[=[ch1,ch2,...]]``
Delays the sound to the loudspeakers such that the sound from the
different channels arrives at the listening position simultaneously. It is
only useful if you have more than 2 loudspeakers.
``set-matrix``
Set the ``<matrix>`` argument dynamically. This can be used to change
the mixing matrix at runtime, without reinitializing the entire filter
chain.
``[ch1,ch2,...]``
The delay in ms that should be imposed on each channel (floating point
number between 0 and 1000).
To calculate the required delay for the different channels, do as follows:
1. Measure the distance to the loudspeakers in meters in relation to your
listening position, giving you the distances s1 to s5 (for a 5.1
system). There is no point in compensating for the subwoofer (you will
not hear the difference anyway).
2. Subtract the distances s1 to s5 from the maximum distance, i.e.
``s[i] = max(s) - s[i]; i = 1...5``.
3. Calculate the required delays in ms as ``d[i] = 1000*s[i]/342; i =
1...5``.
.. admonition:: Example
``mpv --af=delay=[10.5,10.5,0,0,7,0] media.avi``
Would delay front left and right by 10.5 ms, the two rear channels
and the subwoofer by 0 ms and the center channel by 7 ms.
``drc[=method:target]``
Applies dynamic range compression. This maximizes the volume by compressing
the audio signal's dynamic range. (Formerly called ``volnorm``.)
``<method>``
Sets the used method.
1
Use a single sample to smooth the variations via the standard
weighted mean over past samples (default).
2
Use several samples to smooth the variations via the standard
weighted mean over past samples.
``<target>``
Sets the target amplitude as a fraction of the maximum for the sample
type (default: 0.25).
.. note::
This filter can cause distortion with audio signals that have a very
large dynamic range.
``scaletempo[=option1:option2:...]``
Scales audio tempo without altering pitch, optionally synced to playback
@@ -359,6 +422,10 @@ Available filters are:
``mpv --af=scaletempo=stride=30:overlap=.50:search=10 media.ogg``
Would tweak the quality and performance parameters.
``mpv --af=format=float,scaletempo media.ogg``
Would make scaletempo use float code. Maybe faster on some
platforms.
``mpv --af=scaletempo=scale=1.2:speed=pitch audio.ogg``
Would play media at 1.2x normal speed, with audio at normal pitch.
Changing playback speed would change pitch, leaving audio tempo at
@@ -367,13 +434,9 @@ Available filters are:
``rubberband``
High quality pitch correction with librubberband. This can be used in place
of ``scaletempo``, and will be used to adjust audio pitch when playing
at speed different from normal. It can also be used to adjust audio pitch
without changing playback speed.
at speed different from normal.
``<pitch-scale>``
Sets the pitch scaling factor. Frequencies are multiplied by this value.
This filter has a number of additional sub-options. You can list them with
This filter has a number of sub-options. You can list them with
``mpv --af=rubberband=help``. This will also show the default values
for each option. The options are not documented here, because they are
merely passed to librubberband. Look at the librubberband documentation
@@ -382,13 +445,6 @@ Available filters are:
(The mapping of the mpv rubberband filter sub-option names and values to
those of librubberband follows a simple pattern: ``"Option" + Name + Value``.)
This filter supports the following ``af-command`` commands:
``set-pitch``
Set the ``<pitch-scale>`` argument dynamically. This can be used to
change the playback pitch at runtime. Note that speed is controlled
using the standard ``speed`` property, not ``af-command``.
``lavfi=graph``
Filter audio using FFmpeg's libavfilter.
+120 -72
View File
@@ -4,11 +4,17 @@ AUDIO OUTPUT DRIVERS
Audio output drivers are interfaces to different audio output facilities. The
syntax is:
``--ao=<driver1,driver2,...[,]>``
``--ao=<driver1[:suboption1[=value]:...],driver2,...[,]>``
Specify a priority list of audio output drivers to be used.
If the list has a trailing ',', mpv will fall back on drivers not contained
in the list.
in the list. Suboptions are optional and can mostly be omitted.
You can also set defaults for each driver. The defaults are applied before the
normal driver parameters.
``--ao-defaults=<driver1[:parameter1:parameter2:...],driver2,...>``
Set defaults for each driver.
.. note::
@@ -17,19 +23,87 @@ in the list.
where PulseAudio is used. On BSD systems, ``--ao=oss`` or ``--ao=sndio``
may work (the latter being experimental).
.. admonition:: Examples
- ``--ao=alsa,oss,`` Try the ALSA driver, then the OSS driver, then others.
- ``--ao=alsa:resample=yes:device=[plughw:0,3]`` Lets ALSA resample and
sets the device-name as first card, fourth device.
Available audio output drivers are:
``alsa`` (Linux only)
ALSA audio output driver
See `ALSA audio output options`_ for options specific to this AO.
``device=<device>``
Sets the device name. For ac3 output via S/PDIF, use an "iec958" or
"spdif" device, unless you really know how to set it correctly.
``resample=yes``
Enable ALSA resampling plugin. (This is disabled by default, because
some drivers report incorrect audio delay in some cases.)
``mixer-device=<device>``
Set the mixer device used with ``--no-softvol`` (default: ``default``).
``mixer-name=<name>``
Set the name of the mixer element (default: ``Master``). This is for
example ``PCM`` or ``Master``.
``mixer-index=<number>``
Set the index of the mixer channel (default: 0). Consider the output of
"``amixer scontrols``", then the index is the number that follows the
name of the element.
``non-interleaved``
Allow output of non-interleaved formats (if the audio decoder uses
this format). Currently disabled by default, because some popular
ALSA plugins are utterly broken with non-interleaved formats.
``ignore-chmap``
Don't read or set the channel map of the ALSA device - only request the
required number of channels, and then pass the audio as-is to it. This
option most likely should not be used. It can be useful for debugging,
or for static setups with a specially engineered ALSA configuration (in
this case you should always force the same layout with ``--audio-channels``,
or it will work only for files which use the layout implicit to your
ALSA device).
.. note::
MPlayer and mplayer2 required you to replace any ',' with '.' and
any ':' with '=' in the ALSA device name. mpv does not do this anymore.
Instead, quote the device name:
``--ao=alsa:device=[plug:surround50]``
Note that the ``[`` and ``]`` simply quote the device name. With some
shells (like zsh), you have to quote the option string to prevent the
shell from interpreting the brackets instead of passing them to mpv.
Actually, you should use the ``--audio-device`` option, instead of
setting the device directly.
.. warning::
To get multichannel/surround audio, use ``--audio-channels=auto``. The
default for this option is ``auto-safe``, which makes this audio otuput
explicitly reject multichannel output, as there is no way to detect
whether a certain channel layout is actually supported.
Handling of multichannel/surround audio changed in mpv 0.8.0 from the
behavior in MPlayer/mplayer2 and older versions of mpv.
The old behavior is that the player always downmixed to stereo by
default. The ``--audio-channels`` (or ``--channels`` before that) option
had to be set to get multichannel audio. Then playing stereo would
use the ``default`` device (which typically allows multiple programs
to play audio at the same time via dmix), while playing anything with
more channels would open one of the hardware devices, e.g. via the
``surround51`` alias (typically with exclusive access). Whether the
player would use exclusive access or not would depend on the file
being played.
The new behavior since mpv 0.8.0 always enables multichannel audio,
i.e. ``--audio-channels=auto`` is the default. However, since ALSA
provides no good way to play multichannel audio in a non-exclusive
way (without blocking other applications from using audio), the player
is restricted to the capabilities of the ``default`` device by default,
which means it supports only stereo and mono (at least with current
typical ALSA configurations). But if a hardware device is selected,
then multichannel audio will typically work.
The short story is: if you want multichannel audio with ALSA, use
``--audio-device`` to select the device (use ``--audio-device=help``
to get a list of all devices and their mpv name).
You can also try `using the upmix plugin <http://git.io/vfuAy>`_.
This setup enables multichannel audio on the ``default`` device
@@ -39,36 +113,31 @@ Available audio output drivers are:
``oss``
OSS audio output driver
The following global options are supported by this audio output:
``--oss-device``
``<dsp-device>``
Sets the audio output device (default: ``/dev/dsp``).
Deprecated, use ``--audio-device``.
``--oss-mixer-device``
``<mixer-device>``
Sets the audio mixer device (default: ``/dev/mixer``).
``--oss-mixer-channel``
``<mixer-channel>``
Sets the audio mixer channel (default: ``pcm``). Other valid values
include **vol, pcm, line**. For a complete list of options look for
``SOUND_DEVICE_NAMES`` in ``/usr/include/linux/soundcard.h``.
``jack``
JACK (Jack Audio Connection Kit) audio output driver.
JACK (Jack Audio Connection Kit) audio output driver
The following global options are supported by this audio output:
``--jack-port=<name>``
``port=<name>``
Connects to the ports with the given name (default: physical ports).
``--jack-name=<client>``
``name=<client>``
Client name that is passed to JACK (default: ``mpv``). Useful
if you want to have certain connections established automatically.
``--jack-autostart=<yes|no>``
``(no-)autostart``
Automatically start jackd if necessary (default: disabled). Note that
this tends to be unreliable and will flood stdout with server messages.
``--jack-connect=<yes|no>``
``(no-)connect``
Automatically create connections to output ports (default: enabled).
When enabled, the maximum number of output channels will be limited to
the number of available output ports.
``--jack-std-channel-layout=<waveext|any>``
``std-channel-layout=waveext|any``
Select the standard channel layout (default: waveext). JACK itself has no
notion of channel layouts (i.e. assigning which speaker a given
channel is supposed to map to) - it just takes whatever the application
@@ -88,9 +157,7 @@ Available audio output drivers are:
Automatically redirects to ``coreaudio_exclusive`` when playing compressed
formats.
The following global options are supported by this audio output:
``--coreaudio-change-physical-format=<yes|no>``
``change-physical-format=<yes|no>``
Change the physical format to one similar to the requested audio format
(default: no). This has the advantage that multichannel audio output
will actually work. The disadvantage is that it will change the
@@ -98,13 +165,11 @@ Available audio output drivers are:
setting in the ``Audio Devices`` dialog in the ``Audio MIDI Setup``
utility. Note that this does not affect the selected speaker setup.
``--coreaudio-exclusive``
Deprecated, use ``--audio-exclusive``.
``exclusive``
Use exclusive mode access. This merely redirects to
``coreaudio_exclusive``, but should be preferred over using that AO
directly.
``coreaudio_exclusive`` (Mac OS X only)
Native Mac OS X audio output driver using direct device access and
exclusive mode (bypasses the sound server).
@@ -118,21 +183,18 @@ Available audio output drivers are:
``pulse``
PulseAudio audio output driver
The following global options are supported by this audio output:
``--pulse-host=<host>``, ``--pulse-sink=<sink>``
``[<host>][:<output sink>]``
Specify the host and optionally output sink to use. An empty <host>
string uses a local connection, "localhost" uses network transfer
(most likely not what you want).
Deprecated, use ``--audio-device``.
``--pulse-buffer=<1-2000|native>``
``buffer=<1-2000|native>``
Set the audio buffer size in milliseconds. A higher value buffers
more data, and has a lower probability of buffer underruns. A smaller
value makes the audio stream react faster, e.g. to playback speed
changes. Default: 250.
``--pulse-latency-hacks=<yes|no>``
``latency-hacks=<yes|no>``
Enable hacks to workaround PulseAudio timing bugs (default: no). If
enabled, mpv will do elaborate latency calculations on its own. If
disabled, it will use PulseAudio automatically updated timing
@@ -152,67 +214,61 @@ Available audio output drivers are:
environments, such as systems where none of the other drivers
are available.
The following global options are supported by this audio output:
``--sdl-buflen=<length>``
``buflen=<length>``
Sets the audio buffer length in seconds. Is used only as a hint by the
sound system. Playing a file with ``-v`` will show the requested and
obtained exact buffer size. A value of 0 selects the sound system
default.
``--sdl-bufcnt=<count>``
``bufcnt=<count>``
Sets the number of extra audio buffers in mpv. Usually needs not be
changed.
``null``
Produces no audio output but maintains video playback speed. You can use
``--ao=null --ao-null-untimed`` for benchmarking.
Produces no audio output but maintains video playback speed. Use
``--ao=null:untimed`` for benchmarking.
The following global options are supported by this audio output:
``--ao-null-untimed``
``untimed``
Do not simulate timing of a perfect audio device. This means audio
decoding will go as fast as possible, instead of timing it to the
system clock.
``--ao-null-buffer``
``buffer``
Simulated buffer length in seconds.
``--ao-null-outburst``
``outburst``
Simulated chunk size in samples.
``--ao-null-speed``
``speed``
Simulated audio playback speed as a multiplier. Usually, a real audio
device will not go exactly as fast as the system clock. It will deviate
just a little, and this option helps to simulate this.
``--ao-null-latency``
``latency``
Simulated device latency. This is additional to EOF.
``--ao-null-broken-eof``
``broken-eof``
Simulate broken audio drivers, which always add the fixed device
latency to the reported audio playback position.
``--ao-null-broken-delay``
``broken-delay``
Simulate broken audio drivers, which don't report latency correctly.
``--ao-null-channel-layouts``
``channel-layouts``
If not empty, this is a ``,`` separated list of channel layouts the
AO allows. This can be used to test channel layout selection.
``pcm``
Raw PCM/WAVE file writer audio output
The following global options are supported by this audio output:
``--ao-pcm-waveheader=<yes|no>``
``(no-)waveheader``
Include or do not include the WAVE header (default: included). When
not included, raw PCM will be generated.
``--ao-pcm-file=<filename>``
``file=<filename>``
Write the sound to ``<filename>`` instead of the default
``audiodump.wav``. If ``no-waveheader`` is specified, the default is
``audiodump.pcm``.
``--ao-pcm-append=<yes|no>``
``(no-)append``
Append to the file, instead of overwriting it. Always use this with the
``no-waveheader`` option - with ``waveheader`` it's broken, because
it will write a WAVE header every time the file is opened.
@@ -224,19 +280,14 @@ Available audio output drivers are:
confused with RoarAudio, which is something completely
different.
The following global options are supported by this audio output:
``--rsound-host=<name/path>``
``host=<name/path>``
Set the address of the server (default: localhost). Can be either a
network hostname for TCP connections or a Unix domain socket path
starting with '/'.
``--rsound-port=<number>``
``port=<number>``
Set the TCP port used for connecting to the server (default: 12345).
Not used if connecting to a Unix domain socket.
These options are deprecated. If anyone cares enough, their functionality
can be added back using ``--audio-device``.
``sndio``
Audio output to the OpenBSD sndio sound system
@@ -245,24 +296,16 @@ Available audio output drivers are:
(Note: only supports mono, stereo, 4.0, 5.1 and 7.1 channel
layouts.)
The following global options are supported by this audio output:
``--ao-sndio-device=<device>``
``device=<device>``
sndio device to use (default: ``$AUDIODEVICE``, resp. ``snd0``).
Deprecated, use ``--audio-device``.
``wasapi``
Audio output to the Windows Audio Session API.
The following global options are supported by this audio output:
``--ao-wasapi-exclusive``
Deprecated, use ``--audio-exclusive``.
``exclusive``
Requests exclusive, direct hardware access. By definition prevents
sound playback of any other program until mpv exits.
``--ao-wasapi-device=<id>``
Deprecated, use ``--audio-device``.
``device=<id>``
Uses the requested endpoint instead of the system's default audio
endpoint. Both an ordinal number (0,1,2,...) and the GUID
String are valid; the GUID string is guaranteed to not change
@@ -270,3 +313,8 @@ Available audio output drivers are:
Also supports searching active devices by human-readable name. If more
than one device matches the name, refuses loading it.
This option is mostly deprecated in favour of the more general
``--audio-device`` option. That said, ``--audio-device=help`` will give
a list of valid device GUIDs (prefixed with ``wasapi/``), as well as
their human readable names, which should work here.
+1 -6
View File
@@ -8,11 +8,6 @@ There is no real changelog, but you can look at the following things:
https://github.com/mpv-player/mpv/releases
* The git log, which is the "real" changelog
* The files ``client-api-changes.rst`` and ``interface-changes.rst`` in the
``DOCS`` sub directoryon the git repository, which document API and user
interface changes (the latter usually documents breaking changes only, rather
than additions).
* The file ``mplayer-changes.rst`` in the ``DOCS`` sub directory on the git
repository, which used to be in place of this section. It documents some
changes that happened since mplayer2 forked off MPlayer. (Not updated
anymore.)
changes that happened since mplayer2 forked off MPlayer.
+209 -246
View File
@@ -95,7 +95,7 @@ List of Input Commands
relative (default)
Seek relative to current position (a negative value seeks backwards).
absolute
Seek to a given time (a negative value starts from the end of the file).
Seek to a given time.
absolute-percent
Seek to a given percent position.
relative-percent
@@ -159,10 +159,10 @@ List of Input Commands
``multiply <property> <factor>``
Multiplies the value of a property with the numeric factor.
``screenshot [subtitles|video|window|single|each-frame]``
``screenshot [subtitles|video|window|- [single|each-frame]]``
Take a screenshot.
Multiple flags are available (some can be combined with ``+``):
First argument:
<subtitles> (default)
Save the video image, in its original resolution, and with subtitles.
@@ -182,16 +182,6 @@ List of Input Commands
frame was dropped. This flag can be combined with the other flags,
e.g. ``video+each-frame``.
Older mpv versions required passing ``single`` and ``each-frame`` as
second argument (and did not have flags). This syntax is still understood,
but deprecated and might be removed in the future.
Setting the ``async`` flag will make encoding and writing the actual image
file asynchronous in most cases. (``each-frame`` mode ignores this flag
currently.) Requesting async screenshots too early or too often could lead
to the same filenames being chosen, and overwriting each others in undefined
order.
``screenshot-to-file "<filename>" [subtitles|video|window]``
Take a screenshot and save it to a given file. The format of the file will
be guessed by the extension (and ``--screenshot-format`` is ignored - the
@@ -204,9 +194,6 @@ List of Input Commands
Like all input command parameters, the filename is subject to property
expansion as described in `Property Expansion`_.
The ``async`` flag has an effect on this command (see ``screenshot``
command).
``playlist-next [weak|force]``
Go to the next entry on the playlist.
@@ -366,11 +353,6 @@ List of Input Commands
<level>
The minimum OSD level to show the text at (see ``--osd-level``).
``expand-text "<string>"``
Property-expand the argument and return the expanded string. This can be
used only through the client API or from a script using
``mp.command_native``. (see `Property Expansion`_).
``show-progress``
Show the progress bar, the elapsed time and the total duration of the file
on the OSD.
@@ -466,10 +448,6 @@ Input Commands that are Possibly Subject to Change
(If several filters are passed to the command, this is done for
each filter.)
A special variant is combining this with labels, and using ``@name``
without filter name and parameters as filter entry. This toggles the
enable/disable flag.
del
Remove the given filters from the video chain. Unlike in the other
cases, the second parameter is a comma separated list of filter names
@@ -505,16 +483,6 @@ Input Commands that are Possibly Subject to Change
- ``b vf set ""`` remove all video filters on ``b``
- ``c vf toggle lavfi=gradfun`` toggle debanding on ``c``
.. admonition:: Example how to toggle disabled filters at runtime
- Add something ``vf-add=@deband:!lavfi=[gradfun]`` to ``mpv.conf``. The
``@deband:`` is the label, and ``deband`` is an arbitrary, user-given
name for this filter entry. The ``!`` before the filter name disables
the filter by default. Everything after this is the normal filter name
and the filter parameters.
- Add ``a vf toggle @deband`` to ``input.conf``. This toggles the
"disabled" flag for the filter identified with ``deband``.
``cycle-values ["!reverse"] <property> "<value1>" "<value2>" ...``
Cycle through a list of values. Each invocation of the command will set the
given property to the next value in the list. The command maintains an
@@ -558,7 +526,7 @@ Input Commands that are Possibly Subject to Change
``disable-section "<section>"``
Disable the named input section. Undoes ``enable-section``.
``define-section "<section>" "<contents>" [default|force]``
``define-section "<section>" "<contents>" [default|forced]``
Create a named input section, or replace the contents of an already existing
input section. The ``contents`` parameter uses the same syntax as the
``input.conf`` file (except that using the section syntax in it is not
@@ -576,7 +544,7 @@ Input Commands that are Possibly Subject to Change
<default> (also used if parameter omitted)
Use a key binding defined by this section only if the user hasn't
already bound this key to a command.
<force>
<forced>
Always bind a key. (The input section that was made active most recently
wins if there are ambiguities.)
@@ -672,7 +640,7 @@ Input Commands that are Possibly Subject to Change
The argument is the name of the binding.
It can optionally be prefixed with the name of the script, using ``/`` as
separator, e.g. ``script-binding scriptname/bindingname``.
separator, e.g. ``script_binding scriptname/bindingname``.
For completeness, here is how this command works internally. The details
could change any time. On any matching key event, ``script-message-to``
@@ -697,6 +665,13 @@ Input Commands that are Possibly Subject to Change
(the ``ab-loop-a`` property); the second the ``B`` point, and the third
will clear both points.
``vo-cmdline "<args>"``
Reset the sub-option of the current VO. Currently works with ``opengl``
(including ``opengl-hq``). The argument is the sub-option string usually
passed to the VO on the command line. Not all sub-options can be set, but
those which can will be reset even if they don't appear in the argument.
This command might be changed or removed in the future.
``drop-buffers``
Drop audio/video/demuxer buffers, and restart from fresh. Might help with
unseekable streams that are going out of sync.
@@ -705,12 +680,11 @@ Input Commands that are Possibly Subject to Change
``screenshot-raw [subtitles|video|window]``
Return a screenshot in memory. This can be used only through the client
API. The MPV_FORMAT_NODE_MAP returned by this command has the ``w``, ``h``,
``stride`` fields set to obvious contents. The ``format`` field is set to
``stride`` fields set to obvious contents. A ``format`` field is set to
``bgr0`` by default. This format is organized as ``B8G8R8X8`` (where ``B``
is the LSB). The contents of the padding ``X`` are undefined. The ``data``
is the LSB). The contents of the padding ``X`` is undefined. The ``data``
field is of type MPV_FORMAT_BYTE_ARRAY with the actual image data. The image
is freed as soon as the result mpv_node is freed. As usual with client API
semantics, you are not allowed to write to the image data.
is freed as soon as the result node is freed.
``vf-command "<label>" "<cmd>" "<args>"``
Send a command to the filter with the given ``<label>``. Use ``all`` to send
@@ -724,17 +698,6 @@ Input Commands that are Possibly Subject to Change
``af-command "<label>" "<cmd>" "<args>"``
Same as ``vf-command``, but for audio filters.
``apply-profile "<name>"``
Apply the contents of a named profile. This is like using ``profile=name``
in a config file, except you can map it to a key binding to change it at
runtime.
There is no such thing as "unapplying" a profile - applying a profile
merely sets all option values listed within the profile.
``load-script "<path>"``
Load a script, similar to the ``--script`` option.
Undocumented commands: ``tv-last-channel`` (TV/DVB only),
``ao-reload`` (experimental/internal).
@@ -815,10 +778,8 @@ Input Command Prefixes
These prefixes are placed between key name and the actual command. Multiple
prefixes can be specified. They are separated by whitespace.
``osd-auto``
Use the default behavior for this command. This is the default for
``input.conf`` commands. Some libmpv/scripting/IPC APIs do not use this as
default, but use ``no-osd`` instead.
``osd-auto`` (default)
Use the default behavior for this command.
``no-osd``
Do not use any OSD for this command.
``osd-bar``
@@ -832,20 +793,11 @@ prefixes can be specified. They are separated by whitespace.
Combine osd-bar and osd-msg.
``raw``
Do not expand properties in string arguments. (Like ``"${property-name}"``.)
This is the default for some libmpv/scripting/IPC APIs.
``expand-properties``
``expand-properties`` (default)
All string arguments are expanded as described in `Property Expansion`_.
This is the default for ``input.conf`` commands.
``repeatable``
For some commands, keeping a key pressed doesn't run the command repeatedly.
This prefix forces enabling key repeat in any case.
``async``
Allow asynchronous execution (if possible). Note that only a few commands
will support this (usually this is explicitly documented). Some commands
are asynchronous by default (or rather, their effects might manifest
after completion of the command). The semantics of this flag might change
in the future. Set it only if you don't rely on the effects of this command
being fully realized when it returns.
All of the osd prefixes are still overridden by the global ``--osd-level``
settings.
@@ -857,7 +809,7 @@ Input sections group a set of bindings, and enable or disable them at once.
In ``input.conf``, each key binding is assigned to an input section, rather
than actually having explicit text sections.
See also: ``enable-section`` and ``disable-section`` commands.
See also: ``enable_section`` and ``disable_section`` commands.
Predefined bindings:
@@ -886,12 +838,20 @@ an option at runtime.
Property list
-------------
.. note::
``osd-level`` (RW)
See ``--osd-level``.
Most options can be set as runtime via properties as well. Just remove the
leading ``--`` from the option name. These are not documented. Only
properties which do not exist as option with the same name, or which have
very different behavior from the options are documented below.
``osd-scale`` (RW)
OSD font size multiplier, see ``--osd-scale``.
``loop`` (RW)
See ``--loop``.
``loop-file`` (RW)
See ``--loop-file`` (uses ``yes``/``no``).
``speed`` (RW)
See ``--speed``.
``audio-speed-correction``, ``video-speed-correction``
Factor multiplied with ``speed`` at which the player attempts to play the
@@ -909,12 +869,6 @@ Property list
looks better for display purposes. Use the ``path`` property to get an
unmodified filename.)
This has a sub-property:
``filename/no-ext``
Like the ``filename`` property, but if the text contains a ``.``, strip
all text after the last ``.``. Usually this removes the file extension.
``file-size``
Length in bytes of the source file/stream. (This is the same as
``${stream-end}``. For ordered chapters and such, the
@@ -951,11 +905,9 @@ Property list
list of format names, e.g. mp4 is ``mov,mp4,m4a,3gp,3g2,mj2`` (the list
may grow in the future for any format).
``current-demuxer``
``demuxer``
Name of the current demuxer. (This is useless.)
(Renamed from ``demuxer``.)
``stream-path``
Filename (full path) of the stream layer filename. (This is probably
useless. It looks like this can be different from ``path`` only when
@@ -984,19 +936,15 @@ Property list
Total A-V sync correction done. Unavailable if audio or video is
disabled.
``decoder-frame-drop-count``
``drop-frame-count``
Video frames dropped by decoder, because video is too far behind audio (when
using ``--framedrop=decoder``). Sometimes, this may be incremented in other
situations, e.g. when video packets are damaged, or the decoder doesn't
follow the usual rules. Unavailable if video is disabled.
``drop-frame-count`` is a deprecated alias.
``frame-drop-count``
``vo-drop-frame-count``
Frames dropped by VO (when using ``--framedrop=vo``).
``vo-drop-frame-count`` is a deprecated alias.
``mistimed-frame-count``
Number of video frames that were not timed correctly in display-sync mode
for the sake of keeping A/V sync. This does not include external
@@ -1035,12 +983,6 @@ Property list
Remaining length of the file in seconds. Note that the file duration is not
always exactly known, so this is an estimate.
``audio-pts`` (R)
Current audio playback position in current file in seconds. Unlike time-pos,
this updates more often than once per frame. For audio-only files, it is
mostly equivalent to time-pos, while for video-only files this property is
not available.
``playtime-remaining``
``time-remaining`` scaled by the current ``speed``.
@@ -1130,6 +1072,10 @@ Property list
"title" MPV_FORMAT_STRING
"default" MPV_FORMAT_FLAG
``ab-loop-a``, ``ab-loop-b`` (RW)
Set/get A-B loop points. See corresponding options and ``ab-loop`` command
for details.
``angle`` (RW)
Current DVD angle.
@@ -1202,12 +1148,13 @@ Property list
``af-metadata/<filter-label>``
Equivalent to ``vf-metadata/<filter-label>``, but for audio filters.
``idle-active``
``pause`` (RW)
Pause status. This is usually ``yes`` or ``no``. See ``--pause``.
``idle``
Return ``yes`` if no file is loaded, but the player is staying around
because of the ``--idle`` option.
(Renamed from ``idle``.)
``core-idle``
Return ``yes`` if the playback core is paused, otherwise ``no``. This can
be different ``pause`` in special situations, such as when the player
@@ -1263,17 +1210,6 @@ Property list
Returns ``yes`` if the demuxer is idle, which means the demuxer cache is
filled to the requested amount, and is currently not reading more data.
``demuxer-via-network``
Returns ``yes`` if the stream demuxed via the main demuxer is most likely
played via network. What constitutes "network" is not always clear, might
be used for other types of untrusted streams, could be wrong in certain
cases, and its definition might be changing. Also, external files (like
separate audio files or streams) do not influence the value of this
property (currently).
``demuxer-start-time`` (R)
Returns the start time reported by the demuxer in fractional seconds.
``paused-for-cache``
Returns ``yes`` when playback is paused because of waiting for the cache.
@@ -1294,12 +1230,25 @@ Property list
is loaded, or when switching ordered chapter segments. This is because
the same underlying code is used for seeking and resyncing.)
``hr-seek`` (RW)
See ``--hr-seek``.
``mixer-active``
Return ``yes`` if the audio mixer is active, ``no`` otherwise.
This option is relatively useless. Before mpv 0.18.1, it could be used to
infer behavior of the ``volume`` property.
``volume`` (RW)
Current volume (see ``--volume`` for details).
``volume-max`` (RW)
Current maximum value the volume property can be set to. (Equivalent to the
``--volume-max`` option.)
``mute`` (RW)
Current mute status (``yes``/``no``).
``ao-volume`` (RW)
System volume. This property is available only if mpv audio output is
currently active, and only if the underlying implementation supports volume
@@ -1311,6 +1260,9 @@ Property list
Similar to ``ao-volume``, but controls the mute state. May be unimplemented
even if ``ao-volume`` works.
``audio-delay`` (RW)
See ``--audio-delay``.
``audio-codec``
Audio codec selected for decoding.
@@ -1358,6 +1310,26 @@ Property list
Same as ``audio-params``, but the format of the data written to the audio
API.
``aid`` (RW)
Current audio track (similar to ``--aid``).
``audio`` (RW)
Alias for ``aid``.
``balance`` (RW)
Audio channel balance. (The implementation of this feature is rather odd.
It doesn't change the volumes of each channel, but instead sets up a pan
matrix to mix the left and right channels.)
``fullscreen`` (RW)
See ``--fullscreen``.
``deinterlace`` (RW)
See ``--deinterlace``.
``field-dominance`` (RW)
See ``--field-dominance``
``colormatrix`` (R)
Redirects to ``video-params/colormatrix``. This parameter (as well as
similar ones) can be overridden with the ``format`` video filter.
@@ -1365,9 +1337,42 @@ Property list
``colormatrix-input-range`` (R)
See ``colormatrix``.
``video-output-levels`` (RW)
See ``--video-output-levels``,
``colormatrix-primaries`` (R)
See ``colormatrix``.
``taskbar-progress`` (RW)
See ``--taskbar-progress``.
``ontop`` (RW)
See ``--ontop``.
``border`` (RW)
See ``--border``.
``on-all-workspaces`` (RW)
See ``--on-all-workspaces``. Unsetting may not work on all WMs.
``framedrop`` (RW)
See ``--framedrop``.
``gamma`` (RW)
See ``--gamma``.
``brightness`` (RW)
See ``--brightness``.
``contrast`` (RW)
See ``--contrast``.
``saturation`` (RW)
See ``--saturation``.
``hue`` (RW)
See ``--hue``.
``hwdec`` (RW)
Reflects the ``--hwdec`` option.
@@ -1390,8 +1395,8 @@ Property list
This is known only once the VO has opened (and possibly later). With some
VOs (like ``opengl``), this might be never known in advance, but only when
the decoder attempted to create the hw decoder successfully. (Using
``--opengl-hwdec-interop`` can load it eagerly.) If there are multiple
drivers loaded, they will be separated by ``,``.
``--hwdec-preload`` can load it eagerly.) If there are multiple drivers
loaded, they will be separated by ``,``.
If no VO is active or no interop driver is known, this property is
unavailable.
@@ -1400,8 +1405,26 @@ Property list
multiple interop drivers for the same hardware decoder, depending on
platform and VO.
This is somewhat similar to the ``--opengl-hwdec-interop`` option, but
it returns the actually loaded backend, not the value of this option.
``hwdec-active``
Deprecated. To be removed in mpv 0.20.0. Use ``hwdec-current`` instead.
Return ``yes`` or ``no``, depending on whether any type of hardware decoding
is actually in use.
``hwdec-detected``
Deprecated. To be removed in mpv 0.20.0.
If hardware decoding is active, this returns the hardware decoder in use.
Otherwise, it returns either ``no``, or if applicable, the currently loaded
hardware decoding API. This is known only once the VO has opened (and
possibly later). With some VOs (like ``opengl``), this is never known in
advance, but only when the decoder attempted to create the hw decoder
successfully. Also, hw decoders with ``-copy`` suffix will return ``no``
while no video is being decoded. All this reflects how detecting hw decoders
are detected and used internally in mpv.
``panscan`` (RW)
See ``--panscan``.
``video-format``
Video format as string.
@@ -1456,12 +1479,6 @@ Property list
``video-params/gamma``
The gamma function in use as string. (Exact values subject to change.)
``video-params/nom-peak``
The video encoding's nominal peak brightness as float.
``video-params/sig-peak``
The video file's tagged signal peak as float.
``video-params/chroma-location``
Chroma location as string. (Exact values subject to change.)
@@ -1488,9 +1505,6 @@ Property list
"colormatrix" MPV_FORMAT_STRING
"colorlevels" MPV_FORMAT_STRING
"primaries" MPV_FORMAT_STRING
"gamma" MPV_FORMAT_STRING
"nom-peak" MPV_FORMAT_DOUBLE
"sig-peak" MPV_FORMAT_DOUBLE
"chroma-location" MPV_FORMAT_STRING
"rotate" MPV_FORMAT_INT64
"stereo-in" MPV_FORMAT_STRING
@@ -1503,9 +1517,6 @@ Property list
These have the same values as ``video-out-params/dw`` and
``video-out-params/dh``.
``video-dec-params``
Exactly like ``video-params``, but no overrides applied.
``video-out-params``
Same as ``video-params``, but after video filters have been applied. If
there are no video filters in use, this will contain the same values as
@@ -1528,12 +1539,10 @@ Property list
``video-frame-info/tff``
``video-frame-info/repeat``
``container-fps``
``fps``
Container FPS. This can easily contain bogus values. For videos that use
modern container formats or video codecs, this will often be incorrect.
(Renamed from ``fps``.)
``estimated-vf-fps``
Estimated/measured FPS of the video filter chain output. (If no filters
are used, this corresponds to decoder output.) This uses the average of
@@ -1554,10 +1563,7 @@ Property list
``display-names``
Names of the displays that the mpv window covers. On X11, these
are the xrandr names (LVDS1, HDMI1, DP1, VGA1, etc.). On Windows, these
are the GDI names (\\.\DISPLAY1, \\.\DISPLAY2, etc.) and the first display
in the list will be the one that Windows considers associated with the
window (as determined by the MonitorFromWindow API.)
are the xrandr names (LVDS1, HDMI1, DP1, VGA1, etc.).
``display-fps`` (RW)
The refresh rate of the current display. Currently, this is the lowest FPS
@@ -1577,35 +1583,83 @@ Property list
``video-aspect`` (RW)
Video aspect, see ``--video-aspect``.
If video is active, this reports the effective aspect value, instead of
the value of the ``--video-aspect`` option.
``osd-width``, ``osd-height``
Last known OSD width (can be 0). This is needed if you want to use the
``overlay-add`` command. It gives you the actual OSD size, which can be
``overlay_add`` command. It gives you the actual OSD size, which can be
different from the window size in some cases.
``osd-par``
Last known OSD display pixel aspect (can be 0).
``vid`` (RW)
Current video track (similar to ``--vid``).
``video`` (RW)
Alias for ``vid``.
``video-align-x``, ``video-align-y`` (RW)
See ``--video-align-x`` and ``--video-align-y``.
``video-pan-x``, ``video-pan-y`` (RW)
See ``--video-pan-x`` and ``--video-pan-y``.
``video-zoom`` (RW)
See ``--video-zoom``.
``video-unscaled`` (W)
See ``--video-unscaled``.
``program`` (W)
Switch TS program (write-only).
``dvb-channel`` (W)
Pair of integers: card,channel of current DVB stream.
Can be switched to switch to another channel on the same card.
Can be switched to switch to another channel on the same card.
``dvb-channel-name`` (RW)
Name of current DVB program.
On write, a channel-switch to the named channel on the same
card is performed. Can also be used for channel switching.
card is performed. Can also be used for channel switching.
``sub-text``
Return the current subtitle text. Formatting is stripped. If a subtitle
is selected, but no text is currently visible, or the subtitle is not
text-based (i.e. DVD/BD subtitles), an empty string is returned.
``sid`` (RW)
Current subtitle track (similar to ``--sid``).
This property is experimental and might be removed in the future.
``secondary-sid`` (RW)
Secondary subtitle track (see ``--secondary-sid``).
``sub`` (RW)
Alias for ``sid``.
``sub-delay`` (RW)
See ``--sub-delay``.
``sub-pos`` (RW)
See ``--sub-pos``.
``sub-visibility`` (RW)
See ``--sub-visibility``.
``sub-forced-only`` (RW)
See ``--sub-forced-only``.
``sub-scale`` (RW)
Subtitle font size multiplier.
``ass-force-margins`` (RW)
See ``--ass-force-margins``.
``sub-use-margins`` (RW)
See ``--sub-use-margins``.
``ass-vsfilter-aspect-compat`` (RW)
See ``--ass-vsfilter-aspect-compat``.
``ass-style-override`` (RW)
See ``--ass-style-override``.
``stream-capture`` (RW)
A filename, see ``--stream-capture``. Setting this will start capture using
the given filename. Setting it to an empty string will stop it.
``tv-brightness``, ``tv-contrast``, ``tv-saturation``, ``tv-hue`` (RW)
TV stuff.
@@ -1742,16 +1796,6 @@ Property list
``track-list/N/audio-channels`` (deprecated)
Deprecated alias for ``track-list/N/demux-channel-count``.
``track-list/N/replaygain-track-peak``, ``track-list/N/replaygain-track-gain``
Per-track replaygain values. Only available for audio tracks with
corresponding information stored in the source file.
``track-list/N/replaygain-album-peak``, ``track-list/N/replaygain-album-gain``
Per-album replaygain values. If the file has per-track but no per-album
information, the per-album values will be copied from the per-track
values currently. It's possible that future mpv versions will make
these properties unavailable instead in this case.
When querying the property with the client API using ``MPV_FORMAT_NODE``,
or with Lua ``mp.get_property_native``, this will return a mpv_node with
the following contents:
@@ -1781,10 +1825,6 @@ Property list
"demux-samplerate" MPV_FORMAT_INT64
"demux-fps" MPV_FORMAT_DOUBLE
"audio-channels" MPV_FORMAT_INT64
"replaygain-track-peak" MPV_FORMAT_DOUBLE
"replaygain-track-gain" MPV_FORMAT_DOUBLE
"replaygain-album-peak" MPV_FORMAT_DOUBLE
"replaygain-album-gain" MPV_FORMAT_DOUBLE
``chapter-list``
List of chapters, current entry marked. Currently, the raw property value
@@ -1813,8 +1853,11 @@ Property list
"title" MPV_FORMAT_STRING
"time" MPV_FORMAT_DOUBLE
``af``, ``vf`` (RW)
See ``--vf``/``--af`` and the ``vf``/``af`` command.
``af`` (RW)
See ``--af`` and the ``af`` command.
``vf`` (RW)
See ``--vf`` and the ``vf`` command.
When querying the property with the client API using ``MPV_FORMAT_NODE``,
or with Lua ``mp.get_property_native``, this will return a mpv_node with
@@ -1826,13 +1869,18 @@ Property list
MPV_FORMAT_NODE_MAP (for each filter entry)
"name" MPV_FORMAT_STRING
"label" MPV_FORMAT_STRING [optional]
"enabled" MPV_FORMAT_FLAG [optional]
"params" MPV_FORMAT_NODE_MAP [optional]
"key" MPV_FORMAT_STRING
"value" MPV_FORMAT_STRING
It's also possible to write the property using this format.
``video-rotate`` (RW)
See ``--video-rotate`` option.
``video-stereo-mode`` (RW)
See ``--video-stereo-mode`` option.
``seekable``
Return whether it's generally possible to seek in the current file.
@@ -1971,9 +2019,8 @@ Property list
The ``name`` is what is to be passed to the ``--audio-device`` option (and
often a rather cryptic audio API-specific ID), while ``description`` is
human readable free form text. The description is set to the device name
(minus mpv-specific ``<driver>/`` prefix) if no description is available
or the description would have been an empty string.
human readable free form text. The description is an empty string if none
was received.
The special entry with the name set to ``auto`` selects the default audio
output driver and the default device.
@@ -2073,10 +2120,6 @@ Property list
require reloading the file for changes to take effect. If there is an
equivalent property, prefer setting the property instead.
There shouldn't be any reason to access ``options/<name>`` instead of
``<name>``, except in situations in which the properties have different
behavior or conflicting semantics.
``file-local-options/<name>``
Similar to ``options/<name>``, but when setting an option through this
property, the option is reset to its old value once the current file has
@@ -2130,86 +2173,6 @@ Property list
``property-list``
Return the list of top-level properties.
``profile-list``
Return the list of profiles and their contents. This is highly
implementation-specific, and may change any time. Currently, it returns
an array of options for each profile. Each option has a name and a value,
with the value currently always being a string. Note that the options array
is not a map, as order matters and duplicate entries are possible. Recursive
profiles are not expanded, and show up as special ``profile`` options.
Inconsistencies between options and properties
----------------------------------------------
You can access (almost) all options as properties, though there are some
caveats with some properties (due to historical reasons):
``vid``, ``aid``, ``sid``
While playback is active, you can set existing tracks only. (The option
allows setting any track ID, and which tracks to enable is chosen at
loading time.)
Option changes at runtime are affected by this as well.
``deinterlace``
While video is active, this behaves differently from the option. It will
never return the ``auto`` value (but the state as observed by the video
chain). If you set ``auto``, the property will set this as the option value,
and will return the actual video chain state as observed instead of auto.
``video-aspect``
While video is active, always returns the effective aspect ratio. Setting
a special value (like ``no``, values ``<= 0``) will make the property
set this as option, and return whatever actual aspect was derived from the
option setting.
``brightness`` (and other color options)
If ``--vo=xv`` is used, these properties may return the adapter's current
values instead of the option values.
``display-fps``
If a VO is created, this will return either the actual display FPS, or
an invalid value, instead of the option value.
``vf``, ``af``
If you set the properties during playback, and the filter chain fails to
reinitialize, the new value will be rejected. Setting the option or
setting the property outside of playback will always succeed/fail in the
same way. Also, there are no ``vf-add`` etc. properties, but you can use
the ``vf``/``af`` group of commands to achieve the same.
Option changes at runtime are affected by this as well.
``edition``
While a file is loaded, the property will always return the effective
edition, and setting the ``auto`` value will show somewhat strange behavior
(the property eventually switching to whatever is the default edition).
``playlist``
The property is read-only and returns the current internal playlist. The
option is for loading playlist during command line parsing. For client API
uses, you should use the ``loadlist`` command instead.
``window-scale``
Might verify the set value when setting while a window is created.
``audio-file``, ``sub-file``, ``external-file``
These options/properties are actually lists of filenames. To make the
command-line interface easier, each ``--audio-file=...`` option appends
the full string to the internal list. However, when used as properties,
every time you set the property as a string the internal list will be
replaced with a single entry containing the string you set. ``,`` or other
separators are never used. You have to use ``MPV_FORMAT_NODE_ARRAY`` (or
corresponding API, e.g. ``mp.set_property_native()`` with a table in Lua)
to set multiple entries.
Strictly speaking, option access via API (e.g. ``mpv_set_option_string()``)
has the same problem, and it's only a difference between CLI/API.
``playlist-pos``, ``chapter``
These properties behave different from the deprecated options with the same
names.
Property Expansion
------------------
+12 -2
View File
@@ -41,7 +41,7 @@ It's also possible to send input.conf style text-only commands:
::
> echo 'show-text ${playback-time}' | socat - /tmp/mpvsocket
> echo 'show_text ${playback-time}' | socat - /tmp/mpvsocket
But you won't get a reply over the socket. (This particular command shows the
playback time on the player's OSD.)
@@ -65,7 +65,7 @@ You can send commands from a command prompt:
::
echo show-text ${playback-time} >\\.\pipe\mpvsocket
echo show_text ${playback-time} >\\.\pipe\mpvsocket
To be able to simultaneously read and write from the IPC pipe, like on Linux,
it's necessary to write an external program that uses overlapped file I/O (or
@@ -241,6 +241,16 @@ extra commands can also be used as part of the protocol:
By default, most events are enabled, and there is not much use for this
command.
``suspend``
Suspend the mpv main loop. There is a long-winded explanation of this in
the C API function ``mpv_suspend()``. In short, this prevents the player
from displaying the next video frame, so that you don't get blocked when
trying to access the player.
``resume``
Undo one ``suspend`` call. ``suspend`` increments an internal counter, and
``resume`` decrements it. When 0 is reached, the player is actually resumed.
``get_version``
Returns the client API version the C API of the remote mpv instance
provides.
-75
View File
@@ -1,75 +0,0 @@
EMBEDDING INTO OTHER PROGRAMS (LIBMPV)
======================================
mpv can be embedded into other programs as video/audio playback backend. The
recommended way to do so is using libmpv. See ``libmpv/client.h`` in the mpv
source code repository. This provides a C API. Bindings for other languages
might be available (see wiki).
Since libmpv merely allows access to underlying mechanisms that can control
mpv, further documentation is spread over a few places:
- https://github.com/mpv-player/mpv/blob/master/libmpv/client.h
- http://mpv.io/manual/master/#options
- http://mpv.io/manual/master/#list-of-input-commands
- http://mpv.io/manual/master/#properties
- https://github.com/mpv-player/mpv-examples/tree/master/libmpv
C PLUGINS
=========
You can write C plugins for mpv. These use the libmpv API, although they do not
use the libmpv library itself.
Currently, they must be explicitly enabled at build time with
``--enable-cplugins``. They are available on Linux/BSD platforms only.
C plugins location
------------------
C plugins are put into the mpv scripts directory in its config directory
(see the `FILES`_ section for details). They must have a ``.so`` file extension.
They can also be explicitly loaded with the ``--script`` option.
API
---
A C plugin must export the following function::
int mpv_open_cplugin(mpv_handle *handle)
The plugin function will be called on loading time. This function does not
return as long as your plugin is loaded (it runs in its own thread). The
``handle`` will be deallocated as soon as the plugin function returns.
The return value is interpreted as error status. A value of ``0`` is
interpreted as success, while ``-1`` signals an error. In the latter case,
the player prints an uninformative error message that loading failed.
Return values other than ``0`` and ``-1`` are reserved, and trigger undefined
behavior.
Within the plugin function, you can call libmpv API functions. The ``handle``
is created by ``mpv_create_client()`` (or actually an internal equivalent),
and belongs to you. You can call ``mpv_wait_event()`` to wait for things
happening, and so on.
Note that the player might block until your plugin calls ``mpv_wait_event()``
for the first time. This gives you a chance to install initial hooks etc.
before playback begins.
The details are quite similar to Lua scripts.
Linkage to libmpv
-----------------
The current implementation requires that your plugins are **not** linked against
libmpv. What your plugins uses are not symbols from a libmpv binary, but
symbols from the mpv host binary.
Examples
--------
See:
- https://github.com/mpv-player/mpv-examples/tree/master/cplugins
+19 -34
View File
@@ -43,8 +43,9 @@ timers added with ``mp.add_timeout`` or similar.
When the player quits, all scripts will be asked to terminate. This happens via
a ``shutdown`` event, which by default will make the event loop return. If your
script got into an endless loop, mpv will probably behave fine during playback,
but it won't terminate when quitting, because it's waiting on your script.
script got into an endless loop, mpv will probably behave fine during playback
(unless the player is suspended, see ``mp.suspend``), but it won't terminate
when quitting, because it's waiting on your script.
Internally, the C code will call the Lua function ``mp_event_loop`` after
loading a Lua script. This function is normally defined by the default prelude
@@ -240,7 +241,7 @@ The ``mp`` module is preloaded, although it can be loaded manually with
This will print the message ``the key was pressed`` when ``x`` was pressed.
The user can remap these key bindings. Then the user has to put the
following into their input.conf to remap the command to the ``y`` key:
following into his input.conf to remap the command to the ``y`` key:
::
@@ -259,7 +260,7 @@ The ``mp`` module is preloaded, although it can be loaded manually with
``mp.add_forced_key_binding(...)``
This works almost the same as ``mp.add_key_binding``, but registers the
key binding in a way that will overwrite the user's custom bindings in their
key binding in a way that will overwrite the user's custom bindings in his
input.conf. (``mp.add_key_binding`` overwrites default key bindings only,
but not those by the user's input.conf.)
@@ -411,16 +412,21 @@ These also live in the ``mp`` module, but are documented separately as they
are useful only in special situations.
``mp.suspend()``
This function has been deprecated in mpv 0.21.0 and does nothing starting
with mpv 0.23.0 (no replacement).
Suspend the mpv main loop. There is a long-winded explanation of this in
the C API function ``mpv_suspend()``. In short, this prevents the player
from displaying the next video frame, so that you don't get blocked when
trying to access the player.
Before mpv 0.17.0, this was automatically called by the event handler.
``mp.resume()``
This function has been deprecated in mpv 0.21.0 and does nothing starting
with mpv 0.23.0 (no replacement).
Undo one ``mp.suspend()`` call. ``mp.suspend()`` increments an internal
counter, and ``mp.resume()`` decrements it. When 0 is reached, the player
is actually resumed.
``mp.resume_all()``
This function has been deprecated in mpv 0.21.0 and does nothing starting
with mpv 0.23.0 (no replacement).
This resets the internal suspend counter and resumes the player. (It's
like calling ``mp.resume()`` until the player is actually resumed.)
``mp.get_wakeup_pipe()``
Calls ``mpv_get_wakeup_pipe()`` and returns the read end of the wakeup
@@ -444,18 +450,6 @@ are useful only in special situations.
``mp.get_wakeup_pipe()`` if you're interested in properly working
notification of new events and working timers.
``mp.register_idle(fn)``
Register an event loop idle handler. Idle handlers are called before the
script goes to sleep after handling all new events. This can be used for
example to delay processing of property change events: if you're observing
multiple properties at once, you might not want to act on each property
change, but only when all change notifications have been received.
``mp.unregister_idle(fn)``
Undo ``mp.register_idle(fn)``. This removes all idle handlers that
are equal to the ``fn`` parameter. This uses normal Lua ``==`` comparison,
so be careful when dealing with closures.
``mp.enable_messages(level)``
Set the minimum log level of which mpv message output to receive. These
messages are normally printed to the terminal. By calling this function,
@@ -547,8 +541,8 @@ Example command-line::
--script-opts=myscript-optionA=TEST,myscript-optionB=0,myscript-optionC=yes
mp.utils functions
------------------
mp.utils options
----------------
This built-in module provides generic helper functions for Lua, and have
strictly speaking nothing to do with mpv or video/audio playback. They are
@@ -639,16 +633,7 @@ strictly part of the guaranteed API.
Set to ``true`` if the process has been killed by mpv as a result
of ``cancellable`` being set to ``true``.
``utils.subprocess_detached(t)``
Runs an external process and detaches it from mpv's control.
The parameter ``t`` is a table. The function reads the following entries:
``args``
Array of strings of the same semantics as the ``args`` used in the
``subprocess`` function.
The function returns ``nil``.
In all cases, ``mp.resume_all()`` is implicitly called.
``utils.parse_json(str [, trail])``
Parses the given string argument as JSON, and returns it as a Lua table. On
+50 -109
View File
@@ -9,8 +9,6 @@ a media player
:Manual section: 1
:Manual group: multimedia
.. contents:: Table of Contents
SYNOPSIS
========
@@ -140,16 +138,16 @@ L
Toggle infinite looping.
Ctrl + and Ctrl -
Adjust audio delay (A/V sync) by +/- 0.1 seconds.
Adjust audio delay by +/- 0.1 seconds.
u
Switch between applying no style overrides to SSA/ASS subtitles, and
overriding them almost completely with the normal subtitle style. See
``--sub-ass-style-override`` for more info.
``--ass-style-override`` for more info.
V
Toggle subtitle VSFilter aspect compatibility mode. See
``--sub-ass-vsfilter-aspect-compat`` for more info.
``--ass-vsfilter-aspect-compat`` for more info.
r and t
Move subtitles up/down.
@@ -210,6 +208,9 @@ Alt+2 (and command+2 on OSX)
command + f (OSX only)
Toggle fullscreen (see also ``--fs``).
command + [ and command + ] (OSX only)
Set video window alpha.
(The following keys are valid if you have a keyboard with multimedia keys.)
PAUSE
@@ -243,16 +244,6 @@ button 5 and button 6
USAGE
=====
Command line arguments starting with ``-`` are interpreted as options,
everything else as filenames or URLs. All options except *flag* options (or
choice options which include ``yes``) require a parameter in the form
``--option=value``.
One exception is the lone ``-`` (without anything else), which means media data
will be read from stdin. Also, ``--`` (without anything else) will make the
player interpret all following arguments as filenames, even if they start with
``-``. (To play a file named ``-``, you need to use ``./-``.)
Every *flag* option has a *no-flag* counterpart, e.g. the opposite of the
``--fs`` option is ``--no-fs``. ``--fs=yes`` is same as ``--fs``, ``--fs=no``
is the same as ``--no-fs``.
@@ -260,24 +251,6 @@ is the same as ``--no-fs``.
If an option is marked as *(XXX only)*, it will only work in combination with
the *XXX* option or if *XXX* is compiled in.
Legacy option syntax
--------------------
The ``--option=value`` syntax is not strictly enforced, and the alternative
legacy syntax ``-option value`` and ``--option value`` will also work. This is
mostly for compatibility with MPlayer. Using these should be avoided. Their
semantics can change any time in the future.
For example, the alternative syntax will consider an argument following the
option a filename. ``mpv -fs no`` will attempt to play a file named ``no``,
because ``--fs`` is a flag option that requires no parameter. If an option
changes and its parameter becomes optional, then a command line using the
alternative syntax will break.
Currently, the parser makes no difference whether an option starts with ``--``
or a single ``-``. This might also change in the future, and ``--option value``
might always interpret ``value`` as filename in order to reduce ambiguities.
Escaping spaces and other special characters
--------------------------------------------
@@ -295,16 +268,15 @@ command line.
The suboption parser can quote strings with ``"`` and ``[...]``.
Additionally, there is a special form of quoting with ``%n%`` described below.
For example, assume the hypothetical ``foo`` filter can take multiple options:
For example, the ``opengl`` VO can take multiple options:
``mpv test.mkv --vf=foo:option1=value1:option2:option3=value3,bar``
``mpv test.mkv --vo=opengl:scale=lanczos:icc-profile=file.icc,xv``
This passes ``option1`` and ``option3`` to the ``foo`` filter, with ``option2``
as flag (implicitly ``option2=yes``), and adds a ``bar`` filter after that. If
an option contains spaces or characters like ``,`` or ``:``, you need to quote
them:
This passes ``scale=lanczos`` and ``icc-profile=file.icc`` to ``opengl``,
and also specifies ``xv`` as fallback VO. If the icc-profile path contains
spaces or characters like ``,`` or ``:``, you need to quote them:
``mpv '--vf=foo:option1="option value with spaces",bar'``
``mpv '--vo=opengl:icc-profile="file with spaces.icc",xv'``
Shells may actually strip some quotes from the string passed to the commandline,
so the example quotes the string twice, ensuring that mpv receives the ``"``
@@ -325,11 +297,11 @@ It is started with ``%`` and has the following format::
.. admonition:: Examples
``mpv '--vf=foo:option1=%11%quoted text' test.avi``
``mpv --ao=pcm:file=%10%C:test.wav test.avi``
Or in a script:
``mpv --vf=foo:option1=%`expr length "$NAME"`%"$NAME" test.avi``
``mpv --ao=pcm:file=%`expr length "$NAME"`%"$NAME" test.avi``
Suboptions passed to the client API are also subject to escaping. Using
``mpv_set_option_string()`` is exactly like passing ``--name=data`` to the
@@ -337,7 +309,8 @@ command line (but without shell processing of the string). Some options
support passing values in a more structured way instead of flat strings, and
can avoid the suboption parsing mess. For example, ``--vf`` supports
``MPV_FORMAT_NODE``, which lets you pass suboptions as a nested data structure
of maps and arrays.
of maps and arrays. (``--vo`` supports this in the same way, although this
fact is undocumented.)
Paths
-----
@@ -439,7 +412,7 @@ specifying the path to the local copy: ``--dvd-device=PATH``.
Alternatively, running ``mpv PATH`` should auto-detect a DVD directory
tree and play the longest title.
.. note:: DVD library choices
.. note::
mpv uses a different default DVD library than MPlayer. MPlayer
uses libdvdread by default, and mpv uses libdvdnav by default.
@@ -452,17 +425,13 @@ tree and play the longest title.
when using libdvdnav, in which playback gets stuck in a DVD menu
stream. These problems are reported to go away when auto-selecting
the title (``dvd://`` rather than ``dvd://1``) or when using
libdvdread (e.g. ``dvdread://0``). There are also outstanding bugs
in libdvdnav with seeking backwards and forwards in a video
stream. Specify ``dvdread://...`` to fix such problems.
libdvdread (e.g. ``dvdread://0``).
.. note:: DVD subtitles
DVDs use image-based subtitles. Image subtitles are implemented as
a bitmap video stream which can be superimposed over the main
movie. mpv's subtitle styling and positioning options and keyboard
shortcuts generally do not work with image-based subtitles.
Exceptions include options like ``--stretch-dvd-subs`` and
Exceptions include options like ``--stretch-dvd-subs`` and
``--stretch-image-subs-to-screen``.
@@ -559,8 +528,7 @@ profile name ``default`` to continue with normal options.
[slow]
profile-desc="some profile name"
# reference a builtin profile
profile=opengl-hq
vo=opengl:scale=ewa_lanczos:scale-radius=16
[fast]
vo=vdpau
@@ -581,6 +549,10 @@ Some profiles are loaded automatically. The following example demonstrates this:
::
[vo.vdpau]
# Use hardware decoding
hwdec=vdpau
[protocol.dvd]
profile-desc="profile for dvd:// streams"
alang=en
@@ -589,7 +561,11 @@ Some profiles are loaded automatically. The following example demonstrates this:
profile-desc="profile for .flv files"
vf=flip
The profile name follows the schema ``type.name``, where type can be
[ao.alsa]
device=spdif
The profile name follows the schema ``type.name``, where type can be ``vo``
to match the value the ``--vo`` option is set to, ``ao`` for ``--ao``,
``protocol`` for the input/output protocol in use (see ``--list-protocols``),
and ``extension`` for the extension of the path of the currently played file
(*not* the file format).
@@ -669,7 +645,6 @@ PROTOCOLS
=========
``http://...``, ``https://``, ...
Many network protocols are supported, but the protocol prefix must always
be specified. mpv will never attempt to guess whether a filename is
actually a network address. A protocol prefix is always required.
@@ -678,36 +653,18 @@ PROTOCOLS
either aliases to documented protocols, or are just redirections to
protocols implemented and documented in FFmpeg.
``data:`` is supported in FFmpeg (not in Libav), but needs to be in the
format ``data://``. This is done to avoid ambiguity with filenames. You
can also prefix it with ``lavf://`` or ``ffmpeg://``.
``ytdl://...``
By default, the youtube-dl hook script (enabled by default for mpv CLI)
only looks at http URLs. Prefixing an URL with ``ytdl://`` forces it to
be always processed by the script. This can also be used to invoke special
youtube-dl functionality like playing a video by ID or invoking search.
Keep in mind that you can't pass youtube-dl command line options by this,
and you have to use ``--ytdl-raw-options`` instead.
``-``
Play data from stdin.
``smb://PATH``
Play a path from Samba share.
``bd://[title][/device]`` ``--bluray-device=PATH``
Play a Blu-ray disc. Currently, this does not accept ISO files. Instead,
you must mount the ISO file as filesystem, and point ``--bluray-device``
to the mounted directory directly.
``dvd://[title|[starttitle]-endtitle][/device]`` ``--dvd-device=PATH``
Play a DVD. DVD menus are not supported. If no title is given, the longest
title is auto-selected.
@@ -715,39 +672,30 @@ PROTOCOLS
thing.
``dvdread://...:``
Play a DVD using the old libdvdread code. This is what MPlayer and
older mpv versions use for ``dvd://``. Use is discouraged. It's
provided only for compatibility and for transition, and to work
around outstanding dvdnav bugs (see "DVD library choices" above).
Play a DVD using the old libdvdread code. This is what MPlayer and older
mpv versions use for ``dvd://``. Use is discouraged. It's provided only
for compatibility and for transition.
``tv://[channel][/input_id]`` ``--tv-...``
Analogue TV via V4L. Also useful for webcams. (Linux only.)
``pvr://`` ``--pvr-...``
PVR. (Linux only.)
``dvb://[cardnumber@]channel`` ``--dvbin-...``
Digital TV via DVB. (Linux only.)
``mf://[filemask|@listfile]`` ``--mf-...``
Play a series of images as video.
``cdda://[device]`` ``--cdrom-device=PATH`` ``--cdda-...``
``cdda://track[-endtrack][:speed][/device]`` ``--cdrom-device=PATH`` ``--cdda-...``
Play CD.
``lavf://...``
Access any FFmpeg/Libav libavformat protocol. Basically, this passed the
string after the ``//`` directly to libavformat.
``av://type:options``
This is intended for using libavdevice inputs. ``type`` is the libavdevice
demuxer name, and ``options`` is the (pseudo-)filename passed to the
demuxer.
@@ -759,32 +707,26 @@ PROTOCOLS
``avdevice://`` is an alias.
``file://PATH``
A local path as URL. Might be useful in some special use-cases. Note that
``PATH`` itself should start with a third ``/`` to make the path an
absolute path.
``fd://123``
Read data from the given file descriptor (for example 123). This is similar
to piping data to stdin via ``-``, but can use an arbitrary file descriptor.
``edl://[edl specification as in edl-mpv.rst]``
Stitch together parts of multiple files and play them.
``null://``
Simulate an empty file. If opened for writing, it will discard all data.
The ``null`` demuxer will specifically pass autoprobing if this protocol
is used (while it's not automatically invoked for empty files).
``memory://data``
Use the ``data`` part as source data.
``hex://data``
Like ``memory://``, but the string is interpreted as hexdump.
PSEUDO GUI MODE
@@ -801,32 +743,24 @@ Currently this happens only in the following cases:
or file associations provided by desktop environments)
- if started from explorer.exe on Windows (technically, if it was started on
Windows, and all of the stdout/stderr/stdin handles are unset)
- started out of the bundle on OSX
- if you manually use ``--player-operation-mode=pseudo-gui`` on the command line
- manually adding ``--profile=pseudo-gui`` to the command line
This mode applies options from the builtin profile ``builtin-pseudo-gui``, but
only if these haven't been set in the user's config file or on the command line.
Also, for compatibility with the old pseudo-gui behavior, the options in the
``pseudo-gui`` profile are applied unconditionally. In addition, the profile
makes sure to enable the pseudo-GUI mode, so that ``--profile=pseudo-gui``
works like in older mpv releases. The profiles are currently defined as follows:
This mode implicitly adds ``--profile=pseudo-gui`` to the command line, with
the ``pseudo-gui`` profile being predefined with the following contents:
::
[builtin-pseudo-gui]
[pseudo-gui]
terminal=no
force-window=yes
idle=once
screenshot-directory=~~desktop/
[pseudo-gui]
player-operation-mode=pseudo-gui
.. warning::
This follows the mpv config file format. To customize pseudo-GUI mode, you can
put your own ``pseudo-gui`` profile into your ``mpv.conf``. This profile will
enhance the default profile, rather than overwrite it.
Currently, you can extend the ``pseudo-gui`` profile in the config file the
normal way. This is deprecated. In future mpv releases, the behavior might
change, and not apply your additional settings, and/or use a different
profile name.
The profile always overrides other settings in ``mpv.conf``.
.. include:: options.rst
@@ -851,7 +785,14 @@ works like in older mpv releases. The profiles are currently defined as follows:
.. include:: changes.rst
.. include:: libmpv.rst
EMBEDDING INTO OTHER PROGRAMS (LIBMPV)
======================================
mpv can be embedded into other programs as video/audio playback backend. The
recommended way to do so is using libmpv. See ``libmpv/client.h`` in the mpv
source code repository. This provides a C API. Bindings for other languages
might be available (see wiki).
ENVIRONMENT VARIABLES
=====================
@@ -1005,7 +946,7 @@ For Windows-specifics, see `FILES ON WINDOWS`_ section.
``~/.config/mpv/watch_later/``
Contains temporary config files needed for resuming playback of files with
the watch later feature. See for example the ``Q`` key binding, or the
``quit-watch-later`` input command.
``quit_watch_later`` input command.
Each file is a small config file which is loaded if the corresponding media
file is loaded. It contains the playback position and some (not necessarily
+347 -1647
View File
File diff suppressed because it is too large. Load diff
+117 -159
View File
@@ -20,77 +20,37 @@ The Interface
::
+---------+----------+------------------------------------------+----------+
| pl prev | pl next | title | cache |
+------+--+---+------+---------+-----------+------+-------+-----+-----+----+
| play | skip | skip | time | seekbar | time | audio | sub | vol | fs |
| | back | frwd | elapsed | | left | | | | |
+------+------+------+---------+-----------+------+-------+-----+-----+----+
+------------------+-----------+--------------------+
| playlist prev | title | playlist next |
+-------+------+---+--+------+-+----+------+--------+
| audio | skip | seek | | seek | skip | full |
+-------+ back | back | play | frwd | frwd | screen |
| sub | | | | | | |
+-------+------+------+------+------+------+--------+
| seekbar |
+----------------+--------------+-------------------+
| time passed | cache status | time remaining |
+----------------+--------------+-------------------+
pl prev
playlist prev
============= ================================================
left-click play previous file in playlist
right-click show playlist
shift+L-click show playlist
============= ================================================
pl next
============= ================================================
left-click play next file in playlist
right-click show playlist
shift+L-click show playlist
============= ================================================
title
| Displays current media-title, filename, or custom title
| Displays current media-title or filename
============= ================================================
left-click show playlist position and length and full title
right-click show filename
============= ================================================
cache
| Shows current cache fill status
play
playlist next
============= ================================================
left-click toggle play/pause
============= ================================================
skip back
============= ================================================
left-click go to beginning of chapter / previous chapter
right-click show chapters
shift+L-click show chapters
============= ================================================
skip frwd
============= ================================================
left-click go to next chapter
right-click show chapters
shift+L-click show chapters
============= ================================================
time elapsed
| Shows current playback position timestamp
============= ================================================
left-click toggle displaying timecodes with milliseconds
============= ================================================
seekbar
| Indicates current playback position and position of chapters
============= ================================================
left-click seek to position
============= ================================================
time left
| Shows remaining playback time timestamp
============= ================================================
left-click toggle between total and remaining time
left-click play next file in playlist
shift+L-click show playlist
============= ================================================
audio and sub
@@ -102,17 +62,66 @@ audio and sub
shift+L-click show available audio/sub tracks
============= ================================================
vol
skip back
============= ================================================
left-click toggle mute
mouse wheel volume up/down
left-click go to beginning of chapter / previous chapter
shift+L-click show chapters
============= ================================================
fs
seek back
============= ================================================
left-click skip back 5 seconds
right-click skip back 30 seconds
shift-L-click skip back 1 frame
============= ================================================
play
============= ================================================
left-click toggle play/pause
============= ================================================
seek frwd
============= ================================================
left-click skip forward 10 seconds
right-click skip forward 60 seconds
shift-L-click skip forward 1 frame
============= ================================================
skip frwd
============= ================================================
left-click go to next chapter
shift+L-click show chapters
============= ================================================
fullscreen
============= ================================================
left-click toggle fullscreen
============= ================================================
seekbar
| Indicates current playback position and position of chapters
============= ================================================
left-click seek to position
============= ================================================
time passed
| Shows current playback position timestamp
============= ================================================
left-click toggle displaying timecodes with milliseconds
============= ================================================
cache status
| Shows current cache fill status (only visible when below 45%)
time remaining
| Shows remaining playback time timestamp
============= ================================================
left-click toggle between total and remaining time
============= ================================================
Key Bindings
~~~~~~~~~~~~
@@ -158,132 +167,85 @@ Example::
Configurable Options
~~~~~~~~~~~~~~~~~~~~
``layout``
Default: bottombar
The layout for the OSC. Currently available are: box, slimbox,
bottombar and topbar. Default pre-0.21.0 was 'box'.
``seekbarstyle``
Default: bar
Sets the style of the seekbar, slider (diamond marker), knob (circle
marker with guide), or bar (fill).
Default pre-0.21.0 was 'slider'.
``deadzonesize``
Default: 0.5
Size of the deadzone. The deadzone is an area that makes the mouse act
like leaving the window. Movement there won't make the OSC show up and
it will hide immediately if the mouse enters it. The deadzone starts
at the window border opposite to the OSC and the size controls how much
of the window it will span. Values between 0.0 and 1.0, where 0 means the
OSC will always popup with mouse movement in the window, and 1 means the
OSC will only show up when the mouse hovers it. Default pre-0.21.0 was 0.
``minmousemove``
Default: 0
Minimum amount of pixels the mouse has to move between ticks to make
the OSC show up. Default pre-0.21.0 was 3.
``showwindowed``
Default: yes
Enable the OSC when windowed
| Default: yes
| Enable the OSC when windowed
``showfullscreen``
Default: yes
Enable the OSC when fullscreen
| Default: yes
| Enable the OSC when fullscreen
``scalewindowed``
Default: 1.0
Scale factor of the OSC when windowed.
| Default: 1.0
| Scale factor of the OSC when windowed
``scalefullscreen``
Default: 1.0
Scale factor of the OSC when fullscreen
| Default: 1.0
| Scale factor of the OSC when fullscreen
``scaleforcedwindow``
Default: 2.0
Scale factor of the OSC when rendered on a forced (dummy) window
| Default: 2.0
| Scale factor of the OSC when rendered on a forced (dummy) window
``vidscale``
Default: yes
Scale the OSC with the video
``no`` tries to keep the OSC size constant as much as the window size allows
| Default: yes
| Scale the OSC with the video
| ``no`` tries to keep the OSC size constant as much as the window size allows
``valign``
Default: 0.8
Vertical alignment, -1 (top) to 1 (bottom)
| Default: 0.8
| Vertical alignment, -1 (top) to 1 (bottom)
``halign``
Default: 0.0
Horizontal alignment, -1 (left) to 1 (right)
``barmargin``
Default: 0
Margin from bottom (bottombar) or top (topbar), in pixels
| Default: 0.0
| Horizontal alignment, -1 (left) to 1 (right)
``boxalpha``
Default: 80
Alpha of the background box, 0 (opaque) to 255 (fully transparent)
| Default: 80
| Alpha of the background box, 0 (opaque) to 255 (fully transparent)
``hidetimeout``
Default: 500
Duration in ms until the OSC hides if no mouse movement, must not be
negative
| Default: 500
| Duration in ms until the OSC hides if no mouse movement, must not be
negative
``fadeduration``
Default: 200
| Default: 200
| Duration of fade out in ms, 0 = no fade
Duration of fade out in ms, 0 = no fade
``deadzonesize``
| Default: 0
| Size of the deadzone. The deadzone is an area that makes the mouse act
like leaving the window. Movement there won't make the OSC show up and
it will hide immediately if the mouse enters it. The deadzone starts
at the window border opposite to the OSC and the size controls how much
of the window it will span. Values between 0 and 1.
``title``
Default: ${media-title}
``minmousemove``
| Default: 3
| Minimum amount of pixels the mouse has to move between ticks to make
the OSC show up
String that supports property expansion that will be displayed as
OSC title.
ASS tags are escaped, and newlines and trailing slashes are stripped.
``layout``
| Default: box
| The layout for the OSC. Currently available are: box, slimbox,
bottombar and topbar.
``tooltipborder``
Default: 1
Size of the tooltip outline when using bottombar or topbar layouts
``seekbarstyle``
| Default: slider
| Sets the style of the seekbar, slider (diamond marker) or bar (fill)
``timetotal``
Default: no
Show total time instead of time remaining
| Default: no
| Show total time instead of time remaining
``timems``
Default: no
Display timecodes with milliseconds
| Default: no
| Display timecodes with milliseconds
``visibility``
Default: auto (auto hide/show on mouse move)
Also supports ``never`` and ``always``
``boxmaxchars``
Default: 80
Max chars for the osc title at the box layout. mpv does not measure the
text width on screen and so it needs to limit it by number of chars. The
default is conservative to allow wide fonts to be used without overflow.
However, with many common fonts a bigger number can be used. YMMV.
| Default: auto (auto hide/show on mouse move)
| Also supports ``never`` and ``always``
Script Commands
~~~~~~~~~~~~~~~
@@ -307,7 +269,3 @@ to set auto mode (the default) with ``b``::
a script-message osc-visibility never
b script-message osc-visibility auto
``osc-playlist``, ``osc-chapterlist``, ``osc-tracklist``
Shows a limited view of the respective type of list using the OSC. First
argument is duration in seconds.
+8 -61
View File
@@ -5,41 +5,7 @@ Video filters allow you to modify the video stream and its properties. The
syntax is:
``--vf=<filter1[=parameter1:parameter2:...],filter2,...>``
Setup a chain of video filters. This consists on the filter name, and an
option list of parameters after ``=``. The parameters are separated by
``:`` (not ``,``, as that starts a new filter entry).
Before the filter name, a label can be specified with ``@name:``, where
name is an arbitrary user-given name, which identifies the filter. This
is only needed if you want to toggle the filter at runtime.
A ``!`` before the filter name means the filter is enabled by default. It
will be skipped on filter creation. This is also useful for runtime filter
toggling.
See the ``vf`` command (and ``toggle`` sub-command) for further explanations
and examples.
The general filter entry syntax is:
``["@"<label-name>":"] ["!"] <filter-name> [ "=" <filter-parameter-list> ]``
or for the special "toggle" syntax (see ``vf`` command):
``"@"<label-name>``
and the ``filter-parameter-list``:
``<filter-parameter> | <filter-parameter> "," <filter-parameter-list>``
and ``filter-parameter``:
``( <param-name> "=" <param-value> ) | <param-value>``
``param-value`` can further be quoted in ``[`` / ``]`` in case the value
contains characters like ``,`` or ``=``. This is used in particular with
the ``lavfi`` filter, which uses a very similar syntax as mpv (MPlayer
historically) to specify filters and their parameters.
Setup a chain of video filters.
You can also set defaults for each filter. The defaults are applied before the
normal filter parameters.
@@ -55,17 +21,6 @@ normal filter parameters.
wrapper, which gives you access to most of libavfilter's filters. This
includes all filters that have been ported from MPlayer to libavfilter.
Most filters are deprecated in some ways, unless they're only available
in mpv (such as filters which deal with mpv specifics, or which are
implemented in mpv only).
If a filter is not builtin, the ``lavfi-bridge`` will be automatically
tried. This bridge does not support help output, and does not verify
parameters before the filter is actually used. Although the mpv syntax
is rather similar to libavfilter's, it's not the same. (Which means not
everything accepted by vf_lavfi's ``graph`` option will be accepted by
``--vf``.)
Video filters are managed in lists. There are a few commands to manage the
filter list.
@@ -799,15 +754,6 @@ Available filters are:
:no: Deinterlace all frames.
:yes: Only deinterlace frames marked as interlaced (default).
``reversal-bug=<yes|no>``
:no: Use the API as it was interpreted by older Mesa drivers. While
this interpretation was more obvious and inuitive, it was
apparently wrong, and not shared by Intel driver developers.
:yes: Use Intel interpretation of surface forward and backwards
references (default). This is what Intel drivers and newer Mesa
drivers expect. Matters only for the advanced deinterlacing
algorithms.
``vdpaupp``
VDPAU video post processing. Works with ``--vo=vdpau`` and ``--vo=opengl``
only. This filter is automatically inserted if deinterlacing is requested
@@ -860,6 +806,13 @@ Available filters are:
1-9
Apply high quality VDPAU scaling (needs capable hardware).
``vdpaurb``
VDPAU video read back. Works with ``--vo=vdpau`` and ``--vo=opengl`` only.
This filter will read back frames decoded by VDPAU so that other filters,
which are not normally compatible with VDPAU, can be used like normal.
This filter must be specified before ``vdpaupp`` in the filter chain if
``vdpaupp`` is used.
``d3d11vpp``
Direct3D 11 video post processing. Currently requires D3D11 hardware
decoding for use.
@@ -868,12 +821,6 @@ Available filters are:
Whether deinterlacing is enabled (default: no).
``interlaced-only=<yes|no>``
If ``yes`` (default), only deinterlace frames marked as interlaced.
``mode=<blend|bob|adaptive|mocomp|ivctc|none>``
Tries to select a video processor with the given processing capability.
If a video processor supports multiple capabilities, it is not clear
which algorithm is actually selected. ``none`` always falls back. On
most if not all hardware, this option will probably do nothing, because
a video processor usually supports all modes or none.
``buffer=<num>``
Buffer ``<num>`` frames in the filter chain. This filter is probably pretty
+967 -141
View File
File diff suppressed because it is too large. Load diff
+11 -15
View File
@@ -7,11 +7,8 @@ large part of which is incompatible or completely changes how the player
behaves. Although there are still many similarities to its ancestors, **mpv**
should generally be treated as a completely different program.
.. admonition:: Warning
This document is **not updated** anymore, and is **incomplete** and
**outdated**. If you look for old option replacements, always check with
the current mpv manpage, as the options could have changed meanwhile.
.. note::
These lists are incomplete.
General Changes from MPlayer to mpv
-----------------------------------
@@ -33,7 +30,7 @@ Player
* Slave mode compatibility broken (see below).
* Re-enable screensaver while the player is paused.
* Allow resuming playback at a later point with ``Shift+q``, also see the
``quit-watch-later`` input command.
``quit_watch_later`` input command.
* ``--keep-open`` option to stop the player from closing the window and
exiting after playback ends.
* A client API, that allows embedding **mpv** into applications
@@ -212,7 +209,7 @@ Command Line Switches
``-no<opt>`` ``--no-<opt>`` (add a dash)
``-a52drc level`` ``--ad-lavc-ac3drc=level``
``-ac spdifac3`` ``--ad=spdif:ac3`` (see ``--ad=help``)
``-af volnorm`` (removed; use acompressor ffmpeg filter instead)
``-af volnorm`` ``--af=drc`` (renamed)
``-afm hwac3`` ``--ad=spdif:ac3,spdif:dts``
``-ao alsa:device=hw=0.3`` ``--ao=alsa:device=[hw:0,3]``
``-aspect`` ``--video-aspect``
@@ -265,14 +262,13 @@ Command Line Switches
``-ssf <sub>`` ``--sws-...``
``-stop-xscreensaver`` ``--stop-screensaver``
``-sub-fuzziness`` ``--sub-auto``
``-sub-text-*`` ``--sub-*``
``-sub`` ``--sub-file``
``-subcp`` ``--sub-codepage``
``-subdelay`` ``--sub-delay``
``-subfile`` ``--sub-file``
``-subfont-*`` ``--sub-*``, ``--osd-*``
``-subfont-*`` ``--sub-text-*``, ``--osd-*``
``-subfont-text-scale`` ``--sub-scale``
``-subfont`` ``--sub-font``
``-subfont`` ``--sub-text-font``
``-subfps`` ``--sub-fps``
``-subpos`` ``--sub-pos``
``-sws`` ``--sws-scaler``
@@ -316,11 +312,11 @@ input.conf and Slave Commands
+--------------------------------+----------------------------------------+
| Old | New |
+================================+========================================+
| ``pt_step 1 [0|1]`` | ``playlist-next [weak|force]`` |
| ``pt_step 1 [0|1]`` | ``playlist_next [weak|force]`` |
| | (translation layer cannot deal with |
| | whitespace) |
+--------------------------------+----------------------------------------+
| ``pt_step -1 [0|1]`` | ``playlist-prev [weak|force] (same)`` |
| ``pt_step -1 [0|1]`` | ``playlist_prev [weak|force] (same)`` |
+--------------------------------+----------------------------------------+
| ``switch_ratio [<ratio>]`` | ``set video-aspect <ratio>`` |
| | |
@@ -335,7 +331,7 @@ input.conf and Slave Commands
| ``<step> <dir>`` | ``no-osd``: ``no-osd cycle <prop>`` |
| | ``<step>`` |
+--------------------------------+----------------------------------------+
| ``osd_show_property_text`` | ``show-text <text>`` |
| ``osd_show_property_text`` | ``show_text <text>`` |
| ``<text>`` | The property expansion format string |
| | syntax slightly changed. |
+--------------------------------+----------------------------------------+
@@ -344,9 +340,9 @@ input.conf and Slave Commands
| | ``raw`` prefix to disable property |
| | expansion. |
+--------------------------------+----------------------------------------+
| ``show_tracks`` | ``show-text ${track-list}`` |
| ``show_tracks`` | ``show_text ${track-list}`` |
+--------------------------------+----------------------------------------+
| ``show_chapters`` | ``show-text ${chapter-list}`` |
| ``show_chapters`` | ``show_text ${chapter-list}`` |
+--------------------------------+----------------------------------------+
| ``af_switch``, ``af_add``, ... | ``af set|add|...`` |
+--------------------------------+----------------------------------------+
+8 -12
View File
@@ -7,7 +7,8 @@ contains breaking changes, such as changed options or added/removed features,
and Y is incremented if a release contains only bugfixes and other minor
changes.
Releases are tagged on the master branch and will not be maintained separately.
There is only one release branch that keeps track of the latest version and
will not be maintained separately.
The goal of releases is to provide Linux distributions with something to
package. If you want the newest features, just use the master branch.
@@ -18,22 +19,17 @@ Releases other than the latest release are unsupported and unmaintained.
Release procedure
-----------------
While on master:
- Merge master into branch release/current.
- Update the `RELEASE_NOTES` file.
- Create and/or update the `RELEASE_NOTES` file.
- Update the `VERSION` file.
- Create and/or update the `VERSION` file.
- Update `DOCS/client-api-changes.rst` and `DOCS/interface-changes.rst`
(in particular, update the last version numbers if necessary)
- Update `DOCS/client-api-changes.rst` (on major releases).
- Commit changes.
- Create tag v0.X.Y.
- Create signed tag v0.X.Y.
- Add -UNKNOWN suffix to version in `VERSION` file.
- Commit changes, push branch and tag to GitHub.
- Push branch and tag to GitHub.
- Create a new GitHub release using the content of `RELEASE_NOTES` related to
the new version.
+1 -1
View File
@@ -146,7 +146,7 @@ mpv's custom build step on top of waf
Build step is pretty much vanilla waf. The only difference being that the list
of source files can contain both strings or tuples. If a tuple is found,
the second element in the tuple will be used to match the features detected
the second element in the tuple will the used to match the features detected
in the configure step (the ``name`` field described above). If this feature
was not enabled during configure, the source file will not be compiled in.
+12 -31
View File
@@ -7,7 +7,6 @@
* [Overview](#overview)
* [Downloads](#downloads)
* [Changelog](#changelog)
* [Compilation](#compilation)
* [FFmpeg vs. Libav](#ffmpeg-vs-libav)
* [Release cycle](#release-cycle)
@@ -15,7 +14,6 @@
* [Contributing](#contributing)
* [Relation to MPlayer and mplayer2](#relation-to-mplayer-and-mplayer2)
* [Wiki](https://github.com/mpv-player/mpv/wiki)
* [FAQ](https://github.com/mpv-player/mpv/wiki/FAQ)
* [Man pages](http://mpv.io/manual/master/)
* [Contact](#contact)
* [License](#license)
@@ -33,12 +31,14 @@ Releases can be found on the [release list][releases].
- A not too ancient Linux, or Windows Vista or later, or OSX 10.8 or later.
- A somewhat capable CPU. Hardware decoding might sometimes help if the CPU
is too slow to decode video realtime, but must be explicitly enabled with
the `--hwdec` option.
the `--hwdec` option. On Windows, a CPU with SSE4 instruction set is required
to get decent hardware decoding performance.
- A not too crappy GPU. mpv is not intended to be used with bad GPUs. There are
many caveats with drivers or system compositors causing tearing, stutter,
etc. On Windows, you might want to make sure the graphics drivers are
current. In some cases, ancient fallback video output methods can help
(such as `--vo=xv` on Linux), but this use is not recommended or supported.
current, especially OpenGL. In some cases, ancient fallback video output
methods can help (such as `--vo=xv` on Linux), but this use is not
recommended or supported.
## Downloads
@@ -47,20 +47,6 @@ Releases can be found on the [release list][releases].
For semi-official builds and third-party packages please see
[mpv.io](http://mpv.io/installation/).
## Changelog
There is no completely changelog, however changes to the player core interface
are listed in the [interface changelog][interface-changes].
Changes to the C API are documented in the [client API changelog][api-changes].
The [release list][releases] has a summary of most of the important changes
on every release.
Changes to the default key bindings are inidcated in
[restore-old-bindings.conf][restore-old-bindings].
## Compilation
@@ -89,12 +75,11 @@ to the *prefix* after it is compiled.
Essential dependencies (incomplete list):
- gcc or clang
- X development headers (xlib, xrandr, xext, xscrnsaver, xinerama, libvdpau,
libGL, libXv, ...)
- X development headers (xlib, X extensions, libvdpau, libGL, libXv, ...)
- Audio output development headers (libasound/ALSA, pulseaudio)
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libavfilter
and either libswresample or libavresample)
At least FFmpeg 3.2.2 or Libav 12 is required.
At least FFmpeg 2.4.0 or Libav 11 is required.
- zlib
- iconv (normally provided by the system libc)
- libass (OSD, OSC, text subtitles)
@@ -122,13 +107,12 @@ FFmpeg dependencies:
Most of the above libraries are available in suitable versions on normal
Linux distributions. However FFmpeg is an exception (distro versions may be
too old to work at all or work well). For that reason you may want to use
the separately available build wrapper ([mpv-build][mpv-build]) that first
compiles FFmpeg libraries and libass, and then compiles the player statically
linked against those.
the separately available build wrapper ([mpv-build][mpv-build]) that first compiles FFmpeg
libraries and libass, and then compiles the player statically linked against
those.
If you want to build a Windows binary, you either have to use MSYS2 and MinGW,
or cross-compile from Linux with MinGW. See
[Windows compilation][windows_compilation].
or cross-compile from Linux with MinGW. See [Windows compilation][windows_compilation].
## FFmpeg vs. Libav
@@ -213,7 +197,7 @@ In general, mpv should be considered a completely new program, rather than a
MPlayer drop-in replacement.
If you are wondering what's different from mplayer2 and MPlayer, an incomplete
and now unmaintained list of changes is located [here][mplayer-changes].
list of changes is located [here][mplayer-changes].
## Contact
@@ -236,9 +220,6 @@ only if discretion is required.
[release-policy]: https://github.com/mpv-player/mpv/blob/master/DOCS/release-policy.md
[windows_compilation]: https://github.com/mpv-player/mpv/blob/master/DOCS/compile-windows.md
[mplayer-changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/mplayer-changes.rst
[interface-changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/interface-changes.rst
[api-changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/client-api-changes.rst
[restore-old-bindings]: https://github.com/mpv-player/mpv/blob/master/etc/restore-old-bindings.conf
## License
-770
View File
@@ -1,773 +1,3 @@
Release 0.25.0
==============
This release drops support for OS X 10.7 and earlier.
Support for some optical media functionality (DVD/CD) is now disabled by default.
More parts of the player are now licensed under LGPL. In particular:
* OSD symbol font
* ass_mp, sd_ass
* common.h
* demux/packet
* demux_mkv (with minor exceptions), ebml, matroska.h
* sd_lavc
* sub/osd
Thanks to all contributors who have agreed to relicensing of their changes!
See #2033 for details.
Starting with this release, releases will be tagged on the master branch.
The release/current branch is thus abandoned.
Features
--------
Added
~~~~~
- TOOLS: add acompressor.lua script for runtime acompressor ffmpeg filter control
- dvb: add support for DVB-T2
- lavfi: support hwdec filters for --lavfi-complex
- macOS: initial Touch Bar support
- osc: add volume button (mouse wheel to change volume)
- sub: add SDH subtitle filter
- vo_opengl: add experimental vdpauglx backend
- vo_opengl: implement videotoolbox hwdec on iOS
Removed
~~~~~~~
- image_writer: remove useless formats (PPM, PGM, TGA)
- af_drc: remove (use --af=acompressor instead; higher quality)
Options and Commands
--------------------
Added
~~~~~
- --demuxer-lavf-probe-info
- --sub-filter-sdh, --sub-filter-sdh-harder
- add automatic libavfilter bridges to option parsing
- command: add better runtime filter toggling method
- command: add demux-start-time property
- command: add property notifications for hwdec properties (#4289)
- input: add "async" flag
- osc: add user_opts.boxmaxchars for box layout title limit
- player: add --keep-open-pause=no option
- va_vavpp: reversal-bug=no
- vo_opengl: --opengl-es=force2
- vo_opengl: add --opengl-shader-cache-dir option for caching shaders on disk (mostly for ANGLE)
- vo_opengl: angle: add --angle-flip to set the ANGLE present model
Changed
~~~~~~~
- command: update sub-fps etc. options on runtime changes
- vo_opengl: prefer X11 backends over Wayland backends
- options: change --audio-file-auto default to not to load any files
Deprecated
~~~~~~~~~~
- audio: deprecate most non-lavfi audio filters
(channels, equalizer, pan, volume)
- video: deprecate almost all non-lavfi video filters
(buffer, crop, dlopen, dsize, eq, expand, flip, gradfun, mirror, noformat,
pullup, rotate, scale, stereo3d, sub, yadif)
- options: deprecate --loop semantics (planned alias to --loop-file)
Fixes and Minor Enhancements
----------------------------
- Windows: demux_cue: fix UTF-8 paths
- Windows: fix mismatched free/talloc_free (#4315)
- Windows: fix undefined behaviour when toggling fullscreen
- ao_alsa: close lost audio devices (#4189)
- ao_alsa: filter fewer devices
- ao_alsa: fix an error check (#4188)
- ao_jack: update latency on buffer_size/graph change
- ao_wasapi: do not pass nonsense to drivers with double precision formats
- ass_mp: reallocate cached subtitle image data on format changes (#4325)
- build: decouple dvdnav check from dvdread (#4290)
- build: encode_lavc: fix build failure after libavcodec major bump
- build: fix build with HAVE_GL==0
- build: replace android-gl check with a standard GLES3 check
- build: update bundled waf to 1.9.8
- build: vd_lavc: fix potential build failure with vaapi
- demux_lavf: disable half-working mp4 edit list support in libavcodec
- demux_lavf: skip avformat_find_stream_info() for some formats (hls, mp4, mkv by default)
- etc/encoding_profiles.conf: update and remove deprecated stuff
- etc/mpv.conf: remove deprecated options
- external_files: actually try to autoload from fallback paths
- external_files: enable autoloading with URLs (#3264)
- image_writer: make it work with libavcodec's jpg encoder
- macOS: add --ontop-level option for modifying ontop window level (#2376, #3974)
- macOS: add key mappings for previous and next Media Keys (#4204)
- macOS: add option to force dedicated GPU (#3242)
- macOS: fix autofit options on HiDPI resolutions without HiDPI scaling (#4194)
- macOS: fix black edges on live resize
- macOS: fix cursor hiding in the Dock area and top of the screen
- macOS: fix event propagation of menu bar item key shortcuts
- macOS: fix first responder when borderless window is used
- macOS: fix key input in certain circumstances
- macOS: fix retrieval of non-fullscreen window size, also while animating (#4323)
- macOS: fix scroll wheel input with Shift modifier (#3506)
- macOS: improve bundle environment variable handling (#2061)
- macOS: make window draggable on init
- macOS: only move window into screen bounds when changing screens (#4178)
- macOS: only report mouse movements when window is not being dragged (might have triggered OSC and other scripts)
- macOS: properly restore shell state when quitting from the Dock's context menu
- macOS: refactor mouse events and cursor visibility (#1817, #3856, #4147)
- macOS: set background of the title bar from black to white
- osc: bottom/topbar: add fullscreen button
- osc: bottom/topbar: don't clip title vertically
- osc: bottom/topbar: increase timecodes width a bit (#3952)
- osc: fix PlayResX undefined warning when aspect is 0
- osc: fix window dragging with showwindowed=no (#1819)
- osc: make title configurable and use property expansion on it (#4221)
- osc: refactor osc message scaling (#4081, #4083, #4102)
- player: don't block playback stop when seeking
- player: enable "buffering" pausing for DASH streams too
- player: fix core-idle and eof-reached update notifcations
- player: make screenshot commands honor the async flag (#4250)
- player: reduce blocking on VO when switching pause (#4152)
- sd_ass: disable --sub-fix-timing if sub style override is fully disabled
- stream/stream_dvdnav: don't ignore setting title (#4283)
- stream_dvd: fix subs/audio detection on DVDs containing multi-PGC titles
- vf_vavpp: add advanced deint bug compatibility for Intel vaapi drivers
- vf_vavpp: fix first-field mode
- vo_opengl: fix crash with temporal dithering in dumb mode
- vo_opengl: hwdec_d3d11egl: make it work with some ANGLE DLL versions
- vo_x11: reduce flickering on playlist navigation
- wayland: correctly map mouse buttons
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.24.0..v0.25.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.24.0...v0.25.0 or
https://git.srsfckn.biz/mpv/log/?qt=range&q=v0.24.0..v0.25.0
Release 0.24.0
==============
Features
--------
Added
~~~~~
- Windows: allow snapping to screen edges (#2248)
- macOS: add border cycling (#2430)
- player: add experimental C plugin interface
- player: add experimental stream recording feature (--record-file)
- player: add prefetching of the next playlist entry (--prefetch-playlist; does NOT work with URLs resolved by youtube-dl)
- stream_lavf: add support for data URIs (#4058)
- vaapi: add support for 10-bit video formats (requires patched Mesa and capable hardware)
- x11: pseudo HiDPI scaling
Options and Commands
--------------------
Added
~~~~~
- sub: add --sub-justify and --sub-ass-justify options
- sub: add option to force using video resolution for image subtitles (--image-subs-video-resolution)
Changed
~~~~~~~
- command: rename framedrop properties
- drop-frame-count → decoder-frame-drop-count
- vo-drop-frame-count → frame-drop-count
- input.conf: change "L" to change loop-file by default
Deprecated
~~~~~~~~~~
- --hwdec-preload (replaced with --opengl-hwdec-interop)
Removed
~~~~~~~
- options: drop deprecated --sub-codepage syntax
- options: drop deprecated --vd/--ad codecs selection features
- player: remove --stream-capture option/property
Fixes and Minor Enhancements
----------------------------
- Windows: update the fullscreen state on restoring
- ad_spdif: fix obscure cases of AC3 passthrough (e.g. 44100 Hz AC3)
- ao_oss: use --audio-device if --oss-device isn't set (#4122)
- build: fix --disable-gl if cuda is enabled
- build: rpi: rely on pkgconfig for compiler flags to ease cross compilation
- charset_conv: fallback to interpreting subs as latin1 if iconv fails
- charset_conv: fix "auto" fallback with uchardet not compiled (#3954)
- client API: fix freeze when destroying mpv_handle before mpv_initialize
- client API: fix mpv_set_property() return value before init (#3988)
- command: fix potential crash for script-binding with multi-commands
- command: nicer OSD formatting for loop-file
- command: shorten long playlists on OSD
- config: do not resolve default profile during "include" processing (#4024)
- cuda: fix 10 bit decoding
- cue: accept lower-case cue commands (#4057)
- demux_mkv: any reference makes a frame not a keyframe (fixes seeking in WebM files with alpha channel)
- lavfi: slightly better disconnected output handling (#4118)
- lua: close directory after reading its entries (#4045)
- macOS: consistent normalization when searching for external files (#4016)
- macOS: don't change Space on quit in fullscreen (#3957)
- macOS: don't constrain window frame for fullscreen (#4044)
- macOS: don't init displaylink on reconfig (#4031)
- macOS: fix build on OS X 10.9 (#3946)
- macOS: fix color profile retrieval
- macOS: fix displaylink refresh rate retrieval
- macOS: fix dropping of files and URLs (#4036)
- macOS: fix handling of geometry option (#3867)
- macOS: fix unwanted behavior with window level other than the default (#1757, #1884)
- macOS: fix window size in certain circumstances
- macOS: properly recover from toggleFullscreen fail (#4035)
- osc: allow playlist buttons when looping (#4092)
- osc: bottom/topbar: clip title instead of stretching
- osc: bottombar/topbar: make chapter markers slightly bigger
- osc: box: clip with ellipsis after too much stretching
- osc: fix crashes related to field eventresponder being nil (#3210)
- player: add .scc subtitle extension
- stream_bluray: use proper 0-based index
- sub: remove .txt as text subtitle extension
- tv: fix segfaults on TV input (#4096)
- vaapi: set libva > 0.39.4 message callbacks to prevent it from printing messages to the terminal
- vd_lavc: improved fallback behavior for --hwdec=cuda (#3914)
- vdpau: reject decoding of non-4:2:0 (would decode to garbage)
- vf_lavfi: don't crash with VOs without hardware decoding support (#4064)
- vo_opengl, vo_opengl_cb: better hwdec interop backend selection
- vo_opengl: angle: rewrite with custom swap chain (fixes problems with e.g. 24 fps video on 24 Hz monitors, avoids problems with DirectComposition, enables "screenshot window" command on Windows 8 and newer)
- vo_opengl: partially fix rotation for 4:2:2 content
- vo_opengl: x11egl: fix alpha mode
- wayland: fix high CPU usage with mpv paused and visible
- ytdl_hook, edl: implement pseudo-DASH support
- ytdl_hook: add non-dash fallbacks to default formats
- ytdl_hook: fix opening hitbox.tv rtmp stream
- ytdl_hook: respect --no-audio, don't force-select track
- ytdl_hook: support livestream segmented DASH VODs
- ytdl_hook: support segmented dash
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.23.0..v0.24.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.23.0...v0.24.0 or
https://git.srsfckn.biz/mpv/log/?qt=range&q=v0.23.0..v0.24.0
Release 0.23.0
==============
Now requires at least FFmpeg 3.2.2.
Features
--------
- vo_rpi: partially undeprecate
Added
~~~~~
- vo_opengl: hwdec_cuda: Support P016 output surfaces
Removed
~~~~~~~
- charset_conv: drop enca and libguess support in favor of uchardet
- vf_vdpaurb: remove this filter in favor of --hwdec=vdpau-copy
Options and Commands
--------------------
Added
~~~~~
- TOOLS/autoload: allow disabling through script-opts
- demux, stream: add --access-references to prevent opening referenced files
Deprecated
~~~~~~~~~~
- options: deprecate codec family selection in --vd/--ad
Removed
~~~~~~~
- macOS: remove --fs-black-out-screens
- options: remove deprecated sub-option handling for --vo and --ao
Fixes and Minor Enhancements
----------------------------
- Windows: window styles improvements (allow minimizing borderless/fullscreen window) (#2229, #2451)
- ad_spdif: Fix crash when spdif muxer is not available
- audio: fix --audio-stream-silence with ao_alsa
- audio: fix --audio-stream-silence with ao_wasapi
- build: drop build-time dependency on Perl
- build: support linking ANGLE (previously loaded dynamically)
- d3d11va: unconditionally load D3D DLLs (#3348)
- demux_mkv: fix seeking in some broken files (#3920)
- hwdec_cuda: allow building without CUDA SDK (load CUDA dynamically)
- macOS: fix dropping of URLs containing query strings on the window
- macOS: fullscreen refactoring (#2857, #3272, #1352, #2062, #3864)
- macOS: support append file to paylist on drop (#2166)
- macOS: update the menu and remove conflicting “Quit & remember position” item (#3865)
- osc: don't hide playlist buttons, just disable
- osc: fix possible race condition in right timecode
- osc: topbar: use same styles as bottombar
- player: don't print format detection error when aborting loading
- vdpau: fix vaapi probing if libvdpau-va-gl1 is present
- video: use demuxer-signaled duration for last video frame (#3924)
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.22.0..v0.23.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.22.0...v0.23.0 or
https://git.srsfckn.biz/mpv/log/?qt=range&q=v0.22.0..v0.23.0
Release 0.22.0
==============
Features
--------
Added
~~~~~
- audio/out: add AudioUnit output driver for iOS
- demux_mkv: parse Matroska colorimetry metadata
- filter_kernels: add ability to taper kernels/windows, add tukey window
- osc: add seekbarstyle=knob (#2365)
- video/out: add tct as modern caca alternative for true-color and 256-color terminals
- video: add --hwdec=vdpau-copy mode
Deprecated
~~~~~~~~~~
- vf_vdpaurb: deprecated in favor of --hwdec=vdpau-copy
Options and Commands
--------------------
Added
~~~~~
- --opengl-early-flush=auto
- --scale-taper, --scale-wtaper
- --scale-wblur
- macOS: --hidpi-window-scale (#3716)
- osc: add script message handlers for chapter/track/playlists
Fixes and Minor Enhancements
----------------------------
- Apply --autofit-larger after --autofit-smaller (#3753)
- Set subtitle track title to indicate hearing/visual impaired tracks
- ao_alsa: disable chmap API use for mono/stereo (#2905, #3045)
- build: add required failure message for libavfilter check (#3692)
- build: fix compilation with mingw-w64/Clang (#3800)
- build: make VideoToolbox available on iOS
- command: fix reset-on-next-file=all and tv-freq option (#3708)
- command: if window-scale can't be set properly, set it as option (#3724)
- demux_mkv: don't recursively resolve timeline for opened reference files
- demux_mkv: fix ordered chapter sources with ordered editions
- opengl: compile against iOS OpenGLES implementation
- options: handle legacy no-* sub-options
- osc: add alpha animation to tooltip (fix lingering tooltip)
- osc: change default deadzonesize to 0.5
- osc: don't wrap the title
- osc: fix crash after reaching a certain position in limited lists (#3691)
- osc: fix crash with no chapters
- osc: fix crashes when dragging seekbar across file changes (#3210)
- osc: fix displaying only half of the entries when at the end of a list
- osc: fix missing chapter ticks with seekbarstyle=bar
- osc: slimbox: fix clipping with seekbarstyle=bar (#3737)
- osc: top/bottombar: also scale when min-width is reached to match box/slimbox behavior
- osc: top/bottombar: dynamically size timecodes according to timems
- osc: top/bottombar: rescale layout to same size with scale=1
- osc: top/bottombar: scale title if too large like box
- player: consistently initialize screensaver state with --force-window
- player: enable no-video subtitle display on coverart too
- player: make --start-time work with --rebase-start-time=no
- player: make sure non-video subtitle rendering is reset if video resumes (#3770)
- player: removing last playlist entry while looping should not stop (#3808)
- player: show subtitles on VO if --force-window is used (#3684)
- player: speed up audio/video re-sync when there is a huge delay
- vdpau: fix hwdec uninit (#3788)
- vo_opengl: blend against background color for --alpha=blend
- vo_opengl: context_rpi: fix stdatomic usage (#3699)
- vo_opengl: fix --blend-subtitles handling (#3773)
- vo_opengl: fix redrawing with hardware decoding (#3773)
- vo_opengl: partially re-enable glFlush() calls (#3670)
- ytdl_hook: sort chapters by time
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.21.0..v0.22.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.21.0...v0.22.0 or
https://git.srsfckn.biz/mpv/log/?qt=range&q=v0.21.0..v0.22.0
Release 0.21.0
==============
Features
--------
Added
~~~~~
- config: allow profile forward-references in default profile
- demux_lavf: "support" mov edit lists and log errors if used (FFmpeg only)
- hwdec: Add support for CUDA and cuvid/NvDecode (mostly useful on Linux where VDPAU still lacks HEVC Main 10 support; keep using DXVA2 on Windows)
- osc: add right-click behavior to playlist and chapter buttons
- osc: add user-alterable margin for top/bottombar
- rpi: add --hwdec=rpi-copy (#3604)
- sd_lavc: enable teletext
- vaapi: support drm devices when running in vaapi-copy mode
- vd_lavc: Add hwdec wrapper for crystalhd
- vo_opengl: add hw overlay support and use it for RPI
- vo_opengl: basic mali fbdev support
- vo_opengl: rpi: merge vo_rpi features
Removed
~~~~~~~
- vo_opengl: remove pre/post/scale-shaders in favor of user-shaders
Deprecated
~~~~~~~~~~
- config: deprecate ao and vo auto-profiles
- vo_rpi: deprecate this VO
Options and Commands
--------------------
Added
~~~~~
- add --teletext-page option
- af_pan: add af-command support to change the matrix
- af_rubberband: add af-command and option to change the pitch
- command: add a load-script command
- command: add a video-dec-params property
- command: add an apply-profile command
- command: add audio-pts property to get the audio pts
- command: add options to property list
- command: add sub-text property for current subtitle text
- command: export profile list as a property (#977)
- options: add --hwdec=yes as alias for --hwdec=auto
- player: add --player-operation-mode=pseudo-gui
- player: add --video-osd=no option to disable video OSD (#3387)
- player: add --watch-later-directory option
- stream_bluray: select title by playlist (bd://mpls/[playlist])
- vo_opengl: disable glFlush() by default, and add an option to enable it for testing
Changed
~~~~~~~
- af_rubberband: default to channels=together
- command: allow absolute seeks relative to end of stream
- command: make bitrate properties observable
- command: make most options observable
- msg: make --log-file and --dump-stats accept config path expansion (#3591)
- options: deprecate --playlist-pos to --playlist-start
- options: make input options generally runtime-settable
- options: rename subtitle options (--sub-text- → --sub; --ass- → --sub-ass-)
- osc: change default layout to bottombar, seekbarstyle to bar, use larger scalewindowed and scalefullscreen
- player: make --terminal, --log-file, --dump-stats, --osc, --ytdl, --audio-*, --priority, --stop-screensaver (#3615) settable at runtime
- vo_drm: change CLI options
- Change connector selection to accept human readable names (such as eDP-1, HDMI-A-2) rather than arbitrary numbers.
- Change GPU selection to accept GPU number rather than device paths.
- Merge connector and GPU selection into one --drm-connector.
- Add support for --drm-connector=help.
- Add support for --drm-* in EGL backend.
- vo_opengl: rename 3dlut-size to icc-3dlut-size
Removed
~~~~~~~
- command: remove hwdec-active and hwdec-detected properties
- command: remove vo-cmdline
- options: drop unreferenced --bluray-angle option
- vo, ao: disable positional parameter suboptions
- vo_xv: replace no-colorkey with ck-method=none
Deprecated
~~~~~~~~~~
- all VOs and AOs: deprecate sub-options, add them as global options
- command: deprecate "cache" property, replace with "cache-percent"
- deprecate --vo-defaults
- deprecate --vo=opengl-hq alias in favor of opengl-hq profile
- options: deprecate --mute=auto
- vo_direct3d: deprecate direct3d_shaders alias, use shaders by default
- vo_opengl: deprecate 'drm-egl' backend and introduce 'drm' instead
Fixes and Minor Enhancements
----------------------------
- TOOLS/zsh.pl: die if we can't parse main options
- TOOLS/zsh.pl: don't filter files by extension (#2273)
- ao_alsa: try to fallback to "hdmi" before "iec958" for spdif
- ao_rsound: fix compilation (#3501)
- aspect: use nominal width instead of actual width for video-unscaled
- audio/out: prevent underruns with spdif under certain conditions
- audio: fix late audio start (#3610)
- audio: fix missed wakeup when changing audio output device
- audio: fix segfault when yanking USB DAC
- charset_conv: Use CP949 instead of EUC-KR
- command: don't log "ignore" command with -v verbosity
- command: try selecting the next track if track switching fails (#3446)
- demux_mkv: don't crash if --ordered-chapters-files fails
- displayconfig: treat a refresh rate of 1 as invalid
- ipc: log when listening to IPC socket (#3598)
- macOS: fix fullscreen regression on 10.11 and newer (#3364)
- mp_image: fix clearing to black with p010 format
- osc: Fix scaling issues when toggling fullscreen (#3429)
- osc: align text vertically in top/bottombar (#2093)
- osc: change seekbar background's alpha scaling
- osc: fix display of chapters and playlist scaling
- osc: move tooltip to inside seekbar for top/bottombar
- osc: show playlist/chapter list on prev/next instead of osd
- path: default ~~ paths to home directory (#3591)
- player: do not let pseudo-gui override user config settings
- player: enable reading from stdin after loading input.conf
- player: fix instant subtitle refresh on track switches
- player: make --force-window work with opengl-cb
- stream_file: don't use poll() on directories (would hang on macOS; #3530, #3649)
- stream_lavf: fix determining seekability (#1701)
- sub: actually apply text alignment options to non-ASS subtitles
- terminal-win: support modifier keys in console input (#3625)
- vo_drm: fix segfault when using invalid card
- vo_opengl: apply 90° rotation to chroma texture size (#3568)
- vo_opengl: fix incorrect video rendering after vdpau preemption recovery
- vo_opengl: partially fix dumb-mode cropping with rotation
- vo_opengl: rpi: use overlay for yuv420p too
- w32_common: initialize playback status as soon as possible (#3482)
- wayland: reject resize events with either dimension being 0 (#3679)
- x11: fix external fullscreen update (#3570)
- ytdl_hook: Add title to playlist items if available
- ytdl_hook: Set aspect ratio for anamorphic video
- ytdl_hook: Support playlist entries without subtitles
- ytdl_hook: add chapters by parsing video's description
- ytdl_hook: don't add subtitles with unknown duration
- ytdl_hook: temporarily force disable dash segments formats
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.20.0..v0.21.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.20.0...v0.21.0 or
https://git.srsfckn.biz/mpv/log/?qt=range&q=v0.20.0..v0.21.0
Release 0.20.0
==============
Options and Commands
--------------------
Added
~~~~~
- aspect: add --video-unscaled=downscale-big
- player: add --image-display-duration option to control duration of image display (#3425)
- vo_opengl: angle: new flag (dcomposition) to control DirectComposition
- command: add sub-speed property
Fixes and Minor Enhancements
----------------------------
- af_lavrresample: fix error if resampler could not be recreated
- audio: avoid missed wakeups with ab-loops
- audio: do not apply --audio-channels if spdif passthrough is in use (#3445)
- cache: don't use a backbuffer if the cache is as large as the file
- command: prevent O(n^2) behaviour for playlist property
- demux: close underlying stream if it's fully read anyway (#3456)
- demux: fix undefined behavior with ogg metadata update (#3451)
- player: make looping slightly more seamless
- player: refresh very low framerate video on filter changes (#3435)
- stream_memory: disable stream cache
- vf_rotate: allow arbitrary rotation (#3434)
- vo: be more trusting to estimated display FPS (#3433)
- w32_common: use hooks to detect parent window resize
- x11: work around mutter fullscreen issue (#2072)
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.19.0..v0.20.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.19.0...v0.20.0 or
http://git.srsfckn.biz/mpv/log/?qt=range&q=v0.19.0..v0.20.0
Release 0.19.0
==============
Build System Changes
--------------------
- build: add --htmldir option
- build: always require atomics
- wscript: add proper unversioned SONAME for Android
Features
--------
New
~~~
- client API: add stream_cb API for user-defined stream implementations (bumps client API version to 1.22)
- vf_d3d11vpp: add video processor selection
- videotoolbox: add --hwdec=videotoolbox-copy for h/w accelerated decoding with video filters
- vo_opengl: add a tscale=linear direct implementation
Removed
~~~~~~~
- audio/filter: remove delay audio filter
Options and Commands
--------------------
Added
~~~~~
- command: add filename/no-ext sub-property that returns filename without extension (#3404)
- command: add properties for HDR metadata
- command: add replaygain information properties to track-list
- options: add vp9 to --hwdec-codecs
- player: add --audio-stream-silence
- player: add --audio-wait-open
- player: add --no-autoload-files
- videotoolbox: add yuv420p to --videotoolbox-format
Changed
~~~~~~~
- options: un-restrict --audio-delay
- use - as command-name separator everywhere
- vo_opengl: reduce default 3dlut-size to 64x64x64 (since accuracy is improved)
Deprecated
~~~~~~~~~~
- deprecate "balance" option/property (no replacement)
Fixes and Minor Enhancements
----------------------------
- Windows: don't wait for GUI thread when polling for events (#3393)
- af_lavcac3enc: error out properly if encoding fails
- af_volume: don't let softvol overwrite af_volume volumedb sub-option
- ao_pulse: fix some volume control rounding issues
- ao_wasapi: in exclusive mode, do not output multichannel by default
- audio: add heuristic to move auto-downmixing before other filters
- audio: show an osd bar when changing ao-volume
- demux: make ALBUM replaygain tags optional (#3405)
- demux_raw: fix small typo to add s16be support
- demux_timeline: restore mkv edition switching
- libarchive: sanitize non-UTF8 archive entries
- macOS/vo_opengl: fix crash when glctx is NULL during init (#3360)
- player: disable display-sync with spdif transcoding
- player: do not cut off terminal status line if it contains newlines (#3340)
- player: fix display-sync timing if audio resumes slowly
- player: improve instant track switching (#3392)
- player: improve non-hr seeking with external audio tracks
- player: offset demuxer on start/seek properly with audio/sub delay
- player: sync audio as well when enabling it mid-stream
- stream/stream_bluray: display list of available titles in verbose mode
- sub: don't potentially discard too many subtitles on seek
- video: respect --deinterlace=auto
- vo_direct3d: add missing header (fixes Cygwin build)
- vo_opengl: angle: try D3D9 when D3D11 fails eglInitialize
- vo_opengl: angle: use WARP if there are no hw adapters (makes it work on Windows 7 without hardware-accelerated graphics)
- vo_opengl: increase 3DLUT accuracy at smaller LUT sizes
- vo_opengl: remove the 3dlut-size npot2 restriction
- vo_wayland: fix high CPU usage due to busy polling
- wayland_common: clip window size to the display output size
- wayland_common: fix crashes when switching to fullscreen before the video output is fully initialized
- wayland_common: fix fullscreen image switching bug
- wayland_common: prevent black bars on most non-native aspect ratios
- wayland_common: remove untested/unusable wayland dnd code
- win32: mpv.rc: re-add version info
- x11: skip ICC update on every window move
- ytdl: Error out with http_dash_segments (unsupported for now)
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.18.1..v0.19.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.18.1...v0.19.0 or
http://git.srsfckn.biz/mpv/log/?qt=range&q=v0.18.1..v0.19.0
Release 0.18.1
==============
View File
Whitespace-only changes.
+1 -1
View File
@@ -29,7 +29,7 @@ pacman -S --noconfirm --needed \
$MINGW_PACKAGE_PREFIX-libjpeg-turbo \
$MINGW_PACKAGE_PREFIX-lua51 \
$MINGW_PACKAGE_PREFIX-rubberband \
$MINGW_PACKAGE_PREFIX-uchardet
$MINGW_PACKAGE_PREFIX-uchardet-git
# Delete unused packages to reduce space used in the Appveyor cache
pacman -Sc --noconfirm
+24
View File
@@ -0,0 +1,24 @@
#! /usr/bin/env perl
use strict;
use warnings;
# Convert the contents of a file into a C string constant.
# Note that the compiler will implicitly add an extra 0 byte at the end
# of every string, so code using the string may need to remove that to get
# the exact contents of the original file.
# FIXME: why not a char array?
# treat only alphanumeric and punctuations (excluding " and ?) as safe
my $unsafe_chars = qr{[^][A-Za-z0-9!#%&'()*+,./:;<=>^_{|}~ -]};
for my $file (@ARGV) {
open my $fh, '<:raw', $file or next;
print "/* Generated from $file */\n";
while (<$fh>) {
# replace unsafe chars with their equivalent octal escapes
s/($unsafe_chars)/\\@{[sprintf '%03o', ord($1)]}/gos;
print "\"$_\"\n"
}
close $fh;
}
-31
View File
@@ -1,31 +0,0 @@
#!/usr/bin/env python
# Convert the contents of a file into a C string constant.
# Note that the compiler will implicitly add an extra 0 byte at the end
# of every string, so code using the string may need to remove that to get
# the exact contents of the original file.
from __future__ import unicode_literals
import sys
# Indexing a byte string yields int on Python 3.x, and a str on Python 2.x
def pord(c):
return ord(c) if type(c) == str else c
def file2string(infilename, infile, outfile):
outfile.write("// Generated from %s\n\n" % infilename)
conv = ['\\' + ("%03o" % c) for c in range(256)]
safe_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" \
"0123456789!#%&'()*+,-./:;<=>?[]^_{|}~ "
for c in safe_chars:
conv[ord(c)] = c
for c, esc in ("\nn", "\tt", r"\\", '""'):
conv[ord(c)] = '\\' + esc
for line in infile:
outfile.write('"' + ''.join(conv[pord(c)] for c in line) + '"\n')
if __name__ == "__main__":
with open(sys.argv[1], 'rb') as infile:
file2string(sys.argv[1], infile, sys.stdout)
-9
View File
@@ -1,9 +0,0 @@
#!/bin/sh
# This script is expected to be called as TOOLS/gen-osd-font.sh (it will access
# TOOLS/mpv-osd-symbols.sfdir), and it will write sub/osd_font.otf.
# Needs fontforge with python scripting
fontforge -lang=py -c 'f=open(argv[1]); f.generate(argv[2])' \
TOOLS/mpv-osd-symbols.sfdir sub/osd_font.otf
+30
View File
@@ -0,0 +1,30 @@
use 5.008;
use strict;
use warnings;
# ABSTRACT: Module collection to parse Matroska files.
package Parse::Matroska;
=head1 DESCRIPTION
C<use>s L<Parse::Matroska::Reader>. See the documentation
of the modules mentioned in L</"SEE ALSO"> for more information
in how to use this module.
It's intended for this module to contain high-level interfaces
to the other modules in the distribution.
=head1 SOURCE CODE
L<https://github.com/Kovensky/Parse-Matroska>
=head1 SEE ALSO
L<Parse::Matroska::Reader>, L<Parse::Matroska::Element>,
L<Parse::Matroska::Definitions>.
=cut
use Parse::Matroska::Reader;
1;
+357
View File
@@ -0,0 +1,357 @@
use 5.008;
use strict;
use warnings;
# ABSTRACT: internal EBML grammar definitions
package Parse::Matroska::Definitions;
use Parse::Matroska::Utils qw{uniq uncamelize};
use Exporter;
our @ISA = qw{Exporter};
our @EXPORT_OK = qw{elem_by_hexid %EBML_DEFINITION %MATROSKA_DEFINITION};
=head1 SYNOPSIS
use Parse::Matroska::Definitions qw{elem_by_hexid};
my $ebml_id = elem_by_hexid('1a45dfa3');
print "EBML ID $ebml_id->{elid}'s name: $ebml_id->{name}";
=head1 DESCRIPTION
Contains the definition of the EBML grammar as expected in
Matroska files. This module is meant mostly for internal use.
As this was extended from a script in mpv-player, some data
generated is apparently useless for regular module users
but is still relevant to the mpv-player script. Such data
is annotated as being for mpv compatibility.
=head1 NOTE
The API of this module is not yet considered stable.
=head1 GLOBALS
These global variables are considered B<immutable>.
=head2 @Parse::Matroska::Definitions::global_elem_list
A global list of known matroska elements. Useful for
mpv's matroska script, used for generating C headers
that parse matroska.
=head2 %Parse::Matroska::Definitions::global_elem_dict
A global hash of known matroska elements. Used internally
by L</elem_by_hexid($id)>.
=cut
@Parse::Matroska::Definitions::global_elem_list = ();
%Parse::Matroska::Definitions::global_elem_dict = ();
=head2 %EBML_DEFINITION
Optionally-importable hash of known EBML IDs belonging
to the EBML generic grammar.
=head2 %MATROSKA_DEFINITION
Optionally-importable hash of known EBML IDs belonging
to the Matroska-specific grammar.
=cut
our %EBML_DEFINITION = define_ebml();
our %MATROSKA_DEFINITION = define_matroska();
=method elem_by_hexid($id)
Returns an EBML Element Definition corresponding to the provided
hexadecimal string. Returns C<undef> if the element is unknown.
=cut
sub elem_by_hexid {
my ($elid) = @_;
return $Parse::Matroska::Definitions::global_elem_dict{$elid};
}
################################################
### Helper functions for document definition ###
################################################
# used by elem when setting the 'valname' key
use constant TYPE_MAP => {
uint => 'uint64_t',
str => 'char *',
binary => 'struct bstr',
ebml_id => 'uint32_t',
float => 'double',
sint => 'int64_t',
};
# this will be localized to "MATROSKA" or "EBML" on the elem declarations
our $ELEM_DEFINE_TYPE = undef;
=method elem($name,$elid,$valtype)
NOTE: never call this function yourself; it changes data structures
that are considered immutable outside of this package.
Internal API function that generates the EBML Element Definitions.
This API function returns an array which first element is C<$elid>
and the second is a generated hash. The generated hash is stored
in the @global_elem_list and %global_elem_dict.
The generated hash contains:
=for :list
= name
The EBML Element's name, given through C<$name>.
= elid
The EBML Element's hex id, given through C<$elid>. Used for lookups by L</elem_by_hexid($id)>.
= valtype
The EBML Element's type, given through C<$valtype>, except when C<$valtype> is an arrayref.
= multiple
If C<$name> ends with a C<*>, this is set as true and strips the C<*> from L</name>. Used to
mark elements that may be repeated.
= subelements
An arrayref of elements that may be children of this element, given through C<$valtype> if it
is an arrayref. Sets L</valtype> to C<sub> if there are subelements.
= subids
An arrayref listing all the L</elid>s of subelements, C<uniq>ified.
The following elements are for mpv compatibility:
=for :list
= definename
Name used for generating C #defines.
= fieldname
Name used for generating C struct fields.
= structname
Name used for generating C struct names.
= ebmltype
A pre-#defined constant to describe the element's type.
= valname
Typename used when declaring a struct field referring to this element.
=cut
sub elem {
my %e = (name => shift, elid => shift, valtype => shift);
# strip * from name, set 'multiple' if there was one
$e{multiple} = scalar $e{name} =~ s/\*$//;
# ELEM_DEFINE_TYPE is either MATROSKA or EBML
$e{definename} = "${ELEM_DEFINE_TYPE}_ID_".uc($e{name});
$e{fieldname} = uncamelize $e{name};
$e{structname} = "ebml_$e{fieldname}";
if (ref $e{valtype} eq 'HASH') {
$e{subelements} = $e{valtype};
$e{subids} = uniq map { $_->{elid} } values %{$e{subelements}};
$e{valtype} = 'sub';
$e{ebmltype} = 'EBML_TYPE_SUBELEMENTS';
$e{valname} = "struct $e{structname}";
} else {
$e{ebmltype} = "EBML_TYPE_\U$e{valtype}";
die "Unrecognized value type $e{valtype}" unless
defined ($e{valname} = TYPE_MAP->{$e{valtype}});
}
my $e = \%e;
push @Parse::Matroska::Definitions::global_elem_list, $e;
$Parse::Matroska::Definitions::global_elem_dict{$e{elid}} = $e;
return ($e{elid}, $e);
}
#############################################
### EBML and Matroska document definitons ###
#############################################
=method define_ebml
Internal function that defines the EBML generic grammar.
Must not be called from outside the package.
=cut
sub define_ebml {
local $ELEM_DEFINE_TYPE = 'EBML';
return (
elem('EBML', '1a45dfa3', {
elem('EBMLVersion', '4286', 'uint'),
elem('EBMLReadVersion', '42f7', 'uint'),
elem('EBMLMaxIDLength', '42f2', 'uint'),
elem('EBMLMaxSizeLength', '42f3', 'uint'),
elem('DocType', '4282', 'str'),
elem('DocTypeVersion', '4287', 'uint'),
elem('DocTypeReadVersion', '4285', 'uint'),
}),
elem('CRC32', 'bf', 'binary'),
elem('Void', 'ec', 'binary'),
);
}
=method define_matroska
Internal function that defines the Matroska-specific EBML grammar.
Must not be called from outside the package.
=cut
sub define_matroska {
local $ELEM_DEFINE_TYPE = 'MATROSKA';
return (
elem('Segment', '18538067', {
elem('SeekHead*', '114d9b74', {
elem('Seek*', '4dbb', {
elem('SeekID', '53ab', 'ebml_id'),
elem('SeekPosition', '53ac', 'uint'),
}),
}),
elem('Info*', '1549a966', {
elem('SegmentUID', '73a4', 'binary'),
elem('PrevUID', '3cb923', 'binary'),
elem('NextUID', '3eb923', 'binary'),
elem('TimecodeScale', '2ad7b1', 'uint'),
elem('DateUTC', '4461', 'sint'),
elem('Title', '7ba9', 'str'),
elem('MuxingApp', '4d80', 'str'),
elem('WritingApp', '5741', 'str'),
elem('Duration', '4489', 'float'),
}),
elem('Cluster*', '1f43b675', {
elem('Timecode', 'e7', 'uint'),
elem('BlockGroup*', 'a0', {
elem('Block', 'a1', 'binary'),
elem('BlockDuration', '9b', 'uint'),
elem('ReferenceBlock*', 'fb', 'sint'),
elem('DiscardPadding', '75A2', 'sint'),
}),
elem('SimpleBlock*', 'a3', 'binary'),
}),
elem('Tracks*', '1654ae6b', {
elem('TrackEntry*', 'ae', {
elem('TrackNumber', 'd7', 'uint'),
elem('TrackUID', '73c5', 'uint'),
elem('TrackType', '83', 'uint'),
elem('FlagEnabled', 'b9', 'uint'),
elem('FlagDefault', '88', 'uint'),
elem('FlagForced', '55aa', 'uint'),
elem('FlagLacing', '9c', 'uint'),
elem('MinCache', '6de7', 'uint'),
elem('MaxCache', '6df8', 'uint'),
elem('DefaultDuration', '23e383', 'uint'),
elem('TrackTimecodeScale', '23314f', 'float'),
elem('MaxBlockAdditionID', '55ee', 'uint'),
elem('Name', '536e', 'str'),
elem('Language', '22b59c', 'str'),
elem('CodecID', '86', 'str'),
elem('CodecPrivate', '63a2', 'binary'),
elem('CodecName', '258688', 'str'),
elem('CodecDecodeAll', 'aa', 'uint'),
elem('CodecDelay', '56AA', 'uint'),
elem('SeekPreRoll', '56BB', 'uint'),
elem('Video', 'e0', {
elem('FlagInterlaced', '9a', 'uint'),
elem('PixelWidth', 'b0', 'uint'),
elem('PixelHeight', 'ba', 'uint'),
elem('DisplayWidth', '54b0', 'uint'),
elem('DisplayHeight', '54ba', 'uint'),
elem('DisplayUnit', '54b2', 'uint'),
elem('FrameRate', '2383e3', 'float'),
elem('ColourSpace', '2eb524', 'binary'),
elem('StereoMode', '53b8', 'uint'),
}),
elem('Audio', 'e1', {
elem('SamplingFrequency', 'b5', 'float'),
elem('OutputSamplingFrequency', '78b5', 'float'),
elem('Channels', '9f', 'uint'),
elem('BitDepth', '6264', 'uint'),
}),
elem('ContentEncodings', '6d80', {
elem('ContentEncoding*', '6240', {
elem('ContentEncodingOrder', '5031', 'uint'),
elem('ContentEncodingScope', '5032', 'uint'),
elem('ContentEncodingType', '5033', 'uint'),
elem('ContentCompression', '5034', {
elem('ContentCompAlgo', '4254', 'uint'),
elem('ContentCompSettings', '4255', 'binary'),
}),
}),
}),
}),
}),
elem('Cues', '1c53bb6b', {
elem('CuePoint*', 'bb', {
elem('CueTime', 'b3', 'uint'),
elem('CueTrackPositions*', 'b7', {
elem('CueTrack', 'f7', 'uint'),
elem('CueClusterPosition', 'f1', 'uint'),
elem('CueRelativePosition','f0', 'uint'),
elem('CueDuration', 'b2', 'uint'),
}),
}),
}),
elem('Attachments', '1941a469', {
elem('AttachedFile*', '61a7', {
elem('FileDescription', '467e', 'str'),
elem('FileName', '466e', 'str'),
elem('FileMimeType', '4660', 'str'),
elem('FileData', '465c', 'binary'),
elem('FileUID', '46ae', 'uint'),
}),
}),
elem('Chapters', '1043a770', {
elem('EditionEntry*', '45b9', {
elem('EditionUID', '45bc', 'uint'),
elem('EditionFlagHidden', '45bd', 'uint'),
elem('EditionFlagDefault', '45db', 'uint'),
elem('EditionFlagOrdered', '45dd', 'uint'),
elem('ChapterAtom*', 'b6', {
elem('ChapterUID', '73c4', 'uint'),
elem('ChapterTimeStart', '91', 'uint'),
elem('ChapterTimeEnd', '92', 'uint'),
elem('ChapterFlagHidden', '98', 'uint'),
elem('ChapterFlagEnabled', '4598', 'uint'),
elem('ChapterSegmentUID', '6e67', 'binary'),
elem('ChapterSegmentEditionUID', '6ebc', 'uint'),
elem('ChapterDisplay*', '80', {
elem('ChapString', '85', 'str'),
elem('ChapLanguage*', '437c', 'str'),
elem('ChapCountry*', '437e', 'str'),
}),
}),
}),
}),
elem('Tags*', '1254c367', {
elem('Tag*', '7373', {
elem('Targets', '63c0', {
elem('TargetTypeValue', '68ca', 'uint'),
elem('TargetTrackUID', '63c5', 'uint'),
elem('TargetEditionUID', '63c9', 'uint'),
elem('TargetChapterUID', '63c4', 'uint'),
elem('TargetAttachmentUID', '63c6', 'uint'),
}),
elem('SimpleTag*', '67c8', {
elem('TagName', '45a3', 'str'),
elem('TagLanguage', '447a', 'str'),
elem('TagString', '4487', 'str'),
}),
}),
}),
}),
);
}
1;
+331
View File
@@ -0,0 +1,331 @@
use 5.008;
use strict;
use warnings;
# ABSTRACT: a mid-level representation of an EBML element
package Parse::Matroska::Element;
use Carp;
use List::Util qw{first};
=head1 SYNOPSIS
use Parse::Matroska::Reader;
my $reader = Parse::Matroska::Reader->new($path);
my $elem = $reader->read_element;
print "ID: $elem->{elid}\n";
print "Name: $elem->{name}\n";
print "Length: $elem->{content_len}\n";
print "Type: $elem->{type}\n";
print "Child count: ", scalar(@{$elem->all_children}), "\n";
if ($elem->{type} eq 'sub') {
while (my $chld = $elem->next_child) {
print "Child Name: $chld->{name}\n";
}
} else {
print "Value: ", $elem->get_value, "\n";
}
=head1 DESCRIPTION
Represents a single Matroska element as decoded by
L<Parse::Matroska::Reader>. This is essentially a hash
augmented with functions for delay-loading of binary
values and children elements.
=head1 NOTE
The API of this module is not yet considered stable.
=attr elid
The EBML Element ID, suitable for passing to
L<Parse::Matroska::Definitions/elem_by_hexid>.
=attr name
The EBML Element's name.
=attr type
The EBML Element's type. Can be C<uint>, C<sint>,
C<float>, C<ebml_id>, C<str> or C<binary>. See L</value>
for details.
Equivalent to
C<elem_by_hexid($elem-E<gt>{value})-E<gt>{valtype}>.
=attr value
The EBML Element's value. Should be obtained through
L</get_value>.
Is an unicode string if the L</type> is C<str>, that is,
the string has already been decoded by L<Encode/decode>.
Is C<undef> if the L</type> is C<binary> and the contents
were delay-loaded and not yet read. L</get_value> will
do the delayed load if needed.
Is an arrayref if the L</type> is C<sub>, containing
the children nodes that were already loaded.
Is a hashref if the L</type> is C<ebml_id>, containing
the referred element's information as defined in
L<Parse::Matroska::Definitions>. Calling
C<elem_by_hexid($elem-E<gt>{value}-E<gt>{elid})> will
return the same object as $elem->{value}.
=attr full_len
The entire length of this EBML Element, including
the header's.
=attr size_len
The length of the size marker. Used when calculating
L</full_len> from L</content_len>
=attr content_len
The length of the contents of this EBML Element,
which excludes the header.
=attr reader
A weakened reference to the associated
L<Parse::Matroska::Reader>.
=method new(%hash)
Creates a new Element initialized with the hash
given as argument.
=cut
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
$self->initialize(@_);
return $self;
}
=method initialize(%hash)
Called by L</new> on initialization.
=cut
sub initialize {
my ($self, %args) = @_;
for (keys %args) {
$self->{$_} = $args{$_};
}
$self->{depth} = 0 unless $self->{depth};
}
=method skip
Called by the user to ignore the contents of this EBML node.
Needed when ignoring the children of a node.
=cut
sub skip {
my ($self) = @_;
my $reader = $self->{reader};
return unless $reader; # we don't have to skip if there's no reader
my $pos = $reader->getpos;
croak "Too late to skip, reads were already done"
if $pos ne $self->{data_pos};
$reader->skip($self->{content_len});
}
=method get_value($keep_bin)
Returns the value contained by this EBML element.
If the element has children, returns an arrayref to
the children elements that were already encountered.
If the element's type is C<binary> and the value was
delay-loaded, does the reading now.
If $keep_bin is true, the delay-loaded data is kept
as the L</value>, otherwise, further calls to
C<get_value> will reread the data from the L</reader>.
=cut
sub get_value {
my ($self, $keep_bin) = @_;
return undef if $self->{type} eq 'skip';
return $self->{value} if $self->{value};
my $reader = $self->{reader} or
croak "The associated Reader has been deleted";
# delay-loaded 'binary'
if ($self->{type} eq 'binary') {
croak "Cannot seek in the current Reader" unless $self->{data_pos};
# seek to the data position...
$reader->setpos($self->{data_pos});
# read the data, keeping it in value if requested
if ($keep_bin) {
$self->{value} = $reader->readlen($self->{content_len});
return $self->{value};
} else {
return $reader->readlen($self->{content_len});
}
}
}
=method next_child($read_bin)
Builtin iterator; reads and returns the next child element.
Always returns undef if the type isn't C<sub>.
Returns undef at the end of the iterator and resets itself to
point to the first element; so calling L</next_child($read_bin)>
after the iterator returned C<undef> will return the first child.
The optional C<$read_bin> parameter has the children elements
not delay-load their value if their type is C<binary>.
If all children elements have already been read, return
each element in-order as would be given by
L</all_children($recurse,$read_bin)>.
=cut
sub next_child {
my ($self, $read_bin) = @_;
return unless $self->{type} eq 'sub';
if ($self->{_all_children_read}) {
my $idx = $self->{_last_child} ||= 0;
if ($idx == @{$self->{value}}) {
# reset the iterator, returning undef once
$self->{_last_child} = 0;
return;
}
my $ret = $self->{value}->[$idx];
++$idx;
$self->{_last_child} = $idx;
return $ret;
}
my $len = defined $self->{remaining_len}
? $self->{remaining_len}
: $self->{content_len};
if ($len == 0) {
# we've read all children; switch into $self->{value} iteration mode
$self->{_all_children_read} = 1;
# return undef since the iterator will reset
return;
}
$self->{pos_offset} ||= 0;
my $pos = $self->{data_pos};
my $reader = $self->{reader} or croak "The associated reader has been deleted";
$reader->setpos($pos);
$reader->{fh}->seek($self->{pos_offset}, 1) if $pos;
my $chld = $reader->read_element($read_bin);
return undef unless defined $chld;
$self->{pos_offset} += $chld->{full_len};
$self->{remaining_len} = $len - $chld->{full_len};
if ($self->{remaining_len} < 0) {
croak "Child elements consumed $self->{remaining_len} more bytes than parent $self->{name} contained";
}
$chld->{depth} = $self->{depth} + 1;
$self->{value} ||= [];
push @{$self->{value}}, $chld;
return $chld;
}
=method all_children($recurse,$read_bin)
Calls L</populate_children($recurse,$read_bin)> on self
and returns an arrayref with the children nodes.
Both C<$recurse> and C<$read_bin> are optional and default
to false.
=cut
sub all_children {
my ($self, $recurse, $read_bin) = @_;
$self->populate_children($recurse, $read_bin);
return $self->{value};
}
=method children_by_name($name)
Searches in the already read children elements for all
elements with the EBML name C<$name>. Returns an array
containing all found elements. On scalar context,
returns only the first element found.
Croaks if the element's C<type> isn't C<sub>.
=cut
sub children_by_name {
my ($self, $name) = @_;
return unless defined wantarray; # don't do work if work isn't wanted
croak "Element can't have children" unless $self->{type} eq 'sub';
my @found = grep { $_->{name} eq $name } @{$self->{value}};
return @found if wantarray; # list
return shift @found if defined wantarray; # scalar
}
=method populate_children($recurse,$read_bin)
Populates the internal array of children elements, that is,
requests that the associated L<Matroska::Parser::Reader> reads
all children elements. Returns itself.
Returns false if the element's C<type> isn't C<sub>.
If C<$recurse> is provided and is true, the method will call
itself in the children elements with the same parameters it
received; this will build a full EBML tree.
If C<$read_bin> is provided and is true, disables delay-loading
of the contents of C<binary>-type nodes, reading the contents
to memory.
If both C<$recurse> and C<$read_bin> are true, entire EBML trees
can be loaded without requiring seeks, thus behaving correctly
on unseekable streams. If C<$read_bin> is false, the entire EBML
tree is still loaded, but calling L</get_value> on C<binary>-type
nodes will produce an error on unseekable streams.
=cut
sub populate_children {
my ($self, $recurse, $read_bin) = @_;
return unless $self->{type} eq 'sub';
if (@{$self->{value}} && $recurse) {
# only recurse
foreach (@{$self->{value}}) {
$_->populate_children($recurse, $read_bin);
}
return $self;
}
while (my $chld = $self->next_child($read_bin)) {
$chld->populate_children($recurse, $read_bin) if $recurse;
}
return $self;
}
1;
+426
View File
@@ -0,0 +1,426 @@
use 5.008;
use strict;
use warnings;
# ABSTRACT: a low-level reader for EBML files
package Parse::Matroska::Reader;
use Parse::Matroska::Definitions qw{elem_by_hexid};
use Parse::Matroska::Element;
use Carp;
use Scalar::Util qw{openhandle weaken};
use IO::Handle;
use IO::File;
use List::Util qw{first};
use Encode;
use constant BIGINT_TRY => 'Pari,GMP,FastCalc';
use Math::BigInt try => BIGINT_TRY;
use Math::BigRat try => BIGINT_TRY;
=head1 SYNOPSIS
use Parse::Matroska::Reader;
my $reader = Parse::Matroska::Reader->new($path);
$reader->close;
$reader->open(\$string_with_matroska_data);
my $elem = $reader->read_element;
print "Element ID: $elem->{elid}\n";
print "Element name: $elem->{name}\n";
if ($elem->{type} ne 'sub') {
print "Element value: $elem->get_value\n";
} else {
while (my $child = $elem->next_child) {
print "Child element: $child->{name}\n";
}
}
$reader->close;
=head1 DESCRIPTION
Reads EBML data, which is used in Matroska files.
This is a low-level reader which is meant to be used as a backend
for higher level readers. TODO: write the high level readers :)
=head1 NOTE
The API of this module is not yet considered stable.
=method new
Creates a new reader.
Calls L</open($arg)> with its arguments if provided.
=cut
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
$self->open(@_) if @_;
return $self;
}
=method open($arg)
Creates the internal filehandle. The argument can be:
=for :list
* An open filehandle or L<IO::Handle> object.
The filehandle is not C<dup()>ed, so calling L</close> in this
object will close the given filehandle as well.
* A scalar containing a path to a file.
* On perl v5.14 or newer, a scalarref pointing to EBML data.
For similar functionality in older perls, give an L<IO::String> object
or the handle to an already C<open>ed scalarref.
=cut
sub open {
my ($self, $arg) = @_;
$self->{fh} = openhandle($arg) || IO::File->new($arg, "<:raw")
or croak "Can't open $arg: $!";
}
=method close
Closes the internal filehandle.
=cut
sub close {
my ($self) = @_;
$self->{fh}->close;
delete $self->{fh};
}
# equivalent to $self->readlen(1), possibly faster
sub _getc {
my ($self) = @_;
my $c = $self->{fh}->getc;
croak "Can't do read of length 1: $!" if !defined $c && $!;
return $c;
}
=method readlen($length)
Reads C<$length> bytes from the internal filehandle.
=cut
sub readlen {
my ($self, $len) = @_;
my $data;
my $readlen = $self->{fh}->read($data, $len);
croak "Can't do read of length $len: $!"
unless defined $readlen;
return $data;
}
# converts a byte string into an integer
# we do so by converting the integer into a hex string (big-endian)
# and then reading the hex-string into an integer
sub _bin2int($) {
my ($bin) = @_;
# if the length is larger than 3
# the resulting integer might be larger than INT_MAX
if (length($bin) > 3) {
return Math::BigInt->from_hex(unpack("H*", $bin));
}
return hex(unpack("H*", $bin));
}
# creates a floating-point number with the given mantissa and exponent
sub _ldexp {
my ($mantissa, $exponent) = @_;
my $r = new Math::BigRat($mantissa);
return $r * Math::BigRat->new(2)**$exponent;
}
# NOTE: the read_* functions are hard to read because they're ports
# of even harder to read python functions.
# TODO: make them readable
=method read_id
Reads an EBML ID atom in hexadecimal string format, suitable
for passing to L<Parse::Matroska::Definitions/elem_by_hexid($id)>.
=cut
sub read_id {
my ($self) = @_;
my $t = $self->_getc;
return undef unless defined $t;
my $i = 0;
my $mask = 1<<7;
if (ord($t) == 0) {
croak "Matroska Syntax error: first byte of ID was \\0"
}
until (ord($t) & $mask) {
++$i;
$mask >>= 1;
}
# return hex string of the bytes we just read
return unpack "H*", ($t . $self->readlen($i));
}
=method read_size
Reads an EBML Data Size atom, which immediately follows
an EBML ID atom.
This returns an array consisting of:
=for :list
0. The length of the Data Size atom.
1. The value encoded in the Data Size atom, which is the length of all the data following it.
=cut
sub read_size {
my ($self) = @_;
my $t = $self->_getc;
my $i = 0;
my $mask = 1<<7;
if (ord($t) == 0) {
croak "Matroska Syntax error: first byte of data size was \\0"
}
until (ord($t) & $mask) {
++$i;
$mask >>= 1;
}
$t = $t & chr($mask-1); # strip length bits (keep only significant bits)
return ($i+1, _bin2int $t . $self->readlen($i));
}
=method read_str($length)
Reads a string of length C<$length> bytes from the internal filehandle.
The string is already L<Encode/decode>d from C<UTF-8>, which is the
standard Matroska string encoding.
=cut
{
my $utf8 = find_encoding("UTF-8");
sub read_str {
my ($self, $length) = @_;
return $utf8->decode($self->readlen($length));
}
}
=method read_uint($length)
Reads an unsigned integer of length C<$length> bytes
from the internal filehandle.
Returns a L<Math::BigInt> object if C<$length> is greater
than 4.
=cut
sub read_uint {
my ($self, $length) = @_;
return _bin2int $self->readlen($length);
}
=method read_sint($length)
Reads a signed integer of length C<$length> bytes
from the internal filehandle.
Returns a L<Math::BigInt> object if C<$length> is greater
than 4.
=cut
sub read_sint {
my ($self, $length) = @_;
my $i = $self->read_uint($length);
# Apply 2's complement to the unsigned int
my $mask = int(2 ** ($length * 8 - 1));
# if the most significant bit is set...
if ($i & $mask) {
# subtract the MSB twice
$i -= 2 * $mask;
}
return $i;
}
=method read_float($length)
Reads an IEEE floating point number of length C<$length>
bytes from the internal filehandle.
Only lengths C<4> and C<8> are supported (C C<float> and C<double>).
=cut
{
my $b1 = new Math::BigInt 1;
sub read_float {
my ($self, $length) = @_;
my $i = new Math::BigInt $self->read_uint($length)->bstr;
my $f;
# These evil expressions reinterpret an unsigned int as IEEE binary floats
if ($length == 4) {
$f = _ldexp(($i & ((1<<23) - 1)) + (1<<23), ($i>>23 & ((1<<8) - 1)) - 150);
$f = -$f if $i & ($b1<<31);
} elsif ($length == 8) {
$f = _ldexp(($i & (($b1<<52) - 1)) + ($b1<<52), ($i>>52 & ((1<<12) - 1)) - 1075);
$f = -$f if $i & ($b1<<63);
} else {
croak "Matroska Syntax error: unsupported IEEE float byte size $length";
}
return $f;
}
}
=method read_ebml_id($length)
Reads an EBML ID when it's encoded as the data inside another
EBML element, that is, when the enclosing element's C<type> is
C<ebml_id>.
This returns a hashref with the EBML element description as
defined in L<Parse::Matroska::Definitions>.
=cut
sub read_ebml_id {
my ($self, $length) = @_;
return elem_by_hexid(unpack("H*", $self->readlen($length)));
}
=method skip($length)
Skips C<$length> bytes in the internal filehandle.
=cut
sub skip {
my ($self, $len) = @_;
return if $self->{fh}->can('seek') && $self->{fh}->seek($len, 1);
$self->readlen($len);
return;
}
=method getpos
Wrapper for L<IO::Seekable/$io-E<gt>getpos> in the internal filehandle.
Returns undef if the internal filehandle can't C<getpos>.
=cut
sub getpos {
my ($self) = @_;
return undef unless $self->{fh}->can('getpos');
return $self->{fh}->getpos;
}
=method setpos($pos)
Wrapper for L<IO::Seekable/$io-E<gt>setpos> in the internal filehandle.
Returns C<undef> if the internal filehandle can't C<setpos>.
Croaks if C<setpos> does not seek to the requested position,
that is, if calling C<getpos> does not yield the same object
as the C<$pos> argument.
=cut
sub setpos {
my ($self, $pos) = @_;
return undef unless $pos && $self->{fh}->can('setpos');
my $ret = $self->{fh}->setpos($pos);
croak "Cannot seek to correct position"
unless $self->getpos eq $pos;
return $ret;
}
=method read_element($read_bin)
Reads a full EBML element from the internal filehandle.
Returns a L<Parse::Matroska::Element> object initialized with
the read data. If C<read_bin> is not present or is false, will
delay-load the contents of C<binary> type elements, that is,
they will only be loaded when calling C<get_value> on the
returned L<Parse::Matroska::Element> object.
Does not read the children of the element if its type is
C<sub>. Look into the L<Parse::Matroska::Element> interface
for details in how to read children elements.
Pass a true C<$read_bin> if the stream being read is not
seekable (C<getpos> is undef) and the contents of C<binary>
elements is desired, otherwise seeking errors or internal
filehandle corruption might occur.
=cut
sub read_element {
my ($self, $read_bin) = @_;
return undef if $self->{fh}->eof;
my $elem_pos = $self->getpos;
my $elid = $self->read_id;
my $elem_def = elem_by_hexid($elid);
my ($size_len, $content_len) = $self->read_size;
my $full_len = length($elid)/2 + $size_len + $content_len;
my $elem = Parse::Matroska::Element->new(
elid => $elid,
name => $elem_def && $elem_def->{name},
type => $elem_def && $elem_def->{valtype},
size_len => $size_len,
content_len => $content_len,
full_len => $full_len,
reader => $self,
elem_pos => $elem_pos,
data_pos => $self->getpos,
);
weaken($elem->{reader});
if (defined $elem_def) {
if ($elem->{type} eq 'sub') {
$elem->{value} = [];
} elsif ($elem->{type} eq 'str') {
$elem->{value} = $self->read_str($content_len);
} elsif ($elem->{type} eq 'ebml_id') {
$elem->{value} = $self->read_ebml_id($content_len);
} elsif ($elem->{type} eq 'uint') {
$elem->{value} = $self->read_uint($content_len);
} elsif ($elem->{type} eq 'sint') {
$elem->{value} = $self->read_sint($content_len);
} elsif ($elem->{type} eq 'float') {
$elem->{value} = $self->read_float($content_len);
} elsif ($elem->{type} eq 'skip') {
$self->skip($content_len);
} elsif ($elem->{type} eq 'binary') {
if ($read_bin) {
$elem->{value} = $self->readlen($content_len);
} else {
$self->skip($content_len);
}
} else {
die "Matroska Definition error: type $elem->{valtype} unknown"
}
} else {
$self->skip($content_len);
}
return $elem;
}
1;
=head1 CAVEATS
Children elements have to be processed as soon as an element
with children is found, or their children ignored with
L<Parse::Matroska::Element/skip>. Not doing so doesn't cause
errors but results in an invalid structure, with constant C<0>
depth.
To work correctly in unseekable streams, either the contents
of C<binary>-type elements has to be ignored or the C<read_bin>
flag to C<read_element> has to be true.
+37
View File
@@ -0,0 +1,37 @@
use strict;
use warnings;
# ABSTRACT: internally-used helper functions
package Parse::Matroska::Utils;
use Exporter;
our @ISA = qw{Exporter};
our @EXPORT_OK = qw{uniq uncamelize};
=method uniq(@array)
The same as L<List::MoreUtils/"uniq LIST">.
Included to avoid depending on it since it's
not a core module.
=cut
sub uniq(@) {
my %seen;
return grep { !$seen{$_}++ } @_;
}
=method uncamelize($string)
Converts a "StringLikeTHIS" into a
"string_like_this".
=cut
sub uncamelize($) {
local $_ = shift;
# lc followed by UC: lc_UC
s/(?<=[a-z])([A-Z])/_\L$1/g;
# UC followed by two lc: _UClclc
s/([A-Z])(?=[a-z]{2})/_\L$1/g;
# strip leading _ that the second regexp might add; lowercase all
s/^_//; lc
}
-126
View File
@@ -1,126 +0,0 @@
-- This script adds control to the dynamic range compression ffmpeg
-- filter including key bindings for adjusting parameters.
--
-- See https://ffmpeg.org/ffmpeg-filters.html#acompressor for explanation
-- of the parameteres.
--
-- Default key bindings:
-- n: Toggle dynamic range compression on or off
-- F1/Shift+F1: Increase/Decrease threshold parameter
-- F2/Shift+F2: Increase/Decrease ratio parameter
-- F3/Shift+F3: Increase/Decrease knee parameter
-- F4/Shift+F4: Increase/Decrease makeup gain parameter
-- F5/Shift+F5: Increase/Decrease attack parameter
-- F6/Shift+F6: Increase/Decrease release parameter
--
-- To change key bindings in input.conf use:
-- BINDING script-message-to acompressor toggle-acompressor
-- BINDING script-message-to acompressor update-param PARAM INCREMENT
-- BINDING is the key binding to use, PARAM is either 'attack', 'release',
-- 'threshold', 'ratio', 'knee' or 'makeup' and INCREMENT is a signed floating
-- point value to add to the current parameter value.
--
-- You may also just adjust default parameters to your liking in this table.
local params = {
-- 'hide' defines wether the parameter should be hidden from OSD display (it will still be included in ffmpeg filter graph).
-- 'input_format' is used to parse the value back from a obtained filter graph.
-- 'output_format' defines how the value shall be formatted for creating the filter graph.
{ name = 'Attack', value= 20, min=0.01, max=2000, hide= 20, input_format='attack=(%d+[.%d+]*)', output_format='%g' },
{ name = 'Release', value=250, min=0.01, max=9000, hide=250, input_format='release=(%d+[.%d+]*)', output_format='%g' },
{ name = 'Threshold', value=-25, min= -30, max= 0, hide=nil, input_format='threshold=(-%d+[.%d+]*)dB', output_format='%gdB' },
{ name = 'Ratio', value= 3, min= 1, max= 20, hide=nil, input_format='ratio=(%d+[.%d+]*)', output_format='%g' },
{ name = 'Knee', value= 2, min= 1, max= 10, hide= 2, input_format='knee=(%d+[.%d+]*)dB', output_format='%gdB' },
{ name = 'Makeup', value= 8, min= 0, max= 24, hide=nil, input_format='makeup=(%d+[.%d+]*)dB', output_format='%gdB' }
}
-- Defines the mpv filter label to be used. This allows us to easily add/replace/remove it, so
-- it should be left so something meaningful and unique.
local filter_label = 'acompressor'
local function update_filter()
local graph = {}
local pretty = {}
for _,param in pairs(params) do
graph[#graph+1] = string.format('%s=' .. param.output_format, string.lower(param.name), param.value)
if param.hide ~= param.value then
pretty[#pretty+1] = string.format('%s: ' .. param.output_format, param.name, param.value)
end
end
if #pretty == 0 then
pretty = ''
else
pretty = '\n(' .. table.concat(pretty, ', ') .. ')'
end
mp.command(string.format('no-osd af add @%s:lavfi=[acompressor=%s]; show-text "Dynamic range compressor: enabled%s" 4000', filter_label, table.concat(graph, ':'), pretty))
end
local function read_filter()
local graph = nil
local af = mp.get_property_native('af', {})
for i = 1, #af do
if af[i]['name'] == 'lavfi' and af[i]['label'] == 'acompressor' then
graph = af[i]['params']['graph']
break
end
end
if graph == nil then
return false
end
for _,param in pairs(params) do
local value = tonumber(string.match(graph, param.input_format))
if value ~= nil and value >= param.min and value <= param.max then
param.value = value
end
end
return true
end
local function toggle_acompressor()
if read_filter() then
mp.command(string.format('no-osd af del @%s; show-text "Dynamic range compressor: disabled"', filter_label))
else
update_filter()
end
end
local function update_param(name, increment)
-- The current filter values could come from a watch_later config.
-- read_filter() will parse them, so that we don't clobber those with our default values.
read_filter()
for _,param in pairs(params) do
if string.lower(param.name) == string.lower(name) then
param.value = math.max(param.min, math.min(param.value + increment, param.max))
update_filter()
return
end
end
mp.msg.error('Unknown parameter "' .. name .. '"')
end
mp.add_key_binding("n", "toggle-acompressor", toggle_acompressor)
mp.register_script_message('update-param', update_param)
mp.add_key_binding("F1", 'acompressor-inc-threshold', function() update_param('threshold', -5); end, { repeatable = true })
mp.add_key_binding("Shift+F1", 'acompressor-dec-threshold', function() update_param('Threshold', 5); end, { repeatable = true })
mp.add_key_binding("F2", 'acompressor-inc-ratio', function() update_param('Ratio', 1); end, { repeatable = true })
mp.add_key_binding("Shift+F2", 'acompressor-dec-ratio', function() update_param('Ratio', -1); end, { repeatable = true })
mp.add_key_binding("F3", 'acompressor-inc-knee', function() update_param('Knee', 1); end, { repeatable = true })
mp.add_key_binding("Shift+F3", 'acompressor-dec-knee', function() update_param('Knee', -1); end, { repeatable = true })
mp.add_key_binding("F4", 'acompressor-inc-makeup', function() update_param('Makeup', 1); end, { repeatable = true })
mp.add_key_binding("Shift+F4", 'acompressor-dec-makeup', function() update_param('Makeup', -1); end, { repeatable = true })
mp.add_key_binding("F5", 'acompressor-inc-attack', function() update_param('Attack', 10); end, { repeatable = true })
mp.add_key_binding("Shift+F5", 'acompressor-dec-attack', function() update_param('Attack', -10); end, { repeatable = true })
mp.add_key_binding("F6", 'acompressor-inc-release', function() update_param('Release', 10); end, { repeatable = true })
mp.add_key_binding("Shift+F6", 'acompressor-dec-release', function() update_param('Release', -10); end, { repeatable = true })
+2 -9
View File
@@ -7,13 +7,6 @@
-- Add at most 5000 * 2 files when starting a file (before + after).
MAXENTRIES = 5000
local options = require 'mp.options'
o = {
disabled = false
}
options.read_options(o)
function Set (t)
local set = {}
for _, v in pairs(t) do set[v] = true end
@@ -32,7 +25,7 @@ function add_files_at(index, files)
local oldcount = mp.get_property_number("playlist-count", 1)
for i = 1, #files do
mp.commandv("loadfile", files[i], "append")
mp.commandv("playlist-move", oldcount + i - 1, index + i - 1)
mp.commandv("playlist_move", oldcount + i - 1, index + i - 1)
end
end
@@ -56,7 +49,7 @@ end
function find_and_add_entries()
local path = mp.get_property("path", "")
local dir, filename = mputils.split_path(path)
if o.disabled or #dir == 0 then
if #dir == 0 then
return
end
local pl_count = mp.get_property_number("playlist-count", 1)
+99
View File
@@ -0,0 +1,99 @@
-- This script enables live control of the dynamic range compression
-- (drc) audio filter while the video is playing back. This can be
-- useful to avoid having to stop and restart mpv to adjust filter
-- parameters. See the entry for "drc" under the "AUDIO FILTERS"
-- section of the man page for a complete description of the filter.
--
-- This script registers the key-binding "\" to toggle the filter between
--
-- * off
-- * method=1 (single-sample smoothing)
-- * method=2 (multi-sample smoothing)
--
-- It registers the keybindings ctrl+9/ctrl+0 to decrease/increase the
-- target ampltiude. These keys will insert the filter at the default
-- target amplitude of 0.25 if it was not previously present.
--
-- OSD feedback of the current filter state is displayed on pressing
-- each bound key.
script_name = mp.get_script_name()
function print_state(params)
if params then
mp.osd_message(script_name..":\n"
.."method = "..params["method"].."\n"
.."target = "..params["target"])
else
mp.osd_message(script_name..":\noff")
end
end
function get_index_of_drc(afs)
for i,af in pairs(afs) do
if af["label"] == script_name then
return i
end
end
end
function append_drc(afs)
afs[#afs+1] = {
name = "drc",
label = script_name,
params = {
method = "1",
target = "0.25"
}
}
print_state(afs[#afs]["params"])
end
function modify_or_create_af(fun)
afs = mp.get_property_native("af")
i = get_index_of_drc(afs)
if not i then
append_drc(afs)
else
fun(afs, i)
end
mp.set_property_native("af", afs)
end
function drc_toggle_method_handler()
modify_or_create_af(
function (afs, i)
new_method=(afs[i]["params"]["method"]+1)%3
if new_method == 0 then
table.remove(afs, i)
print_state(nil)
else
afs[i]["params"]["method"] = tostring((afs[i]["params"]["method"])%2+1)
print_state(afs[i]["params"])
end
end
)
end
function drc_scale_target(factor)
modify_or_create_af(
function (afs)
afs[i]["params"]["target"] = tostring(afs[i]["params"]["target"]*factor)
print_state(afs[i]["params"])
end
)
end
function drc_louder_handler()
drc_scale_target(2.0)
end
function drc_quieter_handler()
drc_scale_target(0.5)
end
-- toggle between off, method 1 and method 2
mp.add_key_binding("\\", "drc_toggle_method", drc_toggle_method_handler)
-- increase or decrease target volume
mp.add_key_binding("ctrl+9", "drc_quieter", drc_quieter_handler)
mp.add_key_binding("ctrl+0", "drc_louder", drc_louder_handler)
+1 -9
View File
@@ -6,17 +6,9 @@
local utils = require("mp.utils")
function observe(name)
for i,name in ipairs(mp.get_property_native("property-list")) do
mp.observe_property(name, "native", function(name, val)
print("property '" .. name .. "' changed to '" ..
utils.to_string(val) .. "'")
end)
end
for i,name in ipairs(mp.get_property_native("property-list")) do
observe(name)
end
for i,name in ipairs(mp.get_property_native("options")) do
observe("options/" .. name)
end
+169
View File
@@ -0,0 +1,169 @@
#! /usr/bin/env perl
# Generate C definitions for parsing Matroska files.
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/lib";
use Parse::Matroska::Definitions;
use Parse::Matroska::Reader;
use Getopt::Long;
use List::Util qw{max};
my @global_elem_list = @Parse::Matroska::Definitions::global_elem_list;
Getopt::Long::Configure(qw{auto_version auto_help});
my %opt;
GetOptions(\%opt,
"generate-header",
"generate-definitions",
"full",
);
if ($opt{"generate-header"}) {
generate_c_header();
} elsif ($opt{"generate-definitions"}) {
generate_c_definitions();
} else {
for (@ARGV) {
my $reader = Parse::Matroska::Reader->new($_ eq '-' ? \*STDIN : $_) or die $!;
while (my $elem = $reader->read_element($_ eq '-')) {
process_elem($elem, $_ eq '-');
}
}
}
# Generate declarations for libmpdemux/ebml_types.h
sub generate_c_header {
print "/* Generated by TOOLS/matroska.pl, do not edit manually */\n\n";
# Write a #define for the ElementID of each known element
for my $el (@global_elem_list) {
printf "#define %-40s 0x%s\n", $el->{definename}, $el->{elid};
}
print "\n";
# Define a struct for each ElementID that has child elements
for my $el (@global_elem_list) {
next unless $el->{subelements};
print "\nstruct $el->{structname} {\n";
# Figure out the length of the longest variable name
# Used for pretty-printing in the next step
my $l = max(map { length $_->{valname} } values %{$el->{subelements}});
# Output each variable, with pointers for array (multiple) elements
for my $subel (sort { $a->{definename} cmp $b->{definename} } values %{$el->{subelements}}) {
printf " %-${l}s %s%s;\n",
$subel->{valname}, $subel->{multiple}?'*':' ', $subel->{fieldname};
}
print "\n";
# Output a counter variable for each element
# (presence/absence for scalars, item count for arrays)
for my $subel (sort values %{$el->{subelements}}) {
print " int n_$subel->{fieldname};\n"
}
print "};\n";
}
print "\n";
# Output extern references for ebml_elem_desc structs for each of the elements
# These are defined by generate_c_definitions
for my $el (@global_elem_list) {
next unless $el->{subelements};
print "extern const struct ebml_elem_desc $el->{structname}_desc;\n";
}
print "\n";
# Output the max number of sub-elements a known element might have
printf "#define MAX_EBML_SUBELEMENTS %d\n",
max(map { scalar keys %{$_->{subelements}} }
grep { $_->{subelements} } @global_elem_list);
}
# Generate definitions for libmpdemux/ebml_defs.c
sub generate_c_definitions {
print "/* Generated by TOOLS/matroska.pl, do not edit manually */\n\n";
# ebml_defs.c uses macros declared in ebml.c
for my $el (@global_elem_list) {
print "\n";
if ($el->{subelements}) {
# set N for the next macros
print "#define N $el->{fieldname}\n";
# define a struct ebml_$N_desc and gets ready to define fields
# this secretly opens two scopes; hence the }}; at the end
print "E_S(\"$el->{name}\", ".scalar(keys %{$el->{subelements}}).")\n";
# define a field for each subelement
# also does lots of macro magic, but doesn't open a scope
for my $subel (sort { $a->{definename} cmp $b->{definename} } values %{$el->{subelements}}) {
print "F($subel->{definename}, $subel->{fieldname}, ".
($subel->{multiple}?'1':'0').")\n";
}
# close the struct
print "}};\n";
# unset N since we've used it
print "#undef N\n";
} else {
print "E(\"$el->{name}\", $el->{fieldname}, $el->{ebmltype})\n";
}
}
}
sub repr {
my @ret;
foreach (@_) {
if (/'/) {
s/"/\\"/g;
push @ret, "\"$_\"";
} else {
push @ret, "'$_'";
}
}
return @ret if wantarray;
return pop @ret if defined wantarray;
return;
}
sub process_elem {
my ($elem, $read_bin) = @_;
unless ($opt{full}) {
if ($elem->{name} eq 'Cluster' || $elem->{name} eq 'Cues') {
$elem->skip;
return;
}
}
die unless $elem;
if ($elem->{type} ne 'skip') {
print "$elem->{depth} $elem->{elid} $elem->{name} size: $elem->{content_len} value: ";
}
if ($elem->{type} eq 'sub') {
print "subelements:\n";
while (my $chld = $elem->next_child($read_bin)) {
process_elem($chld);
}
} elsif ($elem->{type} eq 'binary') {
my $t = "<skipped $elem->{content_len} bytes>";
if ($elem->{content_len} < 20) {
$t = unpack "H*", $elem->get_value;
}
print "binary $t\n";
delete $elem->{value};
} elsif ($elem->{type} eq 'ebml_id') {
print "binary $elem->{value}->{elid} (".($elem->{value}->{name}||"UNKNOWN").")\n";
} elsif ($elem->{type} eq 'skip') {
# skip
} elsif ($elem->{type} eq 'str') {
print "string ". repr($elem->get_value) . "\n";
} else {
print "$elem->{type} ". $elem->get_value ."\n";
}
}
-471
View File
@@ -1,471 +0,0 @@
#!/usr/bin/env python3
"""
Generate C definitions for parsing Matroska files.
Can also be used to directly parse Matroska files and display their contents.
"""
#
# This file is part of MPlayer.
#
# MPlayer is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# MPlayer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with MPlayer; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# for compatibility with Python 2.x
from __future__ import print_function
elements_ebml = (
'EBML, 1a45dfa3, sub', (
'EBMLVersion, 4286, uint',
'EBMLReadVersion, 42f7, uint',
'EBMLMaxIDLength, 42f2, uint',
'EBMLMaxSizeLength, 42f3, uint',
'DocType, 4282, str',
'DocTypeVersion, 4287, uint',
'DocTypeReadVersion, 4285, uint',
),
'CRC32, bf, binary',
'Void, ec, binary',
)
elements_matroska = (
'Segment, 18538067, sub', (
'SeekHead*, 114d9b74, sub', (
'Seek*, 4dbb, sub', (
'SeekID, 53ab, ebml_id',
'SeekPosition, 53ac, uint',
),
),
'Info*, 1549a966, sub', (
'SegmentUID, 73a4, binary',
'PrevUID, 3cb923, binary',
'NextUID, 3eb923, binary',
'TimecodeScale, 2ad7b1, uint',
'DateUTC, 4461, sint',
'Title, 7ba9, str',
'MuxingApp, 4d80, str',
'WritingApp, 5741, str',
'Duration, 4489, float',
),
'Cluster*, 1f43b675, sub', (
'Timecode, e7, uint',
'BlockGroup*, a0, sub', (
'Block, a1, binary',
'BlockDuration, 9b, uint',
'ReferenceBlock*, fb, sint',
'DiscardPadding, 75A2, sint',
'BlockAdditions, 75A1, sub', (
'BlockMore*, A6, sub', (
'BlockAddID, EE, uint',
'BlockAdditional, A5, binary',
),
),
),
'SimpleBlock*, a3, binary',
),
'Tracks*, 1654ae6b, sub', (
'TrackEntry*, ae, sub', (
'TrackNumber, d7, uint',
'TrackUID, 73c5, uint',
'TrackType, 83, uint',
'FlagEnabled, b9, uint',
'FlagDefault, 88, uint',
'FlagForced, 55aa, uint',
'FlagLacing, 9c, uint',
'MinCache, 6de7, uint',
'MaxCache, 6df8, uint',
'DefaultDuration, 23e383, uint',
'TrackTimecodeScale, 23314f, float',
'MaxBlockAdditionID, 55ee, uint',
'Name, 536e, str',
'Language, 22b59c, str',
'CodecID, 86, str',
'CodecPrivate, 63a2, binary',
'CodecName, 258688, str',
'CodecDecodeAll, aa, uint',
'CodecDelay, 56aa, uint',
'SeekPreRoll, 56bb, uint',
'Video, e0, sub', (
'FlagInterlaced, 9a, uint',
'PixelWidth, b0, uint',
'PixelHeight, ba, uint',
'DisplayWidth, 54b0, uint',
'DisplayHeight, 54ba, uint',
'DisplayUnit, 54b2, uint',
'FrameRate, 2383e3, float',
'ColourSpace, 2eb524, binary',
'StereoMode, 53b8, uint',
'Colour, 55b0, sub', (
'MatrixCoefficients, 55B1, uint',
'BitsPerChannel, 55B2, uint',
'ChromaSubsamplingHorz, 55B3, uint',
'ChromaSubsamplingVert, 55B4, uint',
'CbSubsamplingHorz, 55B5, uint',
'CbSubsamplingVert, 55B6, uint',
'ChromaSitingHorz, 55B7, uint',
'ChromaSitingVert, 55B8, uint',
'Range, 55B9, uint',
'TransferCharacteristics, 55BA, uint',
'Primaries, 55BB, uint',
'MaxCLL, 55BC, uint',
'MaxFALL, 55BD, uint',
'MasteringMetadata, 55D0, sub', (
'PrimaryRChromaticityX, 55D1, float',
'PrimaryRChromaticityY, 55D2, float',
'PrimaryGChromaticityX, 55D3, float',
'PrimaryGChromaticityY, 55D4, float',
'PrimaryBChromaticityX, 55D5, float',
'PrimaryBChromaticityY, 55D6, float',
'WhitePointChromaticityX, 55D7, float',
'WhitePointChromaticityY, 55D8, float',
'LuminanceMax, 55D9, float',
'LuminanceMin, 55DA, float',
),
),
),
'Audio, e1, sub', (
'SamplingFrequency, b5, float',
'OutputSamplingFrequency, 78b5, float',
'Channels, 9f, uint',
'BitDepth, 6264, uint',
),
'ContentEncodings, 6d80, sub', (
'ContentEncoding*, 6240, sub', (
'ContentEncodingOrder, 5031, uint',
'ContentEncodingScope, 5032, uint',
'ContentEncodingType, 5033, uint',
'ContentCompression, 5034, sub', (
'ContentCompAlgo, 4254, uint',
'ContentCompSettings, 4255, binary',
),
),
),
),
),
'Cues, 1c53bb6b, sub', (
'CuePoint*, bb, sub', (
'CueTime, b3, uint',
'CueTrackPositions*, b7, sub', (
'CueTrack, f7, uint',
'CueClusterPosition, f1, uint',
'CueRelativePosition, f0, uint',
'CueDuration, b2, uint',
),
),
),
'Attachments, 1941a469, sub', (
'AttachedFile*, 61a7, sub', (
'FileDescription, 467e, str',
'FileName, 466e, str',
'FileMimeType, 4660, str',
'FileData, 465c, binary',
'FileUID, 46ae, uint',
),
),
'Chapters, 1043a770, sub', (
'EditionEntry*, 45b9, sub', (
'EditionUID, 45bc, uint',
'EditionFlagHidden, 45bd, uint',
'EditionFlagDefault, 45db, uint',
'EditionFlagOrdered, 45dd, uint',
'ChapterAtom*, b6, sub', (
'ChapterUID, 73c4, uint',
'ChapterTimeStart, 91, uint',
'ChapterTimeEnd, 92, uint',
'ChapterFlagHidden, 98, uint',
'ChapterFlagEnabled, 4598, uint',
'ChapterSegmentUID, 6e67, binary',
'ChapterSegmentEditionUID, 6ebc, uint',
'ChapterDisplay*, 80, sub', (
'ChapString, 85, str',
'ChapLanguage*, 437c, str',
'ChapCountry*, 437e, str',
),
),
),
),
'Tags*, 1254c367, sub', (
'Tag*, 7373, sub', (
'Targets, 63c0, sub', (
'TargetTypeValue, 68ca, uint',
'TargetTrackUID, 63c5, uint',
'TargetEditionUID, 63c9, uint',
'TargetChapterUID, 63c4, uint',
'TargetAttachmentUID, 63c6, uint',
),
'SimpleTag*, 67c8, sub', (
'TagName, 45a3, str',
'TagLanguage, 447a, str',
'TagString, 4487, str'
),
),
),
),
)
import sys
from math import ldexp
from binascii import hexlify
def byte2num(s):
return int(hexlify(s), 16)
class EOF(Exception): pass
def camelcase_to_words(name):
parts = []
start = 0
for i in range(1, len(name)):
if name[i].isupper() and (name[i-1].islower() or
name[i+1:i+2].islower()):
parts.append(name[start:i])
start = i
parts.append(name[start:])
return '_'.join(parts).lower()
class MatroskaElement(object):
def __init__(self, name, elid, valtype, namespace):
self.name = name
self.definename = '{0}_ID_{1}'.format(namespace, name.upper())
self.fieldname = camelcase_to_words(name)
self.structname = 'ebml_' + self.fieldname
self.elid = elid
self.valtype = valtype
if valtype == 'sub':
self.ebmltype = 'EBML_TYPE_SUBELEMENTS'
self.valname = 'struct ' + self.structname
else:
self.ebmltype = 'EBML_TYPE_' + valtype.upper()
try:
self.valname = {'uint': 'uint64_t', 'str': 'char *',
'binary': 'bstr', 'ebml_id': 'uint32_t',
'float': 'double', 'sint': 'int64_t',
}[valtype]
except KeyError:
raise SyntaxError('Unrecognized value type ' + valtype)
self.subelements = ()
def add_subelements(self, subelements):
self.subelements = subelements
self.subids = set(x[0].elid for x in subelements)
elementd = {}
elementlist = []
def parse_elems(l, namespace):
subelements = []
for el in l:
if isinstance(el, str):
name, hexid, eltype = [x.strip() for x in el.split(',')]
hexid = hexid.lower()
multiple = name.endswith('*')
name = name.strip('*')
new = MatroskaElement(name, hexid, eltype, namespace)
elementd[hexid] = new
elementlist.append(new)
subelements.append((new, multiple))
else:
new.add_subelements(parse_elems(el, namespace))
return subelements
parse_elems(elements_ebml, 'EBML')
parse_elems(elements_matroska, 'MATROSKA')
def printf(out, *args):
out.write(u' '.join([str(x) for x in args]))
out.write(u'\n')
def generate_C_header(out):
printf(out, '// Generated by TOOLS/matroska.py, do not edit manually')
printf(out)
for el in elementlist:
printf(out, '#define {0.definename:40} 0x{0.elid}'.format(el))
printf(out)
for el in reversed(elementlist):
if not el.subelements:
continue
printf(out)
printf(out, 'struct {0.structname} {{'.format(el))
l = max(len(subel.valname) for subel, multiple in el.subelements)+1
for subel, multiple in el.subelements:
printf(out, ' {e.valname:{l}} {star}{e.fieldname};'.format(
e=subel, l=l, star=' *'[multiple]))
printf(out)
for subel, multiple in el.subelements:
printf(out, ' int n_{0.fieldname};'.format(subel))
printf(out, '};')
for el in elementlist:
if not el.subelements:
continue
printf(out, 'extern const struct ebml_elem_desc {0.structname}_desc;'.format(el))
printf(out)
printf(out, '#define MAX_EBML_SUBELEMENTS', max(len(el.subelements)
for el in elementlist))
def generate_C_definitions(out):
printf(out, '// Generated by TOOLS/matroska.py, do not edit manually')
printf(out)
for el in reversed(elementlist):
printf(out)
if el.subelements:
printf(out, '#define N', el.fieldname)
printf(out, 'E_S("{0}", {1})'.format(el.name, len(el.subelements)))
for subel, multiple in el.subelements:
printf(out, 'F({0.definename}, {0.fieldname}, {1})'.format(
subel, int(multiple)))
printf(out, '}};')
printf(out, '#undef N')
else:
printf(out, 'E("{0.name}", {0.fieldname}, {0.ebmltype})'.format(el))
def read(s, length):
t = s.read(length)
if len(t) != length:
raise EOF
return t
def read_id(s):
t = read(s, 1)
i = 0
mask = 128
if ord(t) == 0:
raise SyntaxError
while not ord(t) & mask:
i += 1
mask >>= 1
t += read(s, i)
return t
def read_vint(s):
t = read(s, 1)
i = 0
mask = 128
if ord(t) == 0:
raise SyntaxError
while not ord(t) & mask:
i += 1
mask >>= 1
t = bytes((ord(t) & (mask - 1),))
t += read(s, i)
return i+1, byte2num(t)
def read_str(s, length):
return read(s, length)
def read_uint(s, length):
t = read(s, length)
return byte2num(t)
def read_sint(s, length):
i = read_uint(s, length)
mask = 1 << (length * 8 - 1)
if i & mask:
i -= 2 * mask
return i
def read_float(s, length):
t = read(s, length)
i = byte2num(t)
if length == 4:
f = ldexp((i & 0x7fffff) + (1 << 23), (i >> 23 & 0xff) - 150)
if i & (1 << 31):
f = -f
elif length == 8:
f = ldexp((i & ((1 << 52) - 1)) + (1 << 52), (i >> 52 & 0x7ff) - 1075)
if i & (1 << 63):
f = -f
else:
raise SyntaxError
return f
def parse_one(s, depth, parent, maxlen):
elid = hexlify(read_id(s)).decode('ascii')
elem = elementd.get(elid)
size, length = read_vint(s)
this_length = len(elid) / 2 + size + length
if elem is not None:
if elem.valtype != 'skip':
print(" " * depth, '[' + elid + ']', elem.name, 'size:', length, 'value:', end=' ')
if elem.valtype == 'sub':
print('subelements:')
while length > 0:
length -= parse_one(s, depth + 1, elem, length)
if length < 0:
raise SyntaxError
elif elem.valtype == 'str':
print('string', repr(read_str(s, length).decode('utf8', 'replace')))
elif elem.valtype in ('binary', 'ebml_id'):
t = read_str(s, length)
dec = ''
if elem.valtype == 'ebml_id':
idelem = elementd.get(hexlify(t).decode('ascii'))
if idelem is None:
dec = '(UNKNOWN)'
else:
dec = '({0.name})'.format(idelem)
if len(t) < 20:
t = hexlify(t).decode('ascii')
else:
t = '<{0} bytes>'.format(len(t))
print('binary', t, dec)
elif elem.valtype == 'uint':
print('uint', read_uint(s, length))
elif elem.valtype == 'sint':
print('sint', read_sint(s, length))
elif elem.valtype == 'float':
print('float', read_float(s, length))
elif elem.valtype == 'skip':
read(s, length)
else:
raise NotImplementedError
else:
print(" " * depth, '[' + elid + '] Unknown element! size:', length)
read(s, length)
return this_length
if __name__ == "__main__":
def parse_toplevel(s):
parse_one(s, 0, None, 1 << 63)
if sys.argv[1] == '--generate-header':
generate_C_header(sys.stdout)
elif sys.argv[1] == '--generate-definitions':
generate_C_definitions(sys.stdout)
else:
if sys.version_info.major < 3:
raise Exception("Dumping requires Python 3.")
s = open(sys.argv[1], "rb")
while 1:
start = s.tell()
try:
parse_toplevel(s)
except EOF:
if s.tell() != start:
raise Exception("Unexpected end of file")
break
@@ -1,6 +0,0 @@
StartChar: .notdef
Encoding: 65536 -1 0
Width: 400
Flags: W
LayerCount: 2
EndChar
-77
View File
@@ -1,77 +0,0 @@
SplineFontDB: 3.0
FontName: mpv-osd-symbols-Regular
FullName: mpv-osd-symbols Regular
FamilyName: mpv-osd-symbols
Weight: Normal
Copyright: This is generated file.
Version: 001.000
ItalicAngle: 0
UnderlinePosition: -133
UnderlineWidth: 50
Ascent: 800
Descent: 200
InvalidEm: 0
sfntRevision: 0x00010000
LayerCount: 2
Layer: 0 0 "Back" 1
Layer: 1 0 "Fore" 0
XUID: [1021 879 -1597228462 15927]
StyleMap: 0x0040
FSType: 8
OS2Version: 3
OS2_WeightWidthSlopeOnly: 0
OS2_UseTypoMetrics: 0
CreationTime: 1408646554
ModificationTime: 1492879730
PfmFamily: 81
TTFWeight: 400
TTFWidth: 5
LineGap: 0
VLineGap: 0
Panose: 0 0 5 0 0 0 0 0 0 0
OS2TypoAscent: 800
OS2TypoAOffset: 0
OS2TypoDescent: -200
OS2TypoDOffset: 0
OS2TypoLinegap: 90
OS2WinAscent: 1000
OS2WinAOffset: 0
OS2WinDescent: 200
OS2WinDOffset: 0
HheadAscent: 1000
HheadAOffset: 0
HheadDescent: -200
HheadDOffset: 0
OS2SubXSize: 650
OS2SubYSize: 600
OS2SubXOff: 0
OS2SubYOff: 75
OS2SupXSize: 650
OS2SupYSize: 600
OS2SupXOff: 0
OS2SupYOff: 350
OS2StrikeYSize: 50
OS2StrikeYPos: 220
OS2Vendor: 'PfEd'
OS2CodePages: 00000001.00000000
OS2UnicodeRanges: 00000000.00000000.00000000.00000000
DEI: 91125
LangName: 1033 "" "" "Regular" "1.000;PfEd;mpv-osd-symbols-Regular" "mpv-osd-symbols" "Version 1.000;PS 001.000;hotconv 1.0.70;makeotf.lib2.5.58329"
Encoding: UnicodeBmp
UnicodeInterp: none
NameList: AGL For New Fonts
DisplaySize: -72
AntiAlias: 1
FitToEm: 0
WinInfo: 57600 8 2
BeginPrivate: 8
BlueValues 31 [-10 0 640 650 720 730 800 810]
BlueScale 5 0.037
BlueShift 1 0
BlueFuzz 1 0
StdHW 4 [65]
StdVW 4 [65]
StemSnapH 8 [65 800]
StemSnapV 8 [65 150]
EndPrivate
EndSplineFont
-16
View File
@@ -1,16 +0,0 @@
StartChar: uniE001
Encoding: 57345 57345 1
Width: 880
GlyphClass: 2
Flags: MW
HStem: 780 20G<200 200>
VStem: 200 375<400 400 400 800>
LayerCount: 2
Fore
SplineSet
575 400 m 1
200 0 l 1
200 800 l 1
575 400 l 1
EndSplineSet
EndChar
-22
View File
@@ -1,22 +0,0 @@
StartChar: uniE002
Encoding: 57346 57346 2
Width: 880
GlyphClass: 2
Flags: MW
HStem: 0 800<200 350 200 350 200 500 500 650>
VStem: 200 150<0 800 0 800> 500 150<0 800 0 800>
LayerCount: 2
Fore
SplineSet
350 800 m 1
350 0 l 1
200 0 l 1
200 800 l 1
350 800 l 1
650 800 m 1
650 0 l 1
500 0 l 1
500 800 l 1
650 800 l 1
EndSplineSet
EndChar
-17
View File
@@ -1,17 +0,0 @@
StartChar: uniE003
Encoding: 57347 57347 3
Width: 880
GlyphClass: 2
Flags: MW
HStem: 0 720<110 775 110 775>
VStem: 110 665<0 720 0 720>
LayerCount: 2
Fore
SplineSet
775 720 m 1
775 0 l 1
110 0 l 1
110 720 l 1
775 720 l 1
EndSplineSet
EndChar
-20
View File
@@ -1,20 +0,0 @@
StartChar: uniE004
Encoding: 57348 57348 4
Width: 880
GlyphClass: 2
Flags: MW
HStem: 780 20G<423 423 813 813>
VStem: 48 765<400 400>
LayerCount: 2
Fore
SplineSet
423 800 m 1
423 0 l 1
48 400 l 1
423 800 l 1
813 800 m 1
813 0 l 1
438 400 l 1
813 800 l 1
EndSplineSet
EndChar
-20
View File
@@ -1,20 +0,0 @@
StartChar: uniE005
Encoding: 57349 57349 5
Width: 880
GlyphClass: 2
Flags: MW
HStem: 780 20G<95 95 485 485>
VStem: 95 765<400 400 400 800 400 800>
LayerCount: 2
Fore
SplineSet
470 400 m 1
95 0 l 1
95 800 l 1
470 400 l 1
860 400 m 1
485 0 l 1
485 800 l 1
860 400 l 1
EndSplineSet
EndChar
-47
View File
@@ -1,47 +0,0 @@
StartChar: uniE006
Encoding: 57350 57350 6
Width: 880
GlyphClass: 2
Flags: MW
HStem: -10 11<396 461 396 543> 196 171<397 461 396 462> 401 31 801 9<397 462 397 397>
VStem: 20 9<369 434 369 513> 224 173<369 408 367 434 367 434> 363 34 397 65<367 404 367 408 367 404 606 801> 462 173<368 404 404 404> 830 10<368 433 433 433>
LayerCount: 2
Fore
SplineSet
430 810 m 0x9940
656 810 840 626 840 400 c 0
840 174 656 -10 430 -10 c 0
204 -10 20 174 20 400 c 0
20 626 204 810 430 810 c 0x9940
397 606 m 1x5280
462 606 l 1
462 801 l 1
397 801 l 1
397 606 l 1x5280
462 367 m 1
462 404 l 1
710 627 l 1
683 657 l 1
439 437 l 1
363 592 l 1
318 570 l 1x4280
397 408 l 1
397 367 l 1x44
462 367 l 1
224 434 m 1
29 434 l 1
29 369 l 1
224 369 l 1
224 434 l 1
830 368 m 1
830 433 l 1
635 433 l 1
635 368 l 1
830 368 l 1
461 196 m 1
396 196 l 1
396 1 l 1
461 1 l 1
461 196 l 1
EndSplineSet
EndChar
-21
View File
@@ -1,21 +0,0 @@
StartChar: uniE007
Encoding: 57351 57351 7
Width: 880
GlyphClass: 2
Flags: MW
HStem: -10 80<339 430 339 543> 730 80<339 430>
VStem: 20 80<309 491 309 513>
LayerCount: 2
Fore
SplineSet
430 -10 m 0
204 -10 20 174 20 400 c 0
20 626 204 810 430 810 c 0
656 810 840 626 840 400 c 0
840 174 656 -10 430 -10 c 0
430 70 m 1
430 730 l 1
248 730 100 582 100 400 c 0
100 218 248 70 430 70 c 1
EndSplineSet
EndChar
-37
View File
@@ -1,37 +0,0 @@
StartChar: uniE008
Encoding: 57352 57352 8
Width: 880
GlyphClass: 2
Flags: MW
HStem: -10 80<339 521 339 543> 240 160<269 313 546 590> 480 160<408 452> 730 80<339 521>
VStem: 20 80<309 491 309 513> 211 160<298 342> 350 160<538 582> 488 160<298 342> 760 80<309 491>
LayerCount: 2
Fore
SplineSet
430 -10 m 0xfa80
204 -10 20 174 20 400 c 0
20 626 204 810 430 810 c 0
656 810 840 626 840 400 c 0
840 174 656 -10 430 -10 c 0xfa80
430 70 m 0
612 70 760 218 760 400 c 0
760 582 612 730 430 730 c 0
248 730 100 582 100 400 c 0
100 218 248 70 430 70 c 0
430 480 m 0
386 480 350 516 350 560 c 0
350 604 386 640 430 640 c 0
474 640 510 604 510 560 c 0
510 516 474 480 430 480 c 0
291 240 m 0xfd80
247 240 211 276 211 320 c 0
211 364 247 400 291 400 c 0
335 400 371 364 371 320 c 0
371 276 335 240 291 240 c 0xfd80
568 240 m 0
524 240 488 276 488 320 c 0
488 364 524 400 568 400 c 0
612 400 648 364 648 320 c 0
648 276 612 240 568 240 c 0
EndSplineSet
EndChar
-17
View File
@@ -1,17 +0,0 @@
StartChar: uniE009
Encoding: 57353 57353 9
Width: 880
Flags: HMW
LayerCount: 2
Fore
SplineSet
716 10 m 1
378 244 l 1
165 244 l 1
165 559 l 1
379 559 l 1
716 793 l 1
716 10 l 1
EndSplineSet
Validated: 1
EndChar
-50
View File
@@ -1,50 +0,0 @@
StartChar: uniE00A
Encoding: 57354 57354 10
Width: 880
GlyphClass: 2
Flags: MW
HStem: 252 48<406 406 456 456> 375 50<57 282 57 282 578 805> 500 48<406 406> 627 20G<149 149 713 713>
VStem: 282 48<375 375 425 425> 406 50<26 252 26 252 548 774> 530 48<375 375>
LayerCount: 2
Fore
SplineSet
805 375 m 1
578 375 l 1
574 352 565 331 553 313 c 1
713 153 l 1
678 118 l 1
518 278 l 1
500 265 479 256 456 252 c 1
456 26 l 1
406 26 l 1
406 252 l 1
383 256 362 265 343 277 c 1
184 118 l 1
149 153 l 1
308 312 l 1
295 330 286 352 282 375 c 1
57 375 l 1
57 425 l 1
282 425 l 1
286 448 295 470 308 488 c 1
149 647 l 1
184 682 l 1
343 523 l 1
362 535 383 544 406 548 c 1
406 774 l 1
456 774 l 1
456 548 l 1
479 544 500 535 518 522 c 1
678 682 l 1
713 647 l 1
553 487 l 1
565 469 574 448 578 425 c 1
805 425 l 1
805 375 l 1
430 300 m 0
485 300 530 345 530 400 c 0
530 455 485 500 430 500 c 0
375 500 330 455 330 400 c 0
330 345 375 300 430 300 c 0
EndSplineSet
EndChar
-27
View File
@@ -1,27 +0,0 @@
StartChar: uniE00B
Encoding: 57355 57355 11
Width: 880
GlyphClass: 2
Flags: MW
HStem: -10 244<341 519 341 543> 566 54<413.5 446.5 413.5 519> 740 70<413.5 446.5>
VStem: 20 88<354 446 354 513> 752 88<354 446>
LayerCount: 2
Fore
SplineSet
430 -10 m 0
204 -10 20 174 20 400 c 0
20 626 204 810 430 810 c 0
656 810 840 626 840 400 c 0
840 174 656 -10 430 -10 c 0
430 620 m 0
463 620 490 647 490 680 c 0
490 713 463 740 430 740 c 0
397 740 370 713 370 680 c 0
370 647 397 620 430 620 c 0
430 234 m 0
608 234 752 308 752 400 c 0
752 492 608 566 430 566 c 0
252 566 108 492 108 400 c 0
108 308 252 234 430 234 c 0
EndSplineSet
EndChar
-21
View File
@@ -1,21 +0,0 @@
StartChar: uniE010
Encoding: 57360 57360 12
Width: 334
GlyphClass: 2
Flags: MW
HStem: 0 90<221 258 221 258> 550 90<221 258 221 221>
VStem: 76 145<90 550 90 640 90 640>
LayerCount: 2
Fore
SplineSet
258 640 m 1
258 550 l 1
221 550 l 1
221 90 l 1
258 90 l 1
258 0 l 1
76 0 l 1
76 640 l 1
258 640 l 1
EndSplineSet
EndChar
-17
View File
@@ -1,17 +0,0 @@
StartChar: uniE011
Encoding: 57361 57361 13
Width: 334
GlyphClass: 2
Flags: MW
HStem: 0 640<84 250 84 250>
VStem: 84 166<0 640 0 640>
LayerCount: 2
Fore
SplineSet
250 640 m 1
250 0 l 1
84 0 l 1
84 640 l 1
250 640 l 1
EndSplineSet
EndChar
-21
View File
@@ -1,21 +0,0 @@
StartChar: uniE012
Encoding: 57362 57362 14
Width: 334
GlyphClass: 2
Flags: MW
HStem: 0 90<76 113 76 258 76 113> 550 90<76 113 76 258>
VStem: 113 145<90 550 550 550>
LayerCount: 2
Fore
SplineSet
113 90 m 1
113 550 l 1
76 550 l 1
76 640 l 1
258 640 l 1
258 0 l 1
76 0 l 1
76 90 l 1
113 90 l 1
EndSplineSet
EndChar
-17
View File
@@ -1,17 +0,0 @@
StartChar: uniE013
Encoding: 57363 57363 15
Width: 334
GlyphClass: 2
Flags: MW
HStem: 255 130<102 232 102 232>
VStem: 102 130<255 385 255 385>
LayerCount: 2
Fore
SplineSet
232 385 m 1
232 255 l 1
102 255 l 1
102 385 l 1
232 385 l 1
EndSplineSet
EndChar
-16
View File
@@ -1,16 +0,0 @@
StartChar: uniE101
Encoding: 57601 57601 16
Width: 880
GlyphClass: 2
Flags: MW
HStem: 780 20G<222 222>
VStem: 222 600<400 400 400 800 400 800>
LayerCount: 2
Fore
SplineSet
822 400 m 1
222 0 l 1
222 800 l 1
822 400 l 1
EndSplineSet
EndChar
-25
View File
@@ -1,25 +0,0 @@
StartChar: uniE104
Encoding: 57604 57604 17
Width: 880
GlyphClass: 2
Flags: MW
HStem: 0 800<3 126 3 126 3 502 3 878> 780 20G<3 126 126 126 502 502 878 878>
VStem: 3 123<0 800 0 800>
LayerCount: 2
Fore
SplineSet
126 800 m 1x60
126 0 l 1
3 0 l 1xa0
3 800 l 1
126 800 l 1x60
502 800 m 1
502 0 l 1
127 400 l 1
502 800 l 1
878 800 m 1
878 0 l 1
503 400 l 1
878 800 l 1
EndSplineSet
EndChar
-25
View File
@@ -1,25 +0,0 @@
StartChar: uniE105
Encoding: 57605 57605 18
Width: 880
GlyphClass: 2
Flags: MW
HStem: 0 800<3 3 3 379 3 755 755 878> 780 20G<3 3 379 379 755 878 878 878>
VStem: 755 123<0 800>
LayerCount: 2
Fore
SplineSet
3 0 m 1x60
3 800 l 1
378 400 l 1
3 0 l 1x60
379 0 m 1xa0
379 800 l 1
754 400 l 1
379 0 l 1xa0
878 0 m 1
755 0 l 1
755 800 l 1
878 800 l 1
878 0 l 1
EndSplineSet
EndChar
-22
View File
@@ -1,22 +0,0 @@
StartChar: uniE106
Encoding: 57606 57606 19
Width: 880
GlyphClass: 2
Flags: MW
HStem: 0 649<68.5 556.5>
VStem: 0 880
LayerCount: 2
Fore
SplineSet
880 380 m 0
880 230 685 101 449 101 c 0
390 101 336 107 283 118 c 1
278 49 189 0 85 0 c 0
52 0 24 14 0 40 c 1
82 48 137 93 137 158 c 0
137 163 137 168 135 172 c 0
58 217 19 273 19 380 c 0
19 528 258 649 449 649 c 0
664 649 880 508 880 380 c 0
EndSplineSet
EndChar
-56
View File
@@ -1,56 +0,0 @@
StartChar: uniE107
Encoding: 57607 57607 20
Width: 880
GlyphClass: 2
Flags: MW
HStem: 0 60<0 60 60 820> 106 50<146 343 146 343 146 390 390 641 680 735> 207 50<99 317 99 317 99 363 363 488 529 781> 580 60<60 820 60 820>
VStem: 0 60<60 580> 99 218<207 257 207 257> 146 197<106 156 106 156> 363 125<207 257 207 257> 529 112<106 257 106 257> 680 55<106 156 106 156> 820 60<0 60 60 580>
LayerCount: 2
Fore
SplineSet
0 60 m 2xfde0
0 580 l 2
0 610 30 640 60 640 c 2
820 640 l 2
850 640 880 610 880 580 c 2
880 60 l 2
880 30 850 0 820 0 c 2
60 0 l 2
30 0 0 30 0 60 c 2xfde0
60 60 m 1
820 60 l 1
820 580 l 1
60 580 l 1
60 60 l 1
317 257 m 1
317 207 l 1
99 207 l 1
99 257 l 1
317 257 l 1
488 257 m 1
488 207 l 1
363 207 l 1
363 257 l 1
488 257 l 1
781 257 m 1
781 207 l 1
529 207 l 1
529 257 l 1
781 257 l 1
343 156 m 1x4280
343 106 l 1
146 106 l 1
146 156 l 1
343 156 l 1x4280
641 156 m 1
641 106 l 1
390 106 l 1
390 156 l 1x41c0
641 156 l 1
735 156 m 1
735 106 l 1
680 106 l 1
680 156 l 1
735 156 l 1
EndSplineSet
EndChar
-39
View File
@@ -1,39 +0,0 @@
StartChar: uniE108
Encoding: 57608 57608 21
Width: 880
GlyphClass: 2
Flags: MW
HStem: 80 60<0 60 60 820> 321 159<274 606 274 606> 660 60<60 820 60 820>
VStem: 0 60<140 660> 274 332<321 480 321 480> 820 60<80 140 140 660>
LayerCount: 2
Fore
SplineSet
0 140 m 2
0 660 l 2
0 690 30 720 60 720 c 2
820 720 l 2
850 720 880 690 880 660 c 2
880 140 l 2
880 110 850 80 820 80 c 2
60 80 l 2
30 80 0 110 0 140 c 2
60 140 m 1
820 140 l 1
820 660 l 1
60 660 l 1
60 140 l 1
580 600 m 1
760 600 l 1
760 420 l 1
580 600 l 1
606 480 m 1
606 321 l 1
274 321 l 1
274 480 l 1
606 480 l 1
300 200 m 1
120 200 l 1
120 380 l 1
300 200 l 1
EndSplineSet
EndChar
-39
View File
@@ -1,39 +0,0 @@
StartChar: uniE109
Encoding: 57609 57609 22
Width: 880
GlyphClass: 2
Flags: MW
HStem: 80 60<0 60 60 820> 296 209<285 595 285 595> 660 60<60 820 60 820>
VStem: 0 60<140 660> 120 107<400 400 400 510> 285 310<296 505 296 505> 653 107<400 400> 820 60<80 140 140 660>
LayerCount: 2
Fore
SplineSet
0 140 m 2
0 660 l 2
0 690 30 720 60 720 c 2
820 720 l 2
850 720 880 690 880 660 c 2
880 140 l 2
880 110 850 80 820 80 c 2
60 80 l 2
30 80 0 110 0 140 c 2
60 140 m 1
820 140 l 1
820 660 l 1
60 660 l 1
60 140 l 1
227 400 m 1
120 290 l 1
120 510 l 1
227 400 l 1
760 290 m 1
653 400 l 1
760 510 l 1
760 290 l 1
595 505 m 1
595 296 l 1
285 296 l 1
285 505 l 1
595 505 l 1
EndSplineSet
EndChar
-36
View File
@@ -1,36 +0,0 @@
StartChar: uniE10A
Encoding: 57610 57610 23
Width: 1977
GlyphClass: 2
Flags: HMWO
HStem: 242 248<2 155 2 156>
LayerCount: 2
Fore
SplineSet
398 58 m 1
155 242 l 1
2 242 l 1
2 490 l 1
156 490 l 1
398 674 l 1
398 58 l 1
809 524 m 0
814 524 819 523 823 519 c 0
831 511 831 499 823 491 c 2
697 365 l 1
823 239 l 2
830 232 830 221 823 213 c 0
816 206 804 206 797 213 c 2
671 339 l 1
545 213 l 2
538 206 525 206 518 213 c 0
510 221 510 233 518 241 c 2
643 367 l 1
517 493 l 2
510 500 510 511 517 519 c 0
525 526 536 526 544 519 c 2
670 393 l 1
796 519 l 2
799 523 804 524 809 524 c 0
EndSplineSet
EndChar
-26
View File
@@ -1,26 +0,0 @@
StartChar: uniE10B
Encoding: 57611 57611 24
Width: 1977
GlyphClass: 2
Flags: MW
HStem: 242 248<2 155 2 156>
VStem: 603 47<326.5 405>
LayerCount: 2
Fore
SplineSet
650 366 m 0
650 281 615 198 545 119 c 1
507 142 l 1
571 213 603 287 603 366 c 0
603 444 571 518 507 590 c 1
545 613 l 1
615 534 650 452 650 366 c 0
398 58 m 1
155 242 l 1
2 242 l 1
2 490 l 1
156 490 l 1
398 674 l 1
398 58 l 1
EndSplineSet
EndChar
-33
View File
@@ -1,33 +0,0 @@
StartChar: uniE10C
Encoding: 57612 57612 25
Width: 1977
GlyphClass: 2
Flags: MW
HStem: 242 248<2 155 2 156>
VStem: 603 47<326.5 405> 717 47<316.5 416>
LayerCount: 2
Fore
SplineSet
764 366 m 0
764 258 720 156 631 61 c 1
593 84 l 1
675 173 717 267 717 366 c 0
717 466 675 559 593 647 c 1
631 671 l 1
720 578 764 476 764 366 c 0
650 366 m 0
650 281 615 198 545 119 c 1
507 142 l 1
571 213 603 287 603 366 c 0
603 444 571 518 507 590 c 1
545 613 l 1
615 534 650 452 650 366 c 0
398 58 m 1
155 242 l 1
2 242 l 1
2 490 l 1
156 490 l 1
398 674 l 1
398 58 l 1
EndSplineSet
EndChar
-40
View File
@@ -1,40 +0,0 @@
StartChar: uniE10D
Encoding: 57613 57613 26
Width: 1977
GlyphClass: 2
Flags: MW
HStem: 242 248<2 155 2 156> 709 20G<717 717>
VStem: 603 47<326.5 405> 717 47<316.5 416> 830 47<304 426.5>
LayerCount: 2
Fore
SplineSet
877 366 m 0
877 236 824 115 717 3 c 1
679 27 l 1
780 130 830 242 830 366 c 0
830 487 780 600 679 705 c 1
717 729 l 1
824 617 877 496 877 366 c 0
764 366 m 0
764 258 720 156 631 61 c 1
593 84 l 1
675 173 717 267 717 366 c 0
717 466 675 559 593 647 c 1
631 671 l 1
720 578 764 476 764 366 c 0
650 366 m 0
650 281 615 198 545 119 c 1
507 142 l 1
571 213 603 287 603 366 c 0
603 444 571 518 507 590 c 1
545 613 l 1
615 534 650 452 650 366 c 0
398 58 m 1
155 242 l 1
2 242 l 1
2 490 l 1
156 490 l 1
398 674 l 1
398 58 l 1
EndSplineSet
EndChar
-53
View File
@@ -1,53 +0,0 @@
StartChar: uniE10E
Encoding: 57614 57614 27
Width: 1977
GlyphClass: 2
Flags: MW
HStem: 49 95<806 818.5> 242 248<2 155 2 156>
VStem: 559 47<326.5 405> 673 47<316.5 416> 767 91<90 103.5 648 652>
LayerCount: 2
Fore
SplineSet
720 366 m 0
720 258 676 156 587 61 c 1
549 84 l 1
631 173 673 267 673 366 c 0
673 466 631 559 549 647 c 1
587 671 l 1
676 578 720 476 720 366 c 0
606 366 m 0
606 281 571 198 501 119 c 1
463 142 l 1
527 213 559 287 559 366 c 0
559 444 527 518 463 590 c 1
501 613 l 1
571 534 606 452 606 366 c 0
398 58 m 1
155 242 l 1
2 242 l 1
2 490 l 1
156 490 l 1
398 674 l 1
398 58 l 1
858 648 m 1
824 238 l 2
823 224 819 217 812 217 c 0
805 217 801 224 800 238 c 2
767 648 l 1
767 652 l 2
767 665 771 675 780 682 c 0
789 690 800 694 812 694 c 0
825 694 835 690 844 682 c 0
853 675 858 665 858 652 c 2
858 648 l 1
858 97 m 0
858 83 853 72 845 63 c 0
836 53 825 49 812 49 c 0
800 49 789 53 780 63 c 0
771 72 767 83 767 97 c 0
767 110 771 121 780 130 c 0
789 140 800 144 812 144 c 0
825 144 836 140 845 130 c 0
853 121 858 110 858 97 c 0
EndSplineSet
EndChar
-16
View File
@@ -1,16 +0,0 @@
StartChar: uniE110
Encoding: 57616 57616 28
Width: 880
GlyphClass: 2
Flags: MW
HStem: 780 20G<656 656>
VStem: 56 600<400 400>
LayerCount: 2
Fore
SplineSet
656 0 m 1
56 400 l 1
656 800 l 1
656 0 l 1
EndSplineSet
EndChar
-37
View File
@@ -1,37 +0,0 @@
StartChar: uniE111
Encoding: 57617 57617 29
Width: 880
GlyphClass: 2
Flags: W
LayerCount: 2
Fore
SplineSet
0 140 m 2
0 660 l 2
0 690 30 720 60 720 c 2
820 720 l 2
850 720 880 690 880 660 c 2
880 140 l 2
880 110 850 80 820 80 c 2
60 80 l 2
30 80 0 110 0 140 c 2
60 140 m 1
820 140 l 1
820 660 l 1
60 660 l 1
60 140 l 1
227 400 m 1
120 290 l 1
120 510 l 1
227 400 l 1
760 290 m 1
653 400 l 1
760 510 l 1
760 290 l 1
595 505 m 1
595 296 l 1
285 296 l 1
285 505 l 1
595 505 l 1
EndSplineSet
EndChar
+3 -2
View File
@@ -67,12 +67,13 @@ EOF
chapters
editions
titles
duration
audio
audio-bitrate
audio-codec
audio-codec-name
audio-format
channels
samplerate
video
angle
+1 -1
View File
@@ -173,7 +173,7 @@
</dict>
</array>
<key>CFBundleExecutable</key>
<string>mpv-wrapper.sh</string>
<string>mpv</string>
<key>CFBundleIconFile</key>
<string>icon</string>
<key>CFBundleIdentifier</key>
@@ -1,3 +0,0 @@
#!/bin/bash
export MPVBUNDLE="true"
$SHELL -l -c "$(dirname "$0")/mpv --player-operation-mode=pseudo-gui"
@@ -0,0 +1 @@
profile=pseudo-gui
+5 -6
View File
@@ -151,16 +151,15 @@ for cur in ax:
cur.addLegend(offset = (-1, 1))
for e in G.sevents:
cur = ax[1 if e.type == "value" else 0]
if not cur in G.curveno:
G.curveno[cur] = 0
args = {'name': e.name,'antialias':True}
color = mkColor(colors[G.curveno[cur] % len(colors)])
if e.type == "event-signal":
args['symbol'] = e.marker
args['symbolBrush'] = pg.mkBrush(color, width=0)
args['pen'] = None
else:
args['pen'] = pg.mkPen(color, width=0)
G.curveno[cur] += 1
if not cur in G.curveno:
G.curveno[cur] = 0
args['pen'] = pg.mkPen(mkColor(colors[G.curveno[cur] % len(colors)]), width=0)
G.curveno[cur] += 1
n = cur.plot([x for x,y in e.vals], [y for x,y in e.vals], **args)
QtGui.QApplication.instance().exec_()
+3 -3
View File
@@ -89,7 +89,7 @@ class Libav < TravisDepsBuilder
{
"libav-stable" => {
:action => :stable,
:url => 'http://libav.org/releases/libav-12.tar.gz'
:url => 'http://libav.org/releases/libav-11.tar.gz'
},
"libav-git" => {
:action => :git,
@@ -97,7 +97,7 @@ class Libav < TravisDepsBuilder
},
"ffmpeg-stable" => {
:action => :stable,
:url => 'http://www.ffmpeg.org/releases/ffmpeg-3.2.2.tar.gz'
:url => 'http://www.ffmpeg.org/releases/ffmpeg-2.4.tar.gz'
},
"ffmpeg-git" => {
:action => :git,
@@ -107,7 +107,7 @@ class Libav < TravisDepsBuilder
end
def configure
[super, "--cc=#{ENV['CC']} --disable-asm"].join(" ")
[super, "--cc=#{ENV['CC']}"].join(" ")
end
end
-29
View File
@@ -1,29 +0,0 @@
#!/bin/sh
if [ "x$LIBAV" != "xffmpeg-git" ] || [ "x$TRAVIS_OS_NAME" != "xlinux" ]; then
# trigger build only on one of the matrix nodes
exit;
fi
if [ "x$TRAVIS_BRANCH" != "xmaster" ]; then
# only rebuild website with pushes to master
exit;
fi
TRAVIS_COMMIT_RANGE=${TRAVIS_COMMIT_RANGE:-HEAD^..}
if git diff --quiet --name-only --exit-code "$TRAVIS_COMMIT_RANGE" DOCS/; then
exit;
fi
body='{
"request": {
"branch":"master"
}}'
curl -s -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Travis-API-Version: 3" \
-H "Authorization: token $WEBSITE_TRAVIS_TOKEN" \
-d "$body" \
https://api.travis-ci.org/repo/mpv-player%2Fmpv.io/requests
+2 -7
View File
@@ -4,14 +4,11 @@
use strict;
use warnings;
use warnings FATAL => 'uninitialized';
my $mpv = $ARGV[0] || 'mpv';
my @opts = parse_main_opts('--list-options', '^ (\-\-[^\s\*]*)\*?\s*(.*)');
die "Couldn't find any options" unless (@opts);
my @ao = parse_opts('--ao=help', '^ ([^\s\:]*)\s*: (.*)');
my @vo = parse_opts('--vo=help', '^ ([^\s\:]*)\s*: (.*)');
@@ -96,9 +93,6 @@ my $tmpl = <<"EOS";
local curcontext="\$curcontext" state state_descr line
typeset -A opt_args
local -a match mbegin mend
local MATCH MBEGIN MEND
# By default, don't complete URLs unless no files match
local -a tag_order
zstyle -a ":completion:*:*:\$service:*" tag-order tag_order || \
@@ -147,7 +141,8 @@ $runtime_completions
local expl
_tags files urls
while _tags; do
_requested files expl 'media file' _files && rc=0
_requested files expl 'media file' _files -g \\
"*.(#i)(asf|asx|avi|f4v|flac|flv|m1v|m2p|m2v|m4v|mjpg|mka|mkv|mov|mp3|mp4|mpe|mpeg|mpg|ogg|ogm|ogv|opus|qt|rm|ts|vob|wav|webm|wma|wmv|wv)(-.)" && rc=0
if _requested urls; then
while _next_label urls expl URL; do
_urls "\$expl[@]" && rc=0
+1 -1
View File
@@ -1 +1 @@
0.25.0
0.18.1
+11 -34
View File
@@ -138,9 +138,6 @@ static void mp_audio_destructor(void *ptr)
* available on every plane. The previous data is kept (for the smallest
* common number of samples before/after resize).
*
* This also makes sure the resulting buffer is writable (even in the case
* the buffer has the correct size).
*
* mpa->samples is not set or used.
*
* This function is flexible enough to handle format and channel layout
@@ -156,12 +153,6 @@ void mp_audio_realloc(struct mp_audio *mpa, int samples)
int size = get_plane_size(mpa, samples);
if (size < 0)
abort(); // oom or invalid parameters
if (!mp_audio_is_writeable(mpa)) {
for (int n = 0; n < MP_NUM_CHANNELS; n++) {
av_buffer_unref(&mpa->allocated[n]);
mpa->planes[n] = NULL;
}
}
for (int n = 0; n < mpa->num_planes; n++) {
if (!mpa->allocated[n] || size != mpa->allocated[n]->size) {
if (av_buffer_realloc(&mpa->allocated[n], size) < 0)
@@ -180,7 +171,7 @@ void mp_audio_realloc(struct mp_audio *mpa, int samples)
// If the buffer is reallocated, also preallocate.
void mp_audio_realloc_min(struct mp_audio *mpa, int samples)
{
if (samples > mp_audio_get_allocated_size(mpa) || !mp_audio_is_writeable(mpa)) {
if (samples > mp_audio_get_allocated_size(mpa)) {
size_t alloc = ta_calc_prealloc_elems(samples);
if (alloc > INT_MAX)
abort(); // oom
@@ -356,9 +347,9 @@ struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe)
mp_chmap_from_lavc(&lavc_chmap, avframe->channel_layout);
#if LIBAVUTIL_VERSION_MICRO >= 100
// FFmpeg being stupid POS again
if (lavc_chmap.num != av_frame_get_channels(avframe))
mp_chmap_from_channels(&lavc_chmap, av_frame_get_channels(avframe));
// FFmpeg being special again
if (lavc_chmap.num != avframe->channels)
mp_chmap_from_channels(&lavc_chmap, avframe->channels);
#endif
new->rate = avframe->sample_rate;
@@ -403,9 +394,12 @@ fail:
return NULL;
}
int mp_audio_to_avframe(struct mp_audio *frame, struct AVFrame *avframe)
// Returns NULL on failure. The input is always unreffed.
struct AVFrame *mp_audio_to_avframe_and_unref(struct mp_audio *frame)
{
av_frame_unref(avframe);
struct AVFrame *avframe = av_frame_alloc();
if (!avframe)
goto fail;
avframe->nb_samples = frame->samples;
avframe->format = af_to_avformat(frame->format);
@@ -416,8 +410,8 @@ int mp_audio_to_avframe(struct mp_audio *frame, struct AVFrame *avframe)
if (!avframe->channel_layout)
goto fail;
#if LIBAVUTIL_VERSION_MICRO >= 100
// FFmpeg being a stupid POS again
av_frame_set_channels(avframe, frame->channels.num);
// FFmpeg being a stupid POS (but I respect it)
avframe->channels = frame->channels.num;
#endif
avframe->sample_rate = frame->rate;
@@ -463,23 +457,6 @@ int mp_audio_to_avframe(struct mp_audio *frame, struct AVFrame *avframe)
avframe = tmp;
}
return 0;
fail:
av_frame_unref(avframe);
return -1;
}
// Returns NULL on failure. The input is always unreffed.
struct AVFrame *mp_audio_to_avframe_and_unref(struct mp_audio *frame)
{
struct AVFrame *avframe = av_frame_alloc();
if (!avframe)
goto fail;
if (mp_audio_to_avframe(frame, avframe) < 0)
goto fail;
talloc_free(frame);
return avframe;
-1
View File
@@ -81,7 +81,6 @@ int mp_audio_make_writeable(struct mp_audio *data);
struct AVFrame;
struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe);
struct AVFrame *mp_audio_to_avframe_and_unref(struct mp_audio *frame);
int mp_audio_to_avframe(struct mp_audio *frame, struct AVFrame *avframe);
struct mp_audio_pool;
struct mp_audio_pool *mp_audio_pool_create(void *ta_parent);
+38
View File
@@ -230,6 +230,44 @@ void mp_chmap_set_unknown(struct mp_chmap *dst, int num_channels)
}
}
// Return channel index of the given speaker, or -1.
static int mp_chmap_find_speaker(const struct mp_chmap *map, int speaker)
{
for (int n = 0; n < map->num; n++) {
if (map->speaker[n] == speaker)
return n;
}
return -1;
}
static void mp_chmap_remove_speaker(struct mp_chmap *map, int speaker)
{
int index = mp_chmap_find_speaker(map, speaker);
if (index >= 0) {
for (int n = index; n < map->num - 1; n++)
map->speaker[n] = map->speaker[n + 1];
map->num--;
}
}
// Some decoders output additional, redundant channels, which are usually
// useless and will mess up proper audio output channel handling.
// map: channel map from which the channels should be removed
// requested: if not NULL, and if it contains any of the "useless" channels,
// don't remove them (this is for convenience)
void mp_chmap_remove_useless_channels(struct mp_chmap *map,
const struct mp_chmap *requested)
{
if (requested &&
mp_chmap_find_speaker(requested, MP_SPEAKER_ID_DL) >= 0)
return;
if (map->num > 2) {
mp_chmap_remove_speaker(map, MP_SPEAKER_ID_DL);
mp_chmap_remove_speaker(map, MP_SPEAKER_ID_DR);
}
}
// Return the ffmpeg/libav channel layout as in <libavutil/channel_layout.h>.
// Speakers not representable by ffmpeg/libav are dropped.
// Warning: this ignores the order of the channels, and will return a channel
+3
View File
@@ -109,6 +109,9 @@ void mp_chmap_fill_na(struct mp_chmap *map, int num);
void mp_chmap_from_channels(struct mp_chmap *dst, int num_channels);
void mp_chmap_set_unknown(struct mp_chmap *dst, int num_channels);
void mp_chmap_remove_useless_channels(struct mp_chmap *map,
const struct mp_chmap *requested);
uint64_t mp_chmap_to_lavc(const struct mp_chmap *src);
uint64_t mp_chmap_to_lavc_unchecked(const struct mp_chmap *src);
void mp_chmap_from_lavc(struct mp_chmap *dst, uint64_t src);
-13
View File
@@ -374,16 +374,3 @@ void mp_chmal_sel_log(const struct mp_chmap_sel *s, struct mp_log *log, int lev)
if (s->allow_any)
mp_msg(log, lev, " - anything\n");
}
// Select a channel map from the given list that fits best to c. Don't change
// *c if there's no match, or the list is empty.
void mp_chmap_sel_list(struct mp_chmap *c, struct mp_chmap *maps, int num_maps)
{
// This is a separate function to keep messing with mp_chmap_sel internals
// within this source file.
struct mp_chmap_sel sel = {
.chmaps = maps,
.num_chmaps = num_maps,
};
mp_chmap_sel_fallback(&sel, c);
}
-2
View File
@@ -47,6 +47,4 @@ bool mp_chmap_sel_get_def(const struct mp_chmap_sel *s, struct mp_chmap *map,
struct mp_log;
void mp_chmal_sel_log(const struct mp_chmap_sel *s, struct mp_log *log, int lev);
void mp_chmap_sel_list(struct mp_chmap *c, struct mp_chmap *maps, int num_maps);
#endif
+2 -5
View File
@@ -35,11 +35,8 @@ struct ad_functions {
int (*init)(struct dec_audio *da, const char *decoder);
void (*uninit)(struct dec_audio *da);
int (*control)(struct dec_audio *da, int cmd, void *arg);
// Return whether or not the packet has been consumed.
bool (*send_packet)(struct dec_audio *da, struct demux_packet *pkt);
// Return whether decoding is still going on (false if EOF was reached).
// Never returns false & *out set, but can return true with !*out.
bool (*receive_frame)(struct dec_audio *da, struct mp_audio **out);
int (*decode_packet)(struct dec_audio *da, struct demux_packet *pkt,
struct mp_audio **out);
};
enum ad_ctrl {
+69 -50
View File
@@ -45,6 +45,7 @@ struct priv {
uint32_t skip_samples, trim_samples;
bool preroll_done;
double next_pts;
bool needs_reset;
AVRational codec_timebase;
};
@@ -85,7 +86,7 @@ static int init(struct dec_audio *da, const char *decoder)
struct priv *ctx = talloc_zero(NULL, struct priv);
da->priv = ctx;
ctx->codec_timebase = mp_get_codec_timebase(da->codec);
ctx->codec_timebase = (AVRational){0};
ctx->force_channel_map = c->force_channels;
@@ -99,34 +100,39 @@ static int init(struct dec_audio *da, const char *decoder)
lavc_context = avcodec_alloc_context3(lavc_codec);
ctx->avctx = lavc_context;
ctx->avframe = av_frame_alloc();
lavc_context->refcounted_frames = 1;
lavc_context->codec_type = AVMEDIA_TYPE_AUDIO;
lavc_context->codec_id = lavc_codec->id;
#if LIBAVCODEC_VERSION_MICRO >= 100
lavc_context->pkt_timebase = ctx->codec_timebase;
#endif
if (opts->downmix && mpopts->audio_output_channels.num_chmaps == 1) {
if (opts->downmix) {
lavc_context->request_channel_layout =
mp_chmap_to_lavc(&mpopts->audio_output_channels.chmaps[0]);
mp_chmap_to_lavc(&mpopts->audio_output_channels);
}
// Always try to set - option only exists for AC3 at the moment
av_opt_set_double(lavc_context, "drc_scale", opts->ac3drc,
AV_OPT_SEARCH_CHILDREN);
#if LIBAVCODEC_VERSION_MICRO >= 100
#if HAVE_AVFRAME_SKIP_SAMPLES
// Let decoder add AV_FRAME_DATA_SKIP_SAMPLES.
av_opt_set(lavc_context, "flags2", "+skip_manual", AV_OPT_SEARCH_CHILDREN);
#endif
mp_set_avopts(da->log, lavc_context, opts->avopts);
if (mp_set_avctx_codec_headers(lavc_context, c) < 0) {
MP_ERR(da, "Could not set decoder parameters.\n");
uninit(da);
return 0;
}
lavc_context->codec_tag = c->codec_tag;
lavc_context->sample_rate = c->samplerate;
lavc_context->bit_rate = c->bitrate;
lavc_context->block_align = c->block_align;
lavc_context->bits_per_coded_sample = c->bits_per_coded_sample;
lavc_context->channels = c->channels.num;
if (!mp_chmap_is_unknown(&c->channels))
lavc_context->channel_layout = mp_chmap_to_lavc(&c->channels);
// demux_mkv
mp_lavc_set_extradata(lavc_context, c->extradata, c->extradata_size);
mp_set_lav_codec_headers(lavc_context, c);
mp_set_avcodec_threads(da->log, lavc_context, opts->threads);
@@ -168,12 +174,14 @@ static int control(struct dec_audio *da, int cmd, void *arg)
ctx->trim_samples = 0;
ctx->preroll_done = false;
ctx->next_pts = MP_NOPTS_VALUE;
ctx->needs_reset = false;
return CONTROL_TRUE;
}
return CONTROL_UNKNOWN;
}
static bool send_packet(struct dec_audio *da, struct demux_packet *mpkt)
static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt,
struct mp_audio **out)
{
struct priv *priv = da->priv;
AVCodecContext *avctx = priv->avctx;
@@ -184,48 +192,60 @@ static bool send_packet(struct dec_audio *da, struct demux_packet *mpkt)
if (mpkt && priv->next_pts == MP_NOPTS_VALUE)
priv->next_pts = mpkt->pts;
int in_len = mpkt ? mpkt->len : 0;
AVPacket pkt;
mp_set_av_packet(&pkt, mpkt, &priv->codec_timebase);
int ret = avcodec_send_packet(avctx, mpkt ? &pkt : NULL);
int got_frame = 0;
av_frame_unref(priv->avframe);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return false;
if (ret < 0)
MP_ERR(da, "Error decoding audio.\n");
return true;
}
static bool receive_frame(struct dec_audio *da, struct mp_audio **out)
{
struct priv *priv = da->priv;
AVCodecContext *avctx = priv->avctx;
int ret = avcodec_receive_frame(avctx, priv->avframe);
if (ret == AVERROR_EOF) {
// If flushing was initialized earlier and has ended now, make it start
// over in case we get new packets at some point in the future.
if (priv->needs_reset)
control(da, ADCTRL_RESET, NULL);
return false;
} else if (ret < 0 && ret != AVERROR(EAGAIN)) {
MP_ERR(da, "Error decoding audio.\n");
#if HAVE_AVCODEC_NEW_CODEC_API
int ret = avcodec_send_packet(avctx, &pkt);
if (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
if (ret >= 0 && mpkt)
mpkt->len = 0;
ret = avcodec_receive_frame(avctx, priv->avframe);
if (ret >= 0)
got_frame = 1;
if (ret == AVERROR_EOF)
priv->needs_reset = true;
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
ret = 0;
}
#else
int ret = avcodec_decode_audio4(avctx, priv->avframe, &got_frame, &pkt);
if (mpkt) {
// At least "shorten" decodes sub-frames, instead of the whole packet.
// At least "mpc8" can return 0 and wants the packet again next time.
if (ret >= 0) {
ret = FFMIN(ret, mpkt->len); // sanity check against decoder overreads
mpkt->buffer += ret;
mpkt->len -= ret;
mpkt->pts = MP_NOPTS_VALUE; // don't reset PTS next time
}
// LATM may need many packets to find mux info
if (ret == AVERROR(EAGAIN)) {
mpkt->len = 0;
return 0;
}
}
#if LIBAVCODEC_VERSION_MICRO >= 100
if (priv->avframe->flags & AV_FRAME_FLAG_DISCARD)
av_frame_unref(priv->avframe);
#endif
if (ret < 0) {
MP_ERR(da, "Error decoding audio.\n");
return -1;
}
if (!got_frame)
return 0;
if (!priv->avframe->buf[0])
return true;
double out_pts = mp_pts_from_av(priv->avframe->pts, &priv->codec_timebase);
double out_pts = mp_pts_from_av(priv->avframe->pkt_pts, &priv->codec_timebase);
struct mp_audio *mpframe = mp_audio_from_avframe(priv->avframe);
if (!mpframe)
return true;
return -1;
struct mp_chmap lavc_chmap = mpframe->channels;
if (lavc_chmap.num != avctx->channels)
@@ -243,7 +263,7 @@ static bool receive_frame(struct dec_audio *da, struct mp_audio **out)
if (mpframe->pts != MP_NOPTS_VALUE)
priv->next_pts = mpframe->pts + mpframe->samples / (double)mpframe->rate;
#if LIBAVCODEC_VERSION_MICRO >= 100
#if HAVE_AVFRAME_SKIP_SAMPLES
AVFrameSideData *sd =
av_frame_get_side_data(priv->avframe, AV_FRAME_DATA_SKIP_SAMPLES);
if (sd && sd->size >= 10) {
@@ -275,8 +295,8 @@ static bool receive_frame(struct dec_audio *da, struct mp_audio **out)
av_frame_unref(priv->avframe);
MP_DBG(da, "Decoded %d samples\n", mpframe->samples);
return true;
MP_DBG(da, "Decoded %d -> %d samples\n", in_len, mpframe->samples);
return 0;
}
static void add_decoders(struct mp_decoder_list *list)
@@ -290,6 +310,5 @@ const struct ad_functions ad_lavc = {
.init = init,
.uninit = uninit,
.control = control,
.send_packet = send_packet,
.receive_frame = receive_frame,
.decode_packet = decode_packet,
};
+41 -114
View File
@@ -42,8 +42,6 @@ struct spdifContext {
bool use_dts_hd;
struct mp_audio fmt;
struct mp_audio_pool *pool;
bool got_eof;
struct demux_packet *queued_packet;
};
static int write_packet(void *p, uint8_t *buf, int buf_size)
@@ -73,8 +71,6 @@ static void uninit(struct dec_audio *da)
av_freep(&lavf_ctx->pb->buffer);
av_freep(&lavf_ctx->pb);
avformat_free_context(lavf_ctx);
talloc_free(spdif_ctx->queued_packet);
spdif_ctx->lavf_ctx = NULL;
}
}
@@ -86,41 +82,22 @@ static int init(struct dec_audio *da, const char *decoder)
spdif_ctx->use_dts_hd = da->opts->dtshd;
spdif_ctx->pool = mp_audio_pool_create(spdif_ctx);
if (strcmp(decoder, "spdif_dts_hd") == 0)
if (strcmp(decoder, "dts-hd") == 0) {
decoder = "dts";
spdif_ctx->use_dts_hd = true;
}
spdif_ctx->codec_id = mp_codec_to_av_codec_id(da->codec->codec);
spdif_ctx->codec_id = mp_codec_to_av_codec_id(decoder);
return spdif_ctx->codec_id != AV_CODEC_ID_NONE;
}
static void determine_codec_params(struct dec_audio *da, AVPacket *pkt,
int *out_profile, int *out_rate)
static int determine_codec_profile(struct dec_audio *da, AVPacket *pkt)
{
struct spdifContext *spdif_ctx = da->priv;
int profile = FF_PROFILE_UNKNOWN;
AVCodecContext *ctx = NULL;
AVFrame *frame = NULL;
AVCodecParserContext *parser = av_parser_init(spdif_ctx->codec_id);
if (parser) {
// Don't make it wait for the next frame.
parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
ctx = avcodec_alloc_context3(NULL);
uint8_t *d = NULL;
int s = 0;
av_parser_parse2(parser, ctx, &d, &s, pkt->data, pkt->size, 0, 0, 0);
*out_profile = profile = ctx->profile;
*out_rate = ctx->sample_rate;
av_free(ctx);
av_parser_close(parser);
}
if (profile != FF_PROFILE_UNKNOWN || spdif_ctx->codec_id != AV_CODEC_ID_DTS)
return;
AVCodec *codec = avcodec_find_decoder(spdif_ctx->codec_id);
if (!codec)
goto done;
@@ -139,13 +116,18 @@ static void determine_codec_params(struct dec_audio *da, AVPacket *pkt,
goto done;
}
#if HAVE_AVCODEC_NEW_CODEC_API
if (avcodec_send_packet(ctx, pkt) < 0)
goto done;
if (avcodec_receive_frame(ctx, frame) < 0)
goto done;
#else
int got_frame = 0;
if (avcodec_decode_audio4(ctx, frame, &got_frame, pkt) < 1 || !got_frame)
goto done;
#endif
*out_profile = profile = ctx->profile;
*out_rate = ctx->sample_rate;
profile = ctx->profile;
done:
av_frame_free(&frame);
@@ -155,6 +137,8 @@ done:
if (profile == FF_PROFILE_UNKNOWN)
MP_WARN(da, "Failed to parse codec profile.\n");
return profile;
}
static int init_filter(struct dec_audio *da, AVPacket *pkt)
@@ -162,9 +146,8 @@ static int init_filter(struct dec_audio *da, AVPacket *pkt)
struct spdifContext *spdif_ctx = da->priv;
int profile = FF_PROFILE_UNKNOWN;
int c_rate = 0;
determine_codec_params(da, pkt, &profile, &c_rate);
MP_VERBOSE(da, "In: profile=%d samplerate=%d\n", profile, c_rate);
if (spdif_ctx->codec_id == AV_CODEC_ID_DTS)
profile = determine_codec_profile(da, pkt);
AVFormatContext *lavf_ctx = avformat_alloc_context();
if (!lavf_ctx)
@@ -195,7 +178,11 @@ static int init_filter(struct dec_audio *da, AVPacket *pkt)
if (!stream)
goto fail;
#if HAVE_AVCODEC_HAS_CODECPAR
stream->codecpar->codec_id = spdif_ctx->codec_id;
#else
stream->codec->codec_id = spdif_ctx->codec_id;
#endif
AVDictionary *format_opts = NULL;
@@ -210,7 +197,7 @@ static int init_filter(struct dec_audio *da, AVPacket *pkt)
break;
case AV_CODEC_ID_AC3:
sample_format = AF_FORMAT_S_AC3;
samplerate = c_rate > 0 ? c_rate : 48000;
samplerate = 48000;
num_channels = 2;
break;
case AV_CODEC_ID_DTS: {
@@ -267,72 +254,44 @@ fail:
return -1;
}
static bool send_packet(struct dec_audio *da, struct demux_packet *mpkt)
static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt,
struct mp_audio **out)
{
struct spdifContext *spdif_ctx = da->priv;
if (spdif_ctx->queued_packet || spdif_ctx->got_eof)
return false;
spdif_ctx->out_buffer_len = 0;
spdif_ctx->queued_packet = mpkt ? demux_copy_packet(mpkt) : NULL;
spdif_ctx->got_eof = !mpkt;
return true;
}
if (!mpkt)
return 0;
static bool receive_frame(struct dec_audio *da, struct mp_audio **out)
{
struct spdifContext *spdif_ctx = da->priv;
if (spdif_ctx->got_eof) {
spdif_ctx->got_eof = false;
return false;
}
if (!spdif_ctx->queued_packet)
return true;
double pts = spdif_ctx->queued_packet->pts;
double pts = mpkt->pts;
AVPacket pkt;
mp_set_av_packet(&pkt, spdif_ctx->queued_packet, NULL);
mp_set_av_packet(&pkt, mpkt, NULL);
mpkt->len = 0; // will be fully consumed
pkt.pts = pkt.dts = 0;
if (!spdif_ctx->lavf_ctx) {
if (init_filter(da, &pkt) < 0)
goto done;
return -1;
}
spdif_ctx->out_buffer_len = 0;
int ret = av_write_frame(spdif_ctx->lavf_ctx, &pkt);
avio_flush(spdif_ctx->lavf_ctx->pb);
if (ret < 0) {
MP_ERR(da, "spdif mux error: '%s'\n", mp_strerror(AVUNERROR(ret)));
goto done;
}
if (ret < 0)
return -1;
int samples = spdif_ctx->out_buffer_len / spdif_ctx->fmt.sstride;
*out = mp_audio_pool_get(spdif_ctx->pool, &spdif_ctx->fmt, samples);
if (!*out)
goto done;
return -1;
memcpy((*out)->planes[0], spdif_ctx->out_buffer, spdif_ctx->out_buffer_len);
(*out)->pts = pts;
done:
talloc_free(spdif_ctx->queued_packet);
spdif_ctx->queued_packet = NULL;
return true;
return 0;
}
static int control(struct dec_audio *da, int cmd, void *arg)
{
struct spdifContext *spdif_ctx = da->priv;
switch (cmd) {
case ADCTRL_RESET:
talloc_free(spdif_ctx->queued_packet);
spdif_ctx->queued_packet = NULL;
spdif_ctx->got_eof = false;
return CONTROL_TRUE;
}
return CONTROL_UNKNOWN;
}
@@ -346,56 +305,24 @@ static const int codecs[] = {
AV_CODEC_ID_NONE
};
static bool find_codec(const char *name)
static void add_decoders(struct mp_decoder_list *list)
{
for (int n = 0; codecs[n] != AV_CODEC_ID_NONE; n++) {
const char *format = mp_codec_from_av_codec_id(codecs[n]);
if (format && name && strcmp(format, name) == 0)
return true;
}
return false;
}
// codec is the libavcodec name of the source audio codec.
// pref is a ","-separated list of names, some of them which do not match with
// libavcodec names (like dts-hd).
struct mp_decoder_list *select_spdif_codec(const char *codec, const char *pref)
{
struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list);
if (!find_codec(codec))
return list;
bool spdif_allowed = false, dts_hd_allowed = false;
bstr sel = bstr0(pref);
while (sel.len) {
bstr decoder;
bstr_split_tok(sel, ",", &decoder, &sel);
if (decoder.len) {
if (bstr_equals0(decoder, codec))
spdif_allowed = true;
if (bstr_equals0(decoder, "dts-hd") && strcmp(codec, "dts") == 0)
spdif_allowed = dts_hd_allowed = true;
if (format) {
mp_add_decoder(list, "spdif", format, format,
"libavformat/spdifenc audio pass-through decoder");
}
}
if (!spdif_allowed)
return list;
const char *suffix_name = dts_hd_allowed ? "dts_hd" : codec;
char name[80];
snprintf(name, sizeof(name), "spdif_%s", suffix_name);
mp_add_decoder(list, "spdif", codec, name,
mp_add_decoder(list, "spdif", "dts", "dts-hd",
"libavformat/spdifenc audio pass-through decoder");
return list;
}
const struct ad_functions ad_spdif = {
.name = "spdif",
.add_decoders = NULL,
.add_decoders = add_decoders,
.init = init,
.uninit = uninit,
.control = control,
.send_packet = send_packet,
.receive_frame = receive_frame,
.decode_packet = decode_packet,
};
+27 -32
View File
@@ -27,7 +27,6 @@
#include "common/codecs.h"
#include "common/msg.h"
#include "common/recorder.h"
#include "misc/bstr.h"
#include "stream/stream.h"
@@ -44,12 +43,11 @@
#include "audio/filter/af.h"
extern const struct ad_functions ad_lavc;
// Not a real codec - specially treated.
extern const struct ad_functions ad_spdif;
static const struct ad_functions * const ad_drivers[] = {
&ad_lavc,
&ad_spdif,
NULL
};
@@ -92,10 +90,10 @@ static struct mp_decoder_list *audio_select_decoders(struct dec_audio *d_audio)
struct mp_decoder_list *list = audio_decoder_list();
struct mp_decoder_list *new =
mp_select_decoders(d_audio->log, list, codec, opts->audio_decoders);
if (d_audio->try_spdif && codec) {
mp_select_decoders(list, codec, opts->audio_decoders);
if (d_audio->try_spdif) {
struct mp_decoder_list *spdif =
select_spdif_codec(codec, opts->audio_spdif);
mp_select_decoder_list(list, codec, "spdif", opts->audio_spdif);
mp_append_decoders(spdif, new);
talloc_free(new);
new = spdif;
@@ -110,8 +108,6 @@ static const struct ad_functions *find_driver(const char *name)
if (strcmp(ad_drivers[i]->name, name) == 0)
return ad_drivers[i];
}
if (strcmp(name, "spdif") == 0)
return &ad_spdif;
return NULL;
}
@@ -130,18 +126,21 @@ int audio_init_best_codec(struct dec_audio *d_audio)
const struct ad_functions *driver = find_driver(sel->family);
if (!driver)
continue;
MP_VERBOSE(d_audio, "Opening audio decoder %s\n", sel->decoder);
MP_VERBOSE(d_audio, "Opening audio decoder %s:%s\n",
sel->family, sel->decoder);
d_audio->ad_driver = driver;
if (init_audio_codec(d_audio, sel->decoder)) {
decoder = sel;
break;
}
MP_WARN(d_audio, "Audio decoder init failed for %s\n", sel->decoder);
MP_WARN(d_audio, "Audio decoder init failed for "
"%s:%s\n", sel->family, sel->decoder);
}
if (d_audio->ad_driver) {
d_audio->decoder_desc =
talloc_asprintf(d_audio, "%s (%s)", decoder->decoder, decoder->desc);
talloc_asprintf(d_audio, "%s [%s:%s]", decoder->desc, decoder->family,
decoder->decoder);
MP_VERBOSE(d_audio, "Selected audio codec: %s\n", d_audio->decoder_desc);
} else {
MP_ERR(d_audio, "Failed to initialize an audio decoder for codec '%s'.\n",
@@ -181,14 +180,10 @@ static void fix_audio_pts(struct dec_audio *da)
if (da->current_frame->pts != MP_NOPTS_VALUE) {
double newpts = da->current_frame->pts;
if (da->pts != MP_NOPTS_VALUE)
MP_STATS(da, "value %f audio-pts-err", da->pts - newpts);
// Keep the interpolated timestamp if it doesn't deviate more
// than 1 ms from the real one. (MKV rounded timestamps.)
if (da->pts == MP_NOPTS_VALUE || fabs(da->pts - newpts) > 0.001)
da->pts = newpts;
da->pts = da->current_frame->pts;
}
if (da->pts == MP_NOPTS_VALUE && da->header->missing_timestamps)
@@ -202,7 +197,7 @@ static void fix_audio_pts(struct dec_audio *da)
void audio_work(struct dec_audio *da)
{
if (da->current_frame || !da->ad_driver)
if (da->current_frame)
return;
if (!da->packet && !da->new_segment &&
@@ -218,28 +213,30 @@ void audio_work(struct dec_audio *da)
da->packet = NULL;
}
if (da->ad_driver->send_packet(da, da->packet)) {
if (da->recorder_sink)
mp_recorder_feed_packet(da->recorder_sink, da->packet);
bool had_input_packet = !!da->packet;
bool had_packet = da->packet || da->new_segment;
int ret = da->ad_driver->decode_packet(da, da->packet, &da->current_frame);
if (ret < 0 || (da->packet && da->packet->len == 0)) {
talloc_free(da->packet);
da->packet = NULL;
}
bool progress = da->ad_driver->receive_frame(da, &da->current_frame);
if (da->current_frame && !mp_audio_config_valid(da->current_frame)) {
talloc_free(da->current_frame);
da->current_frame = NULL;
}
da->current_state = da->current_frame ? DATA_OK : DATA_AGAIN;
if (!progress)
da->current_state = DATA_OK;
if (!da->current_frame) {
da->current_state = DATA_EOF;
if (had_packet)
da->current_state = DATA_AGAIN;
}
fix_audio_pts(da);
bool segment_end = da->current_state == DATA_EOF;
bool segment_end = !da->current_frame && !had_input_packet;
if (da->current_frame) {
mp_audio_clip_timestamps(da->current_frame, da->start, da->end);
@@ -256,14 +253,12 @@ void audio_work(struct dec_audio *da)
struct demux_packet *new_segment = da->new_segment;
da->new_segment = NULL;
if (da->codec == new_segment->codec) {
audio_reset_decoding(da);
} else {
da->codec = new_segment->codec;
// Could avoid decoder reinit; would still need flush.
da->codec = new_segment->codec;
if (da->ad_driver)
da->ad_driver->uninit(da);
da->ad_driver = NULL;
audio_init_best_codec(da);
}
da->ad_driver = NULL;
audio_init_best_codec(da);
da->start = new_segment->start;
da->end = new_segment->end;
-5
View File
@@ -37,8 +37,6 @@ struct dec_audio {
bool try_spdif;
struct mp_recorder_sink *recorder_sink;
// For free use by the ad_driver
void *priv;
@@ -61,7 +59,4 @@ int audio_get_frame(struct dec_audio *d_audio, struct mp_audio **out_frame);
void audio_reset_decoding(struct dec_audio *d_audio);
// ad_spdif.c
struct mp_decoder_list *select_spdif_codec(const char *codec, const char *pref);
#endif /* MPLAYER_DEC_AUDIO_H */
+142 -174
View File
@@ -31,25 +31,28 @@
#include "af.h"
// Static list of filters
extern const struct af_info af_info_delay;
extern const struct af_info af_info_channels;
extern const struct af_info af_info_format;
extern const struct af_info af_info_volume;
extern const struct af_info af_info_equalizer;
extern const struct af_info af_info_pan;
extern const struct af_info af_info_drc;
extern const struct af_info af_info_lavcac3enc;
extern const struct af_info af_info_lavrresample;
extern const struct af_info af_info_scaletempo;
extern const struct af_info af_info_bs2b;
extern const struct af_info af_info_lavfi;
extern const struct af_info af_info_lavfi_bridge;
extern const struct af_info af_info_rubberband;
static const struct af_info *const filter_list[] = {
&af_info_delay,
&af_info_channels,
&af_info_format,
&af_info_volume,
&af_info_equalizer,
&af_info_pan,
&af_info_drc,
&af_info_lavcac3enc,
&af_info_lavrresample,
#if HAVE_RUBBERBAND
@@ -57,7 +60,6 @@ static const struct af_info *const filter_list[] = {
#endif
&af_info_scaletempo,
&af_info_lavfi,
&af_info_lavfi_bridge,
NULL
};
@@ -80,8 +82,6 @@ static bool get_desc(struct m_obj_desc *dst, int index)
const struct m_obj_list af_obj_list = {
.get_desc = get_desc,
.description = "audio filters",
.allow_disable_entries = true,
.allow_unknown_entries = true,
.aliases = {
{"force", "format"},
{0}
@@ -152,17 +152,10 @@ contain the commandline parameters for the filter */
static struct af_instance *af_create(struct af_stream *s, char *name,
char **args)
{
const char *lavfi_name = NULL;
char **lavfi_args = NULL;
struct m_obj_desc desc;
if (!m_obj_list_find(&desc, &af_obj_list, bstr0(name))) {
if (!m_obj_list_find(&desc, &af_obj_list, bstr0("lavfi-bridge"))) {
MP_ERR(s, "Couldn't find audio filter '%s'.\n", name);
return NULL;
}
lavfi_name = name;
lavfi_args = args;
args = NULL;
MP_ERR(s, "Couldn't find audio filter '%s'.\n", name);
return NULL;
}
MP_VERBOSE(s, "Adding filter %s \n", name);
@@ -175,24 +168,11 @@ static struct af_instance *af_create(struct af_stream *s, char *name,
.replaygain_data = s->replaygain_data,
.out_pool = mp_audio_pool_create(af),
};
struct m_config *config =
m_config_from_obj_desc_and_args(af, s->log, NULL, &desc,
name, s->opts->af_defs, args);
if (!config)
struct m_config *config = m_config_from_obj_desc(af, s->log, &desc);
if (m_config_apply_defaults(config, name, s->opts->af_defs) < 0)
goto error;
if (m_config_set_obj_params(config, args) < 0)
goto error;
if (lavfi_name) {
// Pass the filter arguments as proper sub-options to the bridge filter.
struct m_config_option *name_opt = m_config_get_co(config, bstr0("name"));
assert(name_opt);
assert(name_opt->opt->type == &m_option_type_string);
if (m_config_set_option_raw(config, name_opt, &lavfi_name, 0) < 0)
goto error;
struct m_config_option *opts = m_config_get_co(config, bstr0("opts"));
assert(opts);
assert(opts->opt->type == &m_option_type_keyvalue_list);
if (m_config_set_option_raw(config, opts, &lavfi_args, 0) < 0)
goto error;
}
af->priv = config->optstruct;
// Initialize the new filter
@@ -276,8 +256,6 @@ static void af_print_filter_chain(struct af_stream *s, struct af_instance *at,
mp_snprintf_cat(b, sizeof(b), "\"%s\" ", af->label);
if (af->data)
mp_snprintf_cat(b, sizeof(b), "%s", mp_audio_config_to_str(af->data));
if (af->auto_inserted)
mp_snprintf_cat(b, sizeof(b), " [a]");
if (af == at)
mp_snprintf_cat(b, sizeof(b), " <-");
MP_MSG(s, msg_level, "%s\n", b);
@@ -288,156 +266,164 @@ static void af_print_filter_chain(struct af_stream *s, struct af_instance *at,
MP_MSG(s, msg_level, " [ao] %s\n", mp_audio_config_to_str(&s->output));
}
static void reset_formats(struct af_stream *s)
{
struct mp_audio none = {0};
for (struct af_instance *af = s->first; af; af = af->next) {
if (af != s->first && af != s->last)
mp_audio_copy_config(af->data, &none);
}
}
static int filter_reinit(struct af_instance *af)
// in is what af can take as input - insert a conversion filter if the actual
// input format doesn't match what af expects.
// Returns:
// AF_OK: must call af_reinit() or equivalent, format matches (or is closer)
// AF_FALSE: nothing was changed, format matches
// else: error
static int af_fix_format_conversion(struct af_stream *s,
struct af_instance **p_af,
struct mp_audio in)
{
int rv;
struct af_instance *af = *p_af;
struct af_instance *prev = af->prev;
assert(prev);
// Check if this is the first filter
struct mp_audio in = *prev->data;
// Reset just in case...
mp_audio_set_null_data(&in);
if (!mp_audio_config_valid(&in))
struct mp_audio actual = *prev->data;
if (actual.format == in.format)
return AF_FALSE;
int dstfmt = in.format;
char *filter = "lavrresample";
if (!af_lavrresample_test_conversion(actual.format, dstfmt))
return AF_ERROR;
af->fmt_in = in;
int rv = af->control(af, AF_CONTROL_REINIT, &in);
if (rv == AF_OK && !mp_audio_config_equals(&in, prev->data))
rv = AF_FALSE; // conversion filter needed
if (rv == AF_FALSE)
af->fmt_in = in;
if (rv == AF_OK) {
if (!mp_audio_config_valid(af->data))
return AF_ERROR;
af->fmt_out = *af->data;
}
return rv;
}
static int filter_reinit_with_conversion(struct af_stream *s, struct af_instance *af)
{
int rv = filter_reinit(af);
// Conversion filter is needed
if (rv == AF_FALSE) {
// First try if we can change the output format of the previous
// filter to the input format the current filter is expecting.
struct mp_audio in = af->fmt_in;
if (af->prev != s->first && !mp_audio_config_equals(af->prev->data, &in)) {
// This should have been successful (because it succeeded
// before), even if just reverting to the old output format.
mp_audio_copy_config(af->prev->data, &in);
rv = filter_reinit(af->prev);
if (rv != AF_OK)
return rv;
if (strcmp(filter, prev->info->name) == 0) {
if (prev->control(prev, AF_CONTROL_SET_FORMAT, &dstfmt) == AF_OK) {
*p_af = prev;
return AF_OK;
}
if (!mp_audio_config_equals(af->prev->data, &in)) {
// Retry with conversion filter added.
struct af_instance *new =
af_prepend(s, af, "lavrresample", NULL);
if (!new)
return AF_ERROR;
new->auto_inserted = true;
mp_audio_copy_config(new->data, &in);
rv = filter_reinit(new);
if (rv != AF_OK)
af_remove(s, new);
}
if (rv == AF_OK)
rv = filter_reinit(af);
return AF_ERROR;
}
return rv;
}
static int af_find_output_conversion(struct af_stream *s, struct mp_audio *cfg)
{
assert(mp_audio_config_valid(&s->output));
assert(s->initialized > 0);
if (mp_chmap_equals_reordered(&s->input.channels, &s->output.channels))
struct af_instance *new = af_prepend(s, af, filter, NULL);
if (new == NULL)
return AF_ERROR;
// Heuristic to detect point of conversion. If it looks like something
// more complicated is going on, better bail out.
// We expect that the last filter converts channels.
struct af_instance *conv = s->last->prev;
if (!conv->auto_inserted)
return AF_ERROR;
if (!(mp_chmap_equals_reordered(&conv->fmt_in.channels, &s->input.channels) &&
mp_chmap_equals_reordered(&conv->fmt_out.channels, &s->output.channels)))
return AF_ERROR;
// Also, should be the only one which does auto conversion.
for (struct af_instance *af = s->first->next; af != s->last; af = af->next)
{
if (af != conv && af->auto_inserted &&
!mp_chmap_equals_reordered(&af->fmt_in.channels, &af->fmt_out.channels))
return AF_ERROR;
new->auto_inserted = true;
if (AF_OK != (rv = new->control(new, AF_CONTROL_SET_FORMAT, &dstfmt))) {
af_remove(s, new);
return rv;
}
// And not if it's the only filter.
if (conv->prev == s->first && conv->next == s->last)
return AF_ERROR;
*cfg = s->output;
*p_af = new;
return AF_OK;
}
// Return AF_OK on success or AF_ERROR on failure.
static int af_do_reinit(struct af_stream *s, bool second_pass)
// same as af_fix_format_conversion - only wrt. channels
static int af_fix_channels(struct af_stream *s, struct af_instance **p_af,
struct mp_audio in)
{
struct mp_audio convert_early = {0};
if (second_pass) {
// If a channel conversion happens, and it is done by an auto-inserted
// filter, then insert a filter to convert it early. Otherwise, do
// nothing and return immediately.
if (af_find_output_conversion(s, &convert_early) != AF_OK)
return AF_OK;
int rv;
struct af_instance *af = *p_af;
struct af_instance *prev = af->prev;
struct mp_audio actual = *prev->data;
if (mp_chmap_equals(&actual.channels, &in.channels))
return AF_FALSE;
if (prev->control(prev, AF_CONTROL_SET_CHANNELS, &in.channels) == AF_OK) {
*p_af = prev;
return AF_OK;
}
char *filter = "lavrresample";
struct af_instance *new = af_prepend(s, af, filter, NULL);
if (new == NULL)
return AF_ERROR;
new->auto_inserted = true;
if (AF_OK != (rv = new->control(new, AF_CONTROL_SET_CHANNELS, &in.channels)))
return rv;
*p_af = new;
return AF_OK;
}
static int af_fix_rate(struct af_stream *s, struct af_instance **p_af,
struct mp_audio in)
{
int rv;
struct af_instance *af = *p_af;
struct af_instance *prev = af->prev;
struct mp_audio actual = *prev->data;
if (actual.rate == in.rate)
return AF_FALSE;
if (prev->control(prev, AF_CONTROL_SET_RESAMPLE_RATE, &in.rate) == AF_OK) {
*p_af = prev;
return AF_OK;
}
char *filter = "lavrresample";
struct af_instance *new = af_prepend(s, af, filter, NULL);
if (new == NULL)
return AF_ERROR;
new->auto_inserted = true;
if (AF_OK != (rv = new->control(new, AF_CONTROL_SET_RESAMPLE_RATE, &in.rate)))
return rv;
*p_af = new;
return AF_OK;
}
static void reset_formats(struct af_stream *s)
{
for (struct af_instance *af = s->first; af; af = af->next) {
af->control(af, AF_CONTROL_SET_RESAMPLE_RATE, &(int){0});
af->control(af, AF_CONTROL_SET_CHANNELS, &(struct mp_chmap){0});
af->control(af, AF_CONTROL_SET_FORMAT, &(int){0});
}
}
// Return AF_OK on success or AF_ERROR on failure.
// Warning:
// A failed af_reinit() leaves the audio chain behind in a useless, broken
// state (for example, format filters that were tentatively inserted stay
// inserted).
// In that case, you should always rebuild the filter chain, or abort.
static int af_reinit(struct af_stream *s)
{
remove_auto_inserted_filters(s);
af_chain_forget_frames(s);
reset_formats(s);
s->first->fmt_in = s->first->fmt_out = s->input;
if (mp_audio_config_valid(&convert_early)) {
struct af_instance *new = af_prepend(s, s->first, "lavrresample", NULL);
if (!new)
return AF_ERROR;
new->auto_inserted = true;
mp_audio_copy_config(new->data, &convert_early);
int rv = filter_reinit(new);
if (rv != AF_DETACH && rv != AF_OK)
return AF_ERROR;
MP_VERBOSE(s, "Moving up output conversion.\n");
}
// Start with the second filter, as the first filter is the special input
// filter which needs no initialization.
struct af_instance *af = s->first->next;
// Up to 4 retries per filter (channel, rate, format conversions)
int max_retry = 4;
int retry = 0;
while (af) {
int rv = filter_reinit_with_conversion(s, af);
if (retry >= max_retry)
goto negotiate_error;
// Check if this is the first filter
struct mp_audio in = *af->prev->data;
// Reset just in case...
mp_audio_set_null_data(&in);
if (!mp_audio_config_valid(&in))
goto error;
af->fmt_in = in;
int rv = af->control(af, AF_CONTROL_REINIT, &in);
if (rv == AF_OK && !mp_audio_config_equals(&in, af->prev->data))
rv = AF_FALSE; // conversion filter needed
switch (rv) {
case AF_OK:
if (!mp_audio_config_valid(af->data))
goto error;
af->fmt_out = *af->data;
af = af->next;
break;
case AF_FALSE: {
case AF_FALSE: { // Configuration filter is needed
if (af_fix_channels(s, &af, in) == AF_OK) {
retry++;
continue;
}
if (af_fix_rate(s, &af, in) == AF_OK) {
retry++;
continue;
}
// Do this last, to prevent "format->lavrresample" being added to
// the filter chain when output formats not supported by
// af_lavrresample are in use.
if (af_fix_format_conversion(s, &af, in) == AF_OK) {
retry++;
continue;
}
// If the format conversion is (probably) caused by spdif, then
// (as a feature) drop the filter, instead of failing hard.
int fmt_in1 = af->prev->data->format;
int fmt_in2 = af->fmt_in.format;
int fmt_in2 = in.format;
if (af_fmt_is_valid(fmt_in1) && af_fmt_is_valid(fmt_in2)) {
bool spd1 = af_fmt_is_spdif(fmt_in1);
bool spd2 = af_fmt_is_spdif(fmt_in2);
@@ -448,6 +434,7 @@ static int af_do_reinit(struct af_stream *s, bool second_pass)
struct af_instance *aft = af->prev;
af_remove(s, af);
af = aft->next;
retry++;
continue;
}
}
@@ -465,6 +452,8 @@ static int af_do_reinit(struct af_stream *s, bool second_pass)
af->info->name, rv);
goto error;
}
if (af && !af->auto_inserted)
retry = 0;
}
/* Set previously unset fields in s->output to those of the filter chain
@@ -488,19 +477,6 @@ error:
return AF_ERROR;
}
static int af_reinit(struct af_stream *s)
{
int r = af_do_reinit(s, false);
if (r == AF_OK && mp_audio_config_valid(&s->output)) {
r = af_do_reinit(s, true);
if (r != AF_OK) {
MP_ERR(s, "Failed second pass filter negotiation.\n");
r = af_do_reinit(s, false);
}
}
return r;
}
// Uninit and remove all filters
void af_uninit(struct af_stream *s)
{
@@ -569,8 +545,6 @@ int af_init(struct af_stream *s)
// Add all filters in the list (if there are any)
struct m_obj_settings *list = s->opts->af_settings;
for (int i = 0; list && list[i].name; i++) {
if (!list[i].enabled)
continue;
struct af_instance *af =
af_prepend(s, s->last, list[i].name, list[i].attribs);
if (!af) {
@@ -803,12 +777,6 @@ struct mp_audio *af_read_output_frame(struct af_stream *s)
return af_dequeue_output_frame(s->last);
}
void af_unread_output_frame(struct af_stream *s, struct mp_audio *frame)
{
struct af_instance *af = s->last;
MP_TARRAY_INSERT_AT(af, af->out_queued, af->num_out_queued, 0, frame);
}
// Make sure the caller can change data referenced by the frame.
// Return negative error code on failure (i.e. you can't write).
int af_make_writeable(struct af_instance *af, struct mp_audio *frame)
+5 -1
View File
@@ -112,6 +112,9 @@ struct af_stream {
enum af_control {
AF_CONTROL_REINIT = 1,
AF_CONTROL_RESET,
AF_CONTROL_SET_RESAMPLE_RATE,
AF_CONTROL_SET_FORMAT,
AF_CONTROL_SET_CHANNELS,
AF_CONTROL_SET_VOLUME,
AF_CONTROL_GET_VOLUME,
AF_CONTROL_SET_PAN_LEVEL,
@@ -148,7 +151,6 @@ void af_add_output_frame(struct af_instance *af, struct mp_audio *frame);
int af_filter_frame(struct af_stream *s, struct mp_audio *frame);
int af_output_frame(struct af_stream *s, bool eof);
struct mp_audio *af_read_output_frame(struct af_stream *s);
void af_unread_output_frame(struct af_stream *s, struct mp_audio *frame);
int af_make_writeable(struct af_instance *af, struct mp_audio *frame);
double af_calc_delay(struct af_stream *s);
@@ -158,4 +160,6 @@ int af_test_output(struct af_instance *af, struct mp_audio *out);
int af_from_ms(int n, float *in, int *out, int rate, float mi, float ma);
float af_softclip(float a);
bool af_lavrresample_test_conversion(int src_format, int dst_format);
#endif /* MPLAYER_AF_H */
-2
View File
@@ -214,8 +214,6 @@ static int af_open(struct af_instance* af){
af->filter_frame = filter_frame;
af_channels_t *s = af->priv;
MP_WARN(af, "This filter is deprecated (no replacement).\n");
// If router scan commandline for routing pairs
if(s->routes && s->routes[0]){
char* cp = s->routes;
+194
View File
@@ -0,0 +1,194 @@
/*
* This audio filter delays the output signal for the different
* channels and can be used for simple position panning.
* An extension for this filter would be a reverb.
*
* Original author: Anders
*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "common/common.h"
#include "af.h"
#define L 65536
#define UPDATEQI(qi) qi=(qi+1)&(L-1)
// Data for specific instances of this filter
typedef struct af_delay_s
{
void* q[AF_NCH]; // Circular queues used for delaying audio signal
int wi[AF_NCH]; // Write index
int ri; // Read index
float d[AF_NCH]; // Delay [ms]
char *delaystr;
}af_delay_t;
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
af_delay_t* s = af->priv;
switch(cmd){
case AF_CONTROL_REINIT:{
int i;
struct mp_audio *in = arg;
if (in->bps != 1 && in->bps != 2 && in->bps != 4) {
MP_FATAL(af, "Sample format not supported\n");
return AF_ERROR;
}
// Free prevous delay queues
for(i=0;i<af->data->nch;i++)
free(s->q[i]);
mp_audio_force_interleaved_format(in);
mp_audio_copy_config(af->data, in);
// Allocate new delay queues
for(i=0;i<af->data->nch;i++){
s->q[i] = calloc(L,af->data->bps);
if(NULL == s->q[i])
MP_FATAL(af, "Out of memory\n");
}
if(AF_OK != af_from_ms(AF_NCH, s->d, s->wi, af->data->rate, 0.0, 1000.0))
return AF_ERROR;
s->ri = 0;
for(i=0;i<AF_NCH;i++){
MP_DBG(af, "Channel %i delayed by %0.3fms\n",
i,MPCLAMP(s->d[i],0.0,1000.0));
MP_TRACE(af, "Channel %i delayed by %i samples\n",
i,s->wi[i]);
}
return AF_OK;
}
}
return AF_UNKNOWN;
}
// Deallocate memory
static void uninit(struct af_instance* af)
{
int i;
for(i=0;i<AF_NCH;i++)
free(((af_delay_t*)(af->priv))->q[i]);
}
static int filter_frame(struct af_instance *af, struct mp_audio *c)
{
if (!c)
return 0;
af_delay_t* s = af->priv; // Setup for this instance
int nch = c->nch; // Number of channels
int len = mp_audio_psize(c)/c->bps; // Number of sample in data chunk
int ri = 0;
int ch,i;
if (af_make_writeable(af, c) < 0) {
talloc_free(c);
return -1;
}
for(ch=0;ch<nch;ch++){
switch(c->bps){
case 1:{
int8_t* a = c->planes[0];
int8_t* q = s->q[ch];
int wi = s->wi[ch];
ri = s->ri;
for(i=ch;i<len;i+=nch){
q[wi] = a[i];
a[i] = q[ri];
UPDATEQI(wi);
UPDATEQI(ri);
}
s->wi[ch] = wi;
break;
}
case 2:{
int16_t* a = c->planes[0];
int16_t* q = s->q[ch];
int wi = s->wi[ch];
ri = s->ri;
for(i=ch;i<len;i+=nch){
q[wi] = a[i];
a[i] = q[ri];
UPDATEQI(wi);
UPDATEQI(ri);
}
s->wi[ch] = wi;
break;
}
case 4:{
int32_t* a = c->planes[0];
int32_t* q = s->q[ch];
int wi = s->wi[ch];
ri = s->ri;
for(i=ch;i<len;i+=nch){
q[wi] = a[i];
a[i] = q[ri];
UPDATEQI(wi);
UPDATEQI(ri);
}
s->wi[ch] = wi;
break;
}
}
}
s->ri = ri;
af_add_output_frame(af, c);
return 0;
}
// Allocate memory and set function pointers
static int af_open(struct af_instance* af){
af->control=control;
af->uninit=uninit;
af->filter_frame = filter_frame;
af_delay_t *s = af->priv;
int n = 1;
int i = 0;
char* cl = s->delaystr;
while(cl && n && i < AF_NCH ){
sscanf(cl,"%f%n",&s->d[i],&n);
if(n==0 || cl[n-1] == '\0')
break;
cl=&cl[n];
if (*cl != ',')
break;
cl++;
i++;
}
return AF_OK;
}
#define OPT_BASE_STRUCT af_delay_t
const struct af_info af_info_delay = {
.info = "Delay audio filter",
.name = "delay",
.open = af_open,
.priv_size = sizeof(af_delay_t),
.options = (const struct m_option[]) {
OPT_STRING("delays", delaystr, 0),
{0}
},
};
+334
View File
@@ -0,0 +1,334 @@
/*
* Copyright (C) 2004 Alex Beregszaszi & Pierre Lombard
*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <math.h>
#include <limits.h>
#include "common/common.h"
#include "af.h"
// Methods:
// 1: uses a 1 value memory and coefficients new=a*old+b*cur (with a+b=1)
// 2: uses several samples to smooth the variations (standard weighted mean
// on past samples)
// Size of the memory array
// FIXME: should depend on the frequency of the data (should be a few seconds)
#define NSAMPLES 128
// If summing all the mem[].len is lower than MIN_SAMPLE_SIZE bytes, then we
// choose to ignore the computed value as it's not significant enough
// FIXME: should depend on the frequency of the data (0.5s maybe)
#define MIN_SAMPLE_SIZE 32000
// mul is the value by which the samples are scaled
// and has to be in [MUL_MIN, MUL_MAX]
#define MUL_INIT 1.0
#define MUL_MIN 0.1
#define MUL_MAX 5.0
// Silence level
// FIXME: should be relative to the level of the samples
#define SIL_S16 (SHRT_MAX * 0.01)
#define SIL_FLOAT 0.01
// smooth must be in ]0.0, 1.0[
#define SMOOTH_MUL 0.06
#define SMOOTH_LASTAVG 0.06
#define DEFAULT_TARGET 0.25
// Data for specific instances of this filter
typedef struct af_volume_s
{
int method; // method used
float mul;
// method 1
float lastavg; // history value of the filter
// method 2
int idx;
struct {
float avg; // average level of the sample
int len; // sample size (weight)
} mem[NSAMPLES];
// "Ideal" level
float mid_s16;
float mid_float;
}af_drc_t;
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
switch(cmd){
case AF_CONTROL_REINIT:
// Sanity check
if(!arg) return AF_ERROR;
mp_audio_force_interleaved_format((struct mp_audio*)arg);
mp_audio_copy_config(af->data, (struct mp_audio*)arg);
if(((struct mp_audio*)arg)->format != (AF_FORMAT_S16)){
mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
}
return af_test_output(af,(struct mp_audio*)arg);
}
return AF_UNKNOWN;
}
static void method1_int16(af_drc_t *s, struct mp_audio *c)
{
register int i = 0;
int16_t *data = (int16_t*)c->planes[0]; // Audio data
int len = c->samples*c->nch; // Number of samples
float curavg = 0.0, newavg, neededmul;
int tmp;
for (i = 0; i < len; i++)
{
tmp = data[i];
curavg += tmp * tmp;
}
curavg = sqrt(curavg / (float) len);
// Evaluate an adequate 'mul' coefficient based on previous state, current
// samples level, etc
if (curavg > SIL_S16)
{
neededmul = s->mid_s16 / (curavg * s->mul);
s->mul = (1.0 - SMOOTH_MUL) * s->mul + SMOOTH_MUL * neededmul;
// clamp the mul coefficient
s->mul = MPCLAMP(s->mul, MUL_MIN, MUL_MAX);
}
// Scale & clamp the samples
for (i = 0; i < len; i++)
{
tmp = s->mul * data[i];
tmp = MPCLAMP(tmp, SHRT_MIN, SHRT_MAX);
data[i] = tmp;
}
// Evaluation of newavg (not 100% accurate because of values clamping)
newavg = s->mul * curavg;
// Stores computed values for future smoothing
s->lastavg = (1.0 - SMOOTH_LASTAVG) * s->lastavg + SMOOTH_LASTAVG * newavg;
}
static void method1_float(af_drc_t *s, struct mp_audio *c)
{
register int i = 0;
float *data = (float*)c->planes[0]; // Audio data
int len = c->samples*c->nch; // Number of samples
float curavg = 0.0, newavg, neededmul, tmp;
for (i = 0; i < len; i++)
{
tmp = data[i];
curavg += tmp * tmp;
}
curavg = sqrt(curavg / (float) len);
// Evaluate an adequate 'mul' coefficient based on previous state, current
// samples level, etc
if (curavg > SIL_FLOAT) // FIXME
{
neededmul = s->mid_float / (curavg * s->mul);
s->mul = (1.0 - SMOOTH_MUL) * s->mul + SMOOTH_MUL * neededmul;
// clamp the mul coefficient
s->mul = MPCLAMP(s->mul, MUL_MIN, MUL_MAX);
}
// Scale & clamp the samples
for (i = 0; i < len; i++)
data[i] *= s->mul;
// Evaluation of newavg (not 100% accurate because of values clamping)
newavg = s->mul * curavg;
// Stores computed values for future smoothing
s->lastavg = (1.0 - SMOOTH_LASTAVG) * s->lastavg + SMOOTH_LASTAVG * newavg;
}
static void method2_int16(af_drc_t *s, struct mp_audio *c)
{
register int i = 0;
int16_t *data = (int16_t*)c->planes[0]; // Audio data
int len = c->samples*c->nch; // Number of samples
float curavg = 0.0, newavg, avg = 0.0;
int tmp, totallen = 0;
for (i = 0; i < len; i++)
{
tmp = data[i];
curavg += tmp * tmp;
}
curavg = sqrt(curavg / (float) len);
// Evaluate an adequate 'mul' coefficient based on previous state, current
// samples level, etc
for (i = 0; i < NSAMPLES; i++)
{
avg += s->mem[i].avg * (float)s->mem[i].len;
totallen += s->mem[i].len;
}
if (totallen > MIN_SAMPLE_SIZE)
{
avg /= (float)totallen;
if (avg >= SIL_S16)
{
s->mul = s->mid_s16 / avg;
s->mul = MPCLAMP(s->mul, MUL_MIN, MUL_MAX);
}
}
// Scale & clamp the samples
for (i = 0; i < len; i++)
{
tmp = s->mul * data[i];
tmp = MPCLAMP(tmp, SHRT_MIN, SHRT_MAX);
data[i] = tmp;
}
// Evaluation of newavg (not 100% accurate because of values clamping)
newavg = s->mul * curavg;
// Stores computed values for future smoothing
s->mem[s->idx].len = len;
s->mem[s->idx].avg = newavg;
s->idx = (s->idx + 1) % NSAMPLES;
}
static void method2_float(af_drc_t *s, struct mp_audio *c)
{
register int i = 0;
float *data = (float*)c->planes[0]; // Audio data
int len = c->samples*c->nch; // Number of samples
float curavg = 0.0, newavg, avg = 0.0, tmp;
int totallen = 0;
for (i = 0; i < len; i++)
{
tmp = data[i];
curavg += tmp * tmp;
}
curavg = sqrt(curavg / (float) len);
// Evaluate an adequate 'mul' coefficient based on previous state, current
// samples level, etc
for (i = 0; i < NSAMPLES; i++)
{
avg += s->mem[i].avg * (float)s->mem[i].len;
totallen += s->mem[i].len;
}
if (totallen > MIN_SAMPLE_SIZE)
{
avg /= (float)totallen;
if (avg >= SIL_FLOAT)
{
s->mul = s->mid_float / avg;
s->mul = MPCLAMP(s->mul, MUL_MIN, MUL_MAX);
}
}
// Scale & clamp the samples
for (i = 0; i < len; i++)
data[i] *= s->mul;
// Evaluation of newavg (not 100% accurate because of values clamping)
newavg = s->mul * curavg;
// Stores computed values for future smoothing
s->mem[s->idx].len = len;
s->mem[s->idx].avg = newavg;
s->idx = (s->idx + 1) % NSAMPLES;
}
static int filter(struct af_instance *af, struct mp_audio *data)
{
af_drc_t *s = af->priv;
if (!data)
return 0;
if (af_make_writeable(af, data) < 0) {
talloc_free(data);
return -1;
}
if(af->data->format == (AF_FORMAT_S16))
{
if (s->method == 2)
method2_int16(s, data);
else
method1_int16(s, data);
}
else if(af->data->format == (AF_FORMAT_FLOAT))
{
if (s->method == 2)
method2_float(s, data);
else
method1_float(s, data);
}
af_add_output_frame(af, data);
return 0;
}
// Allocate memory and set function pointers
static int af_open(struct af_instance* af){
int i = 0;
af->control=control;
af->filter_frame = filter;
af_drc_t *priv = af->priv;
priv->mul = MUL_INIT;
priv->lastavg = ((float)SHRT_MAX) * DEFAULT_TARGET;
priv->idx = 0;
for (i = 0; i < NSAMPLES; i++)
{
priv->mem[i].len = 0;
priv->mem[i].avg = 0;
}
priv->mid_s16 = ((float)SHRT_MAX) * priv->mid_float;
return AF_OK;
}
#define OPT_BASE_STRUCT af_drc_t
const struct af_info af_info_drc = {
.info = "Dynamic range compression filter",
.name = "drc",
.open = af_open,
.priv_size = sizeof(af_drc_t),
.options = (const struct m_option[]) {
OPT_INTRANGE("method", method, 0, 1, 2, OPTDEF_INT(1)),
OPT_FLOAT("target", mid_float, 0, OPTDEF_FLOAT(DEFAULT_TARGET)),
{0}
},
};
-1
View File
@@ -188,7 +188,6 @@ static int filter(struct af_instance* af, struct mp_audio* data)
// Allocate memory and set function pointers
static int af_open(struct af_instance* af){
MP_WARN(af, "This filter is deprecated. Use 'anequalizer' or 'firequalizer' instead.\n");
af->control=control;
af->filter_frame = filter;
af_equalizer_t *priv = af->priv;
Loaded 100 of 478 files, more files were not shown because too many files have changed in this diff. Show more