Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6158c324e | ||
|
|
f534c83da6 | ||
|
|
39f6824b30 | ||
|
|
477eefa63f | ||
|
|
87713640ae | ||
|
|
63bd171c0d | ||
|
|
73086a6ba3 | ||
|
|
0126999cde | ||
|
|
2a6b10c9ca | ||
|
|
3fa249b4e1 | ||
|
|
0a55f43181 | ||
|
|
5aa2d496e6 | ||
|
|
76ba91415b | ||
|
|
20a1418af6 | ||
|
|
277dc33268 | ||
|
|
cb2461044b | ||
|
|
1eb7db70d5 | ||
|
|
a8c764acb4 | ||
|
|
62a66e2ff8 | ||
|
|
e8f8d3462e | ||
|
|
7669fe39f6 | ||
|
|
6a1902a2bf | ||
|
|
192af725e6 | ||
|
|
d27bb1ce80 | ||
|
|
e795a1781f | ||
|
|
6e4abfb017 | ||
|
|
62195c174a | ||
|
|
79efe85cf5 | ||
|
|
5f1d6b6e5a | ||
|
|
983d24e3b9 | ||
|
|
72e505a944 | ||
|
|
e11abdbad2 | ||
|
|
8d31ad85ec | ||
|
|
ad11d877a5 | ||
|
|
138c4e50df | ||
|
|
e2326bda82 | ||
|
|
9c6417ea88 | ||
|
|
bf0cb27489 | ||
|
|
6cadeaa79a | ||
|
|
df1f22214b | ||
|
|
1419aac22a | ||
|
|
994438dee5 | ||
|
|
91f6f2bf11 | ||
|
|
b98949c72c | ||
|
|
cc21eadf30 | ||
|
|
90d7e51643 | ||
|
|
e9ca0b1522 | ||
|
|
457e2f7e02 | ||
|
|
daabbe3640 | ||
|
|
589533d97a | ||
|
|
777273c064 | ||
|
|
bcf3904a0d | ||
|
|
1299fbec05 | ||
|
|
3990fe74f6 | ||
|
|
0b240bca8a | ||
|
|
eb62d7ec40 | ||
|
|
eabd2ac9e4 | ||
|
|
dbeb105396 | ||
|
|
445527d45c | ||
|
|
dedb15a429 | ||
|
|
7f29172baf | ||
|
|
a7cf35c1ca | ||
|
|
4ae8fc326d | ||
|
|
74ae74db0c | ||
|
|
bbb0b69d73 | ||
|
|
a3680d1b2d | ||
|
|
ccfe4d6418 | ||
|
|
2469cb5d1f | ||
|
|
07678423fb | ||
|
|
f13266014f | ||
|
|
debf57bb0d | ||
|
|
a1e410e43a | ||
|
|
c6d046414b | ||
|
|
c5654e4005 | ||
|
|
c64e4e48d9 | ||
|
|
ebe2c2b6d1 | ||
|
|
88d3058681 | ||
|
|
34d5b73fbb | ||
|
|
bd5d047c89 | ||
|
|
1dcc38a7c2 | ||
|
|
8e0cf9d878 | ||
|
|
c96404d824 | ||
|
|
3313eba1bf | ||
|
|
f3c8c613ba | ||
|
|
f51952441e | ||
|
|
d8dd4b6c39 | ||
|
|
b0bd0a6e6b | ||
|
|
1d36955f70 | ||
|
|
01cfcd6814 | ||
|
|
55ba4db742 | ||
|
|
18f30787f2 | ||
|
|
00c18b32bf | ||
|
|
e207c24b32 | ||
|
|
baaa27d6db | ||
|
|
e0bb60a708 | ||
|
|
f4292ebf52 | ||
|
|
547976633f | ||
|
|
533b0c70e1 | ||
|
|
9cabef3974 | ||
|
|
7ee18376a9 | ||
|
|
d55c41501f | ||
|
|
95c1487c93 | ||
|
|
dd12040ebe | ||
|
|
e6d7e55012 | ||
|
|
3f8b8b8c0c | ||
|
|
e1e46cc81a | ||
|
|
2896afaa39 | ||
|
|
7d40a33ed9 | ||
|
|
d8a0356b3b | ||
|
|
0ded54dd89 | ||
|
|
d704d61c61 | ||
|
|
9e0cd3b3e7 | ||
|
|
3823d5eb7e | ||
|
|
77c96f111c | ||
|
|
3b2cc79d2f | ||
|
|
5b1c3e4b50 | ||
|
|
d64ff3aa51 | ||
|
|
3287825bd2 | ||
|
|
9e65b5db0b | ||
|
|
f43017bfe9 | ||
|
|
ab2a27ae01 | ||
|
|
f8a98fc133 | ||
|
|
e466a735a3 | ||
|
|
a8e8176ab1 | ||
|
|
544c56bf22 | ||
|
|
2b679020f7 | ||
|
|
3bfdc20aa1 | ||
|
|
ea11b09bc3 | ||
|
|
96d0a3f56c | ||
|
|
1e3aad5f87 | ||
|
|
527911d2a2 | ||
|
|
ac7ecbe30c | ||
|
|
6f46bafbd0 | ||
|
|
abf100f81d | ||
|
|
37a71e57d4 | ||
|
|
41151122e7 | ||
|
|
b3495d9ccf | ||
|
|
cf55fa6471 | ||
|
|
1e692cb043 | ||
|
|
6efd095dfd | ||
|
|
77869e5914 | ||
|
|
46eb04f3c2 | ||
|
|
be6cca7849 | ||
|
|
8fe640c47d | ||
|
|
be259be15c | ||
|
|
d737939f1f | ||
|
|
8d3c826ad8 | ||
|
|
13a0ff8cb7 | ||
|
|
c4faab4871 | ||
|
|
843bc822a8 | ||
|
|
c97f014576 | ||
|
|
f1746741de | ||
|
|
d453600b4f | ||
|
|
e76f6929e5 | ||
|
|
8dc7156bc0 | ||
|
|
4e8ee522f4 | ||
|
|
11556e0530 | ||
|
|
db7d56b19f | ||
|
|
d9d8c9ce13 | ||
|
|
35e9d75083 | ||
|
|
7a65c44922 | ||
|
|
78fe1d3a2c | ||
|
|
26909c1113 | ||
|
|
36ae8a6cab | ||
|
|
579c4dac34 | ||
|
|
e98ab5e596 | ||
|
|
d857b5f5ab | ||
|
|
5574820f13 | ||
|
|
c7a6b94d63 | ||
|
|
f6b2325c2a | ||
|
|
efae88e521 | ||
|
|
f316f1ec16 | ||
|
|
edef17fcb7 | ||
|
|
7d116a979b | ||
|
|
4a84cd37f3 | ||
|
|
a18dc01655 | ||
|
|
20160fa2e1 | ||
|
|
642f84f922 | ||
|
|
fe60cff03b | ||
|
|
4f84939310 | ||
|
|
717e7a5baa | ||
|
|
51bb5e8194 | ||
|
|
bfbe1342f7 | ||
|
|
b51ff8702b | ||
|
|
27d57af450 | ||
|
|
5704055635 | ||
|
|
8876572e2c | ||
|
|
34caa8b01c | ||
|
|
6bd673c1d2 | ||
|
|
1984e31706 | ||
|
|
13efec228b | ||
|
|
068ff812e4 | ||
|
|
586dc5574f | ||
|
|
00151e987d | ||
|
|
9ea0590371 | ||
|
|
bf3e0bc1da | ||
|
|
46b9df9f9e | ||
|
|
07671ac57b | ||
|
|
8fbc64f74e | ||
|
|
8585845c64 | ||
|
|
3d17b12d9c | ||
|
|
28fa17dac6 | ||
|
|
14a530f474 | ||
|
|
5a2825ec35 | ||
|
|
19f56e2097 | ||
|
|
9a7fa65f8f | ||
|
|
bf69edb1c2 | ||
|
|
83bd128016 | ||
|
|
550d908ba8 | ||
|
|
9b59c175e3 | ||
|
|
f9db94ab71 | ||
|
|
9e98702493 | ||
|
|
f5603cba23 | ||
|
|
4987c1906d | ||
|
|
d4e31166b7 | ||
|
|
ab3a64ee4c | ||
|
|
62030e1090 | ||
|
|
72fcdc32db | ||
|
|
502f9a1450 | ||
|
|
1d2b81b550 | ||
|
|
e408dd20c7 | ||
|
|
b6c28dd26b | ||
|
|
ea00fe0eeb | ||
|
|
8158dfc9e8 | ||
|
|
48dafda7e9 | ||
|
|
d6b102cab0 | ||
|
|
5035501037 | ||
|
|
638a398d62 | ||
|
|
33d587ffa9 | ||
|
|
a6bf38bcad | ||
|
|
1091353d47 | ||
|
|
df27ef2203 | ||
|
|
00230fab6a | ||
|
|
8f0f73e591 | ||
|
|
27715b7dd1 | ||
|
|
273afdc3a4 | ||
|
|
1164dc572c | ||
|
|
205a2ef169 | ||
|
|
39f6f6b104 | ||
|
|
ebef5da074 | ||
|
|
8fff125422 | ||
|
|
38b05daf7d | ||
|
|
4f7abd5e43 | ||
|
|
f82ddf1d0b | ||
|
|
b561ec99ff | ||
|
|
36d1b28849 | ||
|
|
cfaa6e9155 | ||
|
|
634b4afa2b | ||
|
|
091e38cbf7 | ||
|
|
c1afa2763a | ||
|
|
a01b6d99e5 | ||
|
|
e4e27882e7 | ||
|
|
81da34549f | ||
|
|
41c10c3ec2 | ||
|
|
fb61858b63 | ||
|
|
8b82ebd3e6 | ||
|
|
58e0292a9f | ||
|
|
a60e725113 | ||
|
|
6e1c950069 | ||
|
|
987197be46 | ||
|
|
dfbe1832ee | ||
|
|
4bcd6ec41d | ||
|
|
8c43e12b20 | ||
|
|
a67494e86b | ||
|
|
62d3c95367 | ||
|
|
72308256e4 | ||
|
|
83476433b5 | ||
|
|
7977961671 | ||
|
|
45ff6cef62 | ||
|
|
6d9f15a8ab | ||
|
|
85c21ae409 | ||
|
|
cdf9abd872 | ||
|
|
e07d1b397c | ||
|
|
b7325b2f64 | ||
|
|
08df18aea3 | ||
|
|
36c4ac8464 | ||
|
|
81a63545a0 | ||
|
|
1ad4a62336 | ||
|
|
9b5a7241e8 | ||
|
|
1e659a9f0f | ||
|
|
d5318e5e09 | ||
|
|
170a2e0568 | ||
|
|
8c8d6e6878 | ||
|
|
603a0f733f | ||
|
|
54cc610fde | ||
|
|
3f4e154ec6 | ||
|
|
3a6ade7a84 | ||
|
|
c10fb4ce9f | ||
|
|
3714430cdf | ||
|
|
dd08aa7364 | ||
|
|
c48de9e399 | ||
|
|
53f24ac5ad | ||
|
|
e52f7d3da8 | ||
|
|
cfb5e0cea6 | ||
|
|
f92c7fa807 | ||
|
|
68b71346ec | ||
|
|
a09e5dd891 | ||
|
|
7363b0439f | ||
|
|
180e35a175 | ||
|
|
b5e67ca178 | ||
|
|
9d84b2c07d | ||
|
|
16a5c6c535 | ||
|
|
ab37a77b36 | ||
|
|
a5c66601ff | ||
|
|
331b21f267 | ||
|
|
2a2391d3d8 | ||
|
|
6c2f25a7b0 | ||
|
|
167b75c50c | ||
|
|
67bdad9a43 | ||
|
|
3f3d71b0a8 | ||
|
|
612b8a8ab3 | ||
|
|
7205e75079 | ||
|
|
6f5db977c0 | ||
|
|
d790dbc3b5 | ||
|
|
72e67064a3 | ||
|
|
23a3fa8e90 | ||
|
|
fe0c37b007 | ||
|
|
29083ae31b | ||
|
|
25c8bf8754 | ||
|
|
055720fbce | ||
|
|
6b53897d75 | ||
|
|
5f2a8474ae | ||
|
|
145922a070 | ||
|
|
713a8c1a89 | ||
|
|
9c21082835 | ||
|
|
aaa42f82dc | ||
|
|
47c131bb0c | ||
|
|
39ed9b7d96 | ||
|
|
51befc9deb | ||
|
|
15478ca31c | ||
|
|
37cb9a965a | ||
|
|
775a02aab5 | ||
|
|
8fa036b3a0 | ||
|
|
70a190af04 | ||
|
|
d96fad04be | ||
|
|
420e657a0b | ||
|
|
7c2f21cb50 | ||
|
|
2fe81ce789 | ||
|
|
699fc0e51e | ||
|
|
92f1309974 | ||
|
|
e744eef322 | ||
|
|
aa728d5d6f | ||
|
|
4eec5b432b | ||
|
|
0329b81354 | ||
|
|
ce2da9cfcf | ||
|
|
41f9b9376b | ||
|
|
958dbca3ef | ||
|
|
9cd523bf5f | ||
|
|
31a5f08f13 | ||
|
|
ac1e31957d | ||
|
|
44a78a2be2 | ||
|
|
6f3292813f | ||
|
|
c4f4b09014 | ||
|
|
fadf03354e | ||
|
|
add4c9ee03 | ||
|
|
af705d0122 | ||
|
|
a1b3af5df3 | ||
|
|
a0e747ab35 | ||
|
|
efe0fb75bc | ||
|
|
0c9c0474bc | ||
|
|
e07b6fcdfd | ||
|
|
59c18dc73d | ||
|
|
add208c58a | ||
|
|
697fb963c2 | ||
|
|
67b41f533e | ||
|
|
dfec71f55a | ||
|
|
d64c9d8e8c | ||
|
|
f881a520fd | ||
|
|
6de3fe0b34 | ||
|
|
a38b85ce42 | ||
|
|
aedea2a79f | ||
|
|
b2ad2e2fd1 | ||
|
|
acbac01a73 | ||
|
|
ea680d2677 | ||
|
|
3ee9d7c416 | ||
|
|
9b77666783 | ||
|
|
1eeeab2e14 | ||
|
|
9a7fc55607 | ||
|
|
209f8225ed | ||
|
|
73cf615555 | ||
|
|
3974a5ca5e | ||
|
|
e74a4d5bc0 | ||
|
|
ae6019cbc9 | ||
|
|
8a4239e0c2 | ||
|
|
7e9c441d41 | ||
|
|
e9841630ad | ||
|
|
ca474d22c9 | ||
|
|
30860f7b10 | ||
|
|
ca0b33e9b1 | ||
|
|
c7790b4526 | ||
|
|
eb482140d9 | ||
|
|
69c61a882d | ||
|
|
da46a13c6b | ||
|
|
5f8b060ec2 | ||
|
|
574bd127ec | ||
|
|
eff265c140 | ||
|
|
2f5e31cf47 | ||
|
|
fa75a7b6d7 | ||
|
|
ee14da2988 | ||
|
|
30b0a5b98a | ||
|
|
90adf2904e | ||
|
|
cfa44f4e90 | ||
|
|
b9307b7175 | ||
|
|
112d9aeda1 | ||
|
|
39fa05d374 | ||
|
|
5f0eda7b94 | ||
|
|
735bf48496 | ||
|
|
b7f242dfcf | ||
|
|
a26ea50694 | ||
|
|
3efbc1a9a3 | ||
|
|
6983430c35 | ||
|
|
d7f04e2085 | ||
|
|
5c3a6ca96e | ||
|
|
4d0aa01637 | ||
|
|
6f507d14c1 | ||
|
|
8ec9bce2d3 | ||
|
|
ce239f1577 | ||
|
|
6172e843cd | ||
|
|
89db92398e | ||
|
|
b2099f55d2 | ||
|
|
39537f6474 | ||
|
|
bce753060e | ||
|
|
678cd30904 | ||
|
|
1bab7f69ae | ||
|
|
5cddd4ccca | ||
|
|
c66b51dab0 | ||
|
|
ddbecd09b0 | ||
|
|
c30d5f79b5 | ||
|
|
f0ab1f2048 | ||
|
|
12dcc5eaac | ||
|
|
4ff29f33b0 | ||
|
|
fc571e0adb | ||
|
|
720d4a5a1a | ||
|
|
3fe61ada84 | ||
|
|
dfa562b5db | ||
|
|
90496f3088 | ||
|
|
4dd7104af8 | ||
|
|
e9ff136dd3 | ||
|
|
baa354c64c | ||
|
|
05bb2a9e8a | ||
|
|
27b5492a82 | ||
|
|
9657e5a2ca | ||
|
|
4e3f8ccb9d | ||
|
|
963c92eea2 | ||
|
|
2e26639155 | ||
|
|
dcabceb626 | ||
|
|
ae33ec2c5b | ||
|
|
6d4a758295 | ||
|
|
55f69605fb | ||
|
|
e35da1ac02 | ||
|
|
5c49fe97cb | ||
|
|
9e1866af1e | ||
|
|
f447179c59 | ||
|
|
3cd394995f | ||
|
|
771cb34932 | ||
|
|
85bf102f54 | ||
|
|
0bbf36b796 | ||
|
|
3c3f9a8042 | ||
|
|
c028d782c1 | ||
|
|
89306818bb | ||
|
|
9746e71efc | ||
|
|
1ba24d2585 | ||
|
|
b3401e8972 | ||
|
|
22d11d7b3a | ||
|
|
97940e0f48 | ||
|
|
c31e5da734 | ||
|
|
5808f1c408 | ||
|
|
7031335886 | ||
|
|
fa65d657d2 | ||
|
|
89bc2975e9 | ||
|
|
d0fee0ac33 | ||
|
|
a4b6bf8c41 | ||
|
|
01b87e509c | ||
|
|
445b3fbf82 | ||
|
|
4b177bd5c2 | ||
|
|
08199a64d2 | ||
|
|
1bbf1eb3ce | ||
|
|
a76cc1dafc | ||
|
|
8d24e9d9b8 | ||
|
|
833ac3f264 | ||
|
|
40c9e79068 | ||
|
|
03a69bac95 | ||
|
|
721e430cd2 | ||
|
|
b742384162 | ||
|
|
e141caa97d | ||
|
|
653b0dd529 | ||
|
|
729c8b3f64 | ||
|
|
fbacd5de31 | ||
|
|
076b3d1385 | ||
|
|
73c5c3df53 | ||
|
|
e7b7a5a476 | ||
|
|
fbf76da913 | ||
|
|
5824eb7107 | ||
|
|
64456488b3 | ||
|
|
1eb533afb3 | ||
|
|
b143102f6d | ||
|
|
b7bb0de1d9 | ||
|
|
d896f043e4 | ||
|
|
0f99b302f5 | ||
|
|
0da6a7346a | ||
|
|
6e73b4dac7 | ||
|
|
f47beb1f07 | ||
|
|
7b02c79a23 | ||
|
|
a22de99544 | ||
|
|
0035dbdbb8 | ||
|
|
a5f3083ae7 | ||
|
|
280c826379 | ||
|
|
a2e0cd7f25 | ||
|
|
633147c959 | ||
|
|
e85bcc1223 | ||
|
|
899f0cd51e | ||
|
|
f3eb6ae783 | ||
|
|
8e80b3fd2f | ||
|
|
eb0db4d6fd | ||
|
|
9349cfca91 | ||
|
|
02bd54c0ac | ||
|
|
2bf0a5f2bc | ||
|
|
2e23be5a7b | ||
|
|
a761a1531a | ||
|
|
3c21a13a16 | ||
|
|
010cf183fe | ||
|
|
9fa73b6f64 | ||
|
|
dbc5d7b7db | ||
|
|
71cc322f13 | ||
|
|
53641a689d | ||
|
|
9fbcb56bee | ||
|
|
cc011415ff | ||
|
|
2c8d16d89f | ||
|
|
a92cab736f | ||
|
|
5baf74fa24 | ||
|
|
b629da9a40 | ||
|
|
7cff2e4131 | ||
|
|
a0894974ff | ||
|
|
7281a72fab | ||
|
|
a759028f67 | ||
|
|
dc3c718b37 | ||
|
|
dd345afb38 | ||
|
|
d27563cb14 | ||
|
|
eb70e31cc7 | ||
|
|
71a20f7c98 | ||
|
|
c52833bf16 | ||
|
|
446fd5a43a | ||
|
|
36011c7f6d | ||
|
|
8161d621bb | ||
|
|
6765a7549b | ||
|
|
a3733b53d3 | ||
|
|
92d33d06df | ||
|
|
99dfd3368d | ||
|
|
c2c96f9b10 | ||
|
|
b17781bbc6 | ||
|
|
636d6d724d | ||
|
|
24e7280178 | ||
|
|
cf395e1754 | ||
|
|
d77fdc8f82 | ||
|
|
78fb7cbf4d | ||
|
|
1ecd9727f0 | ||
|
|
53867aa9d8 | ||
|
|
0466ce2f98 | ||
|
|
076037531f | ||
|
|
af435e0a02 | ||
|
|
d71bbcbc98 | ||
|
|
ee653b8a26 | ||
|
|
1cac7d1a65 | ||
|
|
6aa6778ac4 | ||
|
|
6c1355be96 | ||
|
|
44411674eb | ||
|
|
2c305d5b29 | ||
|
|
3c9344a1a9 | ||
|
|
d5addec147 | ||
|
|
9861abf8ff | ||
|
|
885c2fff70 | ||
|
|
4356e893a1 | ||
|
|
611f9ab0a8 | ||
|
|
b230f32624 | ||
|
|
14b231119d | ||
|
|
a34d331841 | ||
|
|
c314385280 | ||
|
|
79006ef66d | ||
|
|
3f5b5b758d | ||
|
|
102946ee03 | ||
|
|
37a0c9140a | ||
|
|
c7f450723f | ||
|
|
ff992e093b | ||
|
|
69e6e7b17c | ||
|
|
aa98049877 | ||
|
|
3b269ac0a0 | ||
|
|
fa9b587426 | ||
|
|
082371a160 | ||
|
|
d7a4cb14ff | ||
|
|
1e44c811f3 | ||
|
|
10781c2a9c | ||
|
|
7f03f46882 | ||
|
|
f9872ab26f | ||
|
|
edc0007e74 | ||
|
|
5a186d5942 | ||
|
|
a0a089f6a4 | ||
|
|
3efeee446e | ||
|
|
969edb9e0b | ||
|
|
f54220d951 | ||
|
|
0283815ee1 | ||
|
|
a64b1deaa6 | ||
|
|
d26ba961d0 | ||
|
|
37183532ae | ||
|
|
8b784fb1ca | ||
|
|
0063d94927 | ||
|
|
6e50e59386 | ||
|
|
d34eabe286 | ||
|
|
2308b3a2a6 | ||
|
|
b63503db04 | ||
|
|
14a24f35bf | ||
|
|
4c283d5f8d | ||
|
|
31ac0574ad | ||
|
|
816d7bba1f | ||
|
|
a27aa68dd3 | ||
|
|
cf073138b2 | ||
|
|
f247294d73 | ||
|
|
ecab0d6bb0 | ||
|
|
04472352ae | ||
|
|
a799a4c57f | ||
|
|
de0f3747ee | ||
|
|
bf46f4c997 | ||
|
|
70802d519f | ||
|
|
9aaec7cffb | ||
|
|
5247416735 | ||
|
|
349067a6ab | ||
|
|
cd6dfcbef4 | ||
|
|
db167cd438 | ||
|
|
fd5403cb40 | ||
|
|
417869f845 | ||
|
|
32b56c56ba | ||
|
|
f9f2e1cc4e | ||
|
|
11bd80b31e | ||
|
|
3931544ef3 | ||
|
|
9e14042e57 | ||
|
|
96547a810e | ||
|
|
aee0978d50 | ||
|
|
c59a4f12db | ||
|
|
b8de478f51 | ||
|
|
e920a00eba | ||
|
|
e01750020d | ||
|
|
f061befb33 | ||
|
|
c152c59084 | ||
|
|
545a0e59df | ||
|
|
7bbc617019 | ||
|
|
1d9134d044 | ||
|
|
5c5e38fc0e | ||
|
|
a17ea73636 | ||
|
|
371e5d0665 | ||
|
|
2dc49ea866 | ||
|
|
6299da2047 | ||
|
|
2522bff565 | ||
|
|
73d23a9405 | ||
|
|
df5548a754 | ||
|
|
6f24a61d84 | ||
|
|
76501f4f57 | ||
|
|
d85aa35ffb | ||
|
|
8c055f873f | ||
|
|
cf881396b5 | ||
|
|
67aeccc254 | ||
|
|
b6ab34fc98 | ||
|
|
abbaaaa6e7 | ||
|
|
81d8c5d519 | ||
|
|
2a3d19a9df | ||
|
|
30f3f9fcda |
No files matched your search
@@ -14,7 +14,6 @@
|
||||
/input/input_conf.h
|
||||
/tags
|
||||
/TAGS
|
||||
/video/out/gl_video_shaders.h
|
||||
/video/out/x11_icon.inc
|
||||
/demux/ebml_defs.c
|
||||
/demux/ebml_types.h
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ language: c
|
||||
|
||||
os:
|
||||
- linux
|
||||
# - osx
|
||||
- osx
|
||||
env:
|
||||
matrix:
|
||||
- LIBAV=libav-stable
|
||||
@@ -47,7 +47,7 @@ notifications:
|
||||
email: false
|
||||
irc:
|
||||
channels:
|
||||
- "irc.freenode.org#mpv-player-dev"
|
||||
- "irc.freenode.org#mpv-devel"
|
||||
on_success: change
|
||||
on_failure: always
|
||||
|
||||
|
||||
@@ -25,6 +25,15 @@ API changes
|
||||
|
||||
::
|
||||
|
||||
--- mpv 0.9.0 is released ---
|
||||
1.17 - add MPV_FORMAT_BYTE_ARRAY
|
||||
1.16 - add mpv_opengl_cb_report_flip()
|
||||
- introduce mpv_opengl_cb_draw() and deprecate mpv_opengl_cb_render()
|
||||
1.15 - mpv_initialize() will now load config files. This requires setting
|
||||
the "config" and "config-dir" options. In particular, it will load
|
||||
mpv.conf.
|
||||
- minor backwards-compatible change to the "seek" and "screenshot"
|
||||
commands (new flag syntax, old additional args deprecated)
|
||||
--- mpv 0.8.0 is released ---
|
||||
1.14 - add mpv_wait_async_requests()
|
||||
- the --msg-level option changes its native type from a flat string to
|
||||
|
||||
@@ -46,9 +46,8 @@ public:
|
||||
void render()
|
||||
{
|
||||
QOpenGLFramebufferObject *fbo = framebufferObject();
|
||||
int vp[4] = {0, 0, fbo->width(), fbo->height()};
|
||||
window->resetOpenGLState();
|
||||
mpv_opengl_cb_render(mpv_gl, fbo->handle(), vp);
|
||||
mpv_opengl_cb_draw(mpv_gl, fbo->handle(), fbo->width(), fbo->height());
|
||||
window->resetOpenGLState();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -39,15 +39,13 @@ void MpvRenderer::paint()
|
||||
{
|
||||
window->resetOpenGLState();
|
||||
|
||||
// Render to the whole window.
|
||||
int vp[4] = {0, 0, size.width(), -size.height()};
|
||||
|
||||
// This uses 0 as framebuffer, which indicates that mpv will render directly
|
||||
// to the frontbuffer. Note that mpv will always switch framebuffers
|
||||
// explicitly. Some QWindow setups (such as using QQuickWidget) actually
|
||||
// want you to render into a FBO in the beforeRendering() signal, and this
|
||||
// code won't work there.
|
||||
mpv_opengl_cb_render(mpv_gl, 0, vp);
|
||||
// The negation is used for rendering with OpenGL's flipped coordinates.
|
||||
mpv_opengl_cb_draw(mpv_gl, 0, size.width(), -size.height());
|
||||
|
||||
window->resetOpenGLState();
|
||||
}
|
||||
@@ -96,6 +94,8 @@ void MpvObject::handleWindowChanged(QQuickWindow *win)
|
||||
this, &MpvObject::sync, Qt::DirectConnection);
|
||||
connect(win, &QQuickWindow::sceneGraphInvalidated,
|
||||
this, &MpvObject::cleanup, Qt::DirectConnection);
|
||||
connect(win, &QQuickWindow::frameSwapped,
|
||||
this, &MpvObject::swapped, Qt::DirectConnection);
|
||||
win->setClearBeforeRendering(false);
|
||||
}
|
||||
|
||||
@@ -110,6 +110,11 @@ void MpvObject::sync()
|
||||
renderer->size = window()->size() * window()->devicePixelRatio();
|
||||
}
|
||||
|
||||
void MpvObject::swapped()
|
||||
{
|
||||
mpv_opengl_cb_report_flip(mpv_gl, 0);
|
||||
}
|
||||
|
||||
void MpvObject::cleanup()
|
||||
{
|
||||
if (renderer) {
|
||||
|
||||
@@ -37,6 +37,7 @@ public:
|
||||
public slots:
|
||||
void command(const QVariant& params);
|
||||
void sync();
|
||||
void swapped();
|
||||
void cleanup();
|
||||
signals:
|
||||
void onUpdate();
|
||||
|
||||
@@ -79,6 +79,7 @@ export PATH=/opt/mxe/usr/bin/:$PATH
|
||||
cd ..
|
||||
git clone https://github.com/mpv-player/mpv.git
|
||||
cd mpv
|
||||
python ./bootstrap.py
|
||||
DEST_OS=win32 TARGET=i686-w64-mingw32.static ./waf configure
|
||||
# Or, if 64 bit version,
|
||||
# DEST_OS=win32 TARGET=x86_64-w64-mingw32.static ./waf configure
|
||||
|
||||
+5
-2
@@ -4,8 +4,8 @@ How to contribute
|
||||
General
|
||||
-------
|
||||
|
||||
The main contact for mpv development is IRC, specifically #mpv-player
|
||||
and #mpv-player-dev on Freenode.
|
||||
The main contact for mpv development is IRC, specifically #mpv
|
||||
and #mpv-devel on Freenode.
|
||||
|
||||
Sending patches
|
||||
---------------
|
||||
@@ -14,6 +14,9 @@ Sending patches
|
||||
``git format-patch``. diffs posted as pastebins (especially if the http link
|
||||
returns HTML) just cause extra work for everyone, because they lack commit
|
||||
message and authorship information.
|
||||
- When creating pull requests, be sure to test your changes. If you didn't, please
|
||||
say so in the pull request message.
|
||||
|
||||
- Write informative commit messages. Use present tense to describe the
|
||||
situation with the patch applied, and past tense for the situation before
|
||||
the change.
|
||||
|
||||
+33
-18
@@ -63,7 +63,7 @@ Available filters are:
|
||||
Set AVOptions on the SwrContext or AVAudioResampleContext. These should
|
||||
be documented by FFmpeg or Libav.
|
||||
|
||||
``lavcac3enc[=tospdif[:bitrate[:minchn]]]``
|
||||
``lavcac3enc[=tospdif[:bitrate[:minch]]]``
|
||||
Encode multi-channel audio to AC-3 at runtime using libavcodec. Supports
|
||||
16-bit native-endian input format, maximum 6 channels. The output is
|
||||
big-endian when outputting a raw AC-3 stream, native-endian when
|
||||
@@ -92,8 +92,8 @@ Available filters are:
|
||||
:5ch: 448
|
||||
:6ch: 448
|
||||
|
||||
``minchn=<n>``
|
||||
If the input channel number is less than ``<minchn>``, the filter will
|
||||
``minch=<n>``
|
||||
If the input channel number is less than ``<minch>``, the filter will
|
||||
detach itself (default: 3).
|
||||
|
||||
``sweep[=speed]``
|
||||
@@ -225,14 +225,21 @@ Available filters are:
|
||||
automatically up- and downmix standard channel layouts.
|
||||
|
||||
``format=format:srate:channels:out-format:out-srate:out-channels``
|
||||
Force a specific audio format/configuration without actually changing the
|
||||
audio data. Keep in mind that the filter system might auto-insert actual
|
||||
conversion filters before or after this filter if needed.
|
||||
Does not do any format conversion itself. Rather, it may cause the
|
||||
filter system to insert necessary conversion filters before or after this
|
||||
filter if needed. It is primarily useful for controlling the audio format
|
||||
going into other filters. To specify the format for audio output, see
|
||||
``--audio-format``, ``--audio-samplerate``, and ``--audio-channels``. This
|
||||
filter is able to force a particular format, whereas ``--audio-*``
|
||||
may be overridden by the ao based on output compatibility.
|
||||
|
||||
All parameters are optional. The first 3 parameters restrict what the filter
|
||||
accepts as input. The ``out-`` parameters change the audio format, without
|
||||
actually doing a conversion. The data will be 'reinterpreted' by the
|
||||
filters or audio outputs following this filter.
|
||||
accepts as input. They will therefore cause conversion filters to be
|
||||
inserted before this one. The ``out-`` parameters tell the filters or audio
|
||||
outputs following this filter how to interpret the data without actually
|
||||
doing a conversion. Setting these will probably just break things unless you
|
||||
really know you want this for some reason, such as testing or dealing with
|
||||
broken media.
|
||||
|
||||
``<format>``
|
||||
Force conversion to this format. Use ``--af=format=format=help`` to get
|
||||
@@ -252,14 +259,9 @@ Available filters are:
|
||||
|
||||
``<out-channels>``
|
||||
|
||||
See also ``--audio-format``, ``--audio-samplerate``, and
|
||||
``--audio-channels`` for related options. Keep in mind that
|
||||
``--audio-channels`` does not actually force the number of
|
||||
channels in most cases, while this filter can do this.
|
||||
|
||||
*NOTE*: this filter used to be named ``force``. Also, unlike the old
|
||||
``format`` filter, this does not do any actual conversion anymore.
|
||||
Conversion is done by other, automatically inserted filters.
|
||||
*NOTE*: this filter used to be named ``force``. The old ``format`` filter
|
||||
used to do conversion itself, unlike this one which lets the filter system
|
||||
handle the conversion.
|
||||
|
||||
``convert24``
|
||||
Filter for internal use only. Converts between 24-bit and 32-bit sample
|
||||
@@ -601,6 +603,20 @@ Available filters are:
|
||||
Changing playback speed would change pitch, leaving audio tempo at
|
||||
1.2x.
|
||||
|
||||
``rubberband``
|
||||
High quality pitch correction with librubberband. This can be used in place
|
||||
of ``scaletempo``, and will be used to adjust audio pitch when playing
|
||||
at speed different from normal.
|
||||
|
||||
This filter has a number of sub-options. You can list them with
|
||||
``mpv --af=rubberband=help``. This will also show the default values
|
||||
for each option. The options are not documented here, because they are
|
||||
merely passed to librubberband. Look at the librubberband documentation
|
||||
to learn what each option does:
|
||||
http://breakfastquay.com/rubberband/code-doc/classRubberBand_1_1RubberBandStretcher.html
|
||||
(The mapping of the mpv rubberband filter sub-option names and values to
|
||||
those of librubberband follows a simple pattern: ``"Option" + Name + Value``.)
|
||||
|
||||
``lavfi=graph``
|
||||
Filter audio using FFmpeg's libavfilter.
|
||||
|
||||
@@ -615,4 +631,3 @@ Available filters are:
|
||||
|
||||
``o=<string>``
|
||||
AVOptions.
|
||||
|
||||
+25
-15
@@ -55,6 +55,14 @@ Available audio output drivers are:
|
||||
Allow output of non-interleaved formats (if the audio decoder uses
|
||||
this format). Currently disabled by default, because some popular
|
||||
ALSA plugins are utterly broken with non-interleaved formats.
|
||||
``ingore-chmap``
|
||||
Don't read or set the channel map of the ALSA device - only request the
|
||||
required number of channels, and then pass the audio as-is to it. This
|
||||
option most likely should not be used. It can be useful for debugging,
|
||||
or for static setups with a specially engineered ALSA configuration (in
|
||||
this case you should always force the same layout with ``--audio-channels``,
|
||||
or it will work only for files which use the layout implicit to your
|
||||
ALSA device).
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -99,8 +107,10 @@ Available audio output drivers are:
|
||||
``--audio-device`` to select the device (use ``--audio-device=help``
|
||||
to get a list of all devices and their mpv name).
|
||||
|
||||
You can also try
|
||||
`Using the upmix plugin <https://github.com/mpv-player/mpv/wiki/ALSA:-Surround-Sound-and-Upmixing>`_.
|
||||
You can also try `using the upmix plugin <http://git.io/vfuAy>`_.
|
||||
This setup enables multichannel audio on the ``default`` device
|
||||
with automatic upmixing with shared access, so playing stereo
|
||||
and multichannel audio at the same time will work as expected.
|
||||
|
||||
``oss``
|
||||
OSS audio output driver
|
||||
@@ -294,19 +304,19 @@ Available audio output drivers are:
|
||||
``wasapi``
|
||||
Audio output to the Windows Audio Session API.
|
||||
|
||||
``device=<id>``
|
||||
Uses the requested endpoint instead of the system's default audio
|
||||
endpoint. Both the number and the ID String are valid; the ID String
|
||||
is guaranteed to not change unless the driver is uninstalled.
|
||||
|
||||
Also supports searching active devices by name. If more than one
|
||||
device matches the name, refuses loading it.
|
||||
|
||||
To get a list of the valid devices, give ``help`` as the id. The
|
||||
list is the same as the ``list`` suboption, but stops the player
|
||||
initialization.
|
||||
``exclusive``
|
||||
Requests exclusive, direct hardware access. By definition prevents
|
||||
sound playback of any other program until mpv exits.
|
||||
``list``
|
||||
Lists all audio endpoints (output devices) present in the system.
|
||||
``device=<id>``
|
||||
Uses the requested endpoint instead of the system's default audio
|
||||
endpoint. Both an ordinal number (0,1,2,...) and the GUID
|
||||
String are valid; the GUID string is guaranteed to not change
|
||||
unless the driver is uninstalled.
|
||||
|
||||
Also supports searching active devices by human readable name. If more
|
||||
than one device matches the name, refuses loading it.
|
||||
|
||||
This option is mostly deprecated in favour of the more general
|
||||
``--audio-device`` option. That said, ``--audio-device=help`` will give
|
||||
a list of valid device GUIDs (prefixed with ``wasapi/``), as well as
|
||||
their human readable names, which should work here.
|
||||
+113
-35
@@ -86,11 +86,11 @@ List of Input Commands
|
||||
disabling default bindings, without disabling all bindings with
|
||||
``--no-input-default-bindings``.
|
||||
|
||||
``seek <seconds> [relative|absolute|absolute-percent|- [default-precise|exact|keyframes]]``
|
||||
``seek <seconds> [relative|absolute|absolute-percent|exact|keyframes]``
|
||||
Change the playback position. By default, seeks by a relative amount of
|
||||
seconds.
|
||||
|
||||
The second argument sets the seek mode:
|
||||
The second argument consists of flags controlling the seek mode:
|
||||
|
||||
relative (default)
|
||||
Seek relative to current position (a negative value seeks backwards).
|
||||
@@ -98,16 +98,19 @@ List of Input Commands
|
||||
Seek to a given time.
|
||||
absolute-percent
|
||||
Seek to a given percent position.
|
||||
|
||||
The third argument defines how exact the seek is:
|
||||
|
||||
default-precise (default)
|
||||
Follow the default behavior as set by ``--hr-seek``, which by default
|
||||
does imprecise seeks (like ``keyframes``).
|
||||
exact
|
||||
Always do exact/hr/precise seeks (slow).
|
||||
keyframes
|
||||
Always restart playback at keyframe boundaries (fast).
|
||||
exact
|
||||
Always do exact/hr/precise seeks (slow).
|
||||
|
||||
Multiple flags can be combined, e.g.: ``absolute+keyframes``.
|
||||
|
||||
By default, ``keyframes`` is used for relative seeks, and ``exact`` is used
|
||||
for absolute seeks.
|
||||
|
||||
Before mpv 0.9, the ``keyframes`` and ``exact`` flags had to be passed as
|
||||
3rd parameter (essentially using a space instead of ``+``). The 3rd
|
||||
parameter is still parsed, but is considered deprecated.
|
||||
|
||||
``revert_seek [mode]``
|
||||
Undoes the ``seek`` command, and some other commands that seek (but not
|
||||
@@ -170,16 +173,12 @@ List of Input Commands
|
||||
Save the contents of the mpv window. Typically scaled, with OSD and
|
||||
subtitles. The exact behavior depends on the selected video output, and
|
||||
if no support is available, this will act like ``video``.
|
||||
|
||||
Second argument:
|
||||
|
||||
<single> (default)
|
||||
Take a single screenshot.
|
||||
<each-frame>
|
||||
Take a screenshot each frame. Issue this command again to stop taking
|
||||
screenshots. Note that you should disable frame-dropping when using
|
||||
this mode - or you might receive duplicate images in cases when a
|
||||
frame was dropped.
|
||||
frame was dropped. This flag can be combined with the other flags,
|
||||
e.g. ``video+each-frame``.
|
||||
|
||||
``screenshot_to_file "<filename>" [subtitles|video|window]``
|
||||
Take a screenshot and save it to a given file. The format of the file will
|
||||
@@ -188,8 +187,7 @@ List of Input Commands
|
||||
|
||||
The second argument is like the first argument to ``screenshot``.
|
||||
|
||||
This command tries to never overwrite files. If the file already exists,
|
||||
it fails.
|
||||
If the file already exists, it's overwritten.
|
||||
|
||||
Like all input command parameters, the filename is subject to property
|
||||
expansion as described in `Property Expansion`_.
|
||||
@@ -400,6 +398,21 @@ List of Input Commands
|
||||
``audio_reload [<id>]``
|
||||
Reload the given audio tracks. See ``sub_reload`` command.
|
||||
|
||||
``rescan_external_files [<mode>]``
|
||||
Rescan external files according to the current ``--sub-auto`` and
|
||||
``--audio-file-auto`` settings. This can be used to auto-load external
|
||||
files *after* the file was loaded.
|
||||
|
||||
The ``mode`` argument is one of the following:
|
||||
|
||||
<keep-selection> (default)
|
||||
Do not change current track selections.
|
||||
|
||||
<reselect>
|
||||
Select the default audio and video streams, which typically selects
|
||||
external files with highest preference. (The implementation is not
|
||||
perfect, and could be improved on request.)
|
||||
|
||||
|
||||
Input Commands that are Possibly Subject to Change
|
||||
--------------------------------------------------
|
||||
@@ -618,6 +631,15 @@ Input Commands that are Possibly Subject to Change
|
||||
unseekable streams that are going out of sync.
|
||||
This command might be changed or removed in the future.
|
||||
|
||||
``screenshot_raw [subtitles|video|window]``
|
||||
Return a screenshot in memory. This can be used only through the client
|
||||
API. The MPV_FORMAT_NODE_MAP returned by this command has the ``w``, ``h``,
|
||||
``stride`` fields set to obvious contents. A ``format`` field is set to
|
||||
``bgr0`` by default. This format is organized as ``B8G8R8X8`` (where ``B``
|
||||
is the LSB). The contents of the padding ``X`` is undefined. The ``data``
|
||||
field is of type MPV_FORMAT_BYTE_ARRAY with the actual image data. The image
|
||||
is freed as soon as the result node is freed.
|
||||
|
||||
Undocumented commands: ``tv_last_channel`` (TV/DVB only),
|
||||
``get_property`` (deprecated), ``ao_reload`` (experimental/internal).
|
||||
|
||||
@@ -906,6 +928,10 @@ Property list
|
||||
a BD or DVD. Use the ``discnav menu`` command to actually enter or leave
|
||||
menu mode.
|
||||
|
||||
``disc-mouse-on-button``
|
||||
Return ``yes`` when the mouse cursor is located on a button, or ``no``
|
||||
when cursor is outside of any button for disc navigation.
|
||||
|
||||
``chapters``
|
||||
Number of chapters.
|
||||
|
||||
@@ -1064,6 +1090,11 @@ Property list
|
||||
guess is very unreliable, and often the property will not be available
|
||||
at all, even if data is buffered.
|
||||
|
||||
``demuxer-cache-time``
|
||||
Approximate time of video buffered in the demuxer, in seconds. Same as
|
||||
``demuxer-cache-duration`` but returns the last timestamp of bufferred
|
||||
data in demuxer.
|
||||
|
||||
``demuxer-cache-idle``
|
||||
Returns ``yes`` if the demuxer is idle, which means the demuxer cache is
|
||||
filled to the requested amount, and is currently not reading more data.
|
||||
@@ -1109,9 +1140,6 @@ Property list
|
||||
``audio-codec``
|
||||
Audio codec selected for decoding.
|
||||
|
||||
``audio-bitrate``
|
||||
Audio bitrate. This is probably a very bad guess in most cases.
|
||||
|
||||
``audio-samplerate``
|
||||
Audio samplerate.
|
||||
|
||||
@@ -1139,17 +1167,18 @@ Property list
|
||||
``field-dominance`` (RW)
|
||||
See ``--field-dominance``
|
||||
|
||||
``colormatrix`` (RW)
|
||||
See ``--colormatrix``.
|
||||
``colormatrix`` (R)
|
||||
Redirects to ``video-params/colormatrix``. This parameter (as well as
|
||||
similar ones) can be overridden with the ``format`` video filter.
|
||||
|
||||
``colormatrix-input-range`` (RW)
|
||||
See ``--colormatrix-input-range``.
|
||||
``colormatrix-input-range`` (R)
|
||||
See ``colormatrix``.
|
||||
|
||||
``colormatrix-output-range`` (RW)
|
||||
See ``--colormatrix-output-range``.
|
||||
``colormatrix-output-range`` (R)
|
||||
See ``colormatrix``.
|
||||
|
||||
``colormatrix-primaries`` (RW)
|
||||
See ``--colormatrix-primaries``.
|
||||
``colormatrix-primaries`` (R)
|
||||
See ``colormatrix``.
|
||||
|
||||
``ontop`` (RW)
|
||||
See ``--ontop``.
|
||||
@@ -1208,9 +1237,6 @@ Property list
|
||||
``video-codec``
|
||||
Video codec selected for decoding.
|
||||
|
||||
``video-bitrate``
|
||||
Video bitrate (a bad guess).
|
||||
|
||||
``width``, ``height``
|
||||
Video size. This uses the size of the video as decoded, or if no video
|
||||
frame has been decoded yet, the (possibly incorrect) container indicated
|
||||
@@ -1255,6 +1281,9 @@ Property list
|
||||
``video-params/primaries``
|
||||
The primaries in use as string. (Exact values subject to change.)
|
||||
|
||||
``video-params/gamma``
|
||||
The gamma function in use as string. (Exact values subject to change.)
|
||||
|
||||
``video-params/chroma-location``
|
||||
Chroma location as string. (Exact values subject to change.)
|
||||
|
||||
@@ -1325,6 +1354,13 @@ Property list
|
||||
Names of the displays that the mpv window covers. On X11, these
|
||||
are the xrandr names (LVDS1, HDMI1, DP1, VGA1, etc.).
|
||||
|
||||
``display-fps``
|
||||
The refresh rate of the current display. Currently, this is the lowest FPS
|
||||
of any display covered by the video, as retrieved by the underlying system
|
||||
APIs (e.g. xrandr on X11). It is not the measured FPS. It's not necessarily
|
||||
available on all platforms. Note that any of the listed facts may change
|
||||
any time without a warning.
|
||||
|
||||
``video-aspect`` (RW)
|
||||
Video aspect, see ``--video-aspect``.
|
||||
|
||||
@@ -1381,8 +1417,11 @@ Property list
|
||||
``sub-scale`` (RW)
|
||||
Subtitle font size multiplier.
|
||||
|
||||
``ass-use-margins`` (RW)
|
||||
See ``--ass-use-margins``.
|
||||
``ass-force-margins`` (RW)
|
||||
See ``--ass-force-margins``.
|
||||
|
||||
``sub-use-margins`` (RW)
|
||||
See ``--sub-use-margins``.
|
||||
|
||||
``ass-vsfilter-aspect-compat`` (RW)
|
||||
See ``--ass-vsfilter-aspect-compat``.
|
||||
@@ -1486,6 +1525,13 @@ Property list
|
||||
``track-list/N/selected``
|
||||
``yes`` if the track is currently decoded, ``no`` otherwise.
|
||||
|
||||
``track-list/N/ff-index``
|
||||
The stream index as usually used by the FFmpeg utilities. Note that
|
||||
this can be potentially wrong if a demuxer other than libavformat
|
||||
(``--demuxer=lavf``) is used. For mkv files, the index will usually
|
||||
match even if the default (builtin) demuxer is used, but there is
|
||||
no hard guarantee.
|
||||
|
||||
When querying the property with the client API using ``MPV_FORMAT_NODE``,
|
||||
or with Lua ``mp.get_property_native``, this will return a mpv_node with
|
||||
the following contents:
|
||||
@@ -1607,7 +1653,7 @@ Property list
|
||||
whether the video window is visible. If the ``--force-window`` option is
|
||||
used, this is usually always returns ``yes``.
|
||||
|
||||
``packet-video-bitrate``, ``packet-audio-bitrate``, ``packet-sub-bitrate``
|
||||
``video-bitrate``, ``audio-bitrate``, ``sub-bitrate``
|
||||
Bitrate values calculated on the packet level. This works by dividing the
|
||||
bit size of all packets between two keyframes by their presentation
|
||||
timestamp distance. (This uses the timestamps are stored in the file, so
|
||||
@@ -1616,8 +1662,29 @@ Property list
|
||||
bitrate. To make the property more UI friendly, updates to these properties
|
||||
are throttled in a certain way.
|
||||
|
||||
The unit is bits per second. OSD formatting turns these values in kilobits
|
||||
(or megabits, if appropriate), which can be prevented by using the
|
||||
raw property value, e.g. with ``${=video-bitrate}``.
|
||||
|
||||
Note that the accuracy of these properties is influenced by a few factors.
|
||||
If the underlying demuxer rewrites the packets on demuxing (done for some
|
||||
file formats), the bitrate might be slightly off. If timestamps are bad
|
||||
or jittery (like in Matroska), even constant bitrate streams might show
|
||||
fluctuating bitrate.
|
||||
|
||||
How exactly these values are calculated might change in the future.
|
||||
|
||||
In earlier versions of mpv, these properties returned a static (but bad)
|
||||
guess using a completely different method.
|
||||
|
||||
``packet-video-bitrate``, ``packet-audio-bitrate``, ``packet-sub-bitrate``
|
||||
Old and deprecated properties for ``video-bitrate``, ``audio-bitrate``,
|
||||
``sub-bitrate``. They behave exactly the same, but return a value in
|
||||
kilobits. Also, they don't have any OSD formatting, though the same can be
|
||||
achieved with e.g. ``${=video-bitrate}``.
|
||||
|
||||
These properties shouldn't be used anymore.
|
||||
|
||||
``audio-device-list``
|
||||
Return the list of discovered audio devices. This is mostly for use with
|
||||
the client API, and reflects what ``--audio-device=help`` with the command
|
||||
@@ -1639,6 +1706,13 @@ Property list
|
||||
human readable free form text. The description is an empty string if none
|
||||
was received.
|
||||
|
||||
The special entry with the name set to ``auto`` selects the default audio
|
||||
output driver and the default device.
|
||||
|
||||
The property can be watched with the property observation mechanism in
|
||||
the client API and in Lua scripts. (Technically, change notification is
|
||||
enabled the first time this property is read.)
|
||||
|
||||
``audio-device`` (RW)
|
||||
Set the audio device. This directly reads/writes the ``--audio-device``
|
||||
option, but on write accesses, the audio output will be scheduled for
|
||||
@@ -1662,6 +1736,10 @@ Property list
|
||||
Return the audio device selected by the AO driver (only implemented for
|
||||
some drivers: currently only ``coreaudio``).
|
||||
|
||||
``working-directory``
|
||||
Return the working directory of the mpv process. Can be useful for JSON IPC
|
||||
users, because the command line player usually works with relative paths.
|
||||
|
||||
``mpv-version``
|
||||
Return the mpv version/copyright string. Depending on how the binary was
|
||||
built, it might contain either a release version, or just a git hash.
|
||||
|
||||
@@ -79,6 +79,9 @@ mpv will also send events to clients with JSON messages of the following form:
|
||||
where ``event_name`` is the name of the event. Additional event-specific fields
|
||||
can also be present. See `List of events`_ for a list of all supported events.
|
||||
|
||||
All commands, replies, and events are separated from each other with a line
|
||||
break character (``\n``).
|
||||
|
||||
If the first character (after skipping whitespace) is not ``{``, the command
|
||||
will be interpreted as non-JSON text command, as they are used in input.conf
|
||||
(or ``mpv_command_string()`` in the client API). Additionally, line starting
|
||||
|
||||
+25
-1
@@ -326,7 +326,6 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
the timer is re-added after the function fn is run.
|
||||
|
||||
Returns a timer object. The timer object provides the following methods:
|
||||
|
||||
``stop()``
|
||||
Disable the timer. Does nothing if the timer is already disabled.
|
||||
This will remember the current elapsed time when stopping, so that
|
||||
@@ -357,6 +356,23 @@ The ``mp`` module is preloaded, although it can be loaded manually with
|
||||
(``true``). This value is used when the timer expires (but before
|
||||
the timer callback function fn is run).
|
||||
|
||||
Note that these are method, and you have to call them using ``:`` instead
|
||||
of ``.`` (Refer to http://www.lua.org/manual/5.2/manual.html#3.4.9 .)
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
|
||||
seconds = 0
|
||||
timer = mp.add_periodic_timer(1, function()
|
||||
print("called every second")
|
||||
# stop it after 10 seconds
|
||||
seconds = seconds + 1
|
||||
if seconds >= 10 then
|
||||
timer:kill()
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
``mp.get_opt(key)``
|
||||
Return a setting from the ``--script-opts`` option. It's up to the user and
|
||||
@@ -623,6 +639,14 @@ strictly part of the guaranteed API.
|
||||
trailing text is returned as 3rd return value. (The 3rd return value is
|
||||
always there, but with ``trail`` set, no error is raised.)
|
||||
|
||||
``utils.format_json(v)``
|
||||
Format the given Lua table (or value) as a JSON string and return it. On
|
||||
error, returns ``nil, error``. (Errors usually only happen on value types
|
||||
incompatible with JSON.)
|
||||
|
||||
The argument value uses similar conventions as ``mp.set_property_native()``
|
||||
to distinguish empty objects and arrays.
|
||||
|
||||
``utils.to_string(v)``
|
||||
Turn the given value into a string. Formats tables and their contents. This
|
||||
doesn't do anything special; it is only needed because Lua is terrible.
|
||||
|
||||
+68
-24
@@ -32,8 +32,10 @@ INTERACTIVE CONTROL
|
||||
===================
|
||||
|
||||
mpv has a fully configurable, command-driven control layer which allows you
|
||||
to control mpv using keyboard, mouse, joystick or remote control (with
|
||||
LIRC). See the ``--input-`` options for ways to customize it.
|
||||
to control mpv using keyboard, mouse, or remote control (there is no
|
||||
LIRC support - configure remotes as input devices instead).
|
||||
|
||||
See the ``--input-`` options for ways to customize it.
|
||||
|
||||
Keyboard Control
|
||||
----------------
|
||||
@@ -135,6 +137,11 @@ l
|
||||
Ctrl + and Ctrl -
|
||||
Adjust audio delay by +/- 0.1 seconds.
|
||||
|
||||
u
|
||||
Switch between applying no style overrides to SSA/ASS subtitles, and
|
||||
overriding them almost completely with the normal subtitle style. See
|
||||
``--ass-style-override`` for more info.
|
||||
|
||||
V
|
||||
Toggle subtitle VSFilter aspect compatibility mode. See
|
||||
``--ass-vsfilter-aspect-compat`` for more info.
|
||||
@@ -269,14 +276,16 @@ Shells may actually strip some quotes from the string passed to the commandline,
|
||||
so the example quotes the string twice, ensuring that mpv recieves the ``"``
|
||||
quotes.
|
||||
|
||||
The ``[...]`` from of quotes wraps everything between ``[`` and ``]``. It's
|
||||
The ``[...]`` form of quotes wraps everything between ``[`` and ``]``. It's
|
||||
useful with shells that don't interpret these characters in the middle of
|
||||
an argument (like bash).
|
||||
an argument (like bash). These quotes are balanced (since mpv 0.9.0): the ``[``
|
||||
and ``]`` nest, and the quote terminates on the last ``]`` that has no matching
|
||||
``[`` within the string. (For example, ``[a[b]c]`` results in ``a[b]c``.)
|
||||
|
||||
A special kind of string-escaping intended for use with external scripts and
|
||||
programs is started with ``%``.
|
||||
The fixed-length quoting syntax is intended for use with external
|
||||
scripts and programs.
|
||||
|
||||
It has the following format::
|
||||
It is started with ``%`` and has the following format::
|
||||
|
||||
%n%string_of_length_n
|
||||
|
||||
@@ -312,7 +321,8 @@ console controls. (Which makes it suitable for playing data piped to stdin.)
|
||||
|
||||
For paths passed to suboptions, the situation is further complicated by the
|
||||
need to escape special characters. To work this around, the path can be
|
||||
additionally wrapped in the ``%n%string_of_length_n`` syntax (see above).
|
||||
additionally wrapped in the fixed-length syntax, e.g. ``%n%string_of_length_n``
|
||||
(see above).
|
||||
|
||||
Some mpv options interpret paths starting with ``~``. Currently, the prefix
|
||||
``~~/`` expands to the mpv configuration directory (usually ``~/.config/mpv/``).
|
||||
@@ -368,7 +378,8 @@ Location and Syntax
|
||||
You can put all of the options in configuration files which will be read every
|
||||
time mpv is run. The system-wide configuration file 'mpv.conf' is in your
|
||||
configuration directory (e.g. ``/etc/mpv`` or ``/usr/local/etc/mpv``), the
|
||||
user-specific one is ``~/.config/mpv/mpv.conf``.
|
||||
user-specific one is ``~/.config/mpv/mpv.conf``. For details and platform
|
||||
specifics see the `FILES`_ section.
|
||||
User-specific options override system-wide options and options given on the
|
||||
command line override either. The syntax of the configuration files is
|
||||
``option=<value>``; everything after a *#* is considered a comment. Options
|
||||
@@ -390,10 +401,10 @@ Escaping spaces and special characters
|
||||
This is done like with command line options. The shell is not involved here,
|
||||
but option values still need to be quoted as a whole if it contains certain
|
||||
characters like spaces. A config entry can be quoted with ``"`` and ``'``,
|
||||
as well as with the ``%n%`` syntax mentioned before. This is like passing
|
||||
the exact contents of the quoted string as command line option. C-style escapes
|
||||
are currently _not_ interpreted on this level, although some options to this
|
||||
manually. (This is a mess and should probably be changed at some point.)
|
||||
as well as with the fixed-length syntax (``%n%``) mentioned before. This is like
|
||||
passing the exact contents of the quoted string as command line option. C-style
|
||||
escapes are currently _not_ interpreted on this level, although some options to
|
||||
this manually. (This is a mess and should probably be changed at some point.)
|
||||
|
||||
Putting Command Line Options into the Configuration File
|
||||
--------------------------------------------------------
|
||||
@@ -468,11 +479,8 @@ A screenshot will usually contain the unscaled video contents at the end of the
|
||||
video filter chain and subtitles. By default, ``S`` takes screenshots without
|
||||
subtitles, while ``s`` includes subtitles.
|
||||
|
||||
The ``screenshot`` video filter is not required when using a recommended GUI
|
||||
video output driver. It should normally not be added to the config file, as
|
||||
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.)
|
||||
Unlike with MPlayer, the ``screenshot`` video filter is not required. This
|
||||
filter was never required in mpv, and has been removed.
|
||||
|
||||
TERMINAL STATUS LINE
|
||||
====================
|
||||
@@ -510,10 +518,9 @@ listed.
|
||||
rendering is too slow. Also can be incremented on "hiccups" and when the video
|
||||
frame couldn't be displayed on time. (``vo-drop-frame-count`` property.)
|
||||
If the decoder drops frames, the number of decoder-dropped frames is appended
|
||||
to the display as well, e.g.: ``Dropped: 4/34``. This should almost never
|
||||
happen, unless decoder-framedropping is enabled with one of the
|
||||
``--framedrop`` options, the stream contains errors, or a weird codec is in
|
||||
use. (``drop-frame-count`` property.)
|
||||
to the display as well, e.g.: ``Dropped: 4/34``. This happens only if
|
||||
decoder-framedropping is enabled with the ``--framedrop`` options.
|
||||
(``drop-frame-count`` property.)
|
||||
- Cache state, e.g. ``Cache: 2s+134KB``. Visible if the stream cache is enabled.
|
||||
The first value shows the amount of video buffered in the demuxer in seconds,
|
||||
the second value shows *additional* data buffered in the stream cache in
|
||||
@@ -603,6 +610,39 @@ PROTOCOLS
|
||||
``memory://data``
|
||||
Use the ``data`` part as source data.
|
||||
|
||||
PSEUDO GUI MODE
|
||||
===============
|
||||
|
||||
mpv has no official GUI, other than the OSC (`ON SCREEN CONTROLLER`_), which
|
||||
is not a full GUI and is not meant to be. However, to compensate for the lack
|
||||
of expected GUI behavior, mpv will in some cases start with some settings
|
||||
changed to behave slightly more like a GUI mode.
|
||||
|
||||
Currently this happens only in the following cases:
|
||||
|
||||
- if started using the ``mpv.desktop`` file on Linux (e.g. started from menus
|
||||
or file associations provided by desktop environments)
|
||||
- if started from explorer.exe on Windows (technically, if it was started on
|
||||
Windows, and all of the stdout/stderr/stdin handles are unset)
|
||||
- manually adding ``--profile=pseudo-gui`` to the command line
|
||||
|
||||
This mode implicitly adds ``--profile=pseudo-gui`` to the command line, with
|
||||
the ``pseudo-gui`` profile being predefined with the following contents:
|
||||
|
||||
::
|
||||
|
||||
[pseudo-gui]
|
||||
terminal=no
|
||||
force-window=yes
|
||||
idle=once
|
||||
|
||||
This follows the mpv config file format. To customize pseudo-GUI mode, you can
|
||||
put your own ``pseudo-gui`` profile into your ``mpv.conf``. This profile will
|
||||
enhance the default profile, rather than overwrite it.
|
||||
|
||||
The profile always overrides other settings in ``mpv.conf``.
|
||||
|
||||
|
||||
.. include:: options.rst
|
||||
|
||||
.. include:: ao.rst
|
||||
@@ -757,11 +797,15 @@ input command can take an exit code: in this case, that exit code is returned.
|
||||
FILES
|
||||
=====
|
||||
|
||||
For Windows-specifics, see `FILES ON WINDOWS`_ section.
|
||||
|
||||
``/usr/local/etc/mpv/mpv.conf``
|
||||
mpv system-wide settings (depends on ``--prefix`` passed to configure)
|
||||
mpv system-wide settings (depends on ``--prefix`` passed to configure - mpv
|
||||
in default configuration will use ``/usr/local/etc/mpv/`` as config
|
||||
directory, while most Linux distributions will set it to ``/etc/mpv/``).
|
||||
|
||||
``~/.config/mpv/mpv.conf``
|
||||
mpv user settings
|
||||
mpv user settings (see `CONFIGURATION FILES`_ section)
|
||||
|
||||
``~/.config/mpv/input.conf``
|
||||
key bindings (see `INPUT.CONF`_ section)
|
||||
|
||||
+130
-144
@@ -181,6 +181,7 @@ Playback Control
|
||||
file, such as a chapter seek, but not for relative seeks like
|
||||
the default behavior of arrow keys (default).
|
||||
:yes: Use precise seeks whenever possible.
|
||||
:always: Same as ``yes`` (for compatibility).
|
||||
|
||||
``--hr-seek-demuxer-offset=<seconds>``
|
||||
This option exists to work around failures to do precise seeks (as in
|
||||
@@ -439,7 +440,8 @@ Program Behavior
|
||||
Enable the youtube-dl hook-script. It will look at the input URL, and will
|
||||
play the video located on the website. This works with many streaming sites,
|
||||
not just the one that the script is named after. This requires a recent
|
||||
version of youtube-dl to be installed on the system. (Enabled by default.)
|
||||
version of youtube-dl to be installed on the system. (Enabled by default,
|
||||
except when the client API / libmpv is used.)
|
||||
|
||||
If the script can't do anything with an URL, it will do nothing.
|
||||
|
||||
@@ -454,6 +456,18 @@ Program Behavior
|
||||
``bestvideo+bestaudio``.
|
||||
(Default: ``best``)
|
||||
|
||||
``--ytdl-raw-options=<key>=<value>[,<key>=<value>[,...]]``
|
||||
Pass arbitraty options to youtube-dl. Parameter and argument should be
|
||||
passed as a key-value pair. Options without argument must include ``=``.
|
||||
|
||||
There is no sanity checking so it's possible to break things (i.e.
|
||||
passing invalid parameters to youtube-dl).
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
``--ytdl-raw-options=username=user,password=pass``
|
||||
``--ytdl-raw-options=force-ipv6=``
|
||||
|
||||
Video
|
||||
-----
|
||||
|
||||
@@ -541,7 +555,8 @@ Video
|
||||
:vaapi: requires ``--vo=opengl`` or ``--vo=vaapi`` (Linux with Intel GPUs only)
|
||||
:vaapi-copy: copies video back into system RAM (Linux with Intel GPUs only)
|
||||
:vda: requires ``--vo=opengl`` (OS X only)
|
||||
:dxva2-copy: copies video back to system RAM (Windows only) (experimental)
|
||||
:dxva2-copy: copies video back to system RAM (Windows only)
|
||||
:rpi: requires ``--vo=rpi`` (Raspberry Pi only - default if available)
|
||||
|
||||
``auto`` tries to automatically enable hardware decoding using the first
|
||||
available method. This still depends what VO you are using. For example,
|
||||
@@ -552,8 +567,7 @@ Video
|
||||
|
||||
The ``vaapi-copy`` mode allows you to use vaapi with any VO. Because
|
||||
this copies the decoded video back to system RAM, it's likely less efficient
|
||||
than the ``vaapi`` mode. But there are reports that this is actually faster
|
||||
as well, and avoids many issues with ``vaapi``.
|
||||
than the ``vaapi`` mode.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -614,7 +628,7 @@ Video
|
||||
|
||||
This option is disabled if the ``--no-keepaspect`` option is used.
|
||||
|
||||
``--video-rotate=<0-359|no>``
|
||||
``--video-rotate=<0-360|no>``
|
||||
Rotate the video clockwise, in degrees. Currently supports 90° steps only.
|
||||
If ``no`` is given, the video is never rotated, even if the file has
|
||||
rotation metadata. (The rotation value is added to the rotation metadata,
|
||||
@@ -801,7 +815,7 @@ Audio
|
||||
-----
|
||||
|
||||
``--audio-pitch-correction=<yes|no>``
|
||||
If this is enabled (default), playing with a speed higher than normal
|
||||
If this is enabled (default), playing with a speed different from normal
|
||||
automatically inserts the ``scaletempo`` audio filter. For details, see
|
||||
audio filter section.
|
||||
|
||||
@@ -873,8 +887,7 @@ Audio
|
||||
delay the audio, and negative values delay the video.
|
||||
|
||||
``--no-audio``
|
||||
Do not play sound. With some demuxers this may not work. In those cases
|
||||
you can try ``--ao=null`` instead.
|
||||
Do not play sound.
|
||||
|
||||
``--mute=<auto|yes|no>``
|
||||
Set startup audio mute status. ``auto`` (default) will not change the mute
|
||||
@@ -903,11 +916,14 @@ Audio
|
||||
``--ad-lavc-ac3drc=<level>``
|
||||
Select the Dynamic Range Compression level for AC-3 audio streams.
|
||||
``<level>`` is a float value ranging from 0 to 1, where 0 means no
|
||||
compression and 1 (which is the default) means full compression (make loud
|
||||
passages more silent and vice versa). Values up to 2 are also accepted, but
|
||||
compression (which is the default) and 1 means full compression (make loud
|
||||
passages more silent and vice versa). Values up to 6 are also accepted, but
|
||||
are purely experimental. This option only shows an effect if the AC-3 stream
|
||||
contains the required range compression information.
|
||||
|
||||
The standard mandates that DRC is enabled by default, but mpv (and some
|
||||
other players) ignore this for the sake of better audio quality.
|
||||
|
||||
``--ad-lavc-downmix=<yes|no>``
|
||||
Whether to request audio channel downmixing from the decoder (default: yes).
|
||||
Some decoders, like AC-3, AAC and DTS, can remix audio on decoding. The
|
||||
@@ -967,8 +983,9 @@ Audio
|
||||
|
||||
``--audio-display=<no|attachment>``
|
||||
Setting this option to ``attachment`` (default) will display image
|
||||
attachments when playing audio files. It will display the first image
|
||||
found, and additional images are available as video tracks.
|
||||
attachments (e.g. album cover art) when playing audio files. It will
|
||||
display the first image found, and additional images are available as
|
||||
video tracks.
|
||||
|
||||
Setting this option to ``no`` disables display of video entirely when
|
||||
playing audio files.
|
||||
@@ -1157,13 +1174,22 @@ Subtitles
|
||||
doesn't covert the window fully, e.g. because screen aspect and window
|
||||
aspect mismatch (and the player adds black bars).
|
||||
|
||||
Default: yes.
|
||||
|
||||
This option is misnamed. The difference to the confusingly similar sounding
|
||||
option ``--sub-scale-by-window`` is that ``--sub-scale-with-window`` still
|
||||
scales with the approximate window size, while the other option disables
|
||||
this scaling.
|
||||
|
||||
Affects plain text subtitles only (or ASS if ``--ass-style-override`` is
|
||||
set high enough).
|
||||
|
||||
``--ass-scale-with-window=<yes|no>``
|
||||
Like ``--sub-scale-with-window``, but affects subtitles in ASS format only.
|
||||
Like ``--sub-scale``, this can break ASS subtitles.
|
||||
|
||||
Default: no.
|
||||
|
||||
``--embeddedfonts``, ``--no-embeddedfonts``
|
||||
Use fonts embedded in Matroska container files and ASS scripts (default:
|
||||
enabled). These fonts can be used for SSA/ASS subtitle rendering.
|
||||
@@ -1244,12 +1270,23 @@ Subtitles
|
||||
:signfs: like ``yes``, but apply ``--sub-scale`` only to signs
|
||||
:no: Render subtitles as forced by subtitle scripts.
|
||||
:force: Try to force the font style as defined by the ``--sub-text-*``
|
||||
options. Requires a modified libass, can break rendering easily.
|
||||
Probably more reliable than ``force``.
|
||||
options. Can break rendering easily.
|
||||
|
||||
``--ass-use-margins``
|
||||
``--ass-force-margins``
|
||||
Enables placing toptitles and subtitles in black borders when they are
|
||||
available.
|
||||
available, if the subtitles are in the ASS format.
|
||||
|
||||
Default: no.
|
||||
|
||||
``--sub-use-margins``
|
||||
Enables placing toptitles and subtitles in black borders when they are
|
||||
available, if the subtitles are in a plain text format (or ASS if
|
||||
``--ass-style-override`` is set high enough).
|
||||
|
||||
Default: yes.
|
||||
|
||||
Renamed from ``--ass-use-margins``. To place ASS subtitles in the borders
|
||||
too (like the old option did), also add ``--ass-force-margins``.
|
||||
|
||||
``--ass-vsfilter-aspect-compat=<yes|no>``
|
||||
Stretch SSA/ASS subtitles when playing anamorphic videos for compatibility
|
||||
@@ -1687,19 +1724,13 @@ Window
|
||||
(depending on the video aspect ratio, the width or height will be
|
||||
larger than 500 in order to keep the aspect ratio the same).
|
||||
|
||||
``--autosync=<factor>``
|
||||
Gradually adjusts the A/V sync based on audio delay measurements.
|
||||
Specifying ``--autosync=0``, the default, will cause frame timing to be
|
||||
based entirely on audio delay measurements. Specifying ``--autosync=1``
|
||||
will do the same, but will subtly change the A/V correction algorithm. An
|
||||
uneven video framerate in a video which plays fine with ``--no-audio`` can
|
||||
often be helped by setting this to an integer value greater than 1. The
|
||||
higher the value, the closer the timing will be to ``--no-audio``. Try
|
||||
``--autosync=30`` to smooth out problems with sound drivers which do not
|
||||
implement a perfect audio delay measurement. With this value, if large A/V
|
||||
sync offsets occur, they will only take about 1 or 2 seconds to settle
|
||||
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.
|
||||
``--window-scale=<factor>``
|
||||
Resize the video window to a multiple (or fraction) of the video size. This
|
||||
option is applied before ``--autofit`` and other options are applied (so
|
||||
they override this option).
|
||||
|
||||
For example, ``--window-scale=0.5`` would show the window at half the
|
||||
video size.
|
||||
|
||||
``--cursor-autohide=<number|no|always>``
|
||||
Make mouse cursor automatically hide after given number of milliseconds.
|
||||
@@ -1911,6 +1942,10 @@ Disc Devices
|
||||
``--cdda-skip=<yes|no>``
|
||||
(Never) accept imperfect data reconstruction.
|
||||
|
||||
``--cdda-cdtext=<yes|no>``
|
||||
Print CD text. This is disabled by default, because it ruins perfomance
|
||||
with CD-ROM drives for unknown reasons.
|
||||
|
||||
``--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
|
||||
@@ -1954,101 +1989,6 @@ Equalizer
|
||||
negative of the image with this option. Not supported by all video output
|
||||
drivers.
|
||||
|
||||
``--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
|
||||
BT.709 for HD video. (This is done by default.) Using incorrect color space
|
||||
results in slightly under or over saturated and shifted colors.
|
||||
|
||||
The color space conversion is additionally influenced by the related
|
||||
options --colormatrix-input-range and --colormatrix-output-range.
|
||||
|
||||
These options are not always supported. Different video outputs provide
|
||||
varying degrees of support. The ``opengl`` and ``vdpau`` video output
|
||||
drivers usually offer full support. The ``xv`` output can set the color
|
||||
space if the system video driver supports it, but not input and output
|
||||
levels. The ``scale`` video filter can configure color space and input
|
||||
levels, but only if the output format is RGB (if the video output driver
|
||||
supports RGB output, you can force this with ``-vf scale,format=rgba``).
|
||||
|
||||
If this option is set to ``auto`` (which is the default), the video's
|
||||
color space flag will be used. If that flag is unset, the color space
|
||||
will be selected automatically. This is done using a simple heuristic that
|
||||
attempts to distinguish SD and HD video. If the video is larger than
|
||||
1279x576 pixels, BT.709 (HD) will be used; otherwise BT.601 (SD) is
|
||||
selected.
|
||||
|
||||
Available color spaces are:
|
||||
|
||||
:auto: automatic selection (default)
|
||||
:BT.601: ITU-R BT.601 (SD)
|
||||
:BT.709: ITU-R BT.709 (HD)
|
||||
:BT.2020-NCL: ITU-R BT.2020 non-constant luminance system
|
||||
:BT.2020-CL: ITU-R BT.2020 constant luminance system
|
||||
:SMPTE-240M: SMPTE-240M
|
||||
|
||||
``--colormatrix-input-range=<color-range>``
|
||||
YUV color levels used with YUV to RGB conversion. This option is only
|
||||
necessary when playing broken files which do not follow standard color
|
||||
levels or which are flagged wrong. If the video does not specify its
|
||||
color range, it is assumed to be limited range.
|
||||
|
||||
The same limitations as with --colormatrix apply.
|
||||
|
||||
Available color ranges are:
|
||||
|
||||
:auto: automatic selection (normally limited range) (default)
|
||||
:limited: limited range (16-235 for luma, 16-240 for chroma)
|
||||
:full: full range (0-255 for both luma and chroma)
|
||||
|
||||
``--colormatrix-output-range=<color-range>``
|
||||
RGB color levels used with YUV to RGB conversion. Normally, output devices
|
||||
such as PC monitors use full range color levels. However, some TVs and
|
||||
video monitors expect studio RGB levels. Providing full range output to a
|
||||
device expecting studio level input results in crushed blacks and whites,
|
||||
the reverse in dim gray blacks and dim whites.
|
||||
|
||||
The same limitations as with ``--colormatrix`` apply.
|
||||
|
||||
Available color ranges are:
|
||||
|
||||
:auto: automatic selection (equals to full range) (default)
|
||||
:limited: limited range (16-235 per component), studio levels
|
||||
:full: full range (0-255 per component), PC levels
|
||||
|
||||
.. note::
|
||||
|
||||
It is advisable to use your graphics driver's color range option
|
||||
instead, if available.
|
||||
|
||||
``--colormatrix-primaries=<primaries>``
|
||||
RGB primaries the source file was encoded with. Normally this should be set
|
||||
in the file header, but when playing broken or mistagged files this can be
|
||||
used to override the setting. By default, when unset, BT.709 is used for
|
||||
all files except those tagged with a BT.2020 color matrix.
|
||||
|
||||
This option only affects video output drivers that perform color
|
||||
management, for example ``opengl`` with the ``srgb`` or ``icc-profile``
|
||||
suboptions set.
|
||||
|
||||
If this option is set to ``auto`` (which is the default), the video's
|
||||
primaries flag will be used. If that flag is unset, the color space will
|
||||
be selected automatically, using the following heuristics: If the
|
||||
``--colormatrix`` is set or determined as BT.2020 or BT.709, the
|
||||
corresponding primaries are used. Otherwise, if the video height is
|
||||
exactly 576 (PAL), BT.601-625 is used. If it's exactly 480 or 486 (NTSC),
|
||||
BT.601-525 is used. If the video resolution is anything else, BT.709 is
|
||||
used.
|
||||
|
||||
Available primaries are:
|
||||
|
||||
:auto: automatic selection (default)
|
||||
:BT.601-525: ITU-R BT.601 (SD) 525-line systems (NTSC, SMPTE-C)
|
||||
:BT.601-625: ITU-R BT.601 (SD) 625-line systems (PAL, SECAM)
|
||||
:BT.709: ITU-R BT.709 (HD) (same primaries as sRGB)
|
||||
:BT.2020: ITU-R BT.2020 (UHD)
|
||||
|
||||
|
||||
Demuxer
|
||||
-------
|
||||
|
||||
@@ -2076,6 +2016,12 @@ Demuxer
|
||||
``--demuxer-lavf-format=<name>``
|
||||
Force a specific libavformat demuxer.
|
||||
|
||||
``--demuxer-lavf-hacks=<yes|no>``
|
||||
By default, some formats will be handled differently from other formats
|
||||
by explicitly checking for them. Most of these compensate for weird or
|
||||
imperfect behavior from libavformat demuxers. Passing ``no`` disables
|
||||
these. For debugging and testing only.
|
||||
|
||||
``--demuxer-lavf-genpts-mode=<no|lavf>``
|
||||
Mode for deriving missing packet PTS values from packet DTS. ``lavf``
|
||||
enables libavformat's ``genpts`` option. ``no`` disables it. This used
|
||||
@@ -2160,6 +2106,18 @@ Demuxer
|
||||
will be slower (especially when playing over http), or that behavior with
|
||||
broken files is much worse. So don't use this option.
|
||||
|
||||
``--demuxer-mkv-fix-timestamps=<yes|no>``
|
||||
Fix rounded Matroska timestamps (enabled by default). Matroska usually
|
||||
stores timestamps rounded to milliseconds. This means timestamps jitter
|
||||
by some amount around the intended timestamp. mpv can correct the timestamps
|
||||
based on the framerate value stored in the file: the timestamp is rounded
|
||||
to the next frame (according to the framerate), unless the new timestamp
|
||||
would deviate more than 1ms from the old one. This should undo the rounding
|
||||
done by the muxer.
|
||||
|
||||
(The allowed deviation can be less than 1ms if the file uses a non-standard
|
||||
timecode scale.)
|
||||
|
||||
``--demuxer-rawaudio-channels=<value>``
|
||||
Number of channels (or channel layout) if ``--demuxer=rawaudio`` is used
|
||||
(default: stereo).
|
||||
@@ -2208,7 +2166,7 @@ Demuxer
|
||||
|
||||
``--demuxer-readahead-secs=<seconds>``
|
||||
If ``--demuxer-thread`` is enabled, this controls how much the demuxer
|
||||
should buffer ahead in seconds (default: 0.2). As long as no packet has
|
||||
should buffer ahead in seconds (default: 1). As long as no packet has
|
||||
a timestamp difference higher than the readahead amount relative to the
|
||||
last packet returned to the decoder, the demuxer keeps reading.
|
||||
|
||||
@@ -2286,6 +2244,9 @@ Input
|
||||
get replies or events. Use ``--input-unix-socket`` for something
|
||||
bi-directional. On MS Windows, JSON commands are not available.
|
||||
|
||||
This can also specify a direct file descriptor with ``fd://N`` (UNIX only).
|
||||
In this case, JSON replies will be written if the FD is writable.
|
||||
|
||||
See also ``--slave-broken``.
|
||||
|
||||
.. note::
|
||||
@@ -2318,19 +2279,6 @@ Input
|
||||
driver. Necessary to use the OSC, or to select the buttons in DVD menus.
|
||||
Support depends on the VO in use.
|
||||
|
||||
``--input-joystick``, ``--no-input-joystick``
|
||||
Enable/disable joystick support. Disabled by default.
|
||||
|
||||
``--input-js-dev``
|
||||
Specifies the joystick device to use (default: ``/dev/input/js0``).
|
||||
|
||||
``--input-lirc``, ``--no-input-lirc``
|
||||
Enable/disable LIRC support. Enabled by default.
|
||||
|
||||
``--input-lirc-conf=<filename>``
|
||||
(LIRC only)
|
||||
Specifies a configuration file for LIRC (default: ``~/.lircrc``).
|
||||
|
||||
``--input-media-keys=<yes|no>``
|
||||
(OS X only)
|
||||
Enable/disable media keys support. Enabled by default (except for libmpv).
|
||||
@@ -2469,6 +2417,9 @@ OSD
|
||||
``--osd-blur=<0..20.0>``, ``--sub-text-blur=<0..20.0>``
|
||||
Gaussian blur factor. 0 means no blur applied (default).
|
||||
|
||||
``--osd-bold=<yes|no>``, ``--sub-text-bold=<yes|no>``
|
||||
Format text on bold.
|
||||
|
||||
``--osd-border-color=<color>``, ``--sub-text-border-color=<color>``
|
||||
See ``--osd-color``. Color used for the OSD/sub font border.
|
||||
|
||||
@@ -2513,7 +2464,8 @@ OSD
|
||||
- ``--osd-color='#C0808080'`` set OSD to 50% gray with 75% alpha
|
||||
|
||||
``--osd-fractions``
|
||||
Show OSD times with fractions of seconds.
|
||||
Show OSD times with fractions of seconds (in millisecond precision). Useful
|
||||
to see the exact timestamp of a video frame.
|
||||
|
||||
``--osd-level=<0-3>``
|
||||
Specifies which mode the OSD should start in.
|
||||
@@ -2542,6 +2494,17 @@ OSD
|
||||
|
||||
Default: 22.
|
||||
|
||||
``--osd-align-x=<left|center|right>``, ``--sub-text-align-x=...``
|
||||
Control to which corner of the screen OSD or text subtitles should be
|
||||
aligned to (default: ``center`` for subs, ``left`` for OSD).
|
||||
|
||||
Never applied to ASS subtitles, except in ``--no-sub-ass`` mode. Likewise,
|
||||
this does not apply to image subtitles.
|
||||
|
||||
``--osd-align-y=<top|center|bottom>`` ``--sub-text-align-y=...``
|
||||
Vertical position (default: ``bottom`` for subs, ``top`` for OSD).
|
||||
Details see ``--osd-align-x``.
|
||||
|
||||
``--osd-scale=<factor>``
|
||||
OSD font size multiplier, multiplied with ``--osd-font-size`` value.
|
||||
|
||||
@@ -2594,6 +2557,13 @@ Screenshot
|
||||
:jpg: JPEG (default)
|
||||
:jpeg: JPEG (same as jpg, but with .jpeg file ending)
|
||||
|
||||
``--screenshot-tag-colorspace=<yes|no>``
|
||||
Tag screenshots with the appropriate colorspace.
|
||||
|
||||
Note that not all formats are supported.
|
||||
|
||||
Default: ``yes``.
|
||||
|
||||
``--screenshot-template=<template>``
|
||||
Specify the filename template used to save screenshots. The template
|
||||
specifies the filename without file extension, and can contain format
|
||||
@@ -2892,7 +2862,7 @@ TV
|
||||
Use _ for spaces in names (or play with quoting ;-) ). The channel
|
||||
names will then be written using OSD, and the slave commands
|
||||
``tv_step_channel``, ``tv_set_channel`` and ``tv_last_channel``
|
||||
will be usable for a remote control (see LIRC). Not compatible with
|
||||
will be usable for a remote control. Not compatible with
|
||||
the ``frequency`` parameter.
|
||||
|
||||
.. note::
|
||||
@@ -3001,11 +2971,13 @@ TV
|
||||
Cache
|
||||
-----
|
||||
|
||||
``--cache=<kBytes|no|auto>``
|
||||
``--cache=<kBytes|yes|no|auto>``
|
||||
Set the size of the cache in kilobytes, disable it with ``no``, or
|
||||
automatically enable it if needed with ``auto`` (default: ``auto``).
|
||||
With ``auto``, the cache will usually be enabled for network streams,
|
||||
using the size set by ``--cache-default``.
|
||||
using the size set by ``--cache-default``. With ``yes``, the cache will
|
||||
always be enabled with the size set by ``--cache-default`` (unless the
|
||||
stream can not be cached, or ``--cache-default`` disables caching).
|
||||
|
||||
May be useful when playing files from slow media, but can also have
|
||||
negative effects, especially with file formats that require a lot of
|
||||
@@ -3018,7 +2990,7 @@ Cache
|
||||
because no space is reserved for seeking back yet.
|
||||
|
||||
``--cache-default=<kBytes|no>``
|
||||
Set the size of the cache in kilobytes (default: 25000 KB). Using ``no``
|
||||
Set the size of the cache in kilobytes (default: 150000 KB). Using ``no``
|
||||
will not automatically enable the cache e.g. when playing from a network
|
||||
stream. Note that using ``--cache`` will always override this option.
|
||||
|
||||
@@ -3091,7 +3063,7 @@ Cache
|
||||
``--cache-secs=<seconds>``
|
||||
How many seconds of audio/video to prefetch if the cache is active. This
|
||||
overrides the ``--demuxer-readahead-secs`` option if and only if the cache
|
||||
is enabled and the value is larger. (Default: 2.)
|
||||
is enabled and the value is larger. (Default: 10.)
|
||||
|
||||
``--cache-pause``, ``--no-cache-pause``
|
||||
Whether the player should automatically pause when the cache runs low,
|
||||
@@ -3272,6 +3244,20 @@ Miscellaneous
|
||||
``--mc=<seconds/frame>``
|
||||
Maximum A-V sync correction per frame (in seconds)
|
||||
|
||||
``--autosync=<factor>``
|
||||
Gradually adjusts the A/V sync based on audio delay measurements.
|
||||
Specifying ``--autosync=0``, the default, will cause frame timing to be
|
||||
based entirely on audio delay measurements. Specifying ``--autosync=1``
|
||||
will do the same, but will subtly change the A/V correction algorithm. An
|
||||
uneven video framerate in a video which plays fine with ``--no-audio`` can
|
||||
often be helped by setting this to an integer value greater than 1. The
|
||||
higher the value, the closer the timing will be to ``--no-audio``. Try
|
||||
``--autosync=30`` to smooth out problems with sound drivers which do not
|
||||
implement a perfect audio delay measurement. With this value, if large A/V
|
||||
sync offsets occur, they will only take about 1 or 2 seconds to settle
|
||||
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.
|
||||
|
||||
``--mf-fps=<value>``
|
||||
Framerate used when decoding from multiple PNG or JPEG files with ``mf://``
|
||||
(default: 1).
|
||||
|
||||
+142
-19
@@ -198,7 +198,7 @@ Available filters are:
|
||||
``<aspect>``
|
||||
Force an aspect ratio.
|
||||
|
||||
``format[=fmt[:outfmt]]``
|
||||
``format=fmt=<value>:colormatrix=<value>:...``
|
||||
Restricts the color space for the next filter without doing any conversion.
|
||||
Use together with the scale filter for a real conversion.
|
||||
|
||||
@@ -207,19 +207,148 @@ Available filters are:
|
||||
For a list of available formats, see ``format=fmt=help``.
|
||||
|
||||
``<fmt>``
|
||||
Format name, e.g. rgb15, bgr24, 420p, etc. (default: yuyv).
|
||||
Format name, e.g. rgb15, bgr24, 420p, etc. (default: don't change).
|
||||
``<outfmt>``
|
||||
Format name that should be substituted for the output. If this is not
|
||||
100% compatible with the ``<fmt>`` value, it will crash.
|
||||
Format name that should be substituted for the output. If they do not
|
||||
have the same bytes per pixel and chroma subsamplimg, it will fail.
|
||||
``<colormatrix>``
|
||||
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
|
||||
BT.709 for HD video. (This is done by default.) Using incorrect color space
|
||||
results in slightly under or over saturated and shifted colors.
|
||||
|
||||
.. admonition:: Examples
|
||||
These options are not always supported. Different video outputs provide
|
||||
varying degrees of support. The ``opengl`` and ``vdpau`` video output
|
||||
drivers usually offer full support. The ``xv`` output can set the color
|
||||
space if the system video driver supports it, but not input and output
|
||||
levels. The ``scale`` video filter can configure color space and input
|
||||
levels, but only if the output format is RGB (if the video output driver
|
||||
supports RGB output, you can force this with ``-vf scale,format=rgba``).
|
||||
|
||||
If this option is set to ``auto`` (which is the default), the video's
|
||||
color space flag will be used. If that flag is unset, the color space
|
||||
will be selected automatically. This is done using a simple heuristic that
|
||||
attempts to distinguish SD and HD video. If the video is larger than
|
||||
1279x576 pixels, BT.709 (HD) will be used; otherwise BT.601 (SD) is
|
||||
selected.
|
||||
|
||||
Available color spaces are:
|
||||
|
||||
:auto: automatic selection (default)
|
||||
:bt.601: ITU-R BT.601 (SD)
|
||||
:bt.709: ITU-R BT.709 (HD)
|
||||
:bt.2020-ncl: ITU-R BT.2020 non-constant luminance system
|
||||
:bt.2020-cl: ITU-R BT.2020 constant luminance system
|
||||
:smpte-240m: SMPTE-240M
|
||||
|
||||
``<colorlevels>``
|
||||
YUV color levels used with YUV to RGB conversion. This option is only
|
||||
necessary when playing broken files which do not follow standard color
|
||||
levels or which are flagged wrong. If the video does not specify its
|
||||
color range, it is assumed to be limited range.
|
||||
|
||||
The same limitations as with ``<colormatrix>`` apply.
|
||||
|
||||
Available color ranges are:
|
||||
|
||||
:auto: automatic selection (normally limited range) (default)
|
||||
:limited: limited range (16-235 for luma, 16-240 for chroma)
|
||||
:full: full range (0-255 for both luma and chroma)
|
||||
|
||||
``<outputlevels>``
|
||||
RGB color levels used with YUV to RGB conversion. Normally, output devices
|
||||
such as PC monitors use full range color levels. However, some TVs and
|
||||
video monitors expect studio RGB levels. Providing full range output to a
|
||||
device expecting studio level input results in crushed blacks and whites,
|
||||
the reverse in dim gray blacks and dim whites.
|
||||
|
||||
The same limitations as with ``<colormatrix>`` apply.
|
||||
|
||||
Available color ranges are:
|
||||
|
||||
:auto: automatic selection (equals to full range) (default)
|
||||
:limited: limited range (16-235 per component), studio levels
|
||||
:full: full range (0-255 per component), PC levels
|
||||
|
||||
.. note::
|
||||
|
||||
It is advisable to use your graphics driver's color range option
|
||||
instead, if available.
|
||||
|
||||
``<primaries>``
|
||||
RGB primaries the source file was encoded with. Normally this should be set
|
||||
in the file header, but when playing broken or mistagged files this can be
|
||||
used to override the setting.
|
||||
|
||||
This option only affects video output drivers that perform color
|
||||
management, for example ``opengl`` with the ``target-prim`` or
|
||||
``icc-profile`` suboptions set.
|
||||
|
||||
If this option is set to ``auto`` (which is the default), the video's
|
||||
primaries flag will be used. If that flag is unset, the color space will
|
||||
be selected automatically, using the following heuristics: If the
|
||||
``<colormatrix>`` is set or determined as BT.2020 or BT.709, the
|
||||
corresponding primaries are used. Otherwise, if the video height is
|
||||
exactly 576 (PAL), BT.601-625 is used. If it's exactly 480 or 486 (NTSC),
|
||||
BT.601-525 is used. If the video resolution is anything else, BT.709 is
|
||||
used.
|
||||
|
||||
Available primaries are:
|
||||
|
||||
:auto: automatic selection (default)
|
||||
:bt.601-525: ITU-R BT.601 (SD) 525-line systems (NTSC, SMPTE-C)
|
||||
:bt.601-625: ITU-R BT.601 (SD) 625-line systems (PAL, SECAM)
|
||||
:bt.709: ITU-R BT.709 (HD) (same primaries as sRGB)
|
||||
:bt.2020: ITU-R BT.2020 (UHD)
|
||||
:apple: Apple RGB
|
||||
:adobe: Adobe RGB (1998)
|
||||
:prophoto: ProPhoto RGB (ROMM)
|
||||
:cie1931: CIE 1931 RGB
|
||||
|
||||
``<gamma>``
|
||||
Gamma function the source file was encoded with. Normally this should be set
|
||||
in the file header, but when playing broken or mistagged files this can be
|
||||
used to override the setting.
|
||||
|
||||
This option only affects video output drivers that perform color management.
|
||||
|
||||
If this option is set to ``auto`` (which is the default), the gamma will
|
||||
be set to BT.1886 for YCbCr content, sRGB for RGB content and Linear for
|
||||
XYZ content.
|
||||
|
||||
Available gamma functions are:
|
||||
|
||||
:auto: automatic selection (default)
|
||||
:bt.1886: ITU-R BT.1886 (approximation of BT.601/BT.709/BT.2020 curve)
|
||||
:srgb: IEC 61966-2-4 (sRGB)
|
||||
:linear: Linear light
|
||||
:gamma1.8: Pure power curve (gamma 1.8)
|
||||
:gamma2.2: Pure power curve (gamma 2.2)
|
||||
:gamma2.8: Pure power curve (gamma 2.8)
|
||||
:prophoto: ProPhoto RGB (ROMM) curve
|
||||
|
||||
``<stereo-in>``
|
||||
Set the stereo mode the video is assumed to be encoded in. Takes the
|
||||
same values as the ``--video-stereo-mode`` option.
|
||||
|
||||
``<stereo-out>``
|
||||
Set the stereo mode the video should be displayed as. Takes the
|
||||
same values as the ``--video-stereo-mode`` option.
|
||||
|
||||
``<rotate>``
|
||||
Set the rotation the video is assumed to be encoded with in degrees.
|
||||
The special value ``-1`` uses the input format.
|
||||
|
||||
``<dw>``, ``<dh>``
|
||||
Set the display size. Note that setting the display size such that
|
||||
the video is scaled in both directions instead of just changing the
|
||||
aspect ratio is an implementation detail, and might change later.
|
||||
|
||||
``<dar>``
|
||||
Set the display aspect ratio of the video frame. This is a float,
|
||||
but values such as ``[16:9]`` can be passed too (``[...]`` for quoting
|
||||
to prevent the option parser from interpreting the ``:`` character).
|
||||
|
||||
====================== =====================
|
||||
Valid Invalid (will crash)
|
||||
====================== =====================
|
||||
``format=rgb24:bgr24`` ``format=rgb24:420p``
|
||||
``format=yuyv:uyvy``
|
||||
====================== =====================
|
||||
|
||||
``noformat[=fmt]``
|
||||
Restricts the color space for the next filter without doing any conversion.
|
||||
@@ -432,12 +561,6 @@ Available filters are:
|
||||
``show``
|
||||
Draw a rectangle showing the area defined by x/y/w/h.
|
||||
|
||||
``screenshot``
|
||||
Optional filter for screenshot support. This is only needed if the video
|
||||
output does not provide working direct screenshot support. Note that it is
|
||||
not always safe to insert this filter by default. See `TAKING SCREENSHOTS`_
|
||||
for details.
|
||||
|
||||
``sub=[=bottom-margin:top-margin]``
|
||||
Moves subtitle rendering to an arbitrary point in the filter chain, or force
|
||||
subtitle rendering in the video filter as opposed to using video output OSD
|
||||
@@ -445,9 +568,9 @@ Available filters are:
|
||||
|
||||
``<bottom-margin>``
|
||||
Adds a black band at the bottom of the frame. The SSA/ASS renderer can
|
||||
place subtitles there (with ``--ass-use-margins``).
|
||||
place subtitles there (with ``--sub-use-margins``).
|
||||
``<top-margin>``
|
||||
Black band on the top for toptitles (with ``--ass-use-margins``).
|
||||
Black band on the top for toptitles (with ``--sub-use-margins``).
|
||||
|
||||
.. admonition:: Examples
|
||||
|
||||
|
||||
+232
-99
@@ -308,36 +308,72 @@ Available video output drivers are:
|
||||
This filter corresponds to the old ``lanczos3`` alias if the default
|
||||
radius is used, while ``lanczos2`` corresponds to a radius of 2.
|
||||
|
||||
(This filter is an alias for ``sinc``-windowed ``sinc``)
|
||||
|
||||
``ewa_lanczos``
|
||||
Elliptic weighted average Lanczos scaling. Also known as Jinc.
|
||||
Relatively slow, but very good quality. The number of taps can
|
||||
be controlled with ``scale-radius``. Adding extra taps makes the
|
||||
Relatively slow, but very good quality. The radius can be
|
||||
controlled with ``scale-radius``. Increasing the radius makes the
|
||||
filter sharper but adds more ringing.
|
||||
|
||||
This filter supports antiringing (see ``scale-antiring``).
|
||||
(This filter is an alias for ``jinc``-windowed ``jinc``)
|
||||
|
||||
``ewa_lanczossharp``
|
||||
A slightly sharpened version of ewa_lanczos, preconfigured to use
|
||||
an ideal radius and parameter. If your hardware can run it, this is
|
||||
probably what you should use by default.
|
||||
|
||||
``mitchell``
|
||||
Mitchell-Netravali. The ``b`` and ``c`` parameters can be set with
|
||||
``scale-param1`` and ``scale-param2``. Both are set to 1/3 by default.
|
||||
This filter is very good at downscaling (see ``scale-down``).
|
||||
Mitchell-Netravali. The ``B`` and ``C`` parameters can be set with
|
||||
``scale-param1`` and ``scale-param2``. This filter is very good at
|
||||
downscaling (see ``dscale``).
|
||||
|
||||
``oversample``
|
||||
A version of nearest neighbour that (naively) oversamples pixels,
|
||||
so that pixels overlapping edges get linearly interpolated instead
|
||||
of rounded. This essentially removes the small imperfections and
|
||||
judder artifacts caused by nearest-neighbour interpolation, in
|
||||
exchange for adding some blur. This filter is good at temporal
|
||||
interpolation, and also known as "smoothmotion" (see ``tscale``).
|
||||
|
||||
There are some more filters, but most are not as useful. For a complete
|
||||
list, pass ``help`` as value, e.g.::
|
||||
|
||||
mpv --vo=opengl:scale=help
|
||||
|
||||
``scale-param1=<value>``
|
||||
Set filter parameters. Ignored if the filter is not tunable. These are
|
||||
unset by default, and use the filter specific default if applicable.
|
||||
``scale-param1=<value>``, ``scale-param2=<value>``
|
||||
Set filter parameters. Ignored if the filter is not tunable.
|
||||
Currently, this affects the following filter parameters:
|
||||
|
||||
``scale-param2=<value>``
|
||||
See ``scale-param1``.
|
||||
bcspline
|
||||
Spline parameters (``B`` and ``C``). Defaults to 0.5 for both.
|
||||
|
||||
``scale-radius=<r>``
|
||||
Set radius for filters listed below, must be a float number between 1.0
|
||||
and 16.0. Defaults to be 3.0 if not specified.
|
||||
gaussian
|
||||
Scale parameter (``t``). Increasing this makes the result blurrier.
|
||||
Defaults to 1.
|
||||
|
||||
``sinc``, ``lanczos``, ``ewa_lanczos``, ``blackman``, ``gaussian``
|
||||
sharpen3, sharpen5
|
||||
Sharpening strength. Increasing this makes the image sharper but
|
||||
adds more ringing and aliasing. Defaults to 0.5.
|
||||
|
||||
oversample
|
||||
Minimum distance to an edge before interpolation is used. Setting
|
||||
this to 0 will always interpolate edges, whereas setting it to 0.5
|
||||
will never interpolate, thus behaving as if the regular nearest
|
||||
neighbour algorithm was used. Defaults to 0.0.
|
||||
|
||||
``scale-blur=<value>``
|
||||
Kernel scaling factor (also known as a blur factor). Decreasing this
|
||||
makes the result sharper, increasing it makes it blurrier (default 0).
|
||||
If set to 0, the kernel's preferred blur factor is used. Note that
|
||||
setting this too low (eg. 0.5) leads to bad results. It's generally
|
||||
recommended to stick to values between 0.8 and 1.2.
|
||||
|
||||
``scale-radius=<value>``
|
||||
Set radius for filters listed below, must be a float number between 0.5
|
||||
and 16.0. Defaults to the filter's preferred radius if not specified.
|
||||
|
||||
``sinc`` and derivatives, ``jinc`` and derivatives, ``gaussian``, ``box`` and ``triangle``
|
||||
|
||||
Note that depending on filter implementation details and video scaling
|
||||
ratio, the radius that actually being used might be different
|
||||
@@ -349,7 +385,26 @@ Available video output drivers are:
|
||||
between 0.0 and 1.0. The default value of 0.0 disables antiringing
|
||||
entirely.
|
||||
|
||||
Note that this currently only affects ``ewa_lanczos``.
|
||||
Note that this doesn't affect the special filters ``bilinear``,
|
||||
``bicubic_fast`` or ``sharpen``.
|
||||
|
||||
``scale-window=<window>``
|
||||
(Advanced users only) Choose a custom windowing function for the kernel.
|
||||
Defaults to the filter's preferred window if unset. Use
|
||||
``scale-window=help`` to get a list of supported windowing functions.
|
||||
|
||||
``scale-wparam=<window>``
|
||||
(Advanced users only) Configure the parameter for the window function
|
||||
given by ``scale-window``. Ignored if the window is not tunable.
|
||||
Currently, this affects the following window parameters:
|
||||
|
||||
kaiser
|
||||
Window parameter (alpha). Defaults to 6.33.
|
||||
blackman
|
||||
Window parameter (alpha). Defaults to 0.16.
|
||||
gaussian
|
||||
Scale parameter (t). Increasing this makes the window wider.
|
||||
Defaults to 1.
|
||||
|
||||
``scaler-resizes-only``
|
||||
Disable the scaler if the video image is not resized. In that case,
|
||||
@@ -357,21 +412,6 @@ Available video output drivers are:
|
||||
will reproduce the source image perfectly if no scaling is performed.
|
||||
Note that this option never affects ``cscale``.
|
||||
|
||||
``srgb``
|
||||
Convert and color correct the output to sRGB before displaying it on
|
||||
the screen. This option enables ``linear-scaling``.
|
||||
|
||||
This option is equivalent to using ``icc-profile`` with an sRGB ICC
|
||||
profile, but it is implemented without a 3DLUT and does not require
|
||||
LittleCMS 2. If both ``srgb`` and ``icc-profile`` are present, the
|
||||
latter takes precedence, as they are somewhat redundant.
|
||||
|
||||
Note: When playing back BT.2020 content with this option enabled, out
|
||||
of gamut colors will be numerically clipped, which can potentially
|
||||
change the hue and/or luminance. If this is not desired, it is
|
||||
recommended to use ``icc-profile`` with an sRGB ICC profile instead,
|
||||
when playing back wide-gamut BT.2020 content.
|
||||
|
||||
``pbo``
|
||||
Enable use of PBOs. This is slightly faster, but can sometimes lead to
|
||||
sporadic and temporary image corruption (in theory, because reupload
|
||||
@@ -417,32 +457,59 @@ Available video output drivers are:
|
||||
debug OpenGL context (which does nothing with current graphics drivers
|
||||
as of this writing).
|
||||
|
||||
``interpolation``
|
||||
Reduce stuttering caused by mismatches in the video fps and display
|
||||
refresh rate (also known as judder).
|
||||
|
||||
This essentially attempts to interpolate the missing frames by
|
||||
convoluting the video along the temporal axis. The filter used can be
|
||||
controlled using the ``tscale`` setting.
|
||||
|
||||
Note that this relies on vsync to work, see ``swapinterval`` for more
|
||||
information.
|
||||
|
||||
``swapinterval=<n>``
|
||||
Interval in displayed frames between two buffer swaps.
|
||||
1 is equivalent to enable VSYNC, 0 to disable VSYNC. Defaults to 1 if
|
||||
not specified.
|
||||
|
||||
``cscale=<filter>``
|
||||
As ``scale``, but for interpolating chroma information. If the image
|
||||
is not subsampled, this option is ignored entirely. Note that the
|
||||
implementation is currently always done as a single pass, so using
|
||||
it with separable filters will result in slow performance for very
|
||||
little visible benefit.
|
||||
Note that this depends on proper OpenGL vsync support. On some platforms
|
||||
and drivers, this only works reliably when in fullscreen mode. It may
|
||||
also require driver-specific hacks if using multiple monitors, to
|
||||
ensure mpv syncs to the right one. Compositing window managers can
|
||||
also lead to bad results, as can missing or incorrect display FPS
|
||||
information (see ``--display-fps``).
|
||||
|
||||
``scale-down=<filter>``
|
||||
``dscale=<filter>``
|
||||
Like ``scale``, but apply these filters on downscaling instead. If this
|
||||
option is unset, the filter implied by ``scale`` will be applied.
|
||||
|
||||
``cscale-param1``, ``cscale-param2``, ``cscale-radius``, ``cscale-antiring``
|
||||
Set filter parameters and radius for ``cscale``.
|
||||
``cscale=<filter>``
|
||||
As ``scale``, but for interpolating chroma information. If the image
|
||||
is not subsampled, this option is ignored entirely.
|
||||
|
||||
See ``scale-param1``, ``scale-param2``, ``scale-radius`` and
|
||||
``scale-antiring``.
|
||||
``tscale=<filter>``
|
||||
The filter used for interpolating the temporal axis (frames). This is
|
||||
only used if ``interpolation`` is enabled. The only valid choices
|
||||
for ``tscale`` are separable convolution filters (use ``tscale=help``
|
||||
to get a list). The default is ``oversample``.
|
||||
|
||||
Note that the maximum supported filter radius is currently 3, and that
|
||||
using filters with larger radius may introduce issues when pausing or
|
||||
framestepping, proportional to the radius used. It is recommended to
|
||||
stick to a radius of 1 or 2.
|
||||
|
||||
``dscale-radius``, ``cscale-radius``, ``tscale-radius``, etc.
|
||||
Set filter parameters for ``dscale``, ``cscale`` and ``tscale``,
|
||||
respectively.
|
||||
|
||||
See the corresponding options for ``scale``.
|
||||
|
||||
``linear-scaling``
|
||||
Scale in linear light. This is automatically enabled if ``srgb``,
|
||||
``icc-profile`` or ``sigmoid-upscaling`` is set. It should only
|
||||
be used with a ``fbo-format`` that has at least 16 bit precision.
|
||||
Scale in linear light. This is automatically enabled if
|
||||
``target-prim``, ``target-trc``, ``icc-profile`` or
|
||||
``sigmoid-upscaling`` is set. It should only be used with a
|
||||
``fbo-format`` that has at least 16 bit precision.
|
||||
|
||||
``fancy-downscaling``
|
||||
When using convolution based filters, extend the filter size
|
||||
@@ -481,6 +548,17 @@ Available video output drivers are:
|
||||
|
||||
X11/GLX only.
|
||||
|
||||
``dwmflush=<no|windowed|yes>``
|
||||
Calls ``DwmFlush`` after swapping buffers on Windows (default: no).
|
||||
It also sets ``SwapInterval(0)`` to ignore the OpenGL timing. Values
|
||||
are: no (disabled), windowed (only in windowed mode), yes (also in
|
||||
full screen).
|
||||
This may help getting more consistent frame intervals, especially with
|
||||
high-fps clips - which might also reduce dropped frames. Typically a
|
||||
value of 1 should be enough since full screen may bypass the DWM.
|
||||
|
||||
Windows only.
|
||||
|
||||
``sw``
|
||||
Continue even if a software renderer is detected.
|
||||
|
||||
@@ -524,13 +602,67 @@ Available video output drivers are:
|
||||
0.8
|
||||
Pitch black room
|
||||
|
||||
``gamma-auto``
|
||||
Automatically corrects the gamma value depending on ambient lighting
|
||||
conditions (adding a gamma boost for dark rooms).
|
||||
|
||||
With ambient illuminance of 64lux, mpv will pick the 1.0 gamma value
|
||||
(no boost), and slightly increase the boost up until 0.8 for 16lux.
|
||||
|
||||
NOTE: Only implemented on OS X.
|
||||
|
||||
``target-prim=<value>``
|
||||
Specifies the primaries of the display. Video colors will be adapted
|
||||
to this colorspace if necessary. Valid values are:
|
||||
|
||||
auto
|
||||
Disable any adaptation (default)
|
||||
bt.470m
|
||||
ITU-R BT.470 M
|
||||
bt.601-525
|
||||
ITU-R BT.601 (525-line SD systems, eg. NTSC), SMPTE 170M/240M
|
||||
bt.601-625
|
||||
ITU-R BT.601 (625-line SD systems, eg. PAL/SECAM), ITU-R BT.470 B/G
|
||||
bt.709
|
||||
ITU-R BT.709 (HD), IEC 61966-2-4 (sRGB), SMPTE RP177 Annex B
|
||||
bt.2020
|
||||
ITU-R BT.2020 (UHD)
|
||||
apple
|
||||
Apple RGB
|
||||
adobe
|
||||
Adobe RGB (1998)
|
||||
prophoto
|
||||
ProPhoto RGB (ROMM)
|
||||
cie1931
|
||||
CIE 1931 RGB (not to be confused with CIE XYZ)
|
||||
|
||||
``target-trc=<value>``
|
||||
Specifies the transfer characteristics (gamma) of the display. Video
|
||||
colors will be adjusted to this curve. Valid values are:
|
||||
|
||||
auto
|
||||
Disable any adaptation (default)
|
||||
bt.1886
|
||||
ITU-R BT.1886 curve, without the brightness drop (approx. 1.961)
|
||||
srgb
|
||||
IEC 61966-2-4 (sRGB)
|
||||
linear
|
||||
Linear light output
|
||||
gamma1.8
|
||||
Pure power curve (gamma 1.8), also used for Apple RGB
|
||||
gamma2.2
|
||||
Pure power curve (gamma 2.2)
|
||||
gamma2.8
|
||||
Pure power curve (gamma 2.8), also used for BT.470-BG
|
||||
prophoto
|
||||
ProPhoto RGB (ROMM)
|
||||
|
||||
``icc-profile=<file>``
|
||||
Load an ICC profile and use it to transform linear RGB to screen output.
|
||||
Needs LittleCMS 2 support compiled in. This option overrides the ``srgb``
|
||||
property, as using both is somewhat redundant. It also enables
|
||||
Needs LittleCMS 2 support compiled in. This option overrides the
|
||||
``target-prim`` and ``target-trc`` options. It also enables
|
||||
``linear-scaling``.
|
||||
|
||||
|
||||
``icc-profile-auto``
|
||||
Automatically select the ICC display profile currently specified by
|
||||
the display settings of the operating system.
|
||||
@@ -544,9 +676,8 @@ Available video output drivers are:
|
||||
Its size depends on the ``3dlut-size``, and can be very big.
|
||||
|
||||
``icc-intent=<value>``
|
||||
Specifies the ICC Intent used for transformations between color spaces.
|
||||
This affects the rendering when using ``icc-profile`` or ``srgb`` and
|
||||
also affects the way DCP XYZ content gets converted to RGB.
|
||||
Specifies the ICC intent used for the color transformation (when using
|
||||
``icc-profile``).
|
||||
|
||||
0
|
||||
perceptual
|
||||
@@ -562,6 +693,28 @@ Available video output drivers are:
|
||||
Default is 128x256x64.
|
||||
Sizes must be a power of two, and 512 at most.
|
||||
|
||||
``blend-subtitles=<yes|video|no>``
|
||||
Blend subtitles directly onto upscaled video frames, before
|
||||
interpolation and/or color management (default: no). Enabling this
|
||||
causes subtitles to be affected by ``icc-profile``, ``target-prim``,
|
||||
``target-trc``, ``interpolation``, ``gamma`` and ``linear-scaling``.
|
||||
It also increases subtitle performance when using ``interpolation``.
|
||||
|
||||
The downside of enabling this is that it restricts subtitles to the
|
||||
visible portion of the video, so you can't have subtitles exist in the
|
||||
black margins below a video (for example).
|
||||
|
||||
If ``video`` is selected, the behavior is similar to ``yes``, but subs
|
||||
are drawn at the video's native resolution, and scaled along with the
|
||||
video.
|
||||
|
||||
.. warning:: This changes the way subtitle colors are handled. Normally,
|
||||
subtitle colors are assumed to be in sRGB and color managed
|
||||
as such. Enabling this makes them treated as being in the
|
||||
video's color space instead. This is good if you want
|
||||
things like softsubbed ASS signs to match the video colors,
|
||||
but may cause SRT subtitles or similar to look slightly off.
|
||||
|
||||
``alpha=<blend|yes|no>``
|
||||
Decides what to do if the input has an alpha component (default: blend).
|
||||
|
||||
@@ -577,10 +730,6 @@ Available video output drivers are:
|
||||
no
|
||||
Ignore alpha component.
|
||||
|
||||
``chroma-location=<auto|center|left>``
|
||||
Set the YUV chroma sample location. auto means use the bitstream
|
||||
flags (default: auto).
|
||||
|
||||
``rectangle-textures``
|
||||
Force use of rectangle textures (default: no). Normally this shouldn't
|
||||
have any advantages over normal textures. Note that hardware decoding
|
||||
@@ -590,54 +739,12 @@ Available video output drivers are:
|
||||
Color used to draw parts of the mpv window not covered by video.
|
||||
See ``--osd-color`` option how colors are defined.
|
||||
|
||||
``smoothmotion``
|
||||
Reduce stuttering caused by mismatches in video fps and display
|
||||
refresh rate (also known as judder).
|
||||
|
||||
Instead of drawing source frames for variable durations, smoothmotion
|
||||
will blend frames that overlap the transition between two frames in
|
||||
the source material.
|
||||
|
||||
For example, a 24 Hz clip played back on a 60 Hz display would normally
|
||||
result in a pattern like this::
|
||||
|
||||
A A A B B C C C D D E E E F F
|
||||
|
||||
which has different lengths, alternating between 3 and 2. This
|
||||
difference in frame duration is what causes judder.
|
||||
|
||||
With smoothmotion enabled, the pattern changes to::
|
||||
|
||||
A A A+B B B C C C+D D D E E E+F F F
|
||||
|
||||
where A+B is a blend of A and B. In this pattern, each frame gets a
|
||||
(consistent) duration of roughly 2.5 - resulting in smooth motion.
|
||||
|
||||
GPU drivers or compositing window managers overriding vsync behavior
|
||||
can lead to bad results. If the framerate is close to or over the
|
||||
display refresh rate, results can be bad as well.
|
||||
|
||||
.. note:: On systems other than Linux or OS X, you currently must set
|
||||
the ``--display-fps`` option, or the results will be bad.
|
||||
|
||||
``smoothmotion-threshold=<0.0-0.5>``
|
||||
Mix threshold at which interpolation is skipped (default: 0.0 – never
|
||||
skip).
|
||||
|
||||
For example, with a ``smoothmotion-threshold`` of 0.1, if the
|
||||
smoothmotion algorithm would try to blend two frames by a ratio of
|
||||
95% A + 5% B, it would simply display A instead. (Since the
|
||||
distance, 0.05, is lower than the threshold)
|
||||
|
||||
Setting this to 0.5 would be similar to disabling smoothmotion
|
||||
completely, since it would always just display the nearest frame.
|
||||
|
||||
``opengl-hq``
|
||||
Same as ``opengl``, but with default settings for high quality rendering.
|
||||
|
||||
This is equivalent to::
|
||||
|
||||
--vo=opengl:scale=spline36:scale-down=mitchell:dither-depth=auto:fbo-format=rgba16:fancy-downscaling:sigmoid-upscaling
|
||||
--vo=opengl:scale=spline36:cscale=spline36:dscale=mitchell:dither-depth=auto:fbo-format=rgba16:fancy-downscaling:sigmoid-upscaling
|
||||
|
||||
Note that some cheaper LCDs do dithering that gravely interferes with
|
||||
``opengl``'s dithering. Disabling dithering with ``dither-depth=no`` helps.
|
||||
@@ -796,7 +903,33 @@ Available video output drivers are:
|
||||
clear
|
||||
Drop all frames in the frame queue.
|
||||
|
||||
This also supports many of the suboptions the ``opengl`` VO has. Runs
|
||||
This also supports many of the suboptions the ``opengl`` VO has. Run
|
||||
``mpv --vo=opengl-cb:help`` for a list.
|
||||
|
||||
This also supports the ``vo_cmdline`` command.
|
||||
|
||||
``rpi`` (Raspberry Pi)
|
||||
Native video output on the Raspberry Pi using the MMAL API.
|
||||
|
||||
``display=<number>``
|
||||
Select the display number on which the video overlay should be shown
|
||||
(default: 0).
|
||||
|
||||
``layer=<number>``
|
||||
Select the dispmanx layer on which the video overlay should be shown
|
||||
(default: -10). Note that mpv will also use the 2 layers above the
|
||||
selected layer, to handle the window background and OSD. Actual video
|
||||
rendering will happen on the layer above the selected layer.
|
||||
|
||||
``drm`` (Direct Rendering Manager)
|
||||
Video output driver using Kernel Mode Setting / Direct Rendering Manager.
|
||||
Does not support hardware acceleration. Should be used when one doesn't
|
||||
want to install full-blown graphical environment (e.g. no X).
|
||||
|
||||
``connector=<number>``
|
||||
Select the connector to use (usually this is a monitor.) If set to -1,
|
||||
mpv renders the output on the first available connector. (default: -1)
|
||||
|
||||
``devpath=<filename>``
|
||||
Path to graphic card device.
|
||||
(default: /dev/dri/card0)
|
||||
@@ -46,6 +46,11 @@ Input
|
||||
* Allow customizing whether a key binding for seeking shows the video time, the
|
||||
OSD bar, or nothing (see the `Input Command Prefixes`_ section).
|
||||
* Support mapping multiple commands to one key.
|
||||
* Classic LIRC support was removed. Install remotes as input devices instead.
|
||||
This way they will send X11 key events to the mpv window, which can be bound
|
||||
using the normal ``input.conf``.
|
||||
* Joystick support was removed. It was considered useless and was the cause
|
||||
of some problems (e.g. a laptop's accelerator being recognized as joystick).
|
||||
|
||||
Audio
|
||||
~~~~~
|
||||
@@ -227,7 +232,6 @@ Command Line Switches
|
||||
``-idx`` ``--index``
|
||||
``-lavdopts ...`` ``--vd-lavc-...``
|
||||
``-lavfdopts`` ``--demuxer-lavf-...``
|
||||
``-lircconf`` ``--input-lirc-conf``
|
||||
``-loop 0`` ``--loop=inf``
|
||||
``-mixer-channel`` AO suboptions (``alsa``, ``oss``)
|
||||
``-mixer`` AO suboptions (``alsa``, ``oss``)
|
||||
@@ -239,7 +243,6 @@ Command Line Switches
|
||||
``-noar`` ``--no-input-appleremote``
|
||||
``-noautosub`` ``--no-sub-auto``
|
||||
``-noconsolecontrols`` ``--no-input-terminal``
|
||||
``-nojoystick`` ``--no-input-joystick``
|
||||
``-nosound`` ``--no-audio``
|
||||
``-osdlevel`` ``--osd-level``
|
||||
``-panscanrange`` ``--video-zoom``, ``--video-pan-x/y``
|
||||
|
||||
@@ -20,8 +20,9 @@ shortcomings:
|
||||
part is this pieces are spread apart in the configure and copy pasted for
|
||||
any single case. That brings us to..
|
||||
|
||||
2) --enable-feature has to override the user and help him understand that he
|
||||
has libraries missing and should install them for the feature to be enabled.
|
||||
2) --enable-feature has to be overridden by the user and helps them understand that
|
||||
they have libraries missing and should install them for the feature to be
|
||||
enabled.
|
||||
|
||||
3) Must be customizable, hackable, pleasant to the developer eyes and to work
|
||||
with in general.
|
||||
|
||||
@@ -1,22 +1,39 @@
|
||||
mpv
|
||||
===
|
||||

|
||||
|
||||
## mpv
|
||||
|
||||
--------------
|
||||
|
||||
|
||||
* [Overview](#overview)
|
||||
* [Downloads](#downloads)
|
||||
* [Compilation](#compilation)
|
||||
* [FFmpeg vs. Libav](#ffmpeg-vs-libav)
|
||||
* [Release cycle](#release-cycle)
|
||||
* [Bug reports](#bug-reports)
|
||||
* [Contributing](#contributing)
|
||||
* [Relation to MPlayer and mplayer2](#relation-to-mplayer-and-mplayer2)
|
||||
* [Wiki](https://github.com/mpv-player/mpv/wiki)
|
||||
* [Man pages](http://mpv.io/manual/master/)
|
||||
* [Contact](#contact)
|
||||
* [License](#license)
|
||||
|
||||
## Overview
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
**mpv** is a media player based on MPlayer and mplayer2. It supports a wide
|
||||
variety of video file formats, audio and video codecs, and subtitle types.
|
||||
|
||||
Releases can be found on the [release list][releases].
|
||||
|
||||
Downloads
|
||||
---------
|
||||
## Downloads
|
||||
|
||||
|
||||
For semi-official builds and third-party packages please see
|
||||
[mpv.io](http://mpv.io/installation/).
|
||||
|
||||
Compilation
|
||||
-----------
|
||||
## Compilation
|
||||
|
||||
|
||||
Compiling with full features requires development files for several
|
||||
external libraries. Below is a list of some important requirements.
|
||||
@@ -50,10 +67,10 @@ Essential dependencies (incomplete list):
|
||||
- Audio output development headers (libasound/ALSA, pulseaudio)
|
||||
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libavfilter
|
||||
and either libswresample or libavresample)
|
||||
At least FFmpeg 2.1.4 or Libav 10 is required.
|
||||
At least FFmpeg 2.4.0 or Libav 11 is required.
|
||||
- zlib
|
||||
- iconv (normally provided by the system libc)
|
||||
- libass
|
||||
- libass (OSD, OSC, text subtitles)
|
||||
- Lua (optional, required for the OSC pseudo-GUI and youtube-dl integration)
|
||||
- libjpeg (optional, used for screenshots only)
|
||||
- Enca (optional, for subtitle charset detection)
|
||||
@@ -89,16 +106,16 @@ OSX.
|
||||
If you want to build a Windows binary, you either have to use MSYS2 and MinGW,
|
||||
or cross-compile from Linux with MinGW. See [Windows compilation][windows_compilation].
|
||||
|
||||
FFmpeg vs. Libav
|
||||
----------------
|
||||
## 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.
|
||||
with FFmpeg only (subtitle formats in particular).
|
||||
|
||||
|
||||
Release cycle
|
||||
-------------
|
||||
## Release cycle
|
||||
|
||||
|
||||
Every few months, a new release is cut off of the master branch and is assigned
|
||||
a 0.X.0 version number.
|
||||
@@ -116,21 +133,21 @@ Releases other than the latest release are unsupported and unmaintained.
|
||||
|
||||
See the [release policy document][release-policy] for more information.
|
||||
|
||||
Bug reports
|
||||
-----------
|
||||
## Bug reports
|
||||
|
||||
|
||||
Please use the [issue tracker][issue-tracker] provided by GitHub to send us bug
|
||||
reports or feature requests.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
## Contributing
|
||||
|
||||
|
||||
For small changes you can just send us pull requests through GitHub. For bigger
|
||||
changes come and talk to us on IRC before you start working on them. It will
|
||||
make code review easier for both parties later on.
|
||||
|
||||
Relation to MPlayer and mplayer2
|
||||
--------------------------------
|
||||
## Relation to MPlayer and mplayer2
|
||||
|
||||
|
||||
mpv is based on mplayer2, which in turn is based on the original MPlayer
|
||||
(also called mplayer, mplayer-svn, mplayer1). Many changes have been made, a
|
||||
@@ -151,15 +168,15 @@ MPlayer drop-in replacement.
|
||||
If you are wondering what's different from mplayer2 and MPlayer, an incomplete
|
||||
list of changes is located [here][mplayer-changes].
|
||||
|
||||
Contact
|
||||
-------
|
||||
## Contact
|
||||
|
||||
|
||||
Most activity happens on the IRC channel and the github issue tracker. The
|
||||
mailing lists are mostly unused.
|
||||
|
||||
- **Github issue tracker**: [issue tracker][issue-tracker] (report bugs here)
|
||||
- **User IRC Channel**: `#mpv-player` on `irc.freenode.net`
|
||||
- **Developer IRC Channel**: `#mpv-player-dev` on `irc.freenode.net`
|
||||
- **User IRC Channel**: `#mpv` on `irc.freenode.net`
|
||||
- **Developer IRC Channel**: `#mpv-devel` 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])
|
||||
|
||||
@@ -176,3 +193,8 @@ only if discretion is required.
|
||||
[release-policy]: https://github.com/mpv-player/mpv/blob/master/DOCS/release-policy.md
|
||||
[windows_compilation]: https://github.com/mpv-player/mpv/blob/master/DOCS/compile-windows.md
|
||||
[mplayer-changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/mplayer-changes.rst
|
||||
|
||||
## License
|
||||
|
||||
|
||||
[GPLv2](https://github.com/mpv-player/mpv/blob/master/LICENSE)
|
||||
+420
-4
@@ -1,3 +1,194 @@
|
||||
Release 0.9.1
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
- mpv's IRC channel moved from #mpv-player to #mpv on chat.freenode.net.
|
||||
- Documentation updates.
|
||||
- The default value for the `--ytdl-format` option is now `best`, in order to
|
||||
work around `youtube-dl`'s 2015.04.26 release enabling DASH by default, as
|
||||
FFmpeg / Libav do not yet properly support DASH.
|
||||
- When seeking, the current timestamp will show the predicted seek timestamp
|
||||
instead, until the final timestamp is resolved. Improves UI responsiveness
|
||||
on slow streams and/or large seeks.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- Corrected the release marker on DOCS/client-api-changes. The release manager
|
||||
forgot to fix it before release...
|
||||
- Fix `vo_vdpau` rendering garbage lines on H.264 video with non-mod16 size
|
||||
(issue #1863).
|
||||
- Fix a crash on exit if the "sub_reload" command had run successfully.
|
||||
- Fixed seeking with the mouse when `osc-seekbarstyle=bar` is set (issue
|
||||
#1876).
|
||||
- (IPC) Fixed encoding of UTF-8 data in JSON (issue #1874).
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.9.0..v0.9.1` in the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/v0.9.0...v0.9.1.
|
||||
|
||||
Release 0.9.0
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
Changes that may break users' config files have been annotated with a `(!)`.
|
||||
|
||||
- Note: mpv is not compatible with Lua 5.3. Lua 5.1 or 5.2 is required.
|
||||
- The minimum required libass version is now 0.12.1 or newer.
|
||||
- The minimum required FFmpeg version is now 2.4.0 (equiv. Libav 11) or newer.
|
||||
- The internal libmpg123 support was removed. This was already not used by
|
||||
default in the previous release.
|
||||
- `(!)` The LIRC support was removed. Configure LIRC remotes as input devices
|
||||
instead.
|
||||
- `(!)` The Linux Joystick support was removed.
|
||||
- `(!)` `vf_screenshot` was removed, as they are now handled at a VO level and
|
||||
is compatible with all VOs.
|
||||
- `(!)` `--ass-use-margins` has been renamed to `--sub-use-margins` and applies
|
||||
only to plain-text (non-ASS) subtitles (enabled by default). The new
|
||||
`--ass-force-margins` option applies only to ASS subtitles (disabled by
|
||||
default). To get the old behaviour back, enable both at the same time.
|
||||
- `(!)` The `--sub-scale-with-window` option now only applies to plain text
|
||||
(non-ASS) subtitles (enabled by default). The new `--ass-scale-with-window`
|
||||
option does the same but only with ASS subtitles (disabled by default).
|
||||
- `(!)` The range for the `param1` for the `gaussian` `vo_opengl` scaler has
|
||||
been redefined. Instead of being an arbitrary 1-100 range, have a default
|
||||
value of 1.0, and anything higher is blurrier.
|
||||
- `(!)` The `seek`, `playlist_next, `playlist_prev`, `loadfile` and `loadlist`
|
||||
parameters no longer accept numerical parameters where symbolic parameter
|
||||
names exist.
|
||||
- `(!)` `vo_opengl` changes:
|
||||
- `(!)` The `smoothmotion` suboption has been renamed to `interpolation`.
|
||||
The old name is still supported for now.
|
||||
- `(!)` The `bilinear_slow` scaler has been renamed to `triangle`.
|
||||
- `(!)` `scale-down` has been renamed to `dscale` and now has its own set of
|
||||
config options (e.g. `dscale-radius`).
|
||||
- `(!)` Scaler radius no longer defaults to `3` but to a preferred value
|
||||
that may be different for each filter.
|
||||
- The `scale-radius` option may now go down as low as `0.5`, which is the
|
||||
value used by the `nearest` filter.
|
||||
- `spline36` is the new `cscale` default for `opengl-hq`. This might break
|
||||
setups that use `fbo-format=rgb8`. To work around it, leave `fbo-format`
|
||||
as its default, or set to something higher than 8, or set `cscale=bilinear`,
|
||||
the previous default.
|
||||
- `(!)` `vf_format` no longer converts video to YUYV if there is no parameter.
|
||||
Video is now passed unchanged unless a format is specifically requested.
|
||||
- `(!)` The `--colormatrix`, `--colormatrix-input-range`,
|
||||
`--colormatrix-output-range` and `--colormatrix-primaries` options have been
|
||||
converted into `vf_format` suboptions. See commit 27715b7 and the manual for
|
||||
details.
|
||||
- `vf_mirror`'s implementation was replaced with calling into `libavfilter`'s
|
||||
`vf_hflip` filter, thus depending on `libavfilter` to function.
|
||||
- The `device` subption to `ao_wasapi` has been deprecated in favor of
|
||||
`--audio-device`.
|
||||
- `--video-rotate` now allows 360 as an argument instead of stopping at 359.
|
||||
- Several improvements to `af_scaletempo`.
|
||||
- Options that have multiple options and also include a "yes" option now
|
||||
default to that if specified with no arguments.
|
||||
- The default value of `--cache-default` is now 150000 (153.6 MB, ~146 MiB).
|
||||
- JPEG screenshots now use the same subsampling as the source video. The images
|
||||
are still RGB regardless of source format though.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- mpv no longer saves position on files that can't be resumed (issue #1701).
|
||||
- (X11) Fix the player thinking the mouse has left the window in some WMs /
|
||||
embeddings (issue #1672).
|
||||
- mpv no longer freezes on wayland when the compositor stops asking it to draw
|
||||
itself (e.g. when minimized) (issue #249).
|
||||
- `.ac3` files are no longer rejected by `--audio-file-auto` (issue #1759).
|
||||
- `ao_wasapi` now automatically enables `exclusive` when passthrough is
|
||||
attempted (issue #1742).
|
||||
- Attempt to fix flickering on Intel VAAPI drivers with `--hwdec=vaapi` and
|
||||
`--vo=opengl` (issue #1765).
|
||||
- `youtube-dl` will no longer download video streams when video playback
|
||||
is disabled with `--no-video`.
|
||||
- (Windows) mpv now prevents system sleep when playing a video-only file.
|
||||
Previously, only files with an opened audio track would prevent sleep.
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
- `vo_opengl` features:
|
||||
- Added `ewa_ginseng`, `ewa_hanning`, `robidoux`, `robidouxsharp`,
|
||||
`oversample` and `haasnsoft` scalers.
|
||||
- There are now `ewa_lanczossoft` and `ewa_lanczossharp` aliases to
|
||||
`ewa_lanczos` that are tuned to be blurrier and sharper, respectively.
|
||||
- Added `gamma-auto` option that uses ambient light sensors to automatically
|
||||
adjust the video gamma. See commit c028d78 for details.
|
||||
- Added `blend-subtitles` option to draw subtitles directly into the video
|
||||
instead of rendered afterwards. Potentially necessary for correct rendering
|
||||
with files that use ASS subtitles for typesetting in combination with an
|
||||
`icc-profile`. There is a default option for drawing after upscaling,
|
||||
and a `video` option for drawing before upscaling. See details and warning
|
||||
on the manual.
|
||||
- There is now a `tscale` option, used to choose the temporal scaler used
|
||||
in the `interpolation` mode (previously `smoothmotion`).
|
||||
- There is a new `scale-blur` parameter to adjust the amount of blur that
|
||||
most of the filters produce. Deviating from the default may introduce
|
||||
artifacts in EWA filters.
|
||||
- (Windows) There is now a `dwmflush` option that might help improve
|
||||
rendering of high-fps video. Disabled by default. See manual for options.
|
||||
- New Linux-only `vo_drm` video output driver. Uses the direct rendering /
|
||||
kernel modesetting drivers to draw directly to the framebuffer, but with
|
||||
no hardware acceleration. See manual for details.
|
||||
- New `pseudo-gui` builtin profile, automatically used when launched from
|
||||
`mpv.desktop` by opening `mpv.exe` on windows (`mpv.com` still works as
|
||||
usual), or by opening the `mpv.app` bundle. The `pseudo-gui` tries to make
|
||||
the player window behave closer to what a desktop player would do, by not
|
||||
immediately closing and allowing the user to drag&drop files for playback.
|
||||
See manual for details.
|
||||
- mpv can now play directories by automatically playing their contents instead.
|
||||
Works everywhere but on Windows, due to issues with Windows' C runtime.
|
||||
- Add support to pitch correct stretched audio with librubberband.
|
||||
- Add support for the Raspberry Pi 2's hardware decoder when FFmpeg (or Libav)
|
||||
is built with `--enable-mmal`. See commit 8fff125 for details.
|
||||
- The `--cache` option now accepts a "yes" option, that always enables a
|
||||
`--cache-default`-sized cache on all cases a cache can be used, unless
|
||||
`--cache-default` disables caching.
|
||||
- `ao_pulse`, `ao_coreaudio` and `ao_wasapi` now support device hotplugging.
|
||||
- New `--osd-align-x` and `--osd-align-y` options can be used to align the OSD
|
||||
independently from subtitles.
|
||||
- New `--osd-bold` and `--sub-text-bold` options can be enabled to bold all
|
||||
OSD or plain-text subtitle text, respectively.
|
||||
- Added a default keybind to the `u` key that enables/disables ASS style
|
||||
overriding. When enabled, is equivalent to `--ass-style-override=force`.
|
||||
- There is now a `MOUSE_ENTER` keybind, that is called when the mouse cursor
|
||||
enters the VO from outside.
|
||||
- The new `--ytdl-params` option can be set to arguments that are always given
|
||||
to `youtube-dl` invocations. There is no sanity checking, so invalid options
|
||||
can prevent `mpv` from working with http URLs.
|
||||
- There's a new `--demuxer-mkv-fix-timestamps` option, enabled by default, that
|
||||
tries to guess more accurate video timestamps by using FPS information, if
|
||||
available. See manual for details.
|
||||
- The new `--window-scale` option can be used to scale the video window by the
|
||||
specified multiplier, before other options such as `--autofit` are applied.
|
||||
- `vo_direct3d_shaders` now supports NV12 colorspace without using stretchrect,
|
||||
but it seems no drivers actually support that.
|
||||
- (Client API) Added a `rescan_external_files` command, as requested on issue
|
||||
#1586.
|
||||
- (Client API) If enabled, initializing the Client API will now also load the
|
||||
user's `mpv.conf`.
|
||||
- (Client API) There's a new `mpv_opengl_cb_report_flip()` call for API users
|
||||
to call to inform mpv of when exactly a frame was displayed.
|
||||
- (Client API) The `mpv_opengl_cb_render()` function was deprecated in favor
|
||||
of the new, simpler `mpv_opengl_cb_draw()` function.
|
||||
- (Client API) There is a new `screenshot_raw` command. See `input.rst` for
|
||||
details.
|
||||
- The `--input-file` argument may now also be a file descriptor in the form
|
||||
"fd://N", where N is the FD number.
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.8.0..v0.9.0` in the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/v0.8.0...v0.9.0 (only 250 commits).
|
||||
|
||||
Release 0.8.3
|
||||
=============
|
||||
|
||||
@@ -11,6 +202,9 @@ Bug fixes
|
||||
---------
|
||||
|
||||
- (X11) Fix crash on `vo_xv:no-colorkey` with the Overlay adapter. (bug #1629)
|
||||
- (X11) `--stop-screensaver` is now implemented by calling into
|
||||
`xdg-screensaver`, fixing some compatibility issues that prevented it from
|
||||
actually stopping screensavers.
|
||||
- Make the video equalizer work correctly on some VAAPI drivers. (bug #1647)
|
||||
- Prevent OSD from disappearing when clicking on mozplugger. (bug #1672)
|
||||
- The new DVB-S2 support code, using S2API, now builds on FreeBSD.
|
||||
@@ -26,7 +220,8 @@ Bug fixes
|
||||
- Fix anamorphic scaling being ignored if it was very minor.
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.8.2..v0.8.3` in the git repository.
|
||||
`git log v0.8.2..v0.8.3` in the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/v0.8.2...v0.8.3.
|
||||
|
||||
Release 0.8.2
|
||||
=============
|
||||
@@ -34,7 +229,7 @@ Release 0.8.2
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- Fix OSD placement accidentally messed up in 0.8.1.
|
||||
- Fix OSD placement accidentally messed up in 0.8.1 (commit 22863d6).
|
||||
|
||||
Release 0.8.1
|
||||
=============
|
||||
@@ -65,7 +260,8 @@ New features
|
||||
- mpv now tries to load '.vtt' subtitles.
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.8.0..v0.8.1` in the git repository.
|
||||
`git log v0.8.0..v0.8.1` in the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/v0.8.0...v0.8.1.
|
||||
|
||||
Release 0.8.0
|
||||
=============
|
||||
@@ -231,4 +427,224 @@ New features
|
||||
files.
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.7.0..v0.8.0` in the git repository.
|
||||
`git log v0.7.0..v0.8.0` in the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/v0.7.0...v0.8.0 (only 250 commits).
|
||||
|
||||
Release 0.7.3
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
- Several documentation updates and typo fixes.
|
||||
- Don't show "0%" position when the stream is infinite / has unknown length.
|
||||
- Fixes the config file loading order so that lower priority `mpv.conf` files
|
||||
don't override higher priority `config` files.
|
||||
- (OSX) Remove coreaudio_exclusive from the "auto" codec list.
|
||||
- Failing to create a GL3 context is now a warning instead of error, to reduce
|
||||
user confusion.
|
||||
- The subtitle decoder now gets reset when cycling subtitles. This makes the
|
||||
currently shown subtitle event disappear even if cycling back to the current
|
||||
subtitle track.
|
||||
- `--shuffle` and `--merge-files` now affects the contents of playlist files,
|
||||
instead of just the list of files given as arguments to mpv.
|
||||
- `./waf install` avoids installing a few additional data/config files if only
|
||||
libmpv was built.
|
||||
- Improved channel mapping when the file's channel map doesn't match the AO's
|
||||
available channel maps.
|
||||
- (OSX) VDA now gracefully refuses to run on non-OpenGL3-capable systems instead
|
||||
of trying and failing to build its shaders.
|
||||
- Add workaround for vf_vapoursynth filters that expect an FPS.
|
||||
- The default value for `--screenshot-template` now shows up in
|
||||
`--list-options`.
|
||||
- `ao_pulse`'s `latency-hacks` suboption is now off by default, as it causes
|
||||
issues with newer pulseaudio releases. If A/V Sync issues happen, either
|
||||
add the `latency-hacks=on` pulse suboption in mpv.conf, or update the
|
||||
pulseaudio daemon (bug #1430).
|
||||
- (Linux) `ao_alsa` now deals better with audio device disconnection.
|
||||
- Client API: timestamp properties that have no value return "no" instead of
|
||||
magic number.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- (Windows, OSX) Many `ao_wasapi` and `ao_coreaudio` fixes.
|
||||
- (OSX) Make the window title update correctly on OS X Yosemite.
|
||||
- Fixes for handling mono audio on various AOs.
|
||||
- (Linux) Fixes resuming from suspend on ao_alsa.
|
||||
- Fixes for playlist file parsing.
|
||||
- Overly long options in the --list-options output now break the column layout
|
||||
instead of getting truncated; fixes shell completion scripts.
|
||||
- Fix rendering resolution of certain DVB subtitles (bug #1425).
|
||||
- Fix EDL or --merge-files breaking timestamps with .avi files.
|
||||
- Workaround for libavcodec bug with the VP9 codec parser (bug #1448),
|
||||
fixes possible crash.
|
||||
- Improve robustness of the matroska parser with broken files (bugs #1457,
|
||||
#1461).
|
||||
- Improve 10bit video compatibility with older GPUs (specially Intel) (bug
|
||||
#1383).
|
||||
- Fixes flashing the VO window when playing a list of files that includes
|
||||
non-media files (bug #1459).
|
||||
- Workaround for window embedding in OpenBox (bug #1235)
|
||||
- Fixes for several crashes and lockups (bugs #838, #1389, #1408, #1463, #1473,
|
||||
#1474).
|
||||
- Fixes for the zsh completion script (bugs #997)
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
- mpv now prints the contents of its config.h when running in verbose mode, to
|
||||
aid with debugging.
|
||||
- The `include=` option now accepts `~` to refer to the HOME dir (bug #1406).
|
||||
- `af_volume` now prints ReplayGain values in verbose mode.
|
||||
- m3u playlists that don't have the `#EXTM3U` header are now accepted if they
|
||||
"look like" ASCII or UTF-8 text and have the .m3u extension.
|
||||
- Chapter marks in the seek bar now update when switching files.
|
||||
- Supports embedded cover art in MKV files (bug #1374).
|
||||
- (Windows) Video window can now be resized even with --no-border.
|
||||
- (Windows) Client API: the "run" command now works on Windows too.
|
||||
- (Linux) vo_wayland now supports key modifiers (Meta, Alt, Control, Shift)
|
||||
- Client API: "display-names" property is now observable.
|
||||
|
||||
This listing is not complete. A complete changelog can be seen by running
|
||||
`git log v0.7.2..v0.7.3` in the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/v0.7.2...v0.7.3.
|
||||
|
||||
Release 0.7.2
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
- Give precedence to the DVD menu navigation keyboard bindings so that user
|
||||
defined LEFT/RIGHT/... bindings don't break DVD menu navigation.
|
||||
- Try to fallback to the "default" device if the selected device is busy in the
|
||||
alsa AO.
|
||||
- Don't create Dock icon for audio only files on OS X.
|
||||
- Save screenshots to desktop when using the app bundle on OS X.
|
||||
- Restore ab-loop settings with playback resume.
|
||||
- Bump required youtube-dl version to 2014.11.26 and enable the ytdl_hook Lua
|
||||
script by default (now playing videos from YouTube and the like will work
|
||||
out of the box without any configuration change needed).
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- Don't signal an error if --stream-dump is used.
|
||||
- Fix removing key bindings from Lua scripts.
|
||||
- Reject channel descriptions with too many channels in the coreaudio AO.
|
||||
- Don't async redraw when waiting for VO redraw on OS X (this fixes the very
|
||||
annoying glitch where the black bars disappear for a single frame when going
|
||||
fullscreen).
|
||||
- Fix mono playback with the also AO.
|
||||
- Don't crash if framebuffers are not available in the opengl VO.
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
- Try to handle multi-arc videos in the ytdl_hook Lua script.
|
||||
|
||||
This listing is not complete. There are many more bug fixes and changes. The
|
||||
complete change log can be viewed by running ``git log 47ec404..c7d6b21`` in
|
||||
the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/47ec404...c7d6b21.
|
||||
|
||||
Release 0.7.1
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
- Don't show the volume neutral marker on the OSD if softvol is disabled.
|
||||
- Don't select a subtitle track when executing the sub_add input command in
|
||||
"auto" mode.
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- Fix busy loop when seeking while paused (this fixes a problem with pulseaudio
|
||||
that caused mpv and the pulseaudio daemon to use 100% CPU).
|
||||
- Fix Lua function utils.subprocess() in Windows versions older than Vista.
|
||||
- Avoid creating a window bigger than the screen on Windows.
|
||||
- Don't ignore the last line in m3u playlists.
|
||||
- Don't crash if a codec could not be opened.
|
||||
- Dynamically allocate audio channel map entries (this should fix a crash in
|
||||
the alsa and coreaudio AOs with audio devices that support more than 20
|
||||
channel maps).
|
||||
- Ignore the "srgb" option in the opengl VO if hardware decoding is enabled.
|
||||
- Linearize non-RGB sRGB files correctly (eg. JPEG).
|
||||
- Fix opening reference URLs (.file/id=) on OS X.
|
||||
|
||||
This listing is not complete. There are many more bug fixes and changes. The
|
||||
complete change log can be viewed by running ``git log 8d8b36d..6583ad6`` in
|
||||
the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/8d8b36d...6583ad6.
|
||||
|
||||
Release 0.7.0
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
- Buffer partial log messages in the client API (the client API will now only
|
||||
pass full log messages to clients).
|
||||
- Remove ncurses/terminfo/termcap support (it was disabled by default and
|
||||
replaced by new code since v0.6.0).
|
||||
- Enable cdda:// support by default again (it was disabled since v0.6.0).
|
||||
- Cascade-load input.conf (if there are several input.confs in the set of valid
|
||||
config paths, load them all).
|
||||
- Draw the OSD twice in 3D mode (this fixes subtitles display in 3D mode).
|
||||
- Make wasapi the default AO on Windows again since many of its problems have
|
||||
been solved.
|
||||
- Use "site-functions" subdir to install the zsh completion script instead of
|
||||
the Debian-specific "vendor-completions" (also provide the --zshdir waf
|
||||
configure option for changing this value).
|
||||
- Improve synchronization between the Cocoa GUI and the player (this fixes some
|
||||
long standing deadlock issues on Mac OS X).
|
||||
- Remove --fs-missioncontrol option (only relevant to Mac OS X).
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
- Enable pitch correction by default when playing at higher speeds (this can be
|
||||
controlled with the --audio-pitch-correction option).
|
||||
- Open stream and demuxer asynchronously (this should avoid having the player
|
||||
get blocked on network streams).
|
||||
- Add cache-buffering-state property for querying the cache fill status until
|
||||
the player unpauses.
|
||||
- Add support for listing and selecting the audio device (note that it is not
|
||||
implemented for all AOs, see the --audio-device option for more information).
|
||||
- Add support for a JSON-based IPC mechanism (note that this is not currently
|
||||
supported on Windows, see the JSON IPC section in the manpage for more
|
||||
information).
|
||||
- Add Lua utility function for starting processes (see utils.subprocess() in the
|
||||
manpage).
|
||||
- Add Lua utility function for parsing JSON (see utils.parse_json() in the
|
||||
manpage).
|
||||
- Add field-dominance property (see --field-dominance option).
|
||||
- Add video-rotate property (see --video-rotate option).
|
||||
- Add playback-abort property for querying whether playback is stopped or is to
|
||||
be stopped.
|
||||
- Add cursor-autohide property (see --cursor-autohide option).
|
||||
- Add vo-configured property for querying whether a window is created.
|
||||
- Add support for dxva2 hardware acceleration on Windows.
|
||||
- Drop libquvi support (this has been replaced by a built-in Lua script that
|
||||
invokes the youtube-dl tool, which needs to be installed, see the --ytdl
|
||||
option).
|
||||
- Add support for loading chapters from an external file (see the
|
||||
--chapters-file option).
|
||||
- Add window-minimized property for querying whether the window is minimized
|
||||
(works for X11 only).
|
||||
- Make it possible to configure the OSC seekbar style (see the "seekbarstyle"
|
||||
OSC option).
|
||||
- Add support for libmpv on Mac OS X (it used to be broken, now it's fully
|
||||
functional and also provides support for embedding the mpv window inside a
|
||||
Cocoa/Qt application).
|
||||
- Try to use the audio channel map reported by ALSA in the alsa AO.
|
||||
- Add option to disable text OSD rendering completely (useful for working around
|
||||
certain fontconfig issues, see the --use-text-osd option).
|
||||
|
||||
This listing is not complete. There are many more bug fixes and changes. The
|
||||
complete change log can be viewed by running ``git log 7759c18..9479daa`` in
|
||||
the git repository or by visiting
|
||||
https://github.com/mpv-player/mpv/compare/7759c18...9479daa (only 250 commits).
|
||||
@@ -10,3 +10,5 @@ to mpv's command line.
|
||||
|
||||
Where appropriate, they may also be placed in ~/.config/mpv/scripts/ from
|
||||
where they will be automatically loaded when mpv starts.
|
||||
|
||||
Some of these are just for testing mpv internals.
|
||||
@@ -0,0 +1,13 @@
|
||||
local utils = require("mp.utils")
|
||||
|
||||
mp.observe_property("audio-device-list", "native", function(name, val)
|
||||
print("Audio device list changed:")
|
||||
for index, e in ipairs(val) do
|
||||
print(" - '" .. e.name .. "' (" .. e.description .. ")")
|
||||
end
|
||||
end)
|
||||
|
||||
mp.observe_property("audio-out-detected-device", "native", function(name, val)
|
||||
print("Detected audio device changed:")
|
||||
print(" - '" .. val)
|
||||
end)
|
||||
+40
-1
@@ -7,6 +7,17 @@
|
||||
-- Add at most 5 * 2 files when starting a file (before + after).
|
||||
MAXENTRIES = 5
|
||||
|
||||
function Set (t)
|
||||
local set = {}
|
||||
for _, v in pairs(t) do set[v] = true end
|
||||
return set
|
||||
end
|
||||
|
||||
EXTENSIONS = Set {
|
||||
'mkv', 'avi', 'mp4', 'ogv', 'webm', 'rmvb', 'flv', 'wmv', 'mpeg', 'mpg', 'm4v', '3gp',
|
||||
'mp3', 'wav', 'ogv', 'flac', 'm4a', 'wma',
|
||||
}
|
||||
|
||||
mputils = require 'mp.utils'
|
||||
|
||||
function add_files_at(index, files)
|
||||
@@ -18,20 +29,44 @@ function add_files_at(index, files)
|
||||
end
|
||||
end
|
||||
|
||||
function get_extension(path)
|
||||
return string.match(path, "%.([^%.]+)$" )
|
||||
end
|
||||
|
||||
table.filter = function(t, iter)
|
||||
for i = #t, 1, -1 do
|
||||
if not iter(t[i]) then
|
||||
table.remove(t, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function find_and_add_entries()
|
||||
local path = mp.get_property("path", "")
|
||||
local dir, filename = mputils.split_path(path)
|
||||
if #dir == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local files = mputils.readdir(dir, "files")
|
||||
if files == nil then
|
||||
return
|
||||
end
|
||||
table.sort(files)
|
||||
table.filter(files, function (v, k)
|
||||
local ext = get_extension(v)
|
||||
if ext == nil then
|
||||
return false
|
||||
end
|
||||
return EXTENSIONS[string.lower(ext)]
|
||||
end)
|
||||
table.sort(files, function (a, b)
|
||||
return string.lower(a) < string.lower(b)
|
||||
end)
|
||||
|
||||
if dir == "." then
|
||||
dir = ""
|
||||
end
|
||||
|
||||
local pl = mp.get_property_native("playlist", {})
|
||||
local pl_current = mp.get_property_number("playlist-pos", 0) + 1
|
||||
-- Find the current pl entry (dir+"/"+filename) in the sorted dir list
|
||||
@@ -45,6 +80,7 @@ function find_and_add_entries()
|
||||
if current == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local append = {[-1] = {}, [1] = {}}
|
||||
for direction = -1, 1, 2 do -- 2 iterations, with direction = -1 and +1
|
||||
for i = 1, MAXENTRIES do
|
||||
@@ -53,6 +89,7 @@ function find_and_add_entries()
|
||||
if file == nil or file[1] == "." then
|
||||
break
|
||||
end
|
||||
|
||||
local filepath = dir .. file
|
||||
if pl_e then
|
||||
-- If there's a playlist entry, and it's the same file, stop.
|
||||
@@ -60,6 +97,7 @@ function find_and_add_entries()
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if direction == -1 then
|
||||
if pl_current == 1 then -- never add additional entries in the middle
|
||||
mp.msg.info("Prepending " .. file)
|
||||
@@ -71,6 +109,7 @@ function find_and_add_entries()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
add_files_at(pl_current + 1, append[1])
|
||||
add_files_at(pl_current, append[-1])
|
||||
end
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
--makes mpv disable ontop when pausing and re-enable it again when resuming playback
|
||||
--please note that this won't do anything if ontop was not enabled before pausing
|
||||
|
||||
local was_ontop = false
|
||||
|
||||
mp.observe_property("pause", "bool", function(name, value)
|
||||
local ontop = mp.get_property_native("ontop")
|
||||
if value then
|
||||
if ontop then
|
||||
mp.set_property_native("ontop", false)
|
||||
was_ontop = true
|
||||
end
|
||||
else
|
||||
if was_ontop and not ontop then
|
||||
mp.set_property_native("ontop", true)
|
||||
end
|
||||
was_ontop = false
|
||||
end
|
||||
end)
|
||||
@@ -2,8 +2,6 @@
|
||||
-- if it's brought back again. If the player was already paused when minimizing,
|
||||
-- then try not to mess with the pause state.
|
||||
|
||||
-- Note: currently works with X11 only.
|
||||
|
||||
local did_minimize = false
|
||||
|
||||
mp.observe_property("window-minimized", "bool", function(name, value)
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
--sets the startime of a youtube video as specified in the "t=HHhMMmSSs" part of the url
|
||||
--NOTE: This might become obsolete once youtube-dl adds the functionality
|
||||
|
||||
local msg = require 'mp.msg'
|
||||
|
||||
function youtube_starttime()
|
||||
url = mp.get_property("path", "")
|
||||
start = 0
|
||||
|
||||
if string.find(url, "youtu%.?be") and
|
||||
((url:find("http://") == 1) or (url:find("https://") == 1)) then
|
||||
time = string.match(url, "[#&%?]t=%d*h?%d*m?%d+s?m?h?")
|
||||
--the time-string can start with #, & or ? followed by t= and the timing parameters
|
||||
--at least one number needs to be present after t=, followed by h, m, s or nothing (>implies s)
|
||||
|
||||
if time then
|
||||
for pos in string.gmatch(time,"%d+%a?") do
|
||||
if string.match(pos,"%d+h") then --find out multiplier for
|
||||
multiplier = 60*60 --hours
|
||||
elseif string.match(pos,"%d+m") then
|
||||
multiplier = 60 --minutes
|
||||
else multiplier = 1 end --seconds
|
||||
|
||||
start = start + (string.match(pos,"%d+") * multiplier)
|
||||
end
|
||||
|
||||
msg.info("parsed '" .. time .. "' into '" .. start .. "' seconds")
|
||||
end
|
||||
|
||||
mp.set_property("file-local-options/start",start)
|
||||
end
|
||||
end
|
||||
|
||||
mp.add_hook("on_load", 50, youtube_starttime)
|
||||
@@ -1,3 +1,2 @@
|
||||
screenshot-template=~/Desktop/shot%n
|
||||
quiet
|
||||
idle=once
|
||||
profile=pseudo-gui
|
||||
+1
-1
@@ -21,7 +21,7 @@ script after that will start a new mpv instance.
|
||||
|
||||
Note that you can control the mpv instance by writing to the command fifo:
|
||||
|
||||
echo "cycle fullscreen" > ~/.umpv-fifo
|
||||
echo "cycle fullscreen" > ~/.umpv_fifo
|
||||
|
||||
Note: you can supply custom mpv path and options with the MPV environment
|
||||
variable. The environment variable will be split on whitespace, and the
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Example of script for using mpv with youtube-dl
|
||||
set -e
|
||||
|
||||
cookies_dir="$(mktemp -d /tmp/youtube-dl_mpv.XXXX)"
|
||||
cookies_file="${cookies_dir}/cookies"
|
||||
user_agent="$(youtube-dl --dump-user-agent)" # or set whatever you want
|
||||
|
||||
video_url=$(youtube-dl \
|
||||
--user-agent="${user_agent}" \
|
||||
--cookies="${cookies_file}" \
|
||||
--get-url \
|
||||
"$@")
|
||||
|
||||
set -f
|
||||
${MPV:-mpv} \
|
||||
--cookies \
|
||||
--cookies-file="${cookies_file}" \
|
||||
--user-agent="${user_agent}" \
|
||||
-- ${video_url}
|
||||
|
||||
rm -rf "${cookies_dir}"
|
||||
+42
-55
@@ -7,15 +7,15 @@ use warnings;
|
||||
|
||||
my $mpv = $ARGV[0] || 'mpv';
|
||||
|
||||
my @opts = parse_main_opts("$mpv --list-options", '^ (\-\-[^\s\*]*)\*?\s*(.*)');
|
||||
my @opts = parse_main_opts('--list-options', '^ (\-\-[^\s\*]*)\*?\s*(.*)');
|
||||
|
||||
my @ao = parse_opts("$mpv --ao=help", '^ ([^\s\:]*)\s*: (.*)');
|
||||
my @vo = parse_opts("$mpv --vo=help", '^ ([^\s\:]*)\s*: (.*)');
|
||||
my @ao = parse_opts('--ao=help', '^ ([^\s\:]*)\s*: (.*)');
|
||||
my @vo = parse_opts('--vo=help', '^ ([^\s\:]*)\s*: (.*)');
|
||||
|
||||
my @af = parse_opts("$mpv --af=help", '^ ([^\s\:]*)\s*: (.*)');
|
||||
my @vf = parse_opts("$mpv --vf=help", '^ ([^\s\:]*)\s*: (.*)');
|
||||
my @af = parse_opts('--af=help', '^ ([^\s\:]*)\s*: (.*)');
|
||||
my @vf = parse_opts('--vf=help', '^ ([^\s\:]*)\s*: (.*)');
|
||||
|
||||
my @protos = parse_opts("$mpv --list-protocols", '^ ([^\s]*)');
|
||||
my @protos = parse_opts('--list-protocols', '^ ([^\s]*)');
|
||||
|
||||
my ($opts_str, $ao_str, $vo_str, $af_str, $vf_str, $protos_str);
|
||||
|
||||
@@ -34,36 +34,35 @@ chomp $af_str;
|
||||
$vf_str .= qq{ '$_' \\\n} foreach (@vf);
|
||||
chomp $vf_str;
|
||||
|
||||
$protos_str .= qq{$_ } foreach (@protos);
|
||||
chomp $protos_str;
|
||||
$protos_str = join(' ', @protos);
|
||||
|
||||
my $profile_comp = <<'EOS';
|
||||
local -a profiles
|
||||
local current
|
||||
for current in "${(@f)$($words[1] --profile=help)}"; do
|
||||
current=${current//\*/\\\*}
|
||||
current=${current//\:/\\\:}
|
||||
current=${current//\[/\\\[}
|
||||
current=${current//\]/\\\]}
|
||||
if [[ $current =~ $'\t'([^$'\t']*)$'\t'(.*) ]]; then
|
||||
if [[ -n $match[2] ]]; then
|
||||
current="$match[1][$match[2]]"
|
||||
else
|
||||
current="$match[1]"
|
||||
fi
|
||||
profiles=($profiles $current)
|
||||
local -a profiles
|
||||
local current
|
||||
for current in "${(@f)$($words[1] --profile=help)}"; do
|
||||
current=${current//\*/\\\*}
|
||||
current=${current//\:/\\\:}
|
||||
current=${current//\[/\\\[}
|
||||
current=${current//\]/\\\]}
|
||||
if [[ $current =~ $'\t'([^$'\t']*)$'\t'(.*) ]]; then
|
||||
if [[ -n $match[2] ]]; then
|
||||
current="$match[1][$match[2]]"
|
||||
else
|
||||
current="$match[1]"
|
||||
fi
|
||||
done
|
||||
if [[ $state == show-profile ]]; then
|
||||
# For --show-profile, only one allowed
|
||||
if (( ${#profiles} > 0 )); then
|
||||
_values 'profile' $profiles && rc=0
|
||||
fi
|
||||
else
|
||||
# For --profile, multiple allowed
|
||||
profiles=($profiles 'help[list profiles]')
|
||||
_values -s , 'profile(s)' $profiles && rc=0
|
||||
profiles=($profiles $current)
|
||||
fi
|
||||
done
|
||||
if [[ $state == show-profile ]]; then
|
||||
# For --show-profile, only one allowed
|
||||
if (( ${#profiles} > 0 )); then
|
||||
_values 'profile' $profiles && rc=0
|
||||
fi
|
||||
else
|
||||
# For --profile, multiple allowed
|
||||
profiles=($profiles 'help[list profiles]')
|
||||
_values -s , 'profile(s)' $profiles && rc=0
|
||||
fi
|
||||
EOS
|
||||
chomp $profile_comp;
|
||||
|
||||
@@ -83,39 +82,27 @@ $opts_str
|
||||
|
||||
case \$state in
|
||||
ao)
|
||||
local -a values
|
||||
values=(
|
||||
_values -s , 'audio outputs' \\
|
||||
$ao_str
|
||||
)
|
||||
|
||||
_describe -t values 'audio outputs' values && rc=0
|
||||
&& rc=0
|
||||
;;
|
||||
|
||||
vo)
|
||||
local -a values
|
||||
values=(
|
||||
_values -s , 'video outputs' \\
|
||||
$vo_str
|
||||
)
|
||||
|
||||
_describe -t values 'video outputs' values && rc=0
|
||||
&& rc=0
|
||||
;;
|
||||
|
||||
af)
|
||||
local -a values
|
||||
values=(
|
||||
_values -s , 'audio filters' \\
|
||||
$af_str
|
||||
)
|
||||
|
||||
_describe -t values 'audio filters' values && rc=0
|
||||
&& rc=0
|
||||
;;
|
||||
|
||||
vf)
|
||||
local -a values
|
||||
values=(
|
||||
_values -s , 'video filters' \\
|
||||
$vf_str
|
||||
)
|
||||
|
||||
_describe -t values 'video filters' values && rc=0
|
||||
&& rc=0
|
||||
;;
|
||||
|
||||
profile|show-profile)
|
||||
@@ -154,7 +141,7 @@ sub parse_main_opts {
|
||||
my ($cmd, $regex) = @_;
|
||||
|
||||
my @list;
|
||||
my @lines = split /\n/, `$cmd`;
|
||||
my @lines = split /\n/, `"$mpv" --no-config $cmd`;
|
||||
|
||||
foreach my $line (@lines) {
|
||||
my ($name, $desc) = ($line =~ /^$regex/) or next;
|
||||
@@ -219,7 +206,7 @@ sub parse_opts {
|
||||
my ($cmd, $regex) = @_;
|
||||
|
||||
my @list;
|
||||
my @lines = split /\n/, `$cmd`;
|
||||
my @lines = split /\n/, `"$mpv" --no-config $cmd`;
|
||||
|
||||
foreach my $line (@lines) {
|
||||
if ($line !~ /^$regex/) {
|
||||
@@ -231,7 +218,7 @@ sub parse_opts {
|
||||
if (defined $2) {
|
||||
my $desc = $2;
|
||||
$desc =~ s/\:/\\:/g;
|
||||
$entry .= ':' . $desc;
|
||||
$entry .= "[$desc]";
|
||||
}
|
||||
|
||||
push @list, $entry
|
||||
|
||||
+2
-2
@@ -35,7 +35,7 @@ static void update_redundant_info(struct mp_audio *mpa)
|
||||
mp_chmap_is_valid(&mpa->channels));
|
||||
mpa->nch = mpa->channels.num;
|
||||
mpa->bps = af_fmt2bps(mpa->format);
|
||||
if (af_fmt_is_planar(mpa->format)) {
|
||||
if (AF_FORMAT_IS_PLANAR(mpa->format)) {
|
||||
mpa->spf = 1;
|
||||
mpa->num_planes = mpa->nch;
|
||||
mpa->sstride = mpa->bps;
|
||||
@@ -101,7 +101,7 @@ char *mp_audio_config_to_str_buf(char *buf, size_t buf_sz, struct mp_audio *mpa)
|
||||
|
||||
void mp_audio_force_interleaved_format(struct mp_audio *mpa)
|
||||
{
|
||||
if (af_fmt_is_planar(mpa->format))
|
||||
if (AF_FORMAT_IS_PLANAR(mpa->format))
|
||||
mp_audio_set_format(mpa, af_fmt_from_planar(mpa->format));
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,9 @@ static const char *const speaker_names[MP_SPEAKER_ID_COUNT][2] = {
|
||||
static const char *const std_layout_names[][2] = {
|
||||
{"empty", ""}, // not in lavc
|
||||
{"mono", "fc"},
|
||||
{"1.0", "fc"}, // not in lavc
|
||||
{"stereo", "fl-fr"},
|
||||
{"2.0", "fl-fr"}, // not in lavc
|
||||
{"2.1", "fl-fr-lfe"},
|
||||
{"3.0", "fl-fr-fc"},
|
||||
{"3.0(back)", "fl-fr-bc"},
|
||||
|
||||
+19
-13
@@ -199,12 +199,16 @@ bool mp_chmap_sel_adjust(const struct mp_chmap_sel *s, struct mp_chmap *map)
|
||||
return false;
|
||||
}
|
||||
|
||||
#define UPMIX_IDX 0
|
||||
#define DOWNMIX_IDX 1
|
||||
#define FALLBACK_IDX 2
|
||||
enum {
|
||||
UPMIX_IDX,
|
||||
FALLBACK_UPMIX_IDX,
|
||||
DOWNMIX_IDX,
|
||||
FALLBACK_DOWNMIX_IDX,
|
||||
REMIX_COUNT
|
||||
};
|
||||
|
||||
static bool test_fallbacks(struct mp_chmap *a, struct mp_chmap *b,
|
||||
int best_diffs[2], struct mp_chmap best[2])
|
||||
int best_diffs[], struct mp_chmap best[])
|
||||
{
|
||||
struct mp_chmap diff1, diff2;
|
||||
|
||||
@@ -222,15 +226,15 @@ static bool test_fallbacks(struct mp_chmap *a, struct mp_chmap *b,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (diff1.num > 0 && best_diffs[FALLBACK_IDX] > diff1.num) {
|
||||
best[FALLBACK_IDX] = *a;
|
||||
best_diffs[FALLBACK_IDX] = diff1.num;
|
||||
if (diff1.num > 0 && best_diffs[FALLBACK_UPMIX_IDX] > diff1.num) {
|
||||
best[FALLBACK_UPMIX_IDX] = *a;
|
||||
best_diffs[FALLBACK_UPMIX_IDX] = diff1.num;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (diff2.num > 0 && best_diffs[FALLBACK_IDX] > diff2.num) {
|
||||
best[FALLBACK_IDX] = *a;
|
||||
best_diffs[FALLBACK_IDX] = diff2.num;
|
||||
if (diff2.num > 0 && best_diffs[FALLBACK_DOWNMIX_IDX] > diff2.num) {
|
||||
best[FALLBACK_DOWNMIX_IDX] = *a;
|
||||
best_diffs[FALLBACK_DOWNMIX_IDX] = diff2.num;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -255,8 +259,10 @@ bool mp_chmap_sel_fallback(const struct mp_chmap_sel *s, struct mp_chmap *map)
|
||||
return true;
|
||||
}
|
||||
|
||||
int best_diffs[] = { INT_MAX, INT_MAX, INT_MAX };
|
||||
struct mp_chmap best[] = { {0}, {0}, {0} };
|
||||
struct mp_chmap best[REMIX_COUNT] = {{0}};
|
||||
int best_diffs[REMIX_COUNT];
|
||||
for (int n = 0; n < REMIX_COUNT; n++)
|
||||
best_diffs[n] = INT_MAX;
|
||||
|
||||
for (int n = 0; n < s->num_chmaps; n++) {
|
||||
struct mp_chmap e = s->chmaps[n];
|
||||
@@ -278,7 +284,7 @@ bool mp_chmap_sel_fallback(const struct mp_chmap_sel *s, struct mp_chmap *map)
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = UPMIX_IDX; i < MP_ARRAY_SIZE(best); i++) {
|
||||
for (int i = 0; i < MP_ARRAY_SIZE(best); i++) {
|
||||
if (best_diffs[i] < INT_MAX) {
|
||||
*map = best[i];
|
||||
return true;
|
||||
|
||||
+4
-5
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_AD_H
|
||||
|
||||
+6
-10
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -59,7 +58,7 @@ struct ad_lavc_params {
|
||||
|
||||
const struct m_sub_options ad_lavc_conf = {
|
||||
.opts = (const m_option_t[]) {
|
||||
OPT_FLOATRANGE("ac3drc", ac3drc, 0, 0, 2),
|
||||
OPT_FLOATRANGE("ac3drc", ac3drc, 0, 0, 6),
|
||||
OPT_FLAG("downmix", downmix, 0),
|
||||
OPT_INTRANGE("threads", threads, 0, 1, 16),
|
||||
OPT_KEYVALUELIST("o", avopts, 0),
|
||||
@@ -67,7 +66,7 @@ const struct m_sub_options ad_lavc_conf = {
|
||||
},
|
||||
.size = sizeof(struct ad_lavc_params),
|
||||
.defaults = &(const struct ad_lavc_params){
|
||||
.ac3drc = 1.,
|
||||
.ac3drc = 0,
|
||||
.downmix = 1,
|
||||
.threads = 1,
|
||||
},
|
||||
@@ -145,9 +144,6 @@ static int init(struct dec_audio *da, const char *decoder)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lavc_context->bit_rate != 0)
|
||||
da->bitrate = lavc_context->bit_rate;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,304 +0,0 @@
|
||||
/*
|
||||
* MPEG 1.0/2.0/2.5 audio layer I, II, III decoding with libmpg123
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "ad.h"
|
||||
#include "common/msg.h"
|
||||
|
||||
#include <mpg123.h>
|
||||
|
||||
#if (defined MPG123_API_VERSION) && (MPG123_API_VERSION < 33)
|
||||
#error "This should not happen"
|
||||
#endif
|
||||
|
||||
struct ad_mpg123_context {
|
||||
mpg123_handle *handle;
|
||||
int sample_size;
|
||||
/* Running mean for bit rate, stream length estimation. */
|
||||
float mean_rate;
|
||||
unsigned int mean_count;
|
||||
/* Time delay for updates. */
|
||||
short delay;
|
||||
/* If the stream is actually VBR. */
|
||||
char vbr;
|
||||
struct mp_audio frame;
|
||||
};
|
||||
|
||||
static void uninit(struct dec_audio *da)
|
||||
{
|
||||
struct ad_mpg123_context *con = da->priv;
|
||||
|
||||
mpg123_close(con->handle);
|
||||
mpg123_delete(con->handle);
|
||||
mpg123_exit();
|
||||
}
|
||||
|
||||
/* This initializes libmpg123 and prepares the handle, including funky
|
||||
* parameters. */
|
||||
static int init(struct dec_audio *da, const char *decoder)
|
||||
{
|
||||
int err;
|
||||
struct ad_mpg123_context *con;
|
||||
/* Assumption: You always call preinit + init + uninit, on every file.
|
||||
* But you stop at preinit in case it fails.
|
||||
* If that is not true, one must ensure not to call mpg123_init / exit
|
||||
* twice in a row. */
|
||||
if (mpg123_init() != MPG123_OK)
|
||||
return 0;
|
||||
|
||||
da->priv = talloc_zero(NULL, struct ad_mpg123_context);
|
||||
con = da->priv;
|
||||
/* Auto-choice of optimized decoder (first argument NULL). */
|
||||
con->handle = mpg123_new(NULL, &err);
|
||||
if (!con->handle)
|
||||
goto bad_end;
|
||||
|
||||
/* Basic settings.
|
||||
* Don't spill messages, enable better resync with non-seekable streams.
|
||||
* Give both flags individually without error checking to keep going with
|
||||
* old libmpg123. Generally, it is not fatal if the flags are not
|
||||
* honored */
|
||||
mpg123_param(con->handle, MPG123_ADD_FLAGS, MPG123_QUIET, 0.0);
|
||||
/* Do not bail out on malformed streams at all.
|
||||
* MPlayer does not handle a decoder throwing the towel on crappy input. */
|
||||
mpg123_param(con->handle, MPG123_RESYNC_LIMIT, -1, 0.0);
|
||||
|
||||
/* Open decisions: Configure libmpg123 to force encoding (or stay open about
|
||||
* library builds that support only float or int32 output), (de)configure
|
||||
* gapless decoding (won't work with seeking in MPlayer, though).
|
||||
* Don't forget to eventually enable ReplayGain/RVA support, too.
|
||||
* 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.
|
||||
* 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):
|
||||
mpg123_param(con->handle, MPG123_RVA, MPG123_RVA_MIX, 0.0) */
|
||||
|
||||
/* Prevent funky automatic resampling.
|
||||
* This way, we can be sure that one frame will never produce
|
||||
* more than 1152 stereo samples.
|
||||
* Background:
|
||||
* Going to decode directly to the output buffer. It is important to have
|
||||
* MPG123_AUTO_RESAMPLE disabled for the buffer size being an all-time
|
||||
* limit.
|
||||
* We need at least 1152 samples. dec_audio.c normally guarantees this. */
|
||||
mpg123_param(con->handle, MPG123_REMOVE_FLAGS, MPG123_AUTO_RESAMPLE, 0.);
|
||||
|
||||
err = mpg123_open_feed(con->handle);
|
||||
if (err != MPG123_OK)
|
||||
goto bad_end;
|
||||
|
||||
return 1;
|
||||
|
||||
bad_end:
|
||||
if (!con->handle) {
|
||||
MP_ERR(da, "mpg123 preinit error: %s\n", mpg123_plain_strerror(err));
|
||||
} else {
|
||||
MP_ERR(da, "mpg123 preinit error: %s\n", mpg123_strerror(con->handle));
|
||||
}
|
||||
|
||||
uninit(da);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpg123_format_to_af(int mpg123_encoding)
|
||||
{
|
||||
/* 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 (mpg123_encoding) {
|
||||
case MPG123_ENC_SIGNED_8: return AF_FORMAT_S8;
|
||||
case MPG123_ENC_SIGNED_16: return AF_FORMAT_S16;
|
||||
case MPG123_ENC_SIGNED_32: return AF_FORMAT_S32;
|
||||
case MPG123_ENC_FLOAT_32: return AF_FORMAT_FLOAT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compute bitrate from frame size. */
|
||||
static int compute_bitrate(struct mpg123_frameinfo *i)
|
||||
{
|
||||
static const int samples_per_frame[4][4] = {
|
||||
{-1, 384, 1152, 1152}, /* MPEG 1 */
|
||||
{-1, 384, 1152, 576}, /* MPEG 2 */
|
||||
{-1, 384, 1152, 576}, /* MPEG 2.5 */
|
||||
{-1, -1, -1, -1}, /* Unknown */
|
||||
};
|
||||
return (int) ((i->framesize + 4) * 8 * i->rate /
|
||||
samples_per_frame[i->version][i->layer] + 0.5);
|
||||
}
|
||||
|
||||
/* Update mean bitrate. This could be dropped if accurate time display
|
||||
* on audio file playback is not desired. */
|
||||
static void update_info(struct dec_audio *da)
|
||||
{
|
||||
struct ad_mpg123_context *con = da->priv;
|
||||
struct mpg123_frameinfo finfo;
|
||||
if (mpg123_info(con->handle, &finfo) != MPG123_OK)
|
||||
return;
|
||||
|
||||
/* finfo.bitrate is expressed in kilobits */
|
||||
const int bitrate = finfo.bitrate * 1000;
|
||||
|
||||
if (finfo.vbr != MPG123_CBR) {
|
||||
if (--con->delay < 1) {
|
||||
if (++con->mean_count > ((unsigned int) -1) / 2)
|
||||
con->mean_count = ((unsigned int) -1) / 4;
|
||||
|
||||
/* Might not be numerically optimal, but works fine enough. */
|
||||
con->mean_rate = ((con->mean_count - 1) * con->mean_rate +
|
||||
bitrate) / con->mean_count;
|
||||
da->bitrate = (int) (con->mean_rate + 0.5);
|
||||
|
||||
con->delay = 10;
|
||||
}
|
||||
} else {
|
||||
da->bitrate = bitrate ? bitrate : compute_bitrate(&finfo);
|
||||
con->delay = 1;
|
||||
con->mean_rate = 0.;
|
||||
con->mean_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* libmpg123 has a new format ready; query and store, return return value
|
||||
of mpg123_getformat() */
|
||||
static int set_format(struct dec_audio *da)
|
||||
{
|
||||
struct ad_mpg123_context *con = da->priv;
|
||||
int ret;
|
||||
long rate;
|
||||
int channels;
|
||||
int encoding;
|
||||
ret = mpg123_getformat(con->handle, &rate, &channels, &encoding);
|
||||
if (ret == MPG123_OK) {
|
||||
mp_audio_set_num_channels(&con->frame, channels);
|
||||
con->frame.rate = rate;
|
||||
int af = mpg123_format_to_af(encoding);
|
||||
if (!af) {
|
||||
/* This means we got a funny custom build of libmpg123 that only supports an unknown format. */
|
||||
MP_ERR(da, "Bad encoding from mpg123: %i.\n", encoding);
|
||||
return MPG123_ERR;
|
||||
}
|
||||
mp_audio_set_format(&con->frame, af);
|
||||
con->sample_size = channels * af_fmt2bps(af);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int decode_packet(struct dec_audio *da, struct mp_audio **out)
|
||||
{
|
||||
struct ad_mpg123_context *con = da->priv;
|
||||
int ret;
|
||||
|
||||
struct demux_packet *pkt;
|
||||
if (demux_read_packet_async(da->header, &pkt) == 0)
|
||||
return AD_WAIT;
|
||||
if (!pkt)
|
||||
return AD_EOF;
|
||||
|
||||
/* Next bytes from that presentation time. */
|
||||
if (pkt->pts != MP_NOPTS_VALUE) {
|
||||
da->pts = pkt->pts;
|
||||
da->pts_offset = 0;
|
||||
}
|
||||
|
||||
/* Have to use mpg123_feed() to avoid decoding here. */
|
||||
ret = mpg123_feed(con->handle, pkt->buffer, pkt->len);
|
||||
talloc_free(pkt);
|
||||
|
||||
if (ret != MPG123_OK)
|
||||
goto mpg123_fail;
|
||||
|
||||
unsigned char *audio = NULL;
|
||||
size_t bytes = 0;
|
||||
ret = mpg123_decode_frame(con->handle, NULL, &audio, &bytes);
|
||||
|
||||
if (ret == MPG123_NEED_MORE)
|
||||
return 0;
|
||||
|
||||
if (ret != MPG123_OK && ret != MPG123_DONE && ret != MPG123_NEW_FORMAT)
|
||||
goto mpg123_fail;
|
||||
|
||||
ret = set_format(da);
|
||||
if (ret != MPG123_OK)
|
||||
goto mpg123_fail;
|
||||
|
||||
if (con->sample_size < 1) {
|
||||
MP_ERR(da, "no sample size\n");
|
||||
return AD_ERR;
|
||||
}
|
||||
|
||||
int got_samples = bytes / con->sample_size;
|
||||
*out = mp_audio_pool_get(da->pool, &con->frame, got_samples);
|
||||
if (!*out)
|
||||
return AD_ERR;
|
||||
|
||||
memcpy((*out)->planes[0], audio, bytes);
|
||||
|
||||
update_info(da);
|
||||
return 0;
|
||||
|
||||
mpg123_fail:
|
||||
MP_ERR(da, "mpg123 decoding error: %s\n", mpg123_strerror(con->handle));
|
||||
return AD_ERR;
|
||||
}
|
||||
|
||||
static int control(struct dec_audio *da, int cmd, void *arg)
|
||||
{
|
||||
struct ad_mpg123_context *con = da->priv;
|
||||
|
||||
switch (cmd) {
|
||||
case ADCTRL_RESET:
|
||||
mpg123_close(con->handle);
|
||||
|
||||
if (mpg123_open_feed(con->handle) != MPG123_OK) {
|
||||
MP_ERR(da, "mpg123 failed to reopen stream: %s\n",
|
||||
mpg123_strerror(con->handle));
|
||||
return CONTROL_FALSE;
|
||||
}
|
||||
return CONTROL_TRUE;
|
||||
}
|
||||
return CONTROL_UNKNOWN;
|
||||
}
|
||||
|
||||
static void add_decoders(struct mp_decoder_list *list)
|
||||
{
|
||||
mp_add_decoder(list, "mpg123", "mp3", "mp3",
|
||||
"High-performance decoder using libmpg123");
|
||||
}
|
||||
|
||||
const struct ad_functions ad_mpg123 = {
|
||||
.name = "mpg123",
|
||||
.add_decoders = add_decoders,
|
||||
.init = init,
|
||||
.uninit = uninit,
|
||||
.control = control,
|
||||
.decode_packet = decode_packet,
|
||||
};
|
||||
+5
-14
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* Copyright (C) 2012 Naoya OYAMA
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@@ -36,7 +35,6 @@
|
||||
struct spdifContext {
|
||||
struct mp_log *log;
|
||||
AVFormatContext *lavf_ctx;
|
||||
int iec61937_packet_size;
|
||||
int out_buffer_len;
|
||||
uint8_t out_buffer[OUTBUF_SIZE];
|
||||
bool need_close;
|
||||
@@ -117,13 +115,11 @@ static int init(struct dec_audio *da, const char *decoder)
|
||||
int samplerate = 0;
|
||||
switch (stream->codec->codec_id) {
|
||||
case AV_CODEC_ID_AAC:
|
||||
spdif_ctx->iec61937_packet_size = 16384;
|
||||
sample_format = AF_FORMAT_S_AAC;
|
||||
samplerate = 48000;
|
||||
num_channels = 2;
|
||||
break;
|
||||
case AV_CODEC_ID_AC3:
|
||||
spdif_ctx->iec61937_packet_size = 6144;
|
||||
sample_format = AF_FORMAT_S_AC3;
|
||||
samplerate = 48000;
|
||||
num_channels = 2;
|
||||
@@ -131,31 +127,26 @@ static int init(struct dec_audio *da, const char *decoder)
|
||||
case AV_CODEC_ID_DTS:
|
||||
if (da->opts->dtshd) {
|
||||
av_dict_set(&format_opts, "dtshd_rate", "768000", 0); // 4*192000
|
||||
spdif_ctx->iec61937_packet_size = 32768;
|
||||
sample_format = AF_FORMAT_S_DTSHD;
|
||||
samplerate = 192000;
|
||||
num_channels = 2*4;
|
||||
} else {
|
||||
spdif_ctx->iec61937_packet_size = 32768;
|
||||
sample_format = AF_FORMAT_S_DTS;
|
||||
samplerate = 48000;
|
||||
num_channels = 2;
|
||||
}
|
||||
break;
|
||||
case AV_CODEC_ID_EAC3:
|
||||
spdif_ctx->iec61937_packet_size = 24576;
|
||||
sample_format = AF_FORMAT_S_EAC3;
|
||||
samplerate = 192000;
|
||||
num_channels = 2;
|
||||
break;
|
||||
case AV_CODEC_ID_MP3:
|
||||
spdif_ctx->iec61937_packet_size = 4608;
|
||||
sample_format = AF_FORMAT_S_MP3;
|
||||
samplerate = 48000;
|
||||
num_channels = 2;
|
||||
break;
|
||||
case AV_CODEC_ID_TRUEHD:
|
||||
spdif_ctx->iec61937_packet_size = 61440;
|
||||
sample_format = AF_FORMAT_S_TRUEHD;
|
||||
samplerate = 192000;
|
||||
num_channels = 8;
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -25,7 +24,6 @@
|
||||
|
||||
#include "demux/codec_tags.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "common/codecs.h"
|
||||
#include "common/msg.h"
|
||||
#include "misc/bstr.h"
|
||||
@@ -43,15 +41,11 @@
|
||||
|
||||
#include "audio/filter/af.h"
|
||||
|
||||
extern const struct ad_functions ad_mpg123;
|
||||
extern const struct ad_functions ad_lavc;
|
||||
extern const struct ad_functions ad_spdif;
|
||||
|
||||
static const struct ad_functions * const ad_drivers[] = {
|
||||
&ad_lavc,
|
||||
#if HAVE_MPG123
|
||||
&ad_mpg123,
|
||||
#endif
|
||||
&ad_spdif,
|
||||
NULL
|
||||
};
|
||||
@@ -164,6 +158,9 @@ static int decode_new_frame(struct dec_audio *da)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (da->pts == MP_NOPTS_VALUE && da->header->missing_timestamps)
|
||||
da->pts = 0;
|
||||
|
||||
if (da->waiting) {
|
||||
da->pts_offset += da->waiting->samples;
|
||||
da->decode_format = *da->waiting;
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_DEC_AUDIO_H
|
||||
|
||||
+45
-14
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -54,11 +53,11 @@ extern const struct af_info af_info_center;
|
||||
extern const struct af_info af_info_sinesuppress;
|
||||
extern const struct af_info af_info_karaoke;
|
||||
extern const struct af_info af_info_scaletempo;
|
||||
extern const struct af_info af_info_forcespeed;
|
||||
extern const struct af_info af_info_bs2b;
|
||||
extern const struct af_info af_info_lavfi;
|
||||
extern const struct af_info af_info_convert24;
|
||||
extern const struct af_info af_info_convertsignendian;
|
||||
extern const struct af_info af_info_rubberband;
|
||||
|
||||
static const struct af_info *const filter_list[] = {
|
||||
&af_info_dummy,
|
||||
@@ -79,11 +78,13 @@ static const struct af_info *const filter_list[] = {
|
||||
&af_info_hrtf,
|
||||
#if HAVE_LADSPA
|
||||
&af_info_ladspa,
|
||||
#endif
|
||||
#if HAVE_RUBBERBAND
|
||||
&af_info_rubberband,
|
||||
#endif
|
||||
&af_info_center,
|
||||
&af_info_sinesuppress,
|
||||
&af_info_karaoke,
|
||||
&af_info_forcespeed,
|
||||
&af_info_scaletempo,
|
||||
#if HAVE_LIBBS2B
|
||||
&af_info_bs2b,
|
||||
@@ -503,6 +504,15 @@ static int af_fix_rate(struct af_stream *s, struct af_instance **p_af,
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
static void reset_formats(struct af_stream *s)
|
||||
{
|
||||
for (struct af_instance *af = s->first; af; af = af->next) {
|
||||
af->control(af, AF_CONTROL_SET_RESAMPLE_RATE, &(int){0});
|
||||
af->control(af, AF_CONTROL_SET_CHANNELS, &(struct mp_chmap){0});
|
||||
af->control(af, AF_CONTROL_SET_FORMAT, &(int){0});
|
||||
}
|
||||
}
|
||||
|
||||
// Return AF_OK on success or AF_ERROR on failure.
|
||||
// Warning:
|
||||
// A failed af_reinit() leaves the audio chain behind in a useless, broken
|
||||
@@ -513,6 +523,7 @@ static int af_reinit(struct af_stream *s)
|
||||
{
|
||||
remove_auto_inserted_filters(s);
|
||||
af_chain_forget_frames(s);
|
||||
reset_formats(s);
|
||||
s->first->fmt_in = s->first->fmt_out = s->input;
|
||||
// Start with the second filter, as the first filter is the special input
|
||||
// filter which needs no initialization.
|
||||
@@ -559,6 +570,23 @@ static int af_reinit(struct af_stream *s)
|
||||
retry++;
|
||||
continue;
|
||||
}
|
||||
// If the format conversion is (probably) caused by spdif, then
|
||||
// (as a feature) drop the filter, instead of failing hard.
|
||||
int fmt_in1 = af->prev->data->format;
|
||||
int fmt_in2 = in.format;
|
||||
if (af_fmt_is_valid(fmt_in1) && af_fmt_is_valid(fmt_in2)) {
|
||||
bool spd1 = AF_FORMAT_IS_IEC61937(fmt_in1);
|
||||
bool spd2 = AF_FORMAT_IS_IEC61937(fmt_in2);
|
||||
if (spd1 != spd2) {
|
||||
MP_WARN(af, "Filter %s apparently cannot be used due to "
|
||||
"spdif passthrough - removing it.\n",
|
||||
af->info->name);
|
||||
struct af_instance *aft = af->prev;
|
||||
af_remove(s, af);
|
||||
af = aft->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
goto negotiate_error;
|
||||
}
|
||||
case AF_DETACH: { // Filter is redundant and wants to be unloaded
|
||||
@@ -687,8 +715,14 @@ int af_init(struct af_stream *s)
|
||||
to the stream s. The filter will be inserted somewhere nice in the
|
||||
list of filters. The return value is a pointer to the new filter,
|
||||
If the filter couldn't be added the return value is NULL. */
|
||||
struct af_instance *af_add(struct af_stream *s, char *name, char **args)
|
||||
struct af_instance *af_add(struct af_stream *s, char *name, char *label,
|
||||
char **args)
|
||||
{
|
||||
assert(label);
|
||||
|
||||
if (af_find_by_label(s, label))
|
||||
return NULL;
|
||||
|
||||
struct af_instance *new;
|
||||
// Insert the filter somewhere nice
|
||||
if (af_is_conversion_filter(s->first->next))
|
||||
@@ -697,17 +731,14 @@ struct af_instance *af_add(struct af_stream *s, char *name, char **args)
|
||||
new = af_prepend(s, s->first->next, name, args);
|
||||
if (!new)
|
||||
return NULL;
|
||||
new->label = talloc_strdup(new, label);
|
||||
|
||||
// Reinitalize the filter list
|
||||
if (af_reinit(s) != AF_OK) {
|
||||
af_remove(s, new);
|
||||
if (af_reinit(s) != AF_OK) {
|
||||
af_uninit(s);
|
||||
af_init(s);
|
||||
}
|
||||
af_remove_by_label(s, label);
|
||||
return NULL;
|
||||
}
|
||||
return new;
|
||||
return af_find_by_label(s, label);
|
||||
}
|
||||
|
||||
struct af_instance *af_find_by_label(struct af_stream *s, char *label)
|
||||
|
||||
+6
-8
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_AF_H
|
||||
@@ -141,7 +140,8 @@ struct af_stream *af_new(struct mpv_global *global);
|
||||
void af_destroy(struct af_stream *s);
|
||||
int af_init(struct af_stream *s);
|
||||
void af_uninit(struct af_stream *s);
|
||||
struct af_instance *af_add(struct af_stream *s, char *name, char **args);
|
||||
struct af_instance *af_add(struct af_stream *s, char *name, char *label,
|
||||
char **args);
|
||||
int af_remove_by_label(struct af_stream *s, char *label);
|
||||
struct af_instance *af_find_by_label(struct af_stream *s, char *label);
|
||||
struct af_instance *af_control_any_rev(struct af_stream *s, int cmd, void *arg);
|
||||
@@ -159,9 +159,7 @@ double af_calc_delay(struct af_stream *s);
|
||||
int af_test_output(struct af_instance *af, struct mp_audio *out);
|
||||
|
||||
int af_from_dB(int n, float *in, float *out, float k, float mi, float ma);
|
||||
int af_to_dB(int n, float *in, float *out, float k);
|
||||
int af_from_ms(int n, float *in, int *out, int rate, float mi, float ma);
|
||||
int af_to_ms(int n, int *in, float *out, int rate);
|
||||
float af_softclip(float a);
|
||||
|
||||
#endif /* MPLAYER_AF_H */
|
||||
@@ -4,21 +4,20 @@
|
||||
*
|
||||
* Copyright (c) 2009 Andrew Savchenko
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <bs2b.h>
|
||||
@@ -164,7 +163,8 @@ const struct af_info af_info_bs2b = {
|
||||
OPT_INTRANGE("fcut", fcut, 0, BS2B_MINFCUT, BS2B_MAXFCUT),
|
||||
OPT_INTRANGE("feed", feed, 0, BS2B_MINFEED, BS2B_MAXFEED),
|
||||
OPT_CHOICE("profile", profile, 0,
|
||||
({"default", BS2B_DEFAULT_CLEVEL},
|
||||
({"unset", 0},
|
||||
{"default", BS2B_DEFAULT_CLEVEL},
|
||||
{"cmoy", BS2B_CMOY_CLEVEL},
|
||||
{"jmeier", BS2B_JMEIER_CLEVEL})),
|
||||
{0}
|
||||
|
||||
@@ -8,21 +8,20 @@
|
||||
*
|
||||
* copyright (c) 2005 Alex Beregszaszi
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -5,21 +5,20 @@
|
||||
*
|
||||
* Original author: Anders
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -5,21 +5,20 @@
|
||||
*
|
||||
* Original author: Anders
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Alex Beregszaszi & Pierre Lombard
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -4,21 +4,20 @@
|
||||
*
|
||||
* Original author: Anders
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -6,21 +6,20 @@
|
||||
*
|
||||
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -9,21 +9,20 @@
|
||||
*
|
||||
* Authors: Anders; Gustavo Sverzut Barbieri <gustavo.barbieri@ic.unicamp.br>
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Alex Beregszaszi & Pierre Lombard
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* 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 "af.h"
|
||||
|
||||
struct priv {
|
||||
double speed;
|
||||
};
|
||||
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
{
|
||||
struct priv *priv = af->priv;
|
||||
|
||||
switch (cmd) {
|
||||
case AF_CONTROL_REINIT: {
|
||||
struct mp_audio *in = arg;
|
||||
struct mp_audio orig_in = *in;
|
||||
struct mp_audio *out = af->data;
|
||||
|
||||
mp_audio_copy_config(out, in);
|
||||
out->rate = in->rate * priv->speed;
|
||||
|
||||
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
|
||||
}
|
||||
case AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE: {
|
||||
priv->speed = *(double *)arg;
|
||||
return AF_OK;
|
||||
}
|
||||
}
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
{
|
||||
if (data)
|
||||
mp_audio_copy_config(data, af->data);
|
||||
af_add_output_frame(af, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int af_open(struct af_instance *af)
|
||||
{
|
||||
struct priv *priv = af->priv;
|
||||
af->control = control;
|
||||
af->filter_frame = filter;
|
||||
priv->speed = 1.0;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct priv
|
||||
|
||||
const struct af_info af_info_forcespeed = {
|
||||
.info = "Force audio speed",
|
||||
.name = "forcespeed",
|
||||
.open = af_open,
|
||||
.priv_size = sizeof(struct priv),
|
||||
};
|
||||
@@ -5,21 +5,20 @@
|
||||
*
|
||||
* Author: ylai
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_AF_HRTF_H
|
||||
|
||||
@@ -4,21 +4,20 @@
|
||||
* copyright (c) 2006 Reynaldo H. Verdejo Pinochet
|
||||
* Based on code by Alex Beregszaszi for his 'center' filter.
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -4,21 +4,20 @@
|
||||
* Written by Ivo van Poorten <ivop@euronet.nl>
|
||||
* Copyright (C) 2004, 2005
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
@@ -3,21 +3,20 @@
|
||||
*
|
||||
* Copyright (C) 2007 Ulion <ulion A gmail P com>
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
+27
-1
@@ -61,6 +61,8 @@ struct priv {
|
||||
|
||||
AVRational timebase_out;
|
||||
|
||||
bool eof;
|
||||
|
||||
// options
|
||||
char *cfg_graph;
|
||||
char **cfg_avopts;
|
||||
@@ -71,6 +73,8 @@ static void destroy_graph(struct af_instance *af)
|
||||
struct priv *p = af->priv;
|
||||
avfilter_graph_free(&p->graph);
|
||||
p->in = p->out = NULL;
|
||||
p->samples_in = 0;
|
||||
p->eof = false;
|
||||
}
|
||||
|
||||
static bool recreate_graph(struct af_instance *af, struct mp_audio *config)
|
||||
@@ -167,6 +171,12 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void reset(struct af_instance *af)
|
||||
{
|
||||
if (!recreate_graph(af, &af->fmt_in))
|
||||
MP_FATAL(af, "Can't recreate libavfilter filter after a seek reset.\n");
|
||||
}
|
||||
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
@@ -203,6 +213,9 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
|
||||
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
|
||||
}
|
||||
case AF_CONTROL_RESET:
|
||||
reset(af);
|
||||
return AF_OK;
|
||||
}
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
@@ -210,9 +223,16 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
static int filter_frame(struct af_instance *af, struct mp_audio *data)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
AVFrame *frame = NULL;
|
||||
|
||||
if (p->eof && data)
|
||||
reset(af);
|
||||
|
||||
if (!p->graph)
|
||||
goto error;
|
||||
|
||||
AVFilterLink *l_in = p->in->outputs[0];
|
||||
|
||||
AVFrame *frame = NULL;
|
||||
if (data) {
|
||||
frame = av_frame_alloc();
|
||||
if (!frame)
|
||||
@@ -255,6 +275,9 @@ static int filter_out(struct af_instance *af)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
|
||||
if (!p->graph)
|
||||
goto error;
|
||||
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
if (!frame)
|
||||
goto error;
|
||||
@@ -262,7 +285,10 @@ static int filter_out(struct af_instance *af)
|
||||
int err = av_buffersink_get_frame(p->out, frame);
|
||||
if (err == AVERROR(EAGAIN) || err == AVERROR_EOF) {
|
||||
// Not an error situation - no more output buffers in queue.
|
||||
// AVERROR_EOF means we shouldn't even give the filter more
|
||||
// input, but we don't handle that completely correctly.
|
||||
av_frame_free(&frame);
|
||||
p->eof |= err == AVERROR_EOF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,28 +2,29 @@
|
||||
* Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (c) 2013 Stefano Pigozzi <stefano.pigozzi@gmail.com>
|
||||
*
|
||||
* This file is part of mpv.
|
||||
* Based on Michael Niedermayer's lavcresample.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <libavutil/opt.h>
|
||||
@@ -32,7 +33,7 @@
|
||||
#include <libavutil/samplefmt.h>
|
||||
#include <libavutil/mathematics.h>
|
||||
|
||||
#include "talloc.h"
|
||||
#include "common/common.h"
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_LIBAVRESAMPLE
|
||||
@@ -64,7 +65,8 @@ struct af_resample_opts {
|
||||
int linear;
|
||||
double cutoff;
|
||||
|
||||
int in_rate;
|
||||
int in_rate_af; // filter input sample rate
|
||||
int in_rate; // actual rate (used by lavr), adjusted for playback speed
|
||||
int in_format;
|
||||
struct mp_chmap in_channels;
|
||||
int out_rate;
|
||||
@@ -75,6 +77,9 @@ struct af_resample_opts {
|
||||
struct af_resample {
|
||||
int allow_detach;
|
||||
char **avopts;
|
||||
double playback_speed;
|
||||
struct mp_audio *pending;
|
||||
bool avrctx_ok;
|
||||
struct AVAudioResampleContext *avrctx;
|
||||
struct AVAudioResampleContext *avrctx_out; // for output channel reordering
|
||||
struct af_resample_opts ctx; // opts in the context
|
||||
@@ -94,6 +99,10 @@ static void drop_all_output(struct af_resample *s)
|
||||
{
|
||||
while (avresample_read(s->avrctx, NULL, 1000) > 0) {}
|
||||
}
|
||||
static int get_drain_samples(struct af_resample *s)
|
||||
{
|
||||
return avresample_get_out_samples(s->avrctx, 0);
|
||||
}
|
||||
#else
|
||||
static int get_delay(struct af_resample *s)
|
||||
{
|
||||
@@ -103,18 +112,39 @@ static void drop_all_output(struct af_resample *s)
|
||||
{
|
||||
while (swr_drop_output(s->avrctx, 1000) > 0) {}
|
||||
}
|
||||
static int get_drain_samples(struct af_resample *s)
|
||||
{
|
||||
return 4096; // libswscale does not have this
|
||||
}
|
||||
#endif
|
||||
|
||||
static int resample_frame(struct AVAudioResampleContext *r,
|
||||
struct mp_audio *out, struct mp_audio *in)
|
||||
{
|
||||
return avresample_convert(r,
|
||||
out ? (uint8_t **)out->planes : NULL,
|
||||
out ? mp_audio_get_allocated_size(out) : 0,
|
||||
out ? out->samples : 0,
|
||||
in ? (uint8_t **)in->planes : NULL,
|
||||
in ? mp_audio_get_allocated_size(in) : 0,
|
||||
in ? in->samples : 0);
|
||||
}
|
||||
|
||||
static double af_resample_default_cutoff(int filter_size)
|
||||
{
|
||||
return FFMAX(1.0 - 6.5 / (filter_size + 8), 0.80);
|
||||
}
|
||||
|
||||
static int rate_from_speed(int rate, double speed)
|
||||
{
|
||||
return lrint(rate * speed);
|
||||
}
|
||||
|
||||
static bool needs_lavrctx_reconfigure(struct af_resample *s,
|
||||
struct mp_audio *in,
|
||||
struct mp_audio *out)
|
||||
{
|
||||
return s->ctx.in_rate != in->rate ||
|
||||
return s->ctx.in_rate_af != in->rate ||
|
||||
s->ctx.in_format != in->format ||
|
||||
!mp_chmap_equals(&s->ctx.in_channels, &in->channels) ||
|
||||
s->ctx.out_rate != out->rate ||
|
||||
@@ -138,6 +168,8 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
|
||||
{
|
||||
struct af_resample *s = af->priv;
|
||||
|
||||
s->avrctx_ok = false;
|
||||
|
||||
enum AVSampleFormat in_samplefmt = af_to_avformat(in->format);
|
||||
enum AVSampleFormat out_samplefmt = af_to_avformat(out->format);
|
||||
|
||||
@@ -147,8 +179,12 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
|
||||
avresample_close(s->avrctx);
|
||||
avresample_close(s->avrctx_out);
|
||||
|
||||
talloc_free(s->pending);
|
||||
s->pending = NULL;
|
||||
|
||||
s->ctx.out_rate = out->rate;
|
||||
s->ctx.in_rate = in->rate;
|
||||
s->ctx.in_rate_af = in->rate;
|
||||
s->ctx.in_rate = rate_from_speed(in->rate, s->playback_speed);
|
||||
s->ctx.out_format = out->format;
|
||||
s->ctx.in_format = in->format;
|
||||
s->ctx.out_channels= out->channels;
|
||||
@@ -164,6 +200,10 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
|
||||
|
||||
av_opt_set_double(s->avrctx, "cutoff", s->ctx.cutoff, 0);
|
||||
|
||||
#if HAVE_LIBSWRESAMPLE
|
||||
av_opt_set_double(s->avrctx, "rematrix_maxval", 1.0, 0);
|
||||
#endif
|
||||
|
||||
if (mp_set_avopts(af->log, s->avrctx, s->avopts) < 0)
|
||||
return AF_ERROR;
|
||||
|
||||
@@ -217,24 +257,25 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
|
||||
MP_ERR(af, "Cannot open Libavresample Context. \n");
|
||||
return AF_ERROR;
|
||||
}
|
||||
s->avrctx_ok = true;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
{
|
||||
struct af_resample *s = (struct af_resample *) af->priv;
|
||||
struct mp_audio *in = (struct mp_audio *) arg;
|
||||
struct mp_audio *out = (struct mp_audio *) af->data;
|
||||
struct af_resample *s = af->priv;
|
||||
|
||||
switch (cmd) {
|
||||
case AF_CONTROL_REINIT: {
|
||||
struct mp_audio *in = arg;
|
||||
struct mp_audio *out = af->data;
|
||||
struct mp_audio orig_in = *in;
|
||||
|
||||
if (((out->rate == in->rate) || (out->rate == 0)) &&
|
||||
(out->format == in->format) &&
|
||||
(mp_chmap_equals(&out->channels, &in->channels) || out->nch == 0) &&
|
||||
s->allow_detach)
|
||||
s->allow_detach && s->playback_speed == 1.0)
|
||||
return AF_DETACH;
|
||||
|
||||
if (out->rate == 0)
|
||||
@@ -257,10 +298,11 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
return r;
|
||||
}
|
||||
case AF_CONTROL_SET_FORMAT: {
|
||||
if (af_to_avformat(*(int*)arg) == AV_SAMPLE_FMT_NONE)
|
||||
int format = *(int *)arg;
|
||||
if (format && af_to_avformat(format) == AV_SAMPLE_FMT_NONE)
|
||||
return AF_FALSE;
|
||||
|
||||
mp_audio_set_format(af->data, *(int*)arg);
|
||||
mp_audio_set_format(af->data, format);
|
||||
return AF_OK;
|
||||
}
|
||||
case AF_CONTROL_SET_CHANNELS: {
|
||||
@@ -268,8 +310,28 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
return AF_OK;
|
||||
}
|
||||
case AF_CONTROL_SET_RESAMPLE_RATE:
|
||||
out->rate = *(int *)arg;
|
||||
af->data->rate = *(int *)arg;
|
||||
return AF_OK;
|
||||
case AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE: {
|
||||
s->playback_speed = *(double *)arg;
|
||||
int new_rate = rate_from_speed(s->ctx.in_rate_af, s->playback_speed);
|
||||
if (new_rate != s->ctx.in_rate && s->avrctx_ok && af->fmt_out.format) {
|
||||
// Before reconfiguring, drain the audio that is still buffered
|
||||
// in the resampler.
|
||||
struct mp_audio *pending = talloc_zero(NULL, struct mp_audio);
|
||||
mp_audio_copy_config(pending, &af->fmt_out);
|
||||
pending->samples = get_drain_samples(s);
|
||||
if (pending->samples > 0) {
|
||||
mp_audio_realloc_min(pending, pending->samples);
|
||||
int r = resample_frame(s->avrctx, pending, NULL);
|
||||
pending->samples = MPMAX(r, 0);
|
||||
}
|
||||
// Reinitialize resampler.
|
||||
configure_lavrr(af, &af->fmt_in, &af->fmt_out);
|
||||
s->pending = pending;
|
||||
}
|
||||
return AF_OK;
|
||||
}
|
||||
case AF_CONTROL_RESET:
|
||||
drop_all_output(s);
|
||||
return AF_OK;
|
||||
@@ -289,6 +351,7 @@ static void uninit(struct af_instance *af)
|
||||
if (s->avrctx_out)
|
||||
avresample_close(s->avrctx_out);
|
||||
avresample_free(&s->avrctx_out);
|
||||
talloc_free(s->pending);
|
||||
}
|
||||
|
||||
static bool needs_reorder(int *reorder, int num_ch)
|
||||
@@ -309,22 +372,19 @@ static void reorder_planes(struct mp_audio *mpa, int *reorder)
|
||||
}
|
||||
}
|
||||
|
||||
static int resample_frame(struct AVAudioResampleContext *r,
|
||||
struct mp_audio *out, struct mp_audio *in)
|
||||
{
|
||||
return avresample_convert(r,
|
||||
out ? (uint8_t **)out->planes : NULL,
|
||||
out ? mp_audio_get_allocated_size(out) : 0,
|
||||
out ? out->samples : 0,
|
||||
in ? (uint8_t **)in->planes : NULL,
|
||||
in ? mp_audio_get_allocated_size(in) : 0,
|
||||
in ? in->samples : 0);
|
||||
}
|
||||
|
||||
static int filter(struct af_instance *af, struct mp_audio *in)
|
||||
{
|
||||
struct af_resample *s = af->priv;
|
||||
|
||||
if (s->pending) {
|
||||
if (s->pending->samples) {
|
||||
af_add_output_frame(af, s->pending);
|
||||
} else {
|
||||
talloc_free(s->pending);
|
||||
}
|
||||
s->pending = NULL;
|
||||
}
|
||||
|
||||
int samples = avresample_available(s->avrctx) +
|
||||
av_rescale_rnd(get_delay(s) + (in ? in->samples : 0),
|
||||
s->ctx.out_rate, s->ctx.in_rate, AV_ROUND_UP);
|
||||
@@ -345,7 +405,7 @@ static int filter(struct af_instance *af, struct mp_audio *in)
|
||||
}
|
||||
|
||||
if (needs_reorder(s->reorder_out, out->nch)) {
|
||||
if (af_fmt_is_planar(out->format)) {
|
||||
if (AF_FORMAT_IS_PLANAR(out->format)) {
|
||||
reorder_planes(out, s->reorder_out);
|
||||
} else if (out->samples) {
|
||||
struct mp_audio *new = mp_audio_pool_get(s->reorder_buffer, out,
|
||||
@@ -412,6 +472,7 @@ const struct af_info af_info_lavrresample = {
|
||||
.cutoff = 0.0,
|
||||
.phase_shift = 10,
|
||||
},
|
||||
.playback_speed = 1.0,
|
||||
.allow_detach = 1,
|
||||
},
|
||||
.options = (const struct m_option[]) {
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Anders Johansson ajh@atri.curtin.edu.au
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <rubberband/rubberband-c.h>
|
||||
|
||||
#include "common/common.h"
|
||||
#include "af.h"
|
||||
|
||||
struct priv {
|
||||
RubberBandState rubber;
|
||||
double speed;
|
||||
struct mp_audio *pending;
|
||||
bool needs_reset;
|
||||
// Estimate how much librubberband has buffered internally.
|
||||
// I could not find a way to do this with the librubberband API.
|
||||
double rubber_delay;
|
||||
// command line options
|
||||
int opt_transients, opt_detector, opt_phase, opt_window,
|
||||
opt_smoothing, opt_formant, opt_pitch, opt_channels;
|
||||
};
|
||||
|
||||
static void update_speed(struct af_instance *af, double new_speed)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
|
||||
p->speed = new_speed;
|
||||
rubberband_set_time_ratio(p->rubber, 1.0 / p->speed);
|
||||
}
|
||||
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
|
||||
switch (cmd) {
|
||||
case AF_CONTROL_REINIT: {
|
||||
struct mp_audio *in = arg;
|
||||
struct mp_audio orig_in = *in;
|
||||
struct mp_audio *out = af->data;
|
||||
|
||||
in->format = AF_FORMAT_FLOATP;
|
||||
mp_audio_copy_config(out, in);
|
||||
|
||||
if (p->rubber)
|
||||
rubberband_delete(p->rubber);
|
||||
|
||||
int opts = p->opt_transients | p->opt_detector | p->opt_phase |
|
||||
p->opt_window | p->opt_smoothing | p->opt_formant |
|
||||
p->opt_pitch | p-> opt_channels |
|
||||
RubberBandOptionProcessRealTime;
|
||||
|
||||
p->rubber = rubberband_new(in->rate, in->channels.num, opts, 1.0, 1.0);
|
||||
if (!p->rubber) {
|
||||
MP_FATAL(af, "librubberband initialization failed.\n");
|
||||
return AF_ERROR;
|
||||
}
|
||||
|
||||
update_speed(af, p->speed);
|
||||
control(af, AF_CONTROL_RESET, NULL);
|
||||
|
||||
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
|
||||
}
|
||||
case AF_CONTROL_SET_PLAYBACK_SPEED: {
|
||||
update_speed(af, *(double *)arg);
|
||||
return AF_OK;
|
||||
}
|
||||
case AF_CONTROL_RESET:
|
||||
if (p->rubber)
|
||||
rubberband_reset(p->rubber);
|
||||
talloc_free(p->pending);
|
||||
p->pending = NULL;
|
||||
p->rubber_delay = 0;
|
||||
return AF_OK;
|
||||
}
|
||||
return AF_UNKNOWN;
|
||||
}
|
||||
|
||||
static int filter_frame(struct af_instance *af, struct mp_audio *data)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
|
||||
talloc_free(p->pending);
|
||||
p->pending = data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int filter_out(struct af_instance *af)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
|
||||
while (rubberband_available(p->rubber) <= 0) {
|
||||
const float *dummy[MP_NUM_CHANNELS] = {0};
|
||||
const float **in_data = dummy;
|
||||
size_t in_samples = 0;
|
||||
if (p->pending) {
|
||||
if (!p->pending->samples)
|
||||
break;
|
||||
|
||||
// recover from previous EOF
|
||||
if (p->needs_reset) {
|
||||
rubberband_reset(p->rubber);
|
||||
p->rubber_delay = 0;
|
||||
}
|
||||
p->needs_reset = false;
|
||||
|
||||
size_t needs = rubberband_get_samples_required(p->rubber);
|
||||
in_data = (void *)&p->pending->planes;
|
||||
in_samples = MPMIN(p->pending->samples, needs);
|
||||
}
|
||||
|
||||
if (p->needs_reset)
|
||||
break; // previous EOF
|
||||
p->needs_reset = !p->pending; // EOF
|
||||
|
||||
rubberband_process(p->rubber, in_data, in_samples, p->needs_reset);
|
||||
p->rubber_delay += in_samples;
|
||||
|
||||
if (!p->pending)
|
||||
break;
|
||||
mp_audio_skip_samples(p->pending, in_samples);
|
||||
}
|
||||
|
||||
int out_samples = rubberband_available(p->rubber);
|
||||
if (out_samples > 0) {
|
||||
struct mp_audio *out =
|
||||
mp_audio_pool_get(af->out_pool, af->data, out_samples);
|
||||
if (!out)
|
||||
return -1;
|
||||
if (p->pending)
|
||||
mp_audio_copy_config(out, p->pending);
|
||||
|
||||
float **out_data = (void *)&out->planes;
|
||||
out->samples = rubberband_retrieve(p->rubber, out_data, out->samples);
|
||||
p->rubber_delay -= out->samples * p->speed;
|
||||
|
||||
af_add_output_frame(af, out);
|
||||
}
|
||||
|
||||
int delay_samples = p->rubber_delay;
|
||||
if (p->pending)
|
||||
delay_samples += p->pending->samples;
|
||||
af->delay = delay_samples / (af->data->rate * p->speed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void uninit(struct af_instance *af)
|
||||
{
|
||||
struct priv *p = af->priv;
|
||||
|
||||
if (p->rubber)
|
||||
rubberband_delete(p->rubber);
|
||||
talloc_free(p->pending);
|
||||
}
|
||||
|
||||
static int af_open(struct af_instance *af)
|
||||
{
|
||||
af->control = control;
|
||||
af->filter_frame = filter_frame;
|
||||
af->filter_out = filter_out;
|
||||
af->uninit = uninit;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct priv
|
||||
const struct af_info af_info_rubberband = {
|
||||
.info = "Pitch conversion with librubberband",
|
||||
.name = "rubberband",
|
||||
.open = af_open,
|
||||
.priv_size = sizeof(struct priv),
|
||||
.priv_defaults = &(const struct priv) {
|
||||
.speed = 1.0,
|
||||
.opt_pitch = RubberBandOptionPitchHighConsistency,
|
||||
.opt_transients = RubberBandOptionTransientsMixed,
|
||||
.opt_formant = RubberBandOptionFormantPreserved,
|
||||
},
|
||||
.options = (const struct m_option[]) {
|
||||
OPT_CHOICE("transients", opt_transients, 0,
|
||||
({"crisp", RubberBandOptionTransientsCrisp},
|
||||
{"mixed", RubberBandOptionTransientsMixed},
|
||||
{"smooth", RubberBandOptionTransientsSmooth})),
|
||||
OPT_CHOICE("detector", opt_detector, 0,
|
||||
({"compound", RubberBandOptionDetectorCompound},
|
||||
{"percussive", RubberBandOptionDetectorPercussive},
|
||||
{"soft", RubberBandOptionDetectorSoft})),
|
||||
OPT_CHOICE("phase", opt_phase, 0,
|
||||
({"laminar", RubberBandOptionPhaseLaminar},
|
||||
{"independent", RubberBandOptionPhaseIndependent})),
|
||||
OPT_CHOICE("window", opt_window, 0,
|
||||
({"standard", RubberBandOptionWindowStandard},
|
||||
{"short", RubberBandOptionWindowShort},
|
||||
{"long", RubberBandOptionWindowLong})),
|
||||
OPT_CHOICE("smoothing", opt_smoothing, 0,
|
||||
({"off", RubberBandOptionSmoothingOff},
|
||||
{"on", RubberBandOptionSmoothingOn})),
|
||||
OPT_CHOICE("formant", opt_formant, 0,
|
||||
({"shifted", RubberBandOptionFormantShifted},
|
||||
{"preserved", RubberBandOptionFormantPreserved})),
|
||||
OPT_CHOICE("pitch", opt_pitch, 0,
|
||||
({"quality", RubberBandOptionPitchHighQuality},
|
||||
{"speed", RubberBandOptionPitchHighSpeed},
|
||||
{"consistency", RubberBandOptionPitchHighConsistency})),
|
||||
OPT_CHOICE("channels", opt_channels, 0,
|
||||
({"apart", RubberBandOptionChannelsApart},
|
||||
{"together", RubberBandOptionChannelsTogether})),
|
||||
{0}
|
||||
},
|
||||
};
|
||||
@@ -14,21 +14,20 @@
|
||||
*
|
||||
* Copyright (c) 2007 Robert Juliano
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -76,9 +75,9 @@ typedef struct af_scaletempo_s
|
||||
float ms_stride;
|
||||
float percent_overlap;
|
||||
float ms_search;
|
||||
#define SCALE_TEMPO 1
|
||||
#define SCALE_PITCH 2
|
||||
int speed_opt;
|
||||
short speed_tempo;
|
||||
short speed_pitch;
|
||||
} af_scaletempo_t;
|
||||
|
||||
static int fill_queue(struct af_instance *af, struct mp_audio *data, int offset)
|
||||
@@ -276,6 +275,22 @@ static int filter(struct af_instance *af, struct mp_audio *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void update_speed(struct af_instance *af, float speed)
|
||||
{
|
||||
af_scaletempo_t *s = af->priv;
|
||||
|
||||
s->speed = speed;
|
||||
|
||||
double factor = (s->speed_opt & SCALE_PITCH) ? 1.0 / s->speed : s->speed;
|
||||
s->scale = factor * s->scale_nominal;
|
||||
|
||||
s->frames_stride_scaled = s->scale * s->frames_stride;
|
||||
s->frames_stride_error = MPMIN(s->frames_stride_error, s->frames_stride_scaled);
|
||||
|
||||
MP_VERBOSE(af, "%.3f speed * %.3f scale_nominal = %.3f\n",
|
||||
s->speed, s->scale_nominal, s->scale);
|
||||
}
|
||||
|
||||
// Initialization and runtime control
|
||||
static int control(struct af_instance *af, int cmd, void *arg)
|
||||
{
|
||||
@@ -287,19 +302,9 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
int nch = data->nch;
|
||||
int use_int = 0;
|
||||
|
||||
MP_VERBOSE(af, "%.3f speed * %.3f scale_nominal = %.3f\n",
|
||||
s->speed, s->scale_nominal, s->scale);
|
||||
|
||||
mp_audio_force_interleaved_format(data);
|
||||
mp_audio_copy_config(af->data, data);
|
||||
|
||||
if (s->scale == 1.0) {
|
||||
if (s->speed_tempo && s->speed_pitch)
|
||||
return AF_DETACH;
|
||||
af->delay = 0;
|
||||
return af_test_output(af, data);
|
||||
}
|
||||
|
||||
if (data->format == AF_FORMAT_S16) {
|
||||
use_int = 1;
|
||||
} else {
|
||||
@@ -309,10 +314,10 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
|
||||
s->frames_stride = srate * s->ms_stride;
|
||||
s->bytes_stride = s->frames_stride * bps * nch;
|
||||
s->frames_stride_scaled = s->scale * s->frames_stride;
|
||||
s->frames_stride_error = 0;
|
||||
af->delay = 0;
|
||||
|
||||
update_speed(af, s->speed);
|
||||
|
||||
int frames_overlap = s->frames_stride * s->percent_overlap;
|
||||
if (frames_overlap <= 0) {
|
||||
s->bytes_standing = s->bytes_stride;
|
||||
@@ -422,17 +427,14 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
return af_test_output(af, (struct mp_audio *)arg);
|
||||
}
|
||||
case AF_CONTROL_SET_PLAYBACK_SPEED: {
|
||||
if (s->speed_tempo) {
|
||||
if (s->speed_pitch)
|
||||
double speed = *(double *)arg;
|
||||
if (s->speed_opt & SCALE_TEMPO) {
|
||||
if (s->speed_opt & SCALE_PITCH)
|
||||
break;
|
||||
s->speed = *(double *)arg;
|
||||
s->scale = s->speed * s->scale_nominal;
|
||||
} else {
|
||||
if (s->speed_pitch) {
|
||||
s->speed = 1 / *(double *)arg;
|
||||
s->scale = s->speed * s->scale_nominal;
|
||||
break;
|
||||
}
|
||||
update_speed(af, speed);
|
||||
} else if (s->speed_opt & SCALE_PITCH) {
|
||||
update_speed(af, speed);
|
||||
break; // do not signal OK
|
||||
}
|
||||
return AF_OK;
|
||||
}
|
||||
@@ -456,22 +458,12 @@ static void uninit(struct af_instance *af)
|
||||
free(s->table_window);
|
||||
}
|
||||
|
||||
#define SCALE_TEMPO 1
|
||||
#define SCALE_PITCH 2
|
||||
|
||||
// Allocate memory and set function pointers
|
||||
static int af_open(struct af_instance *af)
|
||||
{
|
||||
af_scaletempo_t *s = af->priv;
|
||||
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->filter_frame = filter;
|
||||
|
||||
s->speed_tempo = !!(s->speed_opt & SCALE_TEMPO);
|
||||
s->speed_pitch = !!(s->speed_opt & SCALE_PITCH);
|
||||
|
||||
s->scale = s->speed * s->scale_nominal;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,21 +3,20 @@
|
||||
* Copyright (C) 2004 Alex Beregszaszi
|
||||
* based upon af_extrastereo.c by Pierre Lombard
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Anders Johansson ajh@watri.uwa.edu.au
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* This filter adds a sub-woofer channels to the audio stream by
|
||||
|
||||
@@ -3,23 +3,22 @@
|
||||
* This will provide a (basic) surround-sound effect from
|
||||
* audio encoded for Dolby Surround, Pro Logic etc.
|
||||
*
|
||||
* original author: Steve Davies <steve@daviesfam.org>
|
||||
* Original author: Steve Davies <steve@daviesfam.org>
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* The principle: Make rear channels by extracting anti-phase data
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Copyright (C)2002 Anders Johansson ajh@atri.curtin.edu.au
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -59,7 +58,7 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
} else {
|
||||
mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
|
||||
}
|
||||
if (af_fmt_is_planar(in->format))
|
||||
if (AF_FORMAT_IS_PLANAR(in->format))
|
||||
mp_audio_set_format(af->data, af_fmt_to_planar(af->data->format));
|
||||
s->rgain = 1.0;
|
||||
if ((s->rgain_track || s->rgain_album) && af->replaygain_data) {
|
||||
|
||||
+4
-5
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Anders Johansson ajh@atri.curtin.edu.au
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_DSP_H
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Anders Johansson ajh@atri.curtin.edu.au
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_EQUALIZER_H
|
||||
|
||||
@@ -3,21 +3,20 @@
|
||||
*
|
||||
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined MPLAYER_DSP_H
|
||||
|
||||
+4
-37
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
@@ -40,24 +39,6 @@ int af_from_dB(int n, float* in, float* out, float k, float mi, float ma)
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
/* Convert from gain value to dB. Returns AF_OK if of and AF_ERROR if
|
||||
* fail. gain=0 will become -200 dB. k is just a multiplier. */
|
||||
int af_to_dB(int n, float* in, float* out, float k)
|
||||
{
|
||||
int i = 0;
|
||||
// Sanity check
|
||||
if(!in || !out)
|
||||
return AF_ERROR;
|
||||
|
||||
for(i=0;i<n;i++){
|
||||
if(in[i] == 0.0)
|
||||
out[i]=-200.0;
|
||||
else
|
||||
out[i]=k*log10(in[i]);
|
||||
}
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
/* Convert from ms to sample time */
|
||||
int af_from_ms(int n, float* in, int* out, int rate, float mi, float ma)
|
||||
{
|
||||
@@ -72,20 +53,6 @@ int af_from_ms(int n, float* in, int* out, int rate, float mi, float ma)
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
/* Convert from sample time to ms */
|
||||
int af_to_ms(int n, int* in, float* out, int rate)
|
||||
{
|
||||
int i = 0;
|
||||
// Sanity check
|
||||
if(!in || !out || !rate)
|
||||
return AF_ERROR;
|
||||
|
||||
for(i=0;i<n;i++)
|
||||
out[i]=1000.0 * (float)in[i]/((float)rate);
|
||||
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* test if output format matches
|
||||
* af: audio filter
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Calculates a number of window functions. The following window
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Calculates a number of window functions. The following window
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libavutil/avutil.h>
|
||||
#include <libavutil/samplefmt.h>
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_SAMPLE_FMT_CONVERSION_H
|
||||
|
||||
+21
-17
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alex Beregszaszi
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -45,11 +44,6 @@ int af_fmt2bits(int format)
|
||||
return af_fmt2bps(format) * 8;
|
||||
}
|
||||
|
||||
bool af_fmt_is_float(int format)
|
||||
{
|
||||
return !!(format & AF_FORMAT_F);
|
||||
}
|
||||
|
||||
static int bits_to_mask(int bits)
|
||||
{
|
||||
switch (bits) {
|
||||
@@ -105,12 +99,6 @@ int af_fmt_from_planar(int format)
|
||||
return format;
|
||||
}
|
||||
|
||||
// false for interleaved and AF_FORMAT_UNKNOWN
|
||||
bool af_fmt_is_planar(int format)
|
||||
{
|
||||
return !!(format & AF_FORMAT_PLANAR);
|
||||
}
|
||||
|
||||
const struct af_fmt_entry af_fmtstr_table[] = {
|
||||
{"u8", AF_FORMAT_U8},
|
||||
{"s8", AF_FORMAT_S8},
|
||||
@@ -161,7 +149,7 @@ const char *af_fmt_to_str(int format)
|
||||
|
||||
int af_fmt_seconds_to_bytes(int format, float seconds, int channels, int samplerate)
|
||||
{
|
||||
assert(!af_fmt_is_planar(format));
|
||||
assert(!AF_FORMAT_IS_PLANAR(format));
|
||||
int bps = af_fmt2bps(format);
|
||||
int framelen = channels * bps;
|
||||
int bytes = seconds * bps * samplerate;
|
||||
@@ -227,3 +215,19 @@ int af_format_conversion_score(int dst_format, int src_format)
|
||||
score -= 2048; // has to convert float<->int
|
||||
return score;
|
||||
}
|
||||
|
||||
// Return the number of samples that make up one frame in this format.
|
||||
// You get the byte size by multiplying them with sample size and channel count.
|
||||
int af_format_sample_alignment(int format)
|
||||
{
|
||||
switch (format) {
|
||||
case AF_FORMAT_S_AAC: return 16384 / 4;
|
||||
case AF_FORMAT_S_AC3: return 6144 / 4;
|
||||
case AF_FORMAT_S_DTSHD: return 32768 / 16;
|
||||
case AF_FORMAT_S_DTS: return 2048 / 4;
|
||||
case AF_FORMAT_S_EAC3: return 24576 / 4;
|
||||
case AF_FORMAT_S_MP3: return 4608 / 4;
|
||||
case AF_FORMAT_S_TRUEHD: return 61440 / 16;
|
||||
default: return 1;
|
||||
}
|
||||
}
|
||||
+9
-7
@@ -3,21 +3,20 @@
|
||||
* The format definition only refers to the storage format,
|
||||
* not the resolution.
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_AF_FORMAT_H
|
||||
@@ -96,6 +95,9 @@ enum af_format {
|
||||
|
||||
#define AF_FORMAT_IS_IEC61937(f) (((f) & AF_FORMAT_TYPE_MASK) == AF_FORMAT_S)
|
||||
#define AF_FORMAT_IS_SPECIAL(f) AF_FORMAT_IS_IEC61937(f)
|
||||
#define AF_FORMAT_IS_FLOAT(f) (!!((f) & AF_FORMAT_F))
|
||||
// false for interleaved and AF_FORMAT_UNKNOWN
|
||||
#define AF_FORMAT_IS_PLANAR(f) (!!((f) & AF_FORMAT_PLANAR))
|
||||
|
||||
struct af_fmt_entry {
|
||||
const char *name;
|
||||
@@ -109,12 +111,10 @@ const char *af_fmt_to_str(int format);
|
||||
|
||||
int af_fmt2bps(int format);
|
||||
int af_fmt2bits(int format);
|
||||
bool af_fmt_is_float(int format);
|
||||
int af_fmt_change_bits(int format, int bits);
|
||||
|
||||
int af_fmt_to_planar(int format);
|
||||
int af_fmt_from_planar(int format);
|
||||
bool af_fmt_is_planar(int format);
|
||||
|
||||
// Amount of bytes that contain audio of the given duration, aligned to frames.
|
||||
int af_fmt_seconds_to_bytes(int format, float seconds, int channels, int samplerate);
|
||||
@@ -125,4 +125,6 @@ void af_fill_silence(void *dst, size_t bytes, int format);
|
||||
|
||||
int af_format_conversion_score(int dst_format, int src_format);
|
||||
|
||||
int af_format_sample_alignment(int format);
|
||||
|
||||
#endif /* MPLAYER_AF_FORMAT_H */
|
||||
+38
-21
@@ -1,24 +1,24 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <libavutil/common.h>
|
||||
|
||||
@@ -37,7 +37,7 @@ struct mixer {
|
||||
struct af_stream *af;
|
||||
// Static, dependent on ao/softvol settings
|
||||
bool softvol; // use AO (false) or af_volume (true)
|
||||
bool ao_softvol; // AO has private or per-app volume
|
||||
bool persistent_volume; // volume does not need to be restored
|
||||
bool emulate_mute; // if true, emulate mute with volume=0
|
||||
// Last known values (possibly out of sync with reality)
|
||||
float vol_l, vol_r;
|
||||
@@ -88,6 +88,7 @@ static void checkvolume(struct mixer *mixer)
|
||||
vol.left = (gain / (mixer->opts->softvol_max / 100.0)) * 100.0;
|
||||
vol.right = (gain / (mixer->opts->softvol_max / 100.0)) * 100.0;
|
||||
} else {
|
||||
MP_DBG(mixer, "Reading volume from AO.\n");
|
||||
// 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);
|
||||
@@ -123,14 +124,17 @@ static void setvolume_internal(struct mixer *mixer, float l, float r)
|
||||
{
|
||||
struct ao_control_vol vol = {.left = l, .right = r};
|
||||
if (!mixer->softvol) {
|
||||
MP_DBG(mixer, "Setting volume on AO.\n");
|
||||
if (ao_control(mixer->ao, AOCONTROL_SET_VOLUME, &vol) != CONTROL_OK)
|
||||
MP_ERR(mixer, "Failed to change audio output volume.\n");
|
||||
return;
|
||||
}
|
||||
float gain = (l + r) / 2.0 / 100.0 * mixer->opts->softvol_max / 100.0;
|
||||
if (!af_control_any_rev(mixer->af, AF_CONTROL_SET_VOLUME, &gain)) {
|
||||
if (gain == 1.0)
|
||||
return;
|
||||
MP_VERBOSE(mixer, "Inserting volume filter.\n");
|
||||
if (!(af_add(mixer->af, "volume", NULL)
|
||||
if (!(af_add(mixer->af, "volume", "softvol", NULL)
|
||||
&& af_control_any_rev(mixer->af, AF_CONTROL_SET_VOLUME, &gain)))
|
||||
MP_ERR(mixer, "No volume control available.\n");
|
||||
}
|
||||
@@ -139,8 +143,7 @@ static void setvolume_internal(struct mixer *mixer, float l, float r)
|
||||
void mixer_setvolume(struct mixer *mixer, float l, float r)
|
||||
{
|
||||
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->emulate_mute && mixer->muted))
|
||||
@@ -218,7 +221,7 @@ void mixer_setbalance(struct mixer *mixer, float val)
|
||||
if (val == 0)
|
||||
return;
|
||||
|
||||
if (!(af_pan_balance = af_add(mixer->af, "pan", NULL))) {
|
||||
if (!(af_pan_balance = af_add(mixer->af, "pan", "autopan", NULL))) {
|
||||
MP_ERR(mixer, "No balance control available.\n");
|
||||
return;
|
||||
}
|
||||
@@ -246,17 +249,23 @@ char *mixer_get_volume_restore_data(struct mixer *mixer)
|
||||
|
||||
static void probe_softvol(struct mixer *mixer)
|
||||
{
|
||||
mixer->ao_softvol =
|
||||
ao_control(mixer->ao, AOCONTROL_HAS_SOFT_VOLUME, 0) == 1 ||
|
||||
ao_control(mixer->ao, AOCONTROL_HAS_PER_APP_VOLUME, 0) == 1;
|
||||
bool ao_perapp = ao_control(mixer->ao, AOCONTROL_HAS_PER_APP_VOLUME, 0) == 1;
|
||||
bool ao_softvol = ao_control(mixer->ao, AOCONTROL_HAS_SOFT_VOLUME, 0) == 1;
|
||||
assert(!(ao_perapp && ao_softvol));
|
||||
mixer->persistent_volume = !ao_softvol;
|
||||
|
||||
if (mixer->opts->softvol == SOFTVOL_AUTO) {
|
||||
// No system-wide volume => fine with AO volume control.
|
||||
mixer->softvol = !mixer->ao_softvol;
|
||||
mixer->softvol = !ao_softvol && !ao_perapp;
|
||||
} else {
|
||||
mixer->softvol = mixer->opts->softvol == SOFTVOL_YES;
|
||||
}
|
||||
|
||||
if (mixer->softvol)
|
||||
mixer->persistent_volume = false;
|
||||
|
||||
MP_DBG(mixer, "Will use af_volume: %s\n", mixer->softvol ? "yes" : "no");
|
||||
|
||||
// If we can't use real volume control => force softvol.
|
||||
if (!mixer->softvol) {
|
||||
ao_control_vol_t vol;
|
||||
@@ -285,11 +294,9 @@ static void restore_volume(struct mixer *mixer)
|
||||
const char *prev_driver = mixer->driver;
|
||||
mixer->driver = mixer->softvol ? "softvol" : ao_get_name(ao);
|
||||
|
||||
bool restore = mixer->softvol || mixer->ao_softvol;
|
||||
|
||||
// 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) {
|
||||
if (!mixer->persistent_volume && strcmp(mixer->driver, prev_driver) == 0) {
|
||||
force_vol_l = mixer->vol_l;
|
||||
force_vol_r = mixer->vol_r;
|
||||
}
|
||||
@@ -306,7 +313,7 @@ static void restore_volume(struct mixer *mixer)
|
||||
|
||||
// Set parameters from playback resume.
|
||||
char *data = mixer->opts->mixer_restore_volume_data;
|
||||
if (restore && data && data[0]) {
|
||||
if (!mixer->persistent_volume && data && data[0]) {
|
||||
char drv[40];
|
||||
float v_l, v_r, s;
|
||||
int m;
|
||||
@@ -316,6 +323,7 @@ static void restore_volume(struct mixer *mixer)
|
||||
force_vol_l = v_l;
|
||||
force_vol_r = v_r;
|
||||
force_mute = !!m;
|
||||
MP_DBG(mixer, "Restoring volume from resume config.\n");
|
||||
}
|
||||
}
|
||||
talloc_free(mixer->opts->mixer_restore_volume_data);
|
||||
@@ -331,10 +339,14 @@ static void restore_volume(struct mixer *mixer)
|
||||
opts->mixer_init_mute = -1;
|
||||
|
||||
checkvolume(mixer);
|
||||
if (force_vol_l >= 0 && force_vol_r >= 0)
|
||||
if (force_vol_l >= 0 && force_vol_r >= 0) {
|
||||
MP_DBG(mixer, "Restoring previous volume.\n");
|
||||
mixer_setvolume(mixer, force_vol_l, force_vol_r);
|
||||
if (force_mute >= 0)
|
||||
}
|
||||
if (force_mute >= 0) {
|
||||
MP_DBG(mixer, "Restoring previous mute toggle.\n");
|
||||
mixer_setmute(mixer, force_mute);
|
||||
}
|
||||
}
|
||||
|
||||
// Called after the audio filter chain is built or rebuilt.
|
||||
@@ -346,6 +358,8 @@ void mixer_reinit_audio(struct mixer *mixer, struct ao *ao, struct af_stream *af
|
||||
mixer->ao = ao;
|
||||
mixer->af = af;
|
||||
|
||||
MP_DBG(mixer, "Reinit...\n");
|
||||
|
||||
probe_softvol(mixer);
|
||||
restore_volume(mixer);
|
||||
|
||||
@@ -362,8 +376,11 @@ void mixer_uninit_audio(struct mixer *mixer)
|
||||
if (!mixer->ao)
|
||||
return;
|
||||
|
||||
MP_DBG(mixer, "Uninit...\n");
|
||||
|
||||
checkvolume(mixer);
|
||||
if (mixer->muted_by_us && !mixer->softvol && !mixer->ao_softvol) {
|
||||
if (mixer->muted_by_us && mixer->persistent_volume) {
|
||||
MP_DBG(mixer, "Draining.\n");
|
||||
/* Current audio output API combines playing the remaining buffered
|
||||
* audio and uninitializing the AO into one operation, even though
|
||||
* ideally unmute would happen between those two steps. We can't do
|
||||
|
||||
+4
-5
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_MIXER_H
|
||||
|
||||
+114
-23
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -199,7 +198,7 @@ static struct ao *ao_init(bool probing, struct mpv_global *global,
|
||||
|
||||
ao->sstride = af_fmt2bps(ao->format);
|
||||
ao->num_planes = 1;
|
||||
if (af_fmt_is_planar(ao->format)) {
|
||||
if (AF_FORMAT_IS_PLANAR(ao->format)) {
|
||||
ao->num_planes = ao->channels.num;
|
||||
} else {
|
||||
ao->sstride *= ao->channels.num;
|
||||
@@ -211,6 +210,9 @@ static struct ao *ao_init(bool probing, struct mpv_global *global,
|
||||
if (ao->device_buffer)
|
||||
MP_VERBOSE(ao, "device buffer: %d samples.\n", ao->device_buffer);
|
||||
ao->buffer = MPMAX(ao->device_buffer, ao->def_buffer * ao->samplerate);
|
||||
|
||||
int align = af_format_sample_alignment(ao->format);
|
||||
ao->buffer = (ao->buffer + align - 1) / align * align;
|
||||
MP_VERBOSE(ao, "using soft-buffer of %d samples.\n", ao->buffer);
|
||||
|
||||
if (ao->api->init(ao) < 0)
|
||||
@@ -386,14 +388,25 @@ int ao_query_and_reset_events(struct ao *ao, int events)
|
||||
int actual_events = 0;
|
||||
if (atomic_load(&ao->request_reload)) // don't need to reset it
|
||||
actual_events |= AO_EVENT_RELOAD;
|
||||
if (atomic_load(&ao->request_hotplug))
|
||||
actual_events |= AO_EVENT_HOTPLUG;
|
||||
return actual_events & events;
|
||||
}
|
||||
|
||||
// Request that the player core destroys and recreates the AO.
|
||||
// Request that the player core destroys and recreates the AO. Fully thread-safe.
|
||||
void ao_request_reload(struct ao *ao)
|
||||
{
|
||||
atomic_store(&ao->request_reload, true);
|
||||
mp_input_wakeup(ao->input_ctx);
|
||||
if (ao->input_ctx)
|
||||
mp_input_wakeup(ao->input_ctx);
|
||||
}
|
||||
|
||||
// Notify the player that the device list changed. Fully thread-safe.
|
||||
void ao_hotplug_event(struct ao *ao)
|
||||
{
|
||||
atomic_store(&ao->request_hotplug, true);
|
||||
if (ao->input_ctx)
|
||||
mp_input_wakeup(ao->input_ctx);
|
||||
}
|
||||
|
||||
bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
|
||||
@@ -405,7 +418,10 @@ bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
|
||||
MP_DBG(ao, "chmap_sel #%d: %s\n", i, mp_chmap_to_str(&c));
|
||||
}
|
||||
}
|
||||
return mp_chmap_sel_adjust(s, map);
|
||||
bool r = mp_chmap_sel_adjust(s, map);
|
||||
if (r)
|
||||
MP_DBG(ao, "result: %s\n", mp_chmap_to_str(map));
|
||||
return r;
|
||||
}
|
||||
|
||||
bool ao_chmap_sel_get_def(struct ao *ao, const struct mp_chmap_sel *s,
|
||||
@@ -439,31 +455,95 @@ bool ao_untimed(struct ao *ao)
|
||||
return ao->untimed;
|
||||
}
|
||||
|
||||
const char *ao_get_detected_device(struct ao *ao)
|
||||
// ---
|
||||
|
||||
struct ao_hotplug {
|
||||
struct mpv_global *global;
|
||||
struct input_ctx *input_ctx;
|
||||
// A single AO instance is used to listen to hotplug events. It wouldn't
|
||||
// make much sense to allow multiple AO drivers; all sane platforms have
|
||||
// a single such audio API.
|
||||
// This is _not_ the same AO instance as used for playing audio.
|
||||
struct ao *ao;
|
||||
// cached
|
||||
struct ao_device_list *list;
|
||||
bool needs_update;
|
||||
};
|
||||
|
||||
struct ao_hotplug *ao_hotplug_create(struct mpv_global *global,
|
||||
struct input_ctx *input_ctx)
|
||||
{
|
||||
return ao->detected_device;
|
||||
struct ao_hotplug *hp = talloc_ptrtype(NULL, hp);
|
||||
*hp = (struct ao_hotplug){
|
||||
.global = global,
|
||||
.input_ctx = input_ctx,
|
||||
.needs_update = true,
|
||||
};
|
||||
return hp;
|
||||
}
|
||||
|
||||
struct ao_device_list *ao_get_device_list(struct mpv_global *global)
|
||||
static void get_devices(struct ao *ao, struct ao_device_list *list)
|
||||
{
|
||||
struct ao_device_list *list = talloc_zero(NULL, struct ao_device_list);
|
||||
int num = list->num_devices;
|
||||
if (ao->driver->list_devs)
|
||||
ao->driver->list_devs(ao, list);
|
||||
// Add at least a default entry
|
||||
if (list->num_devices == num)
|
||||
ao_device_list_add(list, ao, &(struct ao_device_desc){"", "Default"});
|
||||
}
|
||||
|
||||
bool ao_hotplug_check_update(struct ao_hotplug *hp)
|
||||
{
|
||||
if (hp->ao && ao_query_and_reset_events(hp->ao, AO_EVENT_HOTPLUG)) {
|
||||
hp->needs_update = true;
|
||||
atomic_store(&hp->ao->request_hotplug, false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *ao_hotplug_get_detected_device(struct ao_hotplug *hp)
|
||||
{
|
||||
if (!hp || !hp->ao)
|
||||
return NULL;
|
||||
return hp->ao->detected_device;
|
||||
}
|
||||
|
||||
// The return value is valid until the next call to this API.
|
||||
struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp)
|
||||
{
|
||||
if (hp->list && !hp->needs_update)
|
||||
return hp->list;
|
||||
|
||||
talloc_free(hp->list);
|
||||
struct ao_device_list *list = talloc_zero(hp, struct ao_device_list);
|
||||
hp->list = list;
|
||||
|
||||
MP_TARRAY_APPEND(list, list->devices, list->num_devices,
|
||||
(struct ao_device_desc){"auto", "Autoselect device"});
|
||||
|
||||
for (int n = 0; audio_out_drivers[n]; n++) {
|
||||
const struct ao_driver *d = audio_out_drivers[n];
|
||||
if (d == &audio_out_null)
|
||||
break; // don't add unsafe/special entries
|
||||
struct ao *ao = ao_alloc(true, global, NULL, (char *)d->name, NULL);
|
||||
|
||||
struct ao *ao = ao_alloc(true, hp->global, hp->input_ctx,
|
||||
(char *)d->name, NULL);
|
||||
if (!ao)
|
||||
continue;
|
||||
int num = list->num_devices;
|
||||
if (d->list_devs)
|
||||
d->list_devs(ao, list);
|
||||
// Add at least a default entry
|
||||
if (list->num_devices == num)
|
||||
ao_device_list_add(list, ao, &(struct ao_device_desc){"", "Default"});
|
||||
talloc_free(ao);
|
||||
|
||||
if (ao->driver->hotplug_init) {
|
||||
if (!hp->ao && ao->driver->hotplug_init(ao) >= 0)
|
||||
hp->ao = ao; // keep this one
|
||||
if (hp->ao && hp->ao->driver == d)
|
||||
get_devices(hp->ao, list);
|
||||
} else {
|
||||
get_devices(ao, list);
|
||||
}
|
||||
if (ao != hp->ao)
|
||||
talloc_free(ao);
|
||||
}
|
||||
hp->needs_update = false;
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -478,13 +558,24 @@ void ao_device_list_add(struct ao_device_list *list, struct ao *ao,
|
||||
MP_TARRAY_APPEND(list, list->devices, list->num_devices, c);
|
||||
}
|
||||
|
||||
void ao_hotplug_destroy(struct ao_hotplug *hp)
|
||||
{
|
||||
if (!hp)
|
||||
return;
|
||||
if (hp->ao && hp->ao->driver->hotplug_uninit)
|
||||
hp->ao->driver->hotplug_uninit(hp->ao);
|
||||
talloc_free(hp->ao);
|
||||
talloc_free(hp);
|
||||
}
|
||||
|
||||
void ao_print_devices(struct mpv_global *global, struct mp_log *log)
|
||||
{
|
||||
struct ao_device_list *list = ao_get_device_list(global);
|
||||
struct ao_hotplug *hp = ao_hotplug_create(global, NULL);
|
||||
struct ao_device_list *list = ao_hotplug_get_device_list(hp);
|
||||
mp_info(log, "List of detected audio devices:\n");
|
||||
for (int n = 0; n < list->num_devices; n++) {
|
||||
struct ao_device_desc *desc = &list->devices[n];
|
||||
mp_info(log, " '%s' (%s)\n", desc->name, desc->desc);
|
||||
}
|
||||
talloc_free(list);
|
||||
ao_hotplug_destroy(hp);
|
||||
}
|
||||
+14
-7
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_AUDIO_OUT_H
|
||||
@@ -48,6 +47,7 @@ enum aocontrol {
|
||||
|
||||
enum {
|
||||
AO_EVENT_RELOAD = 1,
|
||||
AO_EVENT_HOTPLUG = 2,
|
||||
};
|
||||
|
||||
typedef struct ao_control_vol {
|
||||
@@ -79,7 +79,6 @@ void ao_uninit(struct ao *ao);
|
||||
void ao_get_format(struct ao *ao, struct mp_audio *format);
|
||||
const char *ao_get_name(struct ao *ao);
|
||||
const char *ao_get_description(struct ao *ao);
|
||||
const char *ao_get_detected_device(struct ao *ao);
|
||||
bool ao_untimed(struct ao *ao);
|
||||
int ao_play(struct ao *ao, void **data, int samples, int flags);
|
||||
int ao_control(struct ao *ao, enum aocontrol cmd, void *arg);
|
||||
@@ -92,8 +91,16 @@ void ao_drain(struct ao *ao);
|
||||
bool ao_eof_reached(struct ao *ao);
|
||||
int ao_query_and_reset_events(struct ao *ao, int events);
|
||||
void ao_request_reload(struct ao *ao);
|
||||
void ao_hotplug_event(struct ao *ao);
|
||||
|
||||
struct ao_hotplug;
|
||||
struct ao_hotplug *ao_hotplug_create(struct mpv_global *global,
|
||||
struct input_ctx *input_ctx);
|
||||
void ao_hotplug_destroy(struct ao_hotplug *hp);
|
||||
bool ao_hotplug_check_update(struct ao_hotplug *hp);
|
||||
const char *ao_hotplug_get_detected_device(struct ao_hotplug *hp);
|
||||
struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp);
|
||||
|
||||
struct ao_device_list *ao_get_device_list(struct mpv_global *global);
|
||||
void ao_print_devices(struct mpv_global *global, struct mp_log *log);
|
||||
|
||||
#endif /* MPLAYER_AUDIO_OUT_H */
|
||||
+32
-23
@@ -10,21 +10,20 @@
|
||||
* 04/13/2004 merged with ao_alsa1.x, fixes provided by Jindrich Makovicka
|
||||
* 04/25/2004 printfs converted to mp_msg, Zsolt.
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
@@ -64,6 +63,7 @@ struct priv {
|
||||
int cfg_mixer_index;
|
||||
int cfg_resample;
|
||||
int cfg_ni;
|
||||
int cfg_ignore_chmap;
|
||||
};
|
||||
|
||||
#define BUFFER_TIME 250000 // 250ms
|
||||
@@ -375,6 +375,7 @@ static int try_open_device(struct ao *ao, const char *device)
|
||||
IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER,
|
||||
map_iec958_srate(ao->samplerate));
|
||||
const char *ac3_device = append_params(tmp, device, params);
|
||||
MP_VERBOSE(ao, "opening device '%s' => '%s'\n", device, ac3_device);
|
||||
int err = snd_pcm_open
|
||||
(&p->alsa, ac3_device, SND_PCM_STREAM_PLAYBACK, 0);
|
||||
talloc_free(tmp);
|
||||
@@ -382,6 +383,7 @@ static int try_open_device(struct ao *ao, const char *device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
MP_VERBOSE(ao, "opening device '%s'\n", device);
|
||||
return snd_pcm_open(&p->alsa, device, SND_PCM_STREAM_PLAYBACK, 0);
|
||||
}
|
||||
|
||||
@@ -407,23 +409,14 @@ static int init_device(struct ao *ao)
|
||||
struct priv *p = ao->priv;
|
||||
int err;
|
||||
|
||||
if (!p->cfg_ni)
|
||||
ao->format = af_fmt_from_planar(ao->format);
|
||||
|
||||
const char *device = "default";
|
||||
if (AF_FORMAT_IS_IEC61937(ao->format)) {
|
||||
if (AF_FORMAT_IS_IEC61937(ao->format))
|
||||
device = "iec958";
|
||||
MP_VERBOSE(ao, "playing AC3/iec61937/iec958, %i channels\n",
|
||||
ao->channels.num);
|
||||
}
|
||||
if (ao->device)
|
||||
device = ao->device;
|
||||
if (p->cfg_device && p->cfg_device[0])
|
||||
device = p->cfg_device;
|
||||
|
||||
MP_VERBOSE(ao, "using device: %s\n", device);
|
||||
MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version());
|
||||
|
||||
err = try_open_device(ao, device);
|
||||
CHECK_ALSA_ERROR("Playback open error");
|
||||
|
||||
@@ -466,11 +459,11 @@ static int init_device(struct ao *ao)
|
||||
err = snd_pcm_hw_params_set_format(p->alsa, alsa_hwparams, p->alsa_fmt);
|
||||
CHECK_ALSA_ERROR("Unable to set format");
|
||||
|
||||
snd_pcm_access_t access = af_fmt_is_planar(ao->format)
|
||||
snd_pcm_access_t access = AF_FORMAT_IS_PLANAR(ao->format)
|
||||
? SND_PCM_ACCESS_RW_NONINTERLEAVED
|
||||
: SND_PCM_ACCESS_RW_INTERLEAVED;
|
||||
err = snd_pcm_hw_params_set_access(p->alsa, alsa_hwparams, access);
|
||||
if (err < 0 && af_fmt_is_planar(ao->format)) {
|
||||
if (err < 0 && AF_FORMAT_IS_PLANAR(ao->format)) {
|
||||
ao->format = af_fmt_from_planar(ao->format);
|
||||
access = SND_PCM_ACCESS_RW_INTERLEAVED;
|
||||
err = snd_pcm_hw_params_set_access(p->alsa, alsa_hwparams, access);
|
||||
@@ -478,7 +471,7 @@ static int init_device(struct ao *ao)
|
||||
CHECK_ALSA_ERROR("Unable to set access type");
|
||||
|
||||
struct mp_chmap dev_chmap = ao->channels;
|
||||
if (AF_FORMAT_IS_IEC61937(ao->format)) {
|
||||
if (AF_FORMAT_IS_IEC61937(ao->format) || p->cfg_ignore_chmap) {
|
||||
dev_chmap.num = 0; // disable chmap API
|
||||
} else if (query_chmaps(ao, &dev_chmap)) {
|
||||
ao->channels = dev_chmap;
|
||||
@@ -499,8 +492,11 @@ static int init_device(struct ao *ao)
|
||||
}
|
||||
|
||||
if (num_channels != ao->channels.num) {
|
||||
MP_ERR(ao, "Couldn't get requested number of channels.\n");
|
||||
mp_chmap_from_channels_alsa(&ao->channels, num_channels);
|
||||
if (!mp_chmap_is_valid(&ao->channels))
|
||||
mp_chmap_from_channels(&ao->channels, 2);
|
||||
MP_ERR(ao, "Couldn't get requested number of channels, fallback to %s.\n",
|
||||
mp_chmap_to_str(&ao->channels));
|
||||
}
|
||||
|
||||
// Some ALSA drivers have broken delay reporting, so disable the ALSA
|
||||
@@ -550,8 +546,11 @@ static int init_device(struct ao *ao)
|
||||
|
||||
err = snd_pcm_set_chmap(p->alsa, alsa_chmap);
|
||||
if (err == -ENXIO) {
|
||||
MP_WARN(ao, "Device does not support requested channel map (%s)\n",
|
||||
mp_chmap_to_str(&dev_chmap));
|
||||
// I consider this an ALSA bug: the channel map was reported as
|
||||
// supported, but we still can't set it. It happens virtually
|
||||
// always with dmix, though.
|
||||
MP_VERBOSE(ao, "Device does not support requested channel map (%s)\n",
|
||||
mp_chmap_to_str(&dev_chmap));
|
||||
} else {
|
||||
CHECK_ALSA_WARN("Channel map setup failed");
|
||||
}
|
||||
@@ -571,7 +570,9 @@ static int init_device(struct ao *ao)
|
||||
|
||||
MP_VERBOSE(ao, "which we understand as: %s\n", mp_chmap_to_str(&chmap));
|
||||
|
||||
if (AF_FORMAT_IS_IEC61937(ao->format)) {
|
||||
if (p->cfg_ignore_chmap) {
|
||||
MP_VERBOSE(ao, "user set ignore-chmap; ignoring the channel map.\n");
|
||||
} else if (AF_FORMAT_IS_IEC61937(ao->format)) {
|
||||
MP_VERBOSE(ao, "using spdif passthrough; ignoring the channel map.\n");
|
||||
} else if (mp_chmap_is_valid(&chmap)) {
|
||||
if (mp_chmap_equals(&chmap, &ao->channels)) {
|
||||
@@ -604,6 +605,7 @@ static int init_device(struct ao *ao)
|
||||
// the number of channels to 2 either, because the hw params
|
||||
// are already set! So just fuck it and reopen the device with
|
||||
// the chmap "cleaned out" of NA entries.
|
||||
MP_VERBOSE(ao, "Working around braindead ALSA behavior.\n");
|
||||
err = snd_pcm_close(p->alsa);
|
||||
p->alsa = NULL;
|
||||
CHECK_ALSA_ERROR("pcm close error");
|
||||
@@ -675,6 +677,12 @@ alsa_error:
|
||||
|
||||
static int init(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
if (!p->cfg_ni)
|
||||
ao->format = af_fmt_from_planar(ao->format);
|
||||
|
||||
MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version());
|
||||
|
||||
int r = init_device(ao);
|
||||
if (r == INIT_BRAINDEATH)
|
||||
r = init_device(ao); // retry with normalized channel layout
|
||||
@@ -814,7 +822,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
|
||||
return 0;
|
||||
|
||||
do {
|
||||
if (af_fmt_is_planar(ao->format)) {
|
||||
if (AF_FORMAT_IS_PLANAR(ao->format)) {
|
||||
res = snd_pcm_writen(p->alsa, data, samples);
|
||||
} else {
|
||||
res = snd_pcm_writei(p->alsa, data[0], samples);
|
||||
@@ -934,6 +942,7 @@ const struct ao_driver audio_out_alsa = {
|
||||
OPT_STRING("mixer-name", cfg_mixer_name, 0),
|
||||
OPT_INTRANGE("mixer-index", cfg_mixer_index, 0, 0, 99),
|
||||
OPT_FLAG("non-interleaved", cfg_ni, 0),
|
||||
OPT_FLAG("ignore-chmap", cfg_ignore_chmap, 0),
|
||||
{0}
|
||||
},
|
||||
};
|
||||
+90
-35
@@ -38,11 +38,6 @@ struct priv {
|
||||
bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout,
|
||||
struct mp_chmap *chmap);
|
||||
|
||||
static int64_t ca_frames_to_us(struct ao *ao, uint32_t frames)
|
||||
{
|
||||
return frames / (float) ao->samplerate * 1e6;
|
||||
}
|
||||
|
||||
static int64_t ca_get_hardware_latency(struct ao *ao) {
|
||||
struct priv *p = ao->priv;
|
||||
|
||||
@@ -73,17 +68,6 @@ coreaudio_error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t ca_get_latency(const AudioTimeStamp *ts)
|
||||
{
|
||||
uint64_t out = AudioConvertHostTimeToNanos(ts->mHostTime);
|
||||
uint64_t now = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
|
||||
|
||||
if (now > out)
|
||||
return 0;
|
||||
|
||||
return (out - now) * 1e-3;
|
||||
}
|
||||
|
||||
static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags,
|
||||
const AudioTimeStamp *ts, UInt32 bus,
|
||||
UInt32 frames, AudioBufferList *buffer_list)
|
||||
@@ -134,8 +118,6 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
return set_volume(ao, arg);
|
||||
case AOCONTROL_HAS_SOFT_VOLUME:
|
||||
return CONTROL_TRUE;
|
||||
case AOCONTROL_HAS_PER_APP_VOLUME:
|
||||
return CONTROL_TRUE;
|
||||
}
|
||||
return CONTROL_UNKNOWN;
|
||||
}
|
||||
@@ -143,14 +125,7 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
static bool init_chmap(struct ao *ao);
|
||||
static bool init_audiounit(struct ao *ao, AudioStreamBasicDescription asbd);
|
||||
|
||||
static int init(struct ao *ao)
|
||||
{
|
||||
if (AF_FORMAT_IS_IEC61937(ao->format)) {
|
||||
MP_WARN(ao, "detected IEC61937, redirecting to coreaudio_exclusive\n");
|
||||
ao->redirect = "coreaudio_exclusive";
|
||||
return CONTROL_ERROR;
|
||||
}
|
||||
|
||||
static bool reinit_device(struct ao *ao) {
|
||||
struct priv *p = ao->priv;
|
||||
|
||||
OSStatus err = ca_select_device(ao, ao->device, &p->device);
|
||||
@@ -161,6 +136,23 @@ static int init(struct ao *ao)
|
||||
CHECK_CA_ERROR("failed to get device UID");
|
||||
ao->detected_device = talloc_steal(ao, uid);
|
||||
|
||||
return true;
|
||||
|
||||
coreaudio_error:
|
||||
return false;
|
||||
}
|
||||
|
||||
static int init(struct ao *ao)
|
||||
{
|
||||
if (AF_FORMAT_IS_IEC61937(ao->format)) {
|
||||
MP_WARN(ao, "detected IEC61937, redirecting to coreaudio_exclusive\n");
|
||||
ao->redirect = "coreaudio_exclusive";
|
||||
return CONTROL_ERROR;
|
||||
}
|
||||
|
||||
if (!reinit_device(ao))
|
||||
goto coreaudio_error;
|
||||
|
||||
if (!init_chmap(ao))
|
||||
goto coreaudio_error;
|
||||
|
||||
@@ -361,6 +353,67 @@ static void uninit(struct ao *ao)
|
||||
AudioComponentInstanceDispose(p->audio_unit);
|
||||
}
|
||||
|
||||
static OSStatus hotplug_cb(AudioObjectID id, UInt32 naddr,
|
||||
const AudioObjectPropertyAddress addr[],
|
||||
void *ctx) {
|
||||
reinit_device(ctx);
|
||||
ao_hotplug_event(ctx);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static uint32_t hotplug_properties[] = {
|
||||
kAudioHardwarePropertyDevices,
|
||||
kAudioHardwarePropertyDefaultOutputDevice
|
||||
};
|
||||
|
||||
static int hotplug_init(struct ao *ao)
|
||||
{
|
||||
if (!reinit_device(ao))
|
||||
goto coreaudio_error;
|
||||
|
||||
OSStatus err = noErr;
|
||||
for (int i = 0; i < MP_ARRAY_SIZE(hotplug_properties); i++) {
|
||||
AudioObjectPropertyAddress addr = {
|
||||
hotplug_properties[i],
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
err = AudioObjectAddPropertyListener(
|
||||
kAudioObjectSystemObject, &addr, hotplug_cb, (void *)ao);
|
||||
if (err != noErr) {
|
||||
char *c1 = fourcc_repr(ao, hotplug_properties[i]);
|
||||
char *c2 = fourcc_repr(ao, err);
|
||||
MP_ERR(ao, "failed to set device listener %s (%s)", c1, c2);
|
||||
goto coreaudio_error;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
coreaudio_error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void hotplug_uninit(struct ao *ao)
|
||||
{
|
||||
OSStatus err = noErr;
|
||||
for (int i = 0; i < MP_ARRAY_SIZE(hotplug_properties); i++) {
|
||||
AudioObjectPropertyAddress addr = {
|
||||
hotplug_properties[i],
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
err = AudioObjectRemovePropertyListener(
|
||||
kAudioObjectSystemObject, &addr, hotplug_cb, (void *)ao);
|
||||
if (err != noErr) {
|
||||
char *c1 = fourcc_repr(ao, hotplug_properties[i]);
|
||||
char *c2 = fourcc_repr(ao, err);
|
||||
MP_ERR(ao, "failed to set device listener %s (%s)", c1, c2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Channel Mapping functions
|
||||
static const int speaker_map[][2] = {
|
||||
{ kAudioChannelLabel_Left, MP_SPEAKER_ID_FL },
|
||||
@@ -513,13 +566,15 @@ coreaudio_error:
|
||||
#define OPT_BASE_STRUCT struct priv
|
||||
|
||||
const struct ao_driver audio_out_coreaudio = {
|
||||
.description = "CoreAudio AudioUnit",
|
||||
.name = "coreaudio",
|
||||
.uninit = uninit,
|
||||
.init = init,
|
||||
.control = control,
|
||||
.pause = stop,
|
||||
.resume = start,
|
||||
.list_devs = ca_get_device_list,
|
||||
.priv_size = sizeof(struct priv),
|
||||
.description = "CoreAudio AudioUnit",
|
||||
.name = "coreaudio",
|
||||
.uninit = uninit,
|
||||
.init = init,
|
||||
.control = control,
|
||||
.pause = stop,
|
||||
.resume = start,
|
||||
.hotplug_init = hotplug_init,
|
||||
.hotplug_uninit = hotplug_uninit,
|
||||
.list_devs = ca_get_device_list,
|
||||
.priv_size = sizeof(struct priv),
|
||||
};
|
||||
@@ -11,21 +11,20 @@
|
||||
* module from VideoLAN:
|
||||
* Copyright (c) 2006 Derk-Jan Hartman <hartman at videolan dot org>
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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
|
||||
* along with MPlayer; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -35,21 +34,18 @@
|
||||
* when you are wanting to do good buffering of audio).
|
||||
*/
|
||||
|
||||
#include <CoreAudio/HostTime.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "ao.h"
|
||||
#include "internal.h"
|
||||
#include "audio/format.h"
|
||||
#include "osdep/timer.h"
|
||||
#include "options/m_option.h"
|
||||
#include "misc/ring.h"
|
||||
#include "common/msg.h"
|
||||
#include "audio/out/ao_coreaudio_properties.h"
|
||||
#include "audio/out/ao_coreaudio_utils.h"
|
||||
|
||||
static void audio_pause(struct ao *ao);
|
||||
static void audio_resume(struct ao *ao);
|
||||
static void reset(struct ao *ao);
|
||||
|
||||
static bool ca_format_is_digital(AudioStreamBasicDescription asbd)
|
||||
{
|
||||
switch (asbd.mFormatID)
|
||||
@@ -310,8 +306,6 @@ struct priv {
|
||||
|
||||
bool paused;
|
||||
|
||||
struct mp_ring *buffer;
|
||||
|
||||
// digital render callback
|
||||
AudioDeviceIOProcID render_cb;
|
||||
|
||||
@@ -332,14 +326,10 @@ struct priv {
|
||||
|
||||
bool changed_mixing;
|
||||
int stream_asbd_changed;
|
||||
bool muted;
|
||||
};
|
||||
bool reload_requested;
|
||||
|
||||
static int get_ring_size(struct ao *ao)
|
||||
{
|
||||
return af_fmt_seconds_to_bytes(
|
||||
ao->format, 0.5, ao->channels.num, ao->samplerate);
|
||||
}
|
||||
uint32_t hw_latency_us;
|
||||
};
|
||||
|
||||
static OSStatus render_cb_digital(
|
||||
AudioDeviceID device, const AudioTimeStamp *ts,
|
||||
@@ -351,47 +341,33 @@ static OSStatus render_cb_digital(
|
||||
AudioBuffer buf = out_data->mBuffers[p->stream_idx];
|
||||
int requested = buf.mDataByteSize;
|
||||
|
||||
if (p->muted)
|
||||
mp_ring_drain(p->buffer, requested);
|
||||
else
|
||||
mp_ring_read(p->buffer, buf.mData, requested);
|
||||
int pseudo_frames = requested / ao->sstride;
|
||||
|
||||
// we expect the callback to read full frames, which are aligned accordingly
|
||||
if (pseudo_frames * ao->sstride != requested) {
|
||||
MP_ERR(ao, "Unsupported unaligned read of %d bytes.\n", requested);
|
||||
return kAudioHardwareUnspecifiedError;
|
||||
}
|
||||
|
||||
int64_t end = mp_time_us();
|
||||
end += p->hw_latency_us + ca_get_latency(ts)
|
||||
+ ca_frames_to_us(ao, pseudo_frames);
|
||||
|
||||
ao_read_data(ao, &buf.mData, pseudo_frames, end);
|
||||
|
||||
// Check whether we need to reset the digital output stream.
|
||||
if (p->stream_asbd_changed) {
|
||||
p->stream_asbd_changed = 0;
|
||||
if (!p->reload_requested && ca_stream_supports_digital(ao, p->stream)) {
|
||||
p->reload_requested = true;
|
||||
ao_request_reload(ao);
|
||||
MP_INFO(ao, "Stream format changed! Reloading.\n");
|
||||
}
|
||||
}
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
ao_control_vol_t *control_vol;
|
||||
switch (cmd) {
|
||||
case AOCONTROL_GET_VOLUME:
|
||||
control_vol = (ao_control_vol_t *)arg;
|
||||
// Digital output has no volume adjust.
|
||||
int digitalvol = p->muted ? 0 : 100;
|
||||
*control_vol = (ao_control_vol_t) {
|
||||
.left = digitalvol, .right = digitalvol,
|
||||
};
|
||||
return CONTROL_TRUE;
|
||||
|
||||
case AOCONTROL_SET_VOLUME:
|
||||
control_vol = (ao_control_vol_t *)arg;
|
||||
// Digital output can not set volume. Here we have to return true
|
||||
// to make mixer forget it. Else mixer will add a soft filter,
|
||||
// that's not we expected and the filter not support ac3 stream
|
||||
// will cause mplayer die.
|
||||
|
||||
// Although not support set volume, but at least we support mute.
|
||||
// MPlayer set mute by set volume to zero, we handle it.
|
||||
if (control_vol->left == 0 && control_vol->right == 0)
|
||||
p->muted = true;
|
||||
else
|
||||
p->muted = false;
|
||||
return CONTROL_TRUE;
|
||||
|
||||
} // end switch
|
||||
return CONTROL_UNKNOWN;
|
||||
}
|
||||
|
||||
static int init_digital(struct ao *ao, AudioStreamBasicDescription asbd);
|
||||
|
||||
static int init(struct ao *ao)
|
||||
@@ -457,12 +433,6 @@ static int init_digital(struct ao *ao, AudioStreamBasicDescription asbd)
|
||||
bool digital = ca_stream_supports_digital(ao, streams[i]);
|
||||
|
||||
if (digital) {
|
||||
err = CA_GET(streams[i], kAudioStreamPropertyPhysicalFormat,
|
||||
&p->original_asbd);
|
||||
if (!CHECK_CA_WARN("could not get stream's physical format to "
|
||||
"revert to, getting the next one"))
|
||||
continue;
|
||||
|
||||
AudioStreamRangedDescription *formats;
|
||||
size_t n_formats;
|
||||
|
||||
@@ -509,6 +479,10 @@ static int init_digital(struct ao *ao, AudioStreamBasicDescription asbd)
|
||||
goto coreaudio_error;
|
||||
}
|
||||
|
||||
err = CA_GET(p->stream, kAudioStreamPropertyPhysicalFormat,
|
||||
&p->original_asbd);
|
||||
CHECK_CA_ERROR("could not get stream's original physical format");
|
||||
|
||||
if (!ca_change_format(ao, p->stream, p->stream_asbd))
|
||||
goto coreaudio_error;
|
||||
|
||||
@@ -524,17 +498,29 @@ static int init_digital(struct ao *ao, AudioStreamBasicDescription asbd)
|
||||
(p->stream_asbd.mBytesPerPacket /
|
||||
p->stream_asbd.mFramesPerPacket);
|
||||
|
||||
p->buffer = mp_ring_new(p, get_ring_size(ao));
|
||||
uint32_t latency_frames = 0;
|
||||
uint32_t latency_properties[] = {
|
||||
kAudioDevicePropertyLatency,
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
kAudioDevicePropertySafetyOffset,
|
||||
};
|
||||
for (int n = 0; n < MP_ARRAY_SIZE(latency_properties); n++) {
|
||||
uint32_t temp;
|
||||
err = CA_GET_O(p->device, kAudioDevicePropertyLatency, &temp);
|
||||
CHECK_CA_WARN("cannot get device latency");
|
||||
if (err == noErr)
|
||||
latency_frames += temp;
|
||||
}
|
||||
|
||||
p->hw_latency_us = ca_frames_to_us(ao, latency_frames);
|
||||
MP_VERBOSE(ao, "base latency: %d microseconds\n", (int)p->hw_latency_us);
|
||||
|
||||
err = AudioDeviceCreateIOProcID(p->device,
|
||||
(AudioDeviceIOProc)render_cb_digital,
|
||||
(void *)ao,
|
||||
&p->render_cb);
|
||||
|
||||
CHECK_CA_ERROR("failed to register digital render callback");
|
||||
|
||||
reset(ao);
|
||||
|
||||
return CONTROL_TRUE;
|
||||
|
||||
coreaudio_error:
|
||||
@@ -543,52 +529,6 @@ coreaudio_error:
|
||||
return CONTROL_ERROR;
|
||||
}
|
||||
|
||||
static int play(struct ao *ao, void **data, int samples, int flags)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
void *output_samples = data[0];
|
||||
int num_bytes = samples * ao->sstride;
|
||||
|
||||
// Check whether we need to reset the digital output stream.
|
||||
if (p->stream_asbd_changed) {
|
||||
p->stream_asbd_changed = 0;
|
||||
if (ca_stream_supports_digital(ao, p->stream)) {
|
||||
if (!ca_change_format(ao, p->stream, p->stream_asbd)) {
|
||||
MP_WARN(ao , "can't restore digital output\n");
|
||||
} else {
|
||||
MP_WARN(ao, "restoring digital output succeeded.\n");
|
||||
reset(ao);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int wrote = mp_ring_write(p->buffer, output_samples, num_bytes);
|
||||
audio_resume(ao);
|
||||
|
||||
return wrote / ao->sstride;
|
||||
}
|
||||
|
||||
static void reset(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
audio_pause(ao);
|
||||
mp_ring_reset(p->buffer);
|
||||
}
|
||||
|
||||
static int get_space(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
return mp_ring_available(p->buffer) / ao->sstride;
|
||||
}
|
||||
|
||||
static double get_delay(struct ao *ao)
|
||||
{
|
||||
// FIXME: should also report the delay of coreaudio itself (hardware +
|
||||
// internal buffers)
|
||||
struct priv *p = ao->priv;
|
||||
return mp_ring_buffered(p->buffer) / (double)ao->bps;
|
||||
}
|
||||
|
||||
static void uninit(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
@@ -618,26 +558,16 @@ static void audio_pause(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
|
||||
if (p->paused)
|
||||
return;
|
||||
|
||||
OSStatus err = AudioDeviceStop(p->device, p->render_cb);
|
||||
CHECK_CA_WARN("can't stop digital device");
|
||||
|
||||
p->paused = true;
|
||||
}
|
||||
|
||||
static void audio_resume(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
|
||||
if (!p->paused)
|
||||
return;
|
||||
|
||||
OSStatus err = AudioDeviceStart(p->device, p->render_cb);
|
||||
CHECK_CA_WARN("can't start digital device");
|
||||
|
||||
p->paused = false;
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct priv
|
||||
@@ -647,17 +577,11 @@ const struct ao_driver audio_out_coreaudio_exclusive = {
|
||||
.name = "coreaudio_exclusive",
|
||||
.uninit = uninit,
|
||||
.init = init,
|
||||
.play = play,
|
||||
.control = control,
|
||||
.get_space = get_space,
|
||||
.get_delay = get_delay,
|
||||
.reset = reset,
|
||||
.pause = audio_pause,
|
||||
.resume = audio_resume,
|
||||
.list_devs = ca_get_device_list,
|
||||
.priv_size = sizeof(struct priv),
|
||||
.priv_defaults = &(const struct priv){
|
||||
.muted = false,
|
||||
.stream_asbd_changed = 0,
|
||||
.hog_pid = -1,
|
||||
.stream = 0,
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
* on CoreAudio but not the AUHAL (such as using AudioQueue services).
|
||||
*/
|
||||
|
||||
#include <CoreAudio/HostTime.h>
|
||||
|
||||
#include "audio/out/ao_coreaudio_utils.h"
|
||||
#include "audio/out/ao_coreaudio_properties.h"
|
||||
#include "osdep/timer.h"
|
||||
@@ -115,12 +117,12 @@ OSStatus ca_select_device(struct ao *ao, char* name, AudioDeviceID *device)
|
||||
if (mp_msg_test(ao->log, MSGL_V)) {
|
||||
char *desc;
|
||||
err = CA_GET_STR(*device, kAudioObjectPropertyName, &desc);
|
||||
CHECK_CA_ERROR("could not get selected audio device name");
|
||||
|
||||
MP_VERBOSE(ao, "selected audio output device: %s (%" PRIu32 ")\n",
|
||||
desc, *device);
|
||||
|
||||
talloc_free(desc);
|
||||
CHECK_CA_WARN("could not get selected audio device name");
|
||||
if (err == noErr) {
|
||||
MP_VERBOSE(ao, "selected audio output device: %s (%" PRIu32 ")\n",
|
||||
desc, *device);
|
||||
talloc_free(desc);
|
||||
}
|
||||
}
|
||||
|
||||
coreaudio_error:
|
||||
@@ -139,16 +141,17 @@ char *fourcc_repr(void *talloc_ctx, uint32_t code)
|
||||
};
|
||||
|
||||
bool valid_fourcc = true;
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (fcc[i] >= 32 && fcc[i] < 128)
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (fcc[i] < 32 || fcc[i] >= 128)
|
||||
valid_fourcc = false;
|
||||
}
|
||||
|
||||
char *repr;
|
||||
if (valid_fourcc)
|
||||
repr = talloc_asprintf(talloc_ctx, "'%c%c%c%c'",
|
||||
fcc[0], fcc[1], fcc[2], fcc[3]);
|
||||
else
|
||||
repr = talloc_asprintf(NULL, "%d", code);
|
||||
repr = talloc_asprintf(NULL, "%u", (unsigned int)code);
|
||||
|
||||
return repr;
|
||||
}
|
||||
@@ -197,9 +200,9 @@ void ca_print_asbd(struct ao *ao, const char *description,
|
||||
char *format = fourcc_repr(NULL, asbd->mFormatID);
|
||||
|
||||
MP_VERBOSE(ao,
|
||||
"%s %7.1fHz %" PRIu32 "bit [%s]"
|
||||
"[%" PRIu32 "][%" PRIu32 "][%" PRIu32 "]"
|
||||
"[%" PRIu32 "][%" PRIu32 "] "
|
||||
"%s %7.1fHz %" PRIu32 "bit %s "
|
||||
"[%" PRIu32 "][%" PRIu32 "bpp][%" PRIu32 "fbp]"
|
||||
"[%" PRIu32 "bpf][%" PRIu32 "ch] "
|
||||
"%s %s %s%s%s%s\n",
|
||||
description, asbd->mSampleRate, asbd->mBitsPerChannel, format,
|
||||
asbd->mFormatFlags, asbd->mBytesPerPacket, asbd->mFramesPerPacket,
|
||||
@@ -214,3 +217,18 @@ void ca_print_asbd(struct ao *ao, const char *description,
|
||||
talloc_free(format);
|
||||
}
|
||||
|
||||
int64_t ca_frames_to_us(struct ao *ao, uint32_t frames)
|
||||
{
|
||||
return frames / (float) ao->samplerate * 1e6;
|
||||
}
|
||||
|
||||
int64_t ca_get_latency(const AudioTimeStamp *ts)
|
||||
{
|
||||
uint64_t out = AudioConvertHostTimeToNanos(ts->mHostTime);
|
||||
uint64_t now = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
|
||||
|
||||
if (now > out)
|
||||
return 0;
|
||||
|
||||
return (out - now) * 1e-3;
|
||||
}
|
||||
@@ -56,4 +56,7 @@ void ca_fill_asbd(struct ao *ao, AudioStreamBasicDescription *asbd);
|
||||
void ca_print_asbd(struct ao *ao, const char *description,
|
||||
const AudioStreamBasicDescription *asbd);
|
||||
|
||||
int64_t ca_frames_to_us(struct ao *ao, uint32_t frames);
|
||||
int64_t ca_get_latency(const AudioTimeStamp *ts);
|
||||
|
||||
#endif /* MPV_COREAUDIO_UTILS_H */
|
||||
@@ -3,21 +3,20 @@
|
||||
*
|
||||
* Copyright (c) 2004 Gabor Szecsi <deje@miki.hu>
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
+4
-5
@@ -6,21 +6,20 @@
|
||||
*
|
||||
* Copyleft 2013 by William Light <wrl@illest.net> for the mpv project
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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
|
||||
* along with MPlayer; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
+5
-6
@@ -5,19 +5,18 @@
|
||||
*
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -242,7 +241,7 @@ static int encode(struct ao *ao, double apts, void **data)
|
||||
frame->format = af_to_avformat(ao->format);
|
||||
frame->nb_samples = ac->aframesize;
|
||||
|
||||
size_t num_planes = af_fmt_is_planar(ao->format) ? ao->channels.num : 1;
|
||||
size_t num_planes = AF_FORMAT_IS_PLANAR(ao->format) ? ao->channels.num : 1;
|
||||
assert(num_planes <= AV_NUM_DATA_POINTERS);
|
||||
for (int n = 0; n < num_planes; n++)
|
||||
frame->extended_data[n] = data[n];
|
||||
@@ -351,7 +350,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
|
||||
double pts = ectx->last_audio_in_pts;
|
||||
pts += ectx->samples_since_last_pts / (double)ao->samplerate;
|
||||
|
||||
size_t num_planes = af_fmt_is_planar(ao->format) ? ao->channels.num : 1;
|
||||
size_t num_planes = AF_FORMAT_IS_PLANAR(ao->format) ? ao->channels.num : 1;
|
||||
|
||||
void *tempdata = NULL;
|
||||
void *padded[MP_NUM_CHANNELS];
|
||||
|
||||
+4
-5
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* null audio output driver
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -3,21 +3,20 @@
|
||||
*
|
||||
* Copyleft 2006 by Reimar Döffinger (Reimar.Doeffinger@stud.uni-karlsruhe.de)
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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
|
||||
* along with MPlayer; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
+5
-6
@@ -1,25 +1,24 @@
|
||||
/*
|
||||
* OSS audio output driver
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* Original author: A'rpi
|
||||
* Support for >2 output channels added 2001-11-25
|
||||
* - Steve Davies <steve@daviesfam.org>
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
+5
-6
@@ -1,23 +1,22 @@
|
||||
/*
|
||||
* PCM audio output driver
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* Original author: Atmosfear
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
+45
-13
@@ -3,21 +3,20 @@
|
||||
* Copyright (C) 2006 Lennart Poettering
|
||||
* Copyright (C) 2007 Reimar Doeffinger
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -81,6 +80,27 @@ static void context_state_cb(pa_context *c, void *userdata)
|
||||
}
|
||||
}
|
||||
|
||||
static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t,
|
||||
uint32_t idx, void *userdata)
|
||||
{
|
||||
struct ao *ao = userdata;
|
||||
int type = t & PA_SUBSCRIPTION_MASK_SINK;
|
||||
int fac = t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK;
|
||||
if ((type == PA_SUBSCRIPTION_EVENT_NEW || type == PA_SUBSCRIPTION_EVENT_REMOVE)
|
||||
&& fac == PA_SUBSCRIPTION_EVENT_SINK)
|
||||
{
|
||||
ao_hotplug_event(ao);
|
||||
}
|
||||
}
|
||||
|
||||
static void context_success_cb(pa_context *c, int success, void *userdata)
|
||||
{
|
||||
struct ao *ao = userdata;
|
||||
struct priv *priv = ao->priv;
|
||||
priv->retval = success;
|
||||
pa_threaded_mainloop_signal(priv->mainloop, 0);
|
||||
}
|
||||
|
||||
static void stream_state_cb(pa_stream *s, void *userdata)
|
||||
{
|
||||
struct ao *ao = userdata;
|
||||
@@ -323,6 +343,7 @@ static int pa_init_boilerplate(struct ao *ao)
|
||||
(long)pa_context_get_server_protocol_version(priv->context));
|
||||
|
||||
pa_context_set_state_callback(priv->context, context_state_cb, ao);
|
||||
pa_context_set_subscribe_callback(priv->context, subscribe_cb, ao);
|
||||
|
||||
if (pa_context_connect(priv->context, host, 0, NULL) < 0)
|
||||
goto fail;
|
||||
@@ -397,7 +418,6 @@ static int init(struct ao *ao)
|
||||
MP_ERR(ao, "Failed to allocate proplist\n");
|
||||
goto unlock_and_fail;
|
||||
}
|
||||
(void)pa_proplist_sets(proplist, PA_PROP_MEDIA_ROLE, "video");
|
||||
(void)pa_proplist_sets(proplist, PA_PROP_MEDIA_ICON_NAME, ao->client_name);
|
||||
|
||||
pa_format_info_set_rate(format, ao->samplerate);
|
||||
@@ -751,22 +771,32 @@ static void sink_info_cb(pa_context *c, const pa_sink_info *i, int eol, void *ud
|
||||
ao_device_list_add(ctx->list, ctx->ao, &entry);
|
||||
}
|
||||
|
||||
static int hotplug_init(struct ao *ao)
|
||||
{
|
||||
struct priv *priv = ao->priv;
|
||||
if (pa_init_boilerplate(ao) < 0)
|
||||
return -1;
|
||||
|
||||
pa_threaded_mainloop_lock(priv->mainloop);
|
||||
waitop(priv, pa_context_subscribe(priv->context, PA_SUBSCRIPTION_MASK_SINK,
|
||||
context_success_cb, ao));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void list_devs(struct ao *ao, struct ao_device_list *list)
|
||||
{
|
||||
struct priv *priv = ao->priv;
|
||||
bool need_uninit = !priv->mainloop;
|
||||
struct sink_cb_ctx ctx = {ao, list};
|
||||
|
||||
if (need_uninit && pa_init_boilerplate(ao) < 0)
|
||||
return;
|
||||
|
||||
pa_threaded_mainloop_lock(priv->mainloop);
|
||||
waitop(priv, pa_context_get_sink_info_list(priv->context, sink_info_cb, &ctx));
|
||||
|
||||
if (need_uninit)
|
||||
uninit(ao);
|
||||
}
|
||||
|
||||
static void hotplug_uninit(struct ao *ao)
|
||||
{
|
||||
uninit(ao);
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct priv
|
||||
|
||||
@@ -785,6 +815,8 @@ const struct ao_driver audio_out_pulse = {
|
||||
.drain = drain,
|
||||
.wait = wait_audio,
|
||||
.wakeup = wakeup,
|
||||
.hotplug_init = hotplug_init,
|
||||
.hotplug_uninit = hotplug_uninit,
|
||||
.list_devs = list_devs,
|
||||
.priv_size = sizeof(struct priv),
|
||||
.priv_defaults = &(const struct priv) {
|
||||
|
||||
@@ -3,21 +3,20 @@
|
||||
*
|
||||
* Copyright (C) 2011 Hans-Kristian Arntzen
|
||||
*
|
||||
* This file is part of mplayer2.
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* mplayer2 is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* mplayer2 is distributed in the hope that it will be useful,
|
||||
* 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 mplayer2; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
+3
-4
@@ -4,19 +4,18 @@
|
||||
*
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* 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.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
+2
-20
@@ -125,7 +125,7 @@ static int init(struct ao *ao)
|
||||
const struct af_to_par *ap;
|
||||
int i;
|
||||
|
||||
p->hdl = sio_open(p->dev, SIO_PLAY, 1);
|
||||
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;
|
||||
@@ -304,25 +304,7 @@ static void audio_pause(struct ao *ao)
|
||||
*/
|
||||
static void audio_resume(struct ao *ao)
|
||||
{
|
||||
struct priv *p = ao->priv;
|
||||
int n, count, todo;
|
||||
|
||||
/*
|
||||
* we want to start with buffers full, because mpv uses
|
||||
* get_delay() 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;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct priv
|
||||
|
||||
+116
-117
@@ -63,14 +63,13 @@ static HRESULT get_device_delay(struct wasapi_state *state, double *delay) {
|
||||
|
||||
return S_OK;
|
||||
exit_label:
|
||||
MP_ERR(state, "Error getting device delay: %s (0x%"PRIx32")\n",
|
||||
wasapi_explain_err(hr), (uint32_t) hr);
|
||||
MP_ERR(state, "Error getting device delay: %s\n", mp_HRESULT_to_str(hr));
|
||||
return hr;
|
||||
}
|
||||
|
||||
static void thread_feed(struct ao *ao)
|
||||
{
|
||||
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
|
||||
struct wasapi_state *state = ao->priv;
|
||||
HRESULT hr;
|
||||
|
||||
UINT32 frame_count = state->bufferFrameCount;
|
||||
@@ -106,8 +105,7 @@ static void thread_feed(struct ao *ao)
|
||||
|
||||
return;
|
||||
exit_label:
|
||||
MP_ERR(state, "Error feeding audio: %s (0x%"PRIx32")\n",
|
||||
wasapi_explain_err(hr), (uint32_t) hr);
|
||||
MP_ERR(state, "Error feeding audio: %s\n", mp_HRESULT_to_str(hr));
|
||||
MP_VERBOSE(ao, "Requesting ao reload\n");
|
||||
ao_request_reload(ao);
|
||||
return;
|
||||
@@ -115,93 +113,97 @@ exit_label:
|
||||
|
||||
static void thread_resume(struct ao *ao)
|
||||
{
|
||||
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
|
||||
struct wasapi_state *state = ao->priv;
|
||||
HRESULT hr;
|
||||
|
||||
MP_DBG(state, "Thread Resume\n");
|
||||
UINT32 padding = 0;
|
||||
hr = IAudioClient_GetCurrentPadding(state->pAudioClient, &padding);
|
||||
if (hr != S_OK) {
|
||||
MP_ERR(state, "IAudioClient_GetCurrentPadding returned %s (0x%"PRIx32")\n",
|
||||
wasapi_explain_err(hr), (uint32_t) hr);
|
||||
MP_ERR(state, "IAudioClient_GetCurrentPadding returned %s\n",
|
||||
mp_HRESULT_to_str(hr));
|
||||
}
|
||||
|
||||
/* Fill the buffer before starting, but only if there is no audio queued to play. */
|
||||
/* This prevents overfilling the buffer, which leads to problems in exclusive mode */
|
||||
if (padding < (UINT32)state->bufferFrameCount)
|
||||
if (padding < (UINT32) state->bufferFrameCount)
|
||||
thread_feed(ao);
|
||||
|
||||
// start feeding next wakeup if something else hasn't been requested
|
||||
int expected = WASAPI_THREAD_RESUME;
|
||||
atomic_compare_exchange_strong(&state->thread_state, &expected, WASAPI_THREAD_FEED);
|
||||
hr = IAudioClient_Start(state->pAudioClient);
|
||||
if (hr != S_OK) {
|
||||
MP_ERR(state, "IAudioClient_Start returned %s (0x%"PRIx32")\n",
|
||||
wasapi_explain_err(hr), (uint32_t) hr);
|
||||
}
|
||||
if (hr != S_OK)
|
||||
MP_ERR(state, "IAudioClient_Start returned %s\n", mp_HRESULT_to_str(hr));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void thread_reset(struct ao *ao)
|
||||
{
|
||||
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
|
||||
struct wasapi_state *state = ao->priv;
|
||||
HRESULT hr;
|
||||
MP_DBG(state, "Thread Reset\n");
|
||||
hr = IAudioClient_Stop(state->pAudioClient);
|
||||
/* we may get S_FALSE if the stream is already stopped */
|
||||
if (hr != S_OK &&
|
||||
hr != S_FALSE) {
|
||||
MP_ERR(state, "IAudioClient_Stop returned: %s (0x%"PRIx32")\n",
|
||||
wasapi_explain_err(hr), (uint32_t) hr);
|
||||
}
|
||||
if (hr != S_OK && hr != S_FALSE)
|
||||
MP_ERR(state, "IAudioClient_Stop returned: %s\n", mp_HRESULT_to_str(hr));
|
||||
|
||||
/* we may get S_FALSE if the stream is already reset */
|
||||
hr = IAudioClient_Reset(state->pAudioClient);
|
||||
if (hr != S_OK &&
|
||||
hr != S_FALSE) {
|
||||
MP_ERR(state, "IAudioClient_Reset returned: %s (0x%"PRIx32")\n",
|
||||
wasapi_explain_err(hr), (uint32_t) hr);
|
||||
}
|
||||
if (hr != S_OK && hr != S_FALSE)
|
||||
MP_ERR(state, "IAudioClient_Reset returned: %s\n", mp_HRESULT_to_str(hr));
|
||||
|
||||
atomic_store(&state->sample_count, 0);
|
||||
// start feeding next wakeup if something else hasn't been requested
|
||||
int expected = WASAPI_THREAD_RESET;
|
||||
atomic_compare_exchange_strong(&state->thread_state, &expected, WASAPI_THREAD_FEED);
|
||||
return;
|
||||
}
|
||||
|
||||
static DWORD __stdcall ThreadLoop(void *lpParameter)
|
||||
static DWORD __stdcall AudioThread(void *lpParameter)
|
||||
{
|
||||
struct ao *ao = lpParameter;
|
||||
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
|
||||
struct wasapi_state *state = ao->priv;
|
||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
state->init_ret = wasapi_thread_init(ao);
|
||||
SetEvent(state->init_done);
|
||||
SetEvent(state->hInitDone);
|
||||
if (state->init_ret != S_OK)
|
||||
goto exit_label;
|
||||
|
||||
DWORD waitstatus;
|
||||
HANDLE playcontrol[] =
|
||||
{state->hUninit, state->hFeed, state->hReset, state->hResume, NULL};
|
||||
MP_DBG(ao, "Entering dispatch loop\n");
|
||||
while (true) { /* watch events */
|
||||
waitstatus = MsgWaitForMultipleObjects(4, playcontrol, FALSE, INFINITE,
|
||||
QS_POSTMESSAGE | QS_SENDMESSAGE);
|
||||
switch (waitstatus) {
|
||||
case WAIT_OBJECT_0: /*shutdown*/
|
||||
MP_DBG(ao, "Thread shutdown\n");
|
||||
goto exit_label;
|
||||
case (WAIT_OBJECT_0 + 1): /* feed */
|
||||
thread_feed(ao);
|
||||
HANDLE events[] = {state->hWake};
|
||||
switch (MsgWaitForMultipleObjects(MP_ARRAY_SIZE(events), events, FALSE, INFINITE,
|
||||
QS_POSTMESSAGE | QS_SENDMESSAGE)) {
|
||||
/* AudioThread wakeup */
|
||||
case WAIT_OBJECT_0:
|
||||
switch (atomic_load(&state->thread_state)) {
|
||||
case WASAPI_THREAD_FEED:
|
||||
thread_feed(ao);
|
||||
break;
|
||||
case WASAPI_THREAD_RESET:
|
||||
thread_reset(ao);
|
||||
break;
|
||||
case WASAPI_THREAD_RESUME:
|
||||
thread_reset(ao);
|
||||
thread_resume(ao);
|
||||
break;
|
||||
case WASAPI_THREAD_SHUTDOWN:
|
||||
thread_reset(ao);
|
||||
goto exit_label;
|
||||
default:
|
||||
MP_ERR(ao, "Unhandled thread state\n");
|
||||
goto exit_label;
|
||||
}
|
||||
break;
|
||||
case (WAIT_OBJECT_0 + 2): /* reset */
|
||||
thread_reset(ao);
|
||||
break;
|
||||
case (WAIT_OBJECT_0 + 3): /* resume */
|
||||
thread_resume(ao);
|
||||
break;
|
||||
case (WAIT_OBJECT_0 + 4): /* messages to dispatch (COM marshalling) */
|
||||
MP_DBG(ao, "Dispatch\n");
|
||||
wasapi_dispatch();
|
||||
/* messages to dispatch (COM marshalling) */
|
||||
case (WAIT_OBJECT_0 + MP_ARRAY_SIZE(events)):
|
||||
wasapi_dispatch(ao);
|
||||
break;
|
||||
default:
|
||||
MP_ERR(ao, "Unhandled case in thread loop\n");
|
||||
MP_ERR(ao, "Unhandled thread event\n");
|
||||
goto exit_label;
|
||||
}
|
||||
}
|
||||
@@ -213,32 +215,35 @@ exit_label:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void closehandles(struct ao *ao)
|
||||
static void set_thread_state(struct ao *ao, enum wasapi_thread_state thread_state)
|
||||
{
|
||||
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
|
||||
if (state->init_done) CloseHandle(state->init_done);
|
||||
if (state->hUninit) CloseHandle(state->hUninit);
|
||||
if (state->hFeed) CloseHandle(state->hFeed);
|
||||
if (state->hResume) CloseHandle(state->hResume);
|
||||
if (state->hReset) CloseHandle(state->hReset);
|
||||
if (state->threadLoop) CloseHandle(state->threadLoop);
|
||||
struct wasapi_state *state = ao->priv;
|
||||
atomic_store(&state->thread_state, thread_state);
|
||||
SetEvent(state->hWake);
|
||||
}
|
||||
|
||||
static void uninit(struct ao *ao)
|
||||
{
|
||||
MP_DBG(ao, "Uninit wasapi\n");
|
||||
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
|
||||
struct wasapi_state *state = ao->priv;
|
||||
wasapi_release_proxies(state);
|
||||
if (state->hUninit)
|
||||
SetEvent(state->hUninit);
|
||||
if (state->hWake)
|
||||
set_thread_state(ao, WASAPI_THREAD_SHUTDOWN);
|
||||
|
||||
/* wait up to 10 seconds */
|
||||
if (WaitForSingleObject(state->threadLoop, 10000) == WAIT_TIMEOUT) {
|
||||
if (state->hAudioThread &&
|
||||
WaitForSingleObject(state->hAudioThread, 10000) == WAIT_TIMEOUT)
|
||||
{
|
||||
MP_ERR(ao, "Audio loop thread refuses to abort\n");
|
||||
return;
|
||||
}
|
||||
if (state->VistaBlob.hAvrt)
|
||||
FreeLibrary(state->VistaBlob.hAvrt);
|
||||
closehandles(ao);
|
||||
|
||||
SAFE_RELEASE(state->hInitDone, CloseHandle(state->hInitDone));
|
||||
SAFE_RELEASE(state->hWake, CloseHandle(state->hWake));
|
||||
SAFE_RELEASE(state->hAudioThread,CloseHandle(state->hAudioThread));
|
||||
|
||||
CoUninitialize();
|
||||
MP_DBG(ao, "Uninit wasapi done\n");
|
||||
}
|
||||
@@ -248,53 +253,29 @@ static int init(struct ao *ao)
|
||||
MP_DBG(ao, "Init wasapi\n");
|
||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
ao->format = af_fmt_from_planar(ao->format);
|
||||
struct mp_chmap_sel sel = {0};
|
||||
mp_chmap_sel_add_waveext(&sel);
|
||||
if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels)) {
|
||||
MP_ERR(ao, "Error adjusting channel map to waveext channel order\n");
|
||||
return -1;
|
||||
}
|
||||
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
|
||||
struct wasapi_state *state = ao->priv;
|
||||
state->log = ao->log;
|
||||
if(!wasapi_fill_VistaBlob(state))
|
||||
MP_WARN(ao, "Error loading thread priority functions\n");
|
||||
|
||||
if (state->opt_list) {
|
||||
if(!wasapi_enumerate_devices(state->log, NULL, NULL))
|
||||
MP_WARN(ao, "Error enumerating devices\n");
|
||||
}
|
||||
|
||||
if (state->opt_exclusive) {
|
||||
state->share_mode = AUDCLNT_SHAREMODE_EXCLUSIVE;
|
||||
} else {
|
||||
state->share_mode = AUDCLNT_SHAREMODE_SHARED;
|
||||
}
|
||||
|
||||
state->init_done = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
state->hUninit = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
state->hFeed = CreateEventW(NULL, FALSE, FALSE, NULL); /* for wasapi event mode */
|
||||
state->hResume = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
state->hReset = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (!state->init_done || !state->hFeed || !state->hUninit ||
|
||||
!state->hResume || !state->hReset)
|
||||
{
|
||||
MP_ERR(ao, "Error initing events\n");
|
||||
state->hInitDone = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
state->hWake = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (!state->hInitDone || !state->hWake) {
|
||||
MP_ERR(ao, "Error creating events\n");
|
||||
uninit(ao);
|
||||
/* failed to init events */
|
||||
return -1;
|
||||
}
|
||||
|
||||
state->init_ret = E_FAIL;
|
||||
state->threadLoop = (HANDLE) CreateThread(NULL, 0, &ThreadLoop, ao, 0, NULL);
|
||||
if (!state->threadLoop) {
|
||||
/* failed to init thread */
|
||||
MP_ERR(ao, "Failed to create thread\n");
|
||||
state->hAudioThread = CreateThread(NULL, 0, &AudioThread, ao, 0, NULL);
|
||||
if (!state->hAudioThread) {
|
||||
MP_ERR(ao, "Failed to create audio thread\n");
|
||||
uninit(ao);
|
||||
return -1;
|
||||
}
|
||||
|
||||
WaitForSingleObject(state->init_done, INFINITE); /* wait on init complete */
|
||||
WaitForSingleObject(state->hInitDone, INFINITE); /* wait on init complete */
|
||||
SAFE_RELEASE(state->hInitDone,CloseHandle(state->hInitDone));
|
||||
if (state->init_ret != S_OK) {
|
||||
if (!ao->probing)
|
||||
MP_ERR(ao, "Received failure from audio thread\n");
|
||||
@@ -309,8 +290,8 @@ static int init(struct ao *ao)
|
||||
|
||||
static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
{
|
||||
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
|
||||
ao_control_vol_t *vol = (ao_control_vol_t *)arg;
|
||||
struct wasapi_state *state = ao->priv;
|
||||
ao_control_vol_t *vol = arg;
|
||||
BOOL mute;
|
||||
|
||||
switch (cmd) {
|
||||
@@ -388,40 +369,58 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
|
||||
static void audio_reset(struct ao *ao)
|
||||
{
|
||||
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
|
||||
SetEvent(state->hReset);
|
||||
set_thread_state(ao, WASAPI_THREAD_RESET);
|
||||
}
|
||||
|
||||
static void audio_resume(struct ao *ao)
|
||||
{
|
||||
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
|
||||
SetEvent(state->hResume);
|
||||
set_thread_state(ao, WASAPI_THREAD_RESUME);
|
||||
}
|
||||
|
||||
static void list_devs(struct ao *ao, struct ao_device_list *list)
|
||||
static void hotplug_uninit(struct ao *ao)
|
||||
{
|
||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
if(!wasapi_enumerate_devices(mp_null_log, ao, list))
|
||||
MP_WARN(ao, "Error enumerating devices\n");
|
||||
MP_DBG(ao, "Hotplug uninit\n");
|
||||
struct wasapi_state *state = ao->priv;
|
||||
wasapi_change_uninit(ao);
|
||||
SAFE_RELEASE(state->pEnumerator, IMMDeviceEnumerator_Release(state->pEnumerator));
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
static int hotplug_init(struct ao *ao)
|
||||
{
|
||||
MP_DBG(ao, "Hotplug init\n");
|
||||
struct wasapi_state *state = ao->priv;
|
||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
HRESULT hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
|
||||
&IID_IMMDeviceEnumerator, (void **)&state->pEnumerator);
|
||||
EXIT_ON_ERROR(hr);
|
||||
hr = wasapi_change_init(ao, true);
|
||||
EXIT_ON_ERROR(hr);
|
||||
|
||||
return 0;
|
||||
exit_label:
|
||||
MP_ERR(state, "Error setting up audio hotplug: %s\n", mp_HRESULT_to_str(hr));
|
||||
hotplug_uninit(ao);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct wasapi_state
|
||||
|
||||
const struct ao_driver audio_out_wasapi = {
|
||||
.description = "Windows WASAPI audio output (event mode)",
|
||||
.name = "wasapi",
|
||||
.init = init,
|
||||
.uninit = uninit,
|
||||
.control = control,
|
||||
.reset = audio_reset,
|
||||
.resume = audio_resume,
|
||||
.list_devs = list_devs,
|
||||
.priv_size = sizeof(wasapi_state),
|
||||
.options = (const struct m_option[]) {
|
||||
.description = "Windows WASAPI audio output (event mode)",
|
||||
.name = "wasapi",
|
||||
.init = init,
|
||||
.uninit = uninit,
|
||||
.control = control,
|
||||
.reset = audio_reset,
|
||||
.resume = audio_resume,
|
||||
.list_devs = wasapi_list_devs,
|
||||
.hotplug_init = hotplug_init,
|
||||
.hotplug_uninit = hotplug_uninit,
|
||||
.priv_size = sizeof(wasapi_state),
|
||||
.options = (const struct m_option[]) {
|
||||
OPT_FLAG("exclusive", opt_exclusive, 0),
|
||||
OPT_FLAG("list", opt_list, 0),
|
||||
OPT_STRING_VALIDATE("device", opt_device, 0, wasapi_validate_device),
|
||||
OPT_STRING("device", opt_device, 0),
|
||||
{NULL},
|
||||
},
|
||||
};
|
||||
Loaded 100 of 385 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user