Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78adec6c9c | ||
|
|
0fed032ca0 | ||
|
|
96532916fe | ||
|
|
c265855d44 | ||
|
|
7816fa9745 | ||
|
|
e76076da3d | ||
|
|
90015a8b8b | ||
|
|
d1a8dfb8c4 | ||
|
|
e68fcbfa39 | ||
|
|
391c087d75 | ||
|
|
b4f6e57d2c | ||
|
|
854cdb796e | ||
|
|
504c452568 | ||
|
|
ee54711ceb | ||
|
|
3ac568714c | ||
|
|
d64b165b2a | ||
|
|
78a57135f9 | ||
|
|
09f00db142 | ||
|
|
673919df7d | ||
|
|
d2fc1534c8 | ||
|
|
10c3b71720 | ||
|
|
0ba3760745 | ||
|
|
1dbbd845a4 | ||
|
|
131fad8bc9 | ||
|
|
6af87017d1 | ||
|
|
bd70c32504 | ||
|
|
4c88ac3434 | ||
|
|
4cd36b999f | ||
|
|
1b3155cf51 | ||
|
|
ace9a4b6c6 | ||
|
|
84cd043f85 | ||
|
|
6cdc5627f0 | ||
|
|
cb355443dc | ||
|
|
cc2b5c16fa | ||
|
|
bf345136b9 | ||
|
|
6b525b84bb | ||
|
|
ea17adcd66 | ||
|
|
31cdb96474 | ||
|
|
b3233fa3ff | ||
|
|
132528ff67 | ||
|
|
efc32ac0df | ||
|
|
042302fa65 | ||
|
|
93ce083bd8 | ||
|
|
97c93918fe | ||
|
|
7078df4f5e | ||
|
|
8e642809bf | ||
|
|
8c4cf5ce84 | ||
|
|
16cbc4a014 | ||
|
|
2aff8b7523 | ||
|
|
5d9353f0d5 | ||
|
|
6f139ad981 | ||
|
|
0052445e86 | ||
|
|
2cf8d4ffdb | ||
|
|
e6236e22db | ||
|
|
f572d22863 | ||
|
|
0554379f84 | ||
|
|
a0e4455616 | ||
|
|
935ca52d81 | ||
|
|
71b0c2b88c | ||
|
|
a54ca2da31 | ||
|
|
a0485221c7 | ||
|
|
1b8eeeb8cc | ||
|
|
97770473d0 | ||
|
|
dd3e52fe68 | ||
|
|
f0a5ff39a1 | ||
|
|
7cbb7b680c | ||
|
|
cf02e515d4 | ||
|
|
c7dee24c8c | ||
|
|
8c234045fa | ||
|
|
24fffa0f6b | ||
|
|
5106edfd5e | ||
|
|
5a1b60c567 | ||
|
|
0f1764195a | ||
|
|
683da7411e | ||
|
|
94e71b7cc0 | ||
|
|
eeac26410f | ||
|
|
1560d6ce60 | ||
|
|
9b20c681fd | ||
|
|
a550731209 | ||
|
|
0933f12d28 | ||
|
|
c613d802bc | ||
|
|
8d5f800567 | ||
|
|
f312528ebc | ||
|
|
20988ee607 | ||
|
|
38874b2f2e | ||
|
|
7ce464bef9 | ||
|
|
d1c473bc25 | ||
|
|
57c3fca7a8 | ||
|
|
42189ada97 | ||
|
|
65a3977282 | ||
|
|
177c89d948 | ||
|
|
16450fab3f | ||
|
|
5c3abb9082 | ||
|
|
de6eace6e9 | ||
|
|
ccdaecfc5c | ||
|
|
f3556356b7 | ||
|
|
99adbe1e7c | ||
|
|
55883943c5 | ||
|
|
8304046180 | ||
|
|
2d638347c1 | ||
|
|
2119bcbeac | ||
|
|
ae9a3e33aa | ||
|
|
fd49edccf8 | ||
|
|
1be863afdb | ||
|
|
c3ea08a2d7 | ||
|
|
89fced63b8 | ||
|
|
6a0408be68 | ||
|
|
76f32e3881 | ||
|
|
683e212a77 | ||
|
|
3289473678 | ||
|
|
bdc56771eb | ||
|
|
ef9c5300ef | ||
|
|
93b712fa8a | ||
|
|
df5706f156 | ||
|
|
a4998e08ef | ||
|
|
a8240c1b58 | ||
|
|
4da7630824 | ||
|
|
d24bf6e349 | ||
|
|
ca2b05c0fb | ||
|
|
fde99da5c6 | ||
|
|
886c3ef999 | ||
|
|
f01744ac4e | ||
|
|
3c0333978e | ||
|
|
7be13b4690 | ||
|
|
ed9295c250 | ||
|
|
94d6babb95 | ||
|
|
f210244a1c | ||
|
|
c000a08de2 | ||
|
|
00d41cc5b0 | ||
|
|
9488d312c1 | ||
|
|
2c6a3cb1f2 | ||
|
|
5b3ae5aaac | ||
|
|
60e7926248 | ||
|
|
4e1d65983a | ||
|
|
9d3943840c | ||
|
|
73808cd8f0 | ||
|
|
67d87d36d5 | ||
|
|
0ab9634eb3 | ||
|
|
0e68ff4fad | ||
|
|
1b3fbfc183 | ||
|
|
b7f01957ec | ||
|
|
b8382aabb3 | ||
|
|
0901fc8e0e | ||
|
|
4d2f354da6 | ||
|
|
ede652774e | ||
|
|
3871024ec3 | ||
|
|
0d90dd07ff | ||
|
|
9f149717a6 | ||
|
|
2970352b25 | ||
|
|
828a952c9a | ||
|
|
696a8c5609 | ||
|
|
5a837ced0b | ||
|
|
9a55c4e70c | ||
|
|
f5bf6c0fb3 | ||
|
|
7eb13c4028 | ||
|
|
0a0d7f43a5 | ||
|
|
6048f87e3c | ||
|
|
b0cc3c2cf4 | ||
|
|
200fb7eceb | ||
|
|
72fbd846db | ||
|
|
1e4f08c50c | ||
|
|
4e6751609e | ||
|
|
cc12f05a52 | ||
|
|
641e94cd27 | ||
|
|
7c3f1ffc44 | ||
|
|
39d1ab82e5 | ||
|
|
1ee8d0210d | ||
|
|
1dbb73e0fb | ||
|
|
fdd5140f43 | ||
|
|
d75cfef49c | ||
|
|
3308bc2bc9 | ||
|
|
d4bdcdfe09 | ||
|
|
8764f4cf96 | ||
|
|
3807038193 | ||
|
|
ee57f7fdae | ||
|
|
ddca41bd54 | ||
|
|
20b2d7cb6f | ||
|
|
cc7f8ee620 | ||
|
|
b0f7a26f1a | ||
|
|
ce861c9f33 | ||
|
|
eda596a3f9 | ||
|
|
897d4b58a1 | ||
|
|
f988c63003 | ||
|
|
ab706f9969 | ||
|
|
99576ac483 | ||
|
|
d5a3739105 | ||
|
|
0611c43b97 | ||
|
|
2694b5f378 | ||
|
|
6c28524e0f | ||
|
|
912f609403 | ||
|
|
e5710ccc5d | ||
|
|
3e5b632559 | ||
|
|
542086dd45 | ||
|
|
0162271725 | ||
|
|
327a779a81 | ||
|
|
7623c94ddc | ||
|
|
b8e42ae13c | ||
|
|
ed2d67b6d7 | ||
|
|
061b6ab3aa | ||
|
|
00d8e85373 | ||
|
|
2115c4a3ad | ||
|
|
858dcee5f1 | ||
|
|
6599677b98 | ||
|
|
93feffad15 | ||
|
|
234d967bed | ||
|
|
38b2c97fd6 | ||
|
|
4ba52a9e82 | ||
|
|
296531ad00 | ||
|
|
69e272dad7 | ||
|
|
4a9f618d9f | ||
|
|
5249cccfcf | ||
|
|
1298dbdf01 | ||
|
|
af018f7e4f | ||
|
|
1cb55cebf9 | ||
|
|
12372298a2 | ||
|
|
b97d10a839 | ||
|
|
bb4ea8bb3e | ||
|
|
a08802016d | ||
|
|
fc74574df0 | ||
|
|
82de39b7d5 | ||
|
|
95a2151d19 | ||
|
|
44b6696279 | ||
|
|
2f165ee12b | ||
|
|
6da11789ae | ||
|
|
4a3ceac2b5 | ||
|
|
4f400d2b85 | ||
|
|
471d6f0013 | ||
|
|
d6884defa7 | ||
|
|
132c7f1cf5 | ||
|
|
9aa206a90e | ||
|
|
884c179177 | ||
|
|
aa43405020 | ||
|
|
58cff195e7 | ||
|
|
a87298e501 | ||
|
|
534842b694 | ||
|
|
47715fd1f7 | ||
|
|
855b705980 | ||
|
|
29edc86721 | ||
|
|
15dccc3746 | ||
|
|
61790c98e8 | ||
|
|
438f9e585d | ||
|
|
a0cdb1ea45 | ||
|
|
728816e87b | ||
|
|
1a1504914a | ||
|
|
ea1200111d | ||
|
|
6cec60a454 | ||
|
|
ddd3ade023 | ||
|
|
fe7fed590a | ||
|
|
86c05655d4 | ||
|
|
be96a25dad | ||
|
|
71f287c9c0 | ||
|
|
63c61500b8 | ||
|
|
195b8bfe93 | ||
|
|
6bd911d7db | ||
|
|
cb3d200f58 | ||
|
|
aa5f8ba542 | ||
|
|
1061f43a2f | ||
|
|
3a9c5ef687 | ||
|
|
75e63ebb24 | ||
|
|
beb1aa5988 | ||
|
|
057407a39f | ||
|
|
a84fd1c44a | ||
|
|
b789ef5e8e | ||
|
|
df5606afe0 | ||
|
|
9549746453 | ||
|
|
739cd61024 | ||
|
|
763f33424e | ||
|
|
49849190dd | ||
|
|
9f01797eac | ||
|
|
6de1cb2d59 | ||
|
|
fc18c1ba6e | ||
|
|
6a850b0264 | ||
|
|
cf0e852fcd | ||
|
|
c9a740fccd | ||
|
|
328b951019 | ||
|
|
316dfb93d7 | ||
|
|
bf71e28d6b | ||
|
|
12efec7a48 | ||
|
|
12770d5407 | ||
|
|
683e58066e | ||
|
|
b30ad057a5 | ||
|
|
005407338d | ||
|
|
1b4d9b26cb | ||
|
|
f5195cc4e7 | ||
|
|
3992e5dfca | ||
|
|
c9873ea06c | ||
|
|
856c58aa9c | ||
|
|
35fd083828 | ||
|
|
ba07000b88 | ||
|
|
1aae5981a7 | ||
|
|
222b8c6e02 | ||
|
|
7f398f833e | ||
|
|
9a1978b2ee | ||
|
|
9ec9bff4c1 | ||
|
|
cecbd8864e | ||
|
|
68e331851a | ||
|
|
0509532d70 | ||
|
|
f1b5198b35 | ||
|
|
ac927e39bf | ||
|
|
0a9919fa2e | ||
|
|
681e829793 | ||
|
|
6c19067362 | ||
|
|
5f00c3cf20 | ||
|
|
dd67b32acd | ||
|
|
c7ab8ea513 | ||
|
|
dc475728e0 | ||
|
|
580e925011 | ||
|
|
fde0f40e87 | ||
|
|
9d0d2443fb | ||
|
|
082ea0de12 | ||
|
|
c4b935adf7 | ||
|
|
8894a4b0d2 | ||
|
|
d77a924434 | ||
|
|
494d408583 | ||
|
|
b0797e8fe9 | ||
|
|
ae64f29930 | ||
|
|
c8f49be919 | ||
|
|
db79db8444 | ||
|
|
af83cac9b8 | ||
|
|
2d369a39dd | ||
|
|
5de277e423 | ||
|
|
00a08af9f6 | ||
|
|
88503a12c2 | ||
|
|
62ab8441a6 | ||
|
|
b8d498da15 | ||
|
|
191ac00af2 | ||
|
|
3bb217d5e9 | ||
|
|
b0f8e03f17 | ||
|
|
efc5ac17bf | ||
|
|
dbff29c81d | ||
|
|
266ce242c3 | ||
|
|
ed3187b41a | ||
|
|
7af15f2d6e | ||
|
|
353686e636 | ||
|
|
13f3b55881 | ||
|
|
d57e1aa599 | ||
|
|
add7c2955d | ||
|
|
39a69aeb89 | ||
|
|
694654e383 | ||
|
|
04caddb7c8 | ||
|
|
a5183a761c | ||
|
|
71335183ec | ||
|
|
3e1115569e | ||
|
|
134c3e148c | ||
|
|
6a55fa6793 | ||
|
|
0c7978cf9c | ||
|
|
11d2f723d5 | ||
|
|
42fa7cbbf9 | ||
|
|
61ba810752 | ||
|
|
e366c1a9c6 | ||
|
|
570826448a | ||
|
|
ead525e17a | ||
|
|
3ad7b9419e | ||
|
|
2d363c39b9 | ||
|
|
ddd873902a | ||
|
|
c686e270a1 | ||
|
|
303096bcb2 | ||
|
|
4d62b90f88 | ||
|
|
f5144077ac | ||
|
|
462e6f281a | ||
|
|
c89b162462 | ||
|
|
fd2ead5080 | ||
|
|
33c03c4d0a | ||
|
|
792844f873 | ||
|
|
c181ae87ce | ||
|
|
65321f081d | ||
|
|
56644b8abc | ||
|
|
d3c4ba3ab8 | ||
|
|
75791f4dd9 | ||
|
|
445f8bd29a | ||
|
|
beab54506e | ||
|
|
5895d6c24f | ||
|
|
df9639d755 | ||
|
|
3fc3bf70f9 | ||
|
|
74b846e2f7 | ||
|
|
f3a7849ba6 | ||
|
|
971e8456fc | ||
|
|
8be9c49fcd | ||
|
|
ddc9733446 | ||
|
|
53b5227270 | ||
|
|
58e826e6f2 | ||
|
|
9af505a796 | ||
|
|
8fd274ea3b | ||
|
|
c2cb85851f | ||
|
|
dc2ebae8cf | ||
|
|
e66049c31b | ||
|
|
cf2d0b882a | ||
|
|
d4a874f726 | ||
|
|
554cd7c490 | ||
|
|
20e2d74440 | ||
|
|
47e92b2f88 | ||
|
|
ba4654b729 | ||
|
|
c3a0721d09 | ||
|
|
086b37a830 | ||
|
|
402f85f7f2 | ||
|
|
0d8a62c08d | ||
|
|
11a7a8b30b | ||
|
|
fcde6207a1 | ||
|
|
edd36a3afc | ||
|
|
cb54c2dda8 | ||
|
|
1e649f353b | ||
|
|
bc0abebe8e | ||
|
|
6f86affef5 | ||
|
|
cd7ec016e7 | ||
|
|
f806e268c6 | ||
|
|
a790f2133b | ||
|
|
28eac7dfb3 | ||
|
|
974250b60c | ||
|
|
a9cb2dc1b8 | ||
|
|
94b4a80d45 | ||
|
|
acbf5e826a | ||
|
|
45365ad99f | ||
|
|
74e3a29606 | ||
|
|
c8a7140c73 | ||
|
|
92658864ae | ||
|
|
e49abd2fa2 | ||
|
|
d69b39512d | ||
|
|
f05206f899 | ||
|
|
fb022db423 | ||
|
|
7cec294d08 | ||
|
|
c5e66dde33 | ||
|
|
216e8320b0 | ||
|
|
67704e2977 | ||
|
|
4579cce768 | ||
|
|
2508f38a92 | ||
|
|
adfb71b79e | ||
|
|
062d39fad2 | ||
|
|
4b506525da | ||
|
|
31ce3fcf9d | ||
|
|
8f75588615 | ||
|
|
6bbcb861fa | ||
|
|
b018c7d936 | ||
|
|
8cebec6262 | ||
|
|
ab81af477c | ||
|
|
75298d9f0a | ||
|
|
76963781df | ||
|
|
c890b8942d | ||
|
|
8b245c4d4b | ||
|
|
3e6ed76935 | ||
|
|
4246b5fbf0 | ||
|
|
a82be4348e | ||
|
|
f9271c2ca2 | ||
|
|
fe3c445112 | ||
|
|
00f735d5cb | ||
|
|
acb51c9243 | ||
|
|
380fa71fc7 | ||
|
|
04bc16f6ea | ||
|
|
006c2f66e1 | ||
|
|
be2f2ff033 | ||
|
|
0da9638576 | ||
|
|
30f2db5930 | ||
|
|
e437ecf729 | ||
|
|
cd85379423 | ||
|
|
3ffabe26af | ||
|
|
6704e39fcb | ||
|
|
68b189351c | ||
|
|
cd973fd30f | ||
|
|
04cdc205bc | ||
|
|
11dad6d44b | ||
|
|
36586dd7b7 | ||
|
|
87ce0c3b8d | ||
|
|
d5f1b1638c | ||
|
|
b644fe3da6 | ||
|
|
1ef239a499 | ||
|
|
92720fcc0e | ||
|
|
19a7534573 | ||
|
|
12a6f73a2f | ||
|
|
7df6539a87 | ||
|
|
2827295703 | ||
|
|
c7da4ba744 | ||
|
|
689a25003f | ||
|
|
8fe4790ec8 | ||
|
|
cdf4b7d2ee | ||
|
|
e978511d63 | ||
|
|
abe47a4840 | ||
|
|
c6db8f6a8b | ||
|
|
b27f65a758 |
No files matched your search
+7
-2
@@ -14,9 +14,14 @@
|
||||
/tags
|
||||
/TAGS
|
||||
/video/out/gl_video_shaders.h
|
||||
/video/out/vdpau_template.c
|
||||
/video/out/x11_icon.inc
|
||||
/demux/ebml_defs.c
|
||||
/demux/ebml_types.h
|
||||
/sub/osd_font.h
|
||||
/mpvcore/lua/*.inc
|
||||
/DOCS/man/*/mpv.1
|
||||
|
||||
/DOCS/man/*/mpv.aux
|
||||
/DOCS/man/*/mpv.log
|
||||
/DOCS/man/*/mpv.out
|
||||
/DOCS/man/*/mpv.pdf
|
||||
/DOCS/man/*/mpv.toc
|
||||
@@ -1,35 +1,19 @@
|
||||
mpv is a fork of mplayer2, which is a fork of MPlayer.
|
||||
Original MPlayer Copyright file follows below.
|
||||
|
||||
MPlayer was originally written by Árpád Gereöffy and has been extended and
|
||||
worked on by many more since then, see the AUTHORS file for an (incomplete)
|
||||
list. MPlayer as a whole is copyrighted by the MPlayer team. Individual
|
||||
copyright notices can be found in file headers.
|
||||
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+, 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. Files without Copyright notice are licensed as LGPLv2+.
|
||||
|
||||
Most files in MPlayer are licensed under the GNU General Public License,
|
||||
version 2 with an explicit "or later" clause or a compatible license
|
||||
(LGPL 2.1+, MIT/BSD). An exception are the files talloc.c and talloc.h,
|
||||
which are LGPL 3+.
|
||||
Thus MPlayer as a whole can be redistributed under terms compatible with
|
||||
the GNU General Public License, version 3; see the LICENSE file for details.
|
||||
For information about authors and contributors, consult the git log, which
|
||||
contains the complete SVN and CVS history as well.
|
||||
|
||||
MPlayer includes code from several external sources. General information and
|
||||
license details are listed below:
|
||||
Note that mplayer2 as a whole is licensed under GPLv3+. This is because it uses
|
||||
a copy of talloc (part of Samba), which is LGPLv3+, and the next compatible
|
||||
license for this mix is GPLv3+.
|
||||
|
||||
Name: a couple of files copied from FFmpeg
|
||||
Version: updated to different versions
|
||||
URL: http://www.ffmpeg.org
|
||||
Directory: compat/x86_cpu.h
|
||||
Copyright: Many, see individual files for copyright notices.
|
||||
License: GNU Lesser General Public License
|
||||
|
||||
|
||||
Name: dvbstream
|
||||
Version: 0.4.3-pre3 (CVS checkout)
|
||||
URL: http://sourceforge.net/projects/dvbtools/
|
||||
Directory: stream/dvbin.h stream/stream_dvb.c
|
||||
Copyright: 2001-2002 Dave Chapman <dave@dchapman.com>
|
||||
License: GNU General Public License
|
||||
|
||||
|
||||
This is not a complete list. grep the sources for "Copyright".
|
||||
MPlayer as a whole is licensed under GPLv2 (incompatible to GPLv3!), because
|
||||
some files are licensed to GPLv2 (and _not_ any later version of the license).
|
||||
In particular, this affects the file libmpdemux/demux_ty_osd.c. It is disabled
|
||||
under mplayer2, and has been removed from mpv.
|
||||
@@ -5,9 +5,10 @@ http://mingw-w64.sourceforge.net.
|
||||
You have to run mpv's configure with these arguments:
|
||||
./configure --enable-cross-compile --target=i686-w64-mingw32
|
||||
|
||||
Using MXE to setup a MinGW-w64 environment is recommended: http://mxe.cc
|
||||
Currently, using an experimental branch of MXE is required:
|
||||
https://github.com/tonytheodore/mxe.git
|
||||
Using mingw-w64-cmake to setup a MinGW-w64 environment is recommended (this will
|
||||
also build mpv and its dependencies): https://github.com/lachs0r/mingw-w64-cmake
|
||||
|
||||
Alternatively, use MXE: http://mxe.cc
|
||||
|
||||
Warning: the original MinGW (http://www.mingw.org) is unsupported.
|
||||
|
||||
@@ -18,11 +19,10 @@ Example with MXE
|
||||
================
|
||||
|
||||
# Download MXE. Note that compiling the required packages requires about 1 GB
|
||||
# or more! We are using an experimental repository, which supports MinGW-w64.
|
||||
# The official MXE supports classic MinGW only, which doesn't work with mpv.
|
||||
# or more!
|
||||
|
||||
cd /opt
|
||||
git clone https://github.com/tonytheodore/mxe.git mingw
|
||||
git clone https://github.com/mxe/mxe
|
||||
cd mingw
|
||||
|
||||
# Edit the MXE target, so that MinGW-w64 for 32 bit targets is built.
|
||||
@@ -38,11 +38,6 @@ make libass
|
||||
make jpeg
|
||||
make pthreads
|
||||
|
||||
# Older MXE and MinGW-w64 snapshots don't provide up-to-date OpenGL headers.
|
||||
|
||||
wget http://www.opengl.org/registry/api/glext.h
|
||||
mv glext.h usr/i686-w64-mingw32/include/GL/
|
||||
|
||||
# Build mpv. The target will be used to automatically select the name of the
|
||||
# build tools involved (e.g. it will use i686-w64-mingw32-gcc).
|
||||
|
||||
@@ -52,9 +47,6 @@ export PATH=/opt/mingw/usr/bin/:$PATH
|
||||
./configure --enable-cross-compile --target=i686-w64-mingw32
|
||||
make
|
||||
|
||||
# This should work. For some reason, the resulting .exe will depend on the DLL
|
||||
# /opt/mingw/usr/i686-w64-mingw32/bin/libwinpthread-1.dll because pthreads-w32
|
||||
# folks don't like static linking. How to enable static linking is left as
|
||||
# exercise to the reader. Passsing --disable-pthreads to mpv's configure will
|
||||
# get rid of the dependency, but may disable some features (such as the stream
|
||||
# cache).
|
||||
# This should work. Note however that MXE’s ffmpeg package might be very old
|
||||
# in order to avoid breaking e.g. xine-lib, so you might want to update that
|
||||
# or build it manually as well.
|
||||
@@ -0,0 +1,20 @@
|
||||
[latex2e writer]
|
||||
use-latex-docinfo: yes
|
||||
use-latex-toc: yes
|
||||
hyperlink-color: Blue!30!RoyalPurple!70!Black
|
||||
latex-preamble: \usepackage[usenames,dvipsnames]{xcolor}
|
||||
\usepackage{fullpage}
|
||||
\usepackage{graphicx}
|
||||
\renewcommand{\familydefault}{\sfdefault}
|
||||
|
||||
\makeatletter
|
||||
\renewcommand{\maketitle}{
|
||||
\begin{center}
|
||||
\includegraphics{etc/mpv-icon-8bit-64x64.png}\\
|
||||
\vspace*{-1.5em}
|
||||
\begin{Huge}
|
||||
\@title
|
||||
\end{Huge}
|
||||
\end{center}
|
||||
}
|
||||
\makeatother
|
||||
+6
-6
@@ -313,12 +313,12 @@ Available filters are:
|
||||
channels 0 and 1 into output channel 2 (which could be sent to a
|
||||
subwoofer for example).
|
||||
|
||||
.. note::
|
||||
.. note::
|
||||
|
||||
If you just want to force remixing to a certain output channel
|
||||
layout, it is easier to use the ``force`` filter. For example,
|
||||
``mpv '--af=force=channels=5.1' '--channels=5.1'`` would always
|
||||
force remixing audio to 5.1 and output it like this.
|
||||
If you just want to force remixing to a certain output channel layout,
|
||||
it is easier to use the ``force`` filter. For example,
|
||||
``mpv '--af=force=channels=5.1' '--channels=5.1'`` would always force
|
||||
remixing audio to 5.1 and output it like this.
|
||||
|
||||
``sub[=fc:ch]``
|
||||
Adds a subwoofer channel to the audio stream. The audio data used for
|
||||
@@ -438,7 +438,7 @@ Available filters are:
|
||||
|
||||
``drc[=method:target]``
|
||||
Applies dynamic range compression. This maximizes the volume by compressing
|
||||
the audio signal's dynamic range.
|
||||
the audio signal's dynamic range. (Formerly called ``volnorm``.)
|
||||
|
||||
``<method>``
|
||||
Sets the used method.
|
||||
|
||||
+16
-3
@@ -17,8 +17,8 @@ in the list. Suboptions are optional and can mostly be omitted.
|
||||
.. admonition:: Examples
|
||||
|
||||
- ``--ao=alsa,oss,`` Try the ALSA driver, then the OSS driver, then others.
|
||||
- ``--ao=alsa:noblock:device=hw=0.3`` Sets noblock-mode and the device-name
|
||||
as first card, fourth device.
|
||||
- ``--ao=alsa:no-block:device=[hw:0,3]`` Sets noblock-mode and the
|
||||
device-name as first card, fourth device.
|
||||
|
||||
Available audio output drivers are:
|
||||
|
||||
@@ -36,7 +36,7 @@ Available audio output drivers are:
|
||||
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
|
||||
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.
|
||||
|
||||
@@ -48,6 +48,10 @@ Available audio output drivers are:
|
||||
|
||||
``--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.
|
||||
|
||||
``oss``
|
||||
OSS audio output driver
|
||||
|
||||
@@ -170,6 +174,15 @@ Available audio output drivers are:
|
||||
Set the TCP port used for connecting to the server (default: 12345).
|
||||
Not used if connecting to a Unix domain socket.
|
||||
|
||||
``sndio``
|
||||
Audio output to the OpenBSD sndio sound system
|
||||
|
||||
(Note: only supports mono, stereo, 4.0, 5.1 and 7.1 channel
|
||||
layouts.)
|
||||
|
||||
``device=<device>``
|
||||
sndio device to use (default: ``$AUDIODEVICE``, resp. ``snd0``).
|
||||
|
||||
``wasapi``
|
||||
Audio output to the Windows Audio Session API.
|
||||
|
||||
|
||||
+48
-8
@@ -27,7 +27,8 @@ General Changes for MPlayer to mplayer2
|
||||
* Use libass for subtitle rendering by default (better quality)
|
||||
* Generally preferring ffmpeg/libav over internal demuxers and decoders
|
||||
* Improvements when playing multiple files (``--fixed-vo``)
|
||||
* Screenshot improvements (instant screenshots without 1-frame delay)
|
||||
* Screenshot improvements (instant screenshots without 1-frame delay, allow
|
||||
taking screenshots even with hardware decoding)
|
||||
* Improved support for PulseAudio
|
||||
* General code cleanups
|
||||
* Many more changes
|
||||
@@ -35,6 +36,7 @@ General Changes for MPlayer to mplayer2
|
||||
General Changes for mplayer2 to mpv
|
||||
-----------------------------------
|
||||
|
||||
* Switch back to GPLv2+.
|
||||
* Removal of lots of unneeded code to encourage developer activity (less
|
||||
obscure scary zombie code that kills any desire for hacking the codebase)
|
||||
* Removal of dust and dead bodies (code-wise), such as kernel drivers for
|
||||
@@ -55,6 +57,9 @@ General Changes for mplayer2 to mpv
|
||||
``screenshot`` video filter is not needed anymore, and should not be put
|
||||
into the mpv config file)
|
||||
* Removal of teletext support
|
||||
* Removal of most builtin demuxers, using libavformat instead
|
||||
* Removal of builtin network support, using libavformat instead (also,
|
||||
support https via libavformat)
|
||||
* Replace image VOs (``--vo=jpeg`` etc.) with ``--vo=image``
|
||||
* Do not lose settings when playing a new file in the same player instance
|
||||
* New location for config files, new name for the binary.
|
||||
@@ -68,7 +73,38 @@ General Changes for mplayer2 to mpv
|
||||
* Wayland support
|
||||
* Support for precise scrolling which scales the parameter of commands. If the
|
||||
input doesn't support precise scrolling the scale factor stays 1.
|
||||
* General code cleanups
|
||||
* OSX: Cocoa event loop is independent from mplayer's event loop, so user
|
||||
actions like accessing menus and live resizing do not block the playback.
|
||||
* OSX: Apple Remote support.
|
||||
* OSX: Media Keys support.
|
||||
* Windows: Added WASAPI audio output.
|
||||
* New OSD bar with chapter marks and not positioned in the middle of the video
|
||||
(though this can be customized with the ``--osd-bar-align-y`` option).
|
||||
* Allow customizing whether a key binding for seeking shows the video time, the
|
||||
OSD bar, or nothing (see section `Input Command Prefixes`_).
|
||||
* Display list of chapters and audio/subtitle tracks on OSD (see section
|
||||
`Properties`_).
|
||||
* ``--keep-open`` option to stop the player from closing the window and
|
||||
exiting after playback ends.
|
||||
* Re-enable screensaver while the player is paused.
|
||||
* Matroska edition switching at runtime.
|
||||
* Support for libavfilter (for video->video and audio->audio). This allows
|
||||
using most of FFmpeg's filters, which improve greatly on the old MPlayer
|
||||
filters in features, performance, and correctness.
|
||||
* Improved downmixing and output of surround audio. Instead of using hardcoded
|
||||
pan filters to do remixing, use libavresample. Channel maps are used to
|
||||
identify the channel layout, so e.g. ``3.0`` and ``2.1`` audio can be
|
||||
distinguished.
|
||||
* Allow resuming playback at a later point with ``Shift+q``, also see
|
||||
``quit_watch_later`` input command.
|
||||
* Support mapping multiple commands to one key.
|
||||
* Allow changing/adjusting video filters at runtime. (This is also used to make
|
||||
the ``D`` key insert vf_yadif if deinterlacing is not supported otherwise.)
|
||||
* Native VAAPI support
|
||||
* OSX: VDA support using libavcodec hwaccel API insted of FFmpeg's decoder. Up
|
||||
to 2-2.5x reduction in CPU usage.
|
||||
* General bug fixes and removal of long-standing issues
|
||||
* General code cleanups (including refactoring or rewrites of many parts)
|
||||
* Many more changes
|
||||
|
||||
Detailed Listing of User-visible Changes
|
||||
@@ -111,7 +147,7 @@ Command Line Switches
|
||||
``-xineramascreen`` ``--screen`` (different values)
|
||||
``-ss`` ``--start``
|
||||
``-endpos`` ``--length``
|
||||
``--cursor-autohide-delay`` ``--cursor-autohide``
|
||||
``-cursor-autohide-delay`` ``--cursor-autohide``
|
||||
``-sub-fuzziness`` ``--autosub-match``
|
||||
``-subfont`` ``--sub-text-font``
|
||||
``-font`` ``--osd-font``
|
||||
@@ -134,8 +170,12 @@ Command Line Switches
|
||||
``-lavfdopts`` ``--demuxer-lavf-...``
|
||||
``-rawaudio ...`` ``--demuxer-rawaudio-...``
|
||||
``-rawvideo ...`` ``--demuxer-rawvideo-...``
|
||||
``--mixer`` AO suboptions (``alsa``, ``oss``)
|
||||
``--mixer-channel`` AO suboptions (``alsa``, ``oss``)
|
||||
``-mixer`` AO suboptions (``alsa``, ``oss``)
|
||||
``-mixer-channel`` AO suboptions (``alsa``, ``oss``)
|
||||
``-ao alsa:device=hw=0.3`` ``--ao=alsa:device=[hw:0,3]``
|
||||
``-af volnorm`` ``--af=drc`` (renamed)
|
||||
``-zoom`` Inverse available as ``--video-unscaled``
|
||||
``-panscanrange`` ``--video-zoom``, ``--video-pan-x/y``
|
||||
=========================== ========================================
|
||||
|
||||
.. note::
|
||||
@@ -149,8 +189,8 @@ input.conf and Slave Commands
|
||||
|
||||
This lists only commands that are not always gracefully handled by the
|
||||
internal legacy translation layer. If an input.conf contains any legacy
|
||||
commands, they will be displayed with ``-v`` when it is loaded, and show
|
||||
and the replacement commands.
|
||||
commands, a warning will be printed when starting the player. The warnings
|
||||
also show the replacement commands.
|
||||
|
||||
Properties containing ``_`` to separate words use ``-`` instead.
|
||||
|
||||
@@ -189,7 +229,7 @@ input.conf and Slave Commands
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``show_chapters`` | ``show_text ${chapter-list}`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
| ``af_switch``, ``af_add``, ... | ``af [set|add|...]`` |
|
||||
| ``af_switch``, ``af_add``, ... | ``af set|add|...`` |
|
||||
+--------------------------------+----------------------------------------+
|
||||
|
||||
Other
|
||||
|
||||
+112
-8
@@ -35,7 +35,7 @@ Newlines always start a new binding. ``#`` starts a comment (outside of quoted
|
||||
string arguments). To bind commands to the ``#`` key, ``SHARP`` can be used.
|
||||
|
||||
``<key>`` is either the literal character the key produces (ASCII or Unicode
|
||||
character), or a symbol name.
|
||||
character), or a symbolic name (as printed by ``--input-keylist``).
|
||||
|
||||
``<section>`` (braced with ``{`` and ``}``) is the input section for this
|
||||
command.
|
||||
@@ -226,6 +226,15 @@ List of Input Commands
|
||||
``<skip>`` subtitle events is displayed. ``<skip>`` can be negative to step
|
||||
backwards.
|
||||
|
||||
``sub_seek <skip>``
|
||||
Seek to the next (skip set to 1) or the previous (skip set to -1) subtitle.
|
||||
This is similar to ``sub_step``, except that it seeks video and audio
|
||||
instead of adjusting the subtitle delay.
|
||||
|
||||
Like with ``sub_step``, this works with external text subtitles only. For
|
||||
embedded text subtitles (like with Matroska), this works only with subtitle
|
||||
events that have already been displayed.
|
||||
|
||||
``osd [<level>]``
|
||||
Toggle OSD level. If ``<level>`` is specified, set the OSD mode
|
||||
(see ``--osd-level`` for valid values).
|
||||
@@ -316,6 +325,77 @@ Input Commands that are Possibly Subject to Change
|
||||
``disable_section "<section>"``
|
||||
Disable the named input section. Undoes ``enable_section``.
|
||||
|
||||
``overlay_add <id> <x> <y> "<file>" <offset> "<fmt>" <w> <h> <stride>``
|
||||
Add an OSD overlay sourced from raw data. This might be useful for scripts
|
||||
and applications controlling mpv, and which want to display things on top
|
||||
of the video window.
|
||||
|
||||
Overlays are usually displayed in screen resolution, but with some VOs,
|
||||
the resolution is reduced to that of the video's. You can read the
|
||||
``osd-width`` and ``osd-height`` properties. At least with ``--vo-xv`` and
|
||||
anamorphic video (such as DVD), ``osd-par`` should be read as well, and the
|
||||
overlay should be aspect-compensated. (Future directions: maybe mpv should
|
||||
take care of some of these things automatically, but it's hard to tell
|
||||
where to draw the line.)
|
||||
|
||||
``id`` is an integer between 0 and 63 identifying the overlay element. The
|
||||
ID can be used to add multiple overlay parts, update a part by using this
|
||||
command with an already existing ID, or to remove a part with
|
||||
``overlay_remove``. Using a previously unused ID will add a new overlay,
|
||||
while reusing an ID will update it. (Future directions: there should be
|
||||
something to ensure different programs wanting to create overlays don't
|
||||
conflict with each others, should that ever be needed.)
|
||||
|
||||
``x`` and ``y`` specify the position where the OSD should be displayed.
|
||||
|
||||
``file`` specifies the file the raw image data is read from. It can be
|
||||
either a numeric UNIX file descriptor prefixed with ``@`` (e.g. ``@4``),
|
||||
or a filename. The file will be mapped into memory with ``mmap()``. Some VOs
|
||||
will pass the mapped pointer directly to display APIs (e.g. opengl or
|
||||
vdpau), so no actual copying is involved. Truncating the source file while
|
||||
the overlay is active will crash the player. You shouldn't change the data
|
||||
while the overlay is active, because the data is essentially accessed at
|
||||
random points. Instead, call ``overlay_add`` again (preferably with a
|
||||
different memory region to prevent tearing).
|
||||
|
||||
``offset`` is the offset of the first pixel in the source file. It is
|
||||
passed directly to ``mmap`` and is subject to certain restrictions
|
||||
(see ``man mmap`` for details). In particular, this value has to be a
|
||||
multiple of the system's page size.
|
||||
|
||||
``fmt`` is a string identifying the image format. Currently, only ``bgra``
|
||||
is defined. This format has 4 bytes per pixels, with 8 bits per component.
|
||||
The least significant 8 bits are blue, and the most significant 8 bits
|
||||
are alpha (in little endian, the components are B-G-R-A, with B as first
|
||||
byte). This uses premultiplied alpha: every color component is already
|
||||
multiplied with the alpha component. This means the numeric value of each
|
||||
component is equal to or smaller than the alpha component. (Violating this
|
||||
rule will lead to different results with different VOs: numeric overflows
|
||||
resulting from blending broken alpha values is considered something that
|
||||
shouldn't happen, and consequently implementations don't ensure that you
|
||||
get predictable behavior in this case.)
|
||||
|
||||
``w``, ``h``, and ``stride`` specify the size of the overlay. ``w`` is the
|
||||
visible width of the overlay, while ``stride`` gives the width in bytes in
|
||||
memory. In the simple case, and with the ``bgra`` format, ``stride==4*w``.
|
||||
In general, the total amount of memory accessed is ``stride * h``.
|
||||
(Technically, the minimum size would be ``stride * (h - 1) + w * 4``, but
|
||||
for simplicity, the player will access all ``stride * h`` bytes.)
|
||||
|
||||
.. admonition:: Warning
|
||||
|
||||
When updating the overlay, you should prepare a second shared memory
|
||||
region (e.g. make use of the offset parameter) and add this as overlay,
|
||||
instead of reusing the same memory every time. Otherwise, you might
|
||||
get the equivalent of tearing, when your application and mpv write/read
|
||||
the buffer at the same time. Also, keep in mind that mpv might access
|
||||
an overlay's memory at random times whenever it feels the need to do
|
||||
so, for example when redrawing the screen.
|
||||
|
||||
``overlay_remove <id>``
|
||||
Remove an overlay added with ``overlay_add`` and the same ID. Does nothing
|
||||
if no overlay with this ID exists.
|
||||
|
||||
Undocumented commands: ``tv_start_scan``, ``tv_step_channel``, ``tv_step_norm``,
|
||||
``tv_step_chanlist``, ``tv_set_channel``, ``tv_last_channel``, ``tv_set_freq``,
|
||||
``tv_step_freq``, ``tv_set_norm``, ``dvb_set_channel``, ``radio_step_channel``,
|
||||
@@ -326,6 +406,9 @@ should be replaced by properties), ``stop`` (questionable use), ``get_property``
|
||||
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`` (default)
|
||||
Use the default behavior for this command.
|
||||
``no-osd``
|
||||
@@ -390,7 +473,7 @@ Name W Comment
|
||||
``speed`` x see ``--speed``
|
||||
``filename`` currently played file (path stripped)
|
||||
``path`` currently played file (full path)
|
||||
``media-title`` filename or libquvi ``QUVIPROP_PAGETITLE``
|
||||
``media-title`` filename, title tag, or libquvi ``QUVIPROP_PAGETITLE``
|
||||
``demuxer``
|
||||
``stream-path`` filename (full path) of stream layer filename
|
||||
``stream-pos`` x byte position in source stream
|
||||
@@ -412,6 +495,7 @@ Name W Comment
|
||||
``angle`` x current DVD angle
|
||||
``metadata`` metadata key/value pairs
|
||||
``metadata/<key>`` value of metadata entry ``<key>``
|
||||
``chapter-metadata`` metadata of current chapter (works similar)
|
||||
``pause`` x pause status (bool)
|
||||
``cache`` network cache fill state (0-100)
|
||||
``pts-association-mode`` x see ``--pts-association-mode``
|
||||
@@ -428,7 +512,7 @@ Name W Comment
|
||||
``audio`` x alias for ``aid``
|
||||
``balance`` x audio channel balance
|
||||
``fullscreen`` x see ``--fullscreen``
|
||||
``deinterlace`` x deinterlacing, if available (bool)
|
||||
``deinterlace`` x similar to ``--deinterlace``
|
||||
``colormatrix`` x see ``--colormatrix``
|
||||
``colormatrix-input-range`` x see ``--colormatrix-input-range``
|
||||
``colormatrix-output-range`` x see ``--colormatrix-output-range``
|
||||
@@ -450,14 +534,22 @@ Name W Comment
|
||||
``dwidth`` video width (after filters and aspect scaling)
|
||||
``dheight`` video height
|
||||
``aspect`` x video aspect
|
||||
``osd-width`` last known OSD width (can be 0)
|
||||
``osd-height`` last known OSD height (can be 0)
|
||||
``osd-par`` last known OSD display pixel aspect (can be 0)
|
||||
``vid`` x current video track (similar to ``--vid``)
|
||||
``video`` x alias for ``vid``
|
||||
``video-align-x`` x see ``--video-align-x``
|
||||
``video-align-y`` x see ``--video-align-y``
|
||||
``video-pan-x`` x see ``--video-pan-x``
|
||||
``video-pan-y`` x see ``--video-pan-y``
|
||||
``video-zoom`` x see ``--video-zoom``
|
||||
``program`` x switch TS program (write-only)
|
||||
``sid`` x current subtitle track (similar to ``--sid``)
|
||||
``sub`` x alias for ``sid``
|
||||
``sub-delay`` x see ``--sub-delay``
|
||||
``sub-pos`` x see ``--sub-pos``
|
||||
``sub-visibility`` x whether current subtitle is rendered
|
||||
``sub-visibility`` x see ``--sub-visibility``
|
||||
``sub-forced-only`` x see ``--sub-forced-only``
|
||||
``sub-scale`` x subtitle font size multiplicator
|
||||
``ass-use-margins`` x see ``--ass-use-margins``
|
||||
@@ -471,7 +563,7 @@ Name W Comment
|
||||
``playlist-pos`` current position on playlist
|
||||
``playlist-count`` number of total playlist entries
|
||||
``playlist`` playlist, current entry marked
|
||||
``track-list`` list of audio/video/sub tracks, cur. entr. marked
|
||||
``track-list`` list of audio/video/sub tracks, current entry marked
|
||||
``chapter-list`` list of chapters, current entry marked
|
||||
``quvi-format`` x see ``--quvi-format``
|
||||
``af`` x see ``--af``
|
||||
@@ -500,15 +592,27 @@ The following expansions are supported:
|
||||
fails, expand to an error string. (Use ``${NAME:}`` with a trailing
|
||||
``:`` to expand to an empty string instead.)
|
||||
If ``NAME`` is prefixed with ``=``, expand to the raw value of the property
|
||||
(see below).
|
||||
(see section below).
|
||||
``${NAME:STR}``
|
||||
Expands to the value of the property ``NAME``, or ``STR`` if the
|
||||
property cannot be retrieved. ``STR`` is expanded recursively.
|
||||
``${?NAME:STR}``
|
||||
Expands to ``STR`` (recursively) if the property ``NAME`` is available.
|
||||
``${!NAME:STR}``
|
||||
Expands to ``STR`` (recursively) if the property ``NAME`` cannot be
|
||||
retrieved.
|
||||
``${?NAME:STR}``
|
||||
Expands to ``STR`` (recursively) if the property ``NAME`` is available.
|
||||
``${?NAME==VALUE:STR}``
|
||||
Expands to ``STR`` (recursively) if the property ``NAME`` expands to a
|
||||
string equal to ``VALUE``. You can prefix ``NAME`` with ``=`` in order to
|
||||
compare the raw value of a property (see section below). If the property
|
||||
is unavailable, or other errors happen when retrieving it, the value is
|
||||
never considered equal.
|
||||
Note that ``VALUE`` can't contain any of the characters ``:`` or ``}``.
|
||||
Also, it is possible that escaping with ``"`` or ``%`` might be added in
|
||||
the future, should the need arise.
|
||||
``${!NAME==VALUE:STR}``
|
||||
Same as with the ``?`` variant, but ``STR`` is expanded if the value is
|
||||
not equal. (Using the same semantics as with ``?``.)
|
||||
``$$``
|
||||
Expands to ``$``.
|
||||
``$}``
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
LUA SCRIPTING
|
||||
=============
|
||||
|
||||
mpv can load Lua scripts. These scripts can be used to control mpv in a similar
|
||||
way to slave mode. mpv provides the builtin module ``mp`` (can be loaded
|
||||
with ``require 'mpv'``), which provides functions to send commands to the
|
||||
mpv core and to retrieve information about playback state, user settings,
|
||||
file information, and so on.
|
||||
|
||||
.. admonition:: Warning
|
||||
|
||||
Lua scripting is work in progress, and it's in a very early stage. When
|
||||
writing scripts, rely only on the features and functions documented here.
|
||||
Everything else is subject to change.
|
||||
|
||||
.. admonition:: Warning
|
||||
|
||||
Nothing is finished and documented yet.
|
||||
+22
-42
@@ -1,9 +1,3 @@
|
||||
..
|
||||
Hint: To generate a nicely formatted XeLaTeX document from this file, use
|
||||
rst2xetex --use-latex-docinfo --use-latex-toc --hyperlink-color=MidnightBlue --latex-preamble="\usepackage[usenames,dvipsnames]{xcolor}\usepackage{fullpage}\setmainfont{Droid Sans}\setsansfont{Linux Biolinum O}\setmonofont[HyphenChar=None]{DejaVu Sans Mono}" mpv.rst
|
||||
|
||||
You might want to put the .. contents:: directive below to generate a TOC.
|
||||
|
||||
mpv
|
||||
###
|
||||
|
||||
@@ -12,12 +6,15 @@ a movie player
|
||||
##############
|
||||
|
||||
:Author: wm4
|
||||
:Date: 2013-07-08
|
||||
:Copyright: GPLv3
|
||||
:Version: git
|
||||
:Copyright: GPLv2+
|
||||
:Manual section: 1
|
||||
:Manual group: multimedia
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\tableofcontents
|
||||
\pagebreak
|
||||
|
||||
SYNOPSIS
|
||||
========
|
||||
|
||||
@@ -34,7 +31,7 @@ SYNOPSIS
|
||||
| **mpv** \dvb://[card\_number@]channel [options]
|
||||
| **mpv** \mf://[filemask|\@listfile] [-mf options] [options]
|
||||
| **mpv** cdda://track[-endtrack][:speed][/device] [options]
|
||||
| **mpv** [file|mms[t]|http|httpproxy|rt[s]p|ftp|udp|smb]:// [user:pass\@]URL[:port] [options]
|
||||
| **mpv** [file|mms[t]|http|httpproxy|rt[s]p|ftp|udp|smb]://[user:pass\@]URL[:port] [options]
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
@@ -176,7 +173,9 @@ P
|
||||
Show progression bar, elapsed time and total duration on the OSD.
|
||||
|
||||
! and @
|
||||
Seek to the beginning of the previous/next chapter.
|
||||
Seek to the beginning of the previous/next chapter. In most cases,
|
||||
"previous" will actually go to the beginning of the current chapter; see
|
||||
``--chapter-seek-threshold``.
|
||||
|
||||
D (``--vo=vdpau``, ``--vf=yadif`` only)
|
||||
Activate/deactivate deinterlacer.
|
||||
@@ -202,8 +201,7 @@ corresponding adjustment, or the software equalizer (``--vf=eq``).)
|
||||
7 and 8
|
||||
Adjust saturation.
|
||||
|
||||
(The following keys are valid only when using the corevideo video output
|
||||
driver.)
|
||||
(The following keys are valid only on OSX.)
|
||||
|
||||
command + 0
|
||||
Resize movie window to half its original size.
|
||||
@@ -232,7 +230,7 @@ PREVIOUS and NEXT
|
||||
Seek backward/forward 1 minute.
|
||||
|
||||
(The following keys are only valid if you compiled with TV or DVB input
|
||||
support and will take precedence over the keys defined above.)
|
||||
support.)
|
||||
|
||||
h and k
|
||||
Select previous/next channel.
|
||||
@@ -252,24 +250,6 @@ button 3 and button 4
|
||||
button 5 and button 6
|
||||
Decrease/increase volume.
|
||||
|
||||
Joystick Control
|
||||
----------------
|
||||
|
||||
left and right
|
||||
Seek backward/forward 10 seconds.
|
||||
|
||||
up and down
|
||||
Seek forward/backward 1 minute.
|
||||
|
||||
button 1
|
||||
Pause.
|
||||
|
||||
button 2
|
||||
Toggle OSD states: none / seek / seek + timer / seek + timer + total time.
|
||||
|
||||
button 3 and button 4
|
||||
Decrease/increase volume.
|
||||
|
||||
|
||||
USAGE
|
||||
=====
|
||||
@@ -314,6 +294,8 @@ file1.mkv ``--a --b --c``
|
||||
file2.mkv ``--a --b --c``
|
||||
=============== ===========================
|
||||
|
||||
(This is different from MPlayer and mplayer2.)
|
||||
|
||||
Also, if any option is changed at runtime (via input commands), they are not
|
||||
reset when a new file is played.
|
||||
|
||||
@@ -408,7 +390,7 @@ profile name ``default`` to continue with normal options.
|
||||
::
|
||||
|
||||
[vo.vdpau]
|
||||
# Use hardware decoding (this might break playback of some h264 files)
|
||||
# Use hardware decoding (might break playback of some h264 files)
|
||||
hwdec=vdpau
|
||||
|
||||
[protocol.dvd]
|
||||
@@ -442,9 +424,6 @@ taking screenshots is handled by the VOs, and adding the screenshot filter will
|
||||
break hardware decoding. (The filter may still be useful for taking screenshots
|
||||
at a certain point within the video chain when using multiple video filters.)
|
||||
|
||||
OPTIONS
|
||||
=======
|
||||
|
||||
.. include:: options.rst
|
||||
|
||||
.. include:: ao.rst
|
||||
@@ -459,6 +438,10 @@ OPTIONS
|
||||
|
||||
.. include:: input.rst
|
||||
|
||||
.. include:: osc.rst
|
||||
|
||||
.. include:: lua.rst
|
||||
|
||||
.. include:: changes.rst
|
||||
|
||||
ENVIRONMENT VARIABLES
|
||||
@@ -498,7 +481,7 @@ behavior of mpv.
|
||||
|
||||
FFmpeg/Libav:
|
||||
This library accesses various environment variables. However, they are not
|
||||
centrally documented, and documenting them is not our job. Therefore, the
|
||||
centrally documented, and documenting them is not our job. Therefore, this
|
||||
list is incomplete.
|
||||
|
||||
Notable environment variables:
|
||||
@@ -601,13 +584,10 @@ FILES
|
||||
EXAMPLES OF MPV USAGE
|
||||
=====================
|
||||
|
||||
Quickstart Blu-ray playing:
|
||||
Blu-ray playback:
|
||||
- ``mpv bd:////path/to/disc``
|
||||
- ``mpv bd:// --bluray-device=/path/to/disc``
|
||||
|
||||
Quickstart DVD playing:
|
||||
``mpv dvd://1``
|
||||
|
||||
Play in Japanese with English subtitles:
|
||||
``mpv dvd://1 --alang=ja --slang=en``
|
||||
|
||||
@@ -643,6 +623,6 @@ mpv is a MPlayer fork based on mplayer2, which in turn is a fork of MPlayer.
|
||||
MPlayer was initially written by Arpad Gereoffy. See the ``AUTHORS`` file for
|
||||
a list of some of the many other contributors.
|
||||
|
||||
MPlayer is (C) 2000-2012 The MPlayer Team
|
||||
MPlayer is (C) 2000-2013 The MPlayer Team
|
||||
|
||||
This man page was written mainly by Gabucino, Jonas Jermann and Diego Biurrun.
|
||||
+305
-93
@@ -1,3 +1,6 @@
|
||||
OPTIONS
|
||||
=======
|
||||
|
||||
``--ad=<[+|-]family1:(*|decoder1),[+|-]family2:(*|decoder2),...[-]>``
|
||||
Specify a priority list of audio decoders to be used, according to their
|
||||
family and decoder name. Entries like ``family:*`` prioritize all decoders
|
||||
@@ -69,8 +72,7 @@
|
||||
Specify a priority list of audio languages to use. Different container
|
||||
formats employ different language codes. DVDs use ISO 639-1 two-letter
|
||||
language codes, Matroska, MPEG-TS and NUT use ISO 639-2 three-letter
|
||||
language codes, while OGM uses a free-form identifier. mpv prints the
|
||||
available languages when run in verbose (``-v``) mode. See also ``--aid``.
|
||||
language codes, while OGM uses a free-form identifier. See also ``--aid``.
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
@@ -123,19 +125,33 @@
|
||||
|
||||
Using this option may lead to incorrect subtitle rendering.
|
||||
|
||||
``--ass-hinting=<type>``
|
||||
``--ass-hinting=none|light|normal|native``
|
||||
Set font hinting type. <type> can be:
|
||||
|
||||
:0: no hinting
|
||||
:1: FreeType autohinter, light mode
|
||||
:2: FreeType autohinter, normal mode
|
||||
:3: font native hinter
|
||||
:none: no hinting (default)
|
||||
:light: FreeType autohinter, light mode
|
||||
:normal: FreeType autohinter, normal mode
|
||||
:native: font native hinter
|
||||
|
||||
The default value is 0 (no hinting).
|
||||
.. admonition:: Warning
|
||||
|
||||
Enabling hinting can lead to mispositioned text (in situations it's
|
||||
supposed to match up with video background), or reduce the smoothness
|
||||
of animations with some badly authored ASS scripts. It is recommended
|
||||
to not use this option, unless really needed.
|
||||
|
||||
``--ass-line-spacing=<value>``
|
||||
Set line spacing value for SSA/ASS renderer.
|
||||
|
||||
``--ass-shaper=simple|complex``
|
||||
Set the text layout engine used by libass.
|
||||
|
||||
:simple: uses Fribidi only, fast, doesn't render some languages correctly
|
||||
:complex: uses HarfBuzz, slower, wider language support
|
||||
|
||||
``complex`` is the default. If libass hasn't been compiled against HarfBuzz,
|
||||
libass silently reverts to ``simple``.
|
||||
|
||||
``--ass-styles=<filename>``
|
||||
Load all SSA/ASS styles found in the specified file and use them for
|
||||
rendering text subtitles. The syntax of the file is exactly like the ``[V4
|
||||
@@ -183,7 +199,7 @@
|
||||
offset scale factor, not what the video filter chain or the video output
|
||||
use.
|
||||
|
||||
``--ass-vsfilter-color-compat=<basic|full|force-601|no``
|
||||
``--ass-vsfilter-color-compat=<basic|full|force-601|no>``
|
||||
Mangle colors like (xy-)vsfilter do (default: basic). Historically, VSFilter
|
||||
was not colorspace aware. This was no problem as long as the colorspace
|
||||
used for SD video (BT.601) was used. But when everything switched to HD
|
||||
@@ -249,8 +265,8 @@
|
||||
See ``--geometry`` for details how this is handled with multi-monitor
|
||||
setups.
|
||||
|
||||
Use ``--autofit-larger`` instead if you do not want the window to get
|
||||
larger.
|
||||
Use ``--autofit-larger`` instead if you just want to limit the maximum size
|
||||
of the window, rather than always forcing a window size.
|
||||
|
||||
Use ``--geometry`` if you want to force both window width and height to a
|
||||
specific size.
|
||||
@@ -307,17 +323,6 @@
|
||||
out. This delay in reaction time to sudden A/V offsets should be the only
|
||||
side-effect of turning this option on, for all sound drivers.
|
||||
|
||||
``--bandwidth=<bytes>``
|
||||
Specify the maximum bandwidth for network streaming (for servers that are
|
||||
able to send content in different bitrates). Useful if you want to watch
|
||||
live streamed media behind a slow connection. With Real RTSP streaming, it
|
||||
is also used to set the maximum delivery bandwidth allowing faster cache
|
||||
filling and stream dumping.
|
||||
|
||||
.. note::
|
||||
|
||||
Probably broken/useless.
|
||||
|
||||
``--untimed``
|
||||
Do not sleep when outputting video frames. Useful for benchmarks when used
|
||||
with ``--no-audio.``
|
||||
@@ -331,6 +336,10 @@
|
||||
Specify the Blu-ray disc location. Must be a directory with Blu-ray
|
||||
structure.
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
``mpv bd:// --bluray-device=/path/to/bd/``
|
||||
|
||||
``--border``, ``--no-border``
|
||||
Play movie with window border and decorations. Since this is on by
|
||||
default, use ``--no-border`` to disable the standard window decorations.
|
||||
@@ -357,7 +366,7 @@
|
||||
|
||||
``--cache-default=<kBytes|no>``
|
||||
Set the size of the cache in kilobytes (default: 320 KB). Using ``no``
|
||||
will not automatically enable the cache e.h. when playing from a network
|
||||
will not automatically enable the cache e.g. when playing from a network
|
||||
stream. Note that using ``--cache`` will always override this option.
|
||||
|
||||
``--cache-pause=<no|percentage>``
|
||||
@@ -433,11 +442,6 @@
|
||||
libavcodec downmixes the audio into the requested number of channels if
|
||||
possible.
|
||||
|
||||
.. note::
|
||||
|
||||
This option is honored by codecs (AC-3 only), filters (surround) and
|
||||
audio output drivers (OSS at least).
|
||||
|
||||
The ``--channels`` option either takes a channel number or an explicit
|
||||
channel layout. Channel numbers refer to default layouts, e.g. 2 channels
|
||||
refer to stereo, 6 refers to 5.1.
|
||||
@@ -446,6 +450,13 @@
|
||||
lists speaker names, which can be used to express arbitrary channel
|
||||
layouts (e.g. ``fl-fr-lfe`` is 2.1).
|
||||
|
||||
.. note::
|
||||
|
||||
Currently, this option is not very useful. The main effect of this
|
||||
option is that automatic stereo downmixing is disabled. It depends
|
||||
mainly on the selected audio output and the associated audio subsystem
|
||||
how playback of files with surround audio will behave.
|
||||
|
||||
``--chapter=<start[-end]>``
|
||||
Specify which chapter to start playing at. Optionally specify which
|
||||
chapter to end playing at. Also see ``--start``.
|
||||
@@ -459,6 +470,13 @@
|
||||
the start of the next one then keep playing video normally over the
|
||||
chapter change instead of doing a seek.
|
||||
|
||||
``--chapter-seek-threshold=<seconds>``
|
||||
Distance in seconds from the beginning of a chapter within which a backward
|
||||
chapter seek will go to the previous chapter (default: 5.0). Past this
|
||||
threshold, a backward chapter seek will go to the beginning of the current
|
||||
chapter instead. A negative value means always go back to the previous
|
||||
chapter.
|
||||
|
||||
``--colormatrix=<colorspace>``
|
||||
Controls the YUV to RGB color space conversion when playing video. There
|
||||
are various standards. Normally, BT.601 should be used for SD video, and
|
||||
@@ -559,10 +577,30 @@
|
||||
``no`` will disable cursor autohide. ``always`` means the cursor will stay
|
||||
hidden.
|
||||
|
||||
``--cursor-autohide-fs-only``
|
||||
If this option is given, the cursor is always visible in windowed mode. In
|
||||
fullscreen mode, the cursor is shown or hidden according to
|
||||
``--cursor-autohide``.
|
||||
|
||||
``--audio-delay=<sec>``
|
||||
Audio delay in seconds (positive or negative float value). Negative values
|
||||
delay the audio, and positive values delay the video.
|
||||
|
||||
``--deinterlace=<yes|no|auto>``
|
||||
Enable or disable interlacing (default: auto, which usually means no).
|
||||
Interlaced video shows ugly comb-like artifacts, which are visible on
|
||||
fast movement. Enabling this typically inserts the yadif video filter in
|
||||
order to deinterlace the video, or lets the video output apply deinterlacing
|
||||
if supported.
|
||||
|
||||
This behaves exactly like the ``deinterlace`` input property (usually
|
||||
mapped to ``Shift+D``).
|
||||
|
||||
``auto`` is a technicality. Strictly speaking, the default for this option
|
||||
is deinterlacing disabled, but the ``auto`` case is needed if ``yadif`` was
|
||||
added to the filter chain manually with ``--vf``. Then the core shouldn't
|
||||
disable deinterlacing just because the ``--deinterlace`` was not set.
|
||||
|
||||
``--demuxer=<[+]name>``
|
||||
Force demuxer type. Use a '+' before the name to force it; this will skip
|
||||
some checks. Give the demuxer name as printed by ``--demuxer=help``.
|
||||
@@ -584,7 +622,7 @@
|
||||
|
||||
This is default in order to reduce latency when opening HTTP streams.
|
||||
|
||||
``--demuxer-lavf-format=<value>``
|
||||
``--demuxer-lavf-format=<name>``
|
||||
Force a specific libavformat demuxer.
|
||||
|
||||
``--demuxer-lavf-genpts-mode=<auto|lavf|builtin|no>``
|
||||
@@ -667,12 +705,14 @@
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
- ``mpv sample-720x576.yuv --demuxer=rawvideo --demuxer-rawvideo=w=720:h=576``
|
||||
Play a raw YUV sample.
|
||||
Play a raw YUV sample::
|
||||
|
||||
mpv sample-720x576.yuv --demuxer=rawvideo \
|
||||
--demuxer-rawvideo=w=720:h=576
|
||||
|
||||
``--demuxer-rawvideo-format=<value>``
|
||||
Colorspace (fourcc) in hex or string for ``--demuxer=rawvideo``
|
||||
(default: YV12).
|
||||
(default: ``YV12``).
|
||||
|
||||
``--demuxer-rawvideo-mp-format=<value>``
|
||||
Colorspace by internal video format for ``--demuxer=rawvideo``. Use
|
||||
@@ -708,6 +748,10 @@
|
||||
also specify a directory that contains files previously copied directly
|
||||
from a DVD (with e.g. vobcopy).
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
``mpv dvd:// --dvd-device=/path/to/dvd/``
|
||||
|
||||
``--dvd-speed=<speed>``
|
||||
Try to limit DVD speed (default: 0, no change). DVD base speed is 1385
|
||||
kB/s, so an 8x drive can read at speeds up to 11080 kB/s. Slower speeds
|
||||
@@ -724,10 +768,10 @@
|
||||
Some DVDs contain scenes that can be viewed from multiple angles.
|
||||
This option tells mpv which angle to use (default: 1).
|
||||
|
||||
``--edition=<ID>``
|
||||
``--edition=<ID|auto>``
|
||||
(Matroska files only)
|
||||
Specify the edition (set of chapters) to use, where 0 is the first. If set
|
||||
to -1 (the default), mpv will choose the first edition declared as a
|
||||
to ``auto`` (the default), mpv will choose the first edition declared as a
|
||||
default, or if there is no default, the first edition defined.
|
||||
|
||||
``--embeddedfonts``, ``--no-embeddedfonts``
|
||||
@@ -750,7 +794,7 @@
|
||||
|
||||
``--no-fixed-vo``, ``--fixed-vo``
|
||||
``--no-fixed-vo`` enforces closing and reopening the video window for
|
||||
multiple files (one (un)initialization for all files).
|
||||
multiple files (one (un)initialization for each file).
|
||||
|
||||
``--flip``
|
||||
Flip image upside-down.
|
||||
@@ -763,6 +807,20 @@
|
||||
depending on GPU drivers and hardware. For other VOs, this just makes
|
||||
rendering slower.
|
||||
|
||||
``--force-window``
|
||||
Create a video output window even if there is no video. This can be useful
|
||||
when pretending that mpv is a GUI application. Currently, the window
|
||||
always has the size 640x480, and is subject to ``--geometry``,
|
||||
``--autofit``, and similar options.
|
||||
|
||||
.. warning::
|
||||
|
||||
The window is created only after initialization (to make sure default
|
||||
window placement still works if the video size is different from the
|
||||
``--force-window`` default window size). This can be a problem if
|
||||
initialization doesn't work perfectly, such as when opening URLs with
|
||||
bad network connection, or opening broken video files.
|
||||
|
||||
``--force-window-position``
|
||||
Forcefully move mpv's video output window to default location whenever
|
||||
there is a change in video parameters, video stream or file. This used to
|
||||
@@ -959,14 +1017,11 @@
|
||||
See also ``--autofit`` and ``--autofit-larger`` for fitting the window into
|
||||
a given size without changing aspect ratio.
|
||||
|
||||
``--grabpointer``, ``--no-grabpointer``
|
||||
``--no-grabpointer`` tells the player to not grab the mouse pointer after a
|
||||
video mode change (``--vm``). Useful for multihead setups.
|
||||
|
||||
``--heartbeat-cmd``
|
||||
``--heartbeat-cmd=<command>``
|
||||
Command that is executed every 30 seconds during playback via *system()* -
|
||||
i.e. using the shell. The time between the commands can be customized with
|
||||
the ``--heartbeat-interval`` option.
|
||||
the ``--heartbeat-interval`` option. The command is not run while playback
|
||||
is paused.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -979,7 +1034,8 @@
|
||||
This can be "misused" to disable screensavers that do not support the
|
||||
proper X API (see also ``--stop-screensaver``). If you think this is too
|
||||
complicated, ask the author of the screensaver program to support the
|
||||
proper X APIs.
|
||||
proper X APIs. Note that the ``--stop-screensaver`` does not influence the
|
||||
heartbeat code at all.
|
||||
|
||||
.. admonition:: Example for xscreensaver
|
||||
|
||||
@@ -989,9 +1045,14 @@
|
||||
|
||||
``mpv --heartbeat-cmd="gnome-screensaver-command -p" file``
|
||||
|
||||
|
||||
``--heartbeat-interval=<sec>``
|
||||
Time between ``--heartbeat-cmd`` invocations in seconds (default: 30).
|
||||
|
||||
.. note::
|
||||
|
||||
This does not affect the normal screensaver operation in any way.
|
||||
|
||||
``--help``
|
||||
Show short summary of options.
|
||||
|
||||
@@ -1027,7 +1088,10 @@
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
``mpv --http-header-fields='Field1: value1','Field2: value2' http://localhost:1234``
|
||||
::
|
||||
|
||||
mpv --http-header-fields='Field1: value1','Field2: value2' \
|
||||
http://localhost:1234
|
||||
|
||||
Will generate HTTP request::
|
||||
|
||||
@@ -1052,10 +1116,22 @@
|
||||
``<api>`` can be one of the following:
|
||||
|
||||
:no: always use software decoding (default)
|
||||
:vdpau: works with nvidia drivers only, requires ``--vo=vdpau``
|
||||
:vda: OSX
|
||||
:auto: see below
|
||||
:vdpau: requires ``--vo=vdpau`` (Linux only)
|
||||
:vaapi: requires ``--vo=vaapi`` (Linux with Intel GPUs only)
|
||||
:vaapi-copy: copies video back into system RAM (Linux with Intel GPUs only)
|
||||
:vda: requires ``--vo=corevideo`` (OSX only)
|
||||
:crystalhd: Broadcom Crystal HD
|
||||
|
||||
``auto`` tries to automatically enable hardware decoding using the first
|
||||
available method. This still depends what VO you are using. For example,
|
||||
if you are not using ``--vo=vdpau``, vdpau decoding will never be enabled.
|
||||
Also note that if the first found method doesn't actually work, it will
|
||||
always fall back to software decoding, instead of trying the next method.
|
||||
|
||||
The ``vaapi-copy`` function allows you to use vaapi with any VO. Because
|
||||
this copies the decoded video back to system RAM, it's quite inefficient.
|
||||
|
||||
``--hwdec-codecs=<codec1,codec2,...|all>``
|
||||
Allow hardware decoding for a given list of codecs only. The default is the
|
||||
special value ``all``, which always allows all codecs.
|
||||
@@ -1183,10 +1259,31 @@
|
||||
``--list-properties``
|
||||
Print a list of the available properties.
|
||||
|
||||
``--loop=<number|inf|no>``
|
||||
Loops playback ``<number>`` times. ``inf`` means forever and ``no`` disables
|
||||
looping. If several files are specified on command line, the entire playlist
|
||||
is looped.
|
||||
``--load-unsafe-playlists``
|
||||
Normally, something like ``mpv playlist.m3u`` won't load the playlist. This
|
||||
is because the playlist code is unsafe. (This is the same in all other
|
||||
variations of MPlayer.)
|
||||
|
||||
See ``--playlist`` for details.
|
||||
|
||||
Note: this option will allow opening playlists using the ``playlist``
|
||||
special demuxer. The ``--playlist`` uses different code, and supports more
|
||||
playlist formats than the playlist demuxer. This means that for now, the
|
||||
``--playlist`` option should always be used if you intend to open playlists.
|
||||
Background: the special demuxer contains newly written code, while the
|
||||
``--playlist`` option uses the old MPlayer code. Adding support for more
|
||||
playlist formats to the special demuxer is work in progress, and eventually
|
||||
the old code should disappear.
|
||||
|
||||
``--loop=<N|inf|no>``
|
||||
Loops playback ``N`` times. A value of ``1`` plays it one time (default),
|
||||
``2`` two times, etc. ``inf`` means forever. ``no`` is the same as ``1`` and
|
||||
disables looping. If several files are specified on command line, the
|
||||
entire playlist is looped.
|
||||
|
||||
``--lua=<filename>``
|
||||
Load a Lua script. You can load multiple scripts by separating them with
|
||||
commas (``,``).
|
||||
|
||||
``--mc=<seconds/frame>``
|
||||
Maximum A-V sync correction per frame (in seconds)
|
||||
@@ -1219,14 +1316,11 @@
|
||||
1). A value of 1 means square pixels (correct for (almost?) all LCDs). See
|
||||
also ``--monitoraspect`` and ``--aspect``.
|
||||
|
||||
``--mouse-movements``
|
||||
``--mouse-movements``, ``--no-mouse-movements``
|
||||
Permit mpv to receive pointer events reported by the video output
|
||||
driver. Necessary to select the buttons in DVD menus. Supported for
|
||||
X11-based VOs (x11, xv, etc) and the gl, direct3d and corevideo VOs.
|
||||
|
||||
``--mouseinput``, ``--no-mouseinput``
|
||||
``--no-mouseinput`` disables mouse button press/release input.
|
||||
|
||||
``--no-msgcolor``
|
||||
Disable colorful console output on terminals.
|
||||
|
||||
@@ -1307,8 +1401,9 @@
|
||||
``--no-sub``
|
||||
Do not select any subtitle when the file is loaded.
|
||||
|
||||
``--no-sub-visibility``
|
||||
Disable display of subtitles, but still select and decode them.
|
||||
``--sub-visibility``, ``--no-sub-visibility``
|
||||
Can be used to disable display of subtitles, but still select and decode
|
||||
them.
|
||||
|
||||
``--no-video``
|
||||
Do not play video. With some demuxers this may not work. In those cases
|
||||
@@ -1324,6 +1419,9 @@
|
||||
search for video segments from other files, and will also ignore any
|
||||
chapter order specified for the main file.
|
||||
|
||||
``--osc``, ``--no-osc``
|
||||
Whether to load the on-screen-controller (default: yes).
|
||||
|
||||
``--no-osd-bar``, ``--osd-bar``
|
||||
Disable display of the OSD bar. This will make some things (like seeking)
|
||||
use OSD text messages instead of the bar.
|
||||
@@ -1334,13 +1432,15 @@
|
||||
|
||||
``--osd-bar-align-x=<-1-1>``
|
||||
Position of the OSD bar. -1 is far left, 0 is centered, 1 is far right.
|
||||
Fractional values (like 0.5) are allowed.
|
||||
|
||||
``--osd-bar-align-y=<-1-1>``
|
||||
Position of the OSD bar. -1 is top, 0 is centered, 1 is bottom.
|
||||
Fractional values (like 0.5) are allowed.
|
||||
|
||||
``--osd-bar-w=<1-100>``
|
||||
Width of the OSD bar, in percentage of the screen width (default: 75).
|
||||
A value of 0.5 means the bar is half the screen wide.
|
||||
A value of 50 means the bar is half the screen wide.
|
||||
|
||||
``--osd-bar-h=<0.1-50>``
|
||||
Height of the OSD bar, in percentage of the screen height (default: 3.125).
|
||||
@@ -1374,8 +1474,8 @@
|
||||
For example, ``#FF0000`` is red. This is similar to web colors.
|
||||
|
||||
You can specify transparency by specifying an alpha value in the form
|
||||
``#AARRGGBB``. 0 is fully transparent, while ``FF`` is opaque (opaque is
|
||||
default with the shorter color specification).
|
||||
``#AARRGGBB``. ``00`` is fully transparent, while ``FF`` is opaque (opaque
|
||||
is default with the shorter color specification).
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
@@ -1470,17 +1570,9 @@
|
||||
controls how much of the image is cropped. May not work with all video
|
||||
output drivers.
|
||||
|
||||
``--panscanrange=<-19.0-99.0>``
|
||||
(experimental)
|
||||
Change the range of the pan-and-scan functionality (default: 1). Positive
|
||||
values mean multiples of the default range. Negative numbers mean you can
|
||||
zoom in up to a factor of ``--panscanrange=+1``. E.g. ``--panscanrange=-3``
|
||||
allows a zoom factor of up to 4. This feature is experimental. Do not
|
||||
report bugs unless you are using ``--vo=opengl``.
|
||||
|
||||
``--playing-msg=<string>``
|
||||
Print out a string after starting playback. The string is expanded for
|
||||
properties, e.g. ``--playing-msg=file: ${filename}`` will print the string
|
||||
properties, e.g. ``--playing-msg='file: ${filename}'`` will print the string
|
||||
``file:`` followed by a space and the currently played filename.
|
||||
|
||||
See `Property Expansion`_.
|
||||
@@ -1611,6 +1703,8 @@
|
||||
Particularly useful on slow terminals or broken ones which do not properly
|
||||
handle carriage return (i.e. ``\r``).
|
||||
|
||||
Also see ``--really-quiet`` and ``--msglevel``.
|
||||
|
||||
``--quvi-format=<best|default|...>``
|
||||
Video format/quality that is directly passed to libquvi (default: ``best``).
|
||||
This is used when opening links to streaming sites like YouTube. The
|
||||
@@ -1631,9 +1725,10 @@
|
||||
The following explanations are relevant:
|
||||
`<http://quvi.sourceforge.net/doc/0.9/glossary_termino.html#m_stream_id>`_
|
||||
|
||||
With 0.9.x, the ``quvi-format`` property can be used at runtime to cycle
|
||||
through the list of formats. Unfortunately, this resets the playback
|
||||
position and is slow too.
|
||||
The ``quvi-format`` property can be used at runtime to cycle through the
|
||||
list of formats. Unfortunately, this is slow. On libquvi 0.4.x, this
|
||||
functionality is limited to switching between ``best`` and ``default`` if
|
||||
the ``cycle`` input command is used.
|
||||
|
||||
``--radio=<option1:option2:...>``
|
||||
These options set various parameters of the radio capture module. For
|
||||
@@ -1725,9 +1820,10 @@
|
||||
- ``--reset-on-next-file=""``
|
||||
Do not reset pause mode.
|
||||
|
||||
``--reuse-socket``
|
||||
(udp:// only)
|
||||
Allows a socket to be reused by other processes as soon as it is closed.
|
||||
``--rtsp-transport=<lavf|udp|tcp|http>``
|
||||
Select RTSP transport method (default: tcp). This selects the underlying
|
||||
network transport when playing ``rtsp://...`` URLs. The value ``lavf``
|
||||
leaves the decision to libavformat.
|
||||
|
||||
``--saturation=<-100-100>``
|
||||
Adjust the saturation of the video signal (default: 0). You can get
|
||||
@@ -1737,8 +1833,10 @@
|
||||
``--save-position-on-quit``
|
||||
Always save the current playback position on quit. When this file is
|
||||
played again later, the player will seek to the old playback position on
|
||||
start. This affects any form of stopping playback (quitting, going to the
|
||||
next file).
|
||||
start. This does not happen if playback of a file is stopped in any other
|
||||
way than quitting. For example, going to the next file in the playlist
|
||||
will not save the position, and start playback at beginning the next time
|
||||
the file is played.
|
||||
|
||||
This behavior is disabled by default, but is always available when quitting
|
||||
the player with Shift+Q.
|
||||
@@ -1752,12 +1850,12 @@
|
||||
multiple displays), this option tells mpv which screen to display the
|
||||
movie on.
|
||||
|
||||
This option does not always work. In these cases, try to use ``--geometry``
|
||||
to position the window explicitly.
|
||||
|
||||
.. admonition:: Note (X11)
|
||||
|
||||
This option does not work properly with all window managers.
|
||||
This option does not work properly with all window managers. In these
|
||||
cases, you can try to use ``--geometry`` to position the window
|
||||
explicitly. It's also possible that the window manager provides native
|
||||
features to control which screens application windows should use.
|
||||
|
||||
See also ``--fs-screen``.
|
||||
|
||||
@@ -1835,6 +1933,28 @@
|
||||
numbers would be more intuitive, but are not easily implementable
|
||||
because container formats usually use time stamps for identifying
|
||||
frames.)
|
||||
``%wX``
|
||||
Specify the current playback time using the format string ``X``.
|
||||
``%p`` is like ``%wH:%wM:%wS``, and ``%P`` is like ``%wH:%wM:%wS.%wT``.
|
||||
|
||||
Valid format specifiers:
|
||||
``%wH``
|
||||
hour (padded with 0 to two digits)
|
||||
``%wh``
|
||||
hour (not padded)
|
||||
``%wM``
|
||||
minutes (00-59)
|
||||
``%wm``
|
||||
total minutes (includes hours, unlike ``%wM``)
|
||||
``%wS``
|
||||
seconds (00-59)
|
||||
``%ws``
|
||||
total seconds (includes hours and minutes)
|
||||
``%wf``
|
||||
like ``%ws``, but as float
|
||||
``%wT``
|
||||
milliseconds (000-999)
|
||||
|
||||
``%tX``
|
||||
Specify the current local date/time using the format ``X``. This format
|
||||
specifier uses the UNIX ``strftime()`` function internally, and inserts
|
||||
@@ -1863,7 +1983,7 @@
|
||||
Play files in random order.
|
||||
|
||||
``--sid=<ID|auto|no>``
|
||||
Display the subtitle stream specified by ``<ID>`` (0-31). ``auto`` selects
|
||||
Display the subtitle stream specified by ``<ID>``. ``auto`` selects
|
||||
the default, ``no`` disables subtitles.
|
||||
|
||||
See also ``--slang``, ``--no-sub``.
|
||||
@@ -1872,8 +1992,7 @@
|
||||
Specify a priority list of subtitle languages to use. Different container
|
||||
formats employ different language codes. DVDs use ISO 639-1 two letter
|
||||
language codes, Matroska uses ISO 639-2 three letter language codes while
|
||||
OGM uses a free-form identifier. mpv prints the available languages
|
||||
when run in verbose (``-v``) mode. See also ``--sid``.
|
||||
OGM uses a free-form identifier. See also ``--sid``.
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
@@ -1927,6 +2046,14 @@
|
||||
current level. With values below 100 the initial volume (which is 100%)
|
||||
will be above the maximum, which e.g. the OSD cannot display correctly.
|
||||
|
||||
.. admonition:: Note
|
||||
|
||||
The maximum value of ``--volume`` as well as the ``volume`` property
|
||||
is always 100. Likewise, the volume OSD bar always goes from 0 to 100.
|
||||
This means that with ``--softvol-max=200``, ``--volume=100`` sets
|
||||
maximum amplification, i.e. amplify by 200%. The default volume (no
|
||||
change in volume) will be ``50`` in this case.
|
||||
|
||||
``--speed=<0.01-100>``
|
||||
Slow down or speed up playback by the factor given as parameter.
|
||||
|
||||
@@ -1985,7 +2112,8 @@
|
||||
|
||||
``--stop-screensaver``, ``--no-stop-screensaver``
|
||||
Turns off the screensaver (or screen blanker and similar mechanisms) at
|
||||
startup and turns it on again on exit (default: yes).
|
||||
startup and turns it on again on exit (default: yes). The screensaver is
|
||||
always re-enabled when the player is paused.
|
||||
|
||||
This is not supported on all video outputs or platforms. Sometimes it is
|
||||
implemented, but does not work (happens often on GNOME). You might be able
|
||||
@@ -2025,22 +2153,39 @@
|
||||
|
||||
``--subcp=<codepage>``
|
||||
If your system supports ``iconv(3)``, you can use this option to specify
|
||||
the subtitle codepage.
|
||||
the subtitle codepage. By default, ENCA will be used to guess the charset.
|
||||
If mpv is not compiled with ENCA, ``UTF-8:UTF-8-BROKEN`` is the default,
|
||||
which means it will try to use UTF-8, otherwise the ``UTF-8-BROKEN``
|
||||
pseudo codepage (see below).
|
||||
|
||||
.. admonition:: Warning
|
||||
|
||||
If you force the charset, even subtitles that are known to be
|
||||
UTF-8 will be recoded, which is perhaps not what you expect. Prefix
|
||||
codepages with ``utf8:`` if you want the codepage to be used only if the
|
||||
input is not valid UTF-8.
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
- ``--subcp=latin2``
|
||||
- ``--subcp=cp1250``
|
||||
- ``--subcp=utf8:latin2`` Use Latin 2 if input is not UTF-8.
|
||||
- ``--subcp=utf8:cp1250`` Use CP1250 if input is not UTF-8.
|
||||
- ``--subcp=cp1250`` Always force recoding to cp1250.
|
||||
|
||||
If the player was compiled with ENCA support, you can use special syntax
|
||||
to use that::
|
||||
The pseudo codepage ``UTF-8-BROKEN`` is used internally. If this is used
|
||||
as codepage, the subtitle will be interpreted as UTF-8, but with "Latin 1"
|
||||
as fallback for bytes which are not valid UTF-8 sequences. iconv is never
|
||||
involved in this mode.
|
||||
|
||||
--subcp=enca:<language>:<fallback codepage>
|
||||
If the player was compiled with ENCA support, you can control it with the
|
||||
following syntax::
|
||||
|
||||
``--subcp=enca:<language>:<fallback codepage>``
|
||||
|
||||
You can specify your language using a two letter language code to make
|
||||
ENCA detect the codepage automatically. If unsure, enter anything (if the
|
||||
language is invalid, mpv will complain and list valid languages).
|
||||
Fallback codepage specifies the codepage to use if autodetection fails.
|
||||
If no fallback is specified, ``UTF-8-BROKEN`` is used.
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
@@ -2112,10 +2257,10 @@
|
||||
to fix the playback speed for frame-based subtitle formats. Works for
|
||||
external text subtitles only.
|
||||
|
||||
.. admonition:: Examples
|
||||
.. admonition:: Example
|
||||
|
||||
- ``--sub-speed=25/23.976`` plays frame based subtitles which have been
|
||||
loaded assuming a framerate of 23.976 at 25 FPS.
|
||||
`--sub-speed=25/23.976`` plays frame based subtitles which have been
|
||||
loaded assuming a framerate of 23.976 at 25 FPS.
|
||||
|
||||
``--sws=<n>``
|
||||
Specify the software scaler algorithm to be used with ``--vf=scale``. This
|
||||
@@ -2157,7 +2302,17 @@
|
||||
.. warning::
|
||||
|
||||
There is a danger of this causing significant CPU usage, depending on
|
||||
the properties used and the window manager.
|
||||
the properties used and the window manager. Changing the window title
|
||||
is often a slow operation, and if the title changes every frame,
|
||||
playback can be ruined.
|
||||
|
||||
``--tls-ca-file=<filename>``
|
||||
Certificate authority database file for use with TLS. (Silently fails with
|
||||
older ffmpeg or libav versions.)
|
||||
|
||||
``--tls-verify``
|
||||
Verify peer certificates when using TLS (e.g. with ``https://...``).
|
||||
(Silently fails with older ffmpeg or libav versions.)
|
||||
|
||||
``--tv=<option1:option2:...>``
|
||||
This option tunes various properties of the TV capture module. For
|
||||
@@ -2436,6 +2591,51 @@
|
||||
``--vid=<ID|auto|no>``
|
||||
Select video channel. ``auto`` selects the default, ``no`` disables video.
|
||||
|
||||
``--video-align-x=<-1-1>``, ``--video-align-y=<-1-1>``
|
||||
Moves the video rectangle within the black borders, which are usually added
|
||||
to pad the video to screen if video and screen aspect ratios are different.
|
||||
``--video-align-y=-1`` would move the video to the top of the screen
|
||||
(leaving a border only on the bottom), a value of ``0`` centers it
|
||||
(default), and a value of ``-1`` would put the video at the bottom of the
|
||||
screen.
|
||||
|
||||
If video and screen aspect match perfectly, these options do nothing.
|
||||
|
||||
This option is disabled if the ``--no-keepaspect`` option is used.
|
||||
|
||||
``--video-pan-x=<value>``, ``--video-pan-y=<value>``
|
||||
Moves the displayed video rectangle by the given value in the X or Y
|
||||
direction. The unit is in fractions of the size of the scaled video (the
|
||||
full size, even if parts of the video are not visible due to panscan or
|
||||
other options).
|
||||
|
||||
For example, displaying a 1280x720 video fullscreen on a 1680x1050 screen
|
||||
with ``--video-pan-x=-0.1`` would move the video 168 pixels to the left
|
||||
(making 128 pixels of the source video invisible).
|
||||
|
||||
This option is disabled if the ``--no-keepaspect`` option is used.
|
||||
|
||||
``--video-unscaled``
|
||||
Disable scaling of the video. If the window is larger than the video,
|
||||
black bars are added. Otherwise, the video is cropped. The video still
|
||||
can be influenced by the other ``--video-...`` options. (If the
|
||||
``--video-zoom`` option is set to a value other than ``1``, scaling is
|
||||
enabled, but the video isn't automatically scaled to the window size.)
|
||||
|
||||
Note that the scaler algorithm may still be used, even if the video isn't
|
||||
scaled. For example, this can influence chroma conversion.
|
||||
|
||||
This option is disabled if the ``--no-keepaspect`` option is used.
|
||||
|
||||
``--video-zoom=<value>``
|
||||
Adjust the video display scale factor by the given value. The unit is in
|
||||
fractions of original video size.
|
||||
|
||||
For example, given a 1280x720 video, ``--video-zoom=-0.1`` would make the
|
||||
video by 128 pixels smaller in X direction, and 72 pixels in Y direction.
|
||||
|
||||
This option is disabled if the ``--no-keepaspect`` option is used.
|
||||
|
||||
``--vo=<driver1[:suboption1[=value]:...],driver2,...[,]>``
|
||||
Specify a priority list of video output drivers to be used. For
|
||||
interactive use, one would normally specify a single one to use, but in
|
||||
@@ -2450,6 +2650,18 @@
|
||||
Set the startup volume. A value of -1 (the default) will not change the
|
||||
volume. See also ``--softvol``.
|
||||
|
||||
``--volume-restore-data=<string>``
|
||||
Used internally for use by playback resume (e.g. with ``quit_watch_later``).
|
||||
Restoring value has to be done carefully, because different AOs as well as
|
||||
softvol can have different value ranges, and we don't want to restore
|
||||
volume if setting the volume changes it system wide. The normal options
|
||||
(like ``--volume``) would always set the volume. This option was added for
|
||||
restoring volume in a safer way (by storing the method used to set the
|
||||
volume), and is not generally useful. Its semantics are considered private
|
||||
to mpv.
|
||||
|
||||
Do not use.
|
||||
|
||||
``--wid=<ID>``
|
||||
(X11 and Windows only)
|
||||
This tells mpv to attach to an existing window. The ID is interpreted as
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
ON SCREEN CONTROLLER
|
||||
====================
|
||||
|
||||
The On Screen Controller (short: OSC) is a minimal GUI integrated with mpv to
|
||||
offer basic mouse-controllability. It is intended to make interaction easier
|
||||
for new users and to enable precise and direct seeking.
|
||||
|
||||
The OSC is enabled by default if mpv was compiled with lua support. It can be
|
||||
disabled using ``--osc=no``.
|
||||
|
||||
Using the OSC
|
||||
-------------
|
||||
|
||||
By default, the OSC will show up whenever the mouse is moved inside the
|
||||
player window and will hide if the mouse is not moved outside the OSC for
|
||||
0.5 seconds or if the mouse leaves the window.
|
||||
|
||||
The Interface
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
::
|
||||
|
||||
+------------------+-----------+--------------------+
|
||||
| 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 |
|
||||
+----------------+--------------+-------------------+
|
||||
|
||||
|
||||
playlist prev
|
||||
============= ================================================
|
||||
left-click play previous file in playlist
|
||||
shift+L-click show playlist
|
||||
============= ================================================
|
||||
|
||||
title
|
||||
| Displays current media-title or filename
|
||||
|
||||
============= ================================================
|
||||
left-click show playlist position and length and full title
|
||||
right-click show filename
|
||||
============= ================================================
|
||||
|
||||
playlist next
|
||||
============= ================================================
|
||||
left-click play next file in playlist
|
||||
shift+L-click show playlist
|
||||
============= ================================================
|
||||
|
||||
audio and sub
|
||||
| Displays selected track and amount of available tracks
|
||||
|
||||
============= ================================================
|
||||
left-click cycle audio/sub tracks forward
|
||||
right-click cycle audio/sub tracks backwards
|
||||
shift+L-click show available audio/sub tracks
|
||||
============= ================================================
|
||||
|
||||
skip back
|
||||
============= ================================================
|
||||
left-click go to beginning of chapter / previous chapter
|
||||
shift+L-click show chapters
|
||||
============= ================================================
|
||||
|
||||
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 48%)
|
||||
|
||||
time remaining
|
||||
| Shows remaining playback time timestamp
|
||||
|
||||
============= ================================================
|
||||
left-click toggle between total and remaining time
|
||||
============= ================================================
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
The OSC offers limited configuration through a config file ``plugin_osc.conf``
|
||||
placed in mpv's user dir.
|
||||
|
||||
Config Syntax
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The config file must exactly follow the following syntax::
|
||||
|
||||
# this is a comment
|
||||
parameter1=value1
|
||||
parameter2=value2
|
||||
|
||||
``#`` can only be used at the beginning of a line and there may be no
|
||||
spaces around the ``=`` or anywhere else.
|
||||
|
||||
Configurable parameters
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``showwindowed``
|
||||
| Default: yes
|
||||
| Show OSC when windowed?
|
||||
|
||||
``showfullscreen``
|
||||
| Default: yes
|
||||
| Show OSC when fullscreen?
|
||||
|
||||
``scalewindowed``
|
||||
| Default: 1
|
||||
| Scaling of the controller when windowed
|
||||
|
||||
``scalefullscreen``
|
||||
| Default: 1
|
||||
| Scaling of the controller when fullscreen
|
||||
|
||||
``scaleforcedwindow``
|
||||
| Default: 2
|
||||
| Scaling of the controller when rendered on a forced (dummy) window
|
||||
|
||||
``vidscale``
|
||||
| Default: yes
|
||||
| Scale the controller with the video?
|
||||
|
||||
``valign``
|
||||
| Default: 0.8
|
||||
| Vertical alignment, -1 (top) to 1 (bottom)
|
||||
|
||||
``halign``
|
||||
| Default: 0
|
||||
| Horizontal alignment, -1 (left) to 1 (right)
|
||||
|
||||
``hidetimeout``
|
||||
| Default: 500
|
||||
| Duration in ms until the OSC hides if no mouse movement, negative value
|
||||
disables auto-hide
|
||||
|
||||
``fadeduration``
|
||||
| Default: 200
|
||||
| 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.
|
||||
|
||||
``minmousemove``
|
||||
| Default: 3
|
||||
| Minimum amount of pixels the mouse has to move between ticks to make
|
||||
the OSC show up
|
||||
|
||||
@@ -861,3 +861,20 @@ Available filters are:
|
||||
|
||||
``a3=<string>``
|
||||
Specify the fourth parameter to pass to the library.
|
||||
|
||||
``vavpp``
|
||||
VA-API video post processing. Works with ``--vo=vaapi`` only. Currently
|
||||
deinterlaces. This filter is automatically inserted if deinterlacing is
|
||||
requested (either using the ``D`` key, by default mapped to the command
|
||||
``cycle deinterlace``, or the ``--deinterlace`` option).
|
||||
|
||||
``deint=<method>``
|
||||
Select the deinterlacing algorithm.
|
||||
|
||||
no
|
||||
Don't perform deinterlacing.
|
||||
first-field
|
||||
Show only first field (going by ``--field-dominance``).
|
||||
bob
|
||||
bob deinterlacing (default).
|
||||
|
||||
+81
-16
@@ -22,12 +22,9 @@ in the list. Suboptions are optional and can mostly be omitted.
|
||||
Available video output drivers are:
|
||||
|
||||
``xv`` (X11 only)
|
||||
Uses the XVideo extension to enable hardware-accelerated playback. This is
|
||||
Uses the XVideo extension to enable hardware-accelerated display. This is
|
||||
the most compatible VO on X, but may be low-quality, and has issues with
|
||||
OSD and subtitle display.
|
||||
For information about what colorkey is used and how it is drawn, run
|
||||
mpv with the ``-v`` option and look out for the lines tagged with ``[xv
|
||||
common]`` at the beginning.
|
||||
|
||||
``adaptor=<number>``
|
||||
Select a specific XVideo adaptor (check xvinfo results).
|
||||
@@ -133,6 +130,16 @@ Available video output drivers are:
|
||||
``output_surfaces=<2-15>``
|
||||
Allocate this many output surfaces to display video frames (default:
|
||||
3). See below for additional information.
|
||||
``colorkey=<#RRGGBB|#AARRGGBB>``
|
||||
Set the VDPAU presentation queue background color, which in practice
|
||||
is the colorkey used if VDPAU operates in overlay mode (default:
|
||||
``#020507``, some shade of black). If the alpha component of this value
|
||||
is 0, the default VDPAU colorkey will be used instead (which is usually
|
||||
green).
|
||||
``force-yuv``
|
||||
Never accept RGBA input. This means mpv will insert a filter to convert
|
||||
to a YUV format before the VO. Sometimes useful to force availability
|
||||
of certain YUV-only features, like video equalizer or deinterlacing.
|
||||
|
||||
Using the VDPAU frame queueing functionality controlled by the queuetime
|
||||
options makes mpv's frame flip timing less sensitive to system CPU load and
|
||||
@@ -265,7 +272,9 @@ Available video output drivers are:
|
||||
|
||||
|
||||
There are some more filters. For a complete list, pass ``help`` as
|
||||
value, e.g.: ``mpv --vo=opengl:lscale=help``
|
||||
value, e.g.::
|
||||
|
||||
mpv --vo=opengl:lscale=help
|
||||
|
||||
``lparam1=<value>``
|
||||
Set filter parameters. Ignored if the filter is not tunable. These are
|
||||
@@ -413,8 +422,8 @@ Available video output drivers are:
|
||||
Selects the internal format of textures used for FBOs. The format can
|
||||
influence performance and quality of the video output. (FBOs are not
|
||||
always used, and typically only when using extended scalers.)
|
||||
``fmt`` can be one of: rgb, rgba, rgb8, rgb10, rgb16, rgb16f, rgb32f,
|
||||
rgba12, rgba16, rgba16f, rgba32f.
|
||||
``fmt`` can be one of: rgb, rgba, rgb8, rgb10, rgb10_a2, rgb16, rgb16f,
|
||||
rgb32f, rgba12, rgba16, rgba16f, rgba32f.
|
||||
Default: rgb.
|
||||
|
||||
``gamma``
|
||||
@@ -445,13 +454,20 @@ Available video output drivers are:
|
||||
Default is 128x256x64.
|
||||
Sizes must be a power of two, and 256 at most.
|
||||
|
||||
``alpha``
|
||||
Try to create a framebuffer with alpha component. This only makes sense
|
||||
if the video contains alpha information (which is extremely rare). May
|
||||
not be supported on all platforms. If alpha framebuffers are
|
||||
unavailable, it silently falls back on a normal framebuffer. Note
|
||||
that when using FBO indirections (such as with ``opengl-hq``), an FBO
|
||||
format with alpha must be specified with the ``fbo-format`` option.
|
||||
``alpha=<blend|yes|no>``
|
||||
Decides what to do if the input has an alpha component (default: blend).
|
||||
|
||||
blend
|
||||
Blend the frame against a black background.
|
||||
yes
|
||||
Try to create a framebuffer with alpha component. This only makes sense
|
||||
if the video contains alpha information (which is extremely rare). May
|
||||
not be supported on all platforms. If alpha framebuffers are
|
||||
unavailable, it silently falls back on a normal framebuffer. Note
|
||||
that when using FBO indirections (such as with ``opengl-hq``), an FBO
|
||||
format with alpha must be specified with the ``fbo-format`` option.
|
||||
no
|
||||
Ignore alpha component.
|
||||
|
||||
``chroma-location=<auto|center|left>``
|
||||
Set the YUV chroma sample location. auto means use the bitstream
|
||||
@@ -609,8 +625,7 @@ Available video output drivers are:
|
||||
The following options are only useful if writing your own fragment programs.
|
||||
|
||||
``customprog=<filename>``
|
||||
Load a custom fragment program from ``<filename>``. See
|
||||
``TOOLS/edgedect.fp`` for an example.
|
||||
Load a custom fragment program from ``<filename>``.
|
||||
``customtex=<filename>``
|
||||
Load a custom "gamma ramp" texture from ``<filename>``. This can be used
|
||||
in combination with ``yuv=4`` or with the ``customprog`` option.
|
||||
@@ -665,6 +680,46 @@ Available video output drivers are:
|
||||
``switch-mode``
|
||||
Instruct SDL to switch the monitor video mode when going fullscreen.
|
||||
|
||||
``vaapi``
|
||||
Intel VA API video output driver with support for hardware decoding. Note
|
||||
that there is absolutely no reason to use this, other than wanting to use
|
||||
hardware decoding to save power on laptops, or possibly preventing video
|
||||
tearing with some setups.
|
||||
|
||||
``scaling=<algorithm>``
|
||||
default
|
||||
Driver default (mpv default as well).
|
||||
fast
|
||||
Fast, but low quality.
|
||||
hq
|
||||
Unspecified driver dependent high-quality scaling, slow.
|
||||
nla
|
||||
``non-linear anamorphic scaling``
|
||||
|
||||
``deint-mode=<mode>``
|
||||
Select deinterlacing algorithm. Note that by default deinterlacing is
|
||||
initially always off, and needs to be enabled with the ``D`` key
|
||||
(default key binding for ``cycle deinterlace``).
|
||||
|
||||
This option doesn't apply if libva supports video post processing (vpp).
|
||||
In this case, the default for ``deint-mode`` is ``no``, and enabling
|
||||
deinterlacing via user interaction using the methods mentioned above
|
||||
actually inserts the ``vavpp`` video filter. If vpp is not actually
|
||||
supported with the libva backend in use, you can use this option to
|
||||
forcibly enable VO based deinterlacing.
|
||||
|
||||
no
|
||||
Don't allow deinterlacing (default for newer libva).
|
||||
first-field
|
||||
Show only first field (going by ``--field-dominance``).
|
||||
bob
|
||||
bob deinterlacing (default for older libva).
|
||||
|
||||
``scaled-osd=<yes|no>``
|
||||
If enabled, then the OSD is rendered at video resolution and scaled to
|
||||
display resolution. By default, this is disabled, and the OSD is
|
||||
rendered at display resolution if the driver supports it.
|
||||
|
||||
``null``
|
||||
Produces no video output. Useful for benchmarking.
|
||||
|
||||
@@ -712,3 +767,13 @@ Available video output drivers are:
|
||||
JPEG DPI (default: 72)
|
||||
``outdir=<dirname>``
|
||||
Specify the directory to save the image files to (default: ``./``).
|
||||
|
||||
``wayland`` (Wayland only)
|
||||
Wayland shared memory video output as fallback for ``opengl``.
|
||||
|
||||
``default-format``
|
||||
Use the default RGB32 format instead of an auto-detected one.
|
||||
|
||||
``alpha``
|
||||
Use a buffer format that supports videos and images with alpha
|
||||
information
|
||||
@@ -76,6 +76,12 @@ talloc.h & talloc.c:
|
||||
replacement. It works on top of system malloc and provides additional
|
||||
features that are supposed to make memory management easier.
|
||||
|
||||
Warning: actually, we're not using talloc anymore. talloc in mpv has been
|
||||
replaced by a custom re-implementation (TA in ta/). It provides
|
||||
some talloc emulation (just the parts needed by mpv). We will get
|
||||
rid of the talloc emulation later and use TA natively.
|
||||
(See ta/README for details.)
|
||||
|
||||
mpvcore/mp_core.h:
|
||||
Data structures for mplayer.c and command.c. They are usually not accessed
|
||||
by other parts of mpv for the sake of modularization.
|
||||
|
||||
@@ -1,625 +1,284 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
NO WARRANTY
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
@@ -628,15 +287,15 @@ free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
This program 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 3 of the License, or
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
@@ -645,30 +304,37 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
@@ -25,6 +25,7 @@ include config.mak
|
||||
|
||||
SOURCES_AUDIO_INPUT-$(ALSA) += stream/ai_alsa1x.c
|
||||
SOURCES_AUDIO_INPUT-$(OSS) += stream/ai_oss.c
|
||||
SOURCES_AUDIO_INPUT-$(SNDIO) += stream/ai_sndio.c
|
||||
SOURCES-$(AUDIO_INPUT) += $(SOURCES_AUDIO_INPUT-yes)
|
||||
SOURCES-$(CDDA) += stream/stream_cdda.c \
|
||||
stream/cdinfo.c
|
||||
@@ -44,16 +45,21 @@ SOURCES-$(LIBBS2B) += audio/filter/af_bs2b.c
|
||||
SOURCES-$(LIBPOSTPROC) += video/filter/vf_pp.c
|
||||
SOURCES-$(LIBSMBCLIENT) += stream/stream_smb.c
|
||||
|
||||
SOURCES-$(MACOSX_BUNDLE) += osdep/macosx_bundle.m
|
||||
SOURCES-$(COCOA) += video/out/cocoa_common.m \
|
||||
SOURCES-$(COCOA) += video/out/cocoa/view.m \
|
||||
video/out/cocoa/window.m \
|
||||
video/out/cocoa/additions.m \
|
||||
video/out/cocoa_common.m \
|
||||
osdep/macosx_application.m \
|
||||
osdep/macosx_events.m \
|
||||
osdep/ar/HIDRemote.m
|
||||
osdep/ar/HIDRemote.m \
|
||||
osdep/path-macosx.m
|
||||
|
||||
SOURCES-$(MNG) += demux/demux_mng.c
|
||||
SOURCES-$(MPG123) += audio/decode/ad_mpg123.c
|
||||
|
||||
SOURCES-$(NEED_GETTIMEOFDAY) += osdep/gettimeofday.c
|
||||
SOURCES-$(NEED_GLOB) += osdep/glob-win.c
|
||||
SOURCES-$(WIN32) += osdep/path-win.c
|
||||
|
||||
SOURCES-$(PRIORITY) += osdep/priority.c
|
||||
SOURCES-$(PVR) += stream/stream_pvr.c
|
||||
@@ -106,24 +112,32 @@ SOURCES-$(OSS) += audio/out/ao_oss.c
|
||||
SOURCES-$(PULSE) += audio/out/ao_pulse.c
|
||||
SOURCES-$(PORTAUDIO) += audio/out/ao_portaudio.c
|
||||
SOURCES-$(RSOUND) += audio/out/ao_rsound.c
|
||||
SOURCES-$(SNDIO) += audio/out/ao_sndio.c
|
||||
SOURCES-$(VDPAU) += video/vdpau.c video/out/vo_vdpau.c
|
||||
SOURCES-$(VDA) += video/decode/vda.c
|
||||
SOURCES-$(VDPAU_DEC) += video/decode/vdpau.c
|
||||
SOURCES-$(VDPAU_DEC_OLD) += video/decode/vdpau_old.c
|
||||
SOURCES-$(VAAPI) += video/out/vo_vaapi.c \
|
||||
video/decode/vaapi.c \
|
||||
video/vaapi.c
|
||||
SOURCES-$(VAAPI_VPP) += video/filter/vf_vavpp.c
|
||||
|
||||
SOURCES-$(X11) += video/out/vo_x11.c video/out/x11_common.c
|
||||
SOURCES-$(XV) += video/out/vo_xv.c
|
||||
SOURCES-$(WAYLAND) += video/out/vo_wayland.c video/out/wayland_common.c
|
||||
|
||||
SOURCES-$(VF_LAVFI) += video/filter/vf_lavfi.c
|
||||
SOURCES-$(AF_LAVFI) += audio/filter/af_lavfi.c
|
||||
|
||||
SOURCES-$(LUA) += mpvcore/mp_lua.c
|
||||
|
||||
ifeq ($(HAVE_AVUTIL_REFCOUNTING),no)
|
||||
SOURCES-yes += video/decode/lavc_dr1.c
|
||||
endif
|
||||
|
||||
SOURCES-$(DLOPEN) += video/filter/vf_dlopen.c
|
||||
|
||||
SOURCES = talloc.c \
|
||||
audio/audio.c \
|
||||
SOURCES = audio/audio.c \
|
||||
audio/chmap.c \
|
||||
audio/chmap_sel.c \
|
||||
audio/fmt-conversion.c \
|
||||
@@ -167,8 +181,9 @@ SOURCES = talloc.c \
|
||||
demux/demux_lavf.c \
|
||||
demux/demux_mf.c \
|
||||
demux/demux_mkv.c \
|
||||
demux/demux_subreader.c \
|
||||
demux/demux_playlist.c \
|
||||
demux/demux_raw.c \
|
||||
demux/demux_subreader.c \
|
||||
demux/ebml.c \
|
||||
demux/mf.c \
|
||||
mpvcore/asxparser.c \
|
||||
@@ -203,6 +218,7 @@ SOURCES = talloc.c \
|
||||
osdep/numcores.c \
|
||||
osdep/timer.c \
|
||||
stream/cookies.c \
|
||||
stream/rar.c \
|
||||
stream/stream.c \
|
||||
stream/stream_avdevice.c \
|
||||
stream/stream_file.c \
|
||||
@@ -210,6 +226,7 @@ SOURCES = talloc.c \
|
||||
stream/stream_memory.c \
|
||||
stream/stream_mf.c \
|
||||
stream/stream_null.c \
|
||||
stream/stream_rar.c \
|
||||
sub/dec_sub.c \
|
||||
sub/draw_bmp.c \
|
||||
sub/find_subfiles.c \
|
||||
@@ -223,6 +240,9 @@ SOURCES = talloc.c \
|
||||
sub/sd_srt.c \
|
||||
sub/spudec.c \
|
||||
sub/sub.c \
|
||||
ta/ta.c \
|
||||
ta/ta_utils.c \
|
||||
ta/ta_talloc.c \
|
||||
video/csputils.c \
|
||||
video/fmt-conversion.c \
|
||||
video/image_writer.c \
|
||||
@@ -283,22 +303,29 @@ ALL_TARGETS += mpv$(EXESUF)
|
||||
INSTALL_BIN += install-mpv
|
||||
INSTALL_BIN_STRIP += install-mpv-strip
|
||||
INSTALL_MAN =
|
||||
INSTALL_PDF =
|
||||
|
||||
ifeq ($(BUILD_MAN),yes)
|
||||
INSTALL_MAN += install-mpv-man
|
||||
ALL_TARGETS += DOCS/man/en/mpv.1
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_PDF),yes)
|
||||
INSTALL_PDF += install-mpv-pdf
|
||||
ALL_TARGETS += DOCS/man/en/mpv.pdf
|
||||
endif
|
||||
|
||||
DIRS = . \
|
||||
audio \
|
||||
audio/decode \
|
||||
audio/filter \
|
||||
audio/out \
|
||||
core \
|
||||
mpvcore \
|
||||
mpvcore/input \
|
||||
mpvcore/timeline \
|
||||
demux \
|
||||
osdep \
|
||||
osdep/ar \
|
||||
stream \
|
||||
sub \
|
||||
video \
|
||||
@@ -322,6 +349,12 @@ endif
|
||||
|
||||
all: $(ALL_TARGETS)
|
||||
|
||||
%.tex: %.rst
|
||||
$(RST2LATEX) --config=DOCS/man/docutils.conf $< $@
|
||||
|
||||
%.pdf: %.tex
|
||||
pdflatex -interaction=batchmode -jobname=$(basename $@) $<; pdflatex -interaction=batchmode -jobname=$(basename $@) $<
|
||||
|
||||
%.1: %.rst
|
||||
$(RST2MAN) $< $@
|
||||
|
||||
@@ -366,10 +399,26 @@ video/out/gl_video.c: video/out/gl_video_shaders.h
|
||||
video/out/gl_video_shaders.h: TOOLS/file2string.pl video/out/gl_video_shaders.glsl
|
||||
./$^ >$@
|
||||
|
||||
video/out/x11_common.c: video/out/x11_icon.inc
|
||||
video/out/x11_icon.inc: TOOLS/file2string.pl video/out/x11_icon.bin
|
||||
./$^ >$@
|
||||
|
||||
sub/osd_libass.c: sub/osd_font.h
|
||||
sub/osd_font.h: TOOLS/file2string.pl sub/osd_font.otf
|
||||
./$^ >$@
|
||||
|
||||
mpvcore/mp_lua.c: mpvcore/lua/defaults.inc
|
||||
mpvcore/lua/defaults.inc: TOOLS/file2string.pl mpvcore/lua/defaults.lua
|
||||
./$^ >$@
|
||||
|
||||
mpvcore/mp_lua.c: mpvcore/lua/assdraw.inc
|
||||
mpvcore/lua/assdraw.inc: TOOLS/file2string.pl mpvcore/lua/assdraw.lua
|
||||
./$^ >$@
|
||||
|
||||
mpvcore/mp_lua.c: mpvcore/lua/osc.inc
|
||||
mpvcore/lua/osc.inc: TOOLS/file2string.pl mpvcore/lua/osc.lua
|
||||
./$^ >$@
|
||||
|
||||
# ./configure must be rerun if it changed
|
||||
config.mak: configure
|
||||
@echo "############################################################"
|
||||
@@ -392,22 +441,21 @@ mpvcore/version.c osdep/mpv-rc.o: version.h
|
||||
|
||||
osdep/mpv-rc.o: osdep/mpv.exe.manifest etc/mpv-icon.ico
|
||||
|
||||
DOCS/man/en/mpv.1: DOCS/man/en/af.rst \
|
||||
DOCS/man/en/ao.rst \
|
||||
DOCS/man/en/changes.rst \
|
||||
DOCS/man/en/encode.rst \
|
||||
DOCS/man/en/input.rst \
|
||||
DOCS/man/en/options.rst \
|
||||
DOCS/man/en/vf.rst \
|
||||
DOCS/man/en/vo.rst
|
||||
|
||||
DOCS/man/en/mpv.1 DOCS/man/en/mpv.pdf: DOCS/man/en/af.rst \
|
||||
DOCS/man/en/ao.rst \
|
||||
DOCS/man/en/changes.rst \
|
||||
DOCS/man/en/encode.rst \
|
||||
DOCS/man/en/input.rst \
|
||||
DOCS/man/en/options.rst \
|
||||
DOCS/man/en/vf.rst \
|
||||
DOCS/man/en/vo.rst
|
||||
|
||||
###### installation / clean / generic rules #######
|
||||
|
||||
install: $(INSTALL_BIN) $(INSTALL_MAN)
|
||||
install-no-man: $(INSTALL_BIN)
|
||||
install-strip: $(INSTALL_BIN_STRIP) $(INSTALL_MAN)
|
||||
install-strip-no-man: $(INSTALL_BIN_STRIP)
|
||||
install: $(INSTALL_BIN) install-data $(INSTALL_MAN) $(INSTALL_PDF)
|
||||
install-no-man: $(INSTALL_BIN) install-data
|
||||
install-strip: $(INSTALL_BIN_STRIP) install-data $(INSTALL_MAN) $(INSTALL_PDF)
|
||||
install-strip-no-man: $(INSTALL_BIN_STRIP) install-data
|
||||
|
||||
install-dirs:
|
||||
if test ! -d $(BINDIR) ; then $(INSTALL) -d $(BINDIR) ; fi
|
||||
@@ -424,22 +472,54 @@ install-mpv-man-en: DOCS/man/en/mpv.1
|
||||
if test ! -d $(MANDIR)/man1 ; then $(INSTALL) -d $(MANDIR)/man1 ; fi
|
||||
$(INSTALL) -m 644 DOCS/man/en/mpv.1 $(MANDIR)/man1/
|
||||
|
||||
install-mpv-pdf: install-mpv-pdf-en
|
||||
|
||||
install-mpv-pdf-en: DOCS/man/en/mpv.pdf
|
||||
if test ! -d $(DOCDIR) ; then $(INSTALL) -d $(DOCDIR) ; fi
|
||||
$(INSTALL) -m 644 DOCS/man/en/mpv.pdf $(DOCDIR)/
|
||||
|
||||
ICONSIZES = 16x16 32x32 64x64
|
||||
|
||||
define ICON_INSTALL_RULE
|
||||
install-mpv-icon-$(size): etc/mpv-icon-8bit-$(size).png
|
||||
$(INSTALL) -d $(prefix)/share/icons/hicolor/$(size)/apps
|
||||
$(INSTALL) -m 644 etc/mpv-icon-8bit-$(size).png $(prefix)/share/icons/hicolor/$(size)/apps/mpv.png
|
||||
endef
|
||||
|
||||
$(foreach size,$(ICONSIZES),$(eval $(ICON_INSTALL_RULE)))
|
||||
|
||||
install-mpv-icons: $(foreach size,$(ICONSIZES),install-mpv-icon-$(size))
|
||||
|
||||
install-mpv-desktop: etc/mpv.desktop
|
||||
$(INSTALL) -d $(prefix)/share/applications
|
||||
$(INSTALL) -m 644 etc/mpv.desktop $(prefix)/share/applications/
|
||||
|
||||
install-data: install-mpv-icons install-mpv-desktop
|
||||
|
||||
uninstall:
|
||||
$(RM) $(BINDIR)/mpv$(EXESUF)
|
||||
$(RM) $(MANDIR)/man1/mpv.1
|
||||
$(RM) $(MANDIR)/en/man1/mpv.1
|
||||
$(RM) $(DOCDIR)/mpv.pdf
|
||||
$(RM) $(prefix)/share/applications/mpv.desktop
|
||||
$(RM) $(foreach size,$(ICONSIZES),$(prefix)/share/icons/hicolor/$(size)/apps/mpv.png)
|
||||
|
||||
clean:
|
||||
-$(RM) $(call ADD_ALL_DIRS,/*.o /*.d /*.a /*.ho /*~)
|
||||
-$(RM) $(call ADD_ALL_DIRS,/*.o /*.a /*.ho /*~)
|
||||
-$(RM) $(call ADD_ALL_EXESUFS,mpv)
|
||||
-$(RM) DOCS/man/en/mpv.1
|
||||
-$(RM) $(call ADDSUFFIXES,.pdf .tex .log .aux .out .toc,DOCS/man/*/mpv)
|
||||
-$(RM) DOCS/man/*/mpv.1
|
||||
-$(RM) version.h
|
||||
-$(RM) mpvcore/input/input_conf.h
|
||||
-$(RM) video/out/vdpau_template.c
|
||||
-$(RM) demux/ebml_types.h demux/ebml_defs.c
|
||||
-$(RM) video/out/gl_video_shaders.h
|
||||
-$(RM) video/out/x11_icon.inc
|
||||
-$(RM) sub/osd_font.h
|
||||
-$(RM) mpvcore/lua/defaults.inc
|
||||
-$(RM) mpvcore/lua/assdraw.inc
|
||||
-$(RM) mpvcore/lua/osc.inc
|
||||
|
||||
distclean: clean
|
||||
-$(RM) config.log config.mak config.h TAGS tags
|
||||
|
||||
@@ -47,22 +47,33 @@ If you are running Mac OSX and using homebrew we provide [homebrew-mpv][homebrew
|
||||
to date formula that compiles mpv with sensible dependencies and defaults for
|
||||
OSX.
|
||||
|
||||
configure --enable-* parameters
|
||||
-------------------------------
|
||||
### configure `--enable-*` parameters
|
||||
|
||||
The --enable-* parameters unconditionally force options on, completely
|
||||
The `--enable-*` parameters unconditionally force options on, completely
|
||||
skipping autodetection. This behavior is unlike what you may be used to from
|
||||
autoconf-based configure scripts that can decide to override you. This greater
|
||||
level of control comes at a price. You may have to provide the correct compiler
|
||||
and linker flags yourself.
|
||||
|
||||
If you used one of these options and experience a compilation or
|
||||
linking failure, make sure you have passed the necessary compiler/linker flags
|
||||
to configure.
|
||||
|
||||
mpv's configure script is greedy and automatically enables features as a result
|
||||
of autodetection. The cases where you may want to use `--enable-*` are very
|
||||
limited.
|
||||
|
||||
FFmpeg vs. Libav
|
||||
----------------
|
||||
|
||||
Generally, mpv should work with the latest release as well as the git version
|
||||
of both FFmpeg and Libav. But FFmpeg is preferred, and some mpv features work
|
||||
with FFmpeg only. See the [wiki article][ffmpeg_vs_libav] about the issue.
|
||||
|
||||
Bug reports
|
||||
-----------
|
||||
|
||||
Please use the [issue tracker][issue tracker] provided by GitHub to send us bug
|
||||
Please use the [issue tracker][issue-tracker] provided by GitHub to send us bug
|
||||
reports or feature requests.
|
||||
|
||||
Contributing
|
||||
@@ -75,9 +86,22 @@ make code review easier for both parties later on.
|
||||
Contacts
|
||||
--------
|
||||
|
||||
You can find us on IRC in `#mpv-player` on `irc.freenode.net`
|
||||
These forms of contact are meant to ask questions about mpv usage, give
|
||||
feedback on mpv and discuss it's development.
|
||||
|
||||
If possible, please avoid posting bugs here and use the [issue tracker][issue-tracker]
|
||||
instead.
|
||||
|
||||
- **Users IRC Channel**: `#mpv-player` on `irc.freenode.net`
|
||||
- **Users Mailing List**: `mpv-users@googlegroups.com` ([Archive / Subscribe][mpv-users]).
|
||||
- **Devel Mailing List**: `mpv-devel@googlegroups.com` ([Archive / Subscribe][mpv-devel])
|
||||
|
||||
To contact the `mpv` team in private write to `mpv-team@googlegroups.com`.
|
||||
|
||||
[changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/man/en/changes.rst
|
||||
[mpv-build]: https://github.com/mpv-player/mpv-build
|
||||
[homebrew-mpv]: https://github.com/mpv-player/homebrew-mpv
|
||||
[issue tracker]: https://github.com/mpv-player/mpv/issues
|
||||
[issue-tracker]: https://github.com/mpv-player/mpv/issues
|
||||
[mpv-users]: https://groups.google.com/forum/?hl=en#!forum/mpv-users
|
||||
[mpv-devel]: https://groups.google.com/forum/?hl=en#!forum/mpv-devel
|
||||
[ffmpeg_vs_libav]: https://github.com/mpv-player/mpv/wiki/FFmpeg-versus-Libav
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script is expected to be called as TOOLS/gen-x11-icon.sh (it will access
|
||||
# etc/mpv-icon...), and it will write video/out/x11_icon.bin.
|
||||
|
||||
conv() {
|
||||
echo
|
||||
identify -format "icon: %w %h" $1
|
||||
convert $1 -depth 8 rgba:-
|
||||
}
|
||||
|
||||
(echo "# File generated by gen-x11-icon.sh" ;
|
||||
conv etc/mpv-icon-8bit-16x16.png ;
|
||||
conv etc/mpv-icon-8bit-32x32.png ;
|
||||
conv etc/mpv-icon-8bit-64x64.png) | gzip -c > video/out/x11_icon.bin
|
||||
@@ -104,7 +104,7 @@ for __midentify__key in $__midentify__allprops; do
|
||||
eval unset $__midentify__nextprefix$__midentify__key
|
||||
done
|
||||
|
||||
__midentify__output=`$MPV --playing-msg="$__midentify__propstr" --vo=null --ao=null --frames=1 --quiet "$@"`
|
||||
__midentify__output=`$MPV --playing-msg="$__midentify__propstr" --vo=null --ao=null --frames=1 --quiet --no-cache --no-config "$@"`
|
||||
__midentify__fileindex=0
|
||||
__midentify__prefix=
|
||||
while :; do
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<string>wma</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>audio.icns</string>
|
||||
<string>document.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Audio file</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -86,6 +86,7 @@
|
||||
<string>VCD</string>
|
||||
<string>VFW</string>
|
||||
<string>VOB</string>
|
||||
<string>WEBM</string>
|
||||
<string>WMV</string>
|
||||
<string>asf</string>
|
||||
<string>avi</string>
|
||||
@@ -119,10 +120,11 @@
|
||||
<string>vcd</string>
|
||||
<string>vfw</string>
|
||||
<string>vob</string>
|
||||
<string>webm</string>
|
||||
<string>wmv</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>movie.icns</string>
|
||||
<string>document.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Movie file</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -157,7 +159,7 @@
|
||||
<string>utf</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>subtitles.icns</string>
|
||||
<string>document.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Subtitles file</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
@@ -190,57 +192,41 @@
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>Real Time (Streaming) Protocol</string>
|
||||
<string>mpv Custom Protocol</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>rtp</string>
|
||||
<string>rtsp</string>
|
||||
<string>mpv</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>File over HTTP/FTP/UDP</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>icyx</string>
|
||||
<string>udp</string>
|
||||
<string>ftp</string>
|
||||
<string>http_proxy</string>
|
||||
<string>http</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>Microsoft Media Services</string>
|
||||
<string>Streaming Protocol</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>mms</string>
|
||||
<string>mmst</string>
|
||||
<string>http</string>
|
||||
<string>httpproxy</string>
|
||||
<string>rtp</string>
|
||||
<string>rtsp</string>
|
||||
<string>ftp</string>
|
||||
<string>udp</string>
|
||||
<string>smb</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>Cuesheet</string>
|
||||
<string>CD/DVD/Bluray Media</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>cue</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>CD/DVD Media</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>dvdnav</string>
|
||||
<string>cdda</string>
|
||||
<string>dvd</string>
|
||||
<string>vcd</string>
|
||||
<string>bd</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,64 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
echo >&2 "Usage: $0 input.svg output.ico"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# For smooth rendering on high-DPI displays, the standard three app icon sizes
|
||||
# (16x16, 32x32 and 48x48) have to be scaled to the four Windows DPI settings
|
||||
# as in the table below:
|
||||
|
||||
# Small Regular Tiles
|
||||
# 96 DPI (100%) 16x16 32x32 48x48
|
||||
# 120 DPI (125%) 20x20 40x40 60x60
|
||||
# 144 DPI (150%) 24x24 48x48 72x72
|
||||
# 196 DPI (200%) 32x32 64x64 96x96
|
||||
|
||||
# Also, there should also be an extra large 256x256 icon and some low colour
|
||||
# 8-bit and 4-bit variants, which are still used in Remote Desktop.
|
||||
|
||||
# Note: Windows Vista has a bug in its icon scaling that makes no sense.
|
||||
# Instead of following the DPI setting, small icons are always a bit larger
|
||||
# than they should be at 22x22, 26x26 and 36x36 for 120, 144 and 196 DPI. This
|
||||
# script doesn't generate icons with those sizes, since computers with Vista
|
||||
# and a high-DPI display are probably fairly rare these days.
|
||||
|
||||
temppng=".$(basename "$1" .svg)-temp.png"
|
||||
|
||||
inkscape --without-gui --export-png="$temppng" --export-dpi=72 \
|
||||
--export-background-opacity=0 --export-width=512 --export-height=512 \
|
||||
"$1" >/dev/null 2>&1
|
||||
|
||||
# Old versions of ImageMagick (like the one in Cygwin) use the wrong gamma when
|
||||
# exporting icon files. To fix, add -gamma 2.2 after the input file.
|
||||
|
||||
convert png:"$temppng" -filter lanczos2 \
|
||||
\( -clone 0 -resize 96x96 \) \
|
||||
\( -clone 0 -resize 72x72 \) \
|
||||
\( -clone 0 -resize 64x64 \) \
|
||||
\( -clone 0 -resize 60x60 \) \
|
||||
\( -clone 0 -resize 48x48 \) \
|
||||
\( -clone 0 -resize 40x40 \) \
|
||||
\( -clone 0 -resize 32x32 \) \
|
||||
\( -clone 0 -resize 24x24 \) \
|
||||
\( -clone 0 -resize 20x20 \) \
|
||||
\( -clone 0 -resize 16x16 \) \
|
||||
\( -clone 0 -resize 256x256 \) \
|
||||
\( -clone 0 -resize 32x32 \( -clone 0 -alpha opaque -colors 255 \) \
|
||||
\( -clone 0 -channel A -threshold 50% \) \
|
||||
-delete 0 -compose CopyOpacity -composite -colors 256 \) \
|
||||
\( -clone 0 -resize 16x16 \( -clone 0 -alpha opaque -colors 255 \) \
|
||||
\( -clone 0 -channel A -threshold 50% \) \
|
||||
-delete 0 -compose CopyOpacity -composite -colors 256 \) \
|
||||
\( -clone 0 -resize 32x32 \( -clone 0 -alpha opaque -colors 15 \) \
|
||||
\( -clone 0 -channel A -threshold 50% \) \
|
||||
-delete 0 -compose CopyOpacity -composite -colors 16 \) \
|
||||
\( -clone 0 -resize 16x16 \( -clone 0 -alpha opaque -colors 15 \) \
|
||||
\( -clone 0 -channel A -threshold 50% \) \
|
||||
-delete 0 -compose CopyOpacity -composite -colors 16 \) \
|
||||
-delete 0 \
|
||||
-define png:compression-level=9 -define png:include-chunk=none ico:"$2"
|
||||
|
||||
rm "$temppng"
|
||||
+3
-1
@@ -39,6 +39,8 @@ struct ad_functions {
|
||||
int maxlen);
|
||||
};
|
||||
|
||||
#define ADCTRL_RESYNC_STREAM 1 // resync, called after seeking
|
||||
enum ad_ctrl {
|
||||
ADCTRL_RESYNC_STREAM = 1, // resync, called after seeking
|
||||
};
|
||||
|
||||
#endif /* MPLAYER_AD_H */
|
||||
@@ -389,13 +389,15 @@ static int decode_new_packet(struct sh_audio *sh)
|
||||
}
|
||||
int got_frame = 0;
|
||||
int ret = avcodec_decode_audio4(avctx, priv->avframe, &got_frame, &pkt);
|
||||
if (ret > 0) {
|
||||
// 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
|
||||
}
|
||||
if (mpkt->len == 0 || ret <= 0) {
|
||||
if (mpkt->len == 0 || ret < 0) {
|
||||
talloc_free(mpkt);
|
||||
priv->packet = NULL;
|
||||
}
|
||||
|
||||
+88
-61
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MPEG 1.0/2.0/2.5 audio layer I, II, III decoding with libmpg123
|
||||
*
|
||||
* Copyright (C) 2010-2012 Thomas Orgis <thomas@orgis.org>
|
||||
* Copyright (C) 2010-2013 Thomas Orgis <thomas@orgis.org>
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -47,6 +47,7 @@
|
||||
|
||||
struct ad_mpg123_context {
|
||||
mpg123_handle *handle;
|
||||
char new_format;
|
||||
#ifdef AD_MPG123_MEAN_BITRATE
|
||||
/* Running mean for bit rate, stream length estimation. */
|
||||
float mean_rate;
|
||||
@@ -95,7 +96,9 @@ static int preinit(sh_audio_t *sh)
|
||||
* Let's try to run with the default for now. */
|
||||
|
||||
/* That would produce floating point output.
|
||||
* You can get 32 and 24 bit ints, even 8 bit via format matrix. */
|
||||
* You can get 32 and 24 bit ints, even 8 bit via format matrix.
|
||||
* If wanting a specific encoding here, configure format matrix and
|
||||
* make sure it is in set_format(). */
|
||||
/* mpg123_param(con->handle, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT, 0.); */
|
||||
|
||||
/* Example for RVA choice (available since libmpg123 1.0.0):
|
||||
@@ -184,6 +187,59 @@ static void print_header_compact(struct mpg123_frameinfo *i)
|
||||
smodes[i->mode]);
|
||||
}
|
||||
|
||||
/* libmpg123 has a new format ready; query and store, return return value
|
||||
of mpg123_getformat() */
|
||||
static int set_format(sh_audio_t *sh, struct ad_mpg123_context *con)
|
||||
{
|
||||
int ret;
|
||||
long rate;
|
||||
int channels;
|
||||
int encoding;
|
||||
ret = mpg123_getformat(con->handle, &rate, &channels, &encoding);
|
||||
if(ret == MPG123_OK) {
|
||||
mp_chmap_from_channels(&sh->channels, channels);
|
||||
sh->samplerate = rate;
|
||||
/* Without external force, mpg123 will always choose signed encoding,
|
||||
* and non-16-bit only on builds that don't support it.
|
||||
* Be reminded that it doesn't matter to the MPEG file what encoding
|
||||
* is produced from it. */
|
||||
switch (encoding) {
|
||||
case MPG123_ENC_SIGNED_8:
|
||||
sh->sample_format = AF_FORMAT_S8;
|
||||
sh->samplesize = 1;
|
||||
break;
|
||||
case MPG123_ENC_SIGNED_16:
|
||||
sh->sample_format = AF_FORMAT_S16_NE;
|
||||
sh->samplesize = 2;
|
||||
break;
|
||||
/* To stay compatible with the oldest libmpg123 headers, do not rely
|
||||
* on float and 32 bit encoding symbols being defined.
|
||||
* Those formats came later */
|
||||
case 0x1180: /* MPG123_ENC_SIGNED_32 */
|
||||
sh->sample_format = AF_FORMAT_S32_NE;
|
||||
sh->samplesize = 4;
|
||||
break;
|
||||
case 0x200: /* MPG123_ENC_FLOAT_32 */
|
||||
sh->sample_format = AF_FORMAT_FLOAT_NE;
|
||||
sh->samplesize = 4;
|
||||
break;
|
||||
default:
|
||||
/* This means we got a funny custom build of libmpg123 that only supports an unknown format. */
|
||||
mp_msg(MSGT_DECAUDIO, MSGL_ERR,
|
||||
"Bad encoding from mpg123: %i.\n", encoding);
|
||||
return MPG123_ERR;
|
||||
}
|
||||
#ifdef AD_MPG123_FRAMEWISE
|
||||
/* Going to decode directly to MPlayer's memory. It is important
|
||||
* to have MPG123_AUTO_RESAMPLE disabled for the buffer size
|
||||
* being an all-time limit. */
|
||||
sh->audio_out_minsize = 1152 * 2 * sh->samplesize;
|
||||
#endif
|
||||
con->new_format = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This tries to extract a requested amount of decoded data.
|
||||
* Even when you request 0 bytes, it will feed enough input so that
|
||||
* the decoder _could_ have delivered something.
|
||||
@@ -213,6 +269,9 @@ static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count)
|
||||
* This will be handled in init(). */
|
||||
do {
|
||||
size_t got_now = 0;
|
||||
/* Fetch new format now, after old data has been used. */
|
||||
if(con->new_format)
|
||||
ret = set_format(sh, con);
|
||||
|
||||
/* Feed the decoder. This will only fire from the second round on. */
|
||||
if (ret == MPG123_NEED_MORE) {
|
||||
@@ -237,6 +296,15 @@ static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count)
|
||||
talloc_free(pkt);
|
||||
if (ret == MPG123_ERR)
|
||||
break;
|
||||
|
||||
/* Indication of format change is possible here (from mpg123_decode()). */
|
||||
if(ret == MPG123_NEW_FORMAT) {
|
||||
con->new_format = 1;
|
||||
if(got)
|
||||
break; /* Do not switch format during a chunk. */
|
||||
|
||||
ret = set_format(sh, con);
|
||||
}
|
||||
}
|
||||
/* Theoretically, mpg123 could return MPG123_DONE, so be prepared.
|
||||
* Should not happen in our usage, but it is a valid return code. */
|
||||
@@ -247,7 +315,7 @@ static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count)
|
||||
* for the loop condition. */
|
||||
#ifdef AD_MPG123_FRAMEWISE
|
||||
if (!buf) { /* fake call just for feeding to get format */
|
||||
ret = mpg123_getformat(con->handle, NULL, NULL, NULL);
|
||||
ret = set_format(sh, con);
|
||||
} else { /* This is the decoding. One frame at a time. */
|
||||
ret = mpg123_replace_buffer(con->handle, buf, count);
|
||||
if (ret == MPG123_OK)
|
||||
@@ -261,6 +329,15 @@ static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count)
|
||||
got += got_now;
|
||||
sh->pts_bytes += got_now;
|
||||
|
||||
/* Indication of format change should happen here. */
|
||||
if(ret == MPG123_NEW_FORMAT) {
|
||||
con->new_format = 1;
|
||||
if(got)
|
||||
break; /* Do not switch format during a chunk. */
|
||||
|
||||
ret = set_format(sh, con);
|
||||
}
|
||||
|
||||
#ifdef AD_MPG123_FRAMEWISE
|
||||
} while (ret == MPG123_NEED_MORE || (got == 0 && count != 0));
|
||||
#else
|
||||
@@ -270,8 +347,6 @@ static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count)
|
||||
if (ret == MPG123_ERR) {
|
||||
mp_msg(MSGT_DECAUDIO, MSGL_ERR, "mpg123 decoding failed: %s\n",
|
||||
mpg123_strerror(con->handle));
|
||||
mpg123_close(con->handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return got;
|
||||
@@ -290,39 +365,29 @@ static int reopen_stream(sh_audio_t *sh)
|
||||
/* Open and make sure we have fed enough data to get stream properties. */
|
||||
if (MPG123_OK == mpg123_open_feed(con->handle) &&
|
||||
/* Feed data until mpg123 is ready (has found stream beginning). */
|
||||
!decode_a_bit(sh, NULL, 0)) {
|
||||
!decode_a_bit(sh, NULL, 0) &&
|
||||
set_format(sh, con) == MPG123_OK) { /* format setting again just for return value */
|
||||
return 1;
|
||||
} else {
|
||||
mp_msg(MSGT_DECAUDIO, MSGL_ERR,
|
||||
"mpg123 failed to reopen stream: %s\n",
|
||||
mpg123_strerror(con->handle));
|
||||
mpg123_close(con->handle);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we really start accessing some data and determining file format.
|
||||
* Paranoia note: The mpg123_close() on errors is not really necessary,
|
||||
* But it ensures that we don't accidentally continue decoding with a
|
||||
* bad state (possibly interpreting the format badly or whatnot). */
|
||||
* Format now is allowed to change on-the-fly. Here is the only point
|
||||
* that has MPlayer react to errors. We have to pray that exceptional
|
||||
* erros in other places simply cannot occur. */
|
||||
static int init(sh_audio_t *sh, const char *decoder)
|
||||
{
|
||||
long rate = 0;
|
||||
int channels = 0;
|
||||
int encoding = 0;
|
||||
mpg123_id3v2 *v2;
|
||||
struct mpg123_frameinfo finfo;
|
||||
struct ad_mpg123_context *con = sh->context;
|
||||
|
||||
/* We're open about any output format that libmpg123 will suggest.
|
||||
* Note that a standard build will always default to 16 bit signed and
|
||||
* the native sample rate of the file. */
|
||||
if (MPG123_OK == mpg123_format_all(con->handle) &&
|
||||
reopen_stream(sh) &&
|
||||
MPG123_OK == mpg123_getformat(con->handle, &rate, &channels, &encoding) &&
|
||||
/* Forbid the format to change later on. */
|
||||
MPG123_OK == mpg123_format_none(con->handle) &&
|
||||
MPG123_OK == mpg123_format(con->handle, rate, channels, encoding) &&
|
||||
con->new_format = 0;
|
||||
if (reopen_stream(sh) &&
|
||||
/* Get MPEG header info. */
|
||||
MPG123_OK == mpg123_info(con->handle, &finfo) &&
|
||||
/* Since we queried format, mpg123 should have read past ID3v2 tags.
|
||||
@@ -344,50 +409,11 @@ static int init(sh_audio_t *sh, const char *decoder)
|
||||
con->mean_count = 0;
|
||||
#endif
|
||||
con->vbr = (finfo.vbr != MPG123_CBR);
|
||||
mp_chmap_from_channels(&sh->channels, channels);
|
||||
sh->samplerate = rate;
|
||||
/* Without external force, mpg123 will always choose signed encoding,
|
||||
* and non-16-bit only on builds that don't support it.
|
||||
* Be reminded that it doesn't matter to the MPEG file what encoding
|
||||
* is produced from it. */
|
||||
switch (encoding) {
|
||||
case MPG123_ENC_SIGNED_8:
|
||||
sh->sample_format = AF_FORMAT_S8;
|
||||
sh->samplesize = 1;
|
||||
break;
|
||||
case MPG123_ENC_SIGNED_16:
|
||||
sh->sample_format = AF_FORMAT_S16_NE;
|
||||
sh->samplesize = 2;
|
||||
break;
|
||||
/* To stay compatible with the oldest libmpg123 headers, do not rely
|
||||
* on float and 32 bit encoding symbols being defined.
|
||||
* Those formats came later */
|
||||
case 0x1180: /* MPG123_ENC_SIGNED_32 */
|
||||
sh->sample_format = AF_FORMAT_S32_NE;
|
||||
sh->samplesize = 4;
|
||||
break;
|
||||
case 0x200: /* MPG123_ENC_FLOAT_32 */
|
||||
sh->sample_format = AF_FORMAT_FLOAT_NE;
|
||||
sh->samplesize = 4;
|
||||
break;
|
||||
default:
|
||||
mp_msg(MSGT_DECAUDIO, MSGL_ERR,
|
||||
"Bad encoding from mpg123: %i.\n", encoding);
|
||||
mpg123_close(con->handle);
|
||||
return 0;
|
||||
}
|
||||
#ifdef AD_MPG123_FRAMEWISE
|
||||
/* Going to decode directly to MPlayer's memory. It is important
|
||||
* to have MPG123_AUTO_RESAMPLE disabled for the buffer size
|
||||
* being an all-time limit. */
|
||||
sh->audio_out_minsize = 1152 * 2 * sh->samplesize;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
mp_msg(MSGT_DECAUDIO, MSGL_ERR, "mpg123 init error: %s\n",
|
||||
mpg123_strerror(con->handle));
|
||||
mpg123_close(con->handle);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -432,6 +458,7 @@ static int decode_audio(sh_audio_t *sh, unsigned char *buf, int minlen,
|
||||
int bytes;
|
||||
|
||||
bytes = decode_a_bit(sh, buf, maxlen);
|
||||
/* This EOF is ignored, apparently, until input data is exhausted. */
|
||||
if (bytes == 0)
|
||||
return -1; /* EOF */
|
||||
|
||||
|
||||
+12
-29
@@ -437,8 +437,6 @@ static int af_fix_rate(struct af_stream *s, struct af_instance **p_af,
|
||||
// state (for example, format filters that were tentatively inserted stay
|
||||
// inserted).
|
||||
// In that case, you should always rebuild the filter chain, or abort.
|
||||
// Also, note that for complete reinit, fixup_output_format() may have to be
|
||||
// called after this function.
|
||||
static int af_reinit(struct af_stream *s)
|
||||
{
|
||||
// Start with the second filter, as the first filter is the special input
|
||||
@@ -496,7 +494,12 @@ static int af_reinit(struct af_stream *s)
|
||||
|
||||
af_print_filter_chain(s, NULL, MSGL_V);
|
||||
|
||||
return AF_OK;
|
||||
/* Set previously unset fields in s->output to those of the filter chain
|
||||
* output. This is used to make the output format fixed, and even if you
|
||||
* insert new filters or change the input format, the output format won't
|
||||
* change. (Audio outputs generally can't change format at runtime.) */
|
||||
af_copy_unset_fields(&s->output, &s->filter_output);
|
||||
return af_config_equals(&s->output, &s->filter_output) ? AF_OK : AF_ERROR;
|
||||
|
||||
negotiate_error:
|
||||
mp_msg(MSGT_AFILTER, MSGL_ERR, "[libaf] Unable to correct audio format. "
|
||||
@@ -547,21 +550,6 @@ void af_destroy(struct af_stream *s)
|
||||
talloc_free(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set previously unset fields in s->output to those of the filter chain
|
||||
* output. This is used to make the output format fixed, and even if you insert
|
||||
* new filters or change the input format, the output format won't change.
|
||||
* \return AF_ERROR on error, AF_OK if successful.
|
||||
*/
|
||||
static int fixup_output_format(struct af_stream *s)
|
||||
{
|
||||
if (AF_OK != af_reinit(s))
|
||||
return AF_ERROR;
|
||||
|
||||
af_copy_unset_fields(&s->output, &s->filter_output);
|
||||
return af_config_equals(&s->output, &s->filter_output) ? AF_OK : AF_ERROR;
|
||||
}
|
||||
|
||||
/* Initialize the stream "s". This function creates a new filter list
|
||||
if necessary according to the values set in input and output. Input
|
||||
and output should contain the format of the current movie and the
|
||||
@@ -586,23 +574,18 @@ 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 (!af_prepend(s, s->last, list[i].name, list[i].attribs))
|
||||
if (!af_prepend(s, s->last, list[i].name, list[i].attribs)) {
|
||||
af_uninit(s);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
remove_auto_inserted_filters(s);
|
||||
|
||||
// Init filters
|
||||
if (AF_OK != af_reinit(s))
|
||||
return -1;
|
||||
|
||||
if (AF_OK != fixup_output_format(s)) {
|
||||
if (af_reinit(s) != AF_OK) {
|
||||
// Something is stuffed audio out will not work
|
||||
mp_msg(
|
||||
MSGT_AFILTER, MSGL_ERR,
|
||||
"[libaf] Unable to setup filter system can not"
|
||||
" meet sound-card demands, please send a bug report. \n");
|
||||
mp_msg(MSGT_AFILTER, MSGL_ERR, "Could not create audio filter chain.\n");
|
||||
af_uninit(s);
|
||||
return -1;
|
||||
}
|
||||
@@ -628,7 +611,7 @@ struct af_instance *af_add(struct af_stream *s, char *name, char **args)
|
||||
return NULL;
|
||||
|
||||
// Reinitalize the filter list
|
||||
if (af_reinit(s) != AF_OK || fixup_output_format(s) != AF_OK) {
|
||||
if (af_reinit(s) != AF_OK) {
|
||||
af_uninit(s);
|
||||
af_init(s);
|
||||
return NULL;
|
||||
|
||||
@@ -99,6 +99,11 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
for(i = 1; i < af->data->nch; i++)
|
||||
s->buf[i] = (uint8_t *)s->buf[0] + i*s->sz*af->data->bps;
|
||||
|
||||
if (!s->filename) {
|
||||
mp_msg(MSGT_AFILTER, MSGL_FATAL, "[export] No filename set.\n");
|
||||
return AF_ERROR;
|
||||
}
|
||||
|
||||
// Init memory mapping
|
||||
s->fd = open(s->filename, O_RDWR | O_CREAT | O_TRUNC, 0640);
|
||||
mp_msg(MSGT_AFILTER, MSGL_INFO, "[export] Exporting to file: %s\n", s->filename);
|
||||
|
||||
@@ -150,7 +150,7 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
}
|
||||
case AF_CONTROL_COMMAND_LINE:{
|
||||
int format = af_str2fmt_short(bstr0(arg));
|
||||
if (format == -1) {
|
||||
if (!format) {
|
||||
mp_msg(MSGT_AFILTER, MSGL_ERR, "[format] %s is not a valid format\n", (char *)arg);
|
||||
return AF_ERROR;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#define avresample_alloc_context swr_alloc
|
||||
#define avresample_open swr_init
|
||||
#define avresample_close(x) do { } while(0)
|
||||
#define avresample_free swr_free
|
||||
#define avresample_available(x) 0
|
||||
#define avresample_convert(ctx, out, out_planesize, out_samples, in, in_planesize, in_samples) \
|
||||
swr_convert(ctx, out, out_samples, (const uint8_t**)(in), in_samples)
|
||||
@@ -275,8 +276,10 @@ static void uninit(struct af_instance *af)
|
||||
struct af_resample *s = af->priv;
|
||||
if (s->avrctx)
|
||||
avresample_close(s->avrctx);
|
||||
avresample_free(&s->avrctx);
|
||||
if (s->avrctx_out)
|
||||
avresample_close(s->avrctx_out);
|
||||
avresample_free(&s->avrctx_out);
|
||||
}
|
||||
|
||||
static bool needs_reorder(int *reorder, int num_ch)
|
||||
|
||||
@@ -81,17 +81,22 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
}
|
||||
return af_test_output(af,(struct mp_audio*)arg);
|
||||
case AF_CONTROL_COMMAND_LINE:{
|
||||
float v=0.0;
|
||||
float v=1000.0;
|
||||
float vol[AF_NCH];
|
||||
int i;
|
||||
sscanf((char*)arg,"%f:%i:%i", &v, &s->soft, &s->fast);
|
||||
for(i=0;i<AF_NCH;i++) vol[i]=v;
|
||||
float dest = 0.0;
|
||||
if (v < 1000)
|
||||
af_from_dB(1,&v,&dest,20.0,-200.0,60.0);
|
||||
for(i=0;i<AF_NCH;i++) vol[i]=dest;
|
||||
return control(af,AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET, vol);
|
||||
}
|
||||
case AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET:
|
||||
return af_from_dB(AF_NCH,(float*)arg,s->level,20.0,-200.0,60.0);
|
||||
memcpy(s->level, arg, sizeof(float) * AF_NCH);
|
||||
return AF_OK;
|
||||
case AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_GET:
|
||||
return af_to_dB(AF_NCH,s->level,(float*)arg,20.0);
|
||||
memcpy(arg, s->level, sizeof(float) * AF_NCH);
|
||||
return AF_OK;
|
||||
case AF_CONTROL_PRE_DESTROY:{
|
||||
float m = 0.0;
|
||||
int i;
|
||||
|
||||
@@ -43,7 +43,7 @@ enum AVSampleFormat af_to_avformat(int fmt)
|
||||
if (audio_conversion_map[i].fmt == fmt)
|
||||
break;
|
||||
sample_fmt = audio_conversion_map[i].sample_fmt;
|
||||
if (sample_fmt == AF_FORMAT_UNKNOWN)
|
||||
if (sample_fmt == AV_SAMPLE_FMT_NONE)
|
||||
mp_msg(MSGT_GLOBAL, MSGL_V, "Unsupported sample format: %s\n",
|
||||
af_fmt2str_short(fmt));
|
||||
return sample_fmt;
|
||||
|
||||
+2
-18
@@ -47,11 +47,7 @@ int af_fmt2bits(int format)
|
||||
char* af_fmt2str(int format, char* str, int size)
|
||||
{
|
||||
const char *name = af_fmt2str_short(format);
|
||||
if (name) {
|
||||
snprintf(str, size, "%s", name);
|
||||
} else {
|
||||
snprintf(str, size, "%#x", format);
|
||||
}
|
||||
snprintf(str, size, "%s", name);
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -105,11 +101,6 @@ const char *af_fmt2str_short(int format)
|
||||
return "??";
|
||||
}
|
||||
|
||||
static bool af_fmt_valid(int format)
|
||||
{
|
||||
return (format & AF_FORMAT_MASK) == format;
|
||||
}
|
||||
|
||||
int af_fmt_seconds_to_bytes(int format, float seconds, int channels, int samplerate)
|
||||
{
|
||||
int bps = (af_fmt2bits(format) / 8);
|
||||
@@ -122,16 +113,9 @@ int af_fmt_seconds_to_bytes(int format, float seconds, int channels, int sampler
|
||||
|
||||
int af_str2fmt_short(bstr str)
|
||||
{
|
||||
if (bstr_startswith0(str, "0x")) {
|
||||
bstr rest;
|
||||
int fmt = bstrtoll(str, &rest, 16);
|
||||
if (rest.len == 0 && af_fmt_valid(fmt))
|
||||
return fmt;
|
||||
}
|
||||
|
||||
for (int i = 0; af_fmtstr_table[i].name; i++)
|
||||
if (!bstrcasecmp0(str, af_fmtstr_table[i].name))
|
||||
return af_fmtstr_table[i].format;
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
+7
-7
@@ -43,11 +43,6 @@
|
||||
#define AF_FORMAT_US (1<<1) // Unsigned
|
||||
#define AF_FORMAT_SIGN_MASK (1<<1)
|
||||
|
||||
// Fixed or floating point
|
||||
#define AF_FORMAT_I (0<<2) // Int
|
||||
#define AF_FORMAT_F (1<<2) // Foating point
|
||||
#define AF_FORMAT_POINT_MASK (1<<2)
|
||||
|
||||
// Bits used
|
||||
#define AF_FORMAT_8BIT (0<<3)
|
||||
#define AF_FORMAT_16BIT (1<<3)
|
||||
@@ -62,7 +57,12 @@
|
||||
#define AF_FORMAT_IEC61937 (6<<6)
|
||||
#define AF_FORMAT_SPECIAL_MASK (7<<6)
|
||||
|
||||
#define AF_FORMAT_MASK ((1<<9)-1)
|
||||
// Fixed or floating point
|
||||
#define AF_FORMAT_I (1<<9) // Int
|
||||
#define AF_FORMAT_F (2<<9) // Foating point
|
||||
#define AF_FORMAT_POINT_MASK (3<<9)
|
||||
|
||||
#define AF_FORMAT_MASK ((1<<11)-1)
|
||||
|
||||
// PREDEFINED formats
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
#define AF_FORMAT_IEC61937_NE AF_FORMAT_IEC61937_LE
|
||||
#endif
|
||||
|
||||
#define AF_FORMAT_UNKNOWN (-1)
|
||||
#define AF_FORMAT_UNKNOWN 0
|
||||
|
||||
#define AF_FORMAT_IS_AC3(fmt) (((fmt) & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_AC3)
|
||||
#define AF_FORMAT_IS_IEC61937(fmt) (AF_FORMAT_IS_AC3(fmt) || ((fmt) & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_IEC61937)
|
||||
|
||||
+209
-106
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <libavutil/common.h>
|
||||
|
||||
@@ -24,38 +25,66 @@
|
||||
#include "audio/out/ao.h"
|
||||
#include "audio/filter/af.h"
|
||||
#include "mpvcore/mp_msg.h"
|
||||
#include "talloc.h"
|
||||
#include "mixer.h"
|
||||
|
||||
struct mixer {
|
||||
struct MPOpts *opts;
|
||||
struct ao *ao;
|
||||
struct af_stream *af;
|
||||
// Static, dependent on ao/softvol settings
|
||||
bool softvol; // use AO (true) or af_volume (false)
|
||||
bool emulate_mute; // if true, emulate mute with volume=0
|
||||
// Last known values (possibly out of sync with reality)
|
||||
float vol_l, vol_r;
|
||||
bool muted;
|
||||
// Used to decide whether we should unmute on uninit
|
||||
bool muted_by_us;
|
||||
/* Contains ao driver name or "softvol" if volume is not persistent
|
||||
* and needs to be restored after the driver is reinitialized. */
|
||||
const char *driver;
|
||||
// Other stuff
|
||||
float balance;
|
||||
};
|
||||
|
||||
struct mixer *mixer_init(void *talloc_ctx, struct MPOpts *opts)
|
||||
{
|
||||
struct mixer *mixer = talloc_ptrtype(talloc_ctx, mixer);
|
||||
*mixer = (struct mixer) {
|
||||
.opts = opts,
|
||||
.vol_l = 100,
|
||||
.vol_r = 100,
|
||||
.driver = "",
|
||||
};
|
||||
return mixer;
|
||||
}
|
||||
|
||||
bool mixer_audio_initialized(struct mixer *mixer)
|
||||
{
|
||||
return !!mixer->ao;
|
||||
}
|
||||
|
||||
static void checkvolume(struct mixer *mixer)
|
||||
{
|
||||
if (!mixer->ao)
|
||||
return;
|
||||
|
||||
if (mixer->softvol == SOFTVOL_AUTO) {
|
||||
mixer->softvol = mixer->ao->per_application_mixer
|
||||
|| mixer->ao->no_persistent_volume
|
||||
? SOFTVOL_NO : SOFTVOL_YES;
|
||||
}
|
||||
|
||||
ao_control_vol_t vol;
|
||||
if (mixer->softvol || CONTROL_OK != ao_control(mixer->ao,
|
||||
AOCONTROL_GET_VOLUME, &vol)) {
|
||||
mixer->softvol = SOFTVOL_YES;
|
||||
if (!mixer->afilter)
|
||||
return;
|
||||
float db_vals[AF_NCH];
|
||||
if (!af_control_any_rev(mixer->afilter,
|
||||
AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_GET, db_vals))
|
||||
db_vals[0] = db_vals[1] = 1.0;
|
||||
else
|
||||
af_from_dB(2, db_vals, db_vals, 20.0, -200.0, 60.0);
|
||||
vol.left = (db_vals[0] / (mixer->softvol_max / 100.0)) * 100.0;
|
||||
vol.right = (db_vals[1] / (mixer->softvol_max / 100.0)) * 100.0;
|
||||
ao_control_vol_t vol = {mixer->vol_l, mixer->vol_r};
|
||||
if (mixer->softvol) {
|
||||
float vals[AF_NCH];
|
||||
if (!af_control_any_rev(mixer->af,
|
||||
AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_GET, vals))
|
||||
vals[0] = vals[1] = 1.0;
|
||||
vol.left = (vals[0] / (mixer->opts->softvol_max / 100.0)) * 100.0;
|
||||
vol.right = (vals[1] / (mixer->opts->softvol_max / 100.0)) * 100.0;
|
||||
} else {
|
||||
// Rely on the values not changing if the query is not supported
|
||||
ao_control(mixer->ao, AOCONTROL_GET_VOLUME, &vol);
|
||||
ao_control(mixer->ao, AOCONTROL_GET_MUTE, &mixer->muted);
|
||||
}
|
||||
float l = mixer->vol_l;
|
||||
float r = mixer->vol_r;
|
||||
if (mixer->muted_using_volume)
|
||||
if (mixer->emulate_mute && mixer->muted)
|
||||
l = r = 0;
|
||||
/* Try to detect cases where the volume has been changed by some external
|
||||
* action (such as something else changing a shared system-wide volume).
|
||||
@@ -67,73 +96,59 @@ static void checkvolume(struct mixer *mixer)
|
||||
if (FFABS(vol.left - l) >= 3 || FFABS(vol.right - r) >= 3) {
|
||||
mixer->vol_l = vol.left;
|
||||
mixer->vol_r = vol.right;
|
||||
if (mixer->muted_using_volume)
|
||||
if (mixer->emulate_mute)
|
||||
mixer->muted = false;
|
||||
}
|
||||
if (!mixer->softvol)
|
||||
// Rely on the value not changing if the query is not supported
|
||||
ao_control(mixer->ao, AOCONTROL_GET_MUTE, &mixer->muted);
|
||||
mixer->muted_by_us &= mixer->muted;
|
||||
mixer->muted_using_volume &= mixer->muted;
|
||||
}
|
||||
|
||||
void mixer_getvolume(mixer_t *mixer, float *l, float *r)
|
||||
void mixer_getvolume(struct mixer *mixer, float *l, float *r)
|
||||
{
|
||||
checkvolume(mixer);
|
||||
*l = mixer->vol_l;
|
||||
*r = mixer->vol_r;
|
||||
}
|
||||
|
||||
static void setvolume_internal(mixer_t *mixer, float l, float r)
|
||||
static void setvolume_internal(struct mixer *mixer, float l, float r)
|
||||
{
|
||||
struct ao_control_vol vol = {.left = l, .right = r};
|
||||
if (!mixer->softvol) {
|
||||
// relies on the driver data being permanent (so ptr stays valid)
|
||||
mixer->restore_volume = mixer->ao->no_persistent_volume ?
|
||||
mixer->ao->driver->info->short_name : NULL;
|
||||
if (ao_control(mixer->ao, AOCONTROL_SET_VOLUME, &vol) != CONTROL_OK)
|
||||
mp_tmsg(MSGT_GLOBAL, MSGL_ERR,
|
||||
"[Mixer] Failed to change audio output volume.\n");
|
||||
return;
|
||||
}
|
||||
mixer->restore_volume = "softvol";
|
||||
if (!mixer->afilter)
|
||||
return;
|
||||
// af_volume uses values in dB
|
||||
float db_vals[AF_NCH];
|
||||
int i;
|
||||
db_vals[0] = (l / 100.0) * (mixer->softvol_max / 100.0);
|
||||
db_vals[1] = (r / 100.0) * (mixer->softvol_max / 100.0);
|
||||
for (i = 2; i < AF_NCH; i++)
|
||||
db_vals[i] = ((l + r) / 100.0) * (mixer->softvol_max / 100.0) / 2.0;
|
||||
af_to_dB(AF_NCH, db_vals, db_vals, 20.0);
|
||||
if (!af_control_any_rev(mixer->afilter,
|
||||
float vals[AF_NCH];
|
||||
vals[0] = l / 100.0 * mixer->opts->softvol_max / 100.0;
|
||||
vals[1] = r / 100.0 * mixer->opts->softvol_max / 100.0;
|
||||
for (int i = 2; i < AF_NCH; i++)
|
||||
vals[i] = (vals[0] + vals[1]) / 2.0;
|
||||
if (!af_control_any_rev(mixer->af,
|
||||
AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET,
|
||||
db_vals))
|
||||
vals))
|
||||
{
|
||||
mp_tmsg(MSGT_GLOBAL, mixer->softvol ? MSGL_V : MSGL_WARN,
|
||||
"[Mixer] No hardware mixing, inserting volume filter.\n");
|
||||
if (!(af_add(mixer->afilter, "volume", NULL)
|
||||
&& af_control_any_rev(mixer->afilter,
|
||||
mp_tmsg(MSGT_GLOBAL, MSGL_V, "[Mixer] Inserting volume filter.\n");
|
||||
if (!(af_add(mixer->af, "volume", NULL)
|
||||
&& af_control_any_rev(mixer->af,
|
||||
AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET,
|
||||
db_vals)))
|
||||
vals)))
|
||||
mp_tmsg(MSGT_GLOBAL, MSGL_ERR,
|
||||
"[Mixer] No volume control available.\n");
|
||||
}
|
||||
}
|
||||
|
||||
void mixer_setvolume(mixer_t *mixer, float l, float r)
|
||||
void mixer_setvolume(struct mixer *mixer, float l, float r)
|
||||
{
|
||||
checkvolume(mixer); // to check mute status and AO support for volume
|
||||
checkvolume(mixer); // to check mute status
|
||||
if (mixer->vol_l == l && mixer->vol_r == r)
|
||||
return; // just prevent af_volume insertion when not needed
|
||||
mixer->vol_l = av_clipf(l, 0, 100);
|
||||
mixer->vol_r = av_clipf(r, 0, 100);
|
||||
if (!mixer->ao || mixer->muted_using_volume)
|
||||
return;
|
||||
setvolume_internal(mixer, mixer->vol_l, mixer->vol_r);
|
||||
mixer->user_set_volume = true;
|
||||
if (mixer->ao && !(mixer->emulate_mute && mixer->muted))
|
||||
setvolume_internal(mixer, mixer->vol_l, mixer->vol_r);
|
||||
}
|
||||
|
||||
void mixer_getbothvolume(mixer_t *mixer, float *b)
|
||||
void mixer_getbothvolume(struct mixer *mixer, float *b)
|
||||
{
|
||||
float mixer_l, mixer_r;
|
||||
mixer_getvolume(mixer, &mixer_l, &mixer_r);
|
||||
@@ -143,17 +158,20 @@ void mixer_getbothvolume(mixer_t *mixer, float *b)
|
||||
void mixer_setmute(struct mixer *mixer, bool mute)
|
||||
{
|
||||
checkvolume(mixer);
|
||||
if (mute != mixer->muted) {
|
||||
if (!mixer->softvol && !mixer->muted_using_volume && ao_control(
|
||||
mixer->ao, AOCONTROL_SET_MUTE, &mute) == CONTROL_OK) {
|
||||
mixer->muted_using_volume = false;
|
||||
if (mute == mixer->muted)
|
||||
return;
|
||||
if (mixer->ao) {
|
||||
mixer->muted = mute;
|
||||
mixer->muted_by_us = mute;
|
||||
if (mixer->emulate_mute) {
|
||||
setvolume_internal(mixer, mixer->vol_l*!mute, mixer->vol_r*!mute);
|
||||
} else {
|
||||
setvolume_internal(mixer, mixer->vol_l*!mute, mixer->vol_r*!mute);
|
||||
mixer->muted_using_volume = mute;
|
||||
ao_control(mixer->ao, AOCONTROL_SET_MUTE, &mute);
|
||||
}
|
||||
checkvolume(mixer);
|
||||
} else {
|
||||
mixer->muted = mute;
|
||||
mixer->muted_by_us = mute;
|
||||
mixer->user_set_mute = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,26 +183,25 @@ bool mixer_getmute(struct mixer *mixer)
|
||||
|
||||
static void addvolume(struct mixer *mixer, float d)
|
||||
{
|
||||
checkvolume(mixer);
|
||||
mixer_setvolume(mixer, mixer->vol_l + d, mixer->vol_r + d);
|
||||
if (d > 0)
|
||||
mixer_setmute(mixer, false);
|
||||
float vol_l, vol_r;
|
||||
mixer_getvolume(mixer, &vol_l, &vol_r);
|
||||
mixer_setvolume(mixer, vol_l + d, vol_r + d);
|
||||
}
|
||||
|
||||
void mixer_incvolume(mixer_t *mixer)
|
||||
void mixer_incvolume(struct mixer *mixer)
|
||||
{
|
||||
addvolume(mixer, mixer->volstep);
|
||||
addvolume(mixer, mixer->opts->volstep);
|
||||
}
|
||||
|
||||
void mixer_decvolume(mixer_t *mixer)
|
||||
void mixer_decvolume(struct mixer *mixer)
|
||||
{
|
||||
addvolume(mixer, -mixer->volstep);
|
||||
addvolume(mixer, -mixer->opts->volstep);
|
||||
}
|
||||
|
||||
void mixer_getbalance(mixer_t *mixer, float *val)
|
||||
void mixer_getbalance(struct mixer *mixer, float *val)
|
||||
{
|
||||
if (mixer->afilter)
|
||||
af_control_any_rev(mixer->afilter,
|
||||
if (mixer->af)
|
||||
af_control_any_rev(mixer->af,
|
||||
AF_CONTROL_PAN_BALANCE | AF_CONTROL_GET,
|
||||
&mixer->balance);
|
||||
*val = mixer->balance;
|
||||
@@ -201,7 +218,7 @@ void mixer_getbalance(mixer_t *mixer, float *val)
|
||||
* are significantly below 1 will be overwritten with much higher values.
|
||||
*/
|
||||
|
||||
void mixer_setbalance(mixer_t *mixer, float val)
|
||||
void mixer_setbalance(struct mixer *mixer, float val)
|
||||
{
|
||||
float level[AF_NCH];
|
||||
int i;
|
||||
@@ -210,23 +227,22 @@ void mixer_setbalance(mixer_t *mixer, float val)
|
||||
|
||||
mixer->balance = val;
|
||||
|
||||
if (!mixer->afilter)
|
||||
if (!mixer->af)
|
||||
return;
|
||||
|
||||
if (af_control_any_rev(mixer->afilter,
|
||||
if (af_control_any_rev(mixer->af,
|
||||
AF_CONTROL_PAN_BALANCE | AF_CONTROL_SET, &val))
|
||||
return;
|
||||
|
||||
if (val == 0 || mixer->ao->channels.num < 2)
|
||||
return;
|
||||
|
||||
if (!(af_pan_balance = af_add(mixer->afilter, "pan", NULL))) {
|
||||
if (!(af_pan_balance = af_add(mixer->af, "pan", NULL))) {
|
||||
mp_tmsg(MSGT_GLOBAL, MSGL_ERR,
|
||||
"[Mixer] No balance control available.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
af_init(mixer->afilter);
|
||||
/* make all other channels pass thru since by default pan blocks all */
|
||||
memset(level, 0, sizeof(level));
|
||||
for (i = 2; i < AF_NCH; i++) {
|
||||
@@ -242,39 +258,125 @@ void mixer_setbalance(mixer_t *mixer, float val)
|
||||
AF_CONTROL_PAN_BALANCE | AF_CONTROL_SET, &val);
|
||||
}
|
||||
|
||||
// Called after the audio filter chain is built or rebuilt.
|
||||
void mixer_reinit(struct mixer *mixer, struct ao *ao)
|
||||
char *mixer_get_volume_restore_data(struct mixer *mixer)
|
||||
{
|
||||
mixer->ao = ao;
|
||||
/* Use checkvolume() to see if softvol needs to be enabled because of
|
||||
* lacking AO support, but first store values it could overwrite. */
|
||||
float left = mixer->vol_l, right = mixer->vol_r;
|
||||
bool muted = mixer->muted_by_us;
|
||||
checkvolume(mixer);
|
||||
/* Try to avoid restoring volume stored from one control method with
|
||||
* another. Especially, restoring softvol volume (typically high) on
|
||||
* system mixer could have very nasty effects. */
|
||||
const char *restore_reason = mixer->softvol ? "softvol" :
|
||||
mixer->ao->driver->info->short_name;
|
||||
if (mixer->restore_volume && !strcmp(mixer->restore_volume,
|
||||
restore_reason))
|
||||
mixer_setvolume(mixer, left, right);
|
||||
/* We turn mute off at AO uninit, so it has to be restored (unless
|
||||
* we're reinitializing filter chain while keeping AO); but we only
|
||||
* enable mute, not turn external mute off. */
|
||||
if (muted)
|
||||
mixer_setmute(mixer, true);
|
||||
if (mixer->balance != 0)
|
||||
mixer_setbalance(mixer, mixer->balance);
|
||||
mixer->user_set_mute = false;
|
||||
mixer->user_set_volume = false;
|
||||
if (!mixer->driver[0])
|
||||
return NULL;
|
||||
return talloc_asprintf(NULL, "%s:%f:%f:%d", mixer->driver, mixer->vol_l,
|
||||
mixer->vol_r, mixer->muted_by_us);
|
||||
}
|
||||
|
||||
/* Called before uninitializing the audio output. The main purpose is to
|
||||
static void probe_softvol(struct mixer *mixer)
|
||||
{
|
||||
if (mixer->opts->softvol == SOFTVOL_AUTO) {
|
||||
// No system-wide volume => fine with AO volume control.
|
||||
mixer->softvol = !(mixer->ao->per_application_mixer ||
|
||||
mixer->ao->no_persistent_volume);
|
||||
} else {
|
||||
mixer->softvol = mixer->opts->softvol == SOFTVOL_YES;
|
||||
}
|
||||
|
||||
// If we can't use real volume control => force softvol.
|
||||
if (!mixer->softvol) {
|
||||
ao_control_vol_t vol;
|
||||
if (ao_control(mixer->ao, AOCONTROL_GET_VOLUME, &vol) != CONTROL_OK) {
|
||||
mixer->softvol = true;
|
||||
mp_tmsg(MSGT_GLOBAL, MSGL_WARN,
|
||||
"[mixer] Hardware volume control unavailable.\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Probe native mute support.
|
||||
mixer->emulate_mute = true;
|
||||
if (!mixer->softvol) {
|
||||
if (ao_control(mixer->ao, AOCONTROL_GET_MUTE, &(bool){0}) == CONTROL_OK)
|
||||
mixer->emulate_mute = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void restore_volume(struct mixer *mixer)
|
||||
{
|
||||
struct MPOpts *opts = mixer->opts;
|
||||
struct ao *ao = mixer->ao;
|
||||
|
||||
float force_vol_l = -1, force_vol_r = -1;
|
||||
int force_mute = -1;
|
||||
|
||||
const char *prev_driver = mixer->driver;
|
||||
mixer->driver = mixer->softvol ? "softvol" : ao->driver->info->short_name;
|
||||
|
||||
bool restore = mixer->softvol || ao->no_persistent_volume;
|
||||
|
||||
// Restore old parameters if volume won't survive reinitialization.
|
||||
// But not if volume scale is possibly different.
|
||||
if (restore && strcmp(mixer->driver, prev_driver) == 0) {
|
||||
force_vol_l = mixer->vol_l;
|
||||
force_vol_r = mixer->vol_r;
|
||||
}
|
||||
|
||||
// Set mute if we disabled it on uninit last time.
|
||||
if (mixer->muted_by_us)
|
||||
force_mute = 1;
|
||||
|
||||
// Set parameters from command line.
|
||||
if (opts->mixer_init_volume >= 0)
|
||||
force_vol_l = force_vol_r = opts->mixer_init_volume;
|
||||
if (opts->mixer_init_mute >= 0)
|
||||
force_mute = opts->mixer_init_mute;
|
||||
|
||||
// Set parameters from playback resume.
|
||||
char *restore_data = mixer->opts->mixer_restore_volume_data;
|
||||
if (restore && restore_data && restore_data[0]) {
|
||||
char drv[40];
|
||||
float v_l, v_r;
|
||||
int m;
|
||||
if (sscanf(restore_data, "%39[^:]:%f:%f:%d", drv, &v_l, &v_r, &m) == 4) {
|
||||
if (strcmp(mixer->driver, drv) == 0) {
|
||||
force_vol_l = v_l;
|
||||
force_vol_r = v_r;
|
||||
force_mute = !!m;
|
||||
}
|
||||
}
|
||||
talloc_free(restore_data);
|
||||
mixer->opts->mixer_restore_volume_data = NULL;
|
||||
}
|
||||
|
||||
// Using --volume should not reset the volume on every file (i.e. reinit),
|
||||
// OTOH mpv --{ --volume 10 f1.mkv --} --{ --volume 20 f2.mkv --} must work.
|
||||
// Resetting the option volumes to "auto" (-1) is easiest. If file local
|
||||
// options (as shown above) are used, the option handler code will reset
|
||||
// them to other values, and force the volume to be reset as well.
|
||||
opts->mixer_init_volume = -1;
|
||||
opts->mixer_init_mute = -1;
|
||||
|
||||
checkvolume(mixer);
|
||||
if (force_vol_l >= 0 && force_vol_r >= 0)
|
||||
mixer_setvolume(mixer, force_vol_l, force_vol_r);
|
||||
if (force_mute >= 0)
|
||||
mixer_setmute(mixer, force_mute);
|
||||
}
|
||||
|
||||
// Called after the audio filter chain is built or rebuilt.
|
||||
// (Can be called multiple times, even without mixer_uninit() in-between.)
|
||||
void mixer_reinit_audio(struct mixer *mixer, struct ao *ao, struct af_stream *af)
|
||||
{
|
||||
if (!ao || !af)
|
||||
return;
|
||||
mixer->ao = ao;
|
||||
mixer->af = af;
|
||||
|
||||
probe_softvol(mixer);
|
||||
restore_volume(mixer);
|
||||
|
||||
if (mixer->balance != 0)
|
||||
mixer_setbalance(mixer, mixer->balance);
|
||||
}
|
||||
|
||||
/* Called before uninitializing the audio filter chain. The main purpose is to
|
||||
* turn off mute, in case it's a global/persistent setting which might
|
||||
* otherwise be left enabled even after this player instance exits.
|
||||
*/
|
||||
void mixer_uninit(struct mixer *mixer)
|
||||
void mixer_uninit_audio(struct mixer *mixer)
|
||||
{
|
||||
if (!mixer->ao)
|
||||
return;
|
||||
@@ -294,4 +396,5 @@ void mixer_uninit(struct mixer *mixer)
|
||||
mixer->muted_by_us = true;
|
||||
}
|
||||
mixer->ao = NULL;
|
||||
mixer->af = NULL;
|
||||
}
|
||||
+19
-28
@@ -21,40 +21,31 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// Values of MPOpts.softvol
|
||||
enum {
|
||||
SOFTVOL_NO = 0,
|
||||
SOFTVOL_YES = 1,
|
||||
SOFTVOL_AUTO = 2,
|
||||
};
|
||||
|
||||
typedef struct mixer {
|
||||
struct ao *ao;
|
||||
struct af_stream *afilter;
|
||||
int volstep;
|
||||
int softvol;
|
||||
float softvol_max;
|
||||
bool muted;
|
||||
bool muted_by_us;
|
||||
bool muted_using_volume;
|
||||
float vol_l, vol_r;
|
||||
/* Contains ao driver name or "softvol" if volume is not persistent
|
||||
* and needs to be restored after the driver is reinitialized. */
|
||||
const char *restore_volume;
|
||||
float balance;
|
||||
bool user_set_mute;
|
||||
bool user_set_volume;
|
||||
} mixer_t;
|
||||
struct MPOpts;
|
||||
struct ao;
|
||||
struct af_stream;
|
||||
struct mixer;
|
||||
|
||||
void mixer_reinit(struct mixer *mixer, struct ao *ao);
|
||||
void mixer_uninit(struct mixer *mixer);
|
||||
void mixer_getvolume(mixer_t *mixer, float *l, float *r);
|
||||
void mixer_setvolume(mixer_t *mixer, float l, float r);
|
||||
void mixer_incvolume(mixer_t *mixer);
|
||||
void mixer_decvolume(mixer_t *mixer);
|
||||
void mixer_getbothvolume(mixer_t *mixer, float *b);
|
||||
void mixer_setmute(mixer_t *mixer, bool mute);
|
||||
bool mixer_getmute(mixer_t *mixer);
|
||||
void mixer_getbalance(mixer_t *mixer, float *bal);
|
||||
void mixer_setbalance(mixer_t *mixer, float bal);
|
||||
struct mixer *mixer_init(void *talloc_ctx, struct MPOpts *opts);
|
||||
void mixer_reinit_audio(struct mixer *mixer, struct ao *ao, struct af_stream *af);
|
||||
void mixer_uninit_audio(struct mixer *mixer);
|
||||
bool mixer_audio_initialized(struct mixer *mixer);
|
||||
void mixer_getvolume(struct mixer *mixer, float *l, float *r);
|
||||
void mixer_setvolume(struct mixer *mixer, float l, float r);
|
||||
void mixer_incvolume(struct mixer *mixer);
|
||||
void mixer_decvolume(struct mixer *mixer);
|
||||
void mixer_getbothvolume(struct mixer *mixer, float *b);
|
||||
void mixer_setmute(struct mixer *mixer, bool mute);
|
||||
bool mixer_getmute(struct mixer *mixer);
|
||||
void mixer_getbalance(struct mixer *mixer, float *bal);
|
||||
void mixer_setbalance(struct mixer *mixer, float bal);
|
||||
char *mixer_get_volume_restore_data(struct mixer *mixer);
|
||||
|
||||
#endif /* MPLAYER_MIXER_H */
|
||||
+4
-5
@@ -32,13 +32,10 @@
|
||||
#include "mpvcore/mp_msg.h"
|
||||
#include "mpvcore/mpv_global.h"
|
||||
|
||||
// there are some globals:
|
||||
struct ao *global_ao;
|
||||
char *ao_subdevice = NULL;
|
||||
|
||||
extern const struct ao_driver audio_out_oss;
|
||||
extern const struct ao_driver audio_out_coreaudio;
|
||||
extern const struct ao_driver audio_out_rsound;
|
||||
extern const struct ao_driver audio_out_sndio;
|
||||
extern const struct ao_driver audio_out_pulse;
|
||||
extern const struct ao_driver audio_out_jack;
|
||||
extern const struct ao_driver audio_out_openal;
|
||||
@@ -47,7 +44,6 @@ extern const struct ao_driver audio_out_alsa;
|
||||
extern const struct ao_driver audio_out_dsound;
|
||||
extern const struct ao_driver audio_out_wasapi;
|
||||
extern const struct ao_driver audio_out_pcm;
|
||||
extern const struct ao_driver audio_out_pss;
|
||||
extern const struct ao_driver audio_out_lavc;
|
||||
extern const struct ao_driver audio_out_portaudio;
|
||||
extern const struct ao_driver audio_out_sdl;
|
||||
@@ -60,6 +56,9 @@ static const struct ao_driver * const audio_out_drivers[] = {
|
||||
#ifdef CONFIG_PULSE
|
||||
&audio_out_pulse,
|
||||
#endif
|
||||
#ifdef CONFIG_SNDIO
|
||||
&audio_out_sndio,
|
||||
#endif
|
||||
#ifdef CONFIG_ALSA
|
||||
&audio_out_alsa,
|
||||
#endif
|
||||
|
||||
@@ -96,8 +96,6 @@ struct ao {
|
||||
struct mp_log *log; // Using e.g. "[ao/coreaudio]" as prefix
|
||||
};
|
||||
|
||||
extern char *ao_subdevice;
|
||||
|
||||
struct mpv_global;
|
||||
struct ao *ao_init_best(struct mpv_global *global,
|
||||
struct input_ctx *input_ctx,
|
||||
|
||||
+35
-56
@@ -33,12 +33,10 @@
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <alloca.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "mpvcore/options.h"
|
||||
#include "mpvcore/m_option.h"
|
||||
#include "audio/mixer.h"
|
||||
#include "mpvcore/mp_msg.h"
|
||||
|
||||
#define ALSA_PCM_NEW_HW_PARAMS_API
|
||||
@@ -73,8 +71,7 @@ struct priv {
|
||||
#define CHECK_ALSA_ERROR(message) \
|
||||
do { \
|
||||
if (err < 0) { \
|
||||
mp_msg(MSGT_VO, MSGL_ERR, "[AO_ALSA] %s: %s\n", \
|
||||
(message), snd_strerror(err)); \
|
||||
MP_ERR(ao, "%s: %s\n", (message), snd_strerror(err)); \
|
||||
goto alsa_error; \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -94,10 +91,10 @@ static void alsa_error_handler(const char *file, int line, const char *function,
|
||||
va_end(va);
|
||||
|
||||
if (err) {
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "[AO_ALSA] alsa-lib: %s:%i:(%s) %s: %s\n",
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "alsa-lib: %s:%i:(%s) %s: %s\n",
|
||||
file, line, function, tmp, snd_strerror(err));
|
||||
} else {
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "[AO_ALSA] alsa-lib: %s:%i:(%s) %s\n",
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "alsa-lib: %s:%i:(%s) %s\n",
|
||||
file, line, function, tmp);
|
||||
}
|
||||
}
|
||||
@@ -145,10 +142,9 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
|
||||
elem = snd_mixer_find_selem(handle, sid);
|
||||
if (!elem) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR,
|
||||
"[AO_ALSA] Unable to find simple control '%s',%i.\n",
|
||||
snd_mixer_selem_id_get_name(sid),
|
||||
snd_mixer_selem_id_get_index(sid));
|
||||
MP_VERBOSE(ao, "Unable to find simple control '%s',%i.\n",
|
||||
snd_mixer_selem_id_get_name(sid),
|
||||
snd_mixer_selem_id_get_index(sid));
|
||||
goto alsa_error;
|
||||
}
|
||||
|
||||
@@ -164,15 +160,14 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
err = snd_mixer_selem_set_playback_volume
|
||||
(elem, SND_MIXER_SCHN_FRONT_LEFT, set_vol);
|
||||
CHECK_ALSA_ERROR("Error setting left channel");
|
||||
mp_msg(MSGT_AO, MSGL_DBG2, "left=%li, ", set_vol);
|
||||
MP_DBG(ao, "left=%li, ", set_vol);
|
||||
|
||||
set_vol = vol->right / f_multi + pmin + 0.5;
|
||||
|
||||
err = snd_mixer_selem_set_playback_volume
|
||||
(elem, SND_MIXER_SCHN_FRONT_RIGHT, set_vol);
|
||||
CHECK_ALSA_ERROR("Error setting right channel");
|
||||
mp_msg(MSGT_AO, MSGL_DBG2,
|
||||
"right=%li, pmin=%li, pmax=%li, mult=%f\n",
|
||||
MP_DBG(ao, "right=%li, pmin=%li, pmax=%li, mult=%f\n",
|
||||
set_vol, pmin, pmax,
|
||||
f_multi);
|
||||
break;
|
||||
@@ -185,8 +180,7 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
snd_mixer_selem_get_playback_volume
|
||||
(elem, SND_MIXER_SCHN_FRONT_RIGHT, &get_vol);
|
||||
vol->right = (get_vol - pmin) * f_multi;
|
||||
mp_msg(MSGT_AO, MSGL_DBG2, "left=%f, right=%f\n", vol->left,
|
||||
vol->right);
|
||||
MP_DBG(ao, "left=%f, right=%f\n", vol->left, vol->right);
|
||||
break;
|
||||
}
|
||||
case AOCONTROL_SET_MUTE: {
|
||||
@@ -303,9 +297,8 @@ static const char *select_chmap(struct ao *ao)
|
||||
}
|
||||
|
||||
char *name = mp_chmap_to_str(&ao->channels);
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR,
|
||||
"[AO_ALSA] channel layout %s (%d ch) not supported.\n",
|
||||
name, ao->channels.num);
|
||||
MP_ERR(ao, "channel layout %s (%d ch) not supported.\n",
|
||||
name, ao->channels.num);
|
||||
talloc_free(name);
|
||||
return "default";
|
||||
}
|
||||
@@ -370,9 +363,8 @@ static int init(struct ao *ao)
|
||||
|
||||
struct priv *p = ao->priv;
|
||||
|
||||
mp_msg(MSGT_AO, MSGL_V,
|
||||
"alsa-init: requested format: %d Hz, %d channels, %x\n",
|
||||
ao->samplerate, ao->channels.num, ao->format);
|
||||
MP_VERBOSE(ao, "requested format: %d Hz, %d channels, %x\n",
|
||||
ao->samplerate, ao->channels.num, ao->format);
|
||||
|
||||
p->prepause_frames = 0;
|
||||
p->delay_before_pause = 0;
|
||||
@@ -386,9 +378,8 @@ static int init(struct ao *ao)
|
||||
const char *device;
|
||||
if (AF_FORMAT_IS_IEC61937(ao->format)) {
|
||||
device = "iec958";
|
||||
mp_msg(MSGT_AO, MSGL_V,
|
||||
"alsa-spdif-init: playing AC3/iec61937/iec958, %i channels\n",
|
||||
ao->channels.num);
|
||||
MP_VERBOSE(ao, "playing AC3/iec61937/iec958, %i channels\n",
|
||||
ao->channels.num);
|
||||
} else {
|
||||
device = select_chmap(ao);
|
||||
if (strcmp(device, "default") != 0 && ao->format == AF_FORMAT_FLOAT_NE)
|
||||
@@ -400,11 +391,11 @@ static int init(struct ao *ao)
|
||||
if (p->cfg_device && p->cfg_device[0])
|
||||
device = p->cfg_device;
|
||||
|
||||
mp_msg(MSGT_AO, MSGL_V, "alsa-init: using device %s\n", device);
|
||||
MP_VERBOSE(ao, "using device: %s\n", device);
|
||||
|
||||
p->can_pause = 1;
|
||||
|
||||
mp_msg(MSGT_AO, MSGL_V, "alsa-init: using ALSA %s\n", snd_asoundlib_version());
|
||||
MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version());
|
||||
snd_lib_error_set_handler(alsa_error_handler);
|
||||
|
||||
int open_mode = p->cfg_block ? 0 : SND_PCM_NONBLOCK;
|
||||
@@ -413,7 +404,7 @@ static int init(struct ao *ao)
|
||||
err = try_open_device(ao, device, open_mode, isac3);
|
||||
if (err < 0) {
|
||||
if (err != -EBUSY && !p->cfg_block) {
|
||||
mp_tmsg(MSGT_AO, MSGL_INFO, "[AO_ALSA] Open in nonblock-mode "
|
||||
MP_WARN(ao, "Open in nonblock-mode "
|
||||
"failed, trying to open in block-mode.\n");
|
||||
err = try_open_device(ao, device, 0, isac3);
|
||||
}
|
||||
@@ -422,11 +413,9 @@ static int init(struct ao *ao)
|
||||
|
||||
err = snd_pcm_nonblock(p->alsa, 0);
|
||||
if (err < 0) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR,
|
||||
"[AL_ALSA] Error setting block-mode %s.\n",
|
||||
snd_strerror(err));
|
||||
MP_ERR(ao, "Error setting block-mode: %s.\n", snd_strerror(err));
|
||||
} else {
|
||||
mp_msg(MSGT_AO, MSGL_V, "alsa-init: pcm opened in blocking mode\n");
|
||||
MP_VERBOSE(ao, "pcm opened in blocking mode\n");
|
||||
}
|
||||
|
||||
snd_pcm_hw_params_t *alsa_hwparams;
|
||||
@@ -451,8 +440,8 @@ static int init(struct ao *ao)
|
||||
|
||||
err = snd_pcm_hw_params_test_format(p->alsa, alsa_hwparams, p->alsa_fmt);
|
||||
if (err < 0) {
|
||||
mp_tmsg(MSGT_AO, MSGL_INFO, "[AO_ALSA] Format %s is not supported "
|
||||
"by hardware, trying default.\n", af_fmt2str_short(ao->format));
|
||||
MP_INFO(ao, "Format %s is not supported by hardware, trying default.\n",
|
||||
af_fmt2str_short(ao->format));
|
||||
p->alsa_fmt = SND_PCM_FORMAT_S16_LE;
|
||||
if (AF_FORMAT_IS_AC3(ao->format))
|
||||
ao->format = AF_FORMAT_AC3_LE;
|
||||
@@ -471,8 +460,7 @@ static int init(struct ao *ao)
|
||||
CHECK_ALSA_ERROR("Unable to set channels");
|
||||
|
||||
if (num_channels != ao->channels.num) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR,
|
||||
"[AO_ALSA] Couldn't get requested number of channels.\n");
|
||||
MP_ERR(ao, "Couldn't get requested number of channels.\n");
|
||||
mp_chmap_from_channels_alsa(&ao->channels, num_channels);
|
||||
}
|
||||
|
||||
@@ -508,13 +496,12 @@ static int init(struct ao *ao)
|
||||
CHECK_ALSA_ERROR("Unable to get buffersize");
|
||||
|
||||
p->buffersize = bufsize * p->bytes_per_sample;
|
||||
mp_msg(MSGT_AO, MSGL_V, "alsa-init: got buffersize=%i\n",
|
||||
p->buffersize);
|
||||
MP_VERBOSE(ao, "got buffersize=%i\n", p->buffersize);
|
||||
|
||||
err = snd_pcm_hw_params_get_period_size(alsa_hwparams, &chunk_size, NULL);
|
||||
CHECK_ALSA_ERROR("Unable to get period size");
|
||||
|
||||
mp_msg(MSGT_AO, MSGL_V, "alsa-init: got period size %li\n", chunk_size);
|
||||
MP_VERBOSE(ao, "got period size %li\n", chunk_size);
|
||||
p->outburst = chunk_size * p->bytes_per_sample;
|
||||
|
||||
/* setting software parameters */
|
||||
@@ -546,10 +533,9 @@ static int init(struct ao *ao)
|
||||
|
||||
p->can_pause = snd_pcm_hw_params_can_pause(alsa_hwparams);
|
||||
|
||||
mp_msg(MSGT_AO, MSGL_V,
|
||||
"alsa: %d Hz/%d channels/%d bpf/%d bytes buffer/%s\n",
|
||||
ao->samplerate, ao->channels.num, (int)p->bytes_per_sample,
|
||||
p->buffersize, snd_pcm_format_description(p->alsa_fmt));
|
||||
MP_VERBOSE(ao, "opened: %d Hz/%d channels/%d bpf/%d bytes buffer/%s\n",
|
||||
ao->samplerate, ao->channels.num, (int)p->bytes_per_sample,
|
||||
p->buffersize, snd_pcm_format_description(p->alsa_fmt));
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -573,7 +559,7 @@ static void uninit(struct ao *ao, bool immed)
|
||||
err = snd_pcm_close(p->alsa);
|
||||
CHECK_ALSA_ERROR("pcm close error");
|
||||
|
||||
mp_msg(MSGT_AO, MSGL_V, "alsa-uninit: pcm closed\n");
|
||||
MP_VERBOSE(ao, "uninit: pcm closed\n");
|
||||
}
|
||||
|
||||
alsa_error:
|
||||
@@ -590,8 +576,8 @@ static void audio_pause(struct ao *ao)
|
||||
p->delay_before_pause = get_delay(ao);
|
||||
err = snd_pcm_pause(p->alsa, 1);
|
||||
CHECK_ALSA_ERROR("pcm pause error");
|
||||
mp_msg(MSGT_AO, MSGL_V, "alsa-pause: pause supported by hardware\n");
|
||||
} else {
|
||||
MP_VERBOSE(ao, "pause not supported by hardware\n");
|
||||
if (snd_pcm_delay(p->alsa, &p->prepause_frames) < 0
|
||||
|| p->prepause_frames < 0)
|
||||
p->prepause_frames = 0;
|
||||
@@ -610,16 +596,15 @@ static void audio_resume(struct ao *ao)
|
||||
int err;
|
||||
|
||||
if (snd_pcm_state(p->alsa) == SND_PCM_STATE_SUSPENDED) {
|
||||
mp_tmsg(MSGT_AO, MSGL_INFO,
|
||||
"[AO_ALSA] Pcm in suspend mode, trying to resume.\n");
|
||||
MP_INFO(ao, "PCM in suspend mode, trying to resume.\n");
|
||||
while ((err = snd_pcm_resume(p->alsa)) == -EAGAIN)
|
||||
sleep(1);
|
||||
}
|
||||
if (p->can_pause) {
|
||||
err = snd_pcm_pause(p->alsa, 0);
|
||||
CHECK_ALSA_ERROR("pcm resume error");
|
||||
mp_msg(MSGT_AO, MSGL_V, "alsa-resume: resume supported by hardware\n");
|
||||
} else {
|
||||
MP_VERBOSE(ao, "resume not supported by hardware\n");
|
||||
err = snd_pcm_prepare(p->alsa);
|
||||
CHECK_ALSA_ERROR("pcm prepare error");
|
||||
if (p->prepause_frames) {
|
||||
@@ -664,10 +649,8 @@ static int play(struct ao *ao, void *data, int len, int flags)
|
||||
len = len / p->outburst * p->outburst;
|
||||
num_frames = len / p->bytes_per_sample;
|
||||
|
||||
//mp_msg(MSGT_AO,MSGL_ERR,"alsa-play: frames=%i, len=%i\n",num_frames,len);
|
||||
|
||||
if (!p->alsa) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR, "[AO_ALSA] Device configuration error.");
|
||||
MP_ERR(ao, "Device configuration error.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -681,16 +664,12 @@ static int play(struct ao *ao, void *data, int len, int flags)
|
||||
/* nothing to do */
|
||||
res = 0;
|
||||
} else if (res == -ESTRPIPE) { /* suspend */
|
||||
mp_tmsg(MSGT_AO, MSGL_INFO,
|
||||
"[AO_ALSA] Pcm in suspend mode, trying to resume.\n");
|
||||
MP_INFO(ao, "PCM in suspend mode, trying to resume.\n");
|
||||
while ((res = snd_pcm_resume(p->alsa)) == -EAGAIN)
|
||||
sleep(1);
|
||||
}
|
||||
if (res < 0) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR, "[AO_ALSA] Write error: %s\n",
|
||||
snd_strerror(res));
|
||||
mp_tmsg(MSGT_AO, MSGL_INFO,
|
||||
"[AO_ALSA] Trying to reset soundcard.\n");
|
||||
MP_ERR(ao, "Write error: %s\n", snd_strerror(res));
|
||||
res = snd_pcm_prepare(p->alsa);
|
||||
int err = res;
|
||||
CHECK_ALSA_ERROR("pcm prepare error");
|
||||
|
||||
@@ -112,6 +112,7 @@ static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags,
|
||||
if (mp_ring_buffered(p->buffer) < requested) {
|
||||
MP_VERBOSE(ao, "buffer underrun\n");
|
||||
audio_pause(ao);
|
||||
memset(buf.mData, 0, requested);
|
||||
} else {
|
||||
mp_ring_read(p->buffer, buf.mData, requested);
|
||||
}
|
||||
@@ -267,14 +268,16 @@ static int init(struct ao *ao)
|
||||
selected_device = p->opt_device_id;
|
||||
}
|
||||
|
||||
char *device_name;
|
||||
err = CA_GET_STR(selected_device, kAudioObjectPropertyName, &device_name);
|
||||
CHECK_CA_ERROR("could not get selected audio device name");
|
||||
if (mp_msg_test_log(ao->log, MSGL_V)) {
|
||||
char *name;
|
||||
err = CA_GET_STR(selected_device, kAudioObjectPropertyName, &name);
|
||||
CHECK_CA_ERROR("could not get selected audio device name");
|
||||
|
||||
MP_VERBOSE(ao, "selected audio output device: %s (%" PRIu32 ")\n",
|
||||
device_name, selected_device);
|
||||
MP_VERBOSE(ao, "selected audio output device: %s (%" PRIu32 ")\n",
|
||||
name, selected_device);
|
||||
|
||||
talloc_free(device_name);
|
||||
talloc_free(name);
|
||||
}
|
||||
|
||||
// Save selected device id
|
||||
p->device = selected_device;
|
||||
|
||||
+24
-48
@@ -152,24 +152,9 @@ static void UninitDirectSound(struct ao *ao)
|
||||
FreeLibrary(p->hdsound_dll);
|
||||
p->hdsound_dll = NULL;
|
||||
}
|
||||
mp_msg(MSGT_AO, MSGL_V, "ao_dsound: DirectSound uninitialized\n");
|
||||
MP_VERBOSE(ao, "DirectSound uninitialized\n");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief print the commandline help
|
||||
*/
|
||||
static void print_help(void)
|
||||
{
|
||||
mp_msg(MSGT_AO, MSGL_FATAL,
|
||||
"\n-ao dsound commandline help:\n"
|
||||
"Example: mpv -ao dsound:device=1\n"
|
||||
" sets 1st device\n"
|
||||
"\nOptions:\n"
|
||||
" device=<device-number>\n"
|
||||
" Sets device number, use -v to get a list\n");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief enumerate direct sound devices
|
||||
\return TRUE to continue with the enumeration
|
||||
@@ -180,13 +165,13 @@ static BOOL CALLBACK DirectSoundEnum(LPGUID guid, LPCSTR desc, LPCSTR module,
|
||||
struct ao *ao = context;
|
||||
struct priv *p = ao->priv;
|
||||
|
||||
mp_msg(MSGT_AO, MSGL_V, "%i %s ", p->device_index, desc);
|
||||
MP_VERBOSE(ao, "%i %s ", p->device_index, desc);
|
||||
if (p->device_num == p->device_index) {
|
||||
mp_msg(MSGT_AO, MSGL_V, "<--");
|
||||
MP_VERBOSE(ao, "<--");
|
||||
if (guid)
|
||||
memcpy(&p->device, guid, sizeof(GUID));
|
||||
}
|
||||
mp_msg(MSGT_AO, MSGL_V, "\n");
|
||||
MP_VERBOSE(ao, "\n");
|
||||
p->device_index++;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -210,7 +195,7 @@ static int InitDirectSound(struct ao *ao)
|
||||
|
||||
p->hdsound_dll = LoadLibrary("DSOUND.DLL");
|
||||
if (p->hdsound_dll == NULL) {
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "ao_dsound: cannot load DSOUND.DLL\n");
|
||||
MP_ERR(ao, "cannot load DSOUND.DLL\n");
|
||||
return 0;
|
||||
}
|
||||
OurDirectSoundCreate = (void *)GetProcAddress(p->hdsound_dll,
|
||||
@@ -219,21 +204,20 @@ static int InitDirectSound(struct ao *ao)
|
||||
"DirectSoundEnumerateA");
|
||||
|
||||
if (OurDirectSoundCreate == NULL || OurDirectSoundEnumerate == NULL) {
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "ao_dsound: GetProcAddress FAILED\n");
|
||||
MP_ERR(ao, "GetProcAddress FAILED\n");
|
||||
FreeLibrary(p->hdsound_dll);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Enumerate all directsound p->devices
|
||||
mp_msg(MSGT_AO, MSGL_V, "ao_dsound: Output Devices:\n");
|
||||
MP_VERBOSE(ao, "Output Devices:\n");
|
||||
OurDirectSoundEnumerate(DirectSoundEnum, ao);
|
||||
|
||||
// Create the direct sound object
|
||||
if (FAILED(OurDirectSoundCreate((p->device_num) ? &p->device : NULL,
|
||||
&p->hds, NULL)))
|
||||
{
|
||||
mp_msg(MSGT_AO, MSGL_ERR,
|
||||
"ao_dsound: cannot create a DirectSound device\n");
|
||||
MP_ERR(ao, "cannot create a DirectSound device\n");
|
||||
FreeLibrary(p->hdsound_dll);
|
||||
return 0;
|
||||
}
|
||||
@@ -251,22 +235,20 @@ static int InitDirectSound(struct ao *ao)
|
||||
if (IDirectSound_SetCooperativeLevel(p->hds, GetDesktopWindow(),
|
||||
DSSCL_EXCLUSIVE))
|
||||
{
|
||||
mp_msg(MSGT_AO, MSGL_ERR,
|
||||
"ao_dsound: cannot set direct sound cooperative level\n");
|
||||
MP_ERR(ao, "cannot set direct sound cooperative level\n");
|
||||
IDirectSound_Release(p->hds);
|
||||
FreeLibrary(p->hdsound_dll);
|
||||
return 0;
|
||||
}
|
||||
mp_msg(MSGT_AO, MSGL_V, "ao_dsound: DirectSound initialized\n");
|
||||
MP_VERBOSE(ao, "DirectSound initialized\n");
|
||||
|
||||
memset(&dscaps, 0, sizeof(DSCAPS));
|
||||
dscaps.dwSize = sizeof(DSCAPS);
|
||||
if (DS_OK == IDirectSound_GetCaps(p->hds, &dscaps)) {
|
||||
if (dscaps.dwFlags & DSCAPS_EMULDRIVER)
|
||||
mp_msg(MSGT_AO, MSGL_V,
|
||||
"ao_dsound: DirectSound is emulated, waveOut may give better performance\n");
|
||||
MP_VERBOSE(ao, "DirectSound is emulated\n");
|
||||
} else {
|
||||
mp_msg(MSGT_AO, MSGL_V, "ao_dsound: cannot get device capabilities\n");
|
||||
MP_VERBOSE(ao, "cannot get device capabilities\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -424,9 +406,8 @@ static int init(struct ao *ao)
|
||||
case AF_FORMAT_U8:
|
||||
break;
|
||||
default:
|
||||
mp_msg(MSGT_AO, MSGL_V,
|
||||
"ao_dsound: format %s not supported defaulting to Signed 16-bit Little-Endian\n",
|
||||
af_fmt2str_short(format));
|
||||
MP_VERBOSE(ao, "format %s not supported defaulting to Signed 16-bit Little-Endian\n",
|
||||
af_fmt2str_short(format));
|
||||
format = AF_FORMAT_S16_LE;
|
||||
}
|
||||
//set our audio parameters
|
||||
@@ -434,11 +415,10 @@ static int init(struct ao *ao)
|
||||
ao->format = format;
|
||||
ao->bps = ao->channels.num * rate * (af_fmt2bits(format) >> 3);
|
||||
int buffersize = ao->bps; // space for 1 sec
|
||||
mp_msg(MSGT_AO, MSGL_V,
|
||||
"ao_dsound: Samplerate:%iHz Channels:%i Format:%s\n", rate,
|
||||
ao->channels.num, af_fmt2str_short(format));
|
||||
mp_msg(MSGT_AO, MSGL_V, "ao_dsound: Buffersize:%d bytes (%d msec)\n",
|
||||
buffersize, buffersize / ao->bps * 1000);
|
||||
MP_VERBOSE(ao, "Samplerate:%iHz Channels:%i Format:%s\n", rate,
|
||||
ao->channels.num, af_fmt2str_short(format));
|
||||
MP_VERBOSE(ao, "Buffersize:%d bytes (%d msec)\n",
|
||||
buffersize, buffersize / ao->bps * 1000);
|
||||
|
||||
//fill waveformatex
|
||||
ZeroMemory(&wformat, sizeof(WAVEFORMATEXTENSIBLE));
|
||||
@@ -494,19 +474,16 @@ static int init(struct ao *ao)
|
||||
res = IDirectSound_CreateSoundBuffer(p->hds, &dsbpridesc, &p->hdspribuf, NULL);
|
||||
if (res != DS_OK) {
|
||||
UninitDirectSound(ao);
|
||||
mp_msg(MSGT_AO, MSGL_ERR,
|
||||
"ao_dsound: cannot create primary buffer (%s)\n",
|
||||
dserr2str(res));
|
||||
MP_ERR(ao, "cannot create primary buffer (%s)\n", dserr2str(res));
|
||||
return -1;
|
||||
}
|
||||
res = IDirectSoundBuffer_SetFormat(p->hdspribuf, (WAVEFORMATEX *)&wformat);
|
||||
if (res != DS_OK) {
|
||||
mp_msg(MSGT_AO, MSGL_WARN,
|
||||
"ao_dsound: cannot set primary buffer format (%s), using "
|
||||
"standard setting (bad quality)", dserr2str(res));
|
||||
MP_WARN(ao, "cannot set primary buffer format (%s), using "
|
||||
"standard setting (bad quality)", dserr2str(res));
|
||||
}
|
||||
|
||||
mp_msg(MSGT_AO, MSGL_V, "ao_dsound: primary buffer created\n");
|
||||
MP_VERBOSE(ao, "primary buffer created\n");
|
||||
|
||||
// now create the stream buffer
|
||||
|
||||
@@ -519,13 +496,12 @@ static int init(struct ao *ao)
|
||||
}
|
||||
if (res != DS_OK) {
|
||||
UninitDirectSound(ao);
|
||||
mp_msg(MSGT_AO, MSGL_ERR,
|
||||
"ao_dsound: cannot create secondary (stream)buffer (%s)\n",
|
||||
MP_ERR(ao, "cannot create secondary (stream)buffer (%s)\n",
|
||||
dserr2str(res));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
mp_msg(MSGT_AO, MSGL_V, "ao_dsound: secondary (stream)buffer created\n");
|
||||
MP_VERBOSE(ao, "secondary (stream)buffer created\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -169,7 +169,7 @@ static int init(struct ao *ao)
|
||||
struct priv *p = ao->priv;
|
||||
const char **matching_ports = NULL;
|
||||
char *port_name = p->cfg_port && p->cfg_port[0] ? p->cfg_port : NULL;
|
||||
jack_options_t open_options = JackUseExactName;
|
||||
jack_options_t open_options = JackNullOption;
|
||||
int port_flags = JackPortIsInput;
|
||||
int i;
|
||||
|
||||
@@ -190,7 +190,7 @@ static int init(struct ao *ao)
|
||||
open_options |= JackNoStartServer;
|
||||
p->client = jack_client_open(p->cfg_client_name, open_options, NULL);
|
||||
if (!p->client) {
|
||||
mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] cannot open server\n");
|
||||
MP_FATAL(ao, "cannot open server\n");
|
||||
goto err_out;
|
||||
}
|
||||
jack_set_process_callback(p->client, outputaudio, ao);
|
||||
@@ -201,7 +201,7 @@ static int init(struct ao *ao)
|
||||
port_flags |= JackPortIsPhysical;
|
||||
matching_ports = jack_get_ports(p->client, port_name, NULL, port_flags);
|
||||
if (!matching_ports || !matching_ports[0]) {
|
||||
mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] no physical ports available\n");
|
||||
MP_FATAL(ao, "no physical ports available\n");
|
||||
goto err_out;
|
||||
}
|
||||
i = 1;
|
||||
@@ -220,19 +220,19 @@ static int init(struct ao *ao)
|
||||
jack_port_register(p->client, pname, JACK_DEFAULT_AUDIO_TYPE,
|
||||
JackPortIsOutput, 0);
|
||||
if (!p->ports[i]) {
|
||||
mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] not enough ports available\n");
|
||||
MP_FATAL(ao, "not enough ports available\n");
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
if (jack_activate(p->client)) {
|
||||
mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] activate failed\n");
|
||||
MP_FATAL(ao, "activate failed\n");
|
||||
goto err_out;
|
||||
}
|
||||
for (i = 0; i < p->num_ports; i++) {
|
||||
if (jack_connect(p->client, jack_port_name(p->ports[i]),
|
||||
matching_ports[i]))
|
||||
{
|
||||
mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] connecting failed\n");
|
||||
MP_FATAL(ao, "connecting failed\n");
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
+30
-44
@@ -71,13 +71,7 @@ static int init(struct ao *ao)
|
||||
AVCodec *codec;
|
||||
|
||||
if (!encode_lavc_available(ao->encode_lavc_ctx)) {
|
||||
mp_msg(MSGT_ENCODE, MSGL_ERR,
|
||||
"ao-lavc: the option --o (output file) must be specified\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ac->stream) {
|
||||
mp_msg(MSGT_ENCODE, MSGL_ERR, "ao-lavc: rejecting reinitialization\n");
|
||||
MP_ERR(ao, "the option --o (output file) must be specified\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -85,7 +79,7 @@ static int init(struct ao *ao)
|
||||
AVMEDIA_TYPE_AUDIO);
|
||||
|
||||
if (!ac->stream) {
|
||||
mp_msg(MSGT_ENCODE, MSGL_ERR, "ao-lavc: could not get a new audio stream\n");
|
||||
MP_ERR(ao, "could not get a new audio stream\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -243,8 +237,7 @@ out_takefirst:
|
||||
}
|
||||
if (!found_format && !found_planar_format) {
|
||||
// shouldn't happen
|
||||
mp_msg(MSGT_ENCODE, MSGL_ERR,
|
||||
"ao-lavc: sample format not found\n");
|
||||
MP_ERR(ao, "sample format not found\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,8 +278,7 @@ out_takefirst:
|
||||
ao->priv = ac;
|
||||
|
||||
if (ac->planarize)
|
||||
mp_msg(MSGT_ENCODE, MSGL_WARN,
|
||||
"ao-lavc: need to planarize audio data\n");
|
||||
MP_WARN(ao, "need to planarize audio data\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -311,8 +303,7 @@ static void uninit(struct ao *ao, bool cut_audio)
|
||||
struct encode_lavc_context *ectx = ao->encode_lavc_ctx;
|
||||
|
||||
if (!encode_lavc_start(ectx)) {
|
||||
mp_msg(MSGT_ENCODE, MSGL_WARN,
|
||||
"ao-lavc: not even ready to encode audio at end -> dropped");
|
||||
MP_WARN(ao, "not even ready to encode audio at end -> dropped");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -329,8 +320,7 @@ static void uninit(struct ao *ao, bool cut_audio)
|
||||
ac->sample_size, ac->sample_padding);
|
||||
int written = play(ao, paddingbuf, ao->buffer.len + extralen, 0);
|
||||
if (written < ao->buffer.len) {
|
||||
mp_msg(MSGT_ENCODE, MSGL_ERR,
|
||||
"ao-lavc: did not write enough data at the end\n");
|
||||
MP_ERR(ao, "did not write enough data at the end\n");
|
||||
}
|
||||
talloc_free(paddingbuf);
|
||||
ao->buffer.len = 0;
|
||||
@@ -392,7 +382,7 @@ static int encode(struct ao *ao, double apts, void *data)
|
||||
ac->stream->codec->sample_fmt, data,
|
||||
audiolen, 1))
|
||||
{
|
||||
mp_msg(MSGT_ENCODE, MSGL_ERR, "ao-lavc: error filling\n");
|
||||
MP_ERR(ao, "error filling\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -408,9 +398,8 @@ static int encode(struct ao *ao, double apts, void *data)
|
||||
if (ac->lastpts != MP_NOPTS_VALUE && frame_pts <= ac->lastpts) {
|
||||
// this indicates broken video
|
||||
// (video pts failing to increase fast enough to match audio)
|
||||
mp_msg(MSGT_ENCODE, MSGL_WARN, "ao-lavc: audio frame pts went backwards "
|
||||
"(%d <- %d), autofixed\n", (int)frame->pts,
|
||||
(int)ac->lastpts);
|
||||
MP_WARN(ao, "audio frame pts went backwards (%d <- %d), autofixed\n",
|
||||
(int)frame->pts, (int)ac->lastpts);
|
||||
frame_pts = ac->lastpts + 1;
|
||||
frame->pts = av_rescale_q(frame_pts, ac->worst_time_base, ac->stream->codec->time_base);
|
||||
}
|
||||
@@ -436,17 +425,15 @@ static int encode(struct ao *ao, double apts, void *data)
|
||||
status = avcodec_encode_audio2(ac->stream->codec, &packet, NULL, &gotpacket);
|
||||
}
|
||||
|
||||
if(status)
|
||||
{
|
||||
mp_msg(MSGT_ENCODE, MSGL_ERR, "ao-lavc: error encoding\n");
|
||||
if(status) {
|
||||
MP_ERR(ao, "error encoding\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!gotpacket)
|
||||
return 0;
|
||||
|
||||
mp_msg(MSGT_ENCODE, MSGL_DBG2,
|
||||
"ao-lavc: got pts %f (playback time: %f); out size: %d\n",
|
||||
MP_DBG(ao, "got pts %f (playback time: %f); out size: %d\n",
|
||||
apts, realapts, packet.size);
|
||||
|
||||
encode_lavc_write_stats(ao->encode_lavc_ctx, ac->stream);
|
||||
@@ -455,7 +442,7 @@ static int encode(struct ao *ao, double apts, void *data)
|
||||
|
||||
// Do we need this at all? Better be safe than sorry...
|
||||
if (packet.pts == AV_NOPTS_VALUE) {
|
||||
mp_msg(MSGT_ENCODE, MSGL_WARN, "ao-lavc: encoder lost pts, why?\n");
|
||||
MP_WARN(ao, "encoder lost pts, why?\n");
|
||||
if (ac->savepts != MP_NOPTS_VALUE)
|
||||
packet.pts = ac->savepts;
|
||||
}
|
||||
@@ -475,7 +462,7 @@ static int encode(struct ao *ao, double apts, void *data)
|
||||
ac->savepts = MP_NOPTS_VALUE;
|
||||
|
||||
if (encode_lavc_write_frame(ao->encode_lavc_ctx, &packet) < 0) {
|
||||
mp_msg(MSGT_ENCODE, MSGL_ERR, "ao-lavc: error writing at %f %f/%f\n",
|
||||
MP_ERR(ao, "error writing at %f %f/%f\n",
|
||||
realapts, (double) ac->stream->time_base.num,
|
||||
(double) ac->stream->time_base.den);
|
||||
return -1;
|
||||
@@ -501,13 +488,11 @@ static int play(struct ao *ao, void *data, int len, int flags)
|
||||
len /= ac->sample_size * ao->channels.num;
|
||||
|
||||
if (!encode_lavc_start(ectx)) {
|
||||
mp_msg(MSGT_ENCODE, MSGL_WARN,
|
||||
"ao-lavc: not ready yet for encoding audio\n");
|
||||
MP_WARN(ao, "not ready yet for encoding audio\n");
|
||||
return 0;
|
||||
}
|
||||
if (pts == MP_NOPTS_VALUE) {
|
||||
mp_msg(MSGT_ENCODE, MSGL_WARN,
|
||||
"ao-lavc: frame without pts, please report; synthesizing pts instead\n");
|
||||
MP_WARN(ao, "frame without pts, please report; synthesizing pts instead\n");
|
||||
// synthesize pts from previous expected next pts
|
||||
pts = ac->expected_next_pts;
|
||||
}
|
||||
@@ -516,19 +501,21 @@ static int play(struct ao *ao, void *data, int len, int flags)
|
||||
//if (ac->stream->codec->time_base.num / ac->stream->codec->time_base.den >= ac->stream->time_base.num / ac->stream->time_base.den)
|
||||
if (ac->stream->codec->time_base.num * (double) ac->stream->time_base.den >=
|
||||
ac->stream->time_base.num * (double) ac->stream->codec->time_base.den) {
|
||||
mp_msg(MSGT_ENCODE, MSGL_V, "ao-lavc: NOTE: using codec time base "
|
||||
"(%d/%d) for pts adjustment; the stream base (%d/%d) is "
|
||||
"not worse.\n", (int)ac->stream->codec->time_base.num,
|
||||
(int)ac->stream->codec->time_base.den, (int)ac->stream->time_base.num,
|
||||
(int)ac->stream->time_base.den);
|
||||
MP_VERBOSE(ao, "NOTE: using codec time base (%d/%d) for pts "
|
||||
"adjustment; the stream base (%d/%d) is not worse.\n",
|
||||
(int)ac->stream->codec->time_base.num,
|
||||
(int)ac->stream->codec->time_base.den,
|
||||
(int)ac->stream->time_base.num,
|
||||
(int)ac->stream->time_base.den);
|
||||
ac->worst_time_base = ac->stream->codec->time_base;
|
||||
ac->worst_time_base_is_stream = 0;
|
||||
} else {
|
||||
mp_msg(MSGT_ENCODE, MSGL_WARN, "ao-lavc: NOTE: not using codec time "
|
||||
"base (%d/%d) for pts adjustment; the stream base (%d/%d) "
|
||||
"is worse.\n", (int)ac->stream->codec->time_base.num,
|
||||
(int)ac->stream->codec->time_base.den, (int)ac->stream->time_base.num,
|
||||
(int)ac->stream->time_base.den);
|
||||
MP_WARN(ao, "NOTE: not using codec time base (%d/%d) for pts "
|
||||
"adjustment; the stream base (%d/%d) is worse.\n",
|
||||
(int)ac->stream->codec->time_base.num,
|
||||
(int)ac->stream->codec->time_base.den,
|
||||
(int)ac->stream->time_base.num,
|
||||
(int)ac->stream->time_base.den);
|
||||
ac->worst_time_base = ac->stream->time_base;
|
||||
ac->worst_time_base_is_stream = 1;
|
||||
}
|
||||
@@ -596,7 +583,7 @@ static int play(struct ao *ao, void *data, int len, int flags)
|
||||
*/
|
||||
int finalbufpos = len - (len - bufpos) % ac->aframesize;
|
||||
if (finalbufpos < 0) {
|
||||
mp_msg(MSGT_ENCODE, MSGL_WARN, "ao-lavc: cannot attain the "
|
||||
MP_WARN(ao, "cannot attain the "
|
||||
"exact requested audio sync; shifting by %d frames\n",
|
||||
-finalbufpos);
|
||||
bufpos -= finalbufpos;
|
||||
@@ -611,8 +598,7 @@ static int play(struct ao *ao, void *data, int len, int flags)
|
||||
ectx->discontinuity_pts_offset = ectx->next_in_pts - nextpts;
|
||||
}
|
||||
else if (fabs(nextpts + ectx->discontinuity_pts_offset - ectx->next_in_pts) > 30) {
|
||||
mp_msg(MSGT_ENCODE, MSGL_WARN,
|
||||
"ao-lavc: detected an unexpected discontinuity (pts jumped by "
|
||||
MP_WARN(ao, "detected an unexpected discontinuity (pts jumped by "
|
||||
"%f seconds)\n",
|
||||
nextpts + ectx->discontinuity_pts_offset - ectx->next_in_pts);
|
||||
ectx->discontinuity_pts_offset = ectx->next_in_pts - nextpts;
|
||||
|
||||
@@ -127,7 +127,7 @@ static int init(struct ao *ao)
|
||||
int i;
|
||||
struct priv *p = ao->priv;
|
||||
if (ao_data) {
|
||||
mp_msg(MSGT_AO, MSGL_FATAL, "[OpenAL] Not reentrant!\n");
|
||||
MP_FATAL(ao, "Not reentrant!\n");
|
||||
return -1;
|
||||
}
|
||||
ao_data = ao;
|
||||
@@ -145,13 +145,13 @@ static int init(struct ao *ao)
|
||||
speakers[i] = speaker_pos[n];
|
||||
}
|
||||
if (speakers[i].id < 0) {
|
||||
mp_msg(MSGT_AO, MSGL_FATAL, "[OpenAL] Unknown channel layout\n");
|
||||
MP_FATAL(ao, "Unknown channel layout\n");
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
dev = alcOpenDevice(p->cfg_device && p->cfg_device[0] ? p->cfg_device : NULL);
|
||||
if (!dev) {
|
||||
mp_msg(MSGT_AO, MSGL_FATAL, "[OpenAL] could not open device\n");
|
||||
MP_FATAL(ao, "could not open device\n");
|
||||
goto err_out;
|
||||
}
|
||||
ctx = alcCreateContext(dev, attribs);
|
||||
|
||||
+43
-54
@@ -36,7 +36,6 @@
|
||||
#include "config.h"
|
||||
#include "mpvcore/options.h"
|
||||
#include "mpvcore/mp_msg.h"
|
||||
#include "audio/mixer.h"
|
||||
|
||||
#ifdef HAVE_SYS_SOUNDCARD_H
|
||||
#include <sys/soundcard.h>
|
||||
@@ -107,8 +106,6 @@ static int format2oss(int format)
|
||||
if (format_table[n][1] == format)
|
||||
return format_table[n][0];
|
||||
}
|
||||
mp_msg(MSGT_AO, MSGL_V, "OSS: Unknown/not supported internal format: %s\n",
|
||||
af_fmt2str_short(format));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -118,8 +115,6 @@ static int oss2format(int format)
|
||||
if (format_table[n][0] == format)
|
||||
return format_table[n][1];
|
||||
}
|
||||
mp_tmsg(MSGT_GLOBAL, MSGL_ERR, "[AO OSS] Unknown/Unsupported OSS format: %x.\n",
|
||||
format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -204,16 +199,15 @@ static int init(struct ao *ao)
|
||||
if (p->cfg_oss_mixer_channel && p->cfg_oss_mixer_channel[0])
|
||||
mchan = p->cfg_oss_mixer_channel;
|
||||
|
||||
mp_msg(MSGT_AO, MSGL_V, "ao2: %d Hz %d chans %s\n", ao->samplerate,
|
||||
ao->channels.num, af_fmt2str_short(ao->format));
|
||||
MP_VERBOSE(ao, "%d Hz %d chans %s\n", ao->samplerate,
|
||||
ao->channels.num, af_fmt2str_short(ao->format));
|
||||
|
||||
if (mchan) {
|
||||
int fd, devs, i;
|
||||
|
||||
if ((fd = open(p->oss_mixer_device, O_RDONLY)) == -1) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR,
|
||||
"[AO OSS] audio_setup: Can't open mixer device %s: %s\n",
|
||||
p->oss_mixer_device, strerror(errno));
|
||||
MP_ERR(ao, "Can't open mixer device %s: %s\n",
|
||||
p->oss_mixer_device, strerror(errno));
|
||||
} else {
|
||||
ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devs);
|
||||
close(fd);
|
||||
@@ -221,9 +215,8 @@ static int init(struct ao *ao)
|
||||
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
|
||||
if (!strcasecmp(mixer_channels[i], mchan)) {
|
||||
if (!(devs & (1 << i))) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR, "[AO OSS] audio_setup: "
|
||||
"Audio card mixer does not have channel '%s', "
|
||||
"using default.\n", mchan);
|
||||
MP_ERR(ao, "Audio card mixer does not have "
|
||||
"channel '%s', using default.\n", mchan);
|
||||
i = SOUND_MIXER_NRDEVICES + 1;
|
||||
break;
|
||||
}
|
||||
@@ -232,20 +225,17 @@ static int init(struct ao *ao)
|
||||
}
|
||||
}
|
||||
if (i == SOUND_MIXER_NRDEVICES) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR, "[AO OSS] audio_setup: Audio card "
|
||||
"mixer does not have channel '%s', using default.\n",
|
||||
mchan);
|
||||
MP_ERR(ao, "Audio card mixer does not have "
|
||||
"channel '%s', using default.\n", mchan);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p->oss_mixer_channel = SOUND_MIXER_PCM;
|
||||
}
|
||||
|
||||
mp_msg(MSGT_AO, MSGL_V, "audio_setup: using '%s' dsp device\n", p->dsp);
|
||||
mp_msg(MSGT_AO, MSGL_V, "audio_setup: using '%s' mixer device\n",
|
||||
p->oss_mixer_device);
|
||||
mp_msg(MSGT_AO, MSGL_V, "audio_setup: using '%s' mixer device\n",
|
||||
mixer_channels[p->oss_mixer_channel]);
|
||||
MP_VERBOSE(ao, "using '%s' dsp device\n", p->dsp);
|
||||
MP_VERBOSE(ao, "using '%s' mixer device\n", p->oss_mixer_device);
|
||||
MP_VERBOSE(ao, "using '%s' mixer device\n", mixer_channels[p->oss_mixer_channel]);
|
||||
|
||||
#ifdef __linux__
|
||||
p->audio_fd = open(p->dsp, O_WRONLY | O_NONBLOCK);
|
||||
@@ -253,17 +243,14 @@ static int init(struct ao *ao)
|
||||
p->audio_fd = open(p->dsp, O_WRONLY);
|
||||
#endif
|
||||
if (p->audio_fd < 0) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR,
|
||||
"[AO OSS] audio_setup: Can't open audio device %s: %s\n",
|
||||
p->dsp, strerror(errno));
|
||||
MP_ERR(ao, "Can't open audio device %s: %s\n", p->dsp, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
/* Remove the non-blocking flag */
|
||||
if (fcntl(p->audio_fd, F_SETFL, 0) < 0) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR, "[AO OSS] audio_setup: Can't make file "
|
||||
"descriptor blocking: %s\n", strerror(errno));
|
||||
MP_ERR(ao, "Can't make file descriptor blocking: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
@@ -281,6 +268,8 @@ ac3_retry:
|
||||
ao->format = AF_FORMAT_AC3_NE;
|
||||
oss_format = format2oss(ao->format);
|
||||
if (oss_format == -1) {
|
||||
MP_VERBOSE(ao, "Unknown/not supported internal format: %s\n",
|
||||
af_fmt2str_short(ao->format));
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
oss_format = AFMT_S16_BE;
|
||||
#else
|
||||
@@ -291,19 +280,20 @@ ac3_retry:
|
||||
if (ioctl(p->audio_fd, SNDCTL_DSP_SETFMT, &oss_format) < 0 ||
|
||||
oss_format != format2oss(ao->format))
|
||||
{
|
||||
mp_tmsg(MSGT_AO, MSGL_WARN, "[AO OSS] Can't set audio device %s to %s "
|
||||
"output, trying %s...\n", p->dsp, af_fmt2str_short(ao->format),
|
||||
MP_WARN(ao, "Can't set audio device %s to %s output, trying %s...\n",
|
||||
p->dsp, af_fmt2str_short(ao->format),
|
||||
af_fmt2str_short(AF_FORMAT_S16_NE));
|
||||
ao->format = AF_FORMAT_S16_NE;
|
||||
goto ac3_retry;
|
||||
}
|
||||
|
||||
ao->format = oss2format(oss_format);
|
||||
if (ao->format == -1)
|
||||
if (ao->format == -1) {
|
||||
MP_ERR(ao, "Unknown/Unsupported OSS format: %x.\n", oss_format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mp_msg(MSGT_AO, MSGL_V, "audio_setup: sample format: %s\n",
|
||||
af_fmt2str_short(ao->format));
|
||||
MP_VERBOSE(ao, "sample format: %s\n", af_fmt2str_short(ao->format));
|
||||
|
||||
if (!AF_FORMAT_IS_AC3(ao->format)) {
|
||||
struct mp_chmap_sel sel = {0};
|
||||
@@ -317,45 +307,39 @@ ac3_retry:
|
||||
if (ioctl(p->audio_fd, SNDCTL_DSP_CHANNELS, &nchannels) == -1 ||
|
||||
nchannels != reqchannels)
|
||||
{
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR, "[AO OSS] audio_setup: Failed to "
|
||||
"set audio device to %d channels.\n", reqchannels);
|
||||
MP_ERR(ao, "Failed to set audio device to %d channels.\n",
|
||||
reqchannels);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
int c = reqchannels - 1;
|
||||
if (ioctl(p->audio_fd, SNDCTL_DSP_STEREO, &c) == -1) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR, "[AO OSS] audio_setup: Failed to "
|
||||
"set audio device to %d channels.\n", reqchannels);
|
||||
MP_ERR(ao, "Failed to set audio device to %d channels.\n",
|
||||
reqchannels);
|
||||
return -1;
|
||||
}
|
||||
if (!ao_chmap_sel_get_def(ao, &sel, &ao->channels, c + 1))
|
||||
return -1;
|
||||
}
|
||||
mp_msg(MSGT_AO, MSGL_V,
|
||||
"audio_setup: using %d channels (requested: %d)\n",
|
||||
ao->channels.num, reqchannels);
|
||||
MP_VERBOSE(ao, "using %d channels (requested: %d)\n",
|
||||
ao->channels.num, reqchannels);
|
||||
// set rate
|
||||
ioctl(p->audio_fd, SNDCTL_DSP_SPEED, &ao->samplerate);
|
||||
mp_msg(MSGT_AO, MSGL_V, "audio_setup: using %d Hz samplerate\n",
|
||||
ao->samplerate);
|
||||
MP_VERBOSE(ao, "using %d Hz samplerate\n", ao->samplerate);
|
||||
}
|
||||
|
||||
if (ioctl(p->audio_fd, SNDCTL_DSP_GETOSPACE, &p->zz) == -1) {
|
||||
int r = 0;
|
||||
mp_tmsg(MSGT_AO, MSGL_WARN, "[AO OSS] audio_setup: driver doesn't "
|
||||
"support SNDCTL_DSP_GETOSPACE\n");
|
||||
MP_WARN(ao, "driver doesn't support SNDCTL_DSP_GETOSPACE\n");
|
||||
if (ioctl(p->audio_fd, SNDCTL_DSP_GETBLKSIZE, &r) == -1)
|
||||
mp_msg(MSGT_AO, MSGL_V, "audio_setup: %d bytes/frag (config.h)\n",
|
||||
p->outburst);
|
||||
MP_VERBOSE(ao, "%d bytes/frag (config.h)\n", p->outburst);
|
||||
else {
|
||||
p->outburst = r;
|
||||
mp_msg(MSGT_AO, MSGL_V, "audio_setup: %d bytes/frag (GETBLKSIZE)\n",
|
||||
p->outburst);
|
||||
MP_VERBOSE(ao, "%d bytes/frag (GETBLKSIZE)\n", p->outburst);
|
||||
}
|
||||
} else {
|
||||
mp_msg(MSGT_AO, MSGL_V,
|
||||
"audio_setup: frags: %3d/%d (%d bytes/frag) free: %6d\n",
|
||||
p->zz.fragments, p->zz.fragstotal, p->zz.fragsize, p->zz.bytes);
|
||||
MP_VERBOSE(ao, "frags: %3d/%d (%d bytes/frag) free: %6d\n",
|
||||
p->zz.fragments, p->zz.fragstotal, p->zz.fragsize, p->zz.bytes);
|
||||
p->buffersize = p->zz.bytes;
|
||||
p->outburst = p->zz.fragsize;
|
||||
}
|
||||
@@ -381,9 +365,8 @@ ac3_retry:
|
||||
}
|
||||
free(data);
|
||||
if (p->buffersize == 0) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR, "[AO OSS]\n *** Your audio driver "
|
||||
"DOES NOT support select() ***\n Recompile mpv with "
|
||||
"#undef HAVE_AUDIO_SELECT in config.h !\n\n");
|
||||
MP_ERR(ao, "*** Your audio driver DOES NOT support select() ***\n");
|
||||
MP_ERR(ao, "Recompile mpv with #undef HAVE_AUDIO_SELECT in config.h!\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
@@ -433,8 +416,8 @@ static void reset(struct ao *ao)
|
||||
close_device(ao);
|
||||
p->audio_fd = open(p->dsp, O_WRONLY);
|
||||
if (p->audio_fd < 0) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR, "[AO OSS]\nFatal error: *** CANNOT "
|
||||
"RE-OPEN / RESET AUDIO DEVICE *** %s\n", strerror(errno));
|
||||
MP_ERR(ao, "Fatal error: *** CANNOT "
|
||||
"RE-OPEN / RESET AUDIO DEVICE *** %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -493,7 +476,11 @@ static void audio_pause(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
p->prepause_space = get_space(ao);
|
||||
#ifdef SNDCTL_DSP_RESET
|
||||
ioctl(p->audio_fd, SNDCTL_DSP_RESET, NULL);
|
||||
#else
|
||||
close_device(ao);
|
||||
#endif
|
||||
}
|
||||
|
||||
// plays 'len' bytes of 'data'
|
||||
@@ -517,7 +504,9 @@ static void audio_resume(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
int fillcnt;
|
||||
#ifndef SNDCTL_DSP_RESET
|
||||
reset(ao);
|
||||
#endif
|
||||
fillcnt = get_space(ao) - p->prepause_space;
|
||||
if (fillcnt > 0 && !(ao->format & AF_FORMAT_SPECIAL_MASK)) {
|
||||
void *silence = calloc(fillcnt, 1);
|
||||
|
||||
+6
-11
@@ -125,7 +125,6 @@ static int init(struct ao *ao)
|
||||
case AF_FORMAT_S24_LE:
|
||||
case AF_FORMAT_S32_LE:
|
||||
case AF_FORMAT_FLOAT_LE:
|
||||
case AF_FORMAT_AC3_BE:
|
||||
case AF_FORMAT_AC3_LE:
|
||||
break;
|
||||
default:
|
||||
@@ -141,19 +140,16 @@ static int init(struct ao *ao)
|
||||
|
||||
ao->bps = ao->channels.num * ao->samplerate * (af_fmt2bits(ao->format) / 8);
|
||||
|
||||
mp_tmsg(MSGT_AO, MSGL_INFO, "[AO PCM] File: %s (%s)\n"
|
||||
"PCM: Samplerate: %d Hz Channels: %d Format: %s\n",
|
||||
MP_INFO(ao, "File: %s (%s)\nPCM: Samplerate: %d Hz Channels: %d Format: %s\n",
|
||||
priv->outputfilename,
|
||||
priv->waveheader ? "WAVE" : "RAW PCM", ao->samplerate,
|
||||
ao->channels.num, af_fmt2str_short(ao->format));
|
||||
mp_tmsg(MSGT_AO, MSGL_INFO,
|
||||
"[AO PCM] Info: Faster dumping is achieved with -no-video\n"
|
||||
"[AO PCM] Info: To write WAVE files use -ao pcm:waveheader (default).\n");
|
||||
MP_INFO(ao, "Info: Faster dumping is achieved with -no-video\n");
|
||||
MP_INFO(ao, "Info: To write WAVE files use -ao pcm:waveheader (default).\n");
|
||||
|
||||
priv->fp = fopen(priv->outputfilename, "wb");
|
||||
if (!priv->fp) {
|
||||
mp_tmsg(MSGT_AO, MSGL_ERR, "[AO PCM] Failed to open %s for writing!\n",
|
||||
priv->outputfilename);
|
||||
MP_ERR(ao, "Failed to open %s for writing!\n", priv->outputfilename);
|
||||
return -1;
|
||||
}
|
||||
if (priv->waveheader) // Reserve space for wave header
|
||||
@@ -177,11 +173,10 @@ static void uninit(struct ao *ao, bool cut_audio)
|
||||
GetFileType((HANDLE)_get_osfhandle(_fileno(priv->fp)));
|
||||
#endif
|
||||
if (broken_seek || fseek(priv->fp, 0, SEEK_SET) != 0)
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "Could not seek to start, "
|
||||
"WAV size headers not updated!\n");
|
||||
MP_ERR(ao, "Could not seek to start, WAV size headers not updated!\n");
|
||||
else {
|
||||
if (priv->data_length > 0xfffff000) {
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "File larger than allowed for "
|
||||
MP_ERR(ao, "File larger than allowed for "
|
||||
"WAV files, may play truncated!\n");
|
||||
priv->data_length = 0xfffff000;
|
||||
}
|
||||
|
||||
@@ -68,11 +68,11 @@ static const struct format_map format_maps[] = {
|
||||
static bool check_pa_ret(int ret)
|
||||
{
|
||||
if (ret < 0) {
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "[portaudio] %s\n",
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "[ao/portaudio] %s\n",
|
||||
Pa_GetErrorText(ret));
|
||||
if (ret == paUnanticipatedHostError) {
|
||||
const PaHostErrorInfo* hosterr = Pa_GetLastHostErrorInfo();
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "[portaudio] Host error: %s\n",
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "[ao/portaudio] Host error: %s\n",
|
||||
hosterr->errorText);
|
||||
}
|
||||
return false;
|
||||
@@ -121,7 +121,7 @@ static int find_device(const char *name)
|
||||
}
|
||||
}
|
||||
if (found == paNoDevice && !help)
|
||||
mp_msg(MSGT_AO, MSGL_WARN, "[portaudio] Device '%s' not found!\n",
|
||||
mp_msg(MSGT_AO, MSGL_WARN, "[ao/portaudio] Device '%s' not found!\n",
|
||||
name);
|
||||
return found;
|
||||
}
|
||||
@@ -183,7 +183,7 @@ static int stream_callback(const void *input,
|
||||
res = paComplete;
|
||||
priv->play_remaining = false;
|
||||
} else {
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "[portaudio] Buffer underflow!\n");
|
||||
MP_ERR(ao, "Buffer underflow!\n");
|
||||
}
|
||||
fill_silence(output, len_bytes);
|
||||
}
|
||||
@@ -253,8 +253,7 @@ static int init(struct ao *ao)
|
||||
fmt++;
|
||||
}
|
||||
if (!fmt->pa_format) {
|
||||
mp_msg(MSGT_AO, MSGL_V,
|
||||
"[portaudio] Unsupported format, using default.\n");
|
||||
MP_VERBOSE(ao, "Unsupported format, using default.\n");
|
||||
fmt = format_maps;
|
||||
}
|
||||
|
||||
|
||||
+44
-31
@@ -57,9 +57,9 @@ struct priv {
|
||||
char *cfg_sink;
|
||||
};
|
||||
|
||||
#define GENERIC_ERR_MSG(ctx, str) \
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "AO: [pulse] "str": %s\n", \
|
||||
pa_strerror(pa_context_errno(ctx)))
|
||||
#define GENERIC_ERR_MSG(str) \
|
||||
MP_ERR(ao, str": %s\n", \
|
||||
pa_strerror(pa_context_errno(((struct priv *)ao->priv)->context)))
|
||||
|
||||
static void context_state_cb(pa_context *c, void *userdata)
|
||||
{
|
||||
@@ -147,7 +147,6 @@ static const struct format_map {
|
||||
};
|
||||
|
||||
static const int speaker_map[][2] = {
|
||||
{PA_CHANNEL_POSITION_MONO, MP_SPEAKER_ID_FC},
|
||||
{PA_CHANNEL_POSITION_FRONT_LEFT, MP_SPEAKER_ID_FL},
|
||||
{PA_CHANNEL_POSITION_FRONT_RIGHT, MP_SPEAKER_ID_FR},
|
||||
{PA_CHANNEL_POSITION_FRONT_CENTER, MP_SPEAKER_ID_FC},
|
||||
@@ -174,6 +173,10 @@ static bool chmap_pa_from_mp(pa_channel_map *dst, struct mp_chmap *src)
|
||||
if (src->num > PA_CHANNELS_MAX)
|
||||
return false;
|
||||
dst->channels = src->num;
|
||||
if (mp_chmap_equals(src, &(const struct mp_chmap)MP_CHMAP_INIT_MONO)) {
|
||||
dst->map[0] = PA_CHANNEL_POSITION_MONO;
|
||||
return true;
|
||||
}
|
||||
for (int n = 0; n < src->num; n++) {
|
||||
int mp_speaker = src->speaker[n];
|
||||
int pa_speaker = PA_CHANNEL_POSITION_INVALID;
|
||||
@@ -232,6 +235,7 @@ static int init(struct ao *ao)
|
||||
{
|
||||
struct pa_sample_spec ss;
|
||||
struct pa_channel_map map;
|
||||
pa_proplist *proplist = NULL;
|
||||
struct priv *priv = ao->priv;
|
||||
char *host = priv->cfg_host && priv->cfg_host[0] ? priv->cfg_host : NULL;
|
||||
char *sink = priv->cfg_sink && priv->cfg_sink[0] ? priv->cfg_sink : NULL;
|
||||
@@ -247,20 +251,19 @@ static int init(struct ao *ao)
|
||||
* hangs somewhen. */
|
||||
if (strncmp(version, "0.9.1", 5) == 0 && version[5] >= '1'
|
||||
&& version[5] <= '4') {
|
||||
mp_msg(MSGT_AO, MSGL_WARN,
|
||||
"[pulse] working around probably broken pause functionality,\n"
|
||||
" see http://www.pulseaudio.org/ticket/440\n");
|
||||
MP_WARN(ao, "working around probably broken pause functionality,\n"
|
||||
" see http://www.pulseaudio.org/ticket/440\n");
|
||||
priv->broken_pause = true;
|
||||
}
|
||||
|
||||
if (!(priv->mainloop = pa_threaded_mainloop_new())) {
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "AO: [pulse] Failed to allocate main loop\n");
|
||||
MP_ERR(ao, "Failed to allocate main loop\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(priv->context = pa_context_new(pa_threaded_mainloop_get_api(
|
||||
priv->mainloop), PULSE_CLIENT_NAME))) {
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "AO: [pulse] Failed to allocate context\n");
|
||||
MP_ERR(ao, "Failed to allocate context\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -286,8 +289,7 @@ static int init(struct ao *ao)
|
||||
const struct format_map *fmt_map = format_maps;
|
||||
while (fmt_map->mp_format != ao->format) {
|
||||
if (fmt_map->mp_format == AF_FORMAT_UNKNOWN) {
|
||||
mp_msg(MSGT_AO, MSGL_V,
|
||||
"AO: [pulse] Unsupported format, using default\n");
|
||||
MP_VERBOSE(ao, "Unsupported format, using default\n");
|
||||
fmt_map = format_maps;
|
||||
break;
|
||||
}
|
||||
@@ -297,17 +299,27 @@ static int init(struct ao *ao)
|
||||
ss.format = fmt_map->pa_format;
|
||||
|
||||
if (!pa_sample_spec_valid(&ss)) {
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "AO: [pulse] Invalid sample spec\n");
|
||||
goto fail;
|
||||
MP_ERR(ao, "Invalid sample spec\n");
|
||||
goto unlock_and_fail;
|
||||
}
|
||||
|
||||
if (!select_chmap(ao, &map))
|
||||
goto fail;
|
||||
|
||||
if (!(priv->stream = pa_stream_new(priv->context, "audio stream", &ss,
|
||||
&map)))
|
||||
goto unlock_and_fail;
|
||||
|
||||
if (!(proplist = pa_proplist_new())) {
|
||||
MP_ERR(ao, "Failed to allocate proplist\n");
|
||||
goto unlock_and_fail;
|
||||
}
|
||||
(void)pa_proplist_sets(proplist, PA_PROP_MEDIA_ROLE, "video");
|
||||
|
||||
if (!(priv->stream = pa_stream_new_with_proplist(priv->context,
|
||||
"audio stream", &ss,
|
||||
&map, proplist)))
|
||||
goto unlock_and_fail;
|
||||
|
||||
pa_proplist_free(proplist);
|
||||
proplist = NULL;
|
||||
|
||||
pa_stream_set_state_callback(priv->stream, stream_state_cb, ao);
|
||||
pa_stream_set_write_callback(priv->stream, stream_request_cb, ao);
|
||||
pa_stream_set_latency_update_callback(priv->stream,
|
||||
@@ -342,8 +354,12 @@ fail:
|
||||
if (priv->context) {
|
||||
if (!(pa_context_errno(priv->context) == PA_ERR_CONNECTIONREFUSED
|
||||
&& ao->probing))
|
||||
GENERIC_ERR_MSG(priv->context, "Init failed");
|
||||
GENERIC_ERR_MSG("Init failed");
|
||||
}
|
||||
|
||||
if (proplist)
|
||||
pa_proplist_free(proplist);
|
||||
|
||||
uninit(ao, true);
|
||||
return -1;
|
||||
}
|
||||
@@ -355,7 +371,7 @@ static void cork(struct ao *ao, bool pause)
|
||||
priv->retval = 0;
|
||||
if (!waitop(priv, pa_stream_cork(priv->stream, pause, success_cb, ao)) ||
|
||||
!priv->retval)
|
||||
GENERIC_ERR_MSG(priv->context, "pa_stream_cork() failed");
|
||||
GENERIC_ERR_MSG("pa_stream_cork() failed");
|
||||
}
|
||||
|
||||
// Play the specified data to the pulseaudio server
|
||||
@@ -365,7 +381,7 @@ static int play(struct ao *ao, void *data, int len, int flags)
|
||||
pa_threaded_mainloop_lock(priv->mainloop);
|
||||
if (pa_stream_write(priv->stream, data, len, NULL, 0,
|
||||
PA_SEEK_RELATIVE) < 0) {
|
||||
GENERIC_ERR_MSG(priv->context, "pa_stream_write() failed");
|
||||
GENERIC_ERR_MSG("pa_stream_write() failed");
|
||||
len = -1;
|
||||
}
|
||||
if (flags & AOPLAY_FINAL_CHUNK) {
|
||||
@@ -387,7 +403,7 @@ static void reset(struct ao *ao)
|
||||
priv->retval = 0;
|
||||
if (!waitop(priv, pa_stream_flush(priv->stream, success_cb, ao)) ||
|
||||
!priv->retval)
|
||||
GENERIC_ERR_MSG(priv->context, "pa_stream_flush() failed");
|
||||
GENERIC_ERR_MSG("pa_stream_flush() failed");
|
||||
cork(ao, false);
|
||||
}
|
||||
|
||||
@@ -438,20 +454,20 @@ static float get_delay(struct ao *ao)
|
||||
struct priv *priv = ao->priv;
|
||||
pa_threaded_mainloop_lock(priv->mainloop);
|
||||
if (!waitop(priv, pa_stream_update_timing_info(priv->stream, NULL, NULL))) {
|
||||
GENERIC_ERR_MSG(priv->context, "pa_stream_update_timing_info() failed");
|
||||
GENERIC_ERR_MSG("pa_stream_update_timing_info() failed");
|
||||
return 0;
|
||||
}
|
||||
pa_threaded_mainloop_lock(priv->mainloop);
|
||||
const pa_timing_info *ti = pa_stream_get_timing_info(priv->stream);
|
||||
if (!ti) {
|
||||
pa_threaded_mainloop_unlock(priv->mainloop);
|
||||
GENERIC_ERR_MSG(priv->context, "pa_stream_get_timing_info() failed");
|
||||
GENERIC_ERR_MSG("pa_stream_get_timing_info() failed");
|
||||
return 0;
|
||||
}
|
||||
const struct pa_sample_spec *ss = pa_stream_get_sample_spec(priv->stream);
|
||||
if (!ss) {
|
||||
pa_threaded_mainloop_unlock(priv->mainloop);
|
||||
GENERIC_ERR_MSG(priv->context, "pa_stream_get_sample_spec() failed");
|
||||
GENERIC_ERR_MSG("pa_stream_get_sample_spec() failed");
|
||||
return 0;
|
||||
}
|
||||
// data left in PulseAudio's main buffers (not written to sink yet)
|
||||
@@ -485,7 +501,7 @@ static void info_func(struct pa_context *c, const struct pa_sink_input_info *i,
|
||||
struct ao *ao = userdata;
|
||||
struct priv *priv = ao->priv;
|
||||
if (is_last < 0) {
|
||||
GENERIC_ERR_MSG(priv->context, "Failed to get sink input info");
|
||||
GENERIC_ERR_MSG("Failed to get sink input info");
|
||||
return;
|
||||
}
|
||||
if (!i)
|
||||
@@ -504,8 +520,7 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
pa_threaded_mainloop_lock(priv->mainloop);
|
||||
if (!waitop(priv, pa_context_get_sink_input_info(priv->context, devidx,
|
||||
info_func, ao))) {
|
||||
GENERIC_ERR_MSG(priv->context,
|
||||
"pa_stream_get_sink_input_info() failed");
|
||||
GENERIC_ERR_MSG("pa_stream_get_sink_input_info() failed");
|
||||
return CONTROL_ERROR;
|
||||
}
|
||||
// Warning: some information in pi might be unaccessible, because
|
||||
@@ -548,8 +563,7 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
&volume, NULL, NULL);
|
||||
if (!o) {
|
||||
pa_threaded_mainloop_unlock(priv->mainloop);
|
||||
GENERIC_ERR_MSG(priv->context,
|
||||
"pa_context_set_sink_input_volume() failed");
|
||||
GENERIC_ERR_MSG("pa_context_set_sink_input_volume() failed");
|
||||
return CONTROL_ERROR;
|
||||
}
|
||||
} else if (cmd == AOCONTROL_SET_MUTE) {
|
||||
@@ -558,8 +572,7 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
*mute, NULL, NULL);
|
||||
if (!o) {
|
||||
pa_threaded_mainloop_unlock(priv->mainloop);
|
||||
GENERIC_ERR_MSG(priv->context,
|
||||
"pa_context_set_sink_input_mute() failed");
|
||||
GENERIC_ERR_MSG("pa_context_set_sink_input_mute() failed");
|
||||
return CONTROL_ERROR;
|
||||
}
|
||||
} else
|
||||
|
||||
+14
-16
@@ -124,7 +124,7 @@ static unsigned int ceil_power_of_two(unsigned int x)
|
||||
static int init(struct ao *ao)
|
||||
{
|
||||
if (SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "[sdl] already initialized\n");
|
||||
MP_ERR(ao, "already initialized\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ static int init(struct ao *ao)
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO)) {
|
||||
if (!ao->probing)
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "[sdl] SDL_Init failed\n");
|
||||
MP_ERR(ao, "SDL_Init failed\n");
|
||||
uninit(ao, true);
|
||||
return -1;
|
||||
}
|
||||
@@ -174,24 +174,23 @@ static int init(struct ao *ao)
|
||||
desired.callback = audio_callback;
|
||||
desired.userdata = ao;
|
||||
|
||||
mp_msg(MSGT_AO, MSGL_V, "[sdl] requested format: %d Hz, %d channels, %x, "
|
||||
"buffer size: %d samples\n",
|
||||
(int) desired.freq, (int) desired.channels,
|
||||
(int) desired.format, (int) desired.samples);
|
||||
MP_VERBOSE(ao, "requested format: %d Hz, %d channels, %x, "
|
||||
"buffer size: %d samples\n",
|
||||
(int) desired.freq, (int) desired.channels,
|
||||
(int) desired.format, (int) desired.samples);
|
||||
|
||||
obtained = desired;
|
||||
if (SDL_OpenAudio(&desired, &obtained)) {
|
||||
if (!ao->probing)
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "[sdl] could not open audio: %s\n",
|
||||
SDL_GetError());
|
||||
MP_ERR(ao, "could not open audio: %s\n", SDL_GetError());
|
||||
uninit(ao, true);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mp_msg(MSGT_AO, MSGL_V, "[sdl] obtained format: %d Hz, %d channels, %x, "
|
||||
"buffer size: %d samples\n",
|
||||
(int) obtained.freq, (int) obtained.channels,
|
||||
(int) obtained.format, (int) obtained.samples);
|
||||
MP_VERBOSE(ao, "obtained format: %d Hz, %d channels, %x, "
|
||||
"buffer size: %d samples\n",
|
||||
(int) obtained.freq, (int) obtained.channels,
|
||||
(int) obtained.format, (int) obtained.samples);
|
||||
|
||||
switch (obtained.format) {
|
||||
case AUDIO_U8: ao->format = AF_FORMAT_U8; break;
|
||||
@@ -214,8 +213,7 @@ static int init(struct ao *ao)
|
||||
#endif
|
||||
default:
|
||||
if (!ao->probing)
|
||||
mp_msg(MSGT_AO, MSGL_ERR,
|
||||
"[sdl] could not find matching format\n");
|
||||
MP_ERR(ao, "could not find matching format\n");
|
||||
uninit(ao, true);
|
||||
return -1;
|
||||
}
|
||||
@@ -229,13 +227,13 @@ static int init(struct ao *ao)
|
||||
priv->buffer = av_fifo_alloc(obtained.size * priv->bufcnt);
|
||||
priv->buffer_mutex = SDL_CreateMutex();
|
||||
if (!priv->buffer_mutex) {
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "[sdl] SDL_CreateMutex failed\n");
|
||||
MP_ERR(ao, "SDL_CreateMutex failed\n");
|
||||
uninit(ao, true);
|
||||
return -1;
|
||||
}
|
||||
priv->underrun_cond = SDL_CreateCond();
|
||||
if (!priv->underrun_cond) {
|
||||
mp_msg(MSGT_AO, MSGL_ERR, "[sdl] SDL_CreateCond failed\n");
|
||||
MP_ERR(ao, "SDL_CreateCond failed\n");
|
||||
uninit(ao, true);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
|
||||
* Copyright (c) 2013 Christian Neukirchen <chneukirchen@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <sndio.h>
|
||||
|
||||
#include "mpvcore/m_option.h"
|
||||
#include "mpvcore/mp_msg.h"
|
||||
|
||||
#include "audio/format.h"
|
||||
#include "ao.h"
|
||||
|
||||
struct priv {
|
||||
struct sio_hdl *hdl;
|
||||
struct sio_par par;
|
||||
int delay;
|
||||
int vol;
|
||||
int havevol;
|
||||
#define SILENCE_NMAX 0x1000
|
||||
char silence[SILENCE_NMAX];
|
||||
struct pollfd *pfd;
|
||||
char *dev;
|
||||
};
|
||||
|
||||
/*
|
||||
* misc parameters (volume, etc...)
|
||||
*/
|
||||
static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
ao_control_vol_t *vol = arg;
|
||||
|
||||
switch (cmd) {
|
||||
case AOCONTROL_GET_VOLUME:
|
||||
if (!p->havevol)
|
||||
return CONTROL_FALSE;
|
||||
vol->left = vol->right = p->vol * 100 / SIO_MAXVOL;
|
||||
break;
|
||||
case AOCONTROL_SET_VOLUME:
|
||||
if (!p->havevol)
|
||||
return CONTROL_FALSE;
|
||||
sio_setvol(p->hdl, vol->left * SIO_MAXVOL / 100);
|
||||
break;
|
||||
default:
|
||||
return CONTROL_UNKNOWN;
|
||||
}
|
||||
return CONTROL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-back invoked to notify of the hardware position
|
||||
*/
|
||||
static void movecb(void *addr, int delta)
|
||||
{
|
||||
struct priv *p = addr;
|
||||
p->delay -= delta * (int)(p->par.bps * p->par.pchan);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-back invoked to notify about volume changes
|
||||
*/
|
||||
static void volcb(void *addr, unsigned newvol)
|
||||
{
|
||||
struct priv *p = addr;
|
||||
p->vol = newvol;
|
||||
}
|
||||
|
||||
static const struct mp_chmap sndio_layouts[MP_NUM_CHANNELS + 1] = {
|
||||
{0}, // empty
|
||||
{1, {MP_SPEAKER_ID_FL}}, // mono
|
||||
MP_CHMAP2(FL, FR), // stereo
|
||||
{0}, // 2.1
|
||||
MP_CHMAP4(FL, FR, BL, BR), // 4.0
|
||||
{0}, // 5.0
|
||||
MP_CHMAP6(FL, FR, BL, BR, FC, LFE), // 5.1
|
||||
{0}, // 6.1
|
||||
MP_CHMAP8(FL, FR, BL, BR, FC, LFE, SL, SR), // 7.1
|
||||
/* above is the fixed channel assignment for sndio, since we need to fill
|
||||
all channels and cannot insert silence, not all layouts are supported. */
|
||||
};
|
||||
|
||||
/*
|
||||
* open device and setup parameters
|
||||
* return: 0=success -1=fail
|
||||
*/
|
||||
static int init(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
|
||||
struct af_to_par {
|
||||
int format, bits, sig, le;
|
||||
} static const af_to_par[] = {
|
||||
{AF_FORMAT_U8, 8, 0, 0},
|
||||
{AF_FORMAT_S8, 8, 1, 0},
|
||||
{AF_FORMAT_U16_LE, 16, 0, 1},
|
||||
{AF_FORMAT_U16_BE, 16, 0, 0},
|
||||
{AF_FORMAT_S16_LE, 16, 1, 1},
|
||||
{AF_FORMAT_S16_BE, 16, 1, 0},
|
||||
{AF_FORMAT_U24_LE, 16, 0, 1},
|
||||
{AF_FORMAT_U24_BE, 24, 0, 0},
|
||||
{AF_FORMAT_S24_LE, 24, 1, 1},
|
||||
{AF_FORMAT_S24_BE, 24, 1, 0},
|
||||
{AF_FORMAT_U32_LE, 32, 0, 1},
|
||||
{AF_FORMAT_U32_BE, 32, 0, 0},
|
||||
{AF_FORMAT_S32_LE, 32, 1, 1},
|
||||
{AF_FORMAT_S32_BE, 32, 1, 0}
|
||||
}, *ap;
|
||||
int i;
|
||||
|
||||
p->hdl = sio_open(p->dev, SIO_PLAY, 0);
|
||||
if (p->hdl == NULL) {
|
||||
MP_ERR(ao, "can't open sndio %s\n", p->dev);
|
||||
goto error;
|
||||
}
|
||||
sio_initpar(&p->par);
|
||||
for (i = 0, ap = af_to_par;; i++, ap++) {
|
||||
if (i == sizeof(af_to_par) / sizeof(struct af_to_par)) {
|
||||
MP_VERBOSE(ao, "unsupported format\n");
|
||||
p->par.bits = 16;
|
||||
p->par.sig = 1;
|
||||
p->par.le = SIO_LE_NATIVE;
|
||||
break;
|
||||
}
|
||||
if (ap->format == ao->format) {
|
||||
p->par.bits = ap->bits;
|
||||
p->par.sig = ap->sig;
|
||||
if (ap->bits > 8)
|
||||
p->par.le = ap->le;
|
||||
if (ap->bits != SIO_BPS(ap->bits))
|
||||
p->par.bps = ap->bits / 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
p->par.rate = ao->samplerate;
|
||||
|
||||
struct mp_chmap_sel sel = {0};
|
||||
for (int n = 0; n < MP_NUM_CHANNELS+1; n++)
|
||||
mp_chmap_sel_add_map(&sel, &sndio_layouts[n]);
|
||||
|
||||
if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
|
||||
goto error;
|
||||
|
||||
p->par.pchan = ao->channels.num;
|
||||
p->par.appbufsz = p->par.rate * 250 / 1000; /* 250ms buffer */
|
||||
p->par.round = p->par.rate * 10 / 1000; /* 10ms block size */
|
||||
if (!sio_setpar(p->hdl, &p->par)) {
|
||||
MP_ERR(ao, "couldn't set params\n");
|
||||
goto error;
|
||||
}
|
||||
if (!sio_getpar(p->hdl, &p->par)) {
|
||||
MP_ERR(ao, "couldn't get params\n");
|
||||
goto error;
|
||||
}
|
||||
if (p->par.bits == 8 && p->par.bps == 1) {
|
||||
ao->format = p->par.sig ? AF_FORMAT_S8 : AF_FORMAT_U8;
|
||||
} else if (p->par.bits == 16 && p->par.bps == 2) {
|
||||
ao->format = p->par.sig ?
|
||||
(p->par.le ? AF_FORMAT_S16_LE : AF_FORMAT_S16_BE) :
|
||||
(p->par.le ? AF_FORMAT_U16_LE : AF_FORMAT_U16_BE);
|
||||
} else if ((p->par.bits == 24 || p->par.msb) && p->par.bps == 3) {
|
||||
ao->format = p->par.sig ?
|
||||
(p->par.le ? AF_FORMAT_S24_LE : AF_FORMAT_S24_BE) :
|
||||
(p->par.le ? AF_FORMAT_U24_LE : AF_FORMAT_U24_BE);
|
||||
} else if ((p->par.bits == 32 || p->par.msb) && p->par.bps == 4) {
|
||||
ao->format = p->par.sig ?
|
||||
(p->par.le ? AF_FORMAT_S32_LE : AF_FORMAT_S32_BE) :
|
||||
(p->par.le ? AF_FORMAT_U32_LE : AF_FORMAT_U32_BE);
|
||||
} else {
|
||||
MP_ERR(ao, "couldn't set format\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
ao->bps = p->par.bps * p->par.pchan * p->par.rate;
|
||||
ao->no_persistent_volume = true;
|
||||
p->havevol = sio_onvol(p->hdl, volcb, p);
|
||||
sio_onmove(p->hdl, movecb, p);
|
||||
p->delay = 0;
|
||||
if (!sio_start(p->hdl))
|
||||
MP_ERR(ao, "init: couldn't start\n");
|
||||
|
||||
p->pfd = calloc (sio_nfds(p->hdl), sizeof (struct pollfd));
|
||||
if (!p->pfd)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (p->hdl)
|
||||
sio_close(p->hdl);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* close device
|
||||
*/
|
||||
static void uninit(struct ao *ao, bool immed)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
|
||||
if (p->hdl)
|
||||
sio_close(p->hdl);
|
||||
|
||||
free(p->pfd);
|
||||
}
|
||||
|
||||
/*
|
||||
* stop playing and empty buffers (for seeking/pause)
|
||||
*/
|
||||
static void reset(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
|
||||
if (!sio_stop(p->hdl))
|
||||
MP_ERR(ao, "reset: couldn't stop\n");
|
||||
p->delay = 0;
|
||||
if (!sio_start(p->hdl))
|
||||
MP_ERR(ao, "reset: couldn't start\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* play given number of bytes until sio_write() blocks
|
||||
*/
|
||||
static int play(struct ao *ao, void *data, int len, int flags)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
int n;
|
||||
|
||||
n = sio_write(p->hdl, data, len);
|
||||
p->delay += n;
|
||||
if (flags & AOPLAY_FINAL_CHUNK)
|
||||
reset(ao);
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* how many bytes can be played without blocking
|
||||
*/
|
||||
static int get_space(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
int n;
|
||||
|
||||
/*
|
||||
* call poll() and sio_revents(), so the
|
||||
* delay counter is updated
|
||||
*/
|
||||
n = sio_pollfd(p->hdl, p->pfd, POLLOUT);
|
||||
while (poll(p->pfd, n, 0) < 0 && errno == EINTR)
|
||||
; /* nothing */
|
||||
sio_revents(p->hdl, p->pfd);
|
||||
|
||||
return p->par.bufsz * p->par.pchan * p->par.bps - p->delay;
|
||||
}
|
||||
|
||||
/*
|
||||
* return: delay in seconds between first and last sample in buffer
|
||||
*/
|
||||
static float get_delay(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
return (float)p->delay / (p->par.bps * p->par.pchan * p->par.rate);
|
||||
}
|
||||
|
||||
/*
|
||||
* stop playing, keep buffers (for pause)
|
||||
*/
|
||||
static void audio_pause(struct ao *ao)
|
||||
{
|
||||
reset(ao);
|
||||
}
|
||||
|
||||
/*
|
||||
* resume playing, after audio_pause()
|
||||
*/
|
||||
static void audio_resume(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
int n, count, todo;
|
||||
|
||||
/*
|
||||
* we want to start with buffers full, because mplayer uses
|
||||
* get_space() pointer as clock, which would cause video to
|
||||
* accelerate while buffers are filled.
|
||||
*/
|
||||
todo = p->par.bufsz * p->par.pchan * p->par.bps;
|
||||
while (todo > 0) {
|
||||
count = todo;
|
||||
if (count > SILENCE_NMAX)
|
||||
count = SILENCE_NMAX;
|
||||
n = sio_write(p->hdl, p->silence, count);
|
||||
if (n == 0)
|
||||
break;
|
||||
todo -= n;
|
||||
p->delay += n;
|
||||
}
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct priv
|
||||
|
||||
const struct ao_driver audio_out_sndio = {
|
||||
.info = &(const struct ao_info) {
|
||||
"sndio audio output",
|
||||
"sndio",
|
||||
"Alexandre Ratchov <alex@caoua.org>, Christian Neukirchen <chneukirchen@gmail.com>",
|
||||
"under development"
|
||||
},
|
||||
.init = init,
|
||||
.uninit = uninit,
|
||||
.control = control,
|
||||
.get_space = get_space,
|
||||
.play = play,
|
||||
.get_delay = get_delay,
|
||||
.pause = audio_pause,
|
||||
.resume = audio_resume,
|
||||
.reset = reset,
|
||||
.priv_size = sizeof(struct priv),
|
||||
.options = (const struct m_option[]) {
|
||||
OPT_STRING("device", dev, 0, OPTDEF_STR(SIO_DEVANY)),
|
||||
{0}
|
||||
},
|
||||
};
|
||||
@@ -286,12 +286,16 @@ Installation directories:
|
||||
--datadir=DIR directory for installing machine independent
|
||||
data files (skins, etc) [PREFIX/share/mpv]
|
||||
--mandir=DIR directory for installing man pages [PREFIX/share/man]
|
||||
--docdir=DIR directory for installing docs [PREFIX/share/doc/mpv]
|
||||
--confdir=DIR directory for installing configuration files
|
||||
[PREFIX/etc/mpv]
|
||||
--localedir=DIR directory for gettext locales [PREFIX/share/locale]
|
||||
|
||||
Optional features:
|
||||
--disable-encoding disable encoding functionality [enable]
|
||||
--disable-lua disable Lua scripting support [autodetect]
|
||||
--lua=LUA select Lua package which should be autodetected
|
||||
Choices: 51 51deb 52 52deb luajit
|
||||
--disable-libguess disable libguess [autodetect]
|
||||
--enable-terminfo use terminfo database for key codes [autodetect]
|
||||
--enable-termcap use termcap database for key codes [autodetect]
|
||||
@@ -316,16 +320,15 @@ Optional features:
|
||||
--disable-bluray disable Blu-ray support [autodetect]
|
||||
--disable-dvdread disable libdvdread [autodetect]
|
||||
--disable-enca disable ENCA charset oracle library [autodetect]
|
||||
--enable-macosx-bundle enable Mac OS X bundle file locations [autodetect]
|
||||
--disable-pthreads disable Posix threads support [autodetect]
|
||||
--disable-libass disable subtitle rendering with libass [autodetect]
|
||||
--disable-libass-osd disable OSD rendering with libass [autodetect]
|
||||
--enable-rpath enable runtime linker path for extra libs [disabled]
|
||||
--disable-libpostproc disable postprocess filter (vf_pp) [autodetect]
|
||||
--disable-libavdevice enable libavdevice demuxers [autodetect]
|
||||
--disable-libavfilter enable libavfilter [autodetect]
|
||||
--disable-vf-lavfi enable vf_lavfi libavfilter bridge [audodetect]
|
||||
--disable-af-lavfi enable af_lavfi libavfilter bridge [audodetect]
|
||||
--disable-libavdevice disable libavdevice demuxers [autodetect]
|
||||
--disable-libavfilter disable libavfilter [autodetect]
|
||||
--disable-vf-lavfi disable vf_lavfi libavfilter bridge [audodetect]
|
||||
--disable-af-lavfi disable af_lavfi libavfilter bridge [audodetect]
|
||||
|
||||
Codecs:
|
||||
--enable-mng enable MNG input support [autodetect]
|
||||
@@ -347,6 +350,8 @@ Video output:
|
||||
--enable-sdl2 enable SDL 2.0+ audio and video output [disable]
|
||||
--enable-xv enable Xv video output [autodetect]
|
||||
--enable-vdpau enable VDPAU acceleration [autodetect]
|
||||
--enable-vda enable VDA acceleration [autodetect]
|
||||
--enable-vaapi enable VAAPI acceleration [autodetect]
|
||||
--enable-vm enable XF86VidMode support [autodetect]
|
||||
--enable-xinerama enable Xinerama support [autodetect]
|
||||
--enable-x11 enable X11 video output [autodetect]
|
||||
@@ -359,6 +364,7 @@ Audio output:
|
||||
--disable-alsa disable ALSA audio output [autodetect]
|
||||
--disable-ossaudio disable OSS audio output [autodetect]
|
||||
--disable-rsound disable RSound audio output [autodetect]
|
||||
--disable-sndio disable sndio audio output [autodetect]
|
||||
--disable-pulse disable Pulseaudio audio output [autodetect]
|
||||
--disable-portaudio disable PortAudio audio output [autodetect]
|
||||
--disable-jack disable JACK audio output [autodetect]
|
||||
@@ -380,6 +386,7 @@ Miscellaneous options:
|
||||
--enable-static build a statically linked binary
|
||||
--with-install=PATH path to a custom install program
|
||||
--disable-manpage do not build and install manpage [auto]
|
||||
--disable-pdf do not build and install PDF manual [auto]
|
||||
--disable-build-date do not include binary compile time
|
||||
|
||||
Advanced options:
|
||||
@@ -421,6 +428,9 @@ _wayland=auto
|
||||
_xss=auto
|
||||
_xv=auto
|
||||
_vdpau=auto
|
||||
_vda=auto
|
||||
_vda_refcounting=auto
|
||||
_vaapi=auto
|
||||
_direct3d=auto
|
||||
_sdl=no
|
||||
_sdl2=no
|
||||
@@ -450,6 +460,7 @@ _lcms2=auto
|
||||
_xinerama=auto
|
||||
_vm=auto
|
||||
_xf86keysym=auto
|
||||
_sndio=auto
|
||||
_alsa=auto
|
||||
_select=yes
|
||||
_radio=no
|
||||
@@ -474,12 +485,12 @@ _cdda=auto
|
||||
_coreaudio=auto
|
||||
_corevideo=auto
|
||||
_cocoa=auto
|
||||
_macosx_bundle=auto
|
||||
_enca=auto
|
||||
_pthreads=auto
|
||||
_ass=auto
|
||||
_libass_osd=auto
|
||||
_rpath=no
|
||||
lua=auto
|
||||
libpostproc=auto
|
||||
libavfilter=auto
|
||||
vf_lavfi=auto
|
||||
@@ -490,6 +501,7 @@ _priority=no
|
||||
def_dos_paths="#define HAVE_DOS_PATHS 0"
|
||||
def_priority="#undef CONFIG_PRIORITY"
|
||||
_build_man=auto
|
||||
_build_pdf=auto
|
||||
_build_date=yes
|
||||
for ac_option do
|
||||
case "$ac_option" in
|
||||
@@ -505,6 +517,9 @@ for ac_option do
|
||||
--mandir=*)
|
||||
_mandir=$(echo $ac_option | cut -d '=' -f 2)
|
||||
;;
|
||||
--docdir=*)
|
||||
_docdir=$(echo $ac_option | cut -d '=' -f 2)
|
||||
;;
|
||||
--confdir=*)
|
||||
_confdir=$(echo $ac_option | cut -d '=' -f 2)
|
||||
;;
|
||||
@@ -582,6 +597,10 @@ for ac_option do
|
||||
--disable-xv) _xv=no ;;
|
||||
--enable-vdpau) _vdpau=yes ;;
|
||||
--disable-vdpau) _vdpau=no ;;
|
||||
--enable-vda) _vda=yes ;;
|
||||
--disable-vda) _vda=no ;;
|
||||
--enable-vaapi) _vaapi=yes ;;
|
||||
--disable-vaapi) _vaapi=no ;;
|
||||
--enable-direct3d) _direct3d=yes ;;
|
||||
--disable-direct3d) _direct3d=no ;;
|
||||
--enable-sdl) _sdl=yes ;;
|
||||
@@ -608,6 +627,8 @@ for ac_option do
|
||||
--disable-ossaudio) _ossaudio=no ;;
|
||||
--enable-rsound) _rsound=yes ;;
|
||||
--disable-rsound) _rsound=no ;;
|
||||
--enable-sndio) _sndio=yes ;;
|
||||
--disable-sndio) _sndio=no ;;
|
||||
--enable-pulse) _pulse=yes ;;
|
||||
--disable-pulse) _pulse=no ;;
|
||||
--enable-portaudio) _portaudio=yes ;;
|
||||
@@ -666,6 +687,9 @@ for ac_option do
|
||||
--disable-libavresample) _disable_avresample=yes ;;
|
||||
--enable-libavresample) _disable_avresample=no ;;
|
||||
|
||||
--enable-lua) lua=yes ;;
|
||||
--disable-lua) lua=no ;;
|
||||
--lua=*) lua_pkg=$(echo $ac_option | cut -d '=' -f 2) ;;
|
||||
--enable-lirc) _lirc=yes ;;
|
||||
--disable-lirc) _lirc=no ;;
|
||||
--enable-lircc) _lircc=yes ;;
|
||||
@@ -708,11 +732,11 @@ for ac_option do
|
||||
--disable-corevideo) _corevideo=no ;;
|
||||
--enable-cocoa) _cocoa=yes ;;
|
||||
--disable-cocoa) _cocoa=no ;;
|
||||
--enable-macosx-bundle) _macosx_bundle=yes ;;
|
||||
--disable-macosx-bundle) _macosx_bundle=no ;;
|
||||
|
||||
--enable-manpage) _build_man=yes ;;
|
||||
--disable-manpage) _build_man=no ;;
|
||||
--enable-pdf) _build_pdf=yes ;;
|
||||
--disable-pdf) _build_pdf=no ;;
|
||||
|
||||
--enable-build-date) _build_date=yes ;;
|
||||
--disable-build-date) _build_date=no ;;
|
||||
@@ -727,6 +751,7 @@ done
|
||||
# Atmos: moved this here, to be correct, if --prefix is specified
|
||||
test -z "$_bindir" && _bindir="$_prefix/bin"
|
||||
test -z "$_mandir" && _mandir="$_prefix/share/man"
|
||||
test -z "$_docdir" && _docdir="$_prefix/share/doc/mpv"
|
||||
test -z "$_confdir" && _confdir="$_prefix/etc/mpv"
|
||||
test -z "$_localedir" && _localedir="$_prefix/share/locale"
|
||||
|
||||
@@ -920,6 +945,24 @@ else
|
||||
fi
|
||||
echores "$_build_man"
|
||||
|
||||
_rst2latex=rst2latex
|
||||
if [ -f "$(which rst2latex.py)" ] ; then
|
||||
_rst2latex=rst2latex.py
|
||||
fi
|
||||
|
||||
echocheck "whether to build manual PDFs with rst2latex"
|
||||
texcheck() {
|
||||
echo test | $_rst2latex --config=DOCS/man/docutils.conf | pdflatex -halt-on-error -draftmode -output-directory="$mplayer_tmpdir"
|
||||
}
|
||||
|
||||
if test "$_build_pdf" = auto ; then
|
||||
_build_pdf=no
|
||||
command_check texcheck && _build_pdf=yes
|
||||
else
|
||||
_build_pdf=no
|
||||
fi
|
||||
echores "$_build_pdf"
|
||||
|
||||
echocheck "whether to print binary build date"
|
||||
if test "$_build_date" = yes ; then
|
||||
_build_yes=yes
|
||||
@@ -1547,19 +1590,6 @@ fi
|
||||
echores "$_sys_sysinfo"
|
||||
|
||||
|
||||
if darwin; then
|
||||
|
||||
echocheck "Mac OS X Bundle file locations"
|
||||
def_macosx_bundle='#undef CONFIG_MACOSX_BUNDLE'
|
||||
test "$_macosx_bundle" = auto
|
||||
if test "$_macosx_bundle" = yes ; then
|
||||
extra_ldflags="$extra_ldflags -headerpad_max_install_names"
|
||||
def_macosx_bundle='#define CONFIG_MACOSX_BUNDLE 1'
|
||||
fi
|
||||
echores "$_macosx_bundle"
|
||||
|
||||
fi #if darwin
|
||||
|
||||
echocheck "pkg-config"
|
||||
if $($_pkg_config --version > /dev/null 2>&1); then
|
||||
if test "$_ld_static"; then
|
||||
@@ -1694,17 +1724,24 @@ depends_on_application_services(){
|
||||
|
||||
fi #if darwin
|
||||
|
||||
_wlver="1.2.0"
|
||||
echocheck "Wayland"
|
||||
if test "$_wayland" != no; then
|
||||
if test "$_wayland" = yes || test "$_wayland" = auto; then
|
||||
_wayland="no"
|
||||
pkg_config_add "wayland-client >= 1.0.0 wayland-egl >= 9.0.0 wayland-cursor >= 1.0.0 xkbcommon >= 0.3.0" \
|
||||
&& _wayland="yes"
|
||||
pkg_config_add "wayland-client >= $_wlver wayland-cursor >= $_wlver xkbcommon >= 0.3.0" \
|
||||
&& _wayland="yes"
|
||||
fi
|
||||
if test "$_wayland" = yes; then
|
||||
res_comment=""
|
||||
def_wayland='#define CONFIG_WAYLAND'
|
||||
vomodules="wayland $vomodules"
|
||||
else
|
||||
_wayland="no"
|
||||
res_comment=""
|
||||
res_comment="version >= $_wlver"
|
||||
def_wayland='#undef CONFIG_WAYLAND'
|
||||
novomodules="wayland $novomodules"
|
||||
fi
|
||||
echores "$_wayland"
|
||||
unset _wlver
|
||||
|
||||
echocheck "X11 headers presence"
|
||||
_x11_headers="no"
|
||||
@@ -1845,6 +1882,34 @@ fi
|
||||
echores "$_vdpau"
|
||||
|
||||
|
||||
echocheck "VAAPI"
|
||||
_vaapi_vpp=no
|
||||
def_vaapi_vpp='#define CONFIG_VAAPI_VPP 0'
|
||||
if test "$_vaapi" = auto && test "$_x11" = yes ; then
|
||||
_vaapi=no
|
||||
if test "$_dl" = yes ; then
|
||||
pkg_config_add 'libva >= 0.32.0 libva-x11 >= 0.32.0' && _vaapi=yes
|
||||
fi
|
||||
fi
|
||||
if test "$_vaapi" = yes ; then
|
||||
def_vaapi='#define CONFIG_VAAPI 1'
|
||||
vomodules="vaapi $vomodules"
|
||||
else
|
||||
def_vaapi='#define CONFIG_VAAPI 0'
|
||||
novomodules="vaapi $novomodules"
|
||||
fi
|
||||
echores "$_vaapi"
|
||||
|
||||
if test "$_vaapi" = yes ; then
|
||||
echocheck "VAAPI VPP"
|
||||
if pkg-config 'libva >= 0.34.0' ; then
|
||||
_vaapi_vpp=yes
|
||||
def_vaapi_vpp='#define CONFIG_VAAPI_VPP 1'
|
||||
fi
|
||||
echores "$_vaapi_vpp"
|
||||
fi
|
||||
|
||||
|
||||
echocheck "Xinerama"
|
||||
if test "$_xinerama" = auto && test "$_x11" = yes ; then
|
||||
_xinerama=no
|
||||
@@ -2016,7 +2081,8 @@ EOF
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if test "$_wayland" = yes && cc_check -DGL_WAYLAND -lGL -lEGL ; then
|
||||
if test "$_wayland" = yes && cc_check -DGL_WAYLAND -lGL -lEGL &&
|
||||
pkg_config_add "wayland-egl >= 9.0.0"; then
|
||||
_gl=yes
|
||||
_gl_wayland=yes
|
||||
libs_mplayer="$libs_mplayer -lGL -lEGL"
|
||||
@@ -2261,6 +2327,23 @@ else
|
||||
fi
|
||||
|
||||
|
||||
echocheck "sndio"
|
||||
if test "$_sndio" = auto ; then
|
||||
_sndio=no
|
||||
statement_check sndio.h 'struct sio_par par; sio_initpar(&par);' -lsndio && _sndio=yes
|
||||
fi
|
||||
echores "$_sndio"
|
||||
|
||||
if test "$_sndio" = yes ; then
|
||||
def_sndio='#define CONFIG_SNDIO 1'
|
||||
aomodules="sndio $_aomodules"
|
||||
libs_mplayer="$libs_mplayer -lsndio"
|
||||
else
|
||||
def_sndio='#undef CONFIG_SNDIO'
|
||||
noaomodules="sndio $_noaomodules"
|
||||
fi
|
||||
|
||||
|
||||
echocheck "pulse"
|
||||
if test "$_pulse" = auto ; then
|
||||
_pulse=no
|
||||
@@ -2656,16 +2739,6 @@ if test "$_vdpau" = yes ; then
|
||||
fi
|
||||
fi
|
||||
|
||||
echocheck "libavcodec AV_CODEC_PROP_TEXT_SUB API"
|
||||
_avcodec_has_text_flag_api=no
|
||||
statement_check libavcodec/avcodec.h 'int x = AV_CODEC_PROP_TEXT_SUB' && _avcodec_has_text_flag_api=yes
|
||||
if test "$_avcodec_has_text_flag_api" = yes ; then
|
||||
def_avcodec_has_text_flag_api='#define HAVE_AV_CODEC_PROP_TEXT_SUB 1'
|
||||
else
|
||||
def_avcodec_has_text_flag_api='#define HAVE_AV_CODEC_PROP_TEXT_SUB 0'
|
||||
fi
|
||||
echores "$_avcodec_has_text_flag_api"
|
||||
|
||||
|
||||
echocheck "libavcodec avcodec_enum_to_chroma_pos API"
|
||||
_avcodec_has_chroma_pos_api=no
|
||||
@@ -2803,6 +2876,44 @@ else
|
||||
fi
|
||||
echores "$libpostproc"
|
||||
|
||||
def_vda='#define CONFIG_VDA 0'
|
||||
|
||||
if darwin ; then
|
||||
|
||||
echocheck "VDA"
|
||||
if test "$_vda" = auto ; then
|
||||
_vda=no
|
||||
if test "$_avutil_has_refcounting" = "yes" ; then
|
||||
header_check VideoDecodeAcceleration/VDADecoder.h &&
|
||||
statement_check libavcodec/vda.h 'ff_vda_create_decoder(NULL, NULL, NULL)' &&
|
||||
_vda=yes
|
||||
else
|
||||
res_comment="libavutil too old"
|
||||
fi
|
||||
fi
|
||||
if test "$_vda" = yes ; then
|
||||
def_vda='#define CONFIG_VDA 1'
|
||||
libs_mplayer="$libs_mplayer -framework VideoDecodeAcceleration -framework QuartzCore -framework IOSurface"
|
||||
else
|
||||
def_vda='#define CONFIG_VDA 0'
|
||||
fi
|
||||
echores "$_vda"
|
||||
|
||||
echocheck "VDA libavcodec refcounting"
|
||||
_vda_refcounting=no
|
||||
if test "$_vda" = yes ; then
|
||||
statement_check libavcodec/vda.h 'struct vda_context a = (struct vda_context) { .use_ref_buffer = 1 }' &&
|
||||
_vda_refcounting=yes
|
||||
fi
|
||||
if test "$_vda_refcounting" = "yes" ; then
|
||||
def_vda_refcounting='#define HAVE_VDA_LIBAVCODEC_REFCOUNTING 1'
|
||||
else
|
||||
def_vda_refcounting='#define HAVE_VDA_LIBAVCODEC_REFCOUNTING 0'
|
||||
fi
|
||||
echores "$_vda_refcounting"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
echocheck "TV interface"
|
||||
if test "$_tv" = yes ; then
|
||||
@@ -2899,6 +3010,111 @@ fi
|
||||
echores "$_pvr"
|
||||
|
||||
|
||||
# Note: Lua has no official .pc file, so there are different OS-specific ones.
|
||||
# Also, we support luajit, which is compatible to 5.1.
|
||||
# The situation is further complicated by distros supporting multiple Lua
|
||||
# versions, without ensuring libraries linking to conflicting Lua libs don't
|
||||
# cause issues. This is a real problem with libquvi.
|
||||
|
||||
cat > $TMPC << EOF
|
||||
#include <stdlib.h>
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
EOF
|
||||
# abuse $TMPH file as second temp file
|
||||
cat > $TMPH << EOF
|
||||
void test_lua(void) {
|
||||
lua_State *L = luaL_newstate();
|
||||
lua_pushstring(L, "test");
|
||||
lua_setglobal(L, "test");
|
||||
}
|
||||
void test_other(void) {
|
||||
EOF
|
||||
|
||||
# test all other Lua using packages (hack that gives us time)
|
||||
if test "$_libquvi4" = yes ; then
|
||||
|
||||
echo "#include <quvi/quvi.h>" >> $TMPC
|
||||
cat >> $TMPH << EOF
|
||||
quvi_t q;
|
||||
if (quvi_init(&q) == QUVI_OK)
|
||||
quvi_supported(q, "http://nope");
|
||||
EOF
|
||||
|
||||
fi
|
||||
|
||||
if test "$_libquvi9" = yes ; then
|
||||
|
||||
echo "#include <quvi.h>" >> $TMPC
|
||||
cat >> $TMPH << EOF
|
||||
quvi_t q = quvi_new();
|
||||
if (quvi_ok(q))
|
||||
quvi_supports(q, "http://nope", QUVI_SUPPORTS_MODE_OFFLINE, QUVI_SUPPORTS_TYPE_MEDIA);
|
||||
EOF
|
||||
|
||||
fi
|
||||
|
||||
cat >> $TMPH << EOF
|
||||
}
|
||||
int main(void) {
|
||||
test_lua();
|
||||
test_other();
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
cat $TMPH >> $TMPC
|
||||
|
||||
test_lua() {
|
||||
# changed by pkg_config_add
|
||||
old_extra_cflags="$extra_cflags"
|
||||
old_libs_mplayer="$libs_mplayer"
|
||||
echocheck "Lua $2 ($1)"
|
||||
if test "$lua" = yes ; then
|
||||
echores "no"
|
||||
return 1
|
||||
fi
|
||||
if test "x$lua_pkg" != "x" && test "$lua_pkg" != "$1" ; then
|
||||
echores "no"
|
||||
return 1
|
||||
fi
|
||||
if pkg_config_add "$2" ; then
|
||||
if test $_cross_compile = no ; then
|
||||
if cc_check && tmp_run ; then
|
||||
echo > /dev/null # idiot NOP
|
||||
else
|
||||
extra_cflags="$old_extra_cflags"
|
||||
libs_mplayer="$old_libs_mplayer"
|
||||
echores "no - does not run"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
lua=yes
|
||||
fi
|
||||
echores "$lua"
|
||||
test "$lua" = yes
|
||||
return $?
|
||||
}
|
||||
|
||||
if test "$lua" = auto ; then
|
||||
|
||||
lua=no
|
||||
test_lua 51 "lua >= 5.1.0 lua < 5.2.0"
|
||||
test_lua 51deb "lua5.1 >= 5.1.0" # debian
|
||||
test_lua luajit "luajit >= 2.0.0"
|
||||
# assume all our dependencies (libquvi in particular) link with 5.1
|
||||
test_lua 52 "lua >= 5.2.0"
|
||||
test_lua 52deb "lua5.2 >= 5.2.0" # debian
|
||||
|
||||
fi
|
||||
|
||||
if test "$lua" = yes ; then
|
||||
def_lua='#define CONFIG_LUA 1'
|
||||
else
|
||||
def_lua='#undef CONFIG_LUA'
|
||||
fi
|
||||
|
||||
echocheck "encoding"
|
||||
if test "$_encoding" = yes ; then
|
||||
def_encoding="#define CONFIG_ENCODING 1"
|
||||
@@ -3010,6 +3226,7 @@ CONFIGURATION = $configuration
|
||||
prefix = \$(DESTDIR)$_prefix
|
||||
BINDIR = \$(DESTDIR)$_bindir
|
||||
MANDIR = \$(DESTDIR)$_mandir
|
||||
DOCDIR = \$(DESTDIR)$_docdir
|
||||
CONFDIR = \$(DESTDIR)$_confdir
|
||||
LOCALEDIR = \$(DESTDIR)$_localedir
|
||||
|
||||
@@ -3028,6 +3245,8 @@ GETCH = $_getch
|
||||
TIMER = $_timer
|
||||
RST2MAN = $_rst2man
|
||||
BUILD_MAN = $_build_man
|
||||
RST2LATEX = $_rst2latex
|
||||
BUILD_PDF = $_build_pdf
|
||||
|
||||
EXESUF = $_exesuf
|
||||
EXESUFS_ALL = .exe
|
||||
@@ -3069,6 +3288,7 @@ DUMMY_OSD = $_dummy_osd
|
||||
LIBBLURAY = $_bluray
|
||||
LIBBS2B = $_libbs2b
|
||||
LCMS2 = $_lcms2
|
||||
LUA = $lua
|
||||
LIBPOSTPROC = $libpostproc
|
||||
LIBAVDEVICE = $libavdevice
|
||||
LIBAVFILTER = $libavfilter
|
||||
@@ -3079,7 +3299,6 @@ LIBQUVI = $_libquvi4
|
||||
LIBQUVI9 = $_libquvi9
|
||||
LIBGUESS = $_libguess
|
||||
LIRC = $_lirc
|
||||
MACOSX_BUNDLE = $_macosx_bundle
|
||||
MNG = $_mng
|
||||
MPG123 = $_mpg123
|
||||
OPENAL = $_openal
|
||||
@@ -3092,6 +3311,7 @@ PVR = $_pvr
|
||||
RADIO=$_radio
|
||||
RADIO_CAPTURE=$_radio_capture
|
||||
RSOUND = $_rsound
|
||||
SNDIO = $_sndio
|
||||
STREAM_CACHE = $_stream_cache
|
||||
TV = $_tv
|
||||
TV_V4L2 = $_tv_v4l2
|
||||
@@ -3099,6 +3319,10 @@ VCD = $_vcd
|
||||
VDPAU = $_vdpau
|
||||
VDPAU_DEC = $_vdpau_dec
|
||||
VDPAU_DEC_OLD = $_vdpau_dec_old
|
||||
VDA = $_vda
|
||||
VDA_REFCOUNTING = $_vda_refcounting
|
||||
VAAPI = $_vaapi
|
||||
VAAPI_VPP = $_vaapi_vpp
|
||||
WIN32 = $_win32
|
||||
X11 = $_x11
|
||||
WAYLAND = $_wayland
|
||||
@@ -3108,6 +3332,8 @@ XV = $_xv
|
||||
ENCODING = $_encoding
|
||||
|
||||
CONFIG_VDPAU = $_vdpau
|
||||
CONFIG_VDA = $_vda
|
||||
CONFIG_VAAPI = $_vaapi
|
||||
CONFIG_ZLIB = $_zlib
|
||||
|
||||
HAVE_PTHREADS = $_pthreads
|
||||
@@ -3165,7 +3391,6 @@ $def_termios
|
||||
$def_dl
|
||||
$def_dos_paths
|
||||
$def_iconv
|
||||
$def_macosx_bundle
|
||||
$def_priority
|
||||
|
||||
|
||||
@@ -3202,7 +3427,6 @@ $def_zlib
|
||||
$def_avutil_has_refcounting
|
||||
$def_avutil_has_qp_api
|
||||
$def_avcodec_new_vdpau_api
|
||||
$def_avcodec_has_text_flag_api
|
||||
$def_avcodec_has_chroma_pos_api
|
||||
$def_libpostproc
|
||||
$def_libavdevice
|
||||
@@ -3224,6 +3448,7 @@ $def_ossaudio_devmixer
|
||||
$def_pulse
|
||||
$def_portaudio
|
||||
$def_rsound
|
||||
$def_sndio
|
||||
|
||||
$def_ladspa
|
||||
$def_libbs2b
|
||||
@@ -3252,6 +3477,7 @@ $def_libquvi9
|
||||
$def_libguess
|
||||
|
||||
$def_lcms2
|
||||
$def_lua
|
||||
|
||||
|
||||
/* libvo options */
|
||||
@@ -3274,6 +3500,10 @@ $def_jpeg
|
||||
$def_mng
|
||||
$def_v4l2
|
||||
$def_vdpau
|
||||
$def_vda
|
||||
$def_vda_refcounting
|
||||
$def_vaapi
|
||||
$def_vaapi_vpp
|
||||
$def_vm
|
||||
$def_x11
|
||||
$def_wayland
|
||||
|
||||
@@ -312,6 +312,7 @@ static const struct mp_codec_tag mp_video_codec_tags[] = {
|
||||
{MKTAG('V', 'Q', 'A', 'V'), "ws_vqa"},
|
||||
{MKTAG('C', '9', '3', 'V'), "c93"},
|
||||
{MKTAG('V', 'P', '9', '0'), "vp9"},
|
||||
{MKTAG('p', 'r', '0', '0'), "prores"},
|
||||
{0},
|
||||
};
|
||||
|
||||
|
||||
+84
-50
@@ -59,6 +59,7 @@ extern const demuxer_desc_t demuxer_desc_lavf;
|
||||
extern const demuxer_desc_t demuxer_desc_mng;
|
||||
extern const demuxer_desc_t demuxer_desc_libass;
|
||||
extern const demuxer_desc_t demuxer_desc_subreader;
|
||||
extern const demuxer_desc_t demuxer_desc_playlist;
|
||||
|
||||
/* Please do not add any new demuxers here. If you want to implement a new
|
||||
* demuxer, add it to libavformat, except for wrappers around external
|
||||
@@ -77,12 +78,13 @@ const demuxer_desc_t *const demuxer_list[] = {
|
||||
#endif
|
||||
&demuxer_desc_matroska,
|
||||
&demuxer_desc_lavf,
|
||||
&demuxer_desc_subreader,
|
||||
&demuxer_desc_mf,
|
||||
#ifdef CONFIG_MNG
|
||||
&demuxer_desc_mng,
|
||||
#endif
|
||||
// auto-probe last, because it checks file-extensions only
|
||||
&demuxer_desc_mf,
|
||||
&demuxer_desc_playlist,
|
||||
// Pretty aggressive, so should be last.
|
||||
&demuxer_desc_subreader,
|
||||
/* Please do not add any new demuxers here. If you want to implement a new
|
||||
* demuxer, add it to libavformat, except for wrappers around external
|
||||
* libraries and demuxers requiring binary support. */
|
||||
@@ -114,12 +116,11 @@ static void ds_free_packs(struct demux_stream *ds)
|
||||
ds->eof = 0;
|
||||
}
|
||||
|
||||
static int packet_destroy(void *ptr)
|
||||
static void packet_destroy(void *ptr)
|
||||
{
|
||||
struct demux_packet *dp = ptr;
|
||||
talloc_free(dp->avpacket);
|
||||
free(dp->allocation);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct demux_packet *create_packet(size_t len)
|
||||
@@ -191,10 +192,9 @@ void free_demux_packet(struct demux_packet *dp)
|
||||
talloc_free(dp);
|
||||
}
|
||||
|
||||
static int destroy_avpacket(void *pkt)
|
||||
static void destroy_avpacket(void *pkt)
|
||||
{
|
||||
av_free_packet(pkt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct demux_packet *demux_copy_packet(struct demux_packet *dp)
|
||||
@@ -309,6 +309,8 @@ static void free_sh_stream(struct sh_stream *sh)
|
||||
|
||||
void free_demuxer(demuxer_t *demuxer)
|
||||
{
|
||||
if (!demuxer)
|
||||
return;
|
||||
if (demuxer->desc->close)
|
||||
demuxer->desc->close(demuxer);
|
||||
// free streams:
|
||||
@@ -466,7 +468,7 @@ struct demux_packet *demux_read_packet(struct sh_stream *sh)
|
||||
// packets from the queue.
|
||||
double demux_get_next_pts(struct sh_stream *sh)
|
||||
{
|
||||
if (sh) {
|
||||
if (sh && sh->ds->selected) {
|
||||
ds_get_packets(sh);
|
||||
if (sh->ds->head)
|
||||
return sh->ds->head->pts;
|
||||
@@ -538,6 +540,7 @@ static struct demuxer *open_given_type(struct MPOpts *opts,
|
||||
.filepos = -1,
|
||||
.opts = opts,
|
||||
.filename = talloc_strdup(demuxer, stream->url),
|
||||
.metadata = talloc_zero(demuxer, struct mp_tags),
|
||||
};
|
||||
demuxer->params = params; // temporary during open()
|
||||
stream_seek(stream, stream->start_pos);
|
||||
@@ -600,6 +603,10 @@ struct demuxer *demux_open(struct stream *stream, char *force_format,
|
||||
}
|
||||
}
|
||||
|
||||
// Peek this much data to avoid that stream_read() run by some demuxers
|
||||
// or stream filters will flush previous peeked data.
|
||||
stream_peek(stream, STREAM_BUFFER_SIZE);
|
||||
|
||||
// Test demuxers from first to last, one pass for each check_levels[] entry
|
||||
for (int pass = 0; check_levels[pass] != -1; pass++) {
|
||||
enum demux_check level = check_levels[pass];
|
||||
@@ -624,8 +631,7 @@ void demux_flush(demuxer_t *demuxer)
|
||||
demuxer->warned_queue_overflow = false;
|
||||
}
|
||||
|
||||
int demux_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_delay,
|
||||
int flags)
|
||||
int demux_seek(demuxer_t *demuxer, float rel_seek_secs, int flags)
|
||||
{
|
||||
if (!demuxer->seekable) {
|
||||
mp_tmsg(MSGT_SEEK, MSGL_WARN, "Cannot seek in this file.\n");
|
||||
@@ -672,11 +678,47 @@ int demux_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_delay,
|
||||
|
||||
dmx_seek:
|
||||
if (demuxer->desc->seek)
|
||||
demuxer->desc->seek(demuxer, rel_seek_secs, audio_delay, flags);
|
||||
demuxer->desc->seek(demuxer, rel_seek_secs, flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void mp_tags_set_str(struct mp_tags *tags, const char *key, const char *value)
|
||||
{
|
||||
mp_tags_set_bstr(tags, bstr0(key), bstr0(value));
|
||||
}
|
||||
|
||||
void mp_tags_set_bstr(struct mp_tags *tags, bstr key, bstr value)
|
||||
{
|
||||
for (int n = 0; n < tags->num_keys; n++) {
|
||||
if (bstrcasecmp0(key, tags->keys[n]) == 0) {
|
||||
talloc_free(tags->values[n]);
|
||||
tags->values[n] = talloc_strndup(tags, value.start, value.len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MP_RESIZE_ARRAY(tags, tags->keys, tags->num_keys + 1);
|
||||
MP_RESIZE_ARRAY(tags, tags->values, tags->num_keys + 1);
|
||||
tags->keys[tags->num_keys] = talloc_strndup(tags, key.start, key.len);
|
||||
tags->values[tags->num_keys] = talloc_strndup(tags, value.start, value.len);
|
||||
tags->num_keys++;
|
||||
}
|
||||
|
||||
char *mp_tags_get_str(struct mp_tags *tags, const char *key)
|
||||
{
|
||||
return mp_tags_get_bstr(tags, bstr0(key));
|
||||
}
|
||||
|
||||
char *mp_tags_get_bstr(struct mp_tags *tags, bstr key)
|
||||
{
|
||||
for (int n = 0; n < tags->num_keys; n++) {
|
||||
if (bstrcasecmp0(key, tags->keys[n]) == 0)
|
||||
return tags->values[n];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int demux_info_add(demuxer_t *demuxer, const char *opt, const char *param)
|
||||
{
|
||||
return demux_info_add_bstr(demuxer, bstr0(opt), bstr0(param));
|
||||
@@ -684,49 +726,34 @@ int demux_info_add(demuxer_t *demuxer, const char *opt, const char *param)
|
||||
|
||||
int demux_info_add_bstr(demuxer_t *demuxer, struct bstr opt, struct bstr param)
|
||||
{
|
||||
char **info = demuxer->info;
|
||||
int n = 0;
|
||||
|
||||
|
||||
for (n = 0; info && info[2 * n] != NULL; n++) {
|
||||
if (!bstrcasecmp(opt, bstr0(info[2*n]))) {
|
||||
if (!bstrcmp(param, bstr0(info[2*n + 1]))) {
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "Demuxer info %.*s set to unchanged value %.*s\n",
|
||||
BSTR_P(opt), BSTR_P(param));
|
||||
return 0;
|
||||
}
|
||||
mp_tmsg(MSGT_DEMUX, MSGL_INFO, "Demuxer info %.*s changed to %.*s\n",
|
||||
BSTR_P(opt), BSTR_P(param));
|
||||
talloc_free(info[2*n + 1]);
|
||||
info[2*n + 1] = talloc_strndup(demuxer->info, param.start, param.len);
|
||||
char *oldval = mp_tags_get_bstr(demuxer->metadata, opt);
|
||||
if (oldval) {
|
||||
if (bstrcmp0(param, oldval) == 0)
|
||||
return 0;
|
||||
}
|
||||
mp_tmsg(MSGT_DEMUX, MSGL_INFO, "Demuxer info %.*s changed to %.*s\n",
|
||||
BSTR_P(opt), BSTR_P(param));
|
||||
}
|
||||
|
||||
info = demuxer->info = talloc_realloc(demuxer, info, char *, 2 * (n + 2));
|
||||
info[2*n] = talloc_strndup(demuxer->info, opt.start, opt.len);
|
||||
info[2*n + 1] = talloc_strndup(demuxer->info, param.start, param.len);
|
||||
memset(&info[2 * (n + 1)], 0, 2 * sizeof(char *));
|
||||
|
||||
mp_tags_set_bstr(demuxer->metadata, opt, param);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int demux_info_print(demuxer_t *demuxer)
|
||||
{
|
||||
char **info = demuxer->info;
|
||||
struct mp_tags *info = demuxer->metadata;
|
||||
int n;
|
||||
|
||||
if (!info)
|
||||
if (!info || !info->num_keys)
|
||||
return 0;
|
||||
|
||||
mp_tmsg(MSGT_DEMUX, MSGL_INFO, "Clip info:\n");
|
||||
for (n = 0; info[2 * n] != NULL; n++) {
|
||||
mp_msg(MSGT_DEMUX, MSGL_INFO, " %s: %s\n", info[2 * n],
|
||||
info[2 * n + 1]);
|
||||
for (n = 0; n < info->num_keys; n++) {
|
||||
mp_msg(MSGT_DEMUX, MSGL_INFO, " %s: %s\n", info->keys[n],
|
||||
info->values[n]);
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CLIP_INFO_NAME%d=%s\n", n,
|
||||
info[2 * n]);
|
||||
info->keys[n]);
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CLIP_INFO_VALUE%d=%s\n", n,
|
||||
info[2 * n + 1]);
|
||||
info->values[n]);
|
||||
}
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CLIP_INFO_N=%d\n", n);
|
||||
|
||||
@@ -735,15 +762,7 @@ int demux_info_print(demuxer_t *demuxer)
|
||||
|
||||
char *demux_info_get(demuxer_t *demuxer, const char *opt)
|
||||
{
|
||||
int i;
|
||||
char **info = demuxer->info;
|
||||
|
||||
for (i = 0; info && info[2 * i] != NULL; i++) {
|
||||
if (!strcasecmp(opt, info[2 * i]))
|
||||
return info[2 * i + 1];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return mp_tags_get_str(demuxer->metadata, opt);
|
||||
}
|
||||
|
||||
void demux_info_update(struct demuxer *demuxer)
|
||||
@@ -849,18 +868,33 @@ void demuxer_sort_chapters(demuxer_t *demuxer)
|
||||
}
|
||||
|
||||
int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name,
|
||||
uint64_t start, uint64_t end)
|
||||
uint64_t start, uint64_t end, uint64_t demuxer_id)
|
||||
{
|
||||
struct demux_chapter new = {
|
||||
.original_index = demuxer->num_chapters,
|
||||
.start = start,
|
||||
.end = end,
|
||||
.name = name.len ? bstrdup0(demuxer, name) : NULL,
|
||||
.metadata = talloc_zero(demuxer, struct mp_tags),
|
||||
.demuxer_id = demuxer_id,
|
||||
};
|
||||
mp_tags_set_bstr(new.metadata, bstr0("TITLE"), name);
|
||||
MP_TARRAY_APPEND(demuxer, demuxer->chapters, demuxer->num_chapters, new);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void demuxer_add_chapter_info(struct demuxer *demuxer, uint64_t demuxer_id,
|
||||
bstr key, bstr value)
|
||||
{
|
||||
for (int n = 0; n < demuxer->num_chapters; n++) {
|
||||
struct demux_chapter *ch = &demuxer->chapters[n];
|
||||
if (ch->demuxer_id == demuxer_id) {
|
||||
mp_tags_set_bstr(ch->metadata, key, value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void add_stream_chapters(struct demuxer *demuxer)
|
||||
{
|
||||
if (demuxer->num_chapters)
|
||||
@@ -871,7 +905,7 @@ static void add_stream_chapters(struct demuxer *demuxer)
|
||||
if (stream_control(demuxer->stream, STREAM_CTRL_GET_CHAPTER_TIME, &p)
|
||||
!= STREAM_OK)
|
||||
return;
|
||||
demuxer_add_chapter(demuxer, bstr0(""), p * 1e9, 0);
|
||||
demuxer_add_chapter(demuxer, bstr0(""), p * 1e9, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+34
-14
@@ -55,14 +55,16 @@ enum timestamp_type {
|
||||
#define DEMUXER_CTRL_OK 1
|
||||
#define DEMUXER_CTRL_GUESS 2
|
||||
|
||||
#define DEMUXER_CTRL_UPDATE_INFO 8
|
||||
#define DEMUXER_CTRL_SWITCHED_TRACKS 9
|
||||
#define DEMUXER_CTRL_GET_TIME_LENGTH 10
|
||||
#define DEMUXER_CTRL_GET_START_TIME 11
|
||||
#define DEMUXER_CTRL_SWITCH_AUDIO 12
|
||||
#define DEMUXER_CTRL_RESYNC 13
|
||||
#define DEMUXER_CTRL_SWITCH_VIDEO 14
|
||||
#define DEMUXER_CTRL_IDENTIFY_PROGRAM 15
|
||||
enum demux_ctrl {
|
||||
DEMUXER_CTRL_UPDATE_INFO = 1,
|
||||
DEMUXER_CTRL_SWITCHED_TRACKS,
|
||||
DEMUXER_CTRL_GET_TIME_LENGTH,
|
||||
DEMUXER_CTRL_GET_START_TIME,
|
||||
DEMUXER_CTRL_SWITCH_AUDIO,
|
||||
DEMUXER_CTRL_RESYNC,
|
||||
DEMUXER_CTRL_SWITCH_VIDEO,
|
||||
DEMUXER_CTRL_IDENTIFY_PROGRAM,
|
||||
};
|
||||
|
||||
#define SEEK_ABSOLUTE (1 << 0)
|
||||
#define SEEK_FACTOR (1 << 1)
|
||||
@@ -107,16 +109,23 @@ typedef struct demuxer_desc {
|
||||
// The following functions are all optional
|
||||
int (*fill_buffer)(struct demuxer *demuxer); // 0 on EOF, otherwise 1
|
||||
void (*close)(struct demuxer *demuxer);
|
||||
void (*seek)(struct demuxer *demuxer, float rel_seek_secs,
|
||||
float audio_delay, int flags);
|
||||
void (*seek)(struct demuxer *demuxer, float rel_seek_secs, int flags);
|
||||
int (*control)(struct demuxer *demuxer, int cmd, void *arg);
|
||||
} demuxer_desc_t;
|
||||
|
||||
struct mp_tags {
|
||||
char **keys;
|
||||
char **values;
|
||||
int num_keys;
|
||||
};
|
||||
|
||||
typedef struct demux_chapter
|
||||
{
|
||||
int original_index;
|
||||
uint64_t start, end;
|
||||
char *name;
|
||||
struct mp_tags *metadata;
|
||||
uint64_t demuxer_id; // for mapping to internal demuxer data structures
|
||||
} demux_chapter_t;
|
||||
|
||||
struct matroska_data {
|
||||
@@ -141,6 +150,7 @@ typedef struct demux_attachment
|
||||
} demux_attachment_t;
|
||||
|
||||
struct demuxer_params {
|
||||
int matroska_num_wanted_uids;
|
||||
unsigned char (*matroska_wanted_uids)[16];
|
||||
int matroska_wanted_segment;
|
||||
bool *matroska_was_valid;
|
||||
@@ -183,8 +193,12 @@ typedef struct demuxer {
|
||||
// for trivial demuxers which just read the whole file for codec to use
|
||||
struct bstr file_contents;
|
||||
|
||||
// If the file is a playlist file
|
||||
struct playlist *playlist;
|
||||
|
||||
struct mp_tags *metadata;
|
||||
|
||||
void *priv; // demuxer-specific internal data
|
||||
char **info; // metadata
|
||||
struct MPOpts *opts;
|
||||
struct demuxer_params *params;
|
||||
} demuxer_t;
|
||||
@@ -222,8 +236,7 @@ struct demuxer *demux_open(struct stream *stream, char *force_format,
|
||||
struct demuxer_params *params, struct MPOpts *opts);
|
||||
|
||||
void demux_flush(struct demuxer *demuxer);
|
||||
int demux_seek(struct demuxer *demuxer, float rel_seek_secs, float audio_delay,
|
||||
int flags);
|
||||
int demux_seek(struct demuxer *demuxer, float rel_seek_secs, int flags);
|
||||
|
||||
int demux_info_add(struct demuxer *demuxer, const char *opt, const char *param);
|
||||
int demux_info_add_bstr(struct demuxer *demuxer, struct bstr opt,
|
||||
@@ -245,7 +258,9 @@ void demuxer_help(void);
|
||||
int demuxer_add_attachment(struct demuxer *demuxer, struct bstr name,
|
||||
struct bstr type, struct bstr data);
|
||||
int demuxer_add_chapter(struct demuxer *demuxer, struct bstr name,
|
||||
uint64_t start, uint64_t end);
|
||||
uint64_t start, uint64_t end, uint64_t demuxer_id);
|
||||
void demuxer_add_chapter_info(struct demuxer *demuxer, uint64_t demuxer_id,
|
||||
bstr key, bstr value);
|
||||
int demuxer_seek_chapter(struct demuxer *demuxer, int chapter,
|
||||
double *seek_pts);
|
||||
void demuxer_sort_chapters(demuxer_t *demuxer);
|
||||
@@ -281,4 +296,9 @@ double demux_packet_list_duration(struct demux_packet **pkts, int num_pkts);
|
||||
struct demux_packet *demux_packet_list_fill(struct demux_packet **pkts,
|
||||
int num_pkts, int *current);
|
||||
|
||||
void mp_tags_set_str(struct mp_tags *tags, const char *key, const char *value);
|
||||
void mp_tags_set_bstr(struct mp_tags *tags, bstr key, bstr value);
|
||||
char *mp_tags_get_str(struct mp_tags *tags, const char *key);
|
||||
char *mp_tags_get_bstr(struct mp_tags *tags, bstr key);
|
||||
|
||||
#endif /* MPLAYER_DEMUXER_H */
|
||||
+55
-12
@@ -603,12 +603,33 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
|
||||
avfc->pb = priv->pb;
|
||||
}
|
||||
|
||||
if (avformat_open_input(&avfc, priv->filename, priv->avif, NULL) < 0) {
|
||||
AVDictionary *dopts = NULL;
|
||||
|
||||
if (matches_avinputformat_name(priv, "rtsp")) {
|
||||
const char *transport = NULL;
|
||||
switch (opts->network_rtsp_transport) {
|
||||
case 1: transport = "udp"; break;
|
||||
case 2: transport = "tcp"; break;
|
||||
case 3: transport = "http"; break;
|
||||
}
|
||||
if (transport)
|
||||
av_dict_set(&dopts, "rtsp_transport", transport, 0);
|
||||
}
|
||||
|
||||
if (avformat_open_input(&avfc, priv->filename, priv->avif, &dopts) < 0) {
|
||||
mp_msg(MSGT_HEADER, MSGL_ERR,
|
||||
"LAVF_header: avformat_open_input() failed\n");
|
||||
av_dict_free(&dopts);
|
||||
return -1;
|
||||
}
|
||||
|
||||
t = NULL;
|
||||
while ((t = av_dict_get(dopts, "", t, AV_DICT_IGNORE_SUFFIX))) {
|
||||
mp_msg(MSGT_OPEN, MSGL_V, "[lavf] Could not set demux option %s=%s\n",
|
||||
t->key, t->value);
|
||||
}
|
||||
av_dict_free(&dopts);
|
||||
|
||||
priv->avfc = avfc;
|
||||
if (avformat_find_stream_info(avfc, NULL) < 0) {
|
||||
mp_msg(MSGT_HEADER, MSGL_ERR,
|
||||
@@ -627,7 +648,12 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
|
||||
(AVRational){1, 1000000000});
|
||||
t = av_dict_get(c->metadata, "title", NULL, 0);
|
||||
demuxer_add_chapter(demuxer, t ? bstr0(t->value) : bstr0(NULL),
|
||||
start, end);
|
||||
start, end, i);
|
||||
AVDictionaryEntry *t = NULL;
|
||||
while ((t = av_dict_get(c->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
|
||||
demuxer_add_chapter_info(demuxer, i, bstr0(t->key),
|
||||
bstr0(t->value));
|
||||
}
|
||||
}
|
||||
|
||||
add_new_streams(demuxer);
|
||||
@@ -691,10 +717,9 @@ static void seek_reset(demuxer_t *demux)
|
||||
priv->num_packets = 0;
|
||||
}
|
||||
|
||||
static int destroy_avpacket(void *pkt)
|
||||
static void destroy_avpacket(void *pkt)
|
||||
{
|
||||
av_free_packet(pkt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_more_av_packets(demuxer_t *demux)
|
||||
@@ -804,13 +829,12 @@ static int demux_lavf_fill_buffer(demuxer_t *demux)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs,
|
||||
float audio_delay, int flags)
|
||||
static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs, int flags)
|
||||
{
|
||||
lavf_priv_t *priv = demuxer->priv;
|
||||
int avsflags = 0;
|
||||
mp_msg(MSGT_DEMUX, MSGL_DBG2, "demux_seek_lavf(%p, %f, %f, %d)\n",
|
||||
demuxer, rel_seek_secs, audio_delay, flags);
|
||||
mp_msg(MSGT_DEMUX, MSGL_DBG2, "demux_seek_lavf(%p, %f, %d)\n",
|
||||
demuxer, rel_seek_secs, flags);
|
||||
|
||||
seek_reset(demuxer);
|
||||
|
||||
@@ -863,12 +887,31 @@ static void demux_seek_lavf(demuxer_t *demuxer, float rel_seek_secs,
|
||||
// API by default, because there are some major issues.
|
||||
// Set max_ts==ts, so that demuxing starts from an earlier position in
|
||||
// the worst case.
|
||||
int r = avformat_seek_file(priv->avfc, -1, INT64_MIN,
|
||||
priv->last_pts, priv->last_pts, avsflags);
|
||||
// To make this horrible situation even worse, some lavf demuxers have
|
||||
// broken timebase handling (everything that uses
|
||||
// ff_subtitles_queue_seek()), and always uses the stream timebase. So
|
||||
// we use the timebase and stream index of the first enabled stream
|
||||
// (i.e. a stream which can participate in seeking).
|
||||
int stream_index = -1;
|
||||
AVRational time_base = {1, AV_TIME_BASE};
|
||||
for (int n = 0; n < priv->num_streams; n++) {
|
||||
struct sh_stream *stream = priv->streams[n];
|
||||
AVStream *st = priv->avfc->streams[n];
|
||||
if (stream && st->discard != AVDISCARD_ALL) {
|
||||
stream_index = n;
|
||||
time_base = st->time_base;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int64_t pts = priv->last_pts;
|
||||
if (pts != AV_NOPTS_VALUE)
|
||||
pts = pts / (double)AV_TIME_BASE * av_q2d(av_inv_q(time_base));
|
||||
int r = avformat_seek_file(priv->avfc, stream_index, INT64_MIN,
|
||||
pts, pts, avsflags);
|
||||
// Similar issue as in the normal seeking codepath.
|
||||
if (r < 0) {
|
||||
avformat_seek_file(priv->avfc, -1, INT64_MIN,
|
||||
priv->last_pts, INT64_MAX, avsflags);
|
||||
avformat_seek_file(priv->avfc, stream_index, INT64_MIN,
|
||||
pts, INT64_MAX, avsflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -47,7 +47,8 @@ static void free_mf(mf_t *mf)
|
||||
}
|
||||
}
|
||||
|
||||
static void demux_seek_mf(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
|
||||
static void demux_seek_mf(demuxer_t *demuxer, float rel_seek_secs, int flags)
|
||||
{
|
||||
mf_t * mf = (mf_t *)demuxer->priv;
|
||||
int newpos = (flags & SEEK_ABSOLUTE)?0:mf->curr_frame - 1;
|
||||
|
||||
|
||||
+61
-25
@@ -188,7 +188,7 @@ typedef struct mkv_demuxer {
|
||||
|
||||
uint64_t skip_to_timecode;
|
||||
int v_skip_to_keyframe, a_skip_to_keyframe;
|
||||
bool subtitle_preroll;
|
||||
int subtitle_preroll;
|
||||
} mkv_demuxer_t;
|
||||
|
||||
#define REALHEADER_SIZE 16
|
||||
@@ -196,6 +196,10 @@ typedef struct mkv_demuxer {
|
||||
#define RAPROPERTIES4_SIZE 56
|
||||
#define RAPROPERTIES5_SIZE 70
|
||||
|
||||
// Maximum number of subtitle packets that are accepted for pre-roll.
|
||||
// (Subtitle packets added before first A/V keyframe packet is found with seek.)
|
||||
#define NUM_SUB_PREROLL_PACKETS 500
|
||||
|
||||
/**
|
||||
* \brief ensures there is space for at least one additional element
|
||||
* \param array array to grow
|
||||
@@ -369,7 +373,7 @@ static int demux_mkv_read_info(demuxer_t *demuxer)
|
||||
mkv_d->duration);
|
||||
}
|
||||
if (info.n_title) {
|
||||
demux_info_add_bstr(demuxer, bstr0("title"), info.title);
|
||||
demux_info_add_bstr(demuxer, bstr0("TITLE"), info.title);
|
||||
}
|
||||
if (info.n_segment_uid) {
|
||||
int len = info.segment_uid.len;
|
||||
@@ -388,11 +392,11 @@ static int demux_mkv_read_info(demuxer_t *demuxer)
|
||||
}
|
||||
if (demuxer->params && demuxer->params->matroska_wanted_uids) {
|
||||
unsigned char (*uids)[16] = demuxer->params->matroska_wanted_uids;
|
||||
if (!info.n_segment_uid)
|
||||
uids = NULL;
|
||||
for (int i = 0; i < MP_TALLOC_ELEMS(uids); i++) {
|
||||
if (!memcmp(info.segment_uid.start, uids[i], 16))
|
||||
goto out;
|
||||
if (info.n_segment_uid) {
|
||||
for (int i = 0; i < demuxer->params->matroska_num_wanted_uids; i++) {
|
||||
if (!memcmp(info.segment_uid.start, uids[i], 16))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
mp_tmsg(MSGT_DEMUX, MSGL_INFO,
|
||||
"[mkv] This is not one of the wanted files. "
|
||||
@@ -778,6 +782,7 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
|
||||
{
|
||||
struct MPOpts *opts = demuxer->opts;
|
||||
stream_t *s = demuxer->stream;
|
||||
int wanted_edition = opts->edition_id;
|
||||
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing chapters ] ---------\n");
|
||||
struct ebml_chapters file_chapters = {};
|
||||
@@ -789,8 +794,8 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
|
||||
int selected_edition = 0;
|
||||
int num_editions = file_chapters.n_edition_entry;
|
||||
struct ebml_edition_entry *editions = file_chapters.edition_entry;
|
||||
if (opts->edition_id >= 0 && opts->edition_id < num_editions) {
|
||||
selected_edition = opts->edition_id;
|
||||
if (wanted_edition >= 0 && wanted_edition < num_editions) {
|
||||
selected_edition = wanted_edition;
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] User-specified edition: %d\n",
|
||||
selected_edition);
|
||||
} else
|
||||
@@ -874,7 +879,8 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
|
||||
BSTR_P(name));
|
||||
|
||||
if (idx == selected_edition){
|
||||
demuxer_add_chapter(demuxer, name, chapter.start, chapter.end);
|
||||
demuxer_add_chapter(demuxer, name, chapter.start, chapter.end,
|
||||
ca->chapter_uid);
|
||||
if (editions[idx].edition_flag_ordered) {
|
||||
chapter.name = talloc_strndup(m_chapters, name.start,
|
||||
name.len);
|
||||
@@ -909,11 +915,21 @@ static int demux_mkv_read_tags(demuxer_t *demuxer)
|
||||
for (int i = 0; i < tags.n_tag; i++) {
|
||||
struct ebml_tag tag = tags.tag[i];
|
||||
if (tag.targets.target_track_uid || tag.targets.target_edition_uid ||
|
||||
tag.targets.target_chapter_uid || tag.targets.target_attachment_uid)
|
||||
tag.targets.target_attachment_uid)
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < tag.n_simple_tag; j++)
|
||||
demux_info_add_bstr(demuxer, tag.simple_tag[j].tag_name, tag.simple_tag[j].tag_string);
|
||||
if (tag.targets.target_chapter_uid) {
|
||||
for (int j = 0; j < tag.n_simple_tag; j++) {
|
||||
demuxer_add_chapter_info(demuxer, tag.targets.target_chapter_uid,
|
||||
tag.simple_tag[j].tag_name,
|
||||
tag.simple_tag[j].tag_string);
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < tag.n_simple_tag; j++) {
|
||||
demux_info_add_bstr(demuxer, tag.simple_tag[j].tag_name,
|
||||
tag.simple_tag[j].tag_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
talloc_free(parse_ctx.talloc_ctx);
|
||||
@@ -1152,6 +1168,7 @@ static const videocodec_info_t vinfo[] = {
|
||||
{MKV_V_VP8, mmioFOURCC('V', 'P', '8', '0'), 0},
|
||||
{MKV_V_VP9, mmioFOURCC('V', 'P', '9', '0'), 0},
|
||||
{MKV_V_DIRAC, mmioFOURCC('d', 'r', 'a', 'c'), 0},
|
||||
{MKV_V_PRORES, mmioFOURCC('p', 'r', '0', '0'), 0},
|
||||
{NULL, 0, 0}
|
||||
};
|
||||
|
||||
@@ -1613,6 +1630,8 @@ static const char *mkv_sub_tag[][2] = {
|
||||
{ MKV_S_TEXTASCII, "subrip"},
|
||||
{ MKV_S_TEXTUTF8, "subrip"},
|
||||
{ MKV_S_PGS, "hdmv_pgs_subtitle"},
|
||||
{ MKV_S_WEBVTT_S, "webvtt-webm"},
|
||||
{ MKV_S_WEBVTT_C, "webvtt-webm"},
|
||||
{0}
|
||||
};
|
||||
|
||||
@@ -2156,6 +2175,14 @@ static void mkv_parse_packet(mkv_track_t *track, bstr *buffer)
|
||||
buffer->len = size;
|
||||
}
|
||||
#endif
|
||||
} else if (track->codec_id && strcmp(track->codec_id, MKV_V_PRORES) == 0) {
|
||||
size_t newlen = buffer->len + 8;
|
||||
char *data = talloc_size(NULL, newlen);
|
||||
AV_WB32(data + 0, newlen);
|
||||
AV_WB32(data + 4, MKBETAG('i', 'c', 'p', 'f'));
|
||||
memcpy(data + 8, buffer->start, buffer->len);
|
||||
buffer->start = data;
|
||||
buffer->len = newlen;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2266,7 +2293,17 @@ static int handle_block(demuxer_t *demuxer, struct block_info *block_info)
|
||||
if (mkv_d->v_skip_to_keyframe)
|
||||
use_this_block = 0;
|
||||
} else if (track->type == MATROSKA_TRACK_SUBTITLE) {
|
||||
use_this_block |= mkv_d->subtitle_preroll;
|
||||
if (!use_this_block && mkv_d->subtitle_preroll)
|
||||
use_this_block = 1;
|
||||
if (use_this_block) {
|
||||
if (mkv_d->subtitle_preroll) {
|
||||
mkv_d->subtitle_preroll--;
|
||||
} else {
|
||||
// This could overflow the demuxer queue.
|
||||
if (mkv_d->a_skip_to_keyframe || mkv_d->v_skip_to_keyframe)
|
||||
use_this_block = 0;
|
||||
}
|
||||
}
|
||||
if (use_this_block) {
|
||||
if (laces > 1) {
|
||||
mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Subtitles use Matroska "
|
||||
@@ -2313,7 +2350,7 @@ static int handle_block(demuxer_t *demuxer, struct block_info *block_info)
|
||||
if (stream->type == STREAM_VIDEO) {
|
||||
mkv_d->v_skip_to_keyframe = 0;
|
||||
mkv_d->skip_to_timecode = 0;
|
||||
mkv_d->subtitle_preroll = false;
|
||||
mkv_d->subtitle_preroll = 0;
|
||||
} else if (stream->type == STREAM_AUDIO)
|
||||
mkv_d->a_skip_to_keyframe = 0;
|
||||
|
||||
@@ -2557,7 +2594,7 @@ static struct mkv_index *seek_with_cues(struct demuxer *demuxer, int seek_id,
|
||||
|
||||
if (index) { /* We've found an entry. */
|
||||
uint64_t seek_pos = index->filepos;
|
||||
if (mkv_d->subtitle_preroll) {
|
||||
if (flags & SEEK_SUBPREROLL) {
|
||||
uint64_t prev_target = 0;
|
||||
for (int i = 0; i < mkv_d->num_indexes; i++) {
|
||||
if (seek_id < 0 || mkv_d->indexes[i].tnum == seek_id) {
|
||||
@@ -2576,8 +2613,7 @@ static struct mkv_index *seek_with_cues(struct demuxer *demuxer, int seek_id,
|
||||
return index;
|
||||
}
|
||||
|
||||
static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
|
||||
float audio_delay, int flags)
|
||||
static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs, int flags)
|
||||
{
|
||||
mkv_demuxer_t *mkv_d = demuxer->priv;
|
||||
int64_t old_pos = stream_tell(demuxer->stream);
|
||||
@@ -2594,7 +2630,9 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
|
||||
a_tnum = track->tnum;
|
||||
}
|
||||
}
|
||||
mkv_d->subtitle_preroll = (flags & SEEK_SUBPREROLL) && st_active[STREAM_SUB];
|
||||
mkv_d->subtitle_preroll = NUM_SUB_PREROLL_PACKETS;
|
||||
if (!st_active[STREAM_SUB] || !st_active[STREAM_VIDEO])
|
||||
flags &= ~SEEK_SUBPREROLL;
|
||||
if (!(flags & (SEEK_BACKWARD | SEEK_FORWARD))) {
|
||||
if (flags & SEEK_ABSOLUTE || rel_seek_secs < 0)
|
||||
flags |= SEEK_BACKWARD;
|
||||
@@ -2623,14 +2661,13 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
|
||||
if (!index)
|
||||
stream_seek(demuxer->stream, old_pos);
|
||||
|
||||
if (st_active[STREAM_VIDEO])
|
||||
mkv_d->v_skip_to_keyframe = 1;
|
||||
mkv_d->v_skip_to_keyframe = st_active[STREAM_VIDEO];
|
||||
mkv_d->a_skip_to_keyframe = st_active[STREAM_AUDIO];
|
||||
if (flags & SEEK_FORWARD)
|
||||
mkv_d->skip_to_timecode = target_timecode;
|
||||
else
|
||||
mkv_d->skip_to_timecode = index ? index->timecode * mkv_d->tc_scale
|
||||
: 0;
|
||||
mkv_d->a_skip_to_keyframe = 1;
|
||||
|
||||
demux_mkv_fill_buffer(demuxer);
|
||||
} else if ((demuxer->movi_end <= 0) || !(flags & SEEK_ABSOLUTE))
|
||||
@@ -2666,10 +2703,9 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
|
||||
mkv_d->cluster_end = 0;
|
||||
stream_seek(s, index->filepos);
|
||||
|
||||
if (st_active[STREAM_VIDEO])
|
||||
mkv_d->v_skip_to_keyframe = 1;
|
||||
mkv_d->v_skip_to_keyframe = st_active[STREAM_VIDEO];
|
||||
mkv_d->a_skip_to_keyframe = st_active[STREAM_AUDIO];
|
||||
mkv_d->skip_to_timecode = index->timecode * mkv_d->tc_scale;
|
||||
mkv_d->a_skip_to_keyframe = 1;
|
||||
|
||||
demux_mkv_fill_buffer(demuxer);
|
||||
}
|
||||
|
||||
+1
-2
@@ -457,8 +457,7 @@ static void demux_mng_close(demuxer_t* demuxer)
|
||||
* \param[in] audio_delay unused, MNG does not contain audio
|
||||
* \param[in] flags bit flags, \p 1: absolute, \p 2: fractional position
|
||||
*/
|
||||
static void demux_mng_seek(demuxer_t * demuxer, float rel_seek_secs,
|
||||
float audio_delay, int flags)
|
||||
static void demux_mng_seek(demuxer_t * demuxer, float rel_seek_secs, int flags)
|
||||
{
|
||||
mng_priv_t * mng_priv = demuxer->priv;
|
||||
mng_handle h_mng = mng_priv->h_mng;
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 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 "mpvcore/mp_common.h"
|
||||
#include "mpvcore/options.h"
|
||||
#include "mpvcore/mp_msg.h"
|
||||
#include "mpvcore/playlist.h"
|
||||
#include "mpvcore/path.h"
|
||||
#include "stream/stream.h"
|
||||
#include "demux.h"
|
||||
|
||||
#define PROBE_SIZE (8 * 1024)
|
||||
|
||||
struct pl_parser {
|
||||
struct stream *s;
|
||||
char buffer[8 * 1024];
|
||||
int utf16;
|
||||
struct playlist *pl;
|
||||
bool probing;
|
||||
};
|
||||
|
||||
static char *pl_get_line0(struct pl_parser *p)
|
||||
{
|
||||
char *res = stream_read_line(p->s, p->buffer, sizeof(p->buffer), p->utf16);
|
||||
if (res) {
|
||||
int len = strlen(res);
|
||||
if (len > 0 && res[len - 1] == '\n')
|
||||
res[len - 1] = '\0';
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static bstr pl_get_line(struct pl_parser *p)
|
||||
{
|
||||
return bstr0(pl_get_line0(p));
|
||||
}
|
||||
|
||||
static void pl_add(struct pl_parser *p, bstr entry)
|
||||
{
|
||||
char *s = bstrto0(NULL, entry);
|
||||
playlist_add_file(p->pl, s);
|
||||
talloc_free(s);
|
||||
}
|
||||
|
||||
static bool pl_eof(struct pl_parser *p)
|
||||
{
|
||||
return p->s->eof;
|
||||
}
|
||||
|
||||
static int parse_m3u(struct pl_parser *p)
|
||||
{
|
||||
bstr line = bstr_strip(pl_get_line(p));
|
||||
if (!bstr_equals0(line, "#EXTM3U"))
|
||||
return -1;
|
||||
if (p->probing)
|
||||
return 0;
|
||||
while (!pl_eof(p)) {
|
||||
line = bstr_strip(pl_get_line(p));
|
||||
if (line.len == 0 || bstr_startswith0(line, "#"))
|
||||
continue;
|
||||
pl_add(p, line);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_ref_init(struct pl_parser *p)
|
||||
{
|
||||
bstr line = bstr_strip(pl_get_line(p));
|
||||
if (!bstr_equals0(line, "[Reference]"))
|
||||
return -1;
|
||||
while (!pl_eof(p)) {
|
||||
line = bstr_strip(pl_get_line(p));
|
||||
if (bstr_case_startswith(line, bstr0("Ref"))) {
|
||||
bstr_split_tok(line, "=", &(bstr){0}, &line);
|
||||
if (line.len)
|
||||
pl_add(p, line);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_mov_rtsptext(struct pl_parser *p)
|
||||
{
|
||||
bstr line = pl_get_line(p);
|
||||
if (!bstr_eatstart(&line, bstr0("RTSPtext")))
|
||||
return -1;
|
||||
if (p->probing)
|
||||
return 0;
|
||||
line = bstr_strip(line);
|
||||
do {
|
||||
if (bstr_case_startswith(line, bstr0("rtsp://"))) {
|
||||
pl_add(p, line);
|
||||
return 0;
|
||||
}
|
||||
} while (!pl_eof(p) && (line = bstr_strip(pl_get_line(p))).len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct pl_format {
|
||||
const char *name;
|
||||
int (*parse)(struct pl_parser *p);
|
||||
};
|
||||
|
||||
static const struct pl_format formats[] = {
|
||||
{"m3u", parse_m3u},
|
||||
{"ini", parse_ref_init},
|
||||
{"mov", parse_mov_rtsptext},
|
||||
};
|
||||
|
||||
static const struct pl_format *probe_pl(struct pl_parser *p, bool force)
|
||||
{
|
||||
int64_t start = stream_tell(p->s);
|
||||
for (int n = 0; n < MP_ARRAY_SIZE(formats); n++) {
|
||||
const struct pl_format *fmt = &formats[n];
|
||||
stream_seek(p->s, start);
|
||||
if (fmt->parse(p) >= 0)
|
||||
return fmt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int open_file(struct demuxer *demuxer, enum demux_check check)
|
||||
{
|
||||
bool force = check < DEMUX_CHECK_UNSAFE || check == DEMUX_CHECK_REQUEST;
|
||||
|
||||
struct pl_parser *p = talloc_zero(NULL, struct pl_parser);
|
||||
p->pl = talloc_zero(p, struct playlist);
|
||||
|
||||
bstr probe_buf = stream_peek(demuxer->stream, PROBE_SIZE);
|
||||
p->s = open_memory_stream(probe_buf.start, probe_buf.len);
|
||||
p->utf16 = stream_skip_bom(p->s);
|
||||
p->probing = true;
|
||||
const struct pl_format *fmt = probe_pl(p, force);
|
||||
free_stream(p->s);
|
||||
playlist_clear(p->pl);
|
||||
if (!fmt) {
|
||||
talloc_free(p);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->probing = false;
|
||||
p->s = demuxer->stream;
|
||||
p->utf16 = stream_skip_bom(p->s);
|
||||
bool ok = fmt->parse(p) >= 0;
|
||||
if (ok)
|
||||
playlist_add_base_path(p->pl, mp_dirname(demuxer->filename));
|
||||
demuxer->playlist = talloc_steal(demuxer, p->pl);
|
||||
demuxer->filetype = fmt->name;
|
||||
talloc_free(p);
|
||||
return ok ? 0 : -1;
|
||||
}
|
||||
|
||||
const struct demuxer_desc demuxer_desc_playlist = {
|
||||
.name = "playlist",
|
||||
.desc = "Playlist file",
|
||||
.open = open_file,
|
||||
};
|
||||
+7
-5
@@ -35,6 +35,7 @@
|
||||
|
||||
struct priv {
|
||||
int frame_size;
|
||||
int read_frames;
|
||||
double frame_rate;
|
||||
};
|
||||
|
||||
@@ -52,8 +53,8 @@ const m_option_t demux_rawaudio_opts[] = {
|
||||
static int vformat = MP_FOURCC_I420;
|
||||
static int mp_format;
|
||||
static char *codec;
|
||||
static int width = 0;
|
||||
static int height = 0;
|
||||
static int width = 1280;
|
||||
static int height = 720;
|
||||
static float fps = 25;
|
||||
static int imgsize = 0;
|
||||
|
||||
@@ -107,6 +108,7 @@ static int demux_rawaudio_open(demuxer_t *demuxer, enum demux_check check)
|
||||
*p = (struct priv) {
|
||||
.frame_size = samplesize * sh_audio->channels.num,
|
||||
.frame_rate = samplerate,
|
||||
.read_frames = samplerate,
|
||||
};
|
||||
|
||||
return 0;
|
||||
@@ -191,6 +193,7 @@ static int demux_rawvideo_open(demuxer_t *demuxer, enum demux_check check)
|
||||
*p = (struct priv) {
|
||||
.frame_size = imgsize,
|
||||
.frame_rate = fps,
|
||||
.read_frames = 1,
|
||||
};
|
||||
|
||||
return 0;
|
||||
@@ -203,7 +206,7 @@ static int raw_fill_buffer(demuxer_t *demuxer)
|
||||
if (demuxer->stream->eof)
|
||||
return 0;
|
||||
|
||||
struct demux_packet *dp = new_demux_packet(p->frame_size);
|
||||
struct demux_packet *dp = new_demux_packet(p->frame_size * p->read_frames);
|
||||
dp->pos = stream_tell(demuxer->stream) - demuxer->movi_start;
|
||||
dp->pts = (dp->pos / p->frame_size) / p->frame_rate;
|
||||
|
||||
@@ -214,8 +217,7 @@ static int raw_fill_buffer(demuxer_t *demuxer)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void raw_seek(demuxer_t *demuxer, float rel_seek_secs, float audio_delay,
|
||||
int flags)
|
||||
static void raw_seek(demuxer_t *demuxer, float rel_seek_secs, int flags)
|
||||
{
|
||||
struct priv *p = demuxer->priv;
|
||||
stream_t *s = demuxer->stream;
|
||||
|
||||
@@ -1341,6 +1341,8 @@ static int d_open_file(struct demuxer *demuxer, enum demux_check check)
|
||||
if (!res)
|
||||
return -1;
|
||||
|
||||
demuxer->filetype = sr.name;
|
||||
|
||||
sub_data *sd = sub_read_file(demuxer->stream, &sr);
|
||||
if (!sd)
|
||||
return -1;
|
||||
@@ -1367,8 +1369,7 @@ static int d_fill_buffer(struct demuxer *demuxer)
|
||||
return demuxer_add_packet(demuxer, p->sh, dp);
|
||||
}
|
||||
|
||||
static void d_seek(struct demuxer *demuxer, float secs, float audio_delay,
|
||||
int flags)
|
||||
static void d_seek(struct demuxer *demuxer, float secs, int flags)
|
||||
{
|
||||
struct priv *p = demuxer->priv;
|
||||
demux_packet_list_seek(p->pkts, p->num_pkts, &p->current, secs, flags);
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#define MKV_V_MJPEG "V_MJPEG"
|
||||
#define MKV_V_UNCOMPRESSED "V_UNCOMPRESSED"
|
||||
#define MKV_V_DIRAC "V_DIRAC"
|
||||
#define MKV_V_PRORES "V_PRORES"
|
||||
|
||||
#define MKV_S_TEXTASCII "S_TEXT/ASCII"
|
||||
#define MKV_S_TEXTUTF8 "S_TEXT/UTF8"
|
||||
@@ -88,5 +89,7 @@
|
||||
#define MKV_S_PGS "S_HDMV/PGS"
|
||||
#define MKV_S_SSA "S_SSA" // Deprecated
|
||||
#define MKV_S_ASS "S_ASS" // Deprecated
|
||||
#define MKV_S_WEBVTT_S "D_WEBVTT/SUBTITLES"
|
||||
#define MKV_S_WEBVTT_C "D_WEBVTT/CAPTIONS"
|
||||
|
||||
#endif /* MPLAYER_MATROSKA_H */
|
||||
@@ -131,6 +131,7 @@ typedef struct sh_video {
|
||||
struct vf_instance *vfilter; // video filter chain
|
||||
const struct vd_functions *vd_driver;
|
||||
int vf_initialized; // -1 failed, 0 not done, 1 done
|
||||
long vf_reconfig_count; // incremented each mpcodecs_reconfig_vo() call
|
||||
struct mp_image_params *vf_input; // video filter input params
|
||||
struct mp_hwdec_info *hwdec_info; // video output hwdec handles
|
||||
// win32-compatible codec parameters:
|
||||
|
||||
@@ -68,6 +68,7 @@ ovcopts = qscale=4
|
||||
profile-desc = "H.264 (x264)"
|
||||
ovc = libx264
|
||||
ovcopts = preset=medium,crf=23,threads=0
|
||||
vf-add = noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
||||
|
||||
[enc-v-mpeg2]
|
||||
profile-desc = "MPEG-2 Video (FFmpeg)"
|
||||
@@ -152,15 +153,14 @@ profile-desc = "MP4 for Blackberry Bold 9000"
|
||||
profile = enc-f-mp4
|
||||
vf-add = dsize=480:360:0:2,scale=w=0:h=0,dsize=-1:-1 # native screen res, letterbox
|
||||
ovcopts-add = maxrate=1500k,bufsize=1000k,rc_init_occupancy=900k,refs=1,profile=baseline
|
||||
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
||||
omaxfps = 30
|
||||
|
||||
[enc-to-nok-n900]
|
||||
profile-desc = "MP4 for Nokia N900"
|
||||
profile = enc-f-mp4
|
||||
vf-add = dsize=800:480:0:2,scale=w=0:h=0:noup=1 # native screen res, letterbox
|
||||
# DW = 800, DH = 480, SAR = 1
|
||||
vf-add = lavfi=graph="scale=floor(min(min(800\,dar*480)\,in_w*max(1\,sar))/2+0.5)*2:floor(min(min(800/dar\,480)\,in_h*max(1/sar\,1))/2+0.5)*2,setsar=1"
|
||||
ovcopts-add = profile=baseline,level=30,maxrate=10000k,bufsize=10000k,rc_init_occupancy=9000k,refs=5
|
||||
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
||||
omaxfps = 30
|
||||
|
||||
[enc-to-nok-6300]
|
||||
@@ -180,14 +180,12 @@ vf-add = scale=w=480:h=272,dsize=480:270
|
||||
srate = 48000
|
||||
channels = 2
|
||||
ovcopts-add = b=512k,profile=baseline
|
||||
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
||||
|
||||
[enc-to-iphone-noscale]
|
||||
profile-desc = "MP4 for iPhone (no scaling)"
|
||||
profile = enc-f-mp4
|
||||
oautofps = yes # iphone supports 30fps max
|
||||
ovcopts-add = maxrate=2500k,bufsize=1000k,rc_init_occupancy=900k,level=30,profile=baseline
|
||||
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
||||
omaxfps = 30
|
||||
|
||||
[enc-to-iphone]
|
||||
@@ -207,3 +205,51 @@ profile-desc = "MP4 for iPhone 5 (1136x640)"
|
||||
profile = enc-to-iphone-noscale
|
||||
vf-add = dsize=1136:480:1:2,scale=w=0:h=0,dsize=-1:-1 # panscan
|
||||
omaxfps = 30
|
||||
|
||||
[enc-to-hp-slate-7]
|
||||
profile-desc = "MP4 for HP Slate 7 (1024x600, crazy aspect)"
|
||||
profile = enc-f-mp4
|
||||
omaxfps = 30
|
||||
ovcopts-add = profile=high
|
||||
# DW = 1024, DH = 600, DAR = 97:54 (=> SAR = 2425:2304)
|
||||
vf-add = lavfi=graph="scale=floor(min(1024*min(1\,dar*54/97)\,in_w*max(1\,sar*2304/2425))/2+0.5)*2:floor(min(600*min(97/54/dar\,1)\,in_h*max(2425/2304/sar\,1))/2+0.5)*2,setsar=1"
|
||||
|
||||
# Advanced scaling for specific output devices - how it works:
|
||||
# DW = display width (px) (1024)
|
||||
# DH = display height (px) (600)
|
||||
# SAR = display sample aspect ratio, i.e. DAR * DH / DW (2425:2304)
|
||||
# DAR = display aspect ratio, i.e. SAR * DW / DH (97:54)
|
||||
# Variant: zoomed out
|
||||
# vf-add = lavfi=graph="scale=floor(min(DW*min(1\,dar/DAR)\,in_w*max(1\,sar/SAR))/2+0.5)*2:floor(min(DH*min(DAR/dar\,1)\,in_h*max(SAR/sar\,1))/2+0.5)*2,setsar=1"
|
||||
# Variant: zoomed in
|
||||
# vf-add = lavfi=graph="scale=floor(min(DW*max(1\,dar/DAR)\,in_w*max(1\,sar/SAR))/2+0.5)*2:floor(min(DH*max(DAR/dar\,1)\,in_h*max(SAR/sar\,1))/2+0.5)*2,setsar=1"
|
||||
# How it works:
|
||||
# 1a: DW, DH*dar/DAR - fit to display width
|
||||
# 1b: DH*DAR/dar, DH - fit to display height
|
||||
# 1: the min of 1a and 1b these (i.e. fit inside both width and height); for zoomed in view, use the max
|
||||
# 2a: in_w, in_h*SAR/sar - fit to original width
|
||||
# 2b: in_w*sar/SAR, in_h - fit to original height
|
||||
# 2: the max of 2a and 2b (i.e. avoid enlarging both dimensions - let HW scaling handle this)
|
||||
# output: the min of 1 and 2 (i.e. fulfill both constraints)
|
||||
# setsar=1 to prevent scaling on the device (skip this if the device actually wants the proper SAR to be specified for not performing needless scaling)
|
||||
#
|
||||
# Simplified special case for SAR == 1, DAR == DW/DH:
|
||||
# Variant: zoomed out
|
||||
# vf-add = lavfi=graph="scale=floor(min(min(DW\,dar*DH)\,in_w*max(1\,sar))/2+0.5)*2:floor(min(min(DW/dar\,DH)\,in_h*max(1/sar\,1))/2+0.5)*2,setsar=1"
|
||||
# Variant: zoomed in
|
||||
# vf-add = lavfi=graph="scale=floor(min(max(DW\,dar*DH)\,in_w*max(1\,sar))/2+0.5)*2:floor(min(max(DW/dar\,DH)\,in_h*max(1/sar\,1))/2+0.5)*2,setsar=1"
|
||||
# setsar=1 to prevent nasty almost-1 SAR to be passed to the codec due to the rounding which can fail
|
||||
#
|
||||
# If the device supports file SAR properly, we can make use of it to avoid
|
||||
# upscaling. Note that setsar cannot be used to fake a different output SAR by
|
||||
# applying a multiplier to the original one, so e..g it can't be used for the
|
||||
# HP Slate 7!
|
||||
# Variant: zoomed out
|
||||
# vf-add = lavfi=graph="scale=floor(min(DW*min(1\,dar/DAR)\,in_w)/2+0.5)*2:floor(min(DH*min(DAR/dar\,1)\,in_h)/2+0.5)*2"
|
||||
# Variant: zoomed in
|
||||
# vf-add = lavfi=graph="scale=floor(min(DW*max(1\,dar/DAR)\,in_w)/2+0.5)*2:floor(min(DH*max(DAR/dar\,1)\,in_h)/2+0.5)*2"
|
||||
# Simplified special case for SAR == 1, DAR == DW/DH:
|
||||
# Variant: zoomed out
|
||||
# vf-add = lavfi=graph="scale=floor(min(min(DW\,dar*DH)\,in_w)/2+0.5)*2:floor(min(min(DW/dar\,DH)\,in_h)/2+0.5)*2"
|
||||
# Variant: zoomed in
|
||||
# vf-add = lavfi=graph="scale=floor(min(max(DW\,dar*DH)\,in_w)/2+0.5)*2:floor(min(max(DW/dar\,DH)\,in_h)/2+0.5)*2"
|
||||
+33
-24
@@ -3,23 +3,30 @@
|
||||
#
|
||||
# Configuration files are read system-wide from /usr/local/etc/mpv.conf
|
||||
# and per-user from ~/.mpv/config, where per-user settings override
|
||||
# system-wide settings, all of which are overrriden by the command line.
|
||||
# system-wide settings, all of which are overridden by the command line.
|
||||
#
|
||||
# The configuration file settings are the same as the command line
|
||||
# options without the preceding '--'.
|
||||
# Configuration file settings and the command line options use the same
|
||||
# underlying mechanisms. Most options can be put into the configuration file
|
||||
# by dropping the preceding '--'. See the man page for a complete list of
|
||||
# options.
|
||||
#
|
||||
# Lines starting with '#' are comments and are ignored.
|
||||
#
|
||||
# See the CONFIGURATION FILES section in the man page
|
||||
# for a detailed description of the syntax.
|
||||
#
|
||||
# Profiles should be placed at the bottom of the configuration file to ensure
|
||||
# that settings wanted as defaults are not restricted to specific profiles.
|
||||
|
||||
#
|
||||
# Note that the commented example options usually do _not_ set the default
|
||||
# values. Calling mpv with --list-options is a nice way to see the default
|
||||
# values for most options.
|
||||
|
||||
##################
|
||||
# video settings #
|
||||
##################
|
||||
|
||||
# Specify default video driver (see -vo help for a list).
|
||||
# Specify default video driver (see --vo=help for a list).
|
||||
#vo=vdpau
|
||||
|
||||
# Start in fullscreen mode by default.
|
||||
@@ -31,6 +38,9 @@
|
||||
# don't allow a new window to have a size larger than 90% of the screen size
|
||||
#autofit-larger=90%x90%
|
||||
|
||||
# Disable the On Screen Controller (OSC).
|
||||
#osc=no
|
||||
|
||||
# Keep the player window on top of all other windows.
|
||||
#ontop=yes
|
||||
|
||||
@@ -39,7 +49,7 @@
|
||||
# audio settings #
|
||||
##################
|
||||
|
||||
# Specify default audio driver (see -ao help for a list).
|
||||
# Specify default audio driver (see --ao=help for a list).
|
||||
#ao=alsa
|
||||
|
||||
# Disable softvol usage, and always use the system mixer if available.
|
||||
@@ -50,20 +60,15 @@
|
||||
# other settings #
|
||||
##################
|
||||
|
||||
# Pretend to be Window Media Player.
|
||||
# Fixes playback when playlist and media file use the same URL.
|
||||
#user-agent=NSPlayer/4.1.0.3856
|
||||
|
||||
# Pretend to be Winamp
|
||||
# Fixes playback of some NSV streams
|
||||
#user-agent="Winamp NSV Player/5.12 (ultravox/2.0)"
|
||||
|
||||
# Drop frames to preserve audio/video sync.
|
||||
#framedrop = yes
|
||||
# Pretend to be a web browser. Might fix playback with some streaming sites.
|
||||
#user-agent="Mozilla/5.0"
|
||||
|
||||
# cache settings
|
||||
#
|
||||
# Use 8MB input cache by default.
|
||||
# Use 8MB input cache by default. The cache is enabled for network streams only.
|
||||
#cache-default = 8192
|
||||
#
|
||||
# Use 8MB input cache for everything, even local files.
|
||||
#cache = 8192
|
||||
#
|
||||
# Prefill 20% of the cache before starting playback.
|
||||
@@ -72,15 +77,15 @@
|
||||
# Prefill 50% of the cache before restarting playback after the cache emptied.
|
||||
#cache-seek-min = 50
|
||||
|
||||
# DVD: Display English subtitles if available.
|
||||
# Display English subtitles if available.
|
||||
#slang = en
|
||||
|
||||
# DVD: Play English audio tracks if available.
|
||||
#alang = en
|
||||
|
||||
# Use this for a widescreen monitor, non-square pixels.
|
||||
#monitoraspect=16:9
|
||||
# Play Finnish audio if available, fall back to English otherwise.
|
||||
#alang = fi,en
|
||||
|
||||
# Enable hardware decoding if available. Often, this requires using an certain
|
||||
# video output, otherwise no hardware decoding will be used.
|
||||
#hwdec = auto
|
||||
|
||||
############
|
||||
# Profiles #
|
||||
@@ -89,7 +94,11 @@
|
||||
# The options declared as part of profiles override global default settings,
|
||||
# but only take effect when the profile is active.
|
||||
|
||||
#[vo.vdpau]
|
||||
# The following profile can be enabled on the command line with: --profile=vdpau
|
||||
|
||||
#[vdpau]
|
||||
# The profile forces the vdpau VO.
|
||||
#vo=vdpau
|
||||
# Use hardware decoding (this might break playback of some h264 files)
|
||||
#hwdec=vdpau
|
||||
# Most video filters do not work with vdpau.
|
||||
|
||||
+144
-141
@@ -27,171 +27,174 @@
|
||||
# key combinations is only supported through the video windows of certain
|
||||
# output drivers (not in output windows of other drivers or in a terminal).
|
||||
|
||||
MOUSE_BTN0 ignore # don't do anything
|
||||
MOUSE_BTN0_DBL cycle fullscreen # toggle fullscreen on/off
|
||||
MOUSE_BTN2 cycle pause # toggle pause on/off
|
||||
MOUSE_BTN3 seek 10
|
||||
MOUSE_BTN4 seek -10
|
||||
MOUSE_BTN5 add volume 1
|
||||
MOUSE_BTN6 add volume -1
|
||||
# All lines in this file are commented. If you want to remap a key, copy the
|
||||
# file to ~/.mpv/input.conf, and uncomment and edit the binding you want to
|
||||
# change.
|
||||
|
||||
# Developer note:
|
||||
# etc/input.conf from the mpv source tree is baked into the mpv binary, with
|
||||
# all entries magically uncommented and parsed on initialization. This, this
|
||||
# file defines the mpv default key bindings. If this file is read as normal
|
||||
# config file, all lines starting with '#' are treated as comments (and this
|
||||
# file, if unedited, doesn't define any bindings).
|
||||
# Lines that have a space after the '#' are always ignored as real comments.
|
||||
|
||||
#MOUSE_BTN0 ignore # don't do anything
|
||||
#MOUSE_BTN0_DBL cycle fullscreen # toggle fullscreen on/off
|
||||
#MOUSE_BTN2 cycle pause # toggle pause on/off
|
||||
#MOUSE_BTN3 seek 10
|
||||
#MOUSE_BTN4 seek -10
|
||||
#MOUSE_BTN5 add volume 1
|
||||
#MOUSE_BTN6 add volume -1
|
||||
|
||||
# Mouse wheels, touchpad or other input devices that have axes
|
||||
# if the input devices supports precise scrolling it will also scale the
|
||||
# numeric value accordingly
|
||||
AXIS_UP seek 10
|
||||
AXIS_DOWN seek -10
|
||||
AXIS_LEFT add volume 1
|
||||
AXIS_RIGHT add volume -1
|
||||
#AXIS_UP seek 10
|
||||
#AXIS_DOWN seek -10
|
||||
#AXIS_LEFT seek 5
|
||||
#AXIS_RIGHT seek -5
|
||||
|
||||
# Seek units are in seconds, but note that these are limited by keyframes
|
||||
RIGHT seek 10
|
||||
LEFT seek -10
|
||||
UP seek 60
|
||||
DOWN seek -60
|
||||
## Seek units are in seconds, but note that these are limited by keyframes
|
||||
#RIGHT seek 10
|
||||
#LEFT seek -10
|
||||
#UP seek 60
|
||||
#DOWN seek -60
|
||||
# Do smaller, always exact (non-keyframe-limited), seeks with shift.
|
||||
# Don't show them on the OSD (no-osd).
|
||||
Shift+RIGHT no-osd seek 1 - exact
|
||||
Shift+LEFT no-osd seek -1 - exact
|
||||
Shift+UP no-osd seek 5 - exact
|
||||
Shift+DOWN no-osd seek -5 - exact
|
||||
PGUP seek 600
|
||||
PGDWN seek -600
|
||||
+ add audio-delay 0.100 # this changes audio/video sync
|
||||
- add audio-delay -0.100
|
||||
[ speed_mult 0.9091 # scale playback speed
|
||||
] speed_mult 1.1
|
||||
{ speed_mult 0.5
|
||||
} speed_mult 2.0
|
||||
BS set speed 1.0 # reset speed to normal
|
||||
q quit
|
||||
Q quit_watch_later
|
||||
q {encode} quit
|
||||
ESC quit
|
||||
p cycle pause # toggle pause/playback mode
|
||||
. frame_step # advance one frame and pause
|
||||
, frame_back_step # go back by one frame and pause
|
||||
SPACE cycle pause
|
||||
> playlist_next # skip to next file
|
||||
ENTER playlist_next force # skip to next file or quit
|
||||
< playlist_prev # skip to previous file
|
||||
o osd # cycle through OSD mode
|
||||
I show_text "${filename}" # display filename in osd
|
||||
P show_progress
|
||||
z add sub-delay -0.1 # subtract 100 ms delay from subs
|
||||
x add sub-delay +0.1 # add
|
||||
9 add volume -1
|
||||
/ add volume -1
|
||||
0 add volume 1
|
||||
* add volume 1
|
||||
( add balance -0.1 # adjust audio balance in favor of left
|
||||
) add balance 0.1 # right
|
||||
m cycle mute
|
||||
1 add contrast -1
|
||||
2 add contrast 1
|
||||
3 add brightness -1
|
||||
4 add brightness 1
|
||||
5 add gamma -1
|
||||
6 add gamma 1
|
||||
7 add saturation -1
|
||||
8 add saturation 1
|
||||
d cycle framedrop # cycle through framedrop modes
|
||||
#Shift+RIGHT no-osd seek 1 - exact
|
||||
#Shift+LEFT no-osd seek -1 - exact
|
||||
#Shift+UP no-osd seek 5 - exact
|
||||
#Shift+DOWN no-osd seek -5 - exact
|
||||
#PGUP seek 600
|
||||
#PGDWN seek -600
|
||||
#+ add audio-delay 0.100 # this changes audio/video sync
|
||||
#- add audio-delay -0.100
|
||||
#[ speed_mult 0.9091 # scale playback speed
|
||||
#] speed_mult 1.1
|
||||
#{ speed_mult 0.5
|
||||
#} speed_mult 2.0
|
||||
#BS set speed 1.0 # reset speed to normal
|
||||
#q quit
|
||||
#Q quit_watch_later
|
||||
#q {encode} quit
|
||||
#ESC quit
|
||||
#p cycle pause # toggle pause/playback mode
|
||||
#. frame_step # advance one frame and pause
|
||||
#, frame_back_step # go back by one frame and pause
|
||||
#SPACE cycle pause
|
||||
#> playlist_next # skip to next file
|
||||
#ENTER playlist_next force # skip to next file or quit
|
||||
#< playlist_prev # skip to previous file
|
||||
#o osd # cycle through OSD mode
|
||||
#I show_text "${filename}" # display filename in osd
|
||||
#P show_progress
|
||||
#z add sub-delay -0.1 # subtract 100 ms delay from subs
|
||||
#x add sub-delay +0.1 # add
|
||||
#9 add volume -1
|
||||
#/ add volume -1
|
||||
#0 add volume 1
|
||||
#* add volume 1
|
||||
#( add balance -0.1 # adjust audio balance in favor of left
|
||||
#) add balance 0.1 # right
|
||||
#m cycle mute
|
||||
#1 add contrast -1
|
||||
#2 add contrast 1
|
||||
#3 add brightness -1
|
||||
#4 add brightness 1
|
||||
#5 add gamma -1
|
||||
#6 add gamma 1
|
||||
#7 add saturation -1
|
||||
#8 add saturation 1
|
||||
#d cycle framedrop # cycle through framedrop modes
|
||||
# toggle deinterlacer; requires either vdpau output, -vf yadif or kerndeint
|
||||
D cycle deinterlace
|
||||
c cycle colormatrix
|
||||
#D cycle deinterlace
|
||||
#c cycle colormatrix
|
||||
# Next 3 currently only work with --no-ass
|
||||
r add sub-pos -1 # move subtitles up
|
||||
t add sub-pos +1 # down
|
||||
v cycle sub-visibility
|
||||
#r add sub-pos -1 # move subtitles up
|
||||
#t add sub-pos +1 # down
|
||||
#v cycle sub-visibility
|
||||
# stretch SSA/ASS subtitles with anamorphic videos to match historical
|
||||
V cycle ass-vsfilter-aspect-compat
|
||||
j cycle sub # cycle through subtitles
|
||||
J cycle sub down # ...backwards
|
||||
F cycle sub-forced-only
|
||||
SHARP cycle audio # switch audio streams
|
||||
_ cycle video
|
||||
TAB cycle program
|
||||
T cycle ontop # toggle video window ontop of other windows
|
||||
f cycle fullscreen # toggle fullscreen
|
||||
s screenshot # take a screenshot
|
||||
S screenshot video # ...without subtitles
|
||||
Alt+s screenshot - each-frame # automatically screenshot every frame
|
||||
w add panscan -0.1 # zoom out with -panscan 0 -fs
|
||||
e add panscan +0.1 # in
|
||||
POWER quit
|
||||
MENU cycle osd
|
||||
PLAY cycle pause
|
||||
PAUSE cycle pause
|
||||
PLAYPAUSE cycle pause
|
||||
STOP quit
|
||||
FORWARD seek 60
|
||||
REWIND seek -60
|
||||
NEXT playlist_next
|
||||
PREV playlist_prev
|
||||
VOLUME_UP add volume 1
|
||||
VOLUME_DOWN add volume -1
|
||||
MUTE cycle mute
|
||||
CLOSE_WIN quit
|
||||
CLOSE_WIN {encode} quit
|
||||
! add chapter -1 # skip to previous chapter
|
||||
@ add chapter 1 # next
|
||||
E cycle edition # next edition
|
||||
A cycle angle
|
||||
U stop
|
||||
#V cycle ass-vsfilter-aspect-compat
|
||||
#j cycle sub # cycle through subtitles
|
||||
#J cycle sub down # ...backwards
|
||||
#F cycle sub-forced-only
|
||||
#SHARP cycle audio # switch audio streams
|
||||
#_ cycle video
|
||||
#TAB cycle program
|
||||
#T cycle ontop # toggle video window ontop of other windows
|
||||
#f cycle fullscreen # toggle fullscreen
|
||||
#s screenshot # take a screenshot
|
||||
#S screenshot video # ...without subtitles
|
||||
#Alt+s screenshot - each-frame # automatically screenshot every frame
|
||||
#w add panscan -0.1 # zoom out with -panscan 0 -fs
|
||||
#e add panscan +0.1 # in
|
||||
#POWER quit
|
||||
#MENU cycle osd
|
||||
#PLAY cycle pause
|
||||
#PAUSE cycle pause
|
||||
#PLAYPAUSE cycle pause
|
||||
#STOP quit
|
||||
#FORWARD seek 60
|
||||
#REWIND seek -60
|
||||
#NEXT playlist_next
|
||||
#PREV playlist_prev
|
||||
#VOLUME_UP add volume 1
|
||||
#VOLUME_DOWN add volume -1
|
||||
#MUTE cycle mute
|
||||
#CLOSE_WIN quit
|
||||
#CLOSE_WIN {encode} quit
|
||||
#! add chapter -1 # skip to previous chapter
|
||||
#@ add chapter 1 # next
|
||||
#E cycle edition # next edition
|
||||
#A cycle angle
|
||||
#U stop
|
||||
|
||||
l cycle quvi-format 1
|
||||
L cycle quvi-format -1
|
||||
#l cycle quvi-format 1
|
||||
#L cycle quvi-format -1
|
||||
|
||||
# TV
|
||||
h tv_step_channel 1
|
||||
k tv_step_channel -1
|
||||
n tv_step_norm
|
||||
u tv_step_chanlist
|
||||
#h tv_step_channel 1
|
||||
#k tv_step_channel -1
|
||||
#n tv_step_norm
|
||||
#u tv_step_chanlist
|
||||
|
||||
# Apple Remote section
|
||||
AR_PLAY cycle pause
|
||||
AR_PLAY_HOLD quit
|
||||
AR_CENTER cycle pause
|
||||
AR_CENTER_HOLD quit
|
||||
AR_NEXT seek 10
|
||||
AR_NEXT_HOLD seek 120
|
||||
AR_PREV seek -10
|
||||
AR_PREV_HOLD seek -120
|
||||
AR_MENU show_progress
|
||||
AR_MENU_HOLD cycle mute
|
||||
AR_VUP add volume 1
|
||||
AR_VUP_HOLD add chapter 1
|
||||
AR_VDOWN add volume -1
|
||||
AR_VDOWN_HOLD add chapter -1
|
||||
|
||||
# Media Keys section
|
||||
MK_PLAY cycle pause
|
||||
MK_PREV playlist_prev
|
||||
MK_NEXT playlist_next
|
||||
#AR_PLAY cycle pause
|
||||
#AR_PLAY_HOLD quit
|
||||
#AR_CENTER cycle pause
|
||||
#AR_CENTER_HOLD quit
|
||||
#AR_NEXT seek 10
|
||||
#AR_NEXT_HOLD seek 120
|
||||
#AR_PREV seek -10
|
||||
#AR_PREV_HOLD seek -120
|
||||
#AR_MENU show_progress
|
||||
#AR_MENU_HOLD cycle mute
|
||||
#AR_VUP add volume 1
|
||||
#AR_VUP_HOLD add chapter 1
|
||||
#AR_VDOWN add volume -1
|
||||
#AR_VDOWN_HOLD add chapter -1
|
||||
|
||||
# Joystick section
|
||||
# WARNING: joystick support has to be explicitly enabled at
|
||||
# compiletime with --enable-joystick
|
||||
#
|
||||
|
||||
JOY_AXIS0_PLUS seek 10
|
||||
JOY_AXIS0_MINUS seek -10
|
||||
JOY_AXIS1_MINUS seek 60
|
||||
JOY_AXIS1_PLUS seek -60
|
||||
JOY_BTN0 cycle pause
|
||||
JOY_BTN1 cycle osd
|
||||
JOY_BTN2 add volume 1
|
||||
JOY_BTN3 add volume -1
|
||||
|
||||
# Mostly for internal purposes
|
||||
MOUSE_MOVE ignore
|
||||
MOUSE_LEAVE ignore
|
||||
#JOY_AXIS0_PLUS seek 10
|
||||
#JOY_AXIS0_MINUS seek -10
|
||||
#JOY_AXIS1_MINUS seek 60
|
||||
#JOY_AXIS1_PLUS seek -60
|
||||
#JOY_BTN0 cycle pause
|
||||
#JOY_BTN1 cycle osd
|
||||
#JOY_BTN2 add volume 1
|
||||
#JOY_BTN3 add volume -1
|
||||
|
||||
#
|
||||
# Not assigned by default
|
||||
# (not an exhaustive list of unbound commands)
|
||||
#
|
||||
|
||||
#? add sub-scale +0.1 # increase subtitle font size
|
||||
#? add sub-scale -0.1 # decrease subtitle font size
|
||||
#? sub_step -1 # immediately display next subtitle
|
||||
#? sub_step +1 # previous
|
||||
# ? add sub-scale +0.1 # increase subtitle font size
|
||||
# ? add sub-scale -0.1 # decrease subtitle font size
|
||||
# ? sub_step -1 # immediately display next subtitle
|
||||
# ? sub_step +1 # previous
|
||||
-239
@@ -1,239 +0,0 @@
|
||||
/* XPM */
|
||||
static char * mplayer_xpm[] = {
|
||||
"32 32 204 2",
|
||||
" c None",
|
||||
". c #1D153E",
|
||||
"+ c #251B4F",
|
||||
"@ c #2D2161",
|
||||
"# c #362773",
|
||||
"$ c #3A2A7D",
|
||||
"% c #3A2A7C",
|
||||
"& c #23194C",
|
||||
"* c #2C205E",
|
||||
"= c #342670",
|
||||
"- c #39297B",
|
||||
"; c #787682",
|
||||
"> c #817C94",
|
||||
", c #8982A6",
|
||||
"' c #9087B5",
|
||||
") c #9188B6",
|
||||
"! c #857BAF",
|
||||
"~ c #493B87",
|
||||
"{ c #29AEDE",
|
||||
"] c #E3F6FC",
|
||||
"^ c #FFFFFF",
|
||||
"/ c #F1F0F6",
|
||||
"( c #4A4561",
|
||||
"_ c #0BAEE7",
|
||||
": c #AAE3F7",
|
||||
"< c #D1D1D1",
|
||||
"[ c #077399",
|
||||
"} c #0BAEE8",
|
||||
"| c #D9F2FB",
|
||||
"1 c #FEFEFE",
|
||||
"2 c #087DA7",
|
||||
"3 c #E0F5FC",
|
||||
"4 c #07678A",
|
||||
"5 c #E1F5FC",
|
||||
"6 c #E5F6FD",
|
||||
"7 c #E7F7FD",
|
||||
"8 c #F5F4F8",
|
||||
"9 c #D2CEE1",
|
||||
"0 c #E2E0EC",
|
||||
"a c #E4E2ED",
|
||||
"b c #F0EFF5",
|
||||
"c c #CDC9DE",
|
||||
"d c #D1CEE1",
|
||||
"e c #FBFBFC",
|
||||
"f c #DFDFDF",
|
||||
"g c #CBCBCB",
|
||||
"h c #086B8E",
|
||||
"i c #E8F8FD",
|
||||
"j c #C2BDD7",
|
||||
"k c #3B2B7D",
|
||||
"l c #E1DFEB",
|
||||
"m c #5C4E93",
|
||||
"n c #8177AC",
|
||||
"o c #C5C0D9",
|
||||
"p c #4E408A",
|
||||
"q c #655899",
|
||||
"r c #8980B1",
|
||||
"s c #C1C1C1",
|
||||
"t c #535353",
|
||||
"u c #0A87B4",
|
||||
"v c #0BAAE3",
|
||||
"w c #EDF9FD",
|
||||
"x c #A199C1",
|
||||
"y c #6D619E",
|
||||
"z c #4A3B87",
|
||||
"A c #645799",
|
||||
"B c #55478F",
|
||||
"C c #756AA4",
|
||||
"D c #7F74AA",
|
||||
"E c #929292",
|
||||
"F c #8D8D8D",
|
||||
"G c #9A9A9A",
|
||||
"H c #919191",
|
||||
"I c #424242",
|
||||
"J c #DEDEDE",
|
||||
"K c #3E3E3E",
|
||||
"L c #5D5D5D",
|
||||
"M c #CFCFCF",
|
||||
"N c #878787",
|
||||
"O c #494949",
|
||||
"P c #BEBEBE",
|
||||
"Q c #4D4D4D",
|
||||
"R c #3B3B3B",
|
||||
"S c #F3F3F3",
|
||||
"T c #FDFEFF",
|
||||
"U c #0BA3D9",
|
||||
"V c #0993C4",
|
||||
"W c #8075AB",
|
||||
"X c #A59DC3",
|
||||
"Y c #3F2F80",
|
||||
"Z c #A9A2C6",
|
||||
"` c #463785",
|
||||
" . c #574A90",
|
||||
".. c #B5AFCE",
|
||||
"+. c #575757",
|
||||
"@. c #C8C8C8",
|
||||
"#. c #141414",
|
||||
"$. c #E2E2E2",
|
||||
"%. c #2A2A2A",
|
||||
"&. c #A9A9A9",
|
||||
"*. c #767676",
|
||||
"=. c #5C5C5C",
|
||||
"-. c #848484",
|
||||
";. c #ADADAD",
|
||||
">. c #C2C2C2",
|
||||
",. c #5F5F5F",
|
||||
"'. c #DDDDDD",
|
||||
"). c #FAFDFF",
|
||||
"!. c #0879A1",
|
||||
"~. c #F3FBFE",
|
||||
"{. c #9087B6",
|
||||
"]. c #DCD9E8",
|
||||
"^. c #A098C0",
|
||||
"/. c #FAF9FC",
|
||||
"(. c #776CA5",
|
||||
"_. c #CCC8DE",
|
||||
":. c #968DBA",
|
||||
"<. c #BBBBBB",
|
||||
"[. c #656565",
|
||||
"}. c #9B9B9B",
|
||||
"|. c #686868",
|
||||
"1. c #DADADA",
|
||||
"2. c #565656",
|
||||
"3. c #B4B4B4",
|
||||
"4. c #B2B2B2",
|
||||
"5. c #757575",
|
||||
"6. c #B5B5B5",
|
||||
"7. c #B1B1B1",
|
||||
"8. c #B0B0B0",
|
||||
"9. c #065F7E",
|
||||
"0. c #F4FBFE",
|
||||
"a. c #C0C0C0",
|
||||
"b. c #7F7F7F",
|
||||
"c. c #FDFDFD",
|
||||
"d. c #F7FCFE",
|
||||
"e. c #066587",
|
||||
"f. c #E1DEEB",
|
||||
"g. c #FCFBFD",
|
||||
"h. c #087FA9",
|
||||
"i. c #FAFDFE",
|
||||
"j. c #BCB6D3",
|
||||
"k. c #665A9A",
|
||||
"l. c #6A5E9D",
|
||||
"m. c #51438C",
|
||||
"n. c #A8A1C6",
|
||||
"o. c #FFFEFF",
|
||||
"p. c #F1F1F1",
|
||||
"q. c #B6B0CF",
|
||||
"r. c #625597",
|
||||
"s. c #BFBDC8",
|
||||
"t. c #EDEDED",
|
||||
"u. c #EFEEF5",
|
||||
"v. c #7368A3",
|
||||
"w. c #9B93BD",
|
||||
"x. c #EEF9FD",
|
||||
"y. c #9998A1",
|
||||
"z. c #F8F8FB",
|
||||
"A. c #EBEAF2",
|
||||
"B. c #111111",
|
||||
"C. c #8A8A8A",
|
||||
"D. c #F7F7F7",
|
||||
"E. c #F8F7FA",
|
||||
"F. c #84C2E3",
|
||||
"G. c #065A77",
|
||||
"H. c #221A42",
|
||||
"I. c #A19AC1",
|
||||
"J. c #EBE9F2",
|
||||
"K. c #FBFAFC",
|
||||
"L. c #CECADF",
|
||||
"M. c #7A6FA7",
|
||||
"N. c #000000",
|
||||
"O. c #1E1E1E",
|
||||
"P. c #A1A1A1",
|
||||
"Q. c #958DB9",
|
||||
"R. c #32246B",
|
||||
"S. c #291E58",
|
||||
"T. c #201746",
|
||||
"U. c #221949",
|
||||
"V. c #867CAF",
|
||||
"W. c #2F2F2F",
|
||||
"X. c #BFBFBF",
|
||||
"Y. c #A099C1",
|
||||
"Z. c #352671",
|
||||
"`. c #56498F",
|
||||
" + c #FDFDFE",
|
||||
".+ c #151515",
|
||||
"++ c #979797",
|
||||
"@+ c #FCFCFC",
|
||||
"#+ c #7065A1",
|
||||
"$+ c #1E1641",
|
||||
"%+ c #1D153F",
|
||||
"&+ c #251B51",
|
||||
"*+ c #9C94BE",
|
||||
"=+ c #D8D8D8",
|
||||
"-+ c #EFEFEF",
|
||||
";+ c #B8B2D0",
|
||||
">+ c #2E2162",
|
||||
",+ c #2A1F5B",
|
||||
"'+ c #7165A1",
|
||||
")+ c #B3ADCD",
|
||||
"!+ c #B7B1D0",
|
||||
"~+ c #302366",
|
||||
"{+ c #1F1642",
|
||||
"]+ c #201744",
|
||||
" ",
|
||||
" ",
|
||||
" . ",
|
||||
" + @ # $ $ $ $ $ % ",
|
||||
" & * = $ $ $ $ $ $ $ $ $ $ $ $ $ - ",
|
||||
" ; > , ' ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ! ~ ",
|
||||
" { ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ / ( ",
|
||||
" _ : ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ < ",
|
||||
"[ } | ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 ",
|
||||
"2 } 3 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ",
|
||||
"4 } 5 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ",
|
||||
" } 6 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ",
|
||||
" } 7 ^ 8 9 ^ 0 a b c d e f g ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ h ",
|
||||
" } i ^ j k l m n o p q r s t ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ u ",
|
||||
" v w ^ x ~ y z A o B C D E F G H I J K J L M N O P Q R S T U ",
|
||||
" V w ^ W X Y Z ` o ...b +.@.#.$.R S %.&.*.=.-.;.>.,.'.^ ).} ",
|
||||
" !.~.^ {.].^./.(._.:.^ ^ *.<.[.}.|.1.2.O 3.4.5.6.7.8.^ ^ ).} ",
|
||||
" 9.0.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ a.*.b.c.^ ^ ^ ^ ^ ^ ^ ).} ",
|
||||
" d.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ).} e.",
|
||||
" ).^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 a f.g.^ ^ ).} h.",
|
||||
" i.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ j.B k.l.m.n.o.).} !.",
|
||||
" p.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ q.r.s.t.^ u.v.w.x.} ",
|
||||
" y.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ z.m.A.}.B.C.D.E.B F.G. ",
|
||||
" H.I.J././././.K.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ L.M.^ }.N.N.O.P.Q. ",
|
||||
" $ $ $ $ $ $ $ $ $ $ $ $ $ - R.S.T.U.V.^ }.N.N.W.X.Y. ",
|
||||
" T.$ $ $ $ $ $ Z.* & `. +}..+++@+^ #+ ",
|
||||
" $+%+ &+*+=+-+^ ^ ;+>+ ",
|
||||
" ,+'+)+!+D ~+ ",
|
||||
" {+]+ ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 759 B |
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
@@ -1,556 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="512"
|
||||
height="512"
|
||||
id="svg2985"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.2 r9819"
|
||||
sodipodi:docname="icon-mplayer3.svg"
|
||||
inkscape:export-filename="/Users/pigoz/Documents/mplayer-icons/compiled/icon-mplayer2.png"
|
||||
inkscape:export-xdpi="85.699997"
|
||||
inkscape:export-ydpi="85.699997"
|
||||
enable-background="new">
|
||||
<defs
|
||||
id="defs2987">
|
||||
<linearGradient
|
||||
id="linearGradient5632">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5634" />
|
||||
<stop
|
||||
style="stop-color:#646464;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5636" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3979">
|
||||
<stop
|
||||
style="stop-color:#d2d2d2;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3981" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3983" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3877">
|
||||
<stop
|
||||
style="stop-color:#3cc8ff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3879" />
|
||||
<stop
|
||||
id="stop3885"
|
||||
offset="1"
|
||||
style="stop-color:#14b4ff;stop-opacity:0;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3857"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#03062a;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3859" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3943">
|
||||
<stop
|
||||
id="stop3772"
|
||||
offset="0"
|
||||
style="stop-color:#44c8fd;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#284aef;stop-opacity:1;"
|
||||
offset="0.46829268"
|
||||
id="stop3788" />
|
||||
<stop
|
||||
style="stop-color:#06082a;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3947" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3877"
|
||||
id="radialGradient3929"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="256.71875"
|
||||
cy="256.15625"
|
||||
fx="256.71875"
|
||||
fy="256.15625"
|
||||
r="235"
|
||||
gradientTransform="translate(6.6751888,0)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3877"
|
||||
id="radialGradient3932"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(6.6751888,0)"
|
||||
cx="256.71875"
|
||||
cy="256.15625"
|
||||
fx="256.71875"
|
||||
fy="256.15625"
|
||||
r="235" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3979"
|
||||
id="linearGradient3924"
|
||||
x1="256.12192"
|
||||
y1="491.25339"
|
||||
x2="256.12192"
|
||||
y2="11.186499"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3943"
|
||||
id="radialGradient3943"
|
||||
cx="227.08333"
|
||||
cy="218.25"
|
||||
fx="227.08333"
|
||||
fy="218.25"
|
||||
r="197.08333"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3877"
|
||||
id="radialGradient3964"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="258.69565"
|
||||
cy="381.56522"
|
||||
fx="258.69565"
|
||||
fy="381.56522"
|
||||
r="169.56522" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3979-0"
|
||||
id="linearGradient3985"
|
||||
x1="259.45453"
|
||||
y1="256.90909"
|
||||
x2="259.45453"
|
||||
y2="38.000004"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,2)" />
|
||||
<linearGradient
|
||||
id="linearGradient3979-0">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.01960784;"
|
||||
offset="0"
|
||||
id="stop3981-1" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.86274511;"
|
||||
offset="1"
|
||||
id="stop3983-0" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="38.000004"
|
||||
x2="259.45453"
|
||||
y1="256.90909"
|
||||
x1="259.45453"
|
||||
gradientTransform="translate(0,2)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient4907"
|
||||
xlink:href="#linearGradient3979-0"
|
||||
inkscape:collect="always" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter5485">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="6.7826086"
|
||||
id="feGaussianBlur5487" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter5501">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="3.3913043"
|
||||
id="feGaussianBlur5503" />
|
||||
</filter>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3943-7"
|
||||
id="radialGradient3943-9"
|
||||
cx="227.08333"
|
||||
cy="218.25"
|
||||
fx="227.08333"
|
||||
fy="218.25"
|
||||
r="197.08333"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3943-7">
|
||||
<stop
|
||||
id="stop3772-1"
|
||||
offset="0"
|
||||
style="stop-color:#44c8fd;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#284aef;stop-opacity:1;"
|
||||
offset="0.46829268"
|
||||
id="stop3788-5" />
|
||||
<stop
|
||||
style="stop-color:#06082a;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3947-6" />
|
||||
</linearGradient>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath5607">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:#000000;fill-opacity:0.74509804;stroke:none"
|
||||
id="path5609"
|
||||
sodipodi:cx="227.08333"
|
||||
sodipodi:cy="218.25"
|
||||
sodipodi:rx="197.08333"
|
||||
sodipodi:ry="197.08333"
|
||||
d="M 424.16666,218.25 A 197.08333,197.08333 0 1 1 30,218.25 a 197.08333,197.08333 0 1 1 394.16666,0 z"
|
||||
transform="matrix(1.2962957,0,0,1.2962957,-37.866811,203.33677)"
|
||||
mask="none" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath5611">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:#000000;fill-opacity:0.74509804;stroke:none"
|
||||
id="path5613"
|
||||
sodipodi:cx="227.08333"
|
||||
sodipodi:cy="218.25"
|
||||
sodipodi:rx="197.08333"
|
||||
sodipodi:ry="197.08333"
|
||||
d="M 424.16666,218.25 A 197.08333,197.08333 0 1 1 30,218.25 a 197.08333,197.08333 0 1 1 394.16666,0 z"
|
||||
transform="matrix(0.91114848,0,0,0.91114848,50.372646,143.15146)"
|
||||
mask="none" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5632"
|
||||
id="linearGradient5657"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="280.81955"
|
||||
y1="224.967"
|
||||
x2="280.81955"
|
||||
y2="438.65695"
|
||||
gradientTransform="translate(0,2)" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter5667">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="0.32939063"
|
||||
id="feGaussianBlur5669" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5632-0"
|
||||
id="linearGradient5657-3"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="280.81955"
|
||||
y1="224.967"
|
||||
x2="280.81955"
|
||||
y2="438.65695"
|
||||
gradientTransform="translate(0,2)" />
|
||||
<linearGradient
|
||||
id="linearGradient5632-0">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5634-4" />
|
||||
<stop
|
||||
style="stop-color:#646464;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5636-0" />
|
||||
</linearGradient>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter5717">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="4.2775091"
|
||||
id="feGaussianBlur5719" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter5729">
|
||||
<feBlend
|
||||
inkscape:collect="always"
|
||||
mode="darken"
|
||||
in2="BackgroundImage"
|
||||
id="feBlend5731" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter5737">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="2.9374501"
|
||||
id="feGaussianBlur5739" />
|
||||
</filter>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3877"
|
||||
id="radialGradient5741"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="258.69565"
|
||||
cy="381.56522"
|
||||
fx="258.69565"
|
||||
fy="381.56522"
|
||||
r="169.56522" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter5784">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="10.173913"
|
||||
id="feGaussianBlur5786" />
|
||||
</filter>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter5792">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="8.4782608"
|
||||
id="feGaussianBlur5794" />
|
||||
</filter>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3877"
|
||||
id="radialGradient5796"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="258.69565"
|
||||
cy="381.56522"
|
||||
fx="258.69565"
|
||||
fy="381.56522"
|
||||
r="169.56522" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter5845"
|
||||
x="-0.16900845"
|
||||
width="1.3380169"
|
||||
y="-0.20256461"
|
||||
height="1.4051292">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="21.923266"
|
||||
id="feGaussianBlur5847" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.59"
|
||||
inkscape:cx="247.81648"
|
||||
inkscape:cy="251.19615"
|
||||
inkscape:current-layer="layer9"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1629"
|
||||
inkscape:window-height="1006"
|
||||
inkscape:window-x="47"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata2990">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="shadow"
|
||||
id="g4931"
|
||||
inkscape:groupmode="layer"
|
||||
style="filter:url(#filter5729)"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
transform="matrix(1.0008681,0,0,1.0008681,-0.32354214,1.8790597)"
|
||||
d="m 500.88873,255.89879 a 244.78751,244.78751 0 1 1 -489.575009,0 244.78751,244.78751 0 1 1 489.575009,0 z"
|
||||
sodipodi:ry="244.78751"
|
||||
sodipodi:rx="244.78751"
|
||||
sodipodi:cy="255.89879"
|
||||
sodipodi:cx="256.10123"
|
||||
id="path4933"
|
||||
style="fill:#000000;fill-opacity:0.74509804;stroke:none;filter:url(#filter5737)"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="chrome"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:url(#linearGradient3924);fill-opacity:1;stroke:none"
|
||||
id="path3148"
|
||||
sodipodi:cx="256.10123"
|
||||
sodipodi:cy="255.89879"
|
||||
sodipodi:rx="244.78751"
|
||||
sodipodi:ry="244.78751"
|
||||
d="m 500.88873,255.89879 a 244.78751,244.78751 0 1 1 -489.575009,0 244.78751,244.78751 0 1 1 489.575009,0 z"
|
||||
transform="matrix(1.0008681,0,0,1.0008681,-0.32354214,-0.12094033)" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="base-glass"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:url(#radialGradient3943);fill-opacity:1;stroke:none"
|
||||
id="path3927"
|
||||
sodipodi:cx="227.08333"
|
||||
sodipodi:cy="218.25"
|
||||
sodipodi:rx="197.08333"
|
||||
sodipodi:ry="197.08333"
|
||||
d="M 424.16666,218.25 A 197.08333,197.08333 0 1 1 30,218.25 a 197.08333,197.08333 0 1 1 394.16666,0 z"
|
||||
transform="matrix(1.1467231,0,0,1.1467231,-4.401693,5.727699)"
|
||||
mask="none" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer4"
|
||||
inkscape:label="glows"
|
||||
sodipodi:insensitive="true"
|
||||
style="display:inline">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:url(#radialGradient5741);fill-opacity:1;stroke:none;filter:url(#filter5501)"
|
||||
id="path3946"
|
||||
sodipodi:cx="258.69565"
|
||||
sodipodi:cy="381.56522"
|
||||
sodipodi:rx="169.56522"
|
||||
sodipodi:ry="169.56522"
|
||||
d="m 428.26086,381.56522 a 169.56522,169.56522 0 1 1 -339.130428,0 169.56522,169.56522 0 1 1 339.130428,0 z"
|
||||
transform="matrix(1.2585469,0,0,1.2585469,-67.79803,-174.43515)"
|
||||
clip-path="url(#clipPath5611)" />
|
||||
<path
|
||||
transform="matrix(0.88461539,0,0,0.88461539,29.095871,-174.14716)"
|
||||
d="m 428.26086,381.56522 a 169.56522,169.56522 0 1 1 -339.130428,0 169.56522,169.56522 0 1 1 339.130428,0 z"
|
||||
sodipodi:ry="169.56522"
|
||||
sodipodi:rx="169.56522"
|
||||
sodipodi:cy="381.56522"
|
||||
sodipodi:cx="258.69565"
|
||||
id="path3962"
|
||||
style="fill:url(#radialGradient3964);fill-opacity:1;stroke:none;filter:url(#filter5485)"
|
||||
sodipodi:type="arc"
|
||||
clip-path="url(#clipPath5607)" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="glows2"
|
||||
id="g5762"
|
||||
inkscape:groupmode="layer"
|
||||
style="opacity:0.73999999;display:inline"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
clip-path="url(#clipPath5611)"
|
||||
transform="matrix(1.2585469,0,0,1.2585469,-67.79803,-174.43515)"
|
||||
d="m 428.26086,381.56522 a 169.56522,169.56522 0 1 1 -339.130428,0 169.56522,169.56522 0 1 1 339.130428,0 z"
|
||||
sodipodi:ry="169.56522"
|
||||
sodipodi:rx="169.56522"
|
||||
sodipodi:cy="381.56522"
|
||||
sodipodi:cx="258.69565"
|
||||
id="path5764"
|
||||
style="fill:url(#radialGradient5796);fill-opacity:1;stroke:none;filter:url(#filter5792)"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
clip-path="url(#clipPath5607)"
|
||||
sodipodi:type="arc"
|
||||
style="fill:url(#radialGradient3964);fill-opacity:1;stroke:none;filter:url(#filter5784)"
|
||||
id="path5766"
|
||||
sodipodi:cx="258.69565"
|
||||
sodipodi:cy="381.56522"
|
||||
sodipodi:rx="169.56522"
|
||||
sodipodi:ry="169.56522"
|
||||
d="m 428.26086,381.56522 a 169.56522,169.56522 0 1 1 -339.130428,0 169.56522,169.56522 0 1 1 339.130428,0 z"
|
||||
transform="matrix(0.88461539,0,0,0.88461539,29.095871,-174.14716)" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer9"
|
||||
inkscape:label="glow3"
|
||||
style="opacity:0.7">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:#23c8ff;fill-opacity:1;stroke:none;filter:url(#filter5845)"
|
||||
id="path5799"
|
||||
sodipodi:cx="260.0629"
|
||||
sodipodi:cy="345.01886"
|
||||
sodipodi:rx="155.66037"
|
||||
sodipodi:ry="129.87421"
|
||||
d="m 415.72327,345.01886 a 155.66037,129.87421 0 1 1 -311.32074,0 155.66037,129.87421 0 1 1 311.32074,0 z"
|
||||
transform="matrix(0.92027607,0,0,0.82232826,17.588582,32.614052)"
|
||||
inkscape:export-filename="/Users/pigoz/Documents/mplayer-icons/compiled/path5799.png"
|
||||
inkscape:export-xdpi="85.699997"
|
||||
inkscape:export-ydpi="85.699997" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer8"
|
||||
inkscape:label="gloss-clipping"
|
||||
sodipodi:insensitive="true" />
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer6"
|
||||
inkscape:label="play"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter5717)"
|
||||
inkscape:transform-center-x="-31.26597"
|
||||
inkscape:transform-center-y="-0.032805761"
|
||||
d="m 190.37028,382.72523 0,-120.00058 0,-120.0006 93.87484,60.04949 93.87489,60.04951 -93.87489,59.95109 z"
|
||||
id="path3999-1"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
inkscape:export-filename="/Users/pigoz/Documents/icon-mplayer.png"
|
||||
inkscape:export-xdpi="85.699997"
|
||||
inkscape:export-ydpi="85.699997" />
|
||||
<path
|
||||
style="fill:url(#linearGradient5657);fill-opacity:1;stroke:#000000;stroke-width:6;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
inkscape:transform-center-x="-29.755544"
|
||||
inkscape:transform-center-y="-0.03121957"
|
||||
d="m 194.68911,375.82668 0,-114.20348 0,-114.2035 89.33985,57.14856 89.33989,57.14858 -89.33989,57.05492 z"
|
||||
id="path3999"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
inkscape:export-filename="/Users/pigoz/Documents/icon-mplayer.png"
|
||||
inkscape:export-xdpi="85.699997"
|
||||
inkscape:export-ydpi="85.699997" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer5"
|
||||
inkscape:label="white-gloss"
|
||||
style="opacity:0.9137931;display:inline"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
style="fill:url(#linearGradient4907);fill-opacity:1;stroke:none;display:inline;filter:url(#filter5667)"
|
||||
d="M 256,42.90625 C 142.67988,42.90625 49.723058,129.38336 40.3125,239.5 98.19077,257.96934 164.46733,270.1875 258,270.1875 c 96.86848,0 137.8965,-5.8873 213.8125,-29.4375 C 463.00354,130.03648 369.74992,42.90625 256,42.90625 z"
|
||||
id="path3950"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="scscs"
|
||||
inkscape:export-filename="/Users/pigoz/Documents/icon-mplayer.png"
|
||||
inkscape:export-xdpi="85.699997"
|
||||
inkscape:export-ydpi="85.699997"
|
||||
transform="matrix(0.99524152,0,0,0.99524152,0.95307007,-2.3236889)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 18 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 264 KiB |
@@ -0,0 +1,23 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=mpv Media Player
|
||||
Name[ca]=Reproductor multimèdia mpv
|
||||
Name[pl]=mpv odtwarzacz multimedialny
|
||||
Name[ru]=Проигрыватель mpv
|
||||
GenericName=Multimedia player
|
||||
Comment=Play movies and songs
|
||||
Comment[ca]=Reproduïu vídeos i cançons
|
||||
Comment[de]=Filme und Musik abspielen
|
||||
Comment[es]=Reproduzca vídeos y canciones
|
||||
Comment[fr]=Lecteur multimédia
|
||||
Comment[it]=Lettore multimediale
|
||||
Comment[pl]=Odtwarzaj filmy i muzykę
|
||||
Comment[ru]=Воспроизвести фильмы и музыку
|
||||
Comment[zh]=多媒体播放器
|
||||
Icon=mpv
|
||||
TryExec=mpv
|
||||
Exec=mpv --really-quiet --force-window -- %F
|
||||
Terminal=false
|
||||
NoDisplay=true
|
||||
Categories=AudioVideo;Audio;Video;Player;TV;
|
||||
MimeType=application/ogg;application/x-ogg;application/sdp;application/smil;application/x-smil;application/streamingmedia;application/x-streamingmedia;application/vnd.rn-realmedia;application/vnd.rn-realmedia-vbr;audio/aac;audio/x-aac;audio/m4a;audio/x-m4a;audio/mp1;audio/x-mp1;audio/mp2;audio/x-mp2;audio/mp3;audio/x-mp3;audio/mpeg;audio/x-mpeg;audio/mpegurl;audio/x-mpegurl;audio/mpg;audio/x-mpg;audio/rn-mpeg;audio/scpls;audio/x-scpls;audio/vnd.rn-realaudio;audio/wav;audio/x-pn-windows-pcm;audio/x-realaudio;audio/x-pn-realaudio;audio/x-ms-wma;audio/x-pls;audio/x-wav;video/mpeg;video/x-mpeg;video/x-mpeg2;video/mp4;video/msvideo;video/x-msvideo;video/quicktime;video/vnd.rn-realvideo;video/x-ms-afs;video/x-ms-asf;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvxvideo;video/x-avi;video/x-fli;video/x-flv;video/x-theora;video/x-matroska;video/webm;audio/x-flac;
|
||||
+2
-11
@@ -449,7 +449,6 @@ asx_parse_ref(ASX_Parser_t* parser, char** attribs) {
|
||||
|
||||
static void asx_parse_entryref(ASX_Parser_t* parser,char* buffer,char** _attribs) {
|
||||
char *href;
|
||||
stream_t* stream;
|
||||
|
||||
if(parser->deep > 0)
|
||||
return;
|
||||
@@ -459,16 +458,8 @@ static void asx_parse_entryref(ASX_Parser_t* parser,char* buffer,char** _attribs
|
||||
asx_warning_attrib_required(parser,"ENTRYREF" ,"HREF" );
|
||||
return;
|
||||
}
|
||||
stream=stream_open(href, NULL);
|
||||
if(!stream) {
|
||||
mp_msg(MSGT_PLAYTREE,MSGL_WARN,"Can't open playlist %s\n",href);
|
||||
free(href);
|
||||
return;
|
||||
}
|
||||
|
||||
mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Not recursively loading playlist %s\n",href);
|
||||
|
||||
free_stream(stream);
|
||||
mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Recursive playlist %s\n", href);
|
||||
playlist_add_file(parser->pl, href);
|
||||
free(href);
|
||||
//mp_msg(MSGT_PLAYTREE,MSGL_INFO,"Need to implement entryref\n");
|
||||
}
|
||||
|
||||
+29
-14
@@ -41,6 +41,13 @@
|
||||
#include <libavfilter/avfilter.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LIBAVRESAMPLE
|
||||
#include <libavresample/avresample.h>
|
||||
#endif
|
||||
#ifdef CONFIG_LIBSWRESAMPLE
|
||||
#include <libswresample/swresample.h>
|
||||
#endif
|
||||
|
||||
static int av_log_level_to_mp_level(int av_level)
|
||||
{
|
||||
if (av_level > AV_LOG_VERBOSE)
|
||||
@@ -48,7 +55,7 @@ static int av_log_level_to_mp_level(int av_level)
|
||||
if (av_level > AV_LOG_INFO)
|
||||
return MSGL_V;
|
||||
if (av_level > AV_LOG_WARNING)
|
||||
return MSGL_INFO;
|
||||
return MSGL_V;
|
||||
if (av_level > AV_LOG_ERROR)
|
||||
return MSGL_WARN;
|
||||
if (av_level > AV_LOG_FATAL)
|
||||
@@ -140,22 +147,30 @@ void init_libav(void)
|
||||
}
|
||||
|
||||
#define V(x) (x)>>16, (x)>>8 & 255, (x) & 255
|
||||
static void print_version(char *name, unsigned buildv, unsigned runv)
|
||||
static void print_version(int v, char *name, unsigned buildv, unsigned runv)
|
||||
{
|
||||
|
||||
if (buildv == runv)
|
||||
mp_msg(MSGT_CPLAYER, MSGL_V, "Compiled against %s version %d.%d.%d\n",
|
||||
name, V(buildv));
|
||||
else
|
||||
mp_msg(MSGT_CPLAYER, MSGL_V, "Compiled against %s version %d.%d.%d "
|
||||
"(runtime %d.%d.%d)\n", name, V(buildv), V(runv));
|
||||
mp_msg(MSGT_CPLAYER, v, " %-15s %d.%d.%d", name, V(buildv));
|
||||
if (buildv != runv)
|
||||
mp_msg(MSGT_CPLAYER, v, " (runtime %d.%d.%d)", V(runv));
|
||||
mp_msg(MSGT_CPLAYER, v, "\n");
|
||||
}
|
||||
#undef V
|
||||
|
||||
void print_libav_versions(void)
|
||||
void print_libav_versions(int v)
|
||||
{
|
||||
print_version("libavutil", LIBAVUTIL_VERSION_INT, avutil_version());
|
||||
print_version("libavcodec", LIBAVCODEC_VERSION_INT, avcodec_version());
|
||||
print_version("libavformat", LIBAVFORMAT_VERSION_INT, avformat_version());
|
||||
print_version("libswscale", LIBSWSCALE_VERSION_INT, swscale_version());
|
||||
mp_msg(MSGT_CPLAYER, v, "%s library versions:\n", LIB_PREFIX);
|
||||
|
||||
print_version(v, "libavutil", LIBAVUTIL_VERSION_INT, avutil_version());
|
||||
print_version(v, "libavcodec", LIBAVCODEC_VERSION_INT, avcodec_version());
|
||||
print_version(v, "libavformat", LIBAVFORMAT_VERSION_INT, avformat_version());
|
||||
print_version(v, "libswscale", LIBSWSCALE_VERSION_INT, swscale_version());
|
||||
#ifdef CONFIG_LIBAVFILTER
|
||||
print_version(v, "libavfilter", LIBAVFILTER_VERSION_INT, avfilter_version());
|
||||
#endif
|
||||
#ifdef CONFIG_LIBAVRESAMPLE
|
||||
print_version(v, "libavresample", LIBAVRESAMPLE_VERSION_INT, avresample_version());
|
||||
#endif
|
||||
#ifdef CONFIG_LIBSWRESAMPLE
|
||||
print_version(v, "libswresample", LIBSWRESAMPLE_VERSION_INT, swresample_version());
|
||||
#endif
|
||||
}
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
void init_libav(void);
|
||||
void print_libav_versions(void);
|
||||
void print_libav_versions(int v);
|
||||
+72
-1
@@ -273,18 +273,89 @@ int bstr_decode_utf8(struct bstr s, struct bstr *out_next)
|
||||
return -1;
|
||||
codepoint &= 127 >> bytes;
|
||||
for (int n = 1; n < bytes; n++) {
|
||||
int tmp = s.start[0];
|
||||
int tmp = (unsigned char)s.start[0];
|
||||
if ((tmp & 0xC0) != 0x80)
|
||||
return -1;
|
||||
codepoint = (codepoint << 6) | (tmp & ~0xC0);
|
||||
s.start++; s.len--;
|
||||
}
|
||||
if (codepoint > 0x10FFFF || (codepoint >= 0xD800 && codepoint <= 0xDFFF))
|
||||
return -1;
|
||||
// Overlong sequences - check taken from libavcodec.
|
||||
// (The only reason we even bother with this is to make libavcodec's
|
||||
// retarded subtitle utf-8 check happy.)
|
||||
unsigned int min = bytes == 2 ? 0x80 : 1 << (5 * bytes - 4);
|
||||
if (codepoint < min)
|
||||
return -1;
|
||||
}
|
||||
if (out_next)
|
||||
*out_next = s;
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
int bstr_validate_utf8(struct bstr s)
|
||||
{
|
||||
while (s.len) {
|
||||
if (bstr_decode_utf8(s, &s) < 0) {
|
||||
// Try to guess whether the sequence was just cut-off.
|
||||
unsigned int codepoint = (unsigned char)s.start[0];
|
||||
int bytes = bstr_parse_utf8_code_length(codepoint);
|
||||
if (bytes > 1 && s.len < 6) {
|
||||
// Manually check validity of left bytes
|
||||
for (int n = 1; n < bytes; n++) {
|
||||
if (n >= s.len) {
|
||||
// Everything valid until now - just cut off.
|
||||
return -(bytes - s.len);
|
||||
}
|
||||
int tmp = (unsigned char)s.start[n];
|
||||
if ((tmp & 0xC0) != 0x80)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -8;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void append_bstr(bstr *buf, bstr s)
|
||||
{
|
||||
buf->start = talloc_realloc(NULL, buf->start, unsigned char, buf->len + s.len);
|
||||
memcpy(buf->start + buf->len, s.start, s.len);
|
||||
buf->len += s.len;
|
||||
}
|
||||
|
||||
struct bstr bstr_sanitize_utf8_latin1(void *talloc_ctx, struct bstr s)
|
||||
{
|
||||
bstr new = {0};
|
||||
bstr left = s;
|
||||
unsigned char *first_ok = s.start;
|
||||
while (left.len) {
|
||||
int r = bstr_decode_utf8(left, &left);
|
||||
if (r < 0) {
|
||||
append_bstr(&new, (bstr){first_ok, left.start - first_ok});
|
||||
uint32_t codepoint = (unsigned char)left.start[0];
|
||||
char data[8];
|
||||
uint8_t tmp;
|
||||
char *output = data;
|
||||
PUT_UTF8(codepoint, tmp, *output++ = tmp;);
|
||||
append_bstr(&new, (bstr){data, output - data});
|
||||
left.start += 1;
|
||||
left.len -= 1;
|
||||
first_ok = left.start;
|
||||
}
|
||||
}
|
||||
if (!new.start)
|
||||
return s;
|
||||
if (first_ok != left.start)
|
||||
append_bstr(&new, (bstr){first_ok, left.start - first_ok});
|
||||
// For convenience
|
||||
append_bstr(&new, (bstr){"\0", 1});
|
||||
new.len -= 1;
|
||||
talloc_steal(talloc_ctx, new.start);
|
||||
return new;
|
||||
}
|
||||
|
||||
bool bstr_case_startswith(struct bstr s, struct bstr prefix)
|
||||
{
|
||||
struct bstr start = bstr_splice(s, 0, prefix.len);
|
||||
|
||||
@@ -92,6 +92,23 @@ int bstr_decode_utf8(struct bstr str, struct bstr *out_next);
|
||||
// On error, -1 is returned. On success, it returns a value in the range [1, 4].
|
||||
int bstr_parse_utf8_code_length(unsigned char b);
|
||||
|
||||
// Return >= 0 if the string is valid UTF-8, otherwise negative error code.
|
||||
// Embedded \0 bytes are considered valid.
|
||||
// This returns -N if the UTF-8 string was likely just cut-off in the middle of
|
||||
// an UTF-8 sequence: -1 means 1 byte was missing, -5 5 bytes missing.
|
||||
// If the string was likely not cut off, -8 is returned.
|
||||
// Use (return_value > -8) to check whether the string is valid UTF-8 or valid
|
||||
// but cut-off UTF-8.
|
||||
int bstr_validate_utf8(struct bstr s);
|
||||
|
||||
// Force the input string to valid UTF-8. If invalid UTF-8 encoding is
|
||||
// encountered, the invalid bytes are interpreted as Latin-1.
|
||||
// Embedded \0 bytes are considered valid.
|
||||
// If replacement happens, a newly allocated string is returned (with a \0
|
||||
// byte added past its end for convenience). The string is allocated via
|
||||
// talloc, with talloc_ctx as parent.
|
||||
struct bstr bstr_sanitize_utf8_latin1(void *talloc_ctx, struct bstr s);
|
||||
|
||||
// Return the text before the next line break, and return it. Change *rest to
|
||||
// point to the text following this line break. (rest can be NULL.)
|
||||
// Line break characters are not stripped.
|
||||
|
||||
+33
-12
@@ -41,6 +41,12 @@
|
||||
|
||||
#include "charset_conv.h"
|
||||
|
||||
bool mp_charset_is_utf8(const char *user_cp)
|
||||
{
|
||||
return user_cp && (strcasecmp(user_cp, "utf8") == 0 ||
|
||||
strcasecmp(user_cp, "utf-8") == 0);
|
||||
}
|
||||
|
||||
// Split the string on ':' into components.
|
||||
// out_arr is at least max entries long.
|
||||
// Return number of out_arr entries filled.
|
||||
@@ -70,9 +76,13 @@ static int split_colon(const char *user_cp, int max, bstr *out_arr)
|
||||
bool mp_charset_requires_guess(const char *user_cp)
|
||||
{
|
||||
bstr res[2] = {{0}};
|
||||
split_colon(user_cp, 2, res);
|
||||
int r = split_colon(user_cp, 2, res);
|
||||
// Note that "utf8" is the UTF-8 codepage, while "utf8:..." specifies UTF-8
|
||||
// by default, plus a codepage that is used if the input is not UTF-8.
|
||||
return bstrcasecmp0(res[0], "enca") == 0 ||
|
||||
bstrcasecmp0(res[0], "guess") == 0;
|
||||
bstrcasecmp0(res[0], "guess") == 0 ||
|
||||
(r > 1 && bstrcasecmp0(res[0], "utf-8") == 0) ||
|
||||
(r > 1 && bstrcasecmp0(res[0], "utf8") == 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ENCA
|
||||
@@ -110,9 +120,6 @@ static const char *enca_guess(bstr buf, const char *language)
|
||||
#ifdef CONFIG_LIBGUESS
|
||||
static const char *libguess_guess(bstr buf, const char *language)
|
||||
{
|
||||
if (libguess_validate_utf8(buf.start, buf.len))
|
||||
return "UTF-8";
|
||||
|
||||
if (!language || !language[0] || strcmp(language, "help") == 0) {
|
||||
mp_msg(MSGT_SUBREADER, MSGL_ERR, "libguess needs a language: "
|
||||
"japanese taiwanese chinese korean russian arabic turkish "
|
||||
@@ -129,11 +136,17 @@ static const char *libguess_guess(bstr buf, const char *language)
|
||||
// If user_cp doesn't refer to any known auto-detection (for example because
|
||||
// it's a real iconv codepage), user_cp is returned without even looking at
|
||||
// the buf data.
|
||||
const char *mp_charset_guess(bstr buf, const char *user_cp)
|
||||
const char *mp_charset_guess(bstr buf, const char *user_cp, int flags)
|
||||
{
|
||||
if (!mp_charset_requires_guess(user_cp))
|
||||
return user_cp;
|
||||
|
||||
// Do our own UTF-8 detection, because at least ENCA seems to get it
|
||||
// wrong sometimes (suggested by divVerent).
|
||||
int r = bstr_validate_utf8(buf);
|
||||
if (r >= 0 || (r > -8 && (flags & MP_ICONV_ALLOW_CUTOFF)))
|
||||
return "UTF-8";
|
||||
|
||||
bstr params[3] = {{0}};
|
||||
split_colon(user_cp, 3, params);
|
||||
|
||||
@@ -152,6 +165,10 @@ const char *mp_charset_guess(bstr buf, const char *user_cp)
|
||||
if (bstrcasecmp0(type, "guess") == 0)
|
||||
res = libguess_guess(buf, lang);
|
||||
#endif
|
||||
if (bstrcasecmp0(type, "utf8") == 0 || bstrcasecmp0(type, "utf-8") == 0) {
|
||||
if (!fallback)
|
||||
fallback = params[1].start; // must be already 0-terminated
|
||||
}
|
||||
|
||||
if (res) {
|
||||
mp_msg(MSGT_SUBREADER, MSGL_DBG2, "%.*s detected charset: '%s'\n",
|
||||
@@ -160,9 +177,12 @@ const char *mp_charset_guess(bstr buf, const char *user_cp)
|
||||
res = fallback;
|
||||
mp_msg(MSGT_SUBREADER, MSGL_DBG2,
|
||||
"Detection with %.*s failed: fallback to %s\n",
|
||||
BSTR_P(type), res && res[0] ? res : "no conversion");
|
||||
BSTR_P(type), res && res[0] ? res : "broken UTF-8/Latin1");
|
||||
}
|
||||
|
||||
if (!res && !(flags & MP_STRICT_UTF8))
|
||||
res = "UTF-8-BROKEN";
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -176,7 +196,7 @@ const char *mp_charset_guess(bstr buf, const char *user_cp)
|
||||
// returns: same as mp_iconv_to_utf8()
|
||||
bstr mp_charset_guess_and_conv_to_utf8(bstr buf, const char *user_cp, int flags)
|
||||
{
|
||||
return mp_iconv_to_utf8(buf, mp_charset_guess(buf, user_cp), flags);
|
||||
return mp_iconv_to_utf8(buf, mp_charset_guess(buf, user_cp, flags), flags);
|
||||
}
|
||||
|
||||
// Use iconv to convert buf to UTF-8.
|
||||
@@ -193,16 +213,17 @@ bstr mp_charset_guess_and_conv_to_utf8(bstr buf, const char *user_cp, int flags)
|
||||
bstr mp_iconv_to_utf8(bstr buf, const char *cp, int flags)
|
||||
{
|
||||
#ifdef CONFIG_ICONV
|
||||
const char *tocp = "UTF-8";
|
||||
|
||||
if (!cp || !cp[0] || strcasecmp(cp, tocp) == 0)
|
||||
if (!cp || !cp[0] || mp_charset_is_utf8(cp))
|
||||
return buf;
|
||||
|
||||
if (strcasecmp(cp, "ASCII") == 0)
|
||||
return buf;
|
||||
|
||||
if (strcasecmp(cp, "UTF-8-BROKEN") == 0)
|
||||
return bstr_sanitize_utf8_latin1(NULL, buf);
|
||||
|
||||
iconv_t icdsc;
|
||||
if ((icdsc = iconv_open(tocp, cp)) == (iconv_t) (-1)) {
|
||||
if ((icdsc = iconv_open("UTF-8", cp)) == (iconv_t) (-1)) {
|
||||
if (flags & MP_ICONV_VERBOSE)
|
||||
mp_msg(MSGT_SUBREADER, MSGL_ERR,
|
||||
"Error opening iconv with codepage '%s'\n", cp);
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
enum {
|
||||
MP_ICONV_VERBOSE = 1, // print errors instead of failing silently
|
||||
MP_ICONV_ALLOW_CUTOFF = 2, // allow partial input data
|
||||
MP_STRICT_UTF8 = 4, // don't fall back to UTF-8-BROKEN when guessing
|
||||
};
|
||||
|
||||
bool mp_charset_is_utf8(const char *user_cp);
|
||||
bool mp_charset_requires_guess(const char *user_cp);
|
||||
const char *mp_charset_guess(bstr buf, const char *user_cp);
|
||||
const char *mp_charset_guess(bstr buf, const char *user_cp, int flags);
|
||||
bstr mp_charset_guess_and_conv_to_utf8(bstr buf, const char *user_cp, int flags);
|
||||
bstr mp_iconv_to_utf8(bstr buf, const char *cp, int flags);
|
||||
|
||||
|
||||
+535
-205
File diff suppressed because it is too large.
Load diff
+19
-2
@@ -22,12 +22,29 @@
|
||||
struct MPContext;
|
||||
struct mp_cmd;
|
||||
|
||||
void mp_get_osd_mouse_pos(struct MPContext *mpctx, float *x, float *y);
|
||||
void command_init(struct MPContext *mpctx);
|
||||
void command_uninit(struct MPContext *mpctx);
|
||||
|
||||
void run_command(struct MPContext *mpctx, struct mp_cmd *cmd);
|
||||
char *mp_property_expand_string(struct MPContext *mpctx, char *str);
|
||||
char *mp_property_expand_string(struct MPContext *mpctx, const char *str);
|
||||
void property_print_help(void);
|
||||
int mp_property_do(const char* name, int action, void* val,
|
||||
struct MPContext *mpctx);
|
||||
|
||||
const struct m_option *mp_get_property_list(void);
|
||||
|
||||
enum mp_event {
|
||||
MP_EVENT_NONE,
|
||||
MP_EVENT_TICK,
|
||||
MP_EVENT_PROPERTY, // char*, property that is changed
|
||||
MP_EVENT_TRACKS_CHANGED,
|
||||
MP_EVENT_START_FILE,
|
||||
MP_EVENT_END_FILE,
|
||||
};
|
||||
|
||||
void mp_notify(struct MPContext *mpctx, enum mp_event event, void *arg);
|
||||
void mp_notify_property(struct MPContext *mpctx, const char *property);
|
||||
|
||||
void mp_flush_events(struct MPContext *mpctx);
|
||||
|
||||
#endif /* MPLAYER_COMMAND_H */
|
||||
+460
-282
File diff suppressed because it is too large.
Load diff
+16
-4
@@ -43,6 +43,7 @@ enum mp_command_type {
|
||||
MP_CMD_PLAYLIST_REMOVE,
|
||||
MP_CMD_PLAYLIST_MOVE,
|
||||
MP_CMD_SUB_STEP,
|
||||
MP_CMD_SUB_SEEK,
|
||||
MP_CMD_TV_SET_CHANNEL,
|
||||
MP_CMD_TV_LAST_CHANNEL,
|
||||
MP_CMD_TV_SET_FREQ,
|
||||
@@ -74,7 +75,7 @@ enum mp_command_type {
|
||||
MP_CMD_DISABLE_INPUT_SECTION,
|
||||
|
||||
/// DVB commands
|
||||
MP_CMD_DVB_SET_CHANNEL = 5101,
|
||||
MP_CMD_DVB_SET_CHANNEL,
|
||||
|
||||
/// Audio Filter commands
|
||||
MP_CMD_AF,
|
||||
@@ -85,6 +86,12 @@ enum mp_command_type {
|
||||
/// Video output commands
|
||||
MP_CMD_VO_CMDLINE,
|
||||
|
||||
/// Internal for Lua scripts
|
||||
MP_CMD_SCRIPT_DISPATCH,
|
||||
|
||||
MP_CMD_OVERLAY_ADD,
|
||||
MP_CMD_OVERLAY_REMOVE,
|
||||
|
||||
// Internal
|
||||
MP_CMD_COMMAND_LIST, // list of sub-commands in args[0].v.p
|
||||
};
|
||||
@@ -116,6 +123,10 @@ enum mp_input_section_flags {
|
||||
// other sections for it (like the default section). Instead, an unbound
|
||||
// key warning will be printed.
|
||||
MP_INPUT_EXCLUSIVE = 1,
|
||||
// Let mp_input_test_dragging() return true, even if inside the mouse area.
|
||||
MP_INPUT_ALLOW_VO_DRAGGING = 2,
|
||||
// Don't force mouse pointer visible, even if inside the mouse area.
|
||||
MP_INPUT_ALLOW_HIDE_CURSOR = 4,
|
||||
};
|
||||
|
||||
struct input_ctx;
|
||||
@@ -209,7 +220,8 @@ struct mp_cmd *mp_input_get_cmd(struct input_ctx *ictx, int time,
|
||||
|
||||
// Parse text and return corresponding struct mp_cmd.
|
||||
// The location parameter is for error messages.
|
||||
struct mp_cmd *mp_input_parse_cmd(bstr str, const char *location);
|
||||
struct mp_cmd *mp_input_parse_cmd(struct input_ctx *ictx, bstr str,
|
||||
const char *location);
|
||||
|
||||
// After getting a command from mp_input_get_cmd you need to free it using this
|
||||
// function
|
||||
@@ -262,8 +274,8 @@ bool mp_input_test_mouse_active(struct input_ctx *ictx, int x, int y);
|
||||
bool mp_input_test_dragging(struct input_ctx *ictx, int x, int y);
|
||||
|
||||
// Initialize the input system
|
||||
struct MPOpts;
|
||||
struct input_ctx *mp_input_init(struct MPOpts *opts);
|
||||
struct mpv_global;
|
||||
struct input_ctx *mp_input_init(struct mpv_global *global);
|
||||
|
||||
void mp_input_uninit(struct input_ctx *ictx);
|
||||
|
||||
|
||||
+120
-120
@@ -27,90 +27,96 @@
|
||||
#define MP_KEY_TAB 9
|
||||
|
||||
/* Control keys */
|
||||
#define MP_KEY_BACKSPACE (MP_KEY_BASE+0)
|
||||
#define MP_KEY_DELETE (MP_KEY_BASE+1)
|
||||
#define MP_KEY_INSERT (MP_KEY_BASE+2)
|
||||
#define MP_KEY_HOME (MP_KEY_BASE+3)
|
||||
#define MP_KEY_END (MP_KEY_BASE+4)
|
||||
#define MP_KEY_PAGE_UP (MP_KEY_BASE+5)
|
||||
#define MP_KEY_PAGE_DOWN (MP_KEY_BASE+6)
|
||||
#define MP_KEY_ESC (MP_KEY_BASE+7)
|
||||
#define MP_KEY_PRINT (MP_KEY_BASE+8)
|
||||
#define MP_KEY_BACKSPACE (MP_KEY_BASE+0)
|
||||
#define MP_KEY_DELETE (MP_KEY_BASE+1)
|
||||
#define MP_KEY_INSERT (MP_KEY_BASE+2)
|
||||
#define MP_KEY_HOME (MP_KEY_BASE+3)
|
||||
#define MP_KEY_END (MP_KEY_BASE+4)
|
||||
#define MP_KEY_PAGE_UP (MP_KEY_BASE+5)
|
||||
#define MP_KEY_PAGE_DOWN (MP_KEY_BASE+6)
|
||||
#define MP_KEY_ESC (MP_KEY_BASE+7)
|
||||
#define MP_KEY_PRINT (MP_KEY_BASE+8)
|
||||
|
||||
/* Control keys short name */
|
||||
#define MP_KEY_BS MP_KEY_BACKSPACE
|
||||
#define MP_KEY_DEL MP_KEY_DELETE
|
||||
#define MP_KEY_INS MP_KEY_INSERT
|
||||
#define MP_KEY_PGUP MP_KEY_PAGE_UP
|
||||
#define MP_KEY_PGDOWN MP_KEY_PAGE_DOWN
|
||||
#define MP_KEY_PGDWN MP_KEY_PAGE_DOWN
|
||||
#define MP_KEY_BS MP_KEY_BACKSPACE
|
||||
#define MP_KEY_DEL MP_KEY_DELETE
|
||||
#define MP_KEY_INS MP_KEY_INSERT
|
||||
#define MP_KEY_PGUP MP_KEY_PAGE_UP
|
||||
#define MP_KEY_PGDOWN MP_KEY_PAGE_DOWN
|
||||
#define MP_KEY_PGDWN MP_KEY_PAGE_DOWN
|
||||
|
||||
/* Cursor movement */
|
||||
#define MP_KEY_CRSR (MP_KEY_BASE+0x10)
|
||||
#define MP_KEY_RIGHT (MP_KEY_CRSR+0)
|
||||
#define MP_KEY_LEFT (MP_KEY_CRSR+1)
|
||||
#define MP_KEY_DOWN (MP_KEY_CRSR+2)
|
||||
#define MP_KEY_UP (MP_KEY_CRSR+3)
|
||||
#define MP_KEY_CRSR (MP_KEY_BASE+0x10)
|
||||
#define MP_KEY_RIGHT (MP_KEY_CRSR+0)
|
||||
#define MP_KEY_LEFT (MP_KEY_CRSR+1)
|
||||
#define MP_KEY_DOWN (MP_KEY_CRSR+2)
|
||||
#define MP_KEY_UP (MP_KEY_CRSR+3)
|
||||
|
||||
/* Multimedia keyboard/remote keys */
|
||||
#define MP_KEY_MM_BASE (MP_KEY_BASE+0x20)
|
||||
#define MP_KEY_POWER (MP_KEY_MM_BASE+0)
|
||||
#define MP_KEY_MENU (MP_KEY_MM_BASE+1)
|
||||
#define MP_KEY_PLAY (MP_KEY_MM_BASE+2)
|
||||
#define MP_KEY_PAUSE (MP_KEY_MM_BASE+3)
|
||||
#define MP_KEY_PLAYPAUSE (MP_KEY_MM_BASE+4)
|
||||
#define MP_KEY_STOP (MP_KEY_MM_BASE+5)
|
||||
#define MP_KEY_FORWARD (MP_KEY_MM_BASE+6)
|
||||
#define MP_KEY_REWIND (MP_KEY_MM_BASE+7)
|
||||
#define MP_KEY_NEXT (MP_KEY_MM_BASE+8)
|
||||
#define MP_KEY_PREV (MP_KEY_MM_BASE+9)
|
||||
#define MP_KEY_VOLUME_UP (MP_KEY_MM_BASE+10)
|
||||
#define MP_KEY_VOLUME_DOWN (MP_KEY_MM_BASE+11)
|
||||
#define MP_KEY_MUTE (MP_KEY_MM_BASE+12)
|
||||
/* Multimedia/internet keyboard/remote keys */
|
||||
#define MP_KEY_MM_BASE (MP_KEY_BASE+0x20)
|
||||
#define MP_KEY_POWER (MP_KEY_MM_BASE+0)
|
||||
#define MP_KEY_MENU (MP_KEY_MM_BASE+1)
|
||||
#define MP_KEY_PLAY (MP_KEY_MM_BASE+2)
|
||||
#define MP_KEY_PAUSE (MP_KEY_MM_BASE+3)
|
||||
#define MP_KEY_PLAYPAUSE (MP_KEY_MM_BASE+4)
|
||||
#define MP_KEY_STOP (MP_KEY_MM_BASE+5)
|
||||
#define MP_KEY_FORWARD (MP_KEY_MM_BASE+6)
|
||||
#define MP_KEY_REWIND (MP_KEY_MM_BASE+7)
|
||||
#define MP_KEY_NEXT (MP_KEY_MM_BASE+8)
|
||||
#define MP_KEY_PREV (MP_KEY_MM_BASE+9)
|
||||
#define MP_KEY_VOLUME_UP (MP_KEY_MM_BASE+10)
|
||||
#define MP_KEY_VOLUME_DOWN (MP_KEY_MM_BASE+11)
|
||||
#define MP_KEY_MUTE (MP_KEY_MM_BASE+12)
|
||||
#define MP_KEY_HOMEPAGE (MP_KEY_MM_BASE+13)
|
||||
#define MP_KEY_WWW (MP_KEY_MM_BASE+14)
|
||||
#define MP_KEY_MAIL (MP_KEY_MM_BASE+15)
|
||||
#define MP_KEY_FAVORITES (MP_KEY_MM_BASE+16)
|
||||
#define MP_KEY_SEARCH (MP_KEY_MM_BASE+17)
|
||||
#define MP_KEY_SLEEP (MP_KEY_MM_BASE+18)
|
||||
|
||||
/* Function keys */
|
||||
#define MP_KEY_F (MP_KEY_BASE+0x40)
|
||||
|
||||
/* Keypad keys */
|
||||
#define MP_KEY_KEYPAD (MP_KEY_BASE+0x60)
|
||||
#define MP_KEY_KP0 (MP_KEY_KEYPAD+0)
|
||||
#define MP_KEY_KP1 (MP_KEY_KEYPAD+1)
|
||||
#define MP_KEY_KP2 (MP_KEY_KEYPAD+2)
|
||||
#define MP_KEY_KP3 (MP_KEY_KEYPAD+3)
|
||||
#define MP_KEY_KP4 (MP_KEY_KEYPAD+4)
|
||||
#define MP_KEY_KP5 (MP_KEY_KEYPAD+5)
|
||||
#define MP_KEY_KP6 (MP_KEY_KEYPAD+6)
|
||||
#define MP_KEY_KP7 (MP_KEY_KEYPAD+7)
|
||||
#define MP_KEY_KP8 (MP_KEY_KEYPAD+8)
|
||||
#define MP_KEY_KP9 (MP_KEY_KEYPAD+9)
|
||||
#define MP_KEY_KPDEC (MP_KEY_KEYPAD+10)
|
||||
#define MP_KEY_KPINS (MP_KEY_KEYPAD+11)
|
||||
#define MP_KEY_KPDEL (MP_KEY_KEYPAD+12)
|
||||
#define MP_KEY_KPENTER (MP_KEY_KEYPAD+13)
|
||||
#define MP_KEY_KEYPAD (MP_KEY_BASE+0x60)
|
||||
#define MP_KEY_KP0 (MP_KEY_KEYPAD+0)
|
||||
#define MP_KEY_KP1 (MP_KEY_KEYPAD+1)
|
||||
#define MP_KEY_KP2 (MP_KEY_KEYPAD+2)
|
||||
#define MP_KEY_KP3 (MP_KEY_KEYPAD+3)
|
||||
#define MP_KEY_KP4 (MP_KEY_KEYPAD+4)
|
||||
#define MP_KEY_KP5 (MP_KEY_KEYPAD+5)
|
||||
#define MP_KEY_KP6 (MP_KEY_KEYPAD+6)
|
||||
#define MP_KEY_KP7 (MP_KEY_KEYPAD+7)
|
||||
#define MP_KEY_KP8 (MP_KEY_KEYPAD+8)
|
||||
#define MP_KEY_KP9 (MP_KEY_KEYPAD+9)
|
||||
#define MP_KEY_KPDEC (MP_KEY_KEYPAD+10)
|
||||
#define MP_KEY_KPINS (MP_KEY_KEYPAD+11)
|
||||
#define MP_KEY_KPDEL (MP_KEY_KEYPAD+12)
|
||||
#define MP_KEY_KPENTER (MP_KEY_KEYPAD+13)
|
||||
|
||||
|
||||
// Joystick input module
|
||||
#define MP_JOY_BASE (MP_KEY_BASE+0x70)
|
||||
#define MP_JOY_AXIS0_PLUS (MP_JOY_BASE+0)
|
||||
#define MP_JOY_AXIS0_MINUS (MP_JOY_BASE+1)
|
||||
#define MP_JOY_AXIS1_PLUS (MP_JOY_BASE+2)
|
||||
#define MP_JOY_AXIS1_MINUS (MP_JOY_BASE+3)
|
||||
#define MP_JOY_AXIS2_PLUS (MP_JOY_BASE+4)
|
||||
#define MP_JOY_AXIS2_MINUS (MP_JOY_BASE+5)
|
||||
#define MP_JOY_AXIS3_PLUS (MP_JOY_BASE+6)
|
||||
#define MP_JOY_AXIS3_MINUS (MP_JOY_BASE+7)
|
||||
#define MP_JOY_AXIS4_PLUS (MP_JOY_BASE+8)
|
||||
#define MP_JOY_AXIS4_MINUS (MP_JOY_BASE+9)
|
||||
#define MP_JOY_AXIS5_PLUS (MP_JOY_BASE+10)
|
||||
#define MP_JOY_AXIS5_MINUS (MP_JOY_BASE+11)
|
||||
#define MP_JOY_AXIS6_PLUS (MP_JOY_BASE+12)
|
||||
#define MP_JOY_AXIS6_MINUS (MP_JOY_BASE+13)
|
||||
#define MP_JOY_AXIS7_PLUS (MP_JOY_BASE+14)
|
||||
#define MP_JOY_AXIS7_MINUS (MP_JOY_BASE+15)
|
||||
#define MP_JOY_AXIS8_PLUS (MP_JOY_BASE+16)
|
||||
#define MP_JOY_AXIS8_MINUS (MP_JOY_BASE+17)
|
||||
#define MP_JOY_AXIS9_PLUS (MP_JOY_BASE+18)
|
||||
#define MP_JOY_AXIS9_MINUS (MP_JOY_BASE+19)
|
||||
#define MP_JOY_BASE (MP_KEY_BASE+0x70)
|
||||
#define MP_JOY_AXIS0_PLUS (MP_JOY_BASE+0)
|
||||
#define MP_JOY_AXIS0_MINUS (MP_JOY_BASE+1)
|
||||
#define MP_JOY_AXIS1_PLUS (MP_JOY_BASE+2)
|
||||
#define MP_JOY_AXIS1_MINUS (MP_JOY_BASE+3)
|
||||
#define MP_JOY_AXIS2_PLUS (MP_JOY_BASE+4)
|
||||
#define MP_JOY_AXIS2_MINUS (MP_JOY_BASE+5)
|
||||
#define MP_JOY_AXIS3_PLUS (MP_JOY_BASE+6)
|
||||
#define MP_JOY_AXIS3_MINUS (MP_JOY_BASE+7)
|
||||
#define MP_JOY_AXIS4_PLUS (MP_JOY_BASE+8)
|
||||
#define MP_JOY_AXIS4_MINUS (MP_JOY_BASE+9)
|
||||
#define MP_JOY_AXIS5_PLUS (MP_JOY_BASE+10)
|
||||
#define MP_JOY_AXIS5_MINUS (MP_JOY_BASE+11)
|
||||
#define MP_JOY_AXIS6_PLUS (MP_JOY_BASE+12)
|
||||
#define MP_JOY_AXIS6_MINUS (MP_JOY_BASE+13)
|
||||
#define MP_JOY_AXIS7_PLUS (MP_JOY_BASE+14)
|
||||
#define MP_JOY_AXIS7_MINUS (MP_JOY_BASE+15)
|
||||
#define MP_JOY_AXIS8_PLUS (MP_JOY_BASE+16)
|
||||
#define MP_JOY_AXIS8_MINUS (MP_JOY_BASE+17)
|
||||
#define MP_JOY_AXIS9_PLUS (MP_JOY_BASE+18)
|
||||
#define MP_JOY_AXIS9_MINUS (MP_JOY_BASE+19)
|
||||
|
||||
#define MP_JOY_BTN_BASE ((MP_KEY_BASE+0x90)|MP_NO_REPEAT_KEY)
|
||||
#define MP_JOY_BTN0 (MP_JOY_BTN_BASE+0)
|
||||
@@ -126,54 +132,54 @@
|
||||
|
||||
|
||||
// Mouse events from VOs
|
||||
#define MP_MOUSE_BASE ((MP_KEY_BASE+0xA0)|MP_NO_REPEAT_KEY|MP_KEY_EMIT_ON_UP)
|
||||
#define MP_MOUSE_BTN0 (MP_MOUSE_BASE+0)
|
||||
#define MP_MOUSE_BTN1 (MP_MOUSE_BASE+1)
|
||||
#define MP_MOUSE_BTN2 (MP_MOUSE_BASE+2)
|
||||
#define MP_MOUSE_BTN3 (MP_MOUSE_BASE+3)
|
||||
#define MP_MOUSE_BTN4 (MP_MOUSE_BASE+4)
|
||||
#define MP_MOUSE_BTN5 (MP_MOUSE_BASE+5)
|
||||
#define MP_MOUSE_BTN6 (MP_MOUSE_BASE+6)
|
||||
#define MP_MOUSE_BTN7 (MP_MOUSE_BASE+7)
|
||||
#define MP_MOUSE_BTN8 (MP_MOUSE_BASE+8)
|
||||
#define MP_MOUSE_BTN9 (MP_MOUSE_BASE+9)
|
||||
#define MP_MOUSE_BTN10 (MP_MOUSE_BASE+10)
|
||||
#define MP_MOUSE_BTN11 (MP_MOUSE_BASE+11)
|
||||
#define MP_MOUSE_BTN12 (MP_MOUSE_BASE+12)
|
||||
#define MP_MOUSE_BTN13 (MP_MOUSE_BASE+13)
|
||||
#define MP_MOUSE_BTN14 (MP_MOUSE_BASE+14)
|
||||
#define MP_MOUSE_BTN15 (MP_MOUSE_BASE+15)
|
||||
#define MP_MOUSE_BTN16 (MP_MOUSE_BASE+16)
|
||||
#define MP_MOUSE_BTN17 (MP_MOUSE_BASE+17)
|
||||
#define MP_MOUSE_BTN18 (MP_MOUSE_BASE+18)
|
||||
#define MP_MOUSE_BTN19 (MP_MOUSE_BASE+19)
|
||||
#define MP_MOUSE_BASE ((MP_KEY_BASE+0xA0)|MP_NO_REPEAT_KEY|MP_KEY_EMIT_ON_UP)
|
||||
#define MP_MOUSE_BTN0 (MP_MOUSE_BASE+0)
|
||||
#define MP_MOUSE_BTN1 (MP_MOUSE_BASE+1)
|
||||
#define MP_MOUSE_BTN2 (MP_MOUSE_BASE+2)
|
||||
#define MP_MOUSE_BTN3 (MP_MOUSE_BASE+3)
|
||||
#define MP_MOUSE_BTN4 (MP_MOUSE_BASE+4)
|
||||
#define MP_MOUSE_BTN5 (MP_MOUSE_BASE+5)
|
||||
#define MP_MOUSE_BTN6 (MP_MOUSE_BASE+6)
|
||||
#define MP_MOUSE_BTN7 (MP_MOUSE_BASE+7)
|
||||
#define MP_MOUSE_BTN8 (MP_MOUSE_BASE+8)
|
||||
#define MP_MOUSE_BTN9 (MP_MOUSE_BASE+9)
|
||||
#define MP_MOUSE_BTN10 (MP_MOUSE_BASE+10)
|
||||
#define MP_MOUSE_BTN11 (MP_MOUSE_BASE+11)
|
||||
#define MP_MOUSE_BTN12 (MP_MOUSE_BASE+12)
|
||||
#define MP_MOUSE_BTN13 (MP_MOUSE_BASE+13)
|
||||
#define MP_MOUSE_BTN14 (MP_MOUSE_BASE+14)
|
||||
#define MP_MOUSE_BTN15 (MP_MOUSE_BASE+15)
|
||||
#define MP_MOUSE_BTN16 (MP_MOUSE_BASE+16)
|
||||
#define MP_MOUSE_BTN17 (MP_MOUSE_BASE+17)
|
||||
#define MP_MOUSE_BTN18 (MP_MOUSE_BASE+18)
|
||||
#define MP_MOUSE_BTN19 (MP_MOUSE_BASE+19)
|
||||
#define MP_MOUSE_BTN_END (MP_MOUSE_BASE+20)
|
||||
|
||||
#define MP_KEY_IS_MOUSE_BTN_SINGLE(code) \
|
||||
((code) >= MP_MOUSE_BASE && (code) < MP_MOUSE_BTN_END)
|
||||
|
||||
#define MP_MOUSE_BASE_DBL ((MP_KEY_BASE+0xC0)|MP_NO_REPEAT_KEY)
|
||||
#define MP_MOUSE_BTN0_DBL (MP_MOUSE_BASE_DBL+0)
|
||||
#define MP_MOUSE_BTN1_DBL (MP_MOUSE_BASE_DBL+1)
|
||||
#define MP_MOUSE_BTN2_DBL (MP_MOUSE_BASE_DBL+2)
|
||||
#define MP_MOUSE_BTN3_DBL (MP_MOUSE_BASE_DBL+3)
|
||||
#define MP_MOUSE_BTN4_DBL (MP_MOUSE_BASE_DBL+4)
|
||||
#define MP_MOUSE_BTN5_DBL (MP_MOUSE_BASE_DBL+5)
|
||||
#define MP_MOUSE_BTN6_DBL (MP_MOUSE_BASE_DBL+6)
|
||||
#define MP_MOUSE_BTN7_DBL (MP_MOUSE_BASE_DBL+7)
|
||||
#define MP_MOUSE_BTN8_DBL (MP_MOUSE_BASE_DBL+8)
|
||||
#define MP_MOUSE_BTN9_DBL (MP_MOUSE_BASE_DBL+9)
|
||||
#define MP_MOUSE_BTN10_DBL (MP_MOUSE_BASE_DBL+10)
|
||||
#define MP_MOUSE_BTN11_DBL (MP_MOUSE_BASE_DBL+11)
|
||||
#define MP_MOUSE_BTN12_DBL (MP_MOUSE_BASE_DBL+12)
|
||||
#define MP_MOUSE_BTN13_DBL (MP_MOUSE_BASE_DBL+13)
|
||||
#define MP_MOUSE_BTN14_DBL (MP_MOUSE_BASE_DBL+14)
|
||||
#define MP_MOUSE_BTN15_DBL (MP_MOUSE_BASE_DBL+15)
|
||||
#define MP_MOUSE_BTN16_DBL (MP_MOUSE_BASE_DBL+16)
|
||||
#define MP_MOUSE_BTN17_DBL (MP_MOUSE_BASE_DBL+17)
|
||||
#define MP_MOUSE_BTN18_DBL (MP_MOUSE_BASE_DBL+18)
|
||||
#define MP_MOUSE_BTN19_DBL (MP_MOUSE_BASE_DBL+19)
|
||||
#define MP_MOUSE_BTN_DBL_END (MP_MOUSE_BASE_DBL+20)
|
||||
#define MP_MOUSE_BASE_DBL ((MP_KEY_BASE+0xC0)|MP_NO_REPEAT_KEY)
|
||||
#define MP_MOUSE_BTN0_DBL (MP_MOUSE_BASE_DBL+0)
|
||||
#define MP_MOUSE_BTN1_DBL (MP_MOUSE_BASE_DBL+1)
|
||||
#define MP_MOUSE_BTN2_DBL (MP_MOUSE_BASE_DBL+2)
|
||||
#define MP_MOUSE_BTN3_DBL (MP_MOUSE_BASE_DBL+3)
|
||||
#define MP_MOUSE_BTN4_DBL (MP_MOUSE_BASE_DBL+4)
|
||||
#define MP_MOUSE_BTN5_DBL (MP_MOUSE_BASE_DBL+5)
|
||||
#define MP_MOUSE_BTN6_DBL (MP_MOUSE_BASE_DBL+6)
|
||||
#define MP_MOUSE_BTN7_DBL (MP_MOUSE_BASE_DBL+7)
|
||||
#define MP_MOUSE_BTN8_DBL (MP_MOUSE_BASE_DBL+8)
|
||||
#define MP_MOUSE_BTN9_DBL (MP_MOUSE_BASE_DBL+9)
|
||||
#define MP_MOUSE_BTN10_DBL (MP_MOUSE_BASE_DBL+10)
|
||||
#define MP_MOUSE_BTN11_DBL (MP_MOUSE_BASE_DBL+11)
|
||||
#define MP_MOUSE_BTN12_DBL (MP_MOUSE_BASE_DBL+12)
|
||||
#define MP_MOUSE_BTN13_DBL (MP_MOUSE_BASE_DBL+13)
|
||||
#define MP_MOUSE_BTN14_DBL (MP_MOUSE_BASE_DBL+14)
|
||||
#define MP_MOUSE_BTN15_DBL (MP_MOUSE_BASE_DBL+15)
|
||||
#define MP_MOUSE_BTN16_DBL (MP_MOUSE_BASE_DBL+16)
|
||||
#define MP_MOUSE_BTN17_DBL (MP_MOUSE_BASE_DBL+17)
|
||||
#define MP_MOUSE_BTN18_DBL (MP_MOUSE_BASE_DBL+18)
|
||||
#define MP_MOUSE_BTN19_DBL (MP_MOUSE_BASE_DBL+19)
|
||||
#define MP_MOUSE_BTN_DBL_END (MP_MOUSE_BASE_DBL+20)
|
||||
|
||||
#define MP_KEY_IS_MOUSE_BTN_DBL(code) \
|
||||
((code) >= MP_MOUSE_BTN0_DBL && (code) < MP_MOUSE_BTN_DBL_END)
|
||||
@@ -195,12 +201,6 @@
|
||||
#define MP_AR_VDOWN (MP_AR_BASE + 12)
|
||||
#define MP_AR_VDOWN_HOLD (MP_AR_BASE + 13)
|
||||
|
||||
// Apple Media Keys input module
|
||||
#define MP_MK_BASE (MP_KEY_BASE+0xF0)
|
||||
#define MP_MK_PLAY (MP_MK_BASE + 0)
|
||||
#define MP_MK_PREV (MP_MK_BASE + 1)
|
||||
#define MP_MK_NEXT (MP_MK_BASE + 2)
|
||||
|
||||
// Mouse wheels or touchpad input
|
||||
#define MP_AXIS_BASE (MP_KEY_BASE+0x100)
|
||||
#define MP_AXIS_UP (MP_AXIS_BASE+0)
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
local ass_mt = {}
|
||||
ass_mt.__index = ass_mt
|
||||
|
||||
local function ass_new()
|
||||
return setmetatable({ scale = 4, text = "" }, ass_mt)
|
||||
end
|
||||
|
||||
function ass_mt.new_event(ass)
|
||||
-- osd_libass.c adds an event per line
|
||||
if #ass.text > 0 then
|
||||
ass.text = ass.text .. "\n"
|
||||
end
|
||||
end
|
||||
|
||||
function ass_mt.draw_start(ass)
|
||||
ass.text = string.format("%s{\\p%d}", ass.text, ass.scale)
|
||||
end
|
||||
|
||||
function ass_mt.draw_stop(ass)
|
||||
ass.text = ass.text .. "{\\p0}"
|
||||
end
|
||||
|
||||
function ass_mt.coord(ass, x, y)
|
||||
local scale = math.pow(2, ass.scale - 1)
|
||||
local ix = math.ceil(x * scale)
|
||||
local iy = math.ceil(y * scale)
|
||||
ass.text = string.format("%s %d %d", ass.text, ix, iy)
|
||||
end
|
||||
|
||||
function ass_mt.append(ass, s)
|
||||
ass.text = ass.text .. s
|
||||
end
|
||||
|
||||
function ass_mt.merge(ass1, ass2)
|
||||
ass1.text = ass1.text .. ass2.text
|
||||
end
|
||||
|
||||
function ass_mt.pos(ass, x, y)
|
||||
ass:append(string.format("{\\pos(%f,%f)}", x, y))
|
||||
end
|
||||
|
||||
function ass_mt.an(ass, an)
|
||||
ass:append(string.format("{\\an%d}", an))
|
||||
end
|
||||
|
||||
function ass_mt.move_to(ass, x, y)
|
||||
ass:append(" m")
|
||||
ass:coord(x, y)
|
||||
end
|
||||
|
||||
function ass_mt.line_to(ass, x, y)
|
||||
ass:append(" l")
|
||||
ass:coord(x, y)
|
||||
end
|
||||
|
||||
function ass_mt.bezier_curve(ass, x1, y1, x2, y2, x3, y3)
|
||||
ass:append(" b")
|
||||
ass:coord(x1, y1)
|
||||
ass:coord(x2, y2)
|
||||
ass:coord(x3, y3)
|
||||
end
|
||||
|
||||
|
||||
function ass_mt.rect_ccw(ass, x0, y0, x1, y1)
|
||||
ass:move_to(x0, y0)
|
||||
ass:line_to(x0, y1)
|
||||
ass:line_to(x1, y1)
|
||||
ass:line_to(x1, y0)
|
||||
end
|
||||
|
||||
function ass_mt.rect_cw(ass, x0, y0, x1, y1)
|
||||
ass:move_to(x0, y0)
|
||||
ass:line_to(x1, y0)
|
||||
ass:line_to(x1, y1)
|
||||
ass:line_to(x0, y1)
|
||||
end
|
||||
|
||||
function ass_mt.round_rect_cw(ass, x0, y0, x1, y1, r)
|
||||
ass:move_to(x0 + r, y0)
|
||||
ass:line_to(x1 - r, y0) -- top line
|
||||
if r > 0 then
|
||||
ass:bezier_curve(x1, y0, x1, y0, x1, y0 + r) -- top right corner
|
||||
end
|
||||
ass:line_to(x1, y1 - r) -- right line
|
||||
if r > 0 then
|
||||
ass:bezier_curve(x1, y1, x1, y1, x1 - r, y1) -- bottom right corner
|
||||
end
|
||||
ass:line_to(x0 + r, y1) -- bottom line
|
||||
if r > 0 then
|
||||
ass:bezier_curve(x0, y1, x0, y1, x0, y1 - r) -- bottom left corner
|
||||
end
|
||||
ass:line_to(x0, y0 + r) -- left line
|
||||
if r > 0 then
|
||||
ass:bezier_curve(x0, y0, x0, y0, x0 + r, y0) -- top left corner
|
||||
end
|
||||
end
|
||||
|
||||
return {ass_new = ass_new}
|
||||
@@ -0,0 +1,82 @@
|
||||
|
||||
local callbacks = {}
|
||||
-- each script has its own section, so that they don't conflict
|
||||
local default_section = "input_" .. mp.script_name
|
||||
|
||||
-- Set the list of key bindings. These will override the user's bindings, so
|
||||
-- you should use this sparingly.
|
||||
-- A call to this function will remove all bindings previously set with this
|
||||
-- function. For example, set_key_bindings({}) would remove all script defined
|
||||
-- key bindings.
|
||||
-- Note: the bindings are not active by default. Use enable_key_bindings().
|
||||
--
|
||||
-- list is an array of key bindings, where each entry is an array as follow:
|
||||
-- {key, callback}
|
||||
-- {key, callback, callback_down}
|
||||
-- key is the key string as used in input.conf, like "ctrl+a"
|
||||
-- callback is a Lua function that is called when the key binding is used.
|
||||
-- callback_down can be given too, and is called when a mouse button is pressed
|
||||
-- if the key is a mouse button. (The normal callback will be for mouse button
|
||||
-- down.)
|
||||
--
|
||||
-- callback can be a string too, in which case the following will be added like
|
||||
-- an input.conf line: key .. " " .. callback
|
||||
-- (And callback_down is ignored.)
|
||||
function mp.set_key_bindings(list, section)
|
||||
local cfg = ""
|
||||
for i = 1, #list do
|
||||
local entry = list[i]
|
||||
local key = entry[1]
|
||||
local cb = entry[2]
|
||||
local cb_down = entry[3]
|
||||
if type(cb) == "function" then
|
||||
callbacks[#callbacks + 1] = {press=cb, before_press=cb_down}
|
||||
cfg = cfg .. key .. " script_dispatch " .. mp.script_name
|
||||
.. " " .. #callbacks .. "\n"
|
||||
else
|
||||
cfg = cfg .. key .. " " .. cb .. "\n"
|
||||
end
|
||||
end
|
||||
mp.input_define_section(section or default_section, cfg)
|
||||
end
|
||||
|
||||
function mp.enable_key_bindings(section, flags)
|
||||
mp.input_enable_section(section or default_section, flags)
|
||||
end
|
||||
|
||||
function mp.disable_key_bindings(section)
|
||||
mp.input_disable_section(section or default_section)
|
||||
end
|
||||
|
||||
function mp.set_mouse_area(x0, y0, x1, y1, section)
|
||||
mp.input_set_section_mouse_area(section or default_section, x0, y0, x1, y1)
|
||||
end
|
||||
|
||||
-- called by C on script_dispatch input command
|
||||
function mp_script_dispatch(id, event)
|
||||
local cb = callbacks[id]
|
||||
if cb then
|
||||
if event == "press" and cb.press then
|
||||
cb.press()
|
||||
elseif event == "keyup_follows" and cb.before_press then
|
||||
cb.before_press()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mp.msg = {
|
||||
log = mp.log,
|
||||
fatal = function(...) return mp.log("fatal", ...) end,
|
||||
error = function(...) return mp.log("error", ...) end,
|
||||
warn = function(...) return mp.log("warn", ...) end,
|
||||
info = function(...) return mp.log("info", ...) end,
|
||||
verbose = function(...) return mp.log("verbose", ...) end,
|
||||
debug = function(...) return mp.log("debug", ...) end,
|
||||
}
|
||||
|
||||
_G.print = mp.msg.info
|
||||
|
||||
package.loaded["mp"] = mp
|
||||
package.loaded["mp.msg"] = mp.msg
|
||||
|
||||
return {}
|
||||
+1247
File diff suppressed because it is too large.
Load diff
+5
-6
@@ -180,13 +180,12 @@ static void add_options(struct m_config *config,
|
||||
struct m_config_option *parent,
|
||||
const struct m_option *defs);
|
||||
|
||||
static int config_destroy(void *p)
|
||||
static void config_destroy(void *p)
|
||||
{
|
||||
struct m_config *config = p;
|
||||
m_config_restore_backups(config);
|
||||
for (struct m_config_option *copt = config->opts; copt; copt = copt->next)
|
||||
m_option_free(copt->opt, copt->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct m_config *m_config_new(void *talloc_parent, size_t size,
|
||||
@@ -333,7 +332,7 @@ static void add_negation_option(struct m_config *config,
|
||||
.name = talloc_asprintf(no_opt, "no-%s", opt->name),
|
||||
.type = CONF_TYPE_STORE,
|
||||
.flags = opt->flags & (M_OPT_NOCFG | M_OPT_GLOBAL | M_OPT_PRE_PARSE),
|
||||
.new = opt->new,
|
||||
.is_new_option = opt->is_new_option,
|
||||
.p = opt->p,
|
||||
.offset = opt->offset,
|
||||
.max = value,
|
||||
@@ -381,7 +380,7 @@ static struct m_config_option *m_config_add_option(struct m_config *config,
|
||||
void *optstruct = config->optstruct;
|
||||
if (parent && (parent->opt->type->flags & M_OPT_TYPE_USE_SUBSTRUCT))
|
||||
optstruct = substruct_read_ptr(parent->data);
|
||||
co->data = arg->new ? (char *)optstruct + arg->offset : arg->p;
|
||||
co->data = arg->is_new_option ? (char *)optstruct + arg->offset : arg->p;
|
||||
|
||||
if (parent) {
|
||||
// Merge case: pretend it has no parent (note that we still must follow
|
||||
@@ -727,10 +726,10 @@ struct m_profile *m_config_add_profile(struct m_config *config, char *name)
|
||||
return p;
|
||||
}
|
||||
|
||||
void m_profile_set_desc(struct m_profile *p, char *desc)
|
||||
void m_profile_set_desc(struct m_profile *p, bstr desc)
|
||||
{
|
||||
talloc_free(p->desc);
|
||||
p->desc = talloc_strdup(p, desc);
|
||||
p->desc = bstrdup0(p, desc);
|
||||
}
|
||||
|
||||
int m_config_set_profile_option(struct m_config *config, struct m_profile *p,
|
||||
|
||||
+1
-1
@@ -188,7 +188,7 @@ struct m_profile *m_config_add_profile(struct m_config *config, char *name);
|
||||
* \param p The profile object.
|
||||
* \param arg The profile's name.
|
||||
*/
|
||||
void m_profile_set_desc(struct m_profile *p, char *desc);
|
||||
void m_profile_set_desc(struct m_profile *p, bstr desc);
|
||||
|
||||
/* Add an option to a profile.
|
||||
* Used by the config file parser when defining a profile.
|
||||
|
||||
+44
-1
@@ -186,6 +186,7 @@ const m_option_type_t m_option_type_store = {
|
||||
.size = sizeof(int),
|
||||
.flags = M_OPT_TYPE_OPTIONAL_PARAM,
|
||||
.parse = parse_store,
|
||||
.copy = copy_opt,
|
||||
};
|
||||
|
||||
// Same for float types
|
||||
@@ -214,6 +215,7 @@ const m_option_type_t m_option_type_float_store = {
|
||||
.size = sizeof(float),
|
||||
.flags = M_OPT_TYPE_OPTIONAL_PARAM,
|
||||
.parse = parse_store_float,
|
||||
.copy = copy_opt,
|
||||
};
|
||||
|
||||
// Integer
|
||||
@@ -651,6 +653,7 @@ const m_option_type_t m_option_type_double = {
|
||||
.pretty_print = print_double_f3,
|
||||
.copy = copy_opt,
|
||||
.clamp = clamp_double,
|
||||
.add = add_double,
|
||||
};
|
||||
|
||||
#undef VAL
|
||||
@@ -1329,6 +1332,7 @@ const m_option_type_t m_option_type_color = {
|
||||
.name = "Color",
|
||||
.size = sizeof(struct m_color),
|
||||
.parse = parse_color,
|
||||
.copy = copy_opt,
|
||||
};
|
||||
|
||||
|
||||
@@ -1473,6 +1477,7 @@ const m_option_type_t m_option_type_geometry = {
|
||||
.name = "Window geometry",
|
||||
.size = sizeof(struct m_geometry),
|
||||
.parse = parse_geometry,
|
||||
.copy = copy_opt,
|
||||
};
|
||||
|
||||
static int parse_size_box(const m_option_t *opt, struct bstr name,
|
||||
@@ -1502,6 +1507,7 @@ const m_option_type_t m_option_type_size_box = {
|
||||
.name = "Window size",
|
||||
.size = sizeof(struct m_geometry),
|
||||
.parse = parse_size_box,
|
||||
.copy = copy_opt,
|
||||
};
|
||||
|
||||
|
||||
@@ -1595,7 +1601,7 @@ static int parse_afmt(const m_option_t *opt, struct bstr name,
|
||||
}
|
||||
|
||||
int fmt = af_str2fmt_short(param);
|
||||
if (fmt == -1) {
|
||||
if (!fmt) {
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
|
||||
"Option %.*s: unknown format name: '%.*s'\n",
|
||||
BSTR_P(name), BSTR_P(param));
|
||||
@@ -2397,11 +2403,48 @@ static int parse_obj_settings_list(const m_option_t *opt, struct bstr name,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void append_param(char **res, char *param)
|
||||
{
|
||||
if (strspn(param, NAMECH) == strlen(param)) {
|
||||
*res = talloc_strdup_append(*res, param);
|
||||
} else {
|
||||
// Simple escaping: %BYTECOUNT%STRING
|
||||
*res = talloc_asprintf_append(*res, "%%%zd%%%s", strlen(param), param);
|
||||
}
|
||||
}
|
||||
|
||||
static char *print_obj_settings_list(const m_option_t *opt, const void *val)
|
||||
{
|
||||
m_obj_settings_t *list = VAL(val);
|
||||
char *res = talloc_strdup(NULL, "");
|
||||
for (int n = 0; list && list[n].name; n++) {
|
||||
m_obj_settings_t *entry = &list[n];
|
||||
if (n > 0)
|
||||
res = talloc_strdup_append(res, ",");
|
||||
// Assume labels and names don't need escaping
|
||||
if (entry->label && entry->label[0])
|
||||
res = talloc_asprintf_append(res, "@%s:", entry->label);
|
||||
res = talloc_strdup_append(res, entry->name);
|
||||
if (entry->attribs && entry->attribs[0]) {
|
||||
res = talloc_strdup_append(res, "=");
|
||||
for (int i = 0; entry->attribs[i * 2 + 0]; i++) {
|
||||
if (i > 0)
|
||||
res = talloc_strdup_append(res, ":");
|
||||
append_param(&res, entry->attribs[i * 2 + 0]);
|
||||
res = talloc_strdup_append(res, "=");
|
||||
append_param(&res, entry->attribs[i * 2 + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
const m_option_type_t m_option_type_obj_settings_list = {
|
||||
.name = "Object settings list",
|
||||
.size = sizeof(m_obj_settings_t *),
|
||||
.flags = M_OPT_TYPE_DYNAMIC | M_OPT_TYPE_ALLOW_WILDCARD,
|
||||
.parse = parse_obj_settings_list,
|
||||
.print = print_obj_settings_list,
|
||||
.copy = copy_obj_settings_list,
|
||||
.free = free_obj_settings_list,
|
||||
};
|
||||
+5
-5
@@ -313,12 +313,12 @@ struct m_option {
|
||||
*/
|
||||
void *priv;
|
||||
|
||||
int new;
|
||||
int is_new_option;
|
||||
|
||||
int offset;
|
||||
|
||||
// Initialize variable to given default before parsing options
|
||||
void *defval;
|
||||
const void *defval;
|
||||
};
|
||||
|
||||
|
||||
@@ -505,12 +505,12 @@ int m_option_required_params(const m_option_t *opt);
|
||||
#define OPTDEF_INT(i) .defval = (void *)&(const int){i}
|
||||
|
||||
#define OPT_GENERAL(ctype, optname, varname, flagv, ...) \
|
||||
{.name = optname, .flags = flagv, .new = 1, \
|
||||
{.name = optname, .flags = flagv, .is_new_option = 1, \
|
||||
.offset = MP_CHECKED_OFFSETOF(OPT_BASE_STRUCT, varname, ctype), \
|
||||
__VA_ARGS__}
|
||||
|
||||
#define OPT_GENERAL_NOTYPE(optname, varname, flagv, ...) \
|
||||
{.name = optname, .flags = flagv, .new = 1, \
|
||||
{.name = optname, .flags = flagv, .is_new_option = 1, \
|
||||
.offset = offsetof(OPT_BASE_STRUCT, varname), \
|
||||
__VA_ARGS__}
|
||||
|
||||
@@ -624,7 +624,7 @@ int m_option_required_params(const m_option_t *opt);
|
||||
OPT_GENERAL(struct m_geometry, __VA_ARGS__, .type = &m_option_type_size_box)
|
||||
|
||||
#define OPT_TRACKCHOICE(name, var) \
|
||||
OPT_CHOICE_OR_INT(name, var, 0, 0, 8190, ({"no", -2}, {"auto", -1}))
|
||||
OPT_CHOICE_OR_INT(name, var, 0, 1, 8190, ({"no", -2}, {"auto", -1}))
|
||||
|
||||
#define OPT_STRING_VALIDATE_(optname, varname, flags, validate_fn, ...) \
|
||||
OPT_GENERAL(char*, optname, varname, flags, __VA_ARGS__, \
|
||||
|
||||
+35
-22
@@ -214,8 +214,39 @@ static void append_str(char **s, int *len, bstr append)
|
||||
*len = *len + append.len;
|
||||
}
|
||||
|
||||
char *m_properties_expand_string(const m_option_t *prop_list, char *str0,
|
||||
void *ctx)
|
||||
static int expand_property(const m_option_t *prop_list, char **ret, int *ret_len,
|
||||
bstr prop, bool silent_error, void *ctx)
|
||||
{
|
||||
bool cond_yes = bstr_eatstart0(&prop, "?");
|
||||
bool cond_no = !cond_yes && bstr_eatstart0(&prop, "!");
|
||||
bool test = cond_yes || cond_no;
|
||||
bool raw = bstr_eatstart0(&prop, "=");
|
||||
bstr comp_with = {0};
|
||||
bool comp = test && bstr_split_tok(prop, "==", &prop, &comp_with);
|
||||
if (test && !comp)
|
||||
raw = true;
|
||||
int method = raw ? M_PROPERTY_GET_STRING : M_PROPERTY_PRINT;
|
||||
|
||||
char *s = NULL;
|
||||
int r = m_property_do_bstr(prop_list, prop, method, &s, ctx);
|
||||
bool skip;
|
||||
if (comp) {
|
||||
skip = ((s && bstr_equals0(comp_with, s)) != cond_yes);
|
||||
} else if (test) {
|
||||
skip = (!!s != cond_yes);
|
||||
} else {
|
||||
skip = !!s;
|
||||
char *append = s;
|
||||
if (!s && !silent_error && !raw)
|
||||
append = (r == M_PROPERTY_UNAVAILABLE) ? "(unavailable)" : "(error)";
|
||||
append_str(ret, ret_len, bstr0(append));
|
||||
}
|
||||
talloc_free(s);
|
||||
return skip;
|
||||
}
|
||||
|
||||
char *m_properties_expand_string(const m_option_t *prop_list,
|
||||
const char *str0, void *ctx)
|
||||
{
|
||||
char *ret = NULL;
|
||||
int ret_len = 0;
|
||||
@@ -240,26 +271,8 @@ char *m_properties_expand_string(const m_option_t *prop_list, char *str0,
|
||||
bool have_fallback = bstr_eatstart0(&str, ":");
|
||||
|
||||
if (!skip) {
|
||||
bool cond_yes = bstr_eatstart0(&name, "?");
|
||||
bool cond_no = !cond_yes && bstr_eatstart0(&name, "!");
|
||||
bool raw = bstr_eatstart0(&name, "=");
|
||||
int method = (raw || cond_yes || cond_no)
|
||||
? M_PROPERTY_GET_STRING : M_PROPERTY_PRINT;
|
||||
|
||||
char *s = NULL;
|
||||
int r = m_property_do_bstr(prop_list, name, method, &s, ctx);
|
||||
if (cond_yes || cond_no) {
|
||||
skip = (!!s != cond_yes);
|
||||
} else {
|
||||
skip = !!s;
|
||||
char *append = s;
|
||||
if (!s && !have_fallback && !raw) {
|
||||
append = r == M_PROPERTY_UNAVAILABLE
|
||||
? "(unavailable)" : "(error)";
|
||||
}
|
||||
append_str(&ret, &ret_len, bstr0(append));
|
||||
}
|
||||
talloc_free(s);
|
||||
skip = expand_property(prop_list, &ret, &ret_len, name,
|
||||
have_fallback, ctx);
|
||||
if (skip)
|
||||
skip_level = level;
|
||||
}
|
||||
|
||||
@@ -124,8 +124,8 @@ void m_properties_print_help_list(const struct m_option* list);
|
||||
// STR is recursively expanded using the same rules.
|
||||
// "$$" can be used to escape "$", and "$}" to escape "}".
|
||||
// "$>" disables parsing of "$" for the rest of the string.
|
||||
char* m_properties_expand_string(const struct m_option* prop_list, char *str,
|
||||
void *ctx);
|
||||
char* m_properties_expand_string(const struct m_option* prop_list,
|
||||
const char *str, void *ctx);
|
||||
|
||||
// Trivial helpers for implementing properties.
|
||||
int m_property_int_ro(const struct m_option* prop, int action, void* arg,
|
||||
|
||||
Loaded 100 of 261 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user