Compare commits
570 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98f8f5b12f | ||
|
|
0a5251d28e | ||
|
|
2cfabd8ce7 | ||
|
|
87ef295ddf | ||
|
|
03bf78eba6 | ||
|
|
f3c3cd5afb | ||
|
|
256ebf8bb4 | ||
|
|
36c0958fbd | ||
|
|
4e4177dde2 | ||
|
|
c9527df274 | ||
|
|
372bb59438 | ||
|
|
d5b42af8e7 | ||
|
|
2173539519 | ||
|
|
816f7337bf | ||
|
|
9cbac36026 | ||
|
|
a051de092e | ||
|
|
e29c9ef2d5 | ||
|
|
50d726273e | ||
|
|
a4cc1101cc | ||
|
|
d4fc6b211f | ||
|
|
5bc9f70441 | ||
|
|
2bbef8ee27 | ||
|
|
98e177c728 | ||
|
|
f94517934b | ||
|
|
2920c7cec0 | ||
|
|
baca98fc09 | ||
|
|
726133b6d2 | ||
|
|
3738a41830 | ||
|
|
53a6cdf89d | ||
|
|
50cb32480b | ||
|
|
74410f2aba | ||
|
|
febea34f91 | ||
|
|
6da5e63ba7 | ||
|
|
d15b1da8bc | ||
|
|
dc86479e5f | ||
|
|
98cd9cd4c2 | ||
|
|
bd09e3b19c | ||
|
|
5bc3b18e3d | ||
|
|
952393b69e | ||
|
|
04db307c77 | ||
|
|
342d5c20ce | ||
|
|
52c4069119 | ||
|
|
e595087048 | ||
|
|
b66aa37834 | ||
|
|
16ee405707 | ||
|
|
19938f1a11 | ||
|
|
892ceb512f | ||
|
|
5987b16f86 | ||
|
|
66395ac32b | ||
|
|
e889397924 | ||
|
|
7827b06d77 | ||
|
|
bae812711a | ||
|
|
b375cc8bb7 | ||
|
|
f2a6f41dd7 | ||
|
|
8c7b477b97 | ||
|
|
6a10b962e3 | ||
|
|
efb649467c | ||
|
|
6cc7777d4b | ||
|
|
00b0d595eb | ||
|
|
b905d2948a | ||
|
|
7f638d56bd | ||
|
|
c368f07565 | ||
|
|
79f6269fd0 | ||
|
|
539dc1746a | ||
|
|
97e35bc40b | ||
|
|
13c0467c49 | ||
|
|
3abe6554c1 | ||
|
|
aa01a35dd5 | ||
|
|
fa427bdb59 | ||
|
|
1268784d9f | ||
|
|
6405c66a51 | ||
|
|
a76db7176a | ||
|
|
a954b531f6 | ||
|
|
aaecd2ef68 | ||
|
|
2b85709bee | ||
|
|
d986096963 | ||
|
|
20ce366fee | ||
|
|
bbf911b660 | ||
|
|
5bb861d45b | ||
|
|
fc24783c6d | ||
|
|
a2bde1363c | ||
|
|
a7c0243e2f | ||
|
|
00a6211b45 | ||
|
|
220ee7e583 | ||
|
|
9bca2f698b | ||
|
|
6d951be24d | ||
|
|
80dc5b497e | ||
|
|
dd4fd80fe6 | ||
|
|
b97e0e98b4 | ||
|
|
9125bbb3e5 | ||
|
|
27ad04e128 | ||
|
|
66735ddd72 | ||
|
|
f7addaece8 | ||
|
|
b36c97a0ae | ||
|
|
312f96053a | ||
|
|
e5d9f0c3cd | ||
|
|
431ccd3f55 | ||
|
|
74cf081ef0 | ||
|
|
b7362f3c6b | ||
|
|
1a54f239ad | ||
|
|
a2055f8e3f | ||
|
|
c00ef60abd | ||
|
|
12cf6ace44 | ||
|
|
39d9308b99 | ||
|
|
d09ec6c27f | ||
|
|
31c1c0b46a | ||
|
|
6d77a3ff3c | ||
|
|
81527019b1 | ||
|
|
3c6aa2e0d1 | ||
|
|
46acaabd2a | ||
|
|
c1e2c1e84e | ||
|
|
15a408f182 | ||
|
|
22a6713ce9 | ||
|
|
61bf10368c | ||
|
|
266ecedc75 | ||
|
|
753d04b618 | ||
|
|
1df8547366 | ||
|
|
722cbfc5e1 | ||
|
|
9a8419541f | ||
|
|
ef157cec81 | ||
|
|
1f1b73cb16 | ||
|
|
e5714e4ccb | ||
|
|
e93ffb4888 | ||
|
|
f7ea74422f | ||
|
|
d528414568 | ||
|
|
fe5b764e6a | ||
|
|
f865aa6bee | ||
|
|
873397e27e | ||
|
|
260a286e53 | ||
|
|
fb0d1cafab | ||
|
|
25dac3128b | ||
|
|
5c82f67012 | ||
|
|
25b7dc959a | ||
|
|
5c2c0979e2 | ||
|
|
439757d38a | ||
|
|
90c38d6ab8 | ||
|
|
7edf958740 | ||
|
|
858adb27a0 | ||
|
|
6a44539bc8 | ||
|
|
b7afa9f8aa | ||
|
|
a8643da03a | ||
|
|
fe2a92cfd4 | ||
|
|
1d6983c899 | ||
|
|
64ecc9eda9 | ||
|
|
cb14b289bc | ||
|
|
ccc598dbcb | ||
|
|
79a5cac077 | ||
|
|
5415c88e37 | ||
|
|
625fb08959 | ||
|
|
d5f5d21322 | ||
|
|
b424fde5de | ||
|
|
df7f051f4d | ||
|
|
9f8da7e2aa | ||
|
|
1d4199e023 | ||
|
|
ba925988ef | ||
|
|
362a98eea9 | ||
|
|
5b6d056da8 | ||
|
|
efe4dbb6e6 | ||
|
|
1b048028a7 | ||
|
|
66c9e5e3eb | ||
|
|
a871e42e30 | ||
|
|
b08f7e592f | ||
|
|
2b220944e9 | ||
|
|
ee202d98ce | ||
|
|
f720b43615 | ||
|
|
f5839a7826 | ||
|
|
b1da01c051 | ||
|
|
7108189a54 | ||
|
|
e18bd51596 | ||
|
|
e7776cedf5 | ||
|
|
6eb1a6f48b | ||
|
|
706bbb22b1 | ||
|
|
1e74ee34f9 | ||
|
|
288eb8b17e | ||
|
|
9b27474cdf | ||
|
|
af71771a6c | ||
|
|
7072201271 | ||
|
|
c419022789 | ||
|
|
8cbe7461b3 | ||
|
|
fdba18c068 | ||
|
|
6b1a01f3ec | ||
|
|
66aa3c61fe | ||
|
|
8d7ccdf873 | ||
|
|
3b0f0dab4a | ||
|
|
a7f35b7f35 | ||
|
|
43db1288dd | ||
|
|
510f968849 | ||
|
|
eed9fc2f61 | ||
|
|
228b1e3f40 | ||
|
|
bc95cd1480 | ||
|
|
20363bef60 | ||
|
|
e1e7b75cbf | ||
|
|
90ff230fd1 | ||
|
|
f5212833b2 | ||
|
|
1d52ed4da8 | ||
|
|
0ff8f9b8e0 | ||
|
|
bc133fe409 | ||
|
|
4f40dac0af | ||
|
|
6ee9d6e32f | ||
|
|
70247373a1 | ||
|
|
dd01941b9a | ||
|
|
f66f1c5232 | ||
|
|
3814f965aa | ||
|
|
e74ec43293 | ||
|
|
b4bb262b48 | ||
|
|
a9bb748cee | ||
|
|
1f76235dd4 | ||
|
|
7793fc5b33 | ||
|
|
e958bfac8b | ||
|
|
d4241affd8 | ||
|
|
5d737a3d0c | ||
|
|
f61c888743 | ||
|
|
1274e92015 | ||
|
|
8e6d9d48a0 | ||
|
|
c521f9a5cd | ||
|
|
826515083a | ||
|
|
0f5cb5c111 | ||
|
|
6131115d27 | ||
|
|
3078fc9de7 | ||
|
|
5d7b87af7e | ||
|
|
2384c67d06 | ||
|
|
d835d6cd08 | ||
|
|
3c428a5ff7 | ||
|
|
9b76264241 | ||
|
|
36847fd7f1 | ||
|
|
322077091c | ||
|
|
d736890eed | ||
|
|
08a4305128 | ||
|
|
45a0a449bd | ||
|
|
82bcbad1fd | ||
|
|
79bfa4a663 | ||
|
|
ea57abac8d | ||
|
|
2366285207 | ||
|
|
85d5f5502c | ||
|
|
7ed2d4dcb7 | ||
|
|
95ccad6758 | ||
|
|
4d47113c66 | ||
|
|
39a24c1fa8 | ||
|
|
5983ae55ec | ||
|
|
9c6577035e | ||
|
|
7d37865af0 | ||
|
|
bec98cd8bd | ||
|
|
2964778d7e | ||
|
|
a1a7dd4da0 | ||
|
|
54eaad7c6e | ||
|
|
af52a28f4d | ||
|
|
0a75880b64 | ||
|
|
b83e839f1e | ||
|
|
b36be353b8 | ||
|
|
8bdef54c19 | ||
|
|
869e8b1d0f | ||
|
|
fa3bbd77c1 | ||
|
|
89a2384828 | ||
|
|
d757c9428c | ||
|
|
d6c2b08e73 | ||
|
|
a4fb44723d | ||
|
|
25a592e5d4 | ||
|
|
3c8e14482e | ||
|
|
dcc5cdbdbb | ||
|
|
f01e5156df | ||
|
|
d47a3f3f9d | ||
|
|
7810d341d3 | ||
|
|
477020fdf1 | ||
|
|
ebbf9e1eb8 | ||
|
|
1219924dbe | ||
|
|
350f7f0bdf | ||
|
|
f47b687067 | ||
|
|
14da95af46 | ||
|
|
afa243bdf0 | ||
|
|
05efc2bab7 | ||
|
|
f06fae660b | ||
|
|
862b16aabf | ||
|
|
7f3a671ece | ||
|
|
4aea3cd974 | ||
|
|
ed06434bff | ||
|
|
85c8c0c826 | ||
|
|
332a9cbbf7 | ||
|
|
36dd76ef14 | ||
|
|
e9a8242b96 | ||
|
|
408b4fb430 | ||
|
|
fe09596f49 | ||
|
|
8d17000794 | ||
|
|
5c81cf8225 | ||
|
|
a7ca51b273 | ||
|
|
1514e432f9 | ||
|
|
a3e3d72d12 | ||
|
|
89e26447fa | ||
|
|
207f2874c0 | ||
|
|
7a69c1b2ab | ||
|
|
1bb1d2d4a1 | ||
|
|
f20c485e4e | ||
|
|
db83541205 | ||
|
|
8bf18194ab | ||
|
|
57e603fd9f | ||
|
|
65f3fffbcf | ||
|
|
37d51c242f | ||
|
|
054a16d375 | ||
|
|
aa39ca14d6 | ||
|
|
4ee1e00f08 | ||
|
|
2d3da218ce | ||
|
|
cff78c4cc4 | ||
|
|
2a6cad221b | ||
|
|
1f91d66a62 | ||
|
|
536af42121 | ||
|
|
9c7184ae63 | ||
|
|
0f6f163922 | ||
|
|
db8f28fd3f | ||
|
|
77aa9eddbc | ||
|
|
5fb14cc889 | ||
|
|
a78cfe84f9 | ||
|
|
b0d6bff2f2 | ||
|
|
231e242ed2 | ||
|
|
58b05f8720 | ||
|
|
5aa97eb1a6 | ||
|
|
6bdc6bef2a | ||
|
|
03dee014f4 | ||
|
|
56f8ab1802 | ||
|
|
4674c4594f | ||
|
|
f66140a1bd | ||
|
|
fa595a94a1 | ||
|
|
8fee7589d5 | ||
|
|
bd2e3b0e90 | ||
|
|
9f2b473fa7 | ||
|
|
50cd472ce6 | ||
|
|
8fb0b9ae35 | ||
|
|
0ed8bab02f | ||
|
|
e66548345c | ||
|
|
1485562f6e | ||
|
|
bb61a31223 | ||
|
|
773c55b820 | ||
|
|
502313dd50 | ||
|
|
0a6598536c | ||
|
|
7655f73c45 | ||
|
|
2d0c589941 | ||
|
|
30f20c0b93 | ||
|
|
5e8786fc22 | ||
|
|
a17d258e94 | ||
|
|
8ce5038e99 | ||
|
|
4ed0177e4a | ||
|
|
a99a7bb071 | ||
|
|
4dcceb650d | ||
|
|
7129dfdba8 | ||
|
|
efc708afae | ||
|
|
d4f4fa22d7 | ||
|
|
8ee3f73464 | ||
|
|
fc863900b7 | ||
|
|
6f0a892ba0 | ||
|
|
a7ccd87090 | ||
|
|
6652799267 | ||
|
|
6ee76fab4c | ||
|
|
81ea01fb1c | ||
|
|
b0c5fff859 | ||
|
|
8eadc50021 | ||
|
|
f03bab0240 | ||
|
|
7c349ae7e9 | ||
|
|
60385207aa | ||
|
|
d63cec6ce3 | ||
|
|
9b783dc492 | ||
|
|
43919b6e2e | ||
|
|
b31b1499cf | ||
|
|
87ae545648 | ||
|
|
0cabddc13b | ||
|
|
4071e7eaab | ||
|
|
fe4b666707 | ||
|
|
a07319a0cc | ||
|
|
4c91e1eb5c | ||
|
|
aa34d29b2e | ||
|
|
5d21cfb170 | ||
|
|
842c0b9f59 | ||
|
|
be3852ab9b | ||
|
|
025af5ccd1 | ||
|
|
706dd2331a | ||
|
|
0ccc767a15 | ||
|
|
e2b46de961 | ||
|
|
297b077b49 | ||
|
|
09dfcb857e | ||
|
|
6be28e7545 | ||
|
|
762bf27fcc | ||
|
|
8161ebbcc3 | ||
|
|
3e6b3d20b2 | ||
|
|
e1ebd54a26 | ||
|
|
c73128381f | ||
|
|
cc08c44904 | ||
|
|
9e0e1e3d54 | ||
|
|
4770ef8742 | ||
|
|
c098e99d06 | ||
|
|
de43cdb2f5 | ||
|
|
b8b8e4f9eb | ||
|
|
4b1f14dcf5 | ||
|
|
d7d2a121a3 | ||
|
|
bf780cbd99 | ||
|
|
3dd0166bde | ||
|
|
11477cdba5 | ||
|
|
47c30a60e6 | ||
|
|
eaa6ac7ffd | ||
|
|
891f354796 | ||
|
|
1e301c21d7 | ||
|
|
24a9a51e57 | ||
|
|
1108c628ba | ||
|
|
116120045b | ||
|
|
ccce40356a | ||
|
|
508b8c3569 | ||
|
|
edb15cce00 | ||
|
|
5ee27f48d7 | ||
|
|
758258f567 | ||
|
|
9cf601f87d | ||
|
|
65add3a818 | ||
|
|
8d9f927078 | ||
|
|
49279d4cc2 | ||
|
|
016064625f | ||
|
|
582c3d514a | ||
|
|
a60e665162 | ||
|
|
33978a49c0 | ||
|
|
2bf28b9db6 | ||
|
|
2d322bf3e9 | ||
|
|
36fff6c754 | ||
|
|
5546294f63 | ||
|
|
e93e215b36 | ||
|
|
5c524e651f | ||
|
|
d4b731e271 | ||
|
|
927e59b74a | ||
|
|
cbe65ccfa0 | ||
|
|
63637e457c | ||
|
|
ed2572b9c8 | ||
|
|
cf8e004a51 | ||
|
|
a1a14982ec | ||
|
|
29ef35abff | ||
|
|
1fd78b9b34 | ||
|
|
68ed682710 | ||
|
|
44ce16b7f9 | ||
|
|
d88493c02b | ||
|
|
87a47c67a6 | ||
|
|
7e1d9d25fe | ||
|
|
d399f25bd1 | ||
|
|
7323a8ab29 | ||
|
|
aa20863f44 | ||
|
|
83269fd13b | ||
|
|
884cd3caa5 | ||
|
|
cc66247603 | ||
|
|
dc2d3856f3 | ||
|
|
dd36b3a06a | ||
|
|
14f555683a | ||
|
|
bd6c1d5149 | ||
|
|
41fc098a86 | ||
|
|
3442c20c4d | ||
|
|
7d222736c2 | ||
|
|
d5154c055b | ||
|
|
cd81993070 | ||
|
|
2481f1320a | ||
|
|
ceeeccc862 | ||
|
|
07df85b958 | ||
|
|
7643e8584f | ||
|
|
533431d5af | ||
|
|
9519b2560e | ||
|
|
3e3e095fc9 | ||
|
|
41f8a8843d | ||
|
|
64bb329afa | ||
|
|
3ecbac5664 | ||
|
|
0e6febff5a | ||
|
|
3f779aef79 | ||
|
|
35ef033a19 | ||
|
|
aec21cd840 | ||
|
|
47e47cfb07 | ||
|
|
314c425b16 | ||
|
|
148c4fb8d2 | ||
|
|
c12ee64e80 | ||
|
|
46cd1699f9 | ||
|
|
32b95471a8 | ||
|
|
f66bfe71bb | ||
|
|
af1e19b9e4 | ||
|
|
334901aea0 | ||
|
|
bbe9a4b542 | ||
|
|
a772aaf5dc | ||
|
|
c39e8d05f5 | ||
|
|
a0715c1e89 | ||
|
|
a0ed412f38 | ||
|
|
2fb7eb05dc | ||
|
|
8e4f737d2f | ||
|
|
2d51cb1d0a | ||
|
|
c165bad0c0 | ||
|
|
16aa8c8146 | ||
|
|
e5be73e178 | ||
|
|
0e0a413725 | ||
|
|
c269c43a83 | ||
|
|
6f3e3cb8ba | ||
|
|
d147114b9d | ||
|
|
ad82036626 | ||
|
|
a6a2d9d1e5 | ||
|
|
6ad2773142 | ||
|
|
1dc59aaf61 | ||
|
|
9aaddbf0ef | ||
|
|
e00fec907f | ||
|
|
d8364f4e1d | ||
|
|
7d0cc12a56 | ||
|
|
de031809f3 | ||
|
|
6550d0580b | ||
|
|
dff4f58107 | ||
|
|
e9f3cc7fc7 | ||
|
|
ee56777379 | ||
|
|
3bd7ad58a7 | ||
|
|
f97bee9ad5 | ||
|
|
cf655d1643 | ||
|
|
31c9c7ad82 | ||
|
|
08f26d99b5 | ||
|
|
c7d38efbc2 | ||
|
|
cbc9d46066 | ||
|
|
2b863d4e9b | ||
|
|
598016b85f | ||
|
|
a2c7840a6b | ||
|
|
c8f5154fc1 | ||
|
|
b526958ca4 | ||
|
|
039a3e6db8 | ||
|
|
d8affeea82 | ||
|
|
1615d83dcf | ||
|
|
41359d381a | ||
|
|
581cce0cca | ||
|
|
1ed4b52732 | ||
|
|
72a2d6ff56 | ||
|
|
9dee25fbc7 | ||
|
|
fa24e3780b | ||
|
|
1e4979f780 | ||
|
|
c11fd9de76 | ||
|
|
c72ac9ffd0 | ||
|
|
31cebfe789 | ||
|
|
b9a24cee3b | ||
|
|
08b1fd6afb | ||
|
|
35cb0c47bc | ||
|
|
dc2942bbc8 | ||
|
|
35db873534 | ||
|
|
3e33685892 | ||
|
|
d95568f9a2 | ||
|
|
6e5ccabbe8 | ||
|
|
266cf258cc | ||
|
|
c90d521f16 | ||
|
|
346fa70bb8 | ||
|
|
e92f585bd9 | ||
|
|
e622d7723b | ||
|
|
1af7ddecda | ||
|
|
b9a0172260 | ||
|
|
3f6aae377a | ||
|
|
0f8de7a3db | ||
|
|
7e8eb30f40 | ||
|
|
8deaed3b12 | ||
|
|
a0c6b4cfd1 | ||
|
|
20d0f32012 | ||
|
|
07c5e65e6d | ||
|
|
7521d5b8da | ||
|
|
487accbf19 | ||
|
|
fa1ee96026 | ||
|
|
e8b9337281 | ||
|
|
aa896c182d | ||
|
|
956407b5df | ||
|
|
7821c96dd0 | ||
|
|
0c0aa5ebba | ||
|
|
3c1eb57d1e | ||
|
|
dc692ae1b7 | ||
|
|
be756396b5 | ||
|
|
d8db018e31 | ||
|
|
c9c619e667 | ||
|
|
48ee545d11 | ||
|
|
7568b0f553 | ||
|
|
fc20e30058 | ||
|
|
32ceeb579e | ||
|
|
ebf8ec5b0f | ||
|
|
548242d1a1 | ||
|
|
e554c667bd | ||
|
|
e6f35a9cd8 | ||
|
|
660229d647 | ||
|
|
32860d2fb8 | ||
|
|
7fd15f2939 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1,2 +1 @@
|
||||
*.pnm -diff -text
|
||||
tests/ref/fate/sub-scc eol=crlf
|
||||
|
||||
599
Changelog
599
Changelog
@@ -1,38 +1,573 @@
|
||||
Entries are sorted chronologically from oldest to youngest within each release,
|
||||
releases are sorted from youngest to oldest.
|
||||
|
||||
version <next>:
|
||||
- CrystalHD decoder moved to new decode API
|
||||
- add internal ebur128 library, remove external libebur128 dependency
|
||||
- Pro-MPEG CoP #3-R2 FEC protocol
|
||||
- premultiply video filter
|
||||
- Support for spherical videos
|
||||
- configure now fails if autodetect-libraries are requested but not found
|
||||
- PSD Decoder
|
||||
- 16.8 floating point pcm decoder
|
||||
- 24.0 floating point pcm decoder
|
||||
- Apple Pixlet decoder
|
||||
- QDMC audio decoder
|
||||
- NewTek SpeedHQ decoder
|
||||
- MIDI Sample Dump Standard demuxer
|
||||
- readeia608 filter
|
||||
- Sample Dump eXchange demuxer
|
||||
- abitscope multimedia filter
|
||||
- Scenarist Closed Captions demuxer and muxer
|
||||
- threshold filter
|
||||
- midequalizer filter
|
||||
- Optimal Huffman tables for (M)JPEG encoding
|
||||
- FM Screen Capture Codec decoder
|
||||
- native Opus encoder
|
||||
- ScreenPressor decoder
|
||||
- incomplete ClearVideo decoder
|
||||
- Intel QSV video scaling and deinterlacing filters
|
||||
- Support MOV with multiple sample description tables
|
||||
- XPM decoder
|
||||
- Removed the legacy X11 screen grabber, use XCB instead
|
||||
- MPEG-7 Video Signature filter
|
||||
- Removed asyncts filter (use af_aresample instead)
|
||||
version 3.2.8:
|
||||
- avcodec/hevc_ps: Fix c?_qp_offset_list size
|
||||
- avcodec/shorten: Move buffer allocation and offset init to end of read_header()
|
||||
- avcodec/jpeg2000dsp: Fix multiple integer overflows in ict_int()
|
||||
- avcodec/hevcdsp_template: Fix undefined shift in put_hevc_pel_bi_w_pixels
|
||||
- avcodec/diracdec: Fix overflow in DC computation
|
||||
- avcodec/dirac_vlc: limit res_bits in APPEND_RESIDUE()
|
||||
- libavcodec/h264_parse: don't use uninitialized value when chroma_format_idc==0
|
||||
- avformat/asfdec: Fix DoS in asf_build_simple_index()
|
||||
- avformat/mov: Fix DoS in read_tfra()
|
||||
- avcodec/dirac_vlc: Fix invalid shift in ff_dirac_golomb_read_32bit()
|
||||
- avcodec/dirac_dwt: Fix multiple overflows in 9/7 lifting
|
||||
- avcodec/diracdec: Fix integer overflow in INTRA_DC_PRED()
|
||||
- avformat/mxfdec: Fix Sign error in mxf_read_primer_pack()
|
||||
- avformat/mxfdec: Fix DoS issues in mxf_read_index_entry_array()
|
||||
- avformat/nsvdec: Fix DoS due to lack of eof check in nsvs_file_offset loop.
|
||||
- avcodec/snowdec: Fix integer overflow in decode_subband_slice_buffered()
|
||||
- avcodec/hevc_ps: Fix undefined shift in pcm code
|
||||
- avcodec/sbrdsp_fixed: Fix undefined overflows in autocorrelate()
|
||||
- avformat/mvdec: Fix DoS due to lack of eof check
|
||||
- avformat/rl2: Fix DoS due to lack of eof check
|
||||
- avformat/rmdec: Fix DoS due to lack of eof check
|
||||
- avformat/cinedec: Fix DoS due to lack of eof check
|
||||
- avformat/asfdec: Fix DoS due to lack of eof check
|
||||
- avformat/hls: Fix DoS due to infinite loop
|
||||
- ffprobe: Fix NULL pointer handling in color parameter printing
|
||||
- ffprobe: Fix null pointer dereference with color primaries
|
||||
- avcodec/hevc_ps: Check delta_pocs in ff_hevc_decode_short_term_rps()
|
||||
- avformat/rtpdec_h264: Fix heap-buffer-overflow
|
||||
- avformat/aviobuf: Fix signed integer overflow in avio_seek()
|
||||
- avformat/mov: Fix signed integer overflows with total_size
|
||||
- avcodec/utils: Fix signed integer overflow in rc_initial_buffer_occupancy initialization
|
||||
- avcodec/aacdec_template: Fix running cleanup in decode_ics_info()
|
||||
- avcodec/me_cmp: Fix crashes on ARM due to misalignment
|
||||
- avcodec/dirac_dwt_template: Fix integer overflow in vertical_compose53iL0()
|
||||
- avcodec/fic: Fixes signed integer overflow
|
||||
- avcodec/snowdec: Fix off by 1 error
|
||||
- avcodec/diracdec: Fixes integer overflow
|
||||
- avcodec/diracdec: Check perspective_exp and zrs_exp.
|
||||
- avcodec/ffv1dec_template: Fix undefined shift
|
||||
- avcodec/mpeg4videodec: Clear mcsel before decoding an image
|
||||
- avcodec/dirac_dwt: Fixes integer overflows in COMPOSE_DAUB97*
|
||||
- avcodec/aacdec_fixed: fix invalid shift in predict()
|
||||
- avcodec/h264_slice: Fix overflow in slice offset
|
||||
- avformat/utils: fix memory leak in avformat_free_context
|
||||
- avcodec/diracdsp: fix integer overflow
|
||||
- avcodec/diracdec: Check weight_log2denom
|
||||
- avfilter/vf_ssim: fix temp size calculation
|
||||
|
||||
version 3.2.7:
|
||||
- avcodec/dirac_dwt: Fix multiple integer overflows in COMPOSE_DD97iH0()
|
||||
- avcodec/diracdec: Fix integer overflow in divide3()
|
||||
- avcodec/takdec: Fix integer overflow in decode_subframe()
|
||||
- avformat/rtmppkt: Convert ff_amf_get_field_value() to bytestream2
|
||||
- avformat/rtmppkt: Convert ff_amf_tag_size() to bytestream2
|
||||
- avcodec/diracdec: Fix integer overflow in signed multiplication in UNPACK_ARITH()
|
||||
- avcodec/dnxhddec: Move mb height check out of non hr branch
|
||||
- avcodec/hevc_ps: fix integer overflow in log2_parallel_merge_level_minus2
|
||||
- avformat/oggparsecelt: Do not re-allocate os->private
|
||||
- avcodec/ylc: Fix shift overflow
|
||||
- avcodec/aacps: Fix multiple integer overflow in map_val_34_to_20()
|
||||
- avcodec/aacdec_fixed: fix: left shift of negative value -1
|
||||
- avcodec/dirac_vlc: Fix undefined shift
|
||||
- doc/filters: typo in frei0r
|
||||
- avcodec/cfhd: Fix decoding regression due to height check
|
||||
- avcodec/aacdec_template (fixed point): Check gain in decode_cce() to avoid undefined shifts later
|
||||
- avcodec/ffv1dec_template: Fix signed integer overflow
|
||||
- avcodec/aacdec_template: Fix undefined integer overflow in apply_tns()
|
||||
- avcodec/magicyuv: Check that vlc len is not too large
|
||||
- avcodec/mjpegdec: Clip DC also on the negative side.
|
||||
- avcodec/aacps (fixed point): Fix multiple signed integer overflows
|
||||
- avcodec/ylc: Fix vlc of 31 bits
|
||||
- avcodec/sbrdsp_fixed: Fix integer overflow in sbr_hf_apply_noise()
|
||||
- avcodec/wavpack: Fix invalid shift
|
||||
- avcodec/h264_slice: Fix signed integer overflow
|
||||
- avcodec/hevc_ps: Fix integer overflow with beta/tc offsets
|
||||
- avcodec/cfhd: Fix invalid left shift of negative value
|
||||
- avcodec/vb: Check vertical GMC component before multiply
|
||||
- avcodec/jpeg2000dwt: Fix integer overflow in dwt_decode97_int()
|
||||
- avcodec/apedec: Fix integer overflow
|
||||
- avcodec/wavpack: Fix integer overflow in wv_unpack_stereo()
|
||||
- avcodec/mpeg4videodec: Fix GMC with videos of dimension 1
|
||||
- avcodec/wavpack: Fix integer overflow
|
||||
- avcodec/takdec: Fix integer overflow
|
||||
- avcodec/tiff: Update pointer only when the result is used
|
||||
- avcodec/cfhd: Check bpc before setting bpc in context
|
||||
- avcodec/cfhd: Fix undefined shift
|
||||
- avcodec/hevc_filter: Fix invalid shift
|
||||
- avcodec/mpeg4videodec: Fix overflow in virtual_ref computation
|
||||
- avcodec/lpc: signed integer overflow in compute_lpc_coefs() (aacdec_fixed)
|
||||
- avcodec/wavpack: Fix undefined integer negation
|
||||
- avcodec/aacdec_fixed: Check s for being too small
|
||||
- avcodec/htmlsubtitles: Replace very slow redundant sscanf() calls by cleaner and faster code
|
||||
- avcodec/h264: Fix mix of lossless and lossy MBs decoding
|
||||
- avcodec/h264_mb: Fix 8x8dct in lossless for new versions of x264
|
||||
- avcodec/h264_cabac: Fix CABAC+8x8dct in 4:4:4
|
||||
- avcodec/takdec: Fixes: integer overflow in AV_SAMPLE_FMT_U8P outpu
|
||||
|
||||
version 3.2.6:
|
||||
- avcodec/jpeg2000dsp: Reorder operations in ict_int() to avoid 2 integer overflows
|
||||
- avcodec/hevcpred_template: Fix left shift of negative value
|
||||
- avcodec/hevcdec: Fix signed integer overflow in decode_lt_rps()
|
||||
- avcodec/jpeg2000dec: Check nonzerobits more completely
|
||||
- avcodec/shorten: Sanity check maxnlpc
|
||||
- avcodec/truemotion2: Move skip computation after checks
|
||||
- avcodec/jpeg2000: Fixes integer overflow in ff_jpeg2000_ceildivpow2()
|
||||
- avcodec/dnxhd_parser: Do not return invalid value from dnxhd_find_frame_end() on error
|
||||
- avcodec/hevcdec: Check nb_sps
|
||||
- avcodec/hevc_refs: Check nb_refs in add_candidate_ref()
|
||||
- avcodec/mpeg4videodec: Check sprite delta upshift against overflowing.
|
||||
- avcodec/mpeg4videodec: Fix integer overflow in num_sprite_warping_points=2 case
|
||||
- avcodec/aacsbr_fixed: Check shift in sbr_hf_assemble()
|
||||
- avcodec/sbrdsp_fixed: Return an error from sbr_hf_apply_noise() if operations are impossible
|
||||
- avcodec/libvpxdec: Check that display dimensions fit in the storage dimensions
|
||||
- avcodec/jpeg2000dwt: Fix runtime error: left shift of negative value -123
|
||||
- avcodec/wavpack: Fix runtime error: signed integer overflow: 1886191616 + 277872640 cannot be represented in type 'int'
|
||||
- avcodec/snowdec: Fix runtime error: left shift of negative value -1
|
||||
- avcodec/aacdec_fixed: Fix runtime error: left shift of negative value -1297616
|
||||
- avcodec/tiff: Fix leak of geotags[].val
|
||||
- avcodec/ra144: Fix runtime error: signed integer overflow: -2200 * 1033073 cannot be represented in type 'int'
|
||||
- avcodec/flicvideo: Fix runtime error: signed integer overflow: 4864 * 459296 cannot be represented in type 'int'
|
||||
- avcodec/cfhd: Check band parameters before storing them
|
||||
- avcodec/h264_parse: Check picture structure when initializig weight table
|
||||
- avcodec/indeo4: Check remaining data in Pic hdr extension parsing code
|
||||
- avcodec/ac3dec_fixed: Fix multiple runtime error: signed integer overflow: -39271008 * 59 cannot be represented in type 'int'
|
||||
- avcodec/mpeg4videodec: Fix runtime error: signed integer overflow: 53098 * 40448 cannot be represented in type 'int'
|
||||
- avcodec/pafvideo: Fix assertion failure
|
||||
- avcodec/takdec: Fix multiple runtime error: signed integer overflow: 637072 * 4096 cannot be represented in type 'int'
|
||||
- avcodec/mjpegdec: Check that reference frame matches the current frame
|
||||
- avcodec/tiff: Avoid loosing allocated geotag values
|
||||
- avcodec/cavs: Fix runtime error: signed integer overflow: -12648062 * 256 cannot be represented in type 'int'
|
||||
- avformat/hls: Check local file extensions
|
||||
- avcodec/qdrw: Fix null pointer dereference
|
||||
- avutil/softfloat: Fix sign error in and improve documentation of av_int2sf()
|
||||
- avcodec/hevc_ps: Fix runtime error: index 32 out of bounds for type 'uint8_t [32]'
|
||||
- avcodec/dxv: Check remaining bytes in dxv_decompress_raw()
|
||||
- avcodec/pafvideo: Check packet size and frame code before ff_reget_buffer()
|
||||
- avcodec/ac3dec_fixed: Fix runtime error: left shift of 419 by 23 places cannot be represented in type 'int'
|
||||
- avformat/options: log filename on open
|
||||
- avcodec/aacps: Fix runtime error: left shift of 1073741824 by 1 places cannot be represented in type 'INTFLOAT' (aka 'int')
|
||||
- avcodec/wavpack: Fix runtime error: shift exponent 32 is too large for 32-bit type 'int'
|
||||
- avcodec/cfhd: Fix runtime error: signed integer overflow: 65280 * 65288 cannot be represented in type 'int'
|
||||
- avcodec/wavpack: Fix runtime error: signed integer overflow: 2013265955 - -134217694 cannot be represented in type 'int'
|
||||
- avcodec/cinepak: Check input packet size before frame reallocation
|
||||
- avcodec/hevc_ps: Fix runtime error: signed integer overflow: 2147483628 + 256 cannot be represented in type 'int'
|
||||
- avcodec/ra144: Fixes runtime error: signed integer overflow: 7160 * 327138 cannot be represented in type 'int'
|
||||
- avcodec/pnm: Use ff_set_dimensions()
|
||||
- avcodec/cavsdec: Fix runtime error: signed integer overflow: 59 + 2147483600 cannot be represented in type 'int'
|
||||
- avformat/avidec: Limit formats in gab2 to srt and ass/ssa
|
||||
- avcodec/acelp_pitch_delay: Fix runtime error: value 4.83233e+39 is outside the range of representable values of type 'float'
|
||||
- avcodec/wavpack: Check float_shift
|
||||
- avcodec/wavpack: Fix runtime error: signed integer overflow: 24 * -2147483648 cannot be represented in type 'int'
|
||||
- avcodec/ansi: Fix frame memleak
|
||||
- avcodec/dds: Fix runtime error: left shift of 145 by 24 places cannot be represented in type 'int'
|
||||
- avcodec/jpeg2000dec: Use ff_set_dimensions()
|
||||
- avcodec/truemotion2: Fix passing null pointer to memset()
|
||||
- avcodec/truemotion2: Fix runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
|
||||
- avcodec/ra144: Fix runtime error: signed integer overflow: -2449 * 1398101 cannot be represented in type 'int'
|
||||
- avcodec/ra144: Fix runtime error: signed integer overflow: 11184810 * 404 cannot be represented in type 'int'
|
||||
- avcodec/aac_defines: Add missing () to AAC_HALF_SUM() macro
|
||||
- avcodec/webp: Fixes null pointer dereference
|
||||
- avcodec/aacdec_fixed: Fix runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
|
||||
- avcodec/ylc: Check count in build_vlc()
|
||||
- avcodec/snow: Fix runtime error: signed integer overflow: 1086573993 + 1086573994 cannot be represented in type 'int'
|
||||
- avcodec/jpeg2000: Fix runtime error: signed integer overflow: 4185 + 2147483394 cannot be represented in type 'int'
|
||||
- avcodec/jpeg2000dec: Check tile offsets more completely
|
||||
- avcodec/sheervideo: Check input buffer size before allocating and decoding
|
||||
- avcodec/aacdec_fixed: Fix multiple runtime error: shift exponent 127 is too large for 32-bit type 'int'
|
||||
- avcodec/wnv1: More strict buffer size check
|
||||
- avcodec/libfdk-aacdec: Correct buffer_size parameter
|
||||
- avcodec/sbrdsp_template: Fix: runtime error: signed integer overflow: 849815297 + 1315389781 cannot be represented in type 'int'
|
||||
- avcodec/ivi_dsp: Fix runtime error: left shift of negative value -2
|
||||
- doc/filters: Clarify scale2ref example
|
||||
- avcodec/mlpdec: Do not leave invalid values in matrix_out_ch[] on error
|
||||
- avcodec/ra144dec: Fix runtime error: left shift of negative value -17
|
||||
- avformat/mux: Fix copy an paste typo
|
||||
- avutil/internal: Do not enable CHECKED with DEBUG
|
||||
- avcodec/aacdec_fixed: Fix runtime error: signed integer overflow: -2147483648 * -1 cannot be represented in type 'int'
|
||||
- avcodec/smc: Check remaining input
|
||||
- avcodec/diracdec: Fix off by 1 error in quant check
|
||||
- avcodec/jpeg2000dec: Fix copy and paste error
|
||||
- avcodec/jpeg2000dec: Check tile offsets
|
||||
- avcodec/sanm: Fix uninitialized reference frames
|
||||
- avcodec/jpeglsdec: Check get_bits_left() before decoding a picture
|
||||
- avcodec/ivi_dsp: Fix multiple runtime error: left shift of negative value -71
|
||||
- avcodec/mjpegdec: Fix runtime error: signed integer overflow: -32767 * 130560 cannot be represented in type 'int'
|
||||
- avcodec/aacdec_fixed: Fix runtime error: shift exponent 34 is too large for 32-bit type 'int'
|
||||
- avcodec/mpeg4videodec: Check for multiple VOL headers
|
||||
- avcodec/vmnc: Check location before use
|
||||
- avcodec/takdec: Fix runtime error: signed integer overflow: 8192 * 524308 cannot be represented in type 'int'
|
||||
- avcodec/aac_defines: Fix: runtime error: left shift of negative value -2
|
||||
- avcodec/takdec: Fix runtime error: left shift of negative value -63
|
||||
- avcodec/mlpdsp: Fix runtime error: signed integer overflow: -24419392 * 128 cannot be represented in type 'int'
|
||||
- avcodec/sbrdsp_fixed: fix runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
|
||||
- avcodec/aacsbr_fixed: Fix multiple runtime error: shift exponent 170 is too large for 32-bit type 'int'
|
||||
- avcodec/mlpdec: Do not leave a invalid num_primitive_matrices in the context
|
||||
- avcodec/aacsbr_fixed: Fix multiple runtime error: shift exponent 150 is too large for 32-bit type 'int'
|
||||
- avcodec/mimic: Use ff_set_dimensions() to set the dimensions
|
||||
- avcodec/fic: Fix multiple runtime error: signed integer overflow: 5793 * 419752 cannot be represented in type 'int'
|
||||
- avcodec/mlpdec: Fix: runtime error: left shift of negative value -8
|
||||
- avcodec/dfa: Fix: runtime error: signed integer overflow: -14202 * 196877 cannot be represented in type 'int'
|
||||
- avcodec/aacdec: Fix runtime error: signed integer overflow: 2147483520 + 255 cannot be represented in type 'int'
|
||||
- avcodec/aacdec_template: Fix fixed point scale in decode_cce()
|
||||
- avcodec/flicvideo: Check frame_size before decrementing
|
||||
- avcodec/mlpdec: Fix runtime error: left shift of negative value -1
|
||||
- avcodec/takdec: Fix runtime error: left shift of negative value -42
|
||||
- avcodec/hq_hqa: Fix: runtime error: signed integer overflow: -255 * 10180917 cannot be represented in type 'int'
|
||||
- avcodec/nvenc: remove unnecessary alignment
|
||||
- avutil/hwcontext_dxva2: Don't improperly free IDirect3DSurface9 objects
|
||||
- avcodec/hevc_sei: fix amount of bits skipped when reading picture timing SEI message
|
||||
- avcodec/aac_adtstoasc: fix ASC passthrough on small frames
|
||||
|
||||
|
||||
version 3.2.5:
|
||||
- avcodec/truemotion1: Fix multiple runtime error: signed integer overflow: 1246906962 * 2 cannot be represented in type 'int'
|
||||
- avcodec/svq3: Fix runtime error: left shift of negative value -6
|
||||
- avcodec/tiff: reset sampling[] if its invalid
|
||||
- avcodec/aacps: Fix undefined behavior
|
||||
- avcodec/opus_silk: Fix integer overflow and out of array read
|
||||
- avcodec/flacdec: Return error code instead of 0 for failures
|
||||
- avcodec/snowdec: Check width
|
||||
- avcodec/webp: Update canvas size in vp8_lossy_decode_frame() as in vp8_lossless_decode_frame()
|
||||
- avcodec/webp: Factor update_canvas_size() out
|
||||
- avcodec/cllc: Check prefix
|
||||
- avcodec/rscc: Check pixel_size for overflow
|
||||
- avcodec/dds: Fix runtime error: left shift of 210 by 24 places cannot be represented in type 'int'
|
||||
- avcodec/mpeg4videodec: Clear sprite wraping on unsupported cases in VOP decode
|
||||
- avcodec/ac3dec: Fix: runtime error: index -1 out of bounds for type 'INTFLOAT [2]'
|
||||
- avcodec/hqxdsp: Fix runtime error: signed integer overflow: -196264 * 11585 cannot be represented in type 'int'
|
||||
- avcodec/g723_1dec: Fix LCG type
|
||||
- libswscale/tests/swscale: Fix uninitialized variables
|
||||
- avcodec/ffv1dec: Fix runtime error: signed integer overflow: 1550964438 + 1550964438 cannot be represented in type 'int'
|
||||
- avcodec/webp: Fix signedness in prefix_code check
|
||||
- avcodec/svq3: Fix runtime error: signed integer overflow: 169 * 12717677 cannot be represented in type 'int'
|
||||
- avcodec/mlpdec: Check that there is enough data for headers
|
||||
- avcodec/ac3dec: Keep track of band structure
|
||||
- avcodec/webp: Add missing input padding
|
||||
- avcodec/aacdec_fixed: Fix runtime error: left shift of negative value -1
|
||||
- avcodec/aacsbr_template: Do not change bs_num_env before its checked
|
||||
- avcodec/mlp: Fix multiple runtime error: left shift of negative value -1
|
||||
- avcodec/vp8dsp: vp7_luma_dc_wht_c: Fix multiple runtime error: signed integer overflow: -1366381240 + -1262413604 cannot be represented in type 'int'
|
||||
- avcodec/avcodec: Limit the number of side data elements per packet
|
||||
- avcodec/texturedsp: Fix runtime error: left shift of 255 by 24 places cannot be represented in type 'int'
|
||||
- avcodec/g723_1dec: Fix runtime error: left shift of negative value -1
|
||||
- avcodec/wmv2dsp: Fix runtime error: signed integer overflow: 181 * -17047030 cannot be represented in type 'int'
|
||||
- avcodec/diracdec: Fix Assertion frame->buf[0] failed at libavcodec/decode.c:610
|
||||
- avcodec/msmpeg4dec: Check for cbpy VLC errors
|
||||
- avcodec/cllc: Check num_bits
|
||||
- avcodec/cllc: Factor VLC_BITS/DEPTH out, do not use repeated literal numbers
|
||||
- avcodec/dvbsubdec: Check entry_id
|
||||
- avcodec/aacdec_fixed: Fix multiple shift exponent 33 is too large for 32-bit type 'int'
|
||||
- avcodec/mpeg12dec: Fixes runtime error: division by zero
|
||||
- avcodec/webp: Always set pix_fmt
|
||||
- avfilter/vf_uspp: Fix currently unused input frame dimensions
|
||||
- avcodec/truemotion1: Fix multiple runtime error: left shift of negative value -1
|
||||
- avcodec/eatqi: Fix runtime error: signed integer overflow: 4466147 * 1075 cannot be represented in type 'int'
|
||||
- avcodec/dss_sp: Fix runtime error: signed integer overflow: 2147481189 + 4096 cannot be represented in type 'int'
|
||||
- avformat/wavdec: Check chunk_size
|
||||
- avcodec/cavs: Check updated MV
|
||||
- avcodec/y41pdec: Fix width in input buffer size check
|
||||
- avcodec/svq3: Fix multiple runtime error: signed integer overflow: -237341 * 24552 cannot be represented in type 'int'
|
||||
- avcodec/texturedsp: Fix runtime error: left shift of 218 by 24 places cannot be represented in type 'int'
|
||||
- avcodec/lagarith: Check scale_factor
|
||||
- avcodec/lagarith: Fix runtime error: left shift of negative value -1
|
||||
- avcodec/takdec: Fix multiple runtime error: left shift of negative value -1
|
||||
- avcodec/indeo2: Check for invalid VLCs
|
||||
- avcodec/g723_1dec: Fix several integer related cases of undefined behaviour
|
||||
- avcodec/htmlsubtitles: Check for string truncation and return error
|
||||
- avcodec/bmvvideo: Fix runtime error: left shift of 137 by 24 places cannot be represented in type 'int'
|
||||
- avcodec/dss_sp: Fix multiple runtime error: signed integer overflow: -15699 * -164039 cannot be represented in type 'int'
|
||||
- avcodec/dvbsubdec: check region dimensions
|
||||
- avcodec/vp8dsp: Fixes: runtime error: signed integer overflow: 1330143360 - -1023040530 cannot be represented in type 'int'
|
||||
- avcodec/hqxdsp: Fix multiple runtime error: signed integer overflow: 248220 * 21407 cannot be represented in type 'int' in idct_col()
|
||||
- avcodec/cavsdec: Check sym_factor
|
||||
- avcodec/cdxl: Check format for BGR24
|
||||
- avcodec/ffv1dec: Fix copying planes of paletted formats
|
||||
- avcodec/wmv2dsp: Fix runtime error: signed integer overflow: 181 * -12156865 cannot be represented in type 'int'
|
||||
- avcodec/xwddec: Check bpp more completely
|
||||
- avcodec/aacdec_template: Do not decode 2nd PCE if it will lead to failure
|
||||
- avcodec/s302m: Fix left shift of 8 by 28 places cannot be represented in type 'int'
|
||||
- avcodec/eamad: Fix runtime error: signed integer overflow: 49674 * 49858 cannot be represented in type 'int'
|
||||
- avcodec/g726: Fix runtime error: left shift of negative value -2
|
||||
- avcodec/ra144: Fix runtime error: left shift of negative value -798
|
||||
- avcodec/mss34dsp: Fix multiple signed integer overflow
|
||||
- avcodec/targa_y216dec: Fix width type
|
||||
- avcodec/texturedsp: Fix multiple runtime error: left shift of 255 by 24 places cannot be represented in type 'int'
|
||||
- avcodec/ivi_dsp: Fix multiple left shift of negative value -2
|
||||
- avcodec/svq3: Fix multiple runtime error: signed integer overflow: 44161 * 61694 cannot be represented in type 'int'
|
||||
- avcodec/msmpeg4dec: Correct table depth
|
||||
- avcodec/dds: Fix runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
|
||||
- avcodec/cdxl: Check format parameter
|
||||
- avutil/softfloat: Fix overflow in av_div_sf()
|
||||
- avcodec/hq_hqa: Fix runtime error: left shift of negative value -207
|
||||
- avcodec/mss3: Change types in rac_get_model_sym() to match the types they are initialized from
|
||||
- avcodec/shorten: Check k in get_uint()
|
||||
- avcodec/webp: Fix null pointer dereference
|
||||
- avcodec/dfa: Fix signed integer overflow: -2147483648 - 1 cannot be represented in type 'int'
|
||||
- avcodec/g723_1: Fix multiple runtime error: left shift of negative value
|
||||
- avcodec/mimic: Fix runtime error: left shift of negative value -1
|
||||
- avcodec/fic: Fix multiple left shift of negative value -15
|
||||
- avcodec/mlpdec: Fix runtime error: left shift of negative value -22
|
||||
- avcodec/snowdec: Check qbias
|
||||
- avutil/softfloat: Fix multiple runtime error: left shift of negative value -8
|
||||
- avcodec/aacsbr_template: Do not leave bs_num_env invalid
|
||||
- avcodec/mdec: Fix signed integer overflow: 28835400 * 83 cannot be represented in type 'int'
|
||||
- avcodec/dfa: Fix off by 1 error
|
||||
- avcodec/nellymoser: Fix multiple left shift of negative value -8591
|
||||
- avcodec/cdxl: Fix signed integer overflow: 14243456 * 164 cannot be represented in type 'int'
|
||||
- avcodec/g722: Fix multiple runtime error: left shift of negative value -1
|
||||
- avcodec/dss_sp: Fix multiple left shift of negative value -466
|
||||
- avcodec/wnv1: Fix runtime error: left shift of negative value -1
|
||||
- avcodec/tiertexseqv: set the fixed dimenasions, do not depend on the demuxer doing so
|
||||
- avcodec/mjpegdec: Fix runtime error: signed integer overflow: -24543 * 2031616 cannot be represented in type 'int'
|
||||
- avcodec/cavsdec: Fix undefined behavior from integer overflow
|
||||
- avcodec/dvdsubdec: Fix runtime error: left shift of 242 by 24 places cannot be represented in type 'int'
|
||||
- libavcodec/mpeg4videodec: Convert sprite_offset to 64bit
|
||||
- avcodec/pngdec: Use ff_set_dimensions()
|
||||
- avcodec/msvideo1: Check buffer size before re-getting the frame
|
||||
- avcodec/h264_cavlc: Fix undefined behavior on qscale overflow
|
||||
- avcodec/dcadsp: Fix runtime error: signed integer overflow
|
||||
- avcodec/svq3: Reject dx/dy beyond 16bit
|
||||
- avcodec/svq3: Increase offsets to prevent integer overflows
|
||||
- avcodec/indeo2: Check remaining bits in ir2_decode_plane()
|
||||
- avcodec/vp3: Check remaining bits in unpack_dct_coeffs()
|
||||
- doc/developer: Add terse documentation of assumed C implementation defined behavior
|
||||
- avcodec/mdec: Fix runtime error: left shift of negative value -127
|
||||
- avcodec/x86/vc1dsp_init: Fix build failure with --disable-optimizations and clang
|
||||
- libavcodec/exr : fix float to uint16 conversion for negative float value
|
||||
- avformat/webmdashenc: Validate the 'streams' adaptation sets parameter
|
||||
- avformat/webmdashenc: Require the 'adaptation_sets' option to be set
|
||||
- avformat/oggparseogm: Check ff_alloc_extradata() for failure
|
||||
- avformat/oggparseogm: Check available data before reading global header
|
||||
- avformat/mov: Check creation_time for overflow
|
||||
- avcodec/dvdsubdec: Fixes 2 runtime error: left shift of 170 by 24 places cannot be represented in type 'int'
|
||||
- avcodec/h264: Check weight values to be within the specs limits.
|
||||
- libavformat/mov: Fix memory leak, need to free the chapter tracks array
|
||||
- avformat/oggparsedaala: Do not leave an invalid value in gpshift
|
||||
- avformat/oggparsedaala: Check duration for AV_NOPTS_VALUE
|
||||
- avformat/libopenmpt: Check for avio_size() failure
|
||||
- avfilter/af_sofalizer: Fix bad shift
|
||||
- avcodec: fix uninitialized variable read
|
||||
- avfilter/avfiltergraph: Add assert to write down in machine readable form what is assumed about sample rates in swap_samplerates_on_filter()
|
||||
- avcodec/tiff: Perform multiply in tiff_unpack_lzma() as 64bit
|
||||
- avformat/test/fifo_muxer: add check for FailingMuxerPacketData alloc
|
||||
- omx: Fix OOM check
|
||||
- avcodec/vdpau_hevc: Fix potential out-of-bounds write
|
||||
- avcodec/h264_ps: Fix runtime error: signed integer overflow: 2147483647 + 26 cannot be represented in type 'int'
|
||||
- avcodec/tiff: Check geotag count for being non zero
|
||||
- avcodec/vp56: Check avctx->error_concealment before enabling EC
|
||||
- avcodec/tiff: Check stripsize strippos for overflow
|
||||
- avcodec/mpegaudiodec_template: Make l3_unscale() work with e=0
|
||||
- avcodec/tiff: Check for multiple geo key directories
|
||||
- avcodec/wavpack: Fix runtime error: shift exponent 32 is too large for 32-bit type 'int'
|
||||
- avcodec/rv34: Fix runtime error: signed integer overflow: 36880 * 66288 cannot be represented in type 'int'
|
||||
- avcodec/amrwbdec: Fix runtime error: left shift of negative value -1
|
||||
- avcodec/mpeg4videodec: Fix runtime error: signed integer overflow: -135088512 * 16 cannot be represented in type 'int'
|
||||
- avcodec/h264_mvpred: Fix runtime error: left shift of negative value -1
|
||||
- avcodec/mjpegdec: Fix runtime error: left shift of negative value -127
|
||||
- avcodec/wavpack: Fix runtime error: left shift of negative value -5
|
||||
- avcodec/wavpack: Fix runtime error: left shift of negative value -2
|
||||
- avcodec/mpeg4videodec: Fix runtime error: signed integer overflow: 134527392 * 16 cannot be represented in type 'int'
|
||||
- avcodec/mpeg12dec: Fix runtime error: left shift of negative value -13
|
||||
- avcodec/h264_mvpred: Fix multiple runtime error: left shift of negative value
|
||||
- avcodec/adxdec: Fix runtime error: left shift of negative value -1
|
||||
- avcodec/mpeg4videodec: Improve the overflow checks in mpeg4_decode_sprite_trajectory()
|
||||
- avcodec/mjpegdec: Fix runtime error: left shift of negative value -511
|
||||
- avcodec/h264_direct: Fix runtime error: left shift of negative value -14
|
||||
- avcodec/pictordec: Check plane value before doing value/mask computations
|
||||
- avcodec/mpeg4videodec: Fix runtime error: left shift of negative value -2650
|
||||
- avcodec/eac3dec: Fix runtime error: left shift of negative value -3
|
||||
- avcodec/mpeg12dec: Fix runtime error: left shift of negative value -2
|
||||
- avcodec/mpeg4videodec: Check the other 3 sprite points for intermediate overflows
|
||||
- avcodec/mpeg4videodec: Check sprite_offset in addition to shifts
|
||||
- avcodec/mpeg4video: Fix runtime error: left shift of negative value
|
||||
- avcodec/ituh263dec: Fix runtime error: left shift of negative value -22
|
||||
- avcodec/rv40: Fix runtime error: left shift of negative value
|
||||
- avcodec/h264_cabac: runtime error: signed integer overflow: 2147483647 + 14 cannot be represented in type 'int'
|
||||
- avcodec/mpeg4videodec: Fix runtime error: shift exponent -2 is negative
|
||||
- avcodec/mjpegdec: Fix runtime error: left shift of negative value -507
|
||||
- avcodec/eac3dec: Fix runtime error: left shift of negative value
|
||||
- avcodec/htmlsubtitles: Fix reading one byte beyond the array
|
||||
- avcodec/vp6: clear dimensions on failed resolution change in vp6_parse_header()
|
||||
- avcodec/vp56: Reset have_undamaged_frame on resolution changes
|
||||
- avcodec/vp8: Fix hang with slice threads
|
||||
- avcodec/vp8: Check for the bitstream end per MB in decode_mb_row_no_filter()
|
||||
- avcodec/vp568: Check that there is enough data for ff_vp56_init_range_decoder()
|
||||
- avcodec/vp8: remove redundant check
|
||||
- avcodec/vp56: Require a correctly decoded frame before using vp56_conceal_mb()
|
||||
- avcodec/vp3: Do not return random positive values but the buf size
|
||||
- avcodec/vp8: Check for bitsteam end in decode_mb_row_no_filter()
|
||||
- avcodec/vp56: Factorize vp56_render_mb() out
|
||||
- avcodec/vp3dsp: Fix multiple signed integer overflow: 46341 * 47523 cannot be represented in type 'int'
|
||||
- Add CHECK/SUINT code
|
||||
- avcodec/mpeg12dec: Fix runtime error: left shift of negative value -1
|
||||
- avcodec/vp56: Clear dimensions in case of failure in the middle of a resolution change
|
||||
- avcodec/vp56: Implement very basic error concealment
|
||||
- avcodec/amrwbdec: Fix 2 runtime errors: left shift of negative value -1
|
||||
- avcodec/pngdec: Fix runtime error: left shift of 152 by 24 places cannot be represented in type 'int'
|
||||
- avcodec/vp56: Fix sign typo
|
||||
- avcodec/mpegaudiodec_template: Correct return code on id3 tag discarding
|
||||
- avcodec/rv34: Simplify and factor get_slice_offset() code
|
||||
- avcodec/pictordec: Do not read more than nb_planes
|
||||
- avcodec/srtdec: Fix signed integer overflow: 1811992524 * 384 cannot be represented in type 'int'
|
||||
- avcodec/pngdec: Check bit depth for validity
|
||||
- avcodec/mpeg12dec: Fix runtime error: left shift of negative value
|
||||
- avcodec/wavpacl: Fix runtime error: left shift of negative value -1
|
||||
- avformat/http: Check for truncated buffers in http_connect()
|
||||
- avformat/utils: free AVStream.codec properly in free_stream()
|
||||
- avcodec/options: do a more thorough clean up in avcodec_copy_context()
|
||||
- avcodec/options: factorize avcodec_copy_context() cleanup code
|
||||
- avformat/concatdec: fix the h264 annexb extradata check
|
||||
- hwcontext_vdpau: Fix missing subscripts
|
||||
- lavf/flacdec: Return maximum score if the streaminfo header is valid.
|
||||
- avcodec/dnxhd_parser: take into account compressed frame size and skip it
|
||||
- avformat/apng: fix setting frame delay when max_fps is set to no limit
|
||||
- swresample/resample: free existing ResampleContext on reinit
|
||||
- swresample/resample: move resample_free() higher in the file
|
||||
- avformat/matroskaenc: don't write DisplayUnit with value Unknown on WebM files
|
||||
- lavfi/buffersrc: fix directly setting channel layout
|
||||
- lavf/mpeg: Initialize a stack variable used by memcmp().
|
||||
- lavc/avpacket: Initialize a variable in error path.
|
||||
|
||||
|
||||
version 3.2.4:
|
||||
- avcodec/h264_slice: Clear ref_counts on redundant slices
|
||||
- lavf/mov.c: Avoid heap allocation wrap in mov_read_uuid
|
||||
- lavf/mov.c: Avoid heap allocation wrap in mov_read_hdlr
|
||||
- avcodec/pictordec: Fix logic error
|
||||
- ffserver_config: Setup codecpar in add_codec()
|
||||
- Changelog: fix typos
|
||||
|
||||
version 3.2.3:
|
||||
- avcodec/movtextdec: Fix decode_styl() cleanup
|
||||
- lavf/matroskadec: fix is_keyframe for early Blocks
|
||||
- configure: bump year
|
||||
- avcodec/pngdec: Check trns more completely
|
||||
- avcodec/interplayvideo: Move parameter change check up
|
||||
- avcodec/dca_lbr: Fix off by 1 error in freq check
|
||||
- avcodec/mjpegdec: Check for for the bitstream end in mjpeg_decode_scan_progressive_ac()
|
||||
- pgssubdec: reset rle_data_len/rle_remaining_len on allocation error
|
||||
- swscale: save ebx register when it is not available
|
||||
- avformat/flacdec: Check avio_read result when reading flac block header.
|
||||
- avcodec/utils: correct align value for interplay
|
||||
- avcodec/vp56: Check for the bitstream end, pass error codes on
|
||||
- avcodec/mjpegdec: Check remaining bitstream in ljpeg_decode_yuv_scan()
|
||||
- avcodec/pngdec: Fix off by 1 size in decode_zbuf()
|
||||
- libopenmpt: add missing avio_read return value check
|
||||
- avcodec/bsf: Fix av_bsf_list_free()
|
||||
- avcodec/omx: Do not pass negative value into av_malloc()
|
||||
- avformat/avidec: skip odml master index chunks in avi_sync
|
||||
- avcodec/mjpegdec: Check for rgb before flipping
|
||||
- lavf/utils.c Protect against accessing entries[nb_entries]
|
||||
- avutil/random_seed: Reduce the time needed on systems with very low precision clock()
|
||||
- swscale/swscale: Fix dereference of stride array before null check
|
||||
- avutil/random_seed: Improve get_generic_seed() with higher precision clock()
|
||||
- avformat/mp3dec: fix msan warning when verifying mpa header
|
||||
- avformat/utils: Print verbose error message if stream count exceeds max_streams
|
||||
- avformat/options_table: Set the default maximum number of streams to 1000
|
||||
- lavf/chromaprint: Update for version 1.4
|
||||
- avutil: Add av_image_check_size2()
|
||||
- avformat: Add max_streams option
|
||||
- avcodec/ffv1enc: Allocate smaller packet if the worst case size cannot be allocated
|
||||
- avcodec/mpeg4videodec: Fix undefined shifts in mpeg4_decode_sprite_trajectory()
|
||||
- avformat/oggdec: Skip streams in duration correction that did not had their duration set.
|
||||
- avcodec/ffv1enc: Fix size of first slice
|
||||
- ffplay: fix sws_scale possible out of bounds array access
|
||||
- avfilter/vf_hwupload_cuda: Add min/max limits for the 'device' option
|
||||
|
||||
version 3.2.2:
|
||||
- ffserver: Check chunk size
|
||||
- Avoid using the term "file" and prefer "url" in some docs and comments
|
||||
- avformat/rtmppkt: Check for packet size mismatches
|
||||
- zmqsend: Initialize ret to 0
|
||||
- avcodec/flacdec: Fix undefined shift in decode_subframe()
|
||||
- avcodec/get_bits: Fix get_sbits_long(0)
|
||||
- avformat/ffmdec: Check media type for chunks
|
||||
- avcodec/flacdec: Fix signed integer overflow in decode_subframe_fixed()
|
||||
- avcodec/flacdsp_template: Fix undefined shift in flac_decorrelate_indep_c
|
||||
- avformat/oggparsespeex: Check frames_per_packet and packet_size
|
||||
- avformat/utils: Check start/end before computing duration in update_stream_timings()
|
||||
- avcodec/flac_parser: Update nb_headers_buffered
|
||||
- avformat/idroqdec: Check chunk_size for being too large
|
||||
- avcodec/me_cmp: Fix median_sad size
|
||||
- avformat/utils: Fix type mismatch
|
||||
- configure: check for strtoull on msvc
|
||||
- http: move chunk handling from http_read_stream() to http_buf_read().
|
||||
- http: make length/offset-related variables unsigned
|
||||
|
||||
version 3.2.1:
|
||||
- avcodec/aac_adtstoasc_bsf: validate and forward extradata if the stream is already ASC
|
||||
- mss2: only use error correction for matching block counts
|
||||
- softfloat: decrease MIN_EXP to cover full float range
|
||||
- libopusdec: default to stereo for invalid number of channels
|
||||
- flvdec: require need_context_update when changing codec id
|
||||
- pgssubdec: only set w/h/linesize when allocating data
|
||||
- sbgdec: prevent NULL pointer access
|
||||
- rmdec: validate block alignment
|
||||
- smacker: limit recursion depth of smacker_decode_bigtree
|
||||
- mxfdec: fix NULL pointer dereference in mxf_read_packet_old
|
||||
- ffmdec: validate codec parameters
|
||||
- avformat/mpeg: Adjust vid probe threshold to correct mis-detection
|
||||
- avcodec/ass_split: Change order of operations in ass_split_section()
|
||||
- avcodec/rawdec: check for side data before checking its size
|
||||
- avcodec/avpacket: fix leak on realloc in av_packet_add_side_data()
|
||||
- avformat/apngenc: use the stream parameters extradata if available
|
||||
- Revert "apngdec: use side data to pass extradata to the decoder"
|
||||
- ffprobe: fix crash in case -of is specified with an empty string
|
||||
- libavcodec/exr : fix channel size calculation for uint32 channel
|
||||
- exr: fix out-of-bounds read
|
||||
- libschroedingerdec: fix leaking of framewithpts
|
||||
- libschroedingerdec: don't produce empty frames
|
||||
- dds: limit 4 bpp handling to AV_PIX_FMT_PAL8
|
||||
- mlz: limit next_code to data buffer size
|
||||
- softfloat: handle -INT_MAX correctly
|
||||
- filmstripdec: correctly check image dimensions
|
||||
- pnmdec: make sure v is capped by maxval
|
||||
- smvjpegdec: make sure cur_frame is not negative
|
||||
- icodec: correctly check avio_read return value
|
||||
- icodec: fix leaking pkt on error
|
||||
- dvbsubdec: fix division by zero in compute_default_clut
|
||||
- proresdec_lgpl: explicitly check coff[3] against slice_data_size
|
||||
- escape124: reject codebook size 0
|
||||
- mpegts: prevent division by zero
|
||||
- matroskadec: fix NULL pointer dereference in webm_dash_manifest_read_header
|
||||
- mpegaudio_parser: don't return AVERROR_PATCHWELCOME
|
||||
- mxfdec: fix NULL pointer dereference
|
||||
- lzf: update pointer p after realloc
|
||||
- diracdec: check return code of get_buffer_with_edge
|
||||
- diracdec: clear slice_params_num_buf on allocation failure
|
||||
- diracdec: use correct buffer for slice_params_buf realloc
|
||||
- ppc: pixblockdsp: do unaligned block accesses correctly again
|
||||
- avformat: close parser if codec changed
|
||||
- fate: add streamcopy test for apng
|
||||
- apngdec: use side data to pass extradata to the decoder
|
||||
- mov: immediately return from mov_fix_index without old index entries
|
||||
- interplayacm: increase bitstream buffer size by AV_INPUT_BUFFER_PADDING_SIZE
|
||||
- interplayacm: validate number of channels
|
||||
- interplayacm: check for too large b
|
||||
- doc: fix spelling errors
|
||||
- configure: make sure LTO does not optimize out the test functions
|
||||
- fate: add apng encoding/muxing test
|
||||
- apng: use side data to pass extradata to muxer
|
||||
- avcodec/mpeg4videodec: Workaround interlaced mpeg4 edge MC bug
|
||||
- avcodec/mpegvideo: Fix edge emu buffer overlap with interlaced mpeg4
|
||||
- avcodec/rv40: Test remaining space in loop of get_dimension()
|
||||
- avcodec/ituh263dec: Avoid spending a long time in slice sync
|
||||
- avcodec/movtextdec: Add error message for tsmb_size check
|
||||
- avcodec/movtextdec: Fix tsmb_size check==0 check
|
||||
- avcodec/movtextdec: Fix potential integer overflow
|
||||
- ffmpeg: Fix bsf corrupting merged side data
|
||||
- avcodec/sunrast: Fix input buffer pointer check
|
||||
- avcodec/tscc: Check side data size before use
|
||||
- avcodec/rscc: Fix constant
|
||||
- avcodec/rawdec: Check side data size before use
|
||||
- avcodec/rscc: Check side data size before use
|
||||
- avcodec/msvideo1: Check side data size before use
|
||||
- avcodec/qpeg: Check side data size before use
|
||||
- avcodec/qtrle: Check side data size before use
|
||||
- avcodec/msrle: Check side data size before use
|
||||
- avcodec/kmvc: Check side data size before use
|
||||
- avcodec/idcinvideo: Check side data size before use
|
||||
- avcodec/cinepak: Check side data size before use
|
||||
- avcodec/8bps: Check side data size before use
|
||||
- avformat/flvdec: Fix regression losing streams
|
||||
- avformat/hls: Add missing error check for avcodec_parameters_copy()
|
||||
- avformat/hls: Fix probing mpegts audio streams that use probing
|
||||
- avformat/hls: Factor copying stream info to a separate function
|
||||
|
||||
version 3.2:
|
||||
- libopenmpt demuxer
|
||||
@@ -71,7 +606,6 @@ version 3.2:
|
||||
- Matroska muxer now writes CRC32 elements by default in all Level 1 elements
|
||||
- sidedata video and asidedata audio filter
|
||||
- Changed mapping of rtp MIME type G726 to codec g726le.
|
||||
- spec compliant VAAPI/DXVA2 VC-1 decoding of slices in frame-coded images
|
||||
|
||||
|
||||
version 3.1:
|
||||
@@ -119,7 +653,6 @@ version 3.1:
|
||||
- libutvideo wrapper removed
|
||||
- YUY2 Lossless Codec decoder
|
||||
- VideoToolbox H.264 encoder
|
||||
- VAAPI-accelerated MPEG-2 and VP8 encoding
|
||||
|
||||
|
||||
version 3.0:
|
||||
|
||||
@@ -17,6 +17,7 @@ Specifically, the GPL parts of FFmpeg are:
|
||||
- `libavcodec/x86/flac_dsp_gpl.asm`
|
||||
- `libavcodec/x86/idct_mmx.c`
|
||||
- `libavfilter/x86/vf_removegrain.asm`
|
||||
- the X11 grabber in `libavdevice/x11grab.c`
|
||||
- the following building and testing tools
|
||||
- `compat/solaris/make_sunver.pl`
|
||||
- `doc/t2h.pm`
|
||||
@@ -25,6 +26,7 @@ Specifically, the GPL parts of FFmpeg are:
|
||||
- `tests/checkasm/*`
|
||||
- `tests/tiny_ssim.c`
|
||||
- the following filters in libavfilter:
|
||||
- `f_ebur128.c`
|
||||
- `vf_blackframe.c`
|
||||
- `vf_boxblur.c`
|
||||
- `vf_colormatrix.c`
|
||||
|
||||
44
MAINTAINERS
44
MAINTAINERS
@@ -47,7 +47,6 @@ project server Árpád Gereöffy, Michael Niedermayer,
|
||||
presets Robert Swain
|
||||
metadata subsystem Aurelien Jacobs
|
||||
release management Michael Niedermayer
|
||||
API tests Ludmila Glinskih
|
||||
|
||||
|
||||
Communication
|
||||
@@ -60,7 +59,6 @@ mailing lists Baptiste Coudurier, Lou Logan
|
||||
Google+ Paul B Mahol, Michael Niedermayer, Alexander Strasser
|
||||
Twitter Lou Logan, Reynaldo H. Verdejo Pinochet
|
||||
Launchpad Timothy Gu
|
||||
ffmpeg-security Andreas Cadhalpun, Carl Eugen Hoyos, Clément Bœsch, Michael Niedermayer, Reimar Doeffinger, Rodger Combs, wm4
|
||||
|
||||
|
||||
libavutil
|
||||
@@ -116,8 +114,6 @@ Generic Parts:
|
||||
lzw.* Michael Niedermayer
|
||||
floating point AAN DCT:
|
||||
faandct.c, faandct.h Michael Niedermayer
|
||||
Non-power-of-two MDCT:
|
||||
mdct15.c, mdct15.h Rostislav Pehlivanov
|
||||
Golomb coding:
|
||||
golomb.c, golomb.h Michael Niedermayer
|
||||
motion estimation:
|
||||
@@ -179,7 +175,7 @@ Codecs:
|
||||
h263* Michael Niedermayer
|
||||
h264* Loren Merritt, Michael Niedermayer
|
||||
hap* Tom Butterworth
|
||||
huffyuv* Michael Niedermayer
|
||||
huffyuv* Michael Niedermayer, Christophe Gisquet
|
||||
idcinvideo.c Mike Melanson
|
||||
interplayvideo.c Mike Melanson
|
||||
jni*, ffjni* Matthieu Bouron
|
||||
@@ -212,14 +208,13 @@ Codecs:
|
||||
msvideo1.c Mike Melanson
|
||||
nuv.c Reimar Doeffinger
|
||||
nvenc* Timo Rothenpieler
|
||||
opus* Rostislav Pehlivanov
|
||||
paf.* Paul B Mahol
|
||||
pcx.c Ivo van Poorten
|
||||
pgssubdec.c Reimar Doeffinger
|
||||
ptx.c Ivo van Poorten
|
||||
qcelp* Reynaldo H. Verdejo Pinochet
|
||||
qdm2.c, qdm2data.h Roberto Togni
|
||||
qsv* Mark Thompson
|
||||
qsv* Ivan Uskov
|
||||
qtrle.c Mike Melanson
|
||||
ra144.c, ra144.h, ra288.c, ra288.h Roberto Togni
|
||||
resample2.c Michael Niedermayer
|
||||
@@ -227,6 +222,7 @@ Codecs:
|
||||
rpza.c Roberto Togni
|
||||
rtjpeg.c, rtjpeg.h Reimar Doeffinger
|
||||
rv10.c Michael Niedermayer
|
||||
rv4* Christophe Gisquet
|
||||
s3tc* Ivo van Poorten
|
||||
smc.c Mike Melanson
|
||||
smvjpegdec.c Ash Hughes
|
||||
@@ -240,6 +236,7 @@ Codecs:
|
||||
tta.c Alex Beregszaszi, Jaikrishnan Menon
|
||||
ttaenc.c Paul B Mahol
|
||||
txd.c Ivo van Poorten
|
||||
vc1* Christophe Gisquet
|
||||
vc2* Rostislav Pehlivanov
|
||||
vcr1.c Michael Niedermayer
|
||||
vda_h264_dec.c Xidorn Quan
|
||||
@@ -264,8 +261,7 @@ Codecs:
|
||||
|
||||
Hardware acceleration:
|
||||
crystalhd.c Philip Langdale
|
||||
dxva2* Hendrik Leppkes, Laurent Aimar, Steve Lhomme
|
||||
d3d11va* Steve Lhomme
|
||||
dxva2* Hendrik Leppkes, Laurent Aimar
|
||||
mediacodec* Matthieu Bouron
|
||||
vaapi* Gwenole Beauchesne
|
||||
vaapi_encode* Mark Thompson
|
||||
@@ -388,7 +384,6 @@ Muxers/Demuxers:
|
||||
avisynth.c Stephen Hutchinson
|
||||
avr.c Paul B Mahol
|
||||
bink.c Peter Ross
|
||||
boadec.c Michael Niedermayer
|
||||
brstm.c Paul B Mahol
|
||||
caf* Peter Ross
|
||||
cdxl.c Paul B Mahol
|
||||
@@ -401,8 +396,7 @@ Muxers/Demuxers:
|
||||
epafdec.c Paul B Mahol
|
||||
ffm* Baptiste Coudurier
|
||||
flic.c Mike Melanson
|
||||
flvdec.c Michael Niedermayer
|
||||
flvenc.c Michael Niedermayer, Steven Liu
|
||||
flvdec.c, flvenc.c Michael Niedermayer
|
||||
gxf.c Reimar Doeffinger
|
||||
gxfenc.c Baptiste Coudurier
|
||||
hls.c Anssi Hannula
|
||||
@@ -529,32 +523,6 @@ Sparc Roman Shaposhnik
|
||||
OS/2 KO Myung-Hun
|
||||
|
||||
|
||||
Developers with git write access who are currently not maintaining any specific part
|
||||
====================================================================================
|
||||
Alex Converse
|
||||
Andreas Cadhalpun
|
||||
Anuradha Suraparaju
|
||||
Ben Littler
|
||||
Benjamin Larsson
|
||||
Bobby Bingham
|
||||
Daniel Verkamp
|
||||
Derek Buitenhuis
|
||||
Ganesh Ajjanagadde
|
||||
Henrik Gramner
|
||||
Ivan Uskov
|
||||
James Darnley
|
||||
Joakim Plate
|
||||
Kieran Kunhya
|
||||
Kirill Gavrilov
|
||||
Martin Storsjö
|
||||
Panagiotis Issaris
|
||||
Pedro Arthur
|
||||
Sebastien Zwickert
|
||||
Vittorio Giovara
|
||||
wm4
|
||||
(this list is incomplete)
|
||||
|
||||
|
||||
Releases
|
||||
========
|
||||
|
||||
|
||||
12
Makefile
12
Makefile
@@ -79,13 +79,8 @@ tools/cws2fws$(EXESUF): ELIBS = $(ZLIB)
|
||||
tools/uncoded_frame$(EXESUF): $(FF_DEP_LIBS)
|
||||
tools/uncoded_frame$(EXESUF): ELIBS = $(FF_EXTRALIBS)
|
||||
|
||||
CONFIGURABLE_COMPONENTS = \
|
||||
$(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) \
|
||||
$(SRC_PATH)/libavcodec/bitstream_filters.c \
|
||||
$(SRC_PATH)/libavformat/protocols.c \
|
||||
|
||||
config.h: .config
|
||||
.config: $(CONFIGURABLE_COMPONENTS)
|
||||
.config: $(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c))
|
||||
@-tput bold 2>/dev/null
|
||||
@-printf '\nWARNING: $(?F) newer than config.h, rerun configure\n\n'
|
||||
@-tput sgr0 2>/dev/null
|
||||
@@ -93,7 +88,7 @@ config.h: .config
|
||||
SUBDIR_VARS := CLEANFILES EXAMPLES FFLIBS HOSTPROGS TESTPROGS TOOLS \
|
||||
HEADERS ARCH_HEADERS BUILT_HEADERS SKIPHEADERS \
|
||||
ARMV5TE-OBJS ARMV6-OBJS ARMV8-OBJS VFP-OBJS NEON-OBJS \
|
||||
ALTIVEC-OBJS VSX-OBJS MMX-OBJS YASM-OBJS \
|
||||
ALTIVEC-OBJS MMX-OBJS YASM-OBJS \
|
||||
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSP-OBJS MSA-OBJS \
|
||||
MMI-OBJS OBJS SLIBOBJS HOSTOBJS TESTOBJS
|
||||
|
||||
@@ -184,9 +179,6 @@ clean::
|
||||
$(RM) $(ALLAVPROGS) $(ALLAVPROGS_G)
|
||||
$(RM) $(CLEANSUFFIXES)
|
||||
$(RM) $(CLEANSUFFIXES:%=tools/%)
|
||||
$(RM) $(CLEANSUFFIXES:%=compat/msvcrt/%)
|
||||
$(RM) $(CLEANSUFFIXES:%=compat/atomics/pthread/%)
|
||||
$(RM) $(CLEANSUFFIXES:%=compat/%)
|
||||
$(RM) -r coverage-html
|
||||
$(RM) -rf coverage.info coverage.info.in lcov
|
||||
|
||||
|
||||
15
RELEASE_NOTES
Normal file
15
RELEASE_NOTES
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
┌────────────────────────────────────────┐
|
||||
│ RELEASE NOTES for FFmpeg 3.2 "Hypatia" │
|
||||
└────────────────────────────────────────┘
|
||||
|
||||
The FFmpeg Project proudly presents FFmpeg 3.2 "Hypatia", about 4
|
||||
months after the release of FFmpeg 3.1.
|
||||
|
||||
A complete Changelog is available at the root of the project, and the
|
||||
complete Git history on http://source.ffmpeg.org.
|
||||
|
||||
We hope you will like this release as much as we enjoyed working on it, and
|
||||
as usual, if you have any questions about it, or any FFmpeg related topic,
|
||||
feel free to join us on the #ffmpeg IRC channel (on irc.freenode.net) or ask
|
||||
on the mailing-lists.
|
||||
77
cmdutils.c
77
cmdutils.c
@@ -75,12 +75,6 @@ static FILE *report_file;
|
||||
static int report_file_level = AV_LOG_DEBUG;
|
||||
int hide_banner = 0;
|
||||
|
||||
enum show_muxdemuxers {
|
||||
SHOW_DEFAULT,
|
||||
SHOW_DEMUXERS,
|
||||
SHOW_MUXERS,
|
||||
};
|
||||
|
||||
void init_opts(void)
|
||||
{
|
||||
av_dict_set(&sws_dict, "flags", "bicubic", 0);
|
||||
@@ -231,6 +225,7 @@ static const OptionDef *find_option(const OptionDef *po, const char *name)
|
||||
* by default. HAVE_COMMANDLINETOARGVW is true on cygwin, while
|
||||
* it doesn't provide the actual command line via GetCommandLineW(). */
|
||||
#if HAVE_COMMANDLINETOARGVW && defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
/* Will be leaked on exit */
|
||||
static char** win32_argv_utf8 = NULL;
|
||||
@@ -1256,7 +1251,7 @@ static int is_device(const AVClass *avclass)
|
||||
return AV_IS_INPUT_DEVICE(avclass->category) || AV_IS_OUTPUT_DEVICE(avclass->category);
|
||||
}
|
||||
|
||||
static int show_formats_devices(void *optctx, const char *opt, const char *arg, int device_only, int muxdemuxers)
|
||||
static int show_formats_devices(void *optctx, const char *opt, const char *arg, int device_only)
|
||||
{
|
||||
AVInputFormat *ifmt = NULL;
|
||||
AVOutputFormat *ofmt = NULL;
|
||||
@@ -1274,33 +1269,29 @@ static int show_formats_devices(void *optctx, const char *opt, const char *arg,
|
||||
const char *name = NULL;
|
||||
const char *long_name = NULL;
|
||||
|
||||
if (muxdemuxers !=SHOW_DEMUXERS) {
|
||||
while ((ofmt = av_oformat_next(ofmt))) {
|
||||
is_dev = is_device(ofmt->priv_class);
|
||||
if (!is_dev && device_only)
|
||||
continue;
|
||||
if ((!name || strcmp(ofmt->name, name) < 0) &&
|
||||
strcmp(ofmt->name, last_name) > 0) {
|
||||
name = ofmt->name;
|
||||
long_name = ofmt->long_name;
|
||||
encode = 1;
|
||||
}
|
||||
while ((ofmt = av_oformat_next(ofmt))) {
|
||||
is_dev = is_device(ofmt->priv_class);
|
||||
if (!is_dev && device_only)
|
||||
continue;
|
||||
if ((!name || strcmp(ofmt->name, name) < 0) &&
|
||||
strcmp(ofmt->name, last_name) > 0) {
|
||||
name = ofmt->name;
|
||||
long_name = ofmt->long_name;
|
||||
encode = 1;
|
||||
}
|
||||
}
|
||||
if (muxdemuxers != SHOW_MUXERS) {
|
||||
while ((ifmt = av_iformat_next(ifmt))) {
|
||||
is_dev = is_device(ifmt->priv_class);
|
||||
if (!is_dev && device_only)
|
||||
continue;
|
||||
if ((!name || strcmp(ifmt->name, name) < 0) &&
|
||||
strcmp(ifmt->name, last_name) > 0) {
|
||||
name = ifmt->name;
|
||||
long_name = ifmt->long_name;
|
||||
encode = 0;
|
||||
}
|
||||
if (name && strcmp(ifmt->name, name) == 0)
|
||||
decode = 1;
|
||||
while ((ifmt = av_iformat_next(ifmt))) {
|
||||
is_dev = is_device(ifmt->priv_class);
|
||||
if (!is_dev && device_only)
|
||||
continue;
|
||||
if ((!name || strcmp(ifmt->name, name) < 0) &&
|
||||
strcmp(ifmt->name, last_name) > 0) {
|
||||
name = ifmt->name;
|
||||
long_name = ifmt->long_name;
|
||||
encode = 0;
|
||||
}
|
||||
if (name && strcmp(ifmt->name, name) == 0)
|
||||
decode = 1;
|
||||
}
|
||||
if (!name)
|
||||
break;
|
||||
@@ -1317,22 +1308,12 @@ static int show_formats_devices(void *optctx, const char *opt, const char *arg,
|
||||
|
||||
int show_formats(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
return show_formats_devices(optctx, opt, arg, 0, SHOW_DEFAULT);
|
||||
}
|
||||
|
||||
int show_muxers(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
return show_formats_devices(optctx, opt, arg, 0, SHOW_MUXERS);
|
||||
}
|
||||
|
||||
int show_demuxers(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
return show_formats_devices(optctx, opt, arg, 0, SHOW_DEMUXERS);
|
||||
return show_formats_devices(optctx, opt, arg, 0);
|
||||
}
|
||||
|
||||
int show_devices(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
return show_formats_devices(optctx, opt, arg, 1, SHOW_DEFAULT);
|
||||
return show_formats_devices(optctx, opt, arg, 1);
|
||||
}
|
||||
|
||||
#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, get_name) \
|
||||
@@ -2097,10 +2078,18 @@ void *grow_array(void *array, int elem_size, int *size, int new_size)
|
||||
|
||||
double get_rotation(AVStream *st)
|
||||
{
|
||||
AVDictionaryEntry *rotate_tag = av_dict_get(st->metadata, "rotate", NULL, 0);
|
||||
uint8_t* displaymatrix = av_stream_get_side_data(st,
|
||||
AV_PKT_DATA_DISPLAYMATRIX, NULL);
|
||||
double theta = 0;
|
||||
if (displaymatrix)
|
||||
|
||||
if (rotate_tag && *rotate_tag->value && strcmp(rotate_tag->value, "0")) {
|
||||
char *tail;
|
||||
theta = av_strtod(rotate_tag->value, &tail);
|
||||
if (*tail)
|
||||
theta = 0;
|
||||
}
|
||||
if (displaymatrix && !theta)
|
||||
theta = -av_display_rotation_get((int32_t*) displaymatrix);
|
||||
|
||||
theta -= 360*floor(theta/360 + 0.9/360);
|
||||
|
||||
14
cmdutils.h
14
cmdutils.h
@@ -441,20 +441,6 @@ int show_license(void *optctx, const char *opt, const char *arg);
|
||||
*/
|
||||
int show_formats(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Print a listing containing all the muxers supported by the
|
||||
* program (including devices).
|
||||
* This option processing function does not utilize the arguments.
|
||||
*/
|
||||
int show_muxers(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Print a listing containing all the demuxer supported by the
|
||||
* program (including devices).
|
||||
* This option processing function does not utilize the arguments.
|
||||
*/
|
||||
int show_demuxers(void *optctx, const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Print a listing containing all the devices supported by the
|
||||
* program.
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
{ "version" , OPT_EXIT, {.func_arg = show_version}, "show version" },
|
||||
{ "buildconf" , OPT_EXIT, {.func_arg = show_buildconf}, "show build configuration" },
|
||||
{ "formats" , OPT_EXIT, {.func_arg = show_formats }, "show available formats" },
|
||||
{ "muxers" , OPT_EXIT, {.func_arg = show_muxers }, "show available muxers" },
|
||||
{ "demuxers" , OPT_EXIT, {.func_arg = show_demuxers }, "show available demuxers" },
|
||||
{ "devices" , OPT_EXIT, {.func_arg = show_devices }, "show available devices" },
|
||||
{ "codecs" , OPT_EXIT, {.func_arg = show_codecs }, "show available codecs" },
|
||||
{ "decoders" , OPT_EXIT, {.func_arg = show_decoders }, "show available decoders" },
|
||||
|
||||
@@ -213,27 +213,22 @@ static int compare_ocl_device_desc(const void *a, const void *b)
|
||||
|
||||
int opt_opencl_bench(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
int i, j, nb_devices = 0, count = 0, ret = 0;
|
||||
int i, j, nb_devices = 0, count = 0;
|
||||
int64_t score = 0;
|
||||
AVOpenCLDeviceList *device_list;
|
||||
AVOpenCLDeviceNode *device_node = NULL;
|
||||
OpenCLDeviceBenchmark *devices = NULL;
|
||||
cl_platform_id platform;
|
||||
|
||||
ret = av_opencl_get_device_list(&device_list);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
av_opencl_get_device_list(&device_list);
|
||||
for (i = 0; i < device_list->platform_num; i++)
|
||||
nb_devices += device_list->platform_node[i]->device_num;
|
||||
if (!nb_devices) {
|
||||
av_log(NULL, AV_LOG_ERROR, "No OpenCL device detected!\n");
|
||||
av_opencl_free_device_list(&device_list);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if (!(devices = av_malloc_array(nb_devices, sizeof(OpenCLDeviceBenchmark)))) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Could not allocate buffer\n");
|
||||
av_opencl_free_device_list(&device_list);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,15 +74,6 @@ COMPILE_HOSTC = $(call COMPILE,HOSTCC)
|
||||
%_host.o: %.c
|
||||
$(COMPILE_HOSTC)
|
||||
|
||||
%$(DEFAULT_YASMD).asm: %.asm
|
||||
$(DEPYASM) $(YASMFLAGS) -I $(<D)/ -M -o $@ $< > $(@:.asm=.d)
|
||||
$(YASM) $(YASMFLAGS) -I $(<D)/ -e $< | sed '/^%/d;/^$$/d;' > $@
|
||||
|
||||
%.o: %.asm
|
||||
$(DEPYASM) $(YASMFLAGS) -I $(<D)/ -M -o $@ $< > $(@:.o=.d)
|
||||
$(YASM) $(YASMFLAGS) -I $(<D)/ -o $@ $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<)
|
||||
-$(if $(ASMSTRIPFLAGS), $(STRIP) $(ASMSTRIPFLAGS) $@)
|
||||
|
||||
%.o: %.rc
|
||||
$(WINDRES) $(IFLAGS) --preprocessor "$(DEPWINDRES) -E -xc-header -DRC_INVOKED $(CC_DEPFLAGS)" -o $@ $<
|
||||
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* based on vlc_atomic.h from VLC
|
||||
* Copyright (C) 2010 Rémi Denis-Courmont
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_ATOMICS_DUMMY_STDATOMIC_H
|
||||
#define COMPAT_ATOMICS_DUMMY_STDATOMIC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define ATOMIC_FLAG_INIT 0
|
||||
|
||||
#define ATOMIC_VAR_INIT(value) (value)
|
||||
|
||||
#define atomic_init(obj, value) \
|
||||
do { \
|
||||
*(obj) = (value); \
|
||||
} while(0)
|
||||
|
||||
#define kill_dependency(y) ((void)0)
|
||||
|
||||
#define atomic_thread_fence(order) \
|
||||
((void)0)
|
||||
|
||||
#define atomic_signal_fence(order) \
|
||||
((void)0)
|
||||
|
||||
#define atomic_is_lock_free(obj) 0
|
||||
|
||||
typedef intptr_t atomic_flag;
|
||||
typedef intptr_t atomic_bool;
|
||||
typedef intptr_t atomic_char;
|
||||
typedef intptr_t atomic_schar;
|
||||
typedef intptr_t atomic_uchar;
|
||||
typedef intptr_t atomic_short;
|
||||
typedef intptr_t atomic_ushort;
|
||||
typedef intptr_t atomic_int;
|
||||
typedef intptr_t atomic_uint;
|
||||
typedef intptr_t atomic_long;
|
||||
typedef intptr_t atomic_ulong;
|
||||
typedef intptr_t atomic_llong;
|
||||
typedef intptr_t atomic_ullong;
|
||||
typedef intptr_t atomic_wchar_t;
|
||||
typedef intptr_t atomic_int_least8_t;
|
||||
typedef intptr_t atomic_uint_least8_t;
|
||||
typedef intptr_t atomic_int_least16_t;
|
||||
typedef intptr_t atomic_uint_least16_t;
|
||||
typedef intptr_t atomic_int_least32_t;
|
||||
typedef intptr_t atomic_uint_least32_t;
|
||||
typedef intptr_t atomic_int_least64_t;
|
||||
typedef intptr_t atomic_uint_least64_t;
|
||||
typedef intptr_t atomic_int_fast8_t;
|
||||
typedef intptr_t atomic_uint_fast8_t;
|
||||
typedef intptr_t atomic_int_fast16_t;
|
||||
typedef intptr_t atomic_uint_fast16_t;
|
||||
typedef intptr_t atomic_int_fast32_t;
|
||||
typedef intptr_t atomic_uint_fast32_t;
|
||||
typedef intptr_t atomic_int_fast64_t;
|
||||
typedef intptr_t atomic_uint_fast64_t;
|
||||
typedef intptr_t atomic_intptr_t;
|
||||
typedef intptr_t atomic_uintptr_t;
|
||||
typedef intptr_t atomic_size_t;
|
||||
typedef intptr_t atomic_ptrdiff_t;
|
||||
typedef intptr_t atomic_intmax_t;
|
||||
typedef intptr_t atomic_uintmax_t;
|
||||
|
||||
#define atomic_store(object, desired) \
|
||||
do { \
|
||||
*(object) = (desired); \
|
||||
} while (0)
|
||||
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
atomic_store(object, desired)
|
||||
|
||||
#define atomic_load(object) \
|
||||
(*(object))
|
||||
|
||||
#define atomic_load_explicit(object, order) \
|
||||
atomic_load(object)
|
||||
|
||||
static inline intptr_t atomic_exchange(intptr_t *object, intptr_t desired)
|
||||
{
|
||||
intptr_t ret = *object;
|
||||
*object = desired;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define atomic_exchange_explicit(object, desired, order) \
|
||||
atomic_exchange(object, desired)
|
||||
|
||||
static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
|
||||
intptr_t desired)
|
||||
{
|
||||
int ret;
|
||||
if (*object == *expected) {
|
||||
*object = desired;
|
||||
ret = 1;
|
||||
} else {
|
||||
*expected = *object;
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_weak(object, expected, desired)
|
||||
|
||||
#define FETCH_MODIFY(opname, op) \
|
||||
static inline intptr_t atomic_fetch_ ## opname(intptr_t *object, intptr_t operand) \
|
||||
{ \
|
||||
intptr_t ret; \
|
||||
ret = *object; \
|
||||
*object = *object op operand; \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
FETCH_MODIFY(add, +)
|
||||
FETCH_MODIFY(sub, -)
|
||||
FETCH_MODIFY(or, |)
|
||||
FETCH_MODIFY(xor, ^)
|
||||
FETCH_MODIFY(and, &)
|
||||
|
||||
#undef FETCH_MODIFY
|
||||
|
||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
||||
atomic_fetch_add(object, operand)
|
||||
|
||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
||||
atomic_fetch_sub(object, operand)
|
||||
|
||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
||||
atomic_fetch_or(object, operand)
|
||||
|
||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
||||
atomic_fetch_xor(object, operand)
|
||||
|
||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
||||
atomic_fetch_and(object, operand)
|
||||
|
||||
#define atomic_flag_test_and_set(object) \
|
||||
atomic_exchange(object, 1)
|
||||
|
||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
||||
atomic_flag_test_and_set(object)
|
||||
|
||||
#define atomic_flag_clear(object) \
|
||||
atomic_store(object, 0)
|
||||
|
||||
#define atomic_flag_clear_explicit(object, order) \
|
||||
atomic_flag_clear(object)
|
||||
|
||||
#endif /* COMPAT_ATOMICS_DUMMY_STDATOMIC_H */
|
||||
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* based on vlc_atomic.h from VLC
|
||||
* Copyright (C) 2010 Rémi Denis-Courmont
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_ATOMICS_GCC_STDATOMIC_H
|
||||
#define COMPAT_ATOMICS_GCC_STDATOMIC_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define ATOMIC_FLAG_INIT 0
|
||||
|
||||
#define ATOMIC_VAR_INIT(value) (value)
|
||||
|
||||
#define atomic_init(obj, value) \
|
||||
do { \
|
||||
*(obj) = (value); \
|
||||
} while(0)
|
||||
|
||||
#define kill_dependency(y) ((void)0)
|
||||
|
||||
#define atomic_thread_fence(order) \
|
||||
__sync_synchronize()
|
||||
|
||||
#define atomic_signal_fence(order) \
|
||||
((void)0)
|
||||
|
||||
#define atomic_is_lock_free(obj) 0
|
||||
|
||||
typedef _Bool atomic_flag;
|
||||
typedef _Bool atomic_bool;
|
||||
typedef char atomic_char;
|
||||
typedef signed char atomic_schar;
|
||||
typedef unsigned char atomic_uchar;
|
||||
typedef short atomic_short;
|
||||
typedef unsigned short atomic_ushort;
|
||||
typedef int atomic_int;
|
||||
typedef unsigned int atomic_uint;
|
||||
typedef long atomic_long;
|
||||
typedef unsigned long atomic_ulong;
|
||||
typedef long long atomic_llong;
|
||||
typedef unsigned long long atomic_ullong;
|
||||
typedef wchar_t atomic_wchar_t;
|
||||
typedef int_least8_t atomic_int_least8_t;
|
||||
typedef uint_least8_t atomic_uint_least8_t;
|
||||
typedef int_least16_t atomic_int_least16_t;
|
||||
typedef uint_least16_t atomic_uint_least16_t;
|
||||
typedef int_least32_t atomic_int_least32_t;
|
||||
typedef uint_least32_t atomic_uint_least32_t;
|
||||
typedef int_least64_t atomic_int_least64_t;
|
||||
typedef uint_least64_t atomic_uint_least64_t;
|
||||
typedef int_fast8_t atomic_int_fast8_t;
|
||||
typedef uint_fast8_t atomic_uint_fast8_t;
|
||||
typedef int_fast16_t atomic_int_fast16_t;
|
||||
typedef uint_fast16_t atomic_uint_fast16_t;
|
||||
typedef int_fast32_t atomic_int_fast32_t;
|
||||
typedef uint_fast32_t atomic_uint_fast32_t;
|
||||
typedef int_fast64_t atomic_int_fast64_t;
|
||||
typedef uint_fast64_t atomic_uint_fast64_t;
|
||||
typedef intptr_t atomic_intptr_t;
|
||||
typedef uintptr_t atomic_uintptr_t;
|
||||
typedef size_t atomic_size_t;
|
||||
typedef ptrdiff_t atomic_ptrdiff_t;
|
||||
typedef intmax_t atomic_intmax_t;
|
||||
typedef uintmax_t atomic_uintmax_t;
|
||||
|
||||
#define atomic_store(object, desired) \
|
||||
do { \
|
||||
*(object) = (desired); \
|
||||
__sync_synchronize(); \
|
||||
} while (0)
|
||||
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
atomic_store(object, desired)
|
||||
|
||||
#define atomic_load(object) \
|
||||
(__sync_synchronize(), *(object))
|
||||
|
||||
#define atomic_load_explicit(object, order) \
|
||||
atomic_load(object)
|
||||
|
||||
#define atomic_exchange(object, desired) \
|
||||
({ \
|
||||
__typeof__(object) _obj = (object); \
|
||||
__typeof__(*object) _old; \
|
||||
do \
|
||||
_old = atomic_load(_obj); \
|
||||
while (!__sync_bool_compare_and_swap(_obj, _old, (desired))); \
|
||||
_old; \
|
||||
})
|
||||
|
||||
#define atomic_exchange_explicit(object, desired, order) \
|
||||
atomic_exchange(object, desired)
|
||||
|
||||
#define atomic_compare_exchange_strong(object, expected, desired) \
|
||||
({ \
|
||||
__typeof__(object) _exp = (expected); \
|
||||
__typeof__(*object) _old = *_exp; \
|
||||
*_exp = __sync_val_compare_and_swap((object), _old, (desired)); \
|
||||
*_exp == _old; \
|
||||
})
|
||||
|
||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_weak(object, expected, desired)
|
||||
|
||||
#define atomic_fetch_add(object, operand) \
|
||||
__sync_fetch_and_add(object, operand)
|
||||
|
||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
||||
atomic_fetch_add(object, operand)
|
||||
|
||||
#define atomic_fetch_sub(object, operand) \
|
||||
__sync_fetch_and_sub(object, operand)
|
||||
|
||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
||||
atomic_fetch_sub(object, operand)
|
||||
|
||||
#define atomic_fetch_or(object, operand) \
|
||||
__sync_fetch_and_or(object, operand)
|
||||
|
||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
||||
atomic_fetch_or(object, operand)
|
||||
|
||||
#define atomic_fetch_xor(object, operand) \
|
||||
__sync_fetch_and_xor(object, operand)
|
||||
|
||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
||||
atomic_fetch_xor(object, operand)
|
||||
|
||||
#define atomic_fetch_and(object, operand) \
|
||||
__sync_fetch_and_and(object, operand)
|
||||
|
||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
||||
atomic_fetch_and(object, operand)
|
||||
|
||||
#define atomic_flag_test_and_set(object) \
|
||||
atomic_exchange(object, 1)
|
||||
|
||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
||||
atomic_flag_test_and_set(object)
|
||||
|
||||
#define atomic_flag_clear(object) \
|
||||
atomic_store(object, 0)
|
||||
|
||||
#define atomic_flag_clear_explicit(object, order) \
|
||||
atomic_flag_clear(object)
|
||||
|
||||
#endif /* COMPAT_ATOMICS_GCC_STDATOMIC_H */
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* based on vlc_atomic.h from VLC
|
||||
* Copyright (C) 2010 Rémi Denis-Courmont
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "stdatomic.h"
|
||||
|
||||
static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
void avpriv_atomic_lock(void)
|
||||
{
|
||||
pthread_mutex_lock(&atomic_lock);
|
||||
}
|
||||
|
||||
void avpriv_atomic_unlock(void)
|
||||
{
|
||||
pthread_mutex_unlock(&atomic_lock);
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* based on vlc_atomic.h from VLC
|
||||
* Copyright (C) 2010 Rémi Denis-Courmont
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_ATOMICS_PTHREAD_STDATOMIC_H
|
||||
#define COMPAT_ATOMICS_PTHREAD_STDATOMIC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define ATOMIC_FLAG_INIT 0
|
||||
|
||||
#define ATOMIC_VAR_INIT(value) (value)
|
||||
|
||||
#define atomic_init(obj, value) \
|
||||
do { \
|
||||
*(obj) = (value); \
|
||||
} while(0)
|
||||
|
||||
#define kill_dependency(y) ((void)0)
|
||||
|
||||
#define atomic_signal_fence(order) \
|
||||
((void)0)
|
||||
|
||||
#define atomic_is_lock_free(obj) 0
|
||||
|
||||
typedef intptr_t atomic_flag;
|
||||
typedef intptr_t atomic_bool;
|
||||
typedef intptr_t atomic_char;
|
||||
typedef intptr_t atomic_schar;
|
||||
typedef intptr_t atomic_uchar;
|
||||
typedef intptr_t atomic_short;
|
||||
typedef intptr_t atomic_ushort;
|
||||
typedef intptr_t atomic_int;
|
||||
typedef intptr_t atomic_uint;
|
||||
typedef intptr_t atomic_long;
|
||||
typedef intptr_t atomic_ulong;
|
||||
typedef intptr_t atomic_llong;
|
||||
typedef intptr_t atomic_ullong;
|
||||
typedef intptr_t atomic_wchar_t;
|
||||
typedef intptr_t atomic_int_least8_t;
|
||||
typedef intptr_t atomic_uint_least8_t;
|
||||
typedef intptr_t atomic_int_least16_t;
|
||||
typedef intptr_t atomic_uint_least16_t;
|
||||
typedef intptr_t atomic_int_least32_t;
|
||||
typedef intptr_t atomic_uint_least32_t;
|
||||
typedef intptr_t atomic_int_least64_t;
|
||||
typedef intptr_t atomic_uint_least64_t;
|
||||
typedef intptr_t atomic_int_fast8_t;
|
||||
typedef intptr_t atomic_uint_fast8_t;
|
||||
typedef intptr_t atomic_int_fast16_t;
|
||||
typedef intptr_t atomic_uint_fast16_t;
|
||||
typedef intptr_t atomic_int_fast32_t;
|
||||
typedef intptr_t atomic_uint_fast32_t;
|
||||
typedef intptr_t atomic_int_fast64_t;
|
||||
typedef intptr_t atomic_uint_fast64_t;
|
||||
typedef intptr_t atomic_intptr_t;
|
||||
typedef intptr_t atomic_uintptr_t;
|
||||
typedef intptr_t atomic_size_t;
|
||||
typedef intptr_t atomic_ptrdiff_t;
|
||||
typedef intptr_t atomic_intmax_t;
|
||||
typedef intptr_t atomic_uintmax_t;
|
||||
|
||||
void avpriv_atomic_lock(void);
|
||||
void avpriv_atomic_unlock(void);
|
||||
|
||||
static inline void atomic_thread_fence(int order)
|
||||
{
|
||||
avpriv_atomic_lock();
|
||||
avpriv_atomic_unlock();
|
||||
}
|
||||
|
||||
static inline void atomic_store(intptr_t *object, intptr_t desired)
|
||||
{
|
||||
avpriv_atomic_lock();
|
||||
*object = desired;
|
||||
avpriv_atomic_unlock();
|
||||
}
|
||||
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
atomic_store(object, desired)
|
||||
|
||||
static inline intptr_t atomic_load(intptr_t *object)
|
||||
{
|
||||
intptr_t ret;
|
||||
avpriv_atomic_lock();
|
||||
ret = *object;
|
||||
avpriv_atomic_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define atomic_load_explicit(object, order) \
|
||||
atomic_load(object)
|
||||
|
||||
static inline intptr_t atomic_exchange(intptr_t *object, intptr_t desired)
|
||||
{
|
||||
intptr_t ret;
|
||||
avpriv_atomic_lock();
|
||||
ret = *object;
|
||||
*object = desired;
|
||||
avpriv_atomic_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define atomic_exchange_explicit(object, desired, order) \
|
||||
atomic_exchange(object, desired)
|
||||
|
||||
static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
|
||||
intptr_t desired)
|
||||
{
|
||||
int ret;
|
||||
avpriv_atomic_lock();
|
||||
if (*object == *expected) {
|
||||
ret = 1;
|
||||
*object = desired;
|
||||
} else {
|
||||
ret = 0;
|
||||
*expected = *object;
|
||||
}
|
||||
avpriv_atomic_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_weak(object, expected, desired)
|
||||
|
||||
#define FETCH_MODIFY(opname, op) \
|
||||
static inline intptr_t atomic_fetch_ ## opname(intptr_t *object, intptr_t operand) \
|
||||
{ \
|
||||
intptr_t ret; \
|
||||
avpriv_atomic_lock(); \
|
||||
ret = *object; \
|
||||
*object = *object op operand; \
|
||||
avpriv_atomic_unlock(); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
FETCH_MODIFY(add, +)
|
||||
FETCH_MODIFY(sub, -)
|
||||
FETCH_MODIFY(or, |)
|
||||
FETCH_MODIFY(xor, ^)
|
||||
FETCH_MODIFY(and, &)
|
||||
|
||||
#undef FETCH_MODIFY
|
||||
|
||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
||||
atomic_fetch_add(object, operand)
|
||||
|
||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
||||
atomic_fetch_sub(object, operand)
|
||||
|
||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
||||
atomic_fetch_or(object, operand)
|
||||
|
||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
||||
atomic_fetch_xor(object, operand)
|
||||
|
||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
||||
atomic_fetch_and(object, operand)
|
||||
|
||||
#define atomic_flag_test_and_set(object) \
|
||||
atomic_exchange(object, 1)
|
||||
|
||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
||||
atomic_flag_test_and_set(object)
|
||||
|
||||
#define atomic_flag_clear(object) \
|
||||
atomic_store(object, 0)
|
||||
|
||||
#define atomic_flag_clear_explicit(object, order) \
|
||||
atomic_flag_clear(object)
|
||||
|
||||
#endif /* COMPAT_ATOMICS_PTHREAD_STDATOMIC_H */
|
||||
@@ -1,186 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_ATOMICS_SUNCC_STDATOMIC_H
|
||||
#define COMPAT_ATOMICS_SUNCC_STDATOMIC_H
|
||||
|
||||
#include <atomic.h>
|
||||
#include <mbarrier.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define ATOMIC_FLAG_INIT 0
|
||||
|
||||
#define ATOMIC_VAR_INIT(value) (value)
|
||||
|
||||
#define atomic_init(obj, value) \
|
||||
do { \
|
||||
*(obj) = (value); \
|
||||
} while(0)
|
||||
|
||||
#define kill_dependency(y) ((void)0)
|
||||
|
||||
#define atomic_thread_fence(order) \
|
||||
__machine_rw_barrier();
|
||||
|
||||
#define atomic_signal_fence(order) \
|
||||
((void)0)
|
||||
|
||||
#define atomic_is_lock_free(obj) 0
|
||||
|
||||
typedef intptr_t atomic_flag;
|
||||
typedef intptr_t atomic_bool;
|
||||
typedef intptr_t atomic_char;
|
||||
typedef intptr_t atomic_schar;
|
||||
typedef intptr_t atomic_uchar;
|
||||
typedef intptr_t atomic_short;
|
||||
typedef intptr_t atomic_ushort;
|
||||
typedef intptr_t atomic_int;
|
||||
typedef intptr_t atomic_uint;
|
||||
typedef intptr_t atomic_long;
|
||||
typedef intptr_t atomic_ulong;
|
||||
typedef intptr_t atomic_llong;
|
||||
typedef intptr_t atomic_ullong;
|
||||
typedef intptr_t atomic_wchar_t;
|
||||
typedef intptr_t atomic_int_least8_t;
|
||||
typedef intptr_t atomic_uint_least8_t;
|
||||
typedef intptr_t atomic_int_least16_t;
|
||||
typedef intptr_t atomic_uint_least16_t;
|
||||
typedef intptr_t atomic_int_least32_t;
|
||||
typedef intptr_t atomic_uint_least32_t;
|
||||
typedef intptr_t atomic_int_least64_t;
|
||||
typedef intptr_t atomic_uint_least64_t;
|
||||
typedef intptr_t atomic_int_fast8_t;
|
||||
typedef intptr_t atomic_uint_fast8_t;
|
||||
typedef intptr_t atomic_int_fast16_t;
|
||||
typedef intptr_t atomic_uint_fast16_t;
|
||||
typedef intptr_t atomic_int_fast32_t;
|
||||
typedef intptr_t atomic_uint_fast32_t;
|
||||
typedef intptr_t atomic_int_fast64_t;
|
||||
typedef intptr_t atomic_uint_fast64_t;
|
||||
typedef intptr_t atomic_intptr_t;
|
||||
typedef intptr_t atomic_uintptr_t;
|
||||
typedef intptr_t atomic_size_t;
|
||||
typedef intptr_t atomic_ptrdiff_t;
|
||||
typedef intptr_t atomic_intmax_t;
|
||||
typedef intptr_t atomic_uintmax_t;
|
||||
|
||||
static inline void atomic_store(intptr_t *object, intptr_t desired)
|
||||
{
|
||||
*object = desired;
|
||||
__machine_rw_barrier();
|
||||
}
|
||||
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
atomic_store(object, desired)
|
||||
|
||||
static inline intptr_t atomic_load(intptr_t *object)
|
||||
{
|
||||
__machine_rw_barrier();
|
||||
return *object;
|
||||
}
|
||||
|
||||
#define atomic_load_explicit(object, order) \
|
||||
atomic_load(object)
|
||||
|
||||
#define atomic_exchange(object, desired) \
|
||||
atomic_swap_ptr(object, desired)
|
||||
|
||||
#define atomic_exchange_explicit(object, desired, order) \
|
||||
atomic_exchange(object, desired)
|
||||
|
||||
static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
|
||||
intptr_t desired)
|
||||
{
|
||||
intptr_t old = *expected;
|
||||
*expected = atomic_cas_ptr(object, old, desired);
|
||||
return *expected == old;
|
||||
}
|
||||
|
||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_weak(object, expected, desired)
|
||||
|
||||
static inline intptr_t atomic_fetch_add(intptr_t *object, intptr_t operand)
|
||||
{
|
||||
return atomic_add_ptr_nv(object, operand) - operand;
|
||||
}
|
||||
|
||||
#define atomic_fetch_sub(object, operand) \
|
||||
atomic_fetch_add(object, -(operand))
|
||||
|
||||
static inline intptr_t atomic_fetch_or(intptr_t *object, intptr_t operand)
|
||||
{
|
||||
intptr_t old;
|
||||
do {
|
||||
old = atomic_load(object);
|
||||
} while (!atomic_compare_exchange_strong(object, old, old | operand));
|
||||
return old;
|
||||
}
|
||||
|
||||
static inline intptr_t atomic_fetch_xor(intptr_t *object, intptr_t operand)
|
||||
{
|
||||
intptr_t old;
|
||||
do {
|
||||
old = atomic_load(object);
|
||||
} while (!atomic_compare_exchange_strong(object, old, old ^ operand));
|
||||
return old;
|
||||
}
|
||||
|
||||
static inline intptr_t atomic_fetch_and(intptr_t *object, intptr_t operand)
|
||||
{
|
||||
intptr_t old;
|
||||
do {
|
||||
old = atomic_load(object);
|
||||
} while (!atomic_compare_exchange_strong(object, old, old & operand));
|
||||
return old;
|
||||
}
|
||||
|
||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
||||
atomic_fetch_add(object, operand)
|
||||
|
||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
||||
atomic_fetch_sub(object, operand)
|
||||
|
||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
||||
atomic_fetch_or(object, operand)
|
||||
|
||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
||||
atomic_fetch_xor(object, operand)
|
||||
|
||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
||||
atomic_fetch_and(object, operand)
|
||||
|
||||
#define atomic_flag_test_and_set(object) \
|
||||
atomic_exchange(object, 1)
|
||||
|
||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
||||
atomic_flag_test_and_set(object)
|
||||
|
||||
#define atomic_flag_clear(object) \
|
||||
atomic_store(object, 0)
|
||||
|
||||
#define atomic_flag_clear_explicit(object, order) \
|
||||
atomic_flag_clear(object)
|
||||
|
||||
#endif /* COMPAT_ATOMICS_SUNCC_STDATOMIC_H */
|
||||
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_ATOMICS_WIN32_STDATOMIC_H
|
||||
#define COMPAT_ATOMICS_WIN32_STDATOMIC_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define ATOMIC_FLAG_INIT 0
|
||||
|
||||
#define ATOMIC_VAR_INIT(value) (value)
|
||||
|
||||
#define atomic_init(obj, value) \
|
||||
do { \
|
||||
*(obj) = (value); \
|
||||
} while(0)
|
||||
|
||||
#define kill_dependency(y) ((void)0)
|
||||
|
||||
#define atomic_thread_fence(order) \
|
||||
MemoryBarrier();
|
||||
|
||||
#define atomic_signal_fence(order) \
|
||||
((void)0)
|
||||
|
||||
#define atomic_is_lock_free(obj) 0
|
||||
|
||||
typedef intptr_t atomic_flag;
|
||||
typedef intptr_t atomic_bool;
|
||||
typedef intptr_t atomic_char;
|
||||
typedef intptr_t atomic_schar;
|
||||
typedef intptr_t atomic_uchar;
|
||||
typedef intptr_t atomic_short;
|
||||
typedef intptr_t atomic_ushort;
|
||||
typedef intptr_t atomic_int;
|
||||
typedef intptr_t atomic_uint;
|
||||
typedef intptr_t atomic_long;
|
||||
typedef intptr_t atomic_ulong;
|
||||
typedef intptr_t atomic_llong;
|
||||
typedef intptr_t atomic_ullong;
|
||||
typedef intptr_t atomic_wchar_t;
|
||||
typedef intptr_t atomic_int_least8_t;
|
||||
typedef intptr_t atomic_uint_least8_t;
|
||||
typedef intptr_t atomic_int_least16_t;
|
||||
typedef intptr_t atomic_uint_least16_t;
|
||||
typedef intptr_t atomic_int_least32_t;
|
||||
typedef intptr_t atomic_uint_least32_t;
|
||||
typedef intptr_t atomic_int_least64_t;
|
||||
typedef intptr_t atomic_uint_least64_t;
|
||||
typedef intptr_t atomic_int_fast8_t;
|
||||
typedef intptr_t atomic_uint_fast8_t;
|
||||
typedef intptr_t atomic_int_fast16_t;
|
||||
typedef intptr_t atomic_uint_fast16_t;
|
||||
typedef intptr_t atomic_int_fast32_t;
|
||||
typedef intptr_t atomic_uint_fast32_t;
|
||||
typedef intptr_t atomic_int_fast64_t;
|
||||
typedef intptr_t atomic_uint_fast64_t;
|
||||
typedef intptr_t atomic_intptr_t;
|
||||
typedef intptr_t atomic_uintptr_t;
|
||||
typedef intptr_t atomic_size_t;
|
||||
typedef intptr_t atomic_ptrdiff_t;
|
||||
typedef intptr_t atomic_intmax_t;
|
||||
typedef intptr_t atomic_uintmax_t;
|
||||
|
||||
#define atomic_store(object, desired) \
|
||||
do { \
|
||||
*(object) = (desired); \
|
||||
MemoryBarrier(); \
|
||||
} while (0)
|
||||
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
atomic_store(object, desired)
|
||||
|
||||
#define atomic_load(object) \
|
||||
(MemoryBarrier(), *(object))
|
||||
|
||||
#define atomic_load_explicit(object, order) \
|
||||
atomic_load(object)
|
||||
|
||||
#define atomic_exchange(object, desired) \
|
||||
InterlockedExchangePointer(object, desired);
|
||||
|
||||
#define atomic_exchange_explicit(object, desired, order) \
|
||||
atomic_exchange(object, desired)
|
||||
|
||||
static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
|
||||
intptr_t desired)
|
||||
{
|
||||
intptr_t old = *expected;
|
||||
*expected = InterlockedCompareExchangePointer(object, desired, old);
|
||||
return *expected == old;
|
||||
}
|
||||
|
||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_weak(object, expected, desired)
|
||||
|
||||
#ifdef _WIN64
|
||||
#define atomic_fetch_add(object, operand) \
|
||||
InterlockedExchangeAdd64(object, operand)
|
||||
|
||||
#define atomic_fetch_sub(object, operand) \
|
||||
InterlockedExchangeAdd64(object, -(operand))
|
||||
|
||||
#define atomic_fetch_or(object, operand) \
|
||||
InterlockedOr64(object, operand)
|
||||
|
||||
#define atomic_fetch_xor(object, operand) \
|
||||
InterlockedXor64(object, operand)
|
||||
|
||||
#define atomic_fetch_and(object, operand) \
|
||||
InterlockedAnd64(object, operand)
|
||||
#else
|
||||
#define atomic_fetch_add(object, operand) \
|
||||
InterlockedExchangeAdd(object, operand)
|
||||
|
||||
#define atomic_fetch_sub(object, operand) \
|
||||
InterlockedExchangeAdd(object, -(operand))
|
||||
|
||||
#define atomic_fetch_or(object, operand) \
|
||||
InterlockedOr(object, operand)
|
||||
|
||||
#define atomic_fetch_xor(object, operand) \
|
||||
InterlockedXor(object, operand)
|
||||
|
||||
#define atomic_fetch_and(object, operand) \
|
||||
InterlockedAnd(object, operand)
|
||||
#endif /* _WIN64 */
|
||||
|
||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
||||
atomic_fetch_add(object, operand)
|
||||
|
||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
||||
atomic_fetch_sub(object, operand)
|
||||
|
||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
||||
atomic_fetch_or(object, operand)
|
||||
|
||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
||||
atomic_fetch_xor(object, operand)
|
||||
|
||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
||||
atomic_fetch_and(object, operand)
|
||||
|
||||
#define atomic_flag_test_and_set(object) \
|
||||
atomic_exchange(object, 1)
|
||||
|
||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
||||
atomic_flag_test_and_set(object)
|
||||
|
||||
#define atomic_flag_clear(object) \
|
||||
atomic_store(object, 0)
|
||||
|
||||
#define atomic_flag_clear_explicit(object, order) \
|
||||
atomic_flag_clear(object)
|
||||
|
||||
#endif /* COMPAT_ATOMICS_WIN32_STDATOMIC_H */
|
||||
@@ -35,6 +35,10 @@
|
||||
#if !defined(__CUDA_VIDEO_H__)
|
||||
#define __CUDA_VIDEO_H__
|
||||
|
||||
#ifndef __cuda_cuda_h__
|
||||
#include <cuda.h>
|
||||
#endif // __cuda_cuda_h__
|
||||
|
||||
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
|
||||
#if (CUDA_VERSION >= 3020) && (!defined(CUDA_FORCE_API_VERSION) || (CUDA_FORCE_API_VERSION >= 3020))
|
||||
#define __CUVID_DEVPTR64
|
||||
@@ -45,12 +49,6 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
typedef unsigned int tcu_ulong;
|
||||
#else
|
||||
typedef unsigned long tcu_ulong;
|
||||
#endif
|
||||
|
||||
typedef void *CUvideodecoder;
|
||||
typedef struct _CUcontextlock_st *CUvideoctxlock;
|
||||
|
||||
@@ -89,8 +87,7 @@ typedef enum cudaVideoCodec_enum {
|
||||
* Video Surface Formats Enums
|
||||
*/
|
||||
typedef enum cudaVideoSurfaceFormat_enum {
|
||||
cudaVideoSurfaceFormat_NV12=0, /**< NV12 */
|
||||
cudaVideoSurfaceFormat_P016=1 /**< P016 */
|
||||
cudaVideoSurfaceFormat_NV12=0 /**< NV12 (currently the only supported output format) */
|
||||
} cudaVideoSurfaceFormat;
|
||||
|
||||
/*!
|
||||
@@ -131,14 +128,14 @@ typedef enum cudaVideoCreateFlags_enum {
|
||||
*/
|
||||
typedef struct _CUVIDDECODECREATEINFO
|
||||
{
|
||||
tcu_ulong ulWidth; /**< Coded Sequence Width */
|
||||
tcu_ulong ulHeight; /**< Coded Sequence Height */
|
||||
tcu_ulong ulNumDecodeSurfaces; /**< Maximum number of internal decode surfaces */
|
||||
unsigned long ulWidth; /**< Coded Sequence Width */
|
||||
unsigned long ulHeight; /**< Coded Sequence Height */
|
||||
unsigned long ulNumDecodeSurfaces; /**< Maximum number of internal decode surfaces */
|
||||
cudaVideoCodec CodecType; /**< cudaVideoCodec_XXX */
|
||||
cudaVideoChromaFormat ChromaFormat; /**< cudaVideoChromaFormat_XXX (only 4:2:0 is currently supported) */
|
||||
tcu_ulong ulCreationFlags; /**< Decoder creation flags (cudaVideoCreateFlags_XXX) */
|
||||
tcu_ulong bitDepthMinus8;
|
||||
tcu_ulong Reserved1[4]; /**< Reserved for future use - set to zero */
|
||||
unsigned long ulCreationFlags; /**< Decoder creation flags (cudaVideoCreateFlags_XXX) */
|
||||
unsigned long bitDepthMinus8;
|
||||
unsigned long Reserved1[4]; /**< Reserved for future use - set to zero */
|
||||
/**
|
||||
* area of the frame that should be displayed
|
||||
*/
|
||||
@@ -151,9 +148,9 @@ typedef struct _CUVIDDECODECREATEINFO
|
||||
|
||||
cudaVideoSurfaceFormat OutputFormat; /**< cudaVideoSurfaceFormat_XXX */
|
||||
cudaVideoDeinterlaceMode DeinterlaceMode; /**< cudaVideoDeinterlaceMode_XXX */
|
||||
tcu_ulong ulTargetWidth; /**< Post-processed Output Width (Should be aligned to 2) */
|
||||
tcu_ulong ulTargetHeight; /**< Post-processed Output Height (Should be aligbed to 2) */
|
||||
tcu_ulong ulNumOutputSurfaces; /**< Maximum number of output surfaces simultaneously mapped */
|
||||
unsigned long ulTargetWidth; /**< Post-processed Output Width (Should be aligned to 2) */
|
||||
unsigned long ulTargetHeight; /**< Post-processed Output Height (Should be aligbed to 2) */
|
||||
unsigned long ulNumOutputSurfaces; /**< Maximum number of output surfaces simultaneously mapped */
|
||||
CUvideoctxlock vidLock; /**< If non-NULL, context lock used for synchronizing ownership of the cuda context */
|
||||
/**
|
||||
* target rectangle in the output frame (for aspect ratio conversion)
|
||||
@@ -165,7 +162,7 @@ typedef struct _CUVIDDECODECREATEINFO
|
||||
short right;
|
||||
short bottom;
|
||||
} target_rect;
|
||||
tcu_ulong Reserved2[5]; /**< Reserved for future use - set to zero */
|
||||
unsigned long Reserved2[5]; /**< Reserved for future use - set to zero */
|
||||
} CUVIDDECODECREATEINFO;
|
||||
|
||||
/*!
|
||||
@@ -297,7 +294,7 @@ typedef struct _CUVIDH264PICPARAMS
|
||||
{
|
||||
CUVIDH264MVCEXT mvcext;
|
||||
CUVIDH264SVCEXT svcext;
|
||||
} svcmvc;
|
||||
};
|
||||
} CUVIDH264PICPARAMS;
|
||||
|
||||
|
||||
@@ -555,7 +552,7 @@ typedef struct _CUVIDVP8PICPARAMS
|
||||
unsigned char Reserved2Bits : 2;
|
||||
};
|
||||
unsigned char wFrameTagFlags;
|
||||
} tagflags;
|
||||
};
|
||||
unsigned char Reserved1[4];
|
||||
unsigned int Reserved2[3];
|
||||
} CUVIDVP8PICPARAMS;
|
||||
@@ -718,19 +715,19 @@ typedef struct _CUVIDPROCPARAMS
|
||||
* \fn CUresult CUDAAPI cuvidCreateDecoder(CUvideodecoder *phDecoder, CUVIDDECODECREATEINFO *pdci)
|
||||
* Create the decoder object
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidCreateDecoder(CUvideodecoder *phDecoder, CUVIDDECODECREATEINFO *pdci);
|
||||
CUresult CUDAAPI cuvidCreateDecoder(CUvideodecoder *phDecoder, CUVIDDECODECREATEINFO *pdci);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidDestroyDecoder(CUvideodecoder hDecoder)
|
||||
* Destroy the decoder object
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidDestroyDecoder(CUvideodecoder hDecoder);
|
||||
CUresult CUDAAPI cuvidDestroyDecoder(CUvideodecoder hDecoder);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidDecodePicture(CUvideodecoder hDecoder, CUVIDPICPARAMS *pPicParams)
|
||||
* Decode a single picture (field or frame)
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidDecodePicture(CUvideodecoder hDecoder, CUVIDPICPARAMS *pPicParams);
|
||||
CUresult CUDAAPI cuvidDecodePicture(CUvideodecoder hDecoder, CUVIDPICPARAMS *pPicParams);
|
||||
|
||||
|
||||
#if !defined(__CUVID_DEVPTR64) || defined(__CUVID_INTERNAL)
|
||||
@@ -738,15 +735,15 @@ typedef CUresult CUDAAPI tcuvidDecodePicture(CUvideodecoder hDecoder, CUVIDPICPA
|
||||
* \fn CUresult CUDAAPI cuvidMapVideoFrame(CUvideodecoder hDecoder, int nPicIdx, unsigned int *pDevPtr, unsigned int *pPitch, CUVIDPROCPARAMS *pVPP);
|
||||
* Post-process and map a video frame for use in cuda
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidMapVideoFrame(CUvideodecoder hDecoder, int nPicIdx,
|
||||
unsigned int *pDevPtr, unsigned int *pPitch,
|
||||
CUVIDPROCPARAMS *pVPP);
|
||||
CUresult CUDAAPI cuvidMapVideoFrame(CUvideodecoder hDecoder, int nPicIdx,
|
||||
unsigned int *pDevPtr, unsigned int *pPitch,
|
||||
CUVIDPROCPARAMS *pVPP);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidUnmapVideoFrame(CUvideodecoder hDecoder, unsigned int DevPtr)
|
||||
* Unmap a previously mapped video frame
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidUnmapVideoFrame(CUvideodecoder hDecoder, unsigned int DevPtr);
|
||||
CUresult CUDAAPI cuvidUnmapVideoFrame(CUvideodecoder hDecoder, unsigned int DevPtr);
|
||||
#endif
|
||||
|
||||
#if defined(WIN64) || defined(_WIN64) || defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
|
||||
@@ -754,22 +751,23 @@ typedef CUresult CUDAAPI tcuvidUnmapVideoFrame(CUvideodecoder hDecoder, unsigned
|
||||
* \fn CUresult CUDAAPI cuvidMapVideoFrame64(CUvideodecoder hDecoder, int nPicIdx, unsigned long long *pDevPtr, unsigned int *pPitch, CUVIDPROCPARAMS *pVPP);
|
||||
* map a video frame
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidMapVideoFrame64(CUvideodecoder hDecoder, int nPicIdx, unsigned long long *pDevPtr,
|
||||
unsigned int *pPitch, CUVIDPROCPARAMS *pVPP);
|
||||
CUresult CUDAAPI cuvidMapVideoFrame64(CUvideodecoder hDecoder, int nPicIdx, unsigned long long *pDevPtr,
|
||||
unsigned int *pPitch, CUVIDPROCPARAMS *pVPP);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidUnmapVideoFrame64(CUvideodecoder hDecoder, unsigned long long DevPtr);
|
||||
* Unmap a previously mapped video frame
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidUnmapVideoFrame64(CUvideodecoder hDecoder, unsigned long long DevPtr);
|
||||
CUresult CUDAAPI cuvidUnmapVideoFrame64(CUvideodecoder hDecoder, unsigned long long DevPtr);
|
||||
|
||||
#if defined(__CUVID_DEVPTR64) && !defined(__CUVID_INTERNAL)
|
||||
#define tcuvidMapVideoFrame tcuvidMapVideoFrame64
|
||||
#define tcuvidUnmapVideoFrame tcuvidUnmapVideoFrame64
|
||||
#define cuvidMapVideoFrame cuvidMapVideoFrame64
|
||||
#define cuvidUnmapVideoFrame cuvidUnmapVideoFrame64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Context-locking: to facilitate multi-threaded implementations, the following 4 functions
|
||||
@@ -789,27 +787,41 @@ typedef CUresult CUDAAPI tcuvidUnmapVideoFrame64(CUvideodecoder hDecoder, unsign
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidCtxLockCreate(CUvideoctxlock *pLock, CUcontext ctx)
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidCtxLockCreate(CUvideoctxlock *pLock, CUcontext ctx);
|
||||
CUresult CUDAAPI cuvidCtxLockCreate(CUvideoctxlock *pLock, CUcontext ctx);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidCtxLockDestroy(CUvideoctxlock lck)
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidCtxLockDestroy(CUvideoctxlock lck);
|
||||
CUresult CUDAAPI cuvidCtxLockDestroy(CUvideoctxlock lck);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidCtxLock(CUvideoctxlock lck, unsigned int reserved_flags)
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidCtxLock(CUvideoctxlock lck, unsigned int reserved_flags);
|
||||
CUresult CUDAAPI cuvidCtxLock(CUvideoctxlock lck, unsigned int reserved_flags);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidCtxUnlock(CUvideoctxlock lck, unsigned int reserved_flags)
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidCtxUnlock(CUvideoctxlock lck, unsigned int reserved_flags);
|
||||
CUresult CUDAAPI cuvidCtxUnlock(CUvideoctxlock lck, unsigned int reserved_flags);
|
||||
|
||||
/** @} */ /* End VIDEO_DECODER */
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
// Auto-lock helper for C++ applications
|
||||
class CCtxAutoLock
|
||||
{
|
||||
private:
|
||||
CUvideoctxlock m_ctx;
|
||||
public:
|
||||
CCtxAutoLock(CUvideoctxlock ctx);
|
||||
~CCtxAutoLock();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif // __CUDA_VIDEO_H__
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* This copyright notice applies to this header file only:
|
||||
*
|
||||
* Copyright (c) 2016
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the software, and to permit persons to whom the
|
||||
* software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(AV_COMPAT_DYNLINK_CUDA_H) && !defined(CUDA_VERSION)
|
||||
#define AV_COMPAT_DYNLINK_CUDA_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define CUDA_VERSION 7050
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define CUDAAPI __stdcall
|
||||
#else
|
||||
#define CUDAAPI
|
||||
#endif
|
||||
|
||||
#define CU_CTX_SCHED_BLOCKING_SYNC 4
|
||||
|
||||
typedef int CUdevice;
|
||||
typedef void* CUarray;
|
||||
typedef void* CUcontext;
|
||||
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
|
||||
typedef unsigned long long CUdeviceptr;
|
||||
#else
|
||||
typedef unsigned int CUdeviceptr;
|
||||
#endif
|
||||
|
||||
typedef enum cudaError_enum {
|
||||
CUDA_SUCCESS = 0
|
||||
} CUresult;
|
||||
|
||||
typedef enum CUmemorytype_enum {
|
||||
CU_MEMORYTYPE_HOST = 1,
|
||||
CU_MEMORYTYPE_DEVICE = 2
|
||||
} CUmemorytype;
|
||||
|
||||
typedef struct CUDA_MEMCPY2D_st {
|
||||
size_t srcXInBytes;
|
||||
size_t srcY;
|
||||
CUmemorytype srcMemoryType;
|
||||
const void *srcHost;
|
||||
CUdeviceptr srcDevice;
|
||||
CUarray srcArray;
|
||||
size_t srcPitch;
|
||||
|
||||
size_t dstXInBytes;
|
||||
size_t dstY;
|
||||
CUmemorytype dstMemoryType;
|
||||
void *dstHost;
|
||||
CUdeviceptr dstDevice;
|
||||
CUarray dstArray;
|
||||
size_t dstPitch;
|
||||
|
||||
size_t WidthInBytes;
|
||||
size_t Height;
|
||||
} CUDA_MEMCPY2D;
|
||||
|
||||
typedef CUresult CUDAAPI tcuInit(unsigned int Flags);
|
||||
typedef CUresult CUDAAPI tcuDeviceGetCount(int *count);
|
||||
typedef CUresult CUDAAPI tcuDeviceGet(CUdevice *device, int ordinal);
|
||||
typedef CUresult CUDAAPI tcuDeviceGetName(char *name, int len, CUdevice dev);
|
||||
typedef CUresult CUDAAPI tcuDeviceComputeCapability(int *major, int *minor, CUdevice dev);
|
||||
typedef CUresult CUDAAPI tcuCtxCreate_v2(CUcontext *pctx, unsigned int flags, CUdevice dev);
|
||||
typedef CUresult CUDAAPI tcuCtxPushCurrent_v2(CUcontext *pctx);
|
||||
typedef CUresult CUDAAPI tcuCtxPopCurrent_v2(CUcontext *pctx);
|
||||
typedef CUresult CUDAAPI tcuCtxDestroy_v2(CUcontext ctx);
|
||||
typedef CUresult CUDAAPI tcuMemAlloc_v2(CUdeviceptr *dptr, size_t bytesize);
|
||||
typedef CUresult CUDAAPI tcuMemFree_v2(CUdeviceptr dptr);
|
||||
typedef CUresult CUDAAPI tcuMemcpy2D_v2(const CUDA_MEMCPY2D *pcopy);
|
||||
typedef CUresult CUDAAPI tcuGetErrorName(CUresult error, const char** pstr);
|
||||
typedef CUresult CUDAAPI tcuGetErrorString(CUresult error, const char** pstr);
|
||||
|
||||
#endif
|
||||
@@ -1,254 +0,0 @@
|
||||
/*
|
||||
* This copyright notice applies to this header file only:
|
||||
*
|
||||
* Copyright (c) 2016
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the software, and to permit persons to whom the
|
||||
* software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef AV_COMPAT_CUDA_DYNLINK_LOADER_H
|
||||
#define AV_COMPAT_CUDA_DYNLINK_LOADER_H
|
||||
|
||||
#include "compat/cuda/dynlink_cuda.h"
|
||||
#include "compat/cuda/dynlink_nvcuvid.h"
|
||||
#include "compat/nvenc/nvEncodeAPI.h"
|
||||
#include "compat/w32dlfcn.h"
|
||||
|
||||
#include "libavutil/log.h"
|
||||
#include "libavutil/error.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define LIB_HANDLE HMODULE
|
||||
#else
|
||||
# define LIB_HANDLE void*
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# define CUDA_LIBNAME "nvcuda.dll"
|
||||
# define NVCUVID_LIBNAME "nvcuvid.dll"
|
||||
# if ARCH_X86_64
|
||||
# define NVENC_LIBNAME "nvEncodeAPI64.dll"
|
||||
# else
|
||||
# define NVENC_LIBNAME "nvEncodeAPI.dll"
|
||||
# endif
|
||||
#else
|
||||
# define CUDA_LIBNAME "libcuda.so.1"
|
||||
# define NVCUVID_LIBNAME "libnvcuvid.so.1"
|
||||
# define NVENC_LIBNAME "libnvidia-encode.so.1"
|
||||
#endif
|
||||
|
||||
#define LOAD_LIBRARY(l, path) \
|
||||
do { \
|
||||
if (!((l) = dlopen(path, RTLD_LAZY))) { \
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot load %s\n", path); \
|
||||
ret = AVERROR_UNKNOWN; \
|
||||
goto error; \
|
||||
} \
|
||||
av_log(NULL, AV_LOG_TRACE, "Loaded lib: %s\n", path); \
|
||||
} while (0)
|
||||
|
||||
#define LOAD_SYMBOL(fun, symbol) \
|
||||
do { \
|
||||
if (!((f->fun) = dlsym(f->lib, symbol))) { \
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot load %s\n", symbol); \
|
||||
ret = AVERROR_UNKNOWN; \
|
||||
goto error; \
|
||||
} \
|
||||
av_log(NULL, AV_LOG_TRACE, "Loaded sym: %s\n", symbol); \
|
||||
} while (0)
|
||||
|
||||
#define GENERIC_LOAD_FUNC_PREAMBLE(T, n, N) \
|
||||
T *f; \
|
||||
int ret; \
|
||||
\
|
||||
n##_free_functions(functions); \
|
||||
\
|
||||
f = *functions = av_mallocz(sizeof(*f)); \
|
||||
if (!f) \
|
||||
return AVERROR(ENOMEM); \
|
||||
\
|
||||
LOAD_LIBRARY(f->lib, N);
|
||||
|
||||
#define GENERIC_LOAD_FUNC_FINALE(n) \
|
||||
return 0; \
|
||||
error: \
|
||||
n##_free_functions(functions); \
|
||||
return ret;
|
||||
|
||||
#define GENERIC_FREE_FUNC() \
|
||||
if (!functions) \
|
||||
return; \
|
||||
if (*functions && (*functions)->lib) \
|
||||
dlclose((*functions)->lib); \
|
||||
av_freep(functions);
|
||||
|
||||
#ifdef AV_COMPAT_DYNLINK_CUDA_H
|
||||
typedef struct CudaFunctions {
|
||||
tcuInit *cuInit;
|
||||
tcuDeviceGetCount *cuDeviceGetCount;
|
||||
tcuDeviceGet *cuDeviceGet;
|
||||
tcuDeviceGetName *cuDeviceGetName;
|
||||
tcuDeviceComputeCapability *cuDeviceComputeCapability;
|
||||
tcuCtxCreate_v2 *cuCtxCreate;
|
||||
tcuCtxPushCurrent_v2 *cuCtxPushCurrent;
|
||||
tcuCtxPopCurrent_v2 *cuCtxPopCurrent;
|
||||
tcuCtxDestroy_v2 *cuCtxDestroy;
|
||||
tcuMemAlloc_v2 *cuMemAlloc;
|
||||
tcuMemFree_v2 *cuMemFree;
|
||||
tcuMemcpy2D_v2 *cuMemcpy2D;
|
||||
tcuGetErrorName *cuGetErrorName;
|
||||
tcuGetErrorString *cuGetErrorString;
|
||||
|
||||
LIB_HANDLE lib;
|
||||
} CudaFunctions;
|
||||
#else
|
||||
typedef struct CudaFunctions CudaFunctions;
|
||||
#endif
|
||||
|
||||
typedef struct CuvidFunctions {
|
||||
tcuvidCreateDecoder *cuvidCreateDecoder;
|
||||
tcuvidDestroyDecoder *cuvidDestroyDecoder;
|
||||
tcuvidDecodePicture *cuvidDecodePicture;
|
||||
tcuvidMapVideoFrame *cuvidMapVideoFrame;
|
||||
tcuvidUnmapVideoFrame *cuvidUnmapVideoFrame;
|
||||
tcuvidCtxLockCreate *cuvidCtxLockCreate;
|
||||
tcuvidCtxLockDestroy *cuvidCtxLockDestroy;
|
||||
tcuvidCtxLock *cuvidCtxLock;
|
||||
tcuvidCtxUnlock *cuvidCtxUnlock;
|
||||
|
||||
tcuvidCreateVideoSource *cuvidCreateVideoSource;
|
||||
tcuvidCreateVideoSourceW *cuvidCreateVideoSourceW;
|
||||
tcuvidDestroyVideoSource *cuvidDestroyVideoSource;
|
||||
tcuvidSetVideoSourceState *cuvidSetVideoSourceState;
|
||||
tcuvidGetVideoSourceState *cuvidGetVideoSourceState;
|
||||
tcuvidGetSourceVideoFormat *cuvidGetSourceVideoFormat;
|
||||
tcuvidGetSourceAudioFormat *cuvidGetSourceAudioFormat;
|
||||
tcuvidCreateVideoParser *cuvidCreateVideoParser;
|
||||
tcuvidParseVideoData *cuvidParseVideoData;
|
||||
tcuvidDestroyVideoParser *cuvidDestroyVideoParser;
|
||||
|
||||
LIB_HANDLE lib;
|
||||
} CuvidFunctions;
|
||||
|
||||
typedef struct NvencFunctions {
|
||||
NVENCSTATUS (NVENCAPI *NvEncodeAPICreateInstance)(NV_ENCODE_API_FUNCTION_LIST *functionList);
|
||||
NVENCSTATUS (NVENCAPI *NvEncodeAPIGetMaxSupportedVersion)(uint32_t* version);
|
||||
|
||||
LIB_HANDLE lib;
|
||||
} NvencFunctions;
|
||||
|
||||
#ifdef AV_COMPAT_DYNLINK_CUDA_H
|
||||
static inline void cuda_free_functions(CudaFunctions **functions)
|
||||
{
|
||||
GENERIC_FREE_FUNC();
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void cuvid_free_functions(CuvidFunctions **functions)
|
||||
{
|
||||
GENERIC_FREE_FUNC();
|
||||
}
|
||||
|
||||
static inline void nvenc_free_functions(NvencFunctions **functions)
|
||||
{
|
||||
GENERIC_FREE_FUNC();
|
||||
}
|
||||
|
||||
#ifdef AV_COMPAT_DYNLINK_CUDA_H
|
||||
static inline int cuda_load_functions(CudaFunctions **functions)
|
||||
{
|
||||
GENERIC_LOAD_FUNC_PREAMBLE(CudaFunctions, cuda, CUDA_LIBNAME);
|
||||
|
||||
LOAD_SYMBOL(cuInit, "cuInit");
|
||||
LOAD_SYMBOL(cuDeviceGetCount, "cuDeviceGetCount");
|
||||
LOAD_SYMBOL(cuDeviceGet, "cuDeviceGet");
|
||||
LOAD_SYMBOL(cuDeviceGetName, "cuDeviceGetName");
|
||||
LOAD_SYMBOL(cuDeviceComputeCapability, "cuDeviceComputeCapability");
|
||||
LOAD_SYMBOL(cuCtxCreate, "cuCtxCreate_v2");
|
||||
LOAD_SYMBOL(cuCtxPushCurrent, "cuCtxPushCurrent_v2");
|
||||
LOAD_SYMBOL(cuCtxPopCurrent, "cuCtxPopCurrent_v2");
|
||||
LOAD_SYMBOL(cuCtxDestroy, "cuCtxDestroy_v2");
|
||||
LOAD_SYMBOL(cuMemAlloc, "cuMemAlloc_v2");
|
||||
LOAD_SYMBOL(cuMemFree, "cuMemFree_v2");
|
||||
LOAD_SYMBOL(cuMemcpy2D, "cuMemcpy2D_v2");
|
||||
LOAD_SYMBOL(cuGetErrorName, "cuGetErrorName");
|
||||
LOAD_SYMBOL(cuGetErrorString, "cuGetErrorString");
|
||||
|
||||
GENERIC_LOAD_FUNC_FINALE(cuda);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int cuvid_load_functions(CuvidFunctions **functions)
|
||||
{
|
||||
GENERIC_LOAD_FUNC_PREAMBLE(CuvidFunctions, cuvid, NVCUVID_LIBNAME);
|
||||
|
||||
LOAD_SYMBOL(cuvidCreateDecoder, "cuvidCreateDecoder");
|
||||
LOAD_SYMBOL(cuvidDestroyDecoder, "cuvidDestroyDecoder");
|
||||
LOAD_SYMBOL(cuvidDecodePicture, "cuvidDecodePicture");
|
||||
#ifdef __CUVID_DEVPTR64
|
||||
LOAD_SYMBOL(cuvidMapVideoFrame, "cuvidMapVideoFrame64");
|
||||
LOAD_SYMBOL(cuvidUnmapVideoFrame, "cuvidUnmapVideoFrame64");
|
||||
#else
|
||||
LOAD_SYMBOL(cuvidMapVideoFrame, "cuvidMapVideoFrame");
|
||||
LOAD_SYMBOL(cuvidUnmapVideoFrame, "cuvidUnmapVideoFrame");
|
||||
#endif
|
||||
LOAD_SYMBOL(cuvidCtxLockCreate, "cuvidCtxLockCreate");
|
||||
LOAD_SYMBOL(cuvidCtxLockDestroy, "cuvidCtxLockDestroy");
|
||||
LOAD_SYMBOL(cuvidCtxLock, "cuvidCtxLock");
|
||||
LOAD_SYMBOL(cuvidCtxUnlock, "cuvidCtxUnlock");
|
||||
|
||||
LOAD_SYMBOL(cuvidCreateVideoSource, "cuvidCreateVideoSource");
|
||||
LOAD_SYMBOL(cuvidCreateVideoSourceW, "cuvidCreateVideoSourceW");
|
||||
LOAD_SYMBOL(cuvidDestroyVideoSource, "cuvidDestroyVideoSource");
|
||||
LOAD_SYMBOL(cuvidSetVideoSourceState, "cuvidSetVideoSourceState");
|
||||
LOAD_SYMBOL(cuvidGetVideoSourceState, "cuvidGetVideoSourceState");
|
||||
LOAD_SYMBOL(cuvidGetSourceVideoFormat, "cuvidGetSourceVideoFormat");
|
||||
LOAD_SYMBOL(cuvidGetSourceAudioFormat, "cuvidGetSourceAudioFormat");
|
||||
LOAD_SYMBOL(cuvidCreateVideoParser, "cuvidCreateVideoParser");
|
||||
LOAD_SYMBOL(cuvidParseVideoData, "cuvidParseVideoData");
|
||||
LOAD_SYMBOL(cuvidDestroyVideoParser, "cuvidDestroyVideoParser");
|
||||
|
||||
GENERIC_LOAD_FUNC_FINALE(cuvid);
|
||||
}
|
||||
|
||||
static inline int nvenc_load_functions(NvencFunctions **functions)
|
||||
{
|
||||
GENERIC_LOAD_FUNC_PREAMBLE(NvencFunctions, nvenc, NVENC_LIBNAME);
|
||||
|
||||
LOAD_SYMBOL(NvEncodeAPICreateInstance, "NvEncodeAPICreateInstance");
|
||||
LOAD_SYMBOL(NvEncodeAPIGetMaxSupportedVersion, "NvEncodeAPIGetMaxSupportedVersion");
|
||||
|
||||
GENERIC_LOAD_FUNC_FINALE(nvenc);
|
||||
}
|
||||
|
||||
#undef GENERIC_LOAD_FUNC_PREAMBLE
|
||||
#undef LOAD_LIBRARY
|
||||
#undef LOAD_SYMBOL
|
||||
#undef GENERIC_LOAD_FUNC_FINALE
|
||||
#undef GENERIC_FREE_FUNC
|
||||
#undef CUDA_LIBNAME
|
||||
#undef NVCUVID_LIBNAME
|
||||
#undef NVENC_LIBNAME
|
||||
#undef LIB_HANDLE
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,12 +35,17 @@
|
||||
#if !defined(__NVCUVID_H__)
|
||||
#define __NVCUVID_H__
|
||||
|
||||
#include "compat/cuda/dynlink_cuviddec.h"
|
||||
#include "compat/cuda/cuviddec.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*********************************
|
||||
** Initialization
|
||||
*********************************/
|
||||
CUresult CUDAAPI cuvidInit(unsigned int Flags);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// High-level helper APIs for video sources
|
||||
@@ -173,8 +178,8 @@ typedef enum {
|
||||
*/
|
||||
typedef struct _CUVIDSOURCEDATAPACKET
|
||||
{
|
||||
tcu_ulong flags; /**< Combination of CUVID_PKT_XXX flags */
|
||||
tcu_ulong payload_size; /**< number of bytes in the payload (may be zero if EOS flag is set) */
|
||||
unsigned long flags; /**< Combination of CUVID_PKT_XXX flags */
|
||||
unsigned long payload_size; /**< number of bytes in the payload (may be zero if EOS flag is set) */
|
||||
const unsigned char *payload; /**< Pointer to packet payload data (may be NULL if EOS flag is set) */
|
||||
CUvideotimestamp timestamp; /**< Presentation timestamp (10MHz clock), only valid if CUVID_PKT_TIMESTAMP flag is set */
|
||||
} CUVIDSOURCEDATAPACKET;
|
||||
@@ -209,43 +214,43 @@ typedef enum {
|
||||
* \fn CUresult CUDAAPI cuvidCreateVideoSource(CUvideosource *pObj, const char *pszFileName, CUVIDSOURCEPARAMS *pParams)
|
||||
* Create Video Source
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidCreateVideoSource(CUvideosource *pObj, const char *pszFileName, CUVIDSOURCEPARAMS *pParams);
|
||||
CUresult CUDAAPI cuvidCreateVideoSource(CUvideosource *pObj, const char *pszFileName, CUVIDSOURCEPARAMS *pParams);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidCreateVideoSourceW(CUvideosource *pObj, const wchar_t *pwszFileName, CUVIDSOURCEPARAMS *pParams)
|
||||
* Create Video Source
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidCreateVideoSourceW(CUvideosource *pObj, const wchar_t *pwszFileName, CUVIDSOURCEPARAMS *pParams);
|
||||
CUresult CUDAAPI cuvidCreateVideoSourceW(CUvideosource *pObj, const wchar_t *pwszFileName, CUVIDSOURCEPARAMS *pParams);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidDestroyVideoSource(CUvideosource obj)
|
||||
* Destroy Video Source
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidDestroyVideoSource(CUvideosource obj);
|
||||
CUresult CUDAAPI cuvidDestroyVideoSource(CUvideosource obj);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidSetVideoSourceState(CUvideosource obj, cudaVideoState state)
|
||||
* Set Video Source state
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidSetVideoSourceState(CUvideosource obj, cudaVideoState state);
|
||||
CUresult CUDAAPI cuvidSetVideoSourceState(CUvideosource obj, cudaVideoState state);
|
||||
|
||||
/**
|
||||
* \fn cudaVideoState CUDAAPI cuvidGetVideoSourceState(CUvideosource obj)
|
||||
* Get Video Source state
|
||||
*/
|
||||
typedef cudaVideoState CUDAAPI tcuvidGetVideoSourceState(CUvideosource obj);
|
||||
cudaVideoState CUDAAPI cuvidGetVideoSourceState(CUvideosource obj);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidGetSourceVideoFormat(CUvideosource obj, CUVIDEOFORMAT *pvidfmt, unsigned int flags)
|
||||
* Get Video Source Format
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidGetSourceVideoFormat(CUvideosource obj, CUVIDEOFORMAT *pvidfmt, unsigned int flags);
|
||||
CUresult CUDAAPI cuvidGetSourceVideoFormat(CUvideosource obj, CUVIDEOFORMAT *pvidfmt, unsigned int flags);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidGetSourceAudioFormat(CUvideosource obj, CUAUDIOFORMAT *paudfmt, unsigned int flags)
|
||||
* Set Video Source state
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidGetSourceAudioFormat(CUvideosource obj, CUAUDIOFORMAT *paudfmt, unsigned int flags);
|
||||
CUresult CUDAAPI cuvidGetSourceAudioFormat(CUvideosource obj, CUAUDIOFORMAT *paudfmt, unsigned int flags);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -292,17 +297,17 @@ typedef struct _CUVIDPARSERPARAMS
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidCreateVideoParser(CUvideoparser *pObj, CUVIDPARSERPARAMS *pParams)
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidCreateVideoParser(CUvideoparser *pObj, CUVIDPARSERPARAMS *pParams);
|
||||
CUresult CUDAAPI cuvidCreateVideoParser(CUvideoparser *pObj, CUVIDPARSERPARAMS *pParams);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidParseVideoData(CUvideoparser obj, CUVIDSOURCEDATAPACKET *pPacket)
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidParseVideoData(CUvideoparser obj, CUVIDSOURCEDATAPACKET *pPacket);
|
||||
CUresult CUDAAPI cuvidParseVideoData(CUvideoparser obj, CUVIDSOURCEDATAPACKET *pPacket);
|
||||
|
||||
/**
|
||||
* \fn CUresult CUDAAPI cuvidDestroyVideoParser(CUvideoparser obj)
|
||||
*/
|
||||
typedef CUresult CUDAAPI tcuvidDestroyVideoParser(CUvideoparser obj);
|
||||
CUresult CUDAAPI cuvidDestroyVideoParser(CUvideoparser obj);
|
||||
|
||||
/** @} */ /* END VIDEO_PARSER */
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_W32DLFCN_H
|
||||
#define COMPAT_W32DLFCN_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#if _WIN32_WINNT < 0x0602
|
||||
#include "libavutil/wchar_filename.h"
|
||||
#endif
|
||||
/**
|
||||
* Safe function used to open dynamic libs. This attempts to improve program security
|
||||
* by removing the current directory from the dll search path. Only dll's found in the
|
||||
* executable or system directory are allowed to be loaded.
|
||||
* @param name The dynamic lib name.
|
||||
* @return A handle to the opened lib.
|
||||
*/
|
||||
static inline HMODULE win32_dlopen(const char *name)
|
||||
{
|
||||
#if _WIN32_WINNT < 0x0602
|
||||
// Need to check if KB2533623 is available
|
||||
if (!GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetDefaultDllDirectories")) {
|
||||
HMODULE module = NULL;
|
||||
wchar_t *path = NULL, *name_w = NULL;
|
||||
DWORD pathlen;
|
||||
if (utf8towchar(name, &name_w))
|
||||
goto exit;
|
||||
path = (wchar_t *)av_mallocz_array(MAX_PATH, sizeof(wchar_t));
|
||||
// Try local directory first
|
||||
pathlen = GetModuleFileNameW(NULL, path, MAX_PATH);
|
||||
pathlen = wcsrchr(path, '\\') - path;
|
||||
if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH)
|
||||
goto exit;
|
||||
path[pathlen] = '\\';
|
||||
wcscpy(path + pathlen + 1, name_w);
|
||||
module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
if (module == NULL) {
|
||||
// Next try System32 directory
|
||||
pathlen = GetSystemDirectoryW(path, MAX_PATH);
|
||||
if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH)
|
||||
goto exit;
|
||||
path[pathlen] = '\\';
|
||||
wcscpy(path + pathlen + 1, name_w);
|
||||
module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
}
|
||||
exit:
|
||||
av_free(path);
|
||||
av_free(name_w);
|
||||
return module;
|
||||
}
|
||||
#endif
|
||||
#ifndef LOAD_LIBRARY_SEARCH_APPLICATION_DIR
|
||||
# define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200
|
||||
#endif
|
||||
#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32
|
||||
# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
|
||||
#endif
|
||||
return LoadLibraryExA(name, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
}
|
||||
#define dlopen(name, flags) win32_dlopen(name)
|
||||
#define dlclose FreeLibrary
|
||||
#define dlsym GetProcAddress
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#endif /* COMPAT_W32DLFCN_H */
|
||||
111
doc/APIchanges
111
doc/APIchanges
@@ -15,117 +15,6 @@ libavutil: 2015-08-28
|
||||
|
||||
API changes, most recent first:
|
||||
|
||||
2017-03-31 - xxxxxxx - lavu 55.57.100 - spherical.h
|
||||
Add av_spherical_projection_name().
|
||||
Add av_spherical_from_name().
|
||||
|
||||
2017-03-30 - xxxxxxx - lavu 55.53.100 / 55.27.0 - hwcontext.h
|
||||
Add av_hwframe_map() and associated AV_HWFRAME_MAP_* flags.
|
||||
Add av_hwframe_ctx_create_derived().
|
||||
|
||||
2017-03-29 - bfdcdd6d82 - lavu 55.52.100 - avutil.h
|
||||
add av_fourcc_make_string() function and av_fourcc2str() macro to replace
|
||||
av_get_codec_tag_string() from lavc.
|
||||
|
||||
2017-03-27 - ddef3d902f - lavf 57.68.100 - avformat.h
|
||||
Deprecate that demuxers export the stream rotation angle in AVStream.metadata
|
||||
(via an entry named "rotate"). Use av_stream_get_side_data() with
|
||||
AV_PKT_DATA_DISPLAYMATRIX instead, and read the rotation angle with
|
||||
av_display_rotation_get(). The same is done for muxing. Instead of adding a
|
||||
"rotate" entry to AVStream.metadata, AV_PKT_DATA_DISPLAYMATRIX side data has
|
||||
to be added to the AVStream.
|
||||
|
||||
2017-03-23 - 7e4ba776a2 - lavc 57.85.101 - avcodec.h
|
||||
vdpau hardware accelerated decoding now supports the new hwaccel API, which
|
||||
can create the decoder context and allocate hardware frame automatically.
|
||||
See AVCodecContext.hw_device_ctx and AVCodecContext.hw_frames_ctx.
|
||||
|
||||
2017-03-23 - 156bd8278f - lavc 57.85.100 - avcodec.h
|
||||
Add AVCodecContext.hwaccel_flags field. This will control some hwaccels at
|
||||
a later point.
|
||||
|
||||
2017-03-21 - xxxxxxx - lavf 57.67.100 / 57.08.0 - avio.h
|
||||
Add AVIO_SEEKABLE_TIME flag.
|
||||
|
||||
2017-03-21 - d682ae70b4 - lavf 57.66.105, lavc 57.83.101 - avformat.h, avcodec.h
|
||||
Deprecate AVFMT_FLAG_KEEP_SIDE_DATA. It will be ignored after the next major
|
||||
bump, and libavformat will behave as if it were always set.
|
||||
Deprecate av_packet_merge_side_data() and av_packet_split_side_data().
|
||||
|
||||
2016-03-20 - xxxxxxx - lavu 55.50.100 / 55.21.0 - imgutils.h
|
||||
Add av_image_copy_uc_from(), a version of av_image_copy() for copying
|
||||
from GPU mapped memory.
|
||||
|
||||
2017-03-20 - 9c2436e - lavu 55.49.100 - pixdesc.h
|
||||
Add AV_PIX_FMT_FLAG_BAYER pixel format flag.
|
||||
|
||||
2017-03-18 - 3796fb2692 - lavfi 6.77.100 - avfilter.h
|
||||
Deprecate AVFilterGraph.resample_lavr_opts
|
||||
It's never been used by avfilter nor passed to anything.
|
||||
|
||||
2017-02-10 - xxxxxxx - lavu 55.48.100 / 55.33.0 - spherical.h
|
||||
Add AV_SPHERICAL_EQUIRECTANGULAR_TILE, av_spherical_tile_bounds(),
|
||||
and projection-specific properties (bound_left, bound_top, bound_right,
|
||||
bound_bottom, padding) to AVSphericalMapping.
|
||||
|
||||
2017-03-02 - ade7c1a232 - lavc 57.81.104 - videotoolbox.h
|
||||
AVVideotoolboxContext.cv_pix_fmt_type can now be set to 0 to output the
|
||||
native decoder format. (The default value is not changed.)
|
||||
|
||||
2017-03-02 - 554bc4eea8 - lavu 55.47.101, lavc 57.81.102, lavf 57.66.103
|
||||
Remove requirement to use AVOption or accessors to access certain fields
|
||||
in AVFrame, AVCodecContext, and AVFormatContext that were previously
|
||||
documented as "no direct access" allowed.
|
||||
|
||||
2017-02-13 - c1a5fca06f - lavc 57.80.100 - avcodec.h
|
||||
Add AVCodecContext.hw_device_ctx.
|
||||
|
||||
2017-02-11 - e3af49b14b - lavu 55.47.100 - frame.h
|
||||
Add AVFrame.opaque_ref.
|
||||
|
||||
2017-01-31 - xxxxxxx - lavu 55.46.100 / 55.20.0 - cpu.h
|
||||
Add AV_CPU_FLAG_SSSE3SLOW.
|
||||
|
||||
2017-01-24 - c4618f842a - lavu 55.45.100 - channel_layout.h
|
||||
Add av_get_extended_channel_layout()
|
||||
|
||||
2017-01-22 - 76c5a69e26 - lavu 55.44.100 - lfg.h
|
||||
Add av_lfg_init_from_data().
|
||||
|
||||
2017-01-17 - 2a4a8653b6 - lavc 57.74.100 - vaapi.h
|
||||
Deprecate struct vaapi_context and the vaapi.h installed header.
|
||||
Callers should set AVCodecContext.hw_frames_ctx instead.
|
||||
|
||||
2017-01-12 - dbe9dbed31 - lavfi 6.69.100- buffersink.h
|
||||
Add av_buffersink_get_*() functions.
|
||||
|
||||
2017-01-06 - 9488032e10 - lavf 57.62.100- avio.h
|
||||
Add avio_get_dyn_buf()
|
||||
|
||||
2016-12-10 - xxxxxxx - lavu xx.xx.100- imgutils.h
|
||||
Add av_image_check_size2()
|
||||
|
||||
2016-xx-xx - xxxxxxx - lavc 57.67.100 / 57.29.0 - avcodec.h
|
||||
Add AV_PKT_DATA_SPHERICAL packet side data to export AVSphericalMapping
|
||||
information from containers.
|
||||
|
||||
2016-xx-xx - xxxxxxx - lavu 55.42.100 / 55.30.0 - spherical.h
|
||||
Add AV_FRAME_DATA_SPHERICAL value, av_spherical_alloc() API and
|
||||
AVSphericalMapping type to export and describe spherical video properties.
|
||||
|
||||
2016-11-18 - 2ab50647ff - lavf 57.58.100 - avformat.h
|
||||
Add av_stream_add_side_data().
|
||||
|
||||
2016-11-13 - 775a8477b7 - lavu 55.39.100 - hwcontext_vaapi.h
|
||||
Add AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE.
|
||||
|
||||
2016-11-13 - a8d51bb424 - lavu 55.38.100 - hwcontext_vaapi.h
|
||||
Add driver quirks field to VAAPI-specific hwdevice and enum with
|
||||
members AV_VAAPI_DRIVER_QUIRK_* to represent its values.
|
||||
|
||||
2016-11-10 - 638b216d4f - lavu 55.36.100 - pixfmt.h
|
||||
Add AV_PIX_FMT_GRAY12(LE/BE).
|
||||
|
||||
-------- 8< --------- FFmpeg 3.2 was cut here -------- 8< ---------
|
||||
|
||||
2016-10-24 - 73ead47 - lavf 57.55.100 - avformat.h
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = FFmpeg
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_NUMBER = 3.2.8
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
@@ -38,11 +38,8 @@ DOCS = $(DOCS-yes)
|
||||
|
||||
DOC_EXAMPLES-$(CONFIG_AVIO_DIR_CMD_EXAMPLE) += avio_dir_cmd
|
||||
DOC_EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading
|
||||
DOC_EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio
|
||||
DOC_EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video
|
||||
DOC_EXAMPLES-$(CONFIG_DECODING_ENCODING_EXAMPLE) += decoding_encoding
|
||||
DOC_EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
|
||||
DOC_EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio
|
||||
DOC_EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video
|
||||
DOC_EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE) += extract_mvs
|
||||
DOC_EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio
|
||||
DOC_EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE) += filtering_audio
|
||||
|
||||
@@ -26,26 +26,19 @@ with their parameters, if any.
|
||||
|
||||
@section aac_adtstoasc
|
||||
|
||||
Convert MPEG-2/4 AAC ADTS to an MPEG-4 Audio Specific Configuration
|
||||
bitstream.
|
||||
Convert MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration
|
||||
bitstream filter.
|
||||
|
||||
This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4
|
||||
ADTS header and removes the ADTS header.
|
||||
|
||||
This filter is required for example when copying an AAC stream from a
|
||||
raw ADTS AAC or an MPEG-TS container to MP4A-LATM, to an FLV file, or
|
||||
to MOV/MP4 files and related formats such as 3GP or M4A. Please note
|
||||
that it is auto-inserted for MP4A-LATM and MOV/MP4 and related formats.
|
||||
This is required for example when copying an AAC stream from a raw
|
||||
ADTS AAC container to a FLV or a MOV/MP4 file.
|
||||
|
||||
@section chomp
|
||||
|
||||
Remove zero padding at the end of a packet.
|
||||
|
||||
@section dca_core
|
||||
|
||||
Extract the core from a DCA/DTS stream, dropping extensions such as
|
||||
DTS-HD.
|
||||
|
||||
@section dump_extra
|
||||
|
||||
Add extradata to the beginning of the filtered packets.
|
||||
@@ -74,23 +67,9 @@ the header stored in extradata to the key packets:
|
||||
ffmpeg -i INPUT -map 0 -flags:v +global_header -c:v libx264 -bsf:v dump_extra out.ts
|
||||
@end example
|
||||
|
||||
@section extract_extradata
|
||||
@section dca_core
|
||||
|
||||
Extract the in-band extradata.
|
||||
|
||||
Certain codecs allow the long-term headers (e.g. MPEG-2 sequence headers,
|
||||
or H.264/HEVC (VPS/)SPS/PPS) to be transmitted either "in-band" (i.e. as a part
|
||||
of the bitstream containing the coded frames) or "out of band" (e.g. on the
|
||||
container level). This latter form is called "extradata" in FFmpeg terminology.
|
||||
|
||||
This bitstream filter detects the in-band headers and makes them available as
|
||||
extradata.
|
||||
|
||||
@table @option
|
||||
@item remove
|
||||
When this option is enabled, the long-term headers are removed from the
|
||||
bitstream after extraction.
|
||||
@end table
|
||||
Extract DCA core from DTS-HD streams.
|
||||
|
||||
@section h264_mp4toannexb
|
||||
|
||||
@@ -99,7 +78,7 @@ prefixed mode (as defined in the Annex B of the ITU-T H.264
|
||||
specification).
|
||||
|
||||
This is required by some streaming formats, typically the MPEG-2
|
||||
transport stream format (muxer @code{mpegts}).
|
||||
transport stream format ("mpegts").
|
||||
|
||||
For example to remux an MP4 file containing an H.264 stream to mpegts
|
||||
format with @command{ffmpeg}, you can use the command:
|
||||
@@ -108,29 +87,6 @@ format with @command{ffmpeg}, you can use the command:
|
||||
ffmpeg -i INPUT.mp4 -codec copy -bsf:v h264_mp4toannexb OUTPUT.ts
|
||||
@end example
|
||||
|
||||
Please note that this filter is auto-inserted for MPEG-TS (muxer
|
||||
@code{mpegts}) and raw H.264 (muxer @code{h264}) output formats.
|
||||
|
||||
@section hevc_mp4toannexb
|
||||
|
||||
Convert an HEVC/H.265 bitstream from length prefixed mode to start code
|
||||
prefixed mode (as defined in the Annex B of the ITU-T H.265
|
||||
specification).
|
||||
|
||||
This is required by some streaming formats, typically the MPEG-2
|
||||
transport stream format (muxer @code{mpegts}).
|
||||
|
||||
For example to remux an MP4 file containing an HEVC stream to mpegts
|
||||
format with @command{ffmpeg}, you can use the command:
|
||||
|
||||
@example
|
||||
ffmpeg -i INPUT.mp4 -codec copy -bsf:v hevc_mp4toannexb OUTPUT.ts
|
||||
@end example
|
||||
|
||||
Please note that this filter is auto-inserted for MPEG-TS (muxer
|
||||
@code{mpegts}) and raw HEVC/H.265 (muxer @code{h265} or
|
||||
@code{hevc}) output formats.
|
||||
|
||||
@section imxdump
|
||||
|
||||
Modifies the bitstream to fit in MOV and to be usable by the Final Cut
|
||||
@@ -181,22 +137,11 @@ exiftran -i -9 frame*.jpg
|
||||
ffmpeg -i frame_%d.jpg -c:v copy rotated.avi
|
||||
@end example
|
||||
|
||||
@section mjpegadump
|
||||
@section mjpega_dump_header
|
||||
|
||||
Add an MJPEG A header to the bitstream, to enable decoding by
|
||||
Quicktime.
|
||||
@section movsub
|
||||
|
||||
@anchor{mov2textsub}
|
||||
@section mov2textsub
|
||||
|
||||
Extract a representable text file from MOV subtitles, stripping the
|
||||
metadata header from each subtitle packet.
|
||||
|
||||
See also the @ref{text2movsub} filter.
|
||||
|
||||
@section mp3decomp
|
||||
|
||||
Decompress non-standard compressed MP3 audio headers.
|
||||
@section mp3_header_decompress
|
||||
|
||||
@section mpeg4_unpack_bframes
|
||||
|
||||
@@ -236,38 +181,4 @@ applies the modification to every byte.
|
||||
|
||||
@section remove_extra
|
||||
|
||||
Remove extradata from packets.
|
||||
|
||||
It accepts the following parameter:
|
||||
@table @option
|
||||
@item freq
|
||||
Set which frame types to remove extradata from.
|
||||
|
||||
@table @samp
|
||||
@item k
|
||||
Remove extradata from non-keyframes only.
|
||||
|
||||
@item keyframe
|
||||
Remove extradata from keyframes only.
|
||||
|
||||
@item e, all
|
||||
Remove extradata from all frames.
|
||||
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@anchor{text2movsub}
|
||||
@section text2movsub
|
||||
|
||||
Convert text subtitles to MOV subtitles (as used by the @code{mov_text}
|
||||
codec) with metadata headers.
|
||||
|
||||
See also the @ref{mov2textsub} filter.
|
||||
|
||||
@section vp9_superframe
|
||||
|
||||
Merge VP9 invisible (alt-ref) frames back into VP9 superframes. This
|
||||
fixes merging of split/segmented VP9 streams where the alt-ref frame
|
||||
was split from its visible counterpart.
|
||||
|
||||
@c man end BITSTREAM FILTERS
|
||||
|
||||
@@ -138,8 +138,7 @@ Set audio sampling rate (in Hz).
|
||||
Set number of audio channels.
|
||||
|
||||
@item cutoff @var{integer} (@emph{encoding,audio})
|
||||
Set cutoff bandwidth. (Supported only by selected encoders, see
|
||||
their respective documentation sections.)
|
||||
Set cutoff bandwidth.
|
||||
|
||||
@item frame_size @var{integer} (@emph{encoding,audio})
|
||||
Set audio frame size.
|
||||
@@ -1068,15 +1067,12 @@ SMPTE 240 M
|
||||
Film
|
||||
@item bt2020
|
||||
BT.2020
|
||||
@item smpte428
|
||||
@item smpte428_1
|
||||
SMPTE ST 428-1
|
||||
@item smpte431
|
||||
SMPTE 431-2
|
||||
@item smpte432
|
||||
SMPTE 432-1
|
||||
@item jedec-p22
|
||||
JEDEC P22
|
||||
@end table
|
||||
|
||||
@item color_trc @var{integer} (@emph{decoding/encoding,video})
|
||||
@@ -1095,29 +1091,21 @@ SMPTE 240 M
|
||||
@item linear
|
||||
Linear
|
||||
@item log
|
||||
@item log100
|
||||
Log
|
||||
@item log_sqrt
|
||||
@item log316
|
||||
Log square root
|
||||
@item iec61966_2_4
|
||||
@item iec61966-2-4
|
||||
IEC 61966-2-4
|
||||
@item bt1361
|
||||
@item bt1361e
|
||||
BT.1361
|
||||
@item iec61966_2_1
|
||||
@item iec61966-2-1
|
||||
IEC 61966-2-1
|
||||
@item bt2020_10
|
||||
@item bt2020_10bit
|
||||
BT.2020 - 10 bit
|
||||
@item bt2020_12
|
||||
@item bt2020_12bit
|
||||
BT.2020 - 12 bit
|
||||
@item smpte2084
|
||||
SMPTE ST 2084
|
||||
@item smpte428
|
||||
@item smpte428_1
|
||||
SMPTE ST 428-1
|
||||
@item arib-std-b67
|
||||
@@ -1141,10 +1129,8 @@ SMPTE 170 M
|
||||
SMPTE 240 M
|
||||
@item ycocg
|
||||
YCOCG
|
||||
@item bt2020nc
|
||||
@item bt2020_ncl
|
||||
BT.2020 NCL
|
||||
@item bt2020c
|
||||
@item bt2020_cl
|
||||
BT.2020 CL
|
||||
@item smpte2085
|
||||
@@ -1154,32 +1140,8 @@ SMPTE 2085
|
||||
@item color_range @var{integer} (@emph{decoding/encoding,video})
|
||||
If used as input parameter, it serves as a hint to the decoder, which
|
||||
color_range the input has.
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item tv
|
||||
@item mpeg
|
||||
MPEG (219*2^(n-8))
|
||||
@item pc
|
||||
@item jpeg
|
||||
JPEG (2^n-1)
|
||||
@end table
|
||||
|
||||
@item chroma_sample_location @var{integer} (@emph{decoding/encoding,video})
|
||||
Possible values:
|
||||
@table @samp
|
||||
@item left
|
||||
|
||||
@item center
|
||||
|
||||
@item topleft
|
||||
|
||||
@item top
|
||||
|
||||
@item bottomleft
|
||||
|
||||
@item bottom
|
||||
|
||||
@end table
|
||||
|
||||
@item log_level_offset @var{integer}
|
||||
Set the log level offset.
|
||||
@@ -1275,10 +1237,6 @@ ffprobe -dump_separator "
|
||||
" -i ~/videos/matrixbench_mpeg2.mpg
|
||||
@end example
|
||||
|
||||
@item max_pixels @var{integer} (@emph{decoding/encoding,video})
|
||||
Maximum number of pixels per image. This value can be used to avoid out of
|
||||
memory failures due to large images.
|
||||
|
||||
@end table
|
||||
|
||||
@c man end CODEC OPTIONS
|
||||
|
||||
@@ -13,9 +13,8 @@ You can disable all the demuxers using the configure option
|
||||
the option @code{--enable-demuxer=@var{DEMUXER}}, or disable it
|
||||
with the option @code{--disable-demuxer=@var{DEMUXER}}.
|
||||
|
||||
The option @code{-demuxers} of the ff* tools will display the list of
|
||||
enabled demuxers. Use @code{-formats} to view a combined list of
|
||||
enabled demuxers and muxers.
|
||||
The option @code{-formats} of the ff* tools will display the list of
|
||||
enabled demuxers.
|
||||
|
||||
The description of some of the currently available demuxers follows.
|
||||
|
||||
@@ -244,17 +243,11 @@ file subdir/file-2.wav
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section flv, live_flv
|
||||
@section flv
|
||||
|
||||
Adobe Flash Video Format demuxer.
|
||||
|
||||
This demuxer is used to demux FLV files and RTMP network streams. In case of live network streams, if you force format, you may use live_flv option instead of flv to survive timestamp discontinuities.
|
||||
|
||||
@example
|
||||
ffmpeg -f flv -i myfile.flv ...
|
||||
ffmpeg -f live_flv -i rtmp://<any.server>/anything/key ....
|
||||
@end example
|
||||
|
||||
This demuxer is used to demux FLV files and RTMP network streams.
|
||||
|
||||
@table @option
|
||||
@item -flv_metadata @var{bool}
|
||||
@@ -300,6 +293,24 @@ used to end the output video at the length of the shortest input file,
|
||||
which in this case is @file{input.mp4} as the GIF in this example loops
|
||||
infinitely.
|
||||
|
||||
@section hls
|
||||
|
||||
HLS demuxer
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item live_start_index
|
||||
segment index to start live streams at (negative values are from the end).
|
||||
|
||||
@item allowed_extensions
|
||||
',' separated list of file extensions that hls is allowed to access.
|
||||
|
||||
@item max_reload
|
||||
Maximum number of times a insufficient list is attempted to be reloaded.
|
||||
Default value is 1000.
|
||||
@end table
|
||||
|
||||
@section image2
|
||||
|
||||
Image file demuxer.
|
||||
|
||||
@@ -131,6 +131,11 @@ designated struct initializers (@samp{struct s x = @{ .i = 17 @};});
|
||||
|
||||
@item
|
||||
compound literals (@samp{x = (struct s) @{ 17, 23 @};}).
|
||||
|
||||
@item
|
||||
Implementation defined behavior for signed integers is assumed to match the
|
||||
expected behavior for two's complement. Non representable values in integer
|
||||
casts are binary truncated. Shift right of signed values uses sign extension.
|
||||
@end itemize
|
||||
|
||||
These features are supported by all compilers we care about, so we will not
|
||||
|
||||
@@ -488,10 +488,6 @@ is an optional AC-3 feature that increases quality by selectively encoding
|
||||
the left/right channels as mid/side. This option is enabled by default, and it
|
||||
is highly recommended that it be left as enabled except for testing purposes.
|
||||
|
||||
@item cutoff @var{frequency}
|
||||
Set lowpass cutoff frequency. If unspecified, the encoder selects a default
|
||||
determined by various other encoding parameters.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Floating-Point-Only AC-3 Encoding Options
|
||||
@@ -549,8 +545,7 @@ The following options are supported by FFmpeg's flac encoder.
|
||||
@table @option
|
||||
@item compression_level
|
||||
Sets the compression level, which chooses defaults for many other options
|
||||
if they are not set explicitly. Valid values are from 0 to 12, 5 is the
|
||||
default.
|
||||
if they are not set explicitly.
|
||||
|
||||
@item frame_size
|
||||
Sets the size of the frames in samples per channel.
|
||||
@@ -617,27 +612,6 @@ and slightly improves compression.
|
||||
|
||||
@end table
|
||||
|
||||
@anchor{opusenc}
|
||||
@section opus
|
||||
|
||||
Opus encoder.
|
||||
|
||||
This is a native FFmpeg encoder for the Opus format. Currently its in development and
|
||||
only implements the CELT part of the codec. Its quality is usually worse and at best
|
||||
is equal to the libopus encoder.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item b
|
||||
Set bit rate in bits/s. If unspecified it uses the number of channels and the layout
|
||||
to make a good guess.
|
||||
|
||||
@item opus_delay
|
||||
Sets the maximum delay in milliseconds. Lower delays than 20ms will very quickly
|
||||
decrease quality.
|
||||
@end table
|
||||
|
||||
@anchor{libfdk-aac-enc}
|
||||
@section libfdk_aac
|
||||
|
||||
@@ -843,10 +817,6 @@ Set algorithm quality. Valid arguments are integers in the 0-9 range,
|
||||
with 0 meaning highest quality but slowest, and 9 meaning fastest
|
||||
while producing the worst quality.
|
||||
|
||||
@item cutoff (@emph{--lowpass})
|
||||
Set lowpass cutoff frequency. If unspecified, the encoder dynamically
|
||||
adjusts the cutoff.
|
||||
|
||||
@item reservoir
|
||||
Enable use of bit reservoir when set to 1. Default value is 1. LAME
|
||||
has this enabled by default, but can be overridden by use
|
||||
@@ -900,90 +870,6 @@ default value is 0 (disabled).
|
||||
|
||||
@end table
|
||||
|
||||
@section libopus
|
||||
|
||||
libopus Opus Interactive Audio Codec encoder wrapper.
|
||||
|
||||
Requires the presence of the libopus headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libopus}.
|
||||
|
||||
@subsection Option Mapping
|
||||
|
||||
Most libopus options are modelled after the @command{opusenc} utility from
|
||||
opus-tools. The following is an option mapping chart describing options
|
||||
supported by the libopus wrapper, and their @command{opusenc}-equivalent
|
||||
in parentheses.
|
||||
|
||||
@table @option
|
||||
|
||||
@item b (@emph{bitrate})
|
||||
Set the bit rate in bits/s. FFmpeg's @option{b} option is
|
||||
expressed in bits/s, while @command{opusenc}'s @option{bitrate} in
|
||||
kilobits/s.
|
||||
|
||||
@item vbr (@emph{vbr}, @emph{hard-cbr}, and @emph{cvbr})
|
||||
Set VBR mode. The FFmpeg @option{vbr} option has the following
|
||||
valid arguments, with the @command{opusenc} equivalent options
|
||||
in parentheses:
|
||||
|
||||
@table @samp
|
||||
@item off (@emph{hard-cbr})
|
||||
Use constant bit rate encoding.
|
||||
|
||||
@item on (@emph{vbr})
|
||||
Use variable bit rate encoding (the default).
|
||||
|
||||
@item constrained (@emph{cvbr})
|
||||
Use constrained variable bit rate encoding.
|
||||
@end table
|
||||
|
||||
@item compression_level (@emph{comp})
|
||||
Set encoding algorithm complexity. Valid options are integers in
|
||||
the 0-10 range. 0 gives the fastest encodes but lower quality, while 10
|
||||
gives the highest quality but slowest encoding. The default is 10.
|
||||
|
||||
@item frame_duration (@emph{framesize})
|
||||
Set maximum frame size, or duration of a frame in milliseconds. The
|
||||
argument must be exactly the following: 2.5, 5, 10, 20, 40, 60. Smaller
|
||||
frame sizes achieve lower latency but less quality at a given bitrate.
|
||||
Sizes greater than 20ms are only interesting at fairly low bitrates.
|
||||
The default is 20ms.
|
||||
|
||||
@item packet_loss (@emph{expect-loss})
|
||||
Set expected packet loss percentage. The default is 0.
|
||||
|
||||
@item application (N.A.)
|
||||
Set intended application type. Valid options are listed below:
|
||||
|
||||
@table @samp
|
||||
@item voip
|
||||
Favor improved speech intelligibility.
|
||||
@item audio
|
||||
Favor faithfulness to the input (the default).
|
||||
@item lowdelay
|
||||
Restrict to only the lowest delay modes.
|
||||
@end table
|
||||
|
||||
@item cutoff (N.A.)
|
||||
Set cutoff bandwidth in Hz. The argument must be exactly one of the
|
||||
following: 4000, 6000, 8000, 12000, or 20000, corresponding to
|
||||
narrowband, mediumband, wideband, super wideband, and fullband
|
||||
respectively. The default is 0 (cutoff disabled).
|
||||
|
||||
@item mapping_family (@emph{mapping_family})
|
||||
Set channel mapping family to be used by the encoder. The default value of -1
|
||||
uses mapping family 0 for mono and stereo inputs, and mapping family 1
|
||||
otherwise. The default also disables the surround masking and LFE bandwidth
|
||||
optimzations in libopus, and requires that the input contains 8 channels or
|
||||
fewer.
|
||||
|
||||
Other values include 0 for mono and stereo, 1 for surround sound with masking
|
||||
and LFE bandwidth optimizations, and 255 for independent streams with an
|
||||
unspecified channel layout.
|
||||
|
||||
@end table
|
||||
|
||||
@anchor{libshine}
|
||||
@section libshine
|
||||
|
||||
@@ -1123,6 +1009,90 @@ default value is 0 (disabled).
|
||||
|
||||
@end table
|
||||
|
||||
@section libopus
|
||||
|
||||
libopus Opus Interactive Audio Codec encoder wrapper.
|
||||
|
||||
Requires the presence of the libopus headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libopus}.
|
||||
|
||||
@subsection Option Mapping
|
||||
|
||||
Most libopus options are modelled after the @command{opusenc} utility from
|
||||
opus-tools. The following is an option mapping chart describing options
|
||||
supported by the libopus wrapper, and their @command{opusenc}-equivalent
|
||||
in parentheses.
|
||||
|
||||
@table @option
|
||||
|
||||
@item b (@emph{bitrate})
|
||||
Set the bit rate in bits/s. FFmpeg's @option{b} option is
|
||||
expressed in bits/s, while @command{opusenc}'s @option{bitrate} in
|
||||
kilobits/s.
|
||||
|
||||
@item vbr (@emph{vbr}, @emph{hard-cbr}, and @emph{cvbr})
|
||||
Set VBR mode. The FFmpeg @option{vbr} option has the following
|
||||
valid arguments, with the @command{opusenc} equivalent options
|
||||
in parentheses:
|
||||
|
||||
@table @samp
|
||||
@item off (@emph{hard-cbr})
|
||||
Use constant bit rate encoding.
|
||||
|
||||
@item on (@emph{vbr})
|
||||
Use variable bit rate encoding (the default).
|
||||
|
||||
@item constrained (@emph{cvbr})
|
||||
Use constrained variable bit rate encoding.
|
||||
@end table
|
||||
|
||||
@item compression_level (@emph{comp})
|
||||
Set encoding algorithm complexity. Valid options are integers in
|
||||
the 0-10 range. 0 gives the fastest encodes but lower quality, while 10
|
||||
gives the highest quality but slowest encoding. The default is 10.
|
||||
|
||||
@item frame_duration (@emph{framesize})
|
||||
Set maximum frame size, or duration of a frame in milliseconds. The
|
||||
argument must be exactly the following: 2.5, 5, 10, 20, 40, 60. Smaller
|
||||
frame sizes achieve lower latency but less quality at a given bitrate.
|
||||
Sizes greater than 20ms are only interesting at fairly low bitrates.
|
||||
The default is 20ms.
|
||||
|
||||
@item packet_loss (@emph{expect-loss})
|
||||
Set expected packet loss percentage. The default is 0.
|
||||
|
||||
@item application (N.A.)
|
||||
Set intended application type. Valid options are listed below:
|
||||
|
||||
@table @samp
|
||||
@item voip
|
||||
Favor improved speech intelligibility.
|
||||
@item audio
|
||||
Favor faithfulness to the input (the default).
|
||||
@item lowdelay
|
||||
Restrict to only the lowest delay modes.
|
||||
@end table
|
||||
|
||||
@item cutoff (N.A.)
|
||||
Set cutoff bandwidth in Hz. The argument must be exactly one of the
|
||||
following: 4000, 6000, 8000, 12000, or 20000, corresponding to
|
||||
narrowband, mediumband, wideband, super wideband, and fullband
|
||||
respectively. The default is 0 (cutoff disabled).
|
||||
|
||||
@item mapping_family (@emph{mapping_family})
|
||||
Set channel mapping family to be used by the encoder. The default value of -1
|
||||
uses mapping family 0 for mono and stereo inputs, and mapping family 1
|
||||
otherwise. The default also disables the surround masking and LFE bandwidth
|
||||
optimzations in libopus, and requires that the input contains 8 channels or
|
||||
fewer.
|
||||
|
||||
Other values include 0 for mono and stereo, 1 for surround sound with masking
|
||||
and LFE bandwidth optimizations, and 255 for independent streams with an
|
||||
unspecified channel layout.
|
||||
|
||||
@end table
|
||||
|
||||
@section libvorbis
|
||||
|
||||
libvorbis encoder wrapper.
|
||||
@@ -1222,27 +1192,6 @@ Same as @samp{3}, but with extra processing enabled.
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@anchor{mjpegenc}
|
||||
@section mjpeg
|
||||
|
||||
Motion JPEG encoder.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item huffman
|
||||
Set the huffman encoding strategy. Possible values:
|
||||
|
||||
@table @samp
|
||||
@item default
|
||||
Use the default huffman tables. This is the default strategy.
|
||||
|
||||
@item optimal
|
||||
Compute and use optimal huffman tables.
|
||||
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@anchor{wavpackenc}
|
||||
@section wavpack
|
||||
|
||||
@@ -1312,81 +1261,6 @@ disabled
|
||||
A description of some of the currently available video encoders
|
||||
follows.
|
||||
|
||||
@section Hap
|
||||
|
||||
Vidvox Hap video encoder.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item format @var{integer}
|
||||
Specifies the Hap format to encode.
|
||||
|
||||
@table @option
|
||||
@item hap
|
||||
@item hap_alpha
|
||||
@item hap_q
|
||||
@end table
|
||||
|
||||
Default value is @option{hap}.
|
||||
|
||||
@item chunks @var{integer}
|
||||
Specifies the number of chunks to split frames into, between 1 and 64. This
|
||||
permits multithreaded decoding of large frames, potentially at the cost of
|
||||
data-rate. The encoder may modify this value to divide frames evenly.
|
||||
|
||||
Default value is @var{1}.
|
||||
|
||||
@item compressor @var{integer}
|
||||
Specifies the second-stage compressor to use. If set to @option{none},
|
||||
@option{chunks} will be limited to 1, as chunked uncompressed frames offer no
|
||||
benefit.
|
||||
|
||||
@table @option
|
||||
@item none
|
||||
@item snappy
|
||||
@end table
|
||||
|
||||
Default value is @option{snappy}.
|
||||
|
||||
@end table
|
||||
|
||||
@section jpeg2000
|
||||
|
||||
The native jpeg 2000 encoder is lossy by default, the @code{-q:v}
|
||||
option can be used to set the encoding quality. Lossless encoding
|
||||
can be selected with @code{-pred 1}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item format
|
||||
Can be set to either @code{j2k} or @code{jp2} (the default) that
|
||||
makes it possible to store non-rgb pix_fmts.
|
||||
|
||||
@end table
|
||||
|
||||
@section libkvazaar
|
||||
|
||||
Kvazaar H.265/HEVC encoder.
|
||||
|
||||
Requires the presence of the libkvazaar headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@option{--enable-libkvazaar}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item b
|
||||
Set target video bitrate in bit/s and enable rate control.
|
||||
|
||||
@item kvazaar-params
|
||||
Set kvazaar parameters as a list of @var{name}=@var{value} pairs separated
|
||||
by commas (,). See kvazaar documentation for a list of options.
|
||||
|
||||
@end table
|
||||
|
||||
@section libopenh264
|
||||
|
||||
Cisco libopenh264 H.264/MPEG-4 AVC encoder wrapper.
|
||||
@@ -1453,6 +1327,30 @@ Set maximum NAL size in bytes.
|
||||
Allow skipping frames to hit the target bitrate if set to 1.
|
||||
@end table
|
||||
|
||||
@section jpeg2000
|
||||
|
||||
The native jpeg 2000 encoder is lossy by default, the @code{-q:v}
|
||||
option can be used to set the encoding quality. Lossless encoding
|
||||
can be selected with @code{-pred 1}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item format
|
||||
Can be set to either @code{j2k} or @code{jp2} (the default) that
|
||||
makes it possible to store non-rgb pix_fmts.
|
||||
|
||||
@end table
|
||||
|
||||
@section snow
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item iterative_dia_size
|
||||
dia size for the iterative motion estimation
|
||||
@end table
|
||||
|
||||
@section libtheora
|
||||
|
||||
libtheora Theora encoder wrapper.
|
||||
@@ -1686,6 +1584,7 @@ colorspaces:
|
||||
For more information about libvpx see:
|
||||
@url{http://www.webmproject.org/}
|
||||
|
||||
|
||||
@section libwebp
|
||||
|
||||
libwebp WebP Image encoder wrapper
|
||||
@@ -1852,10 +1751,6 @@ Exhaustive search.
|
||||
Hadamard exhaustive search (slowest).
|
||||
@end table
|
||||
|
||||
@item forced-idr
|
||||
Normally, when forcing a I-frame type, the encoder can select any type
|
||||
of I-frame. This option forces it to choose an IDR-frame.
|
||||
|
||||
@item subq (@emph{subme})
|
||||
Sub-pixel motion estimation method.
|
||||
|
||||
@@ -2146,10 +2041,6 @@ Set the x265 preset.
|
||||
@item tune
|
||||
Set the x265 tune parameter.
|
||||
|
||||
@item forced-idr
|
||||
Normally, when forcing a I-frame type, the encoder can select any type
|
||||
of I-frame. This option forces it to choose an IDR-frame.
|
||||
|
||||
@item x265-params
|
||||
Set x265 options using a list of @var{key}=@var{value} couples separated
|
||||
by ":". See @command{x265 --help} for a list of options.
|
||||
@@ -2428,6 +2319,27 @@ Setting a higher @option{bits_per_mb} limit will improve the speed.
|
||||
For the fastest encoding speed set the @option{qscale} parameter (4 is the
|
||||
recommended value) and do not set a size constraint.
|
||||
|
||||
@section libkvazaar
|
||||
|
||||
Kvazaar H.265/HEVC encoder.
|
||||
|
||||
Requires the presence of the libkvazaar headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@option{--enable-libkvazaar}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item b
|
||||
Set target video bitrate in bit/s and enable rate control.
|
||||
|
||||
@item kvazaar-params
|
||||
Set kvazaar parameters as a list of @var{name}=@var{value} pairs separated
|
||||
by commas (,). See kvazaar documentation for a list of options.
|
||||
|
||||
@end table
|
||||
|
||||
@section QSV encoders
|
||||
|
||||
The family of Intel QuickSync Video encoders (MPEG-2, H.264 and HEVC)
|
||||
@@ -2516,15 +2428,6 @@ encoder use CAVLC instead of CABAC.
|
||||
|
||||
@end itemize
|
||||
|
||||
@section snow
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item iterative_dia_size
|
||||
dia size for the iterative motion estimation
|
||||
@end table
|
||||
|
||||
@section vc2
|
||||
|
||||
SMPTE VC-2 (previously BBC Dirac Pro). This codec was primarily aimed at
|
||||
|
||||
5
doc/examples/.gitignore
vendored
5
doc/examples/.gitignore
vendored
@@ -1,10 +1,7 @@
|
||||
/avio_dir_cmd
|
||||
/avio_reading
|
||||
/decode_audio
|
||||
/decode_video
|
||||
/decoding_encoding
|
||||
/demuxing_decoding
|
||||
/encode_audio
|
||||
/encode_video
|
||||
/extract_mvs
|
||||
/filter_audio
|
||||
/filtering_audio
|
||||
|
||||
@@ -13,11 +13,8 @@ LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
|
||||
|
||||
EXAMPLES= avio_dir_cmd \
|
||||
avio_reading \
|
||||
decode_audio \
|
||||
decode_video \
|
||||
decoding_encoding \
|
||||
demuxing_decoding \
|
||||
encode_audio \
|
||||
encode_video \
|
||||
extract_mvs \
|
||||
filtering_video \
|
||||
filtering_audio \
|
||||
@@ -34,7 +31,7 @@ OBJS=$(addsuffix .o,$(EXAMPLES))
|
||||
|
||||
# the following examples make explicit use of the math library
|
||||
avcodec: LDLIBS += -lm
|
||||
encode_audio: LDLIBS += -lm
|
||||
decoding_encoding: LDLIBS += -lm
|
||||
muxing: LDLIBS += -lm
|
||||
resampling_audio: LDLIBS += -lm
|
||||
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* audio decoding with libavcodec API example
|
||||
*
|
||||
* @example decode_audio.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libavutil/frame.h>
|
||||
#include <libavutil/mem.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#define AUDIO_INBUF_SIZE 20480
|
||||
#define AUDIO_REFILL_THRESH 4096
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *outfilename, *filename;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int len;
|
||||
FILE *f, *outfile;
|
||||
uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
AVPacket avpkt;
|
||||
AVFrame *decoded_frame = NULL;
|
||||
|
||||
if (argc <= 2) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
filename = argv[1];
|
||||
outfilename = argv[2];
|
||||
|
||||
/* register all the codecs */
|
||||
avcodec_register_all();
|
||||
|
||||
av_init_packet(&avpkt);
|
||||
|
||||
/* find the MPEG audio decoder */
|
||||
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate audio codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
outfile = fopen(outfilename, "wb");
|
||||
if (!outfile) {
|
||||
av_free(c);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* decode until eof */
|
||||
avpkt.data = inbuf;
|
||||
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
|
||||
|
||||
while (avpkt.size > 0) {
|
||||
int i, ch;
|
||||
int got_frame = 0;
|
||||
|
||||
if (!decoded_frame) {
|
||||
if (!(decoded_frame = av_frame_alloc())) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "Error while decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
if (got_frame) {
|
||||
/* if a frame has been decoded, output it */
|
||||
int data_size = av_get_bytes_per_sample(c->sample_fmt);
|
||||
if (data_size < 0) {
|
||||
/* This should not occur, checking just for paranoia */
|
||||
fprintf(stderr, "Failed to calculate data size\n");
|
||||
exit(1);
|
||||
}
|
||||
for (i=0; i<decoded_frame->nb_samples; i++)
|
||||
for (ch=0; ch<c->channels; ch++)
|
||||
fwrite(decoded_frame->data[ch] + data_size*i, 1, data_size, outfile);
|
||||
}
|
||||
avpkt.size -= len;
|
||||
avpkt.data += len;
|
||||
avpkt.dts =
|
||||
avpkt.pts = AV_NOPTS_VALUE;
|
||||
if (avpkt.size < AUDIO_REFILL_THRESH) {
|
||||
/* Refill the input buffer, to avoid trying to decode
|
||||
* incomplete frames. Instead of this, one could also use
|
||||
* a parser, or use a proper container format through
|
||||
* libavformat. */
|
||||
memmove(inbuf, avpkt.data, avpkt.size);
|
||||
avpkt.data = inbuf;
|
||||
len = fread(avpkt.data + avpkt.size, 1,
|
||||
AUDIO_INBUF_SIZE - avpkt.size, f);
|
||||
if (len > 0)
|
||||
avpkt.size += len;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
fclose(f);
|
||||
|
||||
avcodec_free_context(&c);
|
||||
av_frame_free(&decoded_frame);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* video decoding with libavcodec API example
|
||||
*
|
||||
* @example decode_video.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#define INBUF_SIZE 4096
|
||||
|
||||
static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
|
||||
char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
|
||||
f = fopen(filename,"w");
|
||||
fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
|
||||
for (i = 0; i < ysize; i++)
|
||||
fwrite(buf + i * wrap, 1, xsize, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
|
||||
AVFrame *frame, int *frame_count, AVPacket *pkt, int last)
|
||||
{
|
||||
int len, got_frame;
|
||||
char buf[1024];
|
||||
|
||||
len = avcodec_decode_video2(avctx, frame, &got_frame, pkt);
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "Error while decoding frame %d\n", *frame_count);
|
||||
return len;
|
||||
}
|
||||
if (got_frame) {
|
||||
printf("Saving %sframe %3d\n", last ? "last " : "", *frame_count);
|
||||
fflush(stdout);
|
||||
|
||||
/* the picture is allocated by the decoder, no need to free it */
|
||||
snprintf(buf, sizeof(buf), outfilename, *frame_count);
|
||||
pgm_save(frame->data[0], frame->linesize[0],
|
||||
frame->width, frame->height, buf);
|
||||
(*frame_count)++;
|
||||
}
|
||||
if (pkt->data) {
|
||||
pkt->size -= len;
|
||||
pkt->data += len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *filename, *outfilename;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int frame_count;
|
||||
FILE *f;
|
||||
AVFrame *frame;
|
||||
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
AVPacket avpkt;
|
||||
|
||||
if (argc <= 2) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
filename = argv[1];
|
||||
outfilename = argv[2];
|
||||
|
||||
avcodec_register_all();
|
||||
|
||||
av_init_packet(&avpkt);
|
||||
|
||||
/* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
|
||||
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
/* find the MPEG-1 video decoder */
|
||||
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate video codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
|
||||
c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
|
||||
|
||||
/* For some codecs, such as msmpeg4 and mpeg4, width and height
|
||||
MUST be initialized there because this information is not
|
||||
available in the bitstream. */
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame_count = 0;
|
||||
for (;;) {
|
||||
avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
|
||||
if (avpkt.size == 0)
|
||||
break;
|
||||
|
||||
/* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
|
||||
and this is the only method to use them because you cannot
|
||||
know the compressed data size before analysing it.
|
||||
|
||||
BUT some other codecs (msmpeg4, mpeg4) are inherently frame
|
||||
based, so you must call them with all the data for one
|
||||
frame exactly. You must also initialize 'width' and
|
||||
'height' before initializing them. */
|
||||
|
||||
/* NOTE2: some codecs allow the raw parameters (frame size,
|
||||
sample rate) to be changed at any frame. We handle this, so
|
||||
you should also take care of it */
|
||||
|
||||
/* here, we use a stream based decoder (mpeg1video), so we
|
||||
feed decoder and see if it could decode a frame */
|
||||
avpkt.data = inbuf;
|
||||
while (avpkt.size > 0)
|
||||
if (decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 0) < 0)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Some codecs, such as MPEG, transmit the I- and P-frame with a
|
||||
latency of one frame. You must do the following to have a
|
||||
chance to get the last frame of the video. */
|
||||
avpkt.data = NULL;
|
||||
avpkt.size = 0;
|
||||
decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 1);
|
||||
|
||||
fclose(f);
|
||||
|
||||
avcodec_free_context(&c);
|
||||
av_frame_free(&frame);
|
||||
|
||||
return 0;
|
||||
}
|
||||
665
doc/examples/decoding_encoding.c
Normal file
665
doc/examples/decoding_encoding.c
Normal file
@@ -0,0 +1,665 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* libavcodec API use example.
|
||||
*
|
||||
* @example decoding_encoding.c
|
||||
* Note that libavcodec only handles codecs (MPEG, MPEG-4, etc...),
|
||||
* not file formats (AVI, VOB, MP4, MOV, MKV, MXF, FLV, MPEG-TS, MPEG-PS, etc...).
|
||||
* See library 'libavformat' for the format handling
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/common.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libavutil/mathematics.h>
|
||||
#include <libavutil/samplefmt.h>
|
||||
|
||||
#define INBUF_SIZE 4096
|
||||
#define AUDIO_INBUF_SIZE 20480
|
||||
#define AUDIO_REFILL_THRESH 4096
|
||||
|
||||
/* check that a given sample format is supported by the encoder */
|
||||
static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
const enum AVSampleFormat *p = codec->sample_fmts;
|
||||
|
||||
while (*p != AV_SAMPLE_FMT_NONE) {
|
||||
if (*p == sample_fmt)
|
||||
return 1;
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* just pick the highest supported samplerate */
|
||||
static int select_sample_rate(AVCodec *codec)
|
||||
{
|
||||
const int *p;
|
||||
int best_samplerate = 0;
|
||||
|
||||
if (!codec->supported_samplerates)
|
||||
return 44100;
|
||||
|
||||
p = codec->supported_samplerates;
|
||||
while (*p) {
|
||||
best_samplerate = FFMAX(*p, best_samplerate);
|
||||
p++;
|
||||
}
|
||||
return best_samplerate;
|
||||
}
|
||||
|
||||
/* select layout with the highest channel count */
|
||||
static int select_channel_layout(AVCodec *codec)
|
||||
{
|
||||
const uint64_t *p;
|
||||
uint64_t best_ch_layout = 0;
|
||||
int best_nb_channels = 0;
|
||||
|
||||
if (!codec->channel_layouts)
|
||||
return AV_CH_LAYOUT_STEREO;
|
||||
|
||||
p = codec->channel_layouts;
|
||||
while (*p) {
|
||||
int nb_channels = av_get_channel_layout_nb_channels(*p);
|
||||
|
||||
if (nb_channels > best_nb_channels) {
|
||||
best_ch_layout = *p;
|
||||
best_nb_channels = nb_channels;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return best_ch_layout;
|
||||
}
|
||||
|
||||
/*
|
||||
* Audio encoding example
|
||||
*/
|
||||
static void audio_encode_example(const char *filename)
|
||||
{
|
||||
AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
AVFrame *frame;
|
||||
AVPacket pkt;
|
||||
int i, j, k, ret, got_output;
|
||||
int buffer_size;
|
||||
FILE *f;
|
||||
uint16_t *samples;
|
||||
float t, tincr;
|
||||
|
||||
printf("Encode audio file %s\n", filename);
|
||||
|
||||
/* find the MP2 encoder */
|
||||
codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate audio codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* put sample parameters */
|
||||
c->bit_rate = 64000;
|
||||
|
||||
/* check that the encoder supports s16 pcm input */
|
||||
c->sample_fmt = AV_SAMPLE_FMT_S16;
|
||||
if (!check_sample_fmt(codec, c->sample_fmt)) {
|
||||
fprintf(stderr, "Encoder does not support sample format %s",
|
||||
av_get_sample_fmt_name(c->sample_fmt));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* select other audio parameters supported by the encoder */
|
||||
c->sample_rate = select_sample_rate(codec);
|
||||
c->channel_layout = select_channel_layout(codec);
|
||||
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* frame containing input raw audio */
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame->nb_samples = c->frame_size;
|
||||
frame->format = c->sample_fmt;
|
||||
frame->channel_layout = c->channel_layout;
|
||||
|
||||
/* the codec gives us the frame size, in samples,
|
||||
* we calculate the size of the samples buffer in bytes */
|
||||
buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
|
||||
c->sample_fmt, 0);
|
||||
if (buffer_size < 0) {
|
||||
fprintf(stderr, "Could not get sample buffer size\n");
|
||||
exit(1);
|
||||
}
|
||||
samples = av_malloc(buffer_size);
|
||||
if (!samples) {
|
||||
fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
|
||||
buffer_size);
|
||||
exit(1);
|
||||
}
|
||||
/* setup the data pointers in the AVFrame */
|
||||
ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
|
||||
(const uint8_t*)samples, buffer_size, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not setup audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* encode a single tone sound */
|
||||
t = 0;
|
||||
tincr = 2 * M_PI * 440.0 / c->sample_rate;
|
||||
for (i = 0; i < 200; i++) {
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL; // packet data will be allocated by the encoder
|
||||
pkt.size = 0;
|
||||
|
||||
for (j = 0; j < c->frame_size; j++) {
|
||||
samples[2*j] = (int)(sin(t) * 10000);
|
||||
|
||||
for (k = 1; k < c->channels; k++)
|
||||
samples[2*j + k] = samples[2*j];
|
||||
t += tincr;
|
||||
}
|
||||
/* encode the samples */
|
||||
ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
if (got_output) {
|
||||
fwrite(pkt.data, 1, pkt.size, f);
|
||||
av_packet_unref(&pkt);
|
||||
}
|
||||
}
|
||||
|
||||
/* get the delayed frames */
|
||||
for (got_output = 1; got_output; i++) {
|
||||
ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (got_output) {
|
||||
fwrite(pkt.data, 1, pkt.size, f);
|
||||
av_packet_unref(&pkt);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
av_freep(&samples);
|
||||
av_frame_free(&frame);
|
||||
avcodec_close(c);
|
||||
av_free(c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Audio decoding.
|
||||
*/
|
||||
static void audio_decode_example(const char *outfilename, const char *filename)
|
||||
{
|
||||
AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int len;
|
||||
FILE *f, *outfile;
|
||||
uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
AVPacket avpkt;
|
||||
AVFrame *decoded_frame = NULL;
|
||||
|
||||
av_init_packet(&avpkt);
|
||||
|
||||
printf("Decode audio file %s to %s\n", filename, outfilename);
|
||||
|
||||
/* find the MPEG audio decoder */
|
||||
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate audio codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
outfile = fopen(outfilename, "wb");
|
||||
if (!outfile) {
|
||||
av_free(c);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* decode until eof */
|
||||
avpkt.data = inbuf;
|
||||
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
|
||||
|
||||
while (avpkt.size > 0) {
|
||||
int i, ch;
|
||||
int got_frame = 0;
|
||||
|
||||
if (!decoded_frame) {
|
||||
if (!(decoded_frame = av_frame_alloc())) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "Error while decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
if (got_frame) {
|
||||
/* if a frame has been decoded, output it */
|
||||
int data_size = av_get_bytes_per_sample(c->sample_fmt);
|
||||
if (data_size < 0) {
|
||||
/* This should not occur, checking just for paranoia */
|
||||
fprintf(stderr, "Failed to calculate data size\n");
|
||||
exit(1);
|
||||
}
|
||||
for (i=0; i<decoded_frame->nb_samples; i++)
|
||||
for (ch=0; ch<c->channels; ch++)
|
||||
fwrite(decoded_frame->data[ch] + data_size*i, 1, data_size, outfile);
|
||||
}
|
||||
avpkt.size -= len;
|
||||
avpkt.data += len;
|
||||
avpkt.dts =
|
||||
avpkt.pts = AV_NOPTS_VALUE;
|
||||
if (avpkt.size < AUDIO_REFILL_THRESH) {
|
||||
/* Refill the input buffer, to avoid trying to decode
|
||||
* incomplete frames. Instead of this, one could also use
|
||||
* a parser, or use a proper container format through
|
||||
* libavformat. */
|
||||
memmove(inbuf, avpkt.data, avpkt.size);
|
||||
avpkt.data = inbuf;
|
||||
len = fread(avpkt.data + avpkt.size, 1,
|
||||
AUDIO_INBUF_SIZE - avpkt.size, f);
|
||||
if (len > 0)
|
||||
avpkt.size += len;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
fclose(f);
|
||||
|
||||
avcodec_close(c);
|
||||
av_free(c);
|
||||
av_frame_free(&decoded_frame);
|
||||
}
|
||||
|
||||
/*
|
||||
* Video encoding example
|
||||
*/
|
||||
static void video_encode_example(const char *filename, int codec_id)
|
||||
{
|
||||
AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int i, ret, x, y, got_output;
|
||||
FILE *f;
|
||||
AVFrame *frame;
|
||||
AVPacket pkt;
|
||||
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
|
||||
|
||||
printf("Encode video file %s\n", filename);
|
||||
|
||||
/* find the video encoder */
|
||||
codec = avcodec_find_encoder(codec_id);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate video codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* put sample parameters */
|
||||
c->bit_rate = 400000;
|
||||
/* resolution must be a multiple of two */
|
||||
c->width = 352;
|
||||
c->height = 288;
|
||||
/* frames per second */
|
||||
c->time_base = (AVRational){1,25};
|
||||
/* emit one intra frame every ten frames
|
||||
* check frame pict_type before passing frame
|
||||
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
|
||||
* then gop_size is ignored and the output of encoder
|
||||
* will always be I frame irrespective to gop_size
|
||||
*/
|
||||
c->gop_size = 10;
|
||||
c->max_b_frames = 1;
|
||||
c->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||
|
||||
if (codec_id == AV_CODEC_ID_H264)
|
||||
av_opt_set(c->priv_data, "preset", "slow", 0);
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
frame->format = c->pix_fmt;
|
||||
frame->width = c->width;
|
||||
frame->height = c->height;
|
||||
|
||||
/* the image can be allocated by any means and av_image_alloc() is
|
||||
* just the most convenient way if av_malloc() is to be used */
|
||||
ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
|
||||
c->pix_fmt, 32);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate raw picture buffer\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* encode 1 second of video */
|
||||
for (i = 0; i < 25; i++) {
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL; // packet data will be allocated by the encoder
|
||||
pkt.size = 0;
|
||||
|
||||
fflush(stdout);
|
||||
/* prepare a dummy image */
|
||||
/* Y */
|
||||
for (y = 0; y < c->height; y++) {
|
||||
for (x = 0; x < c->width; x++) {
|
||||
frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cb and Cr */
|
||||
for (y = 0; y < c->height/2; y++) {
|
||||
for (x = 0; x < c->width/2; x++) {
|
||||
frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
|
||||
frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
|
||||
}
|
||||
}
|
||||
|
||||
frame->pts = i;
|
||||
|
||||
/* encode the image */
|
||||
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (got_output) {
|
||||
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
||||
fwrite(pkt.data, 1, pkt.size, f);
|
||||
av_packet_unref(&pkt);
|
||||
}
|
||||
}
|
||||
|
||||
/* get the delayed frames */
|
||||
for (got_output = 1; got_output; i++) {
|
||||
fflush(stdout);
|
||||
|
||||
ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (got_output) {
|
||||
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
||||
fwrite(pkt.data, 1, pkt.size, f);
|
||||
av_packet_unref(&pkt);
|
||||
}
|
||||
}
|
||||
|
||||
/* add sequence end code to have a real MPEG file */
|
||||
fwrite(endcode, 1, sizeof(endcode), f);
|
||||
fclose(f);
|
||||
|
||||
avcodec_close(c);
|
||||
av_free(c);
|
||||
av_freep(&frame->data[0]);
|
||||
av_frame_free(&frame);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Video decoding example
|
||||
*/
|
||||
|
||||
static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
|
||||
char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
|
||||
f = fopen(filename,"w");
|
||||
fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
|
||||
for (i = 0; i < ysize; i++)
|
||||
fwrite(buf + i * wrap, 1, xsize, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
|
||||
AVFrame *frame, int *frame_count, AVPacket *pkt, int last)
|
||||
{
|
||||
int len, got_frame;
|
||||
char buf[1024];
|
||||
|
||||
len = avcodec_decode_video2(avctx, frame, &got_frame, pkt);
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "Error while decoding frame %d\n", *frame_count);
|
||||
return len;
|
||||
}
|
||||
if (got_frame) {
|
||||
printf("Saving %sframe %3d\n", last ? "last " : "", *frame_count);
|
||||
fflush(stdout);
|
||||
|
||||
/* the picture is allocated by the decoder, no need to free it */
|
||||
snprintf(buf, sizeof(buf), outfilename, *frame_count);
|
||||
pgm_save(frame->data[0], frame->linesize[0],
|
||||
frame->width, frame->height, buf);
|
||||
(*frame_count)++;
|
||||
}
|
||||
if (pkt->data) {
|
||||
pkt->size -= len;
|
||||
pkt->data += len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void video_decode_example(const char *outfilename, const char *filename)
|
||||
{
|
||||
AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int frame_count;
|
||||
FILE *f;
|
||||
AVFrame *frame;
|
||||
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
AVPacket avpkt;
|
||||
|
||||
av_init_packet(&avpkt);
|
||||
|
||||
/* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
|
||||
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
printf("Decode video file %s to %s\n", filename, outfilename);
|
||||
|
||||
/* find the MPEG-1 video decoder */
|
||||
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate video codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
|
||||
c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
|
||||
|
||||
/* For some codecs, such as msmpeg4 and mpeg4, width and height
|
||||
MUST be initialized there because this information is not
|
||||
available in the bitstream. */
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame_count = 0;
|
||||
for (;;) {
|
||||
avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
|
||||
if (avpkt.size == 0)
|
||||
break;
|
||||
|
||||
/* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
|
||||
and this is the only method to use them because you cannot
|
||||
know the compressed data size before analysing it.
|
||||
|
||||
BUT some other codecs (msmpeg4, mpeg4) are inherently frame
|
||||
based, so you must call them with all the data for one
|
||||
frame exactly. You must also initialize 'width' and
|
||||
'height' before initializing them. */
|
||||
|
||||
/* NOTE2: some codecs allow the raw parameters (frame size,
|
||||
sample rate) to be changed at any frame. We handle this, so
|
||||
you should also take care of it */
|
||||
|
||||
/* here, we use a stream based decoder (mpeg1video), so we
|
||||
feed decoder and see if it could decode a frame */
|
||||
avpkt.data = inbuf;
|
||||
while (avpkt.size > 0)
|
||||
if (decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 0) < 0)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Some codecs, such as MPEG, transmit the I- and P-frame with a
|
||||
latency of one frame. You must do the following to have a
|
||||
chance to get the last frame of the video. */
|
||||
avpkt.data = NULL;
|
||||
avpkt.size = 0;
|
||||
decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 1);
|
||||
|
||||
fclose(f);
|
||||
|
||||
avcodec_close(c);
|
||||
av_free(c);
|
||||
av_frame_free(&frame);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *output_type;
|
||||
|
||||
/* register all the codecs */
|
||||
avcodec_register_all();
|
||||
|
||||
if (argc < 2) {
|
||||
printf("usage: %s output_type\n"
|
||||
"API example program to decode/encode a media stream with libavcodec.\n"
|
||||
"This program generates a synthetic stream and encodes it to a file\n"
|
||||
"named test.h264, test.mp2 or test.mpg depending on output_type.\n"
|
||||
"The encoded stream is then decoded and written to a raw data output.\n"
|
||||
"output_type must be chosen between 'h264', 'mp2', 'mpg'.\n",
|
||||
argv[0]);
|
||||
return 1;
|
||||
}
|
||||
output_type = argv[1];
|
||||
|
||||
if (!strcmp(output_type, "h264")) {
|
||||
video_encode_example("test.h264", AV_CODEC_ID_H264);
|
||||
} else if (!strcmp(output_type, "mp2")) {
|
||||
audio_encode_example("test.mp2");
|
||||
audio_decode_example("test.pcm", "test.mp2");
|
||||
} else if (!strcmp(output_type, "mpg")) {
|
||||
video_encode_example("test.mpg", AV_CODEC_ID_MPEG1VIDEO);
|
||||
video_decode_example("test%02d.pgm", "test.mpg");
|
||||
} else {
|
||||
fprintf(stderr, "Invalid output type '%s', choose between 'h264', 'mp2', or 'mpg'\n",
|
||||
output_type);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* audio encoding with libavcodec API example.
|
||||
*
|
||||
* @example encode_audio.c
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/common.h>
|
||||
#include <libavutil/frame.h>
|
||||
#include <libavutil/samplefmt.h>
|
||||
|
||||
/* check that a given sample format is supported by the encoder */
|
||||
static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
const enum AVSampleFormat *p = codec->sample_fmts;
|
||||
|
||||
while (*p != AV_SAMPLE_FMT_NONE) {
|
||||
if (*p == sample_fmt)
|
||||
return 1;
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* just pick the highest supported samplerate */
|
||||
static int select_sample_rate(const AVCodec *codec)
|
||||
{
|
||||
const int *p;
|
||||
int best_samplerate = 0;
|
||||
|
||||
if (!codec->supported_samplerates)
|
||||
return 44100;
|
||||
|
||||
p = codec->supported_samplerates;
|
||||
while (*p) {
|
||||
if (!best_samplerate || abs(44100 - *p) < abs(44100 - best_samplerate))
|
||||
best_samplerate = *p;
|
||||
p++;
|
||||
}
|
||||
return best_samplerate;
|
||||
}
|
||||
|
||||
/* select layout with the highest channel count */
|
||||
static int select_channel_layout(const AVCodec *codec)
|
||||
{
|
||||
const uint64_t *p;
|
||||
uint64_t best_ch_layout = 0;
|
||||
int best_nb_channels = 0;
|
||||
|
||||
if (!codec->channel_layouts)
|
||||
return AV_CH_LAYOUT_STEREO;
|
||||
|
||||
p = codec->channel_layouts;
|
||||
while (*p) {
|
||||
int nb_channels = av_get_channel_layout_nb_channels(*p);
|
||||
|
||||
if (nb_channels > best_nb_channels) {
|
||||
best_ch_layout = *p;
|
||||
best_nb_channels = nb_channels;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return best_ch_layout;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *filename;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
AVFrame *frame;
|
||||
AVPacket pkt;
|
||||
int i, j, k, ret, got_output;
|
||||
FILE *f;
|
||||
uint16_t *samples;
|
||||
float t, tincr;
|
||||
|
||||
if (argc <= 1) {
|
||||
fprintf(stderr, "Usage: %s <output file>\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
filename = argv[1];
|
||||
|
||||
/* register all the codecs */
|
||||
avcodec_register_all();
|
||||
|
||||
/* find the MP2 encoder */
|
||||
codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate audio codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* put sample parameters */
|
||||
c->bit_rate = 64000;
|
||||
|
||||
/* check that the encoder supports s16 pcm input */
|
||||
c->sample_fmt = AV_SAMPLE_FMT_S16;
|
||||
if (!check_sample_fmt(codec, c->sample_fmt)) {
|
||||
fprintf(stderr, "Encoder does not support sample format %s",
|
||||
av_get_sample_fmt_name(c->sample_fmt));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* select other audio parameters supported by the encoder */
|
||||
c->sample_rate = select_sample_rate(codec);
|
||||
c->channel_layout = select_channel_layout(codec);
|
||||
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* frame containing input raw audio */
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame->nb_samples = c->frame_size;
|
||||
frame->format = c->sample_fmt;
|
||||
frame->channel_layout = c->channel_layout;
|
||||
|
||||
/* allocate the data buffers */
|
||||
ret = av_frame_get_buffer(frame, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate audio data buffers\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* encode a single tone sound */
|
||||
t = 0;
|
||||
tincr = 2 * M_PI * 440.0 / c->sample_rate;
|
||||
for (i = 0; i < 200; i++) {
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL; // packet data will be allocated by the encoder
|
||||
pkt.size = 0;
|
||||
|
||||
/* make sure the frame is writable -- makes a copy if the encoder
|
||||
* kept a reference internally */
|
||||
ret = av_frame_make_writable(frame);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
samples = (uint16_t*)frame->data[0];
|
||||
|
||||
for (j = 0; j < c->frame_size; j++) {
|
||||
samples[2*j] = (int)(sin(t) * 10000);
|
||||
|
||||
for (k = 1; k < c->channels; k++)
|
||||
samples[2*j + k] = samples[2*j];
|
||||
t += tincr;
|
||||
}
|
||||
/* encode the samples */
|
||||
ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
if (got_output) {
|
||||
fwrite(pkt.data, 1, pkt.size, f);
|
||||
av_packet_unref(&pkt);
|
||||
}
|
||||
}
|
||||
|
||||
/* get the delayed frames */
|
||||
for (got_output = 1; got_output; i++) {
|
||||
ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (got_output) {
|
||||
fwrite(pkt.data, 1, pkt.size, f);
|
||||
av_packet_unref(&pkt);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
av_frame_free(&frame);
|
||||
avcodec_free_context(&c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* video encoding with libavcodec API example
|
||||
*
|
||||
* @example encode_video.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *filename, *codec_name;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int i, ret, x, y, got_output;
|
||||
FILE *f;
|
||||
AVFrame *frame;
|
||||
AVPacket pkt;
|
||||
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
|
||||
|
||||
if (argc <= 2) {
|
||||
fprintf(stderr, "Usage: %s <output file> <codec name>\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
filename = argv[1];
|
||||
codec_name = argv[2];
|
||||
|
||||
avcodec_register_all();
|
||||
|
||||
/* find the mpeg1video encoder */
|
||||
codec = avcodec_find_encoder_by_name(codec_name);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate video codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* put sample parameters */
|
||||
c->bit_rate = 400000;
|
||||
/* resolution must be a multiple of two */
|
||||
c->width = 352;
|
||||
c->height = 288;
|
||||
/* frames per second */
|
||||
c->time_base = (AVRational){1, 25};
|
||||
c->framerate = (AVRational){25, 1};
|
||||
|
||||
/* emit one intra frame every ten frames
|
||||
* check frame pict_type before passing frame
|
||||
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
|
||||
* then gop_size is ignored and the output of encoder
|
||||
* will always be I frame irrespective to gop_size
|
||||
*/
|
||||
c->gop_size = 10;
|
||||
c->max_b_frames = 1;
|
||||
c->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||
|
||||
if (codec->id == AV_CODEC_ID_H264)
|
||||
av_opt_set(c->priv_data, "preset", "slow", 0);
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
frame->format = c->pix_fmt;
|
||||
frame->width = c->width;
|
||||
frame->height = c->height;
|
||||
|
||||
ret = av_frame_get_buffer(frame, 32);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate the video frame data\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* encode 1 second of video */
|
||||
for (i = 0; i < 25; i++) {
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL; // packet data will be allocated by the encoder
|
||||
pkt.size = 0;
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
/* make sure the frame data is writable */
|
||||
ret = av_frame_make_writable(frame);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
/* prepare a dummy image */
|
||||
/* Y */
|
||||
for (y = 0; y < c->height; y++) {
|
||||
for (x = 0; x < c->width; x++) {
|
||||
frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cb and Cr */
|
||||
for (y = 0; y < c->height/2; y++) {
|
||||
for (x = 0; x < c->width/2; x++) {
|
||||
frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
|
||||
frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
|
||||
}
|
||||
}
|
||||
|
||||
frame->pts = i;
|
||||
|
||||
/* encode the image */
|
||||
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (got_output) {
|
||||
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
||||
fwrite(pkt.data, 1, pkt.size, f);
|
||||
av_packet_unref(&pkt);
|
||||
}
|
||||
}
|
||||
|
||||
/* get the delayed frames */
|
||||
for (got_output = 1; got_output; i++) {
|
||||
fflush(stdout);
|
||||
|
||||
ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (got_output) {
|
||||
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
|
||||
fwrite(pkt.data, 1, pkt.size, f);
|
||||
av_packet_unref(&pkt);
|
||||
}
|
||||
}
|
||||
|
||||
/* add sequence end code to have a real MPEG file */
|
||||
fwrite(endcode, 1, sizeof(endcode), f);
|
||||
fclose(f);
|
||||
|
||||
avcodec_free_context(&c);
|
||||
av_frame_free(&frame);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -69,7 +69,8 @@ static int decode_packet(int *got_frame, int cached)
|
||||
return decoded;
|
||||
}
|
||||
|
||||
static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
|
||||
static int open_codec_context(int *stream_idx,
|
||||
AVFormatContext *fmt_ctx, enum AVMediaType type)
|
||||
{
|
||||
int ret;
|
||||
AVStream *st;
|
||||
@@ -77,27 +78,24 @@ static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
|
||||
AVCodec *dec = NULL;
|
||||
AVDictionary *opts = NULL;
|
||||
|
||||
ret = av_find_best_stream(fmt_ctx, type, -1, -1, &dec, 0);
|
||||
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not find %s stream in input file '%s'\n",
|
||||
av_get_media_type_string(type), src_filename);
|
||||
return ret;
|
||||
} else {
|
||||
int stream_idx = ret;
|
||||
st = fmt_ctx->streams[stream_idx];
|
||||
*stream_idx = ret;
|
||||
st = fmt_ctx->streams[*stream_idx];
|
||||
|
||||
dec_ctx = avcodec_alloc_context3(dec);
|
||||
if (!dec_ctx) {
|
||||
fprintf(stderr, "Failed to allocate codec\n");
|
||||
/* find decoder for the stream */
|
||||
dec_ctx = st->codec;
|
||||
dec = avcodec_find_decoder(dec_ctx->codec_id);
|
||||
if (!dec) {
|
||||
fprintf(stderr, "Failed to find %s codec\n",
|
||||
av_get_media_type_string(type));
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
ret = avcodec_parameters_to_context(dec_ctx, st->codecpar);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to copy codec parameters to codec context\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Init the video decoder */
|
||||
av_dict_set(&opts, "flags2", "+export_mvs", 0);
|
||||
if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) {
|
||||
@@ -105,10 +103,6 @@ static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
|
||||
av_get_media_type_string(type));
|
||||
return ret;
|
||||
}
|
||||
|
||||
video_stream_idx = stream_idx;
|
||||
video_stream = fmt_ctx->streams[video_stream_idx];
|
||||
video_dec_ctx = dec_ctx;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -136,7 +130,10 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
open_codec_context(fmt_ctx, AVMEDIA_TYPE_VIDEO);
|
||||
if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
|
||||
video_stream = fmt_ctx->streams[video_stream_idx];
|
||||
video_dec_ctx = video_stream->codec;
|
||||
}
|
||||
|
||||
av_dump_format(fmt_ctx, 0, src_filename, 0);
|
||||
|
||||
@@ -181,7 +178,7 @@ int main(int argc, char **argv)
|
||||
} while (got_frame);
|
||||
|
||||
end:
|
||||
avcodec_free_context(&video_dec_ctx);
|
||||
avcodec_close(video_dec_ctx);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
av_frame_free(&frame);
|
||||
return ret < 0;
|
||||
|
||||
@@ -69,12 +69,7 @@ static int open_input_file(const char *filename)
|
||||
return ret;
|
||||
}
|
||||
audio_stream_index = ret;
|
||||
|
||||
/* create decoding context */
|
||||
dec_ctx = avcodec_alloc_context3(dec);
|
||||
if (!dec_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[audio_stream_index]->codecpar);
|
||||
dec_ctx = fmt_ctx->streams[audio_stream_index]->codec;
|
||||
av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);
|
||||
|
||||
/* init the audio decoder */
|
||||
@@ -216,9 +211,10 @@ static void print_frame(const AVFrame *frame)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
AVPacket packet;
|
||||
AVPacket packet0, packet;
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
AVFrame *filt_frame = av_frame_alloc();
|
||||
int got_frame;
|
||||
|
||||
if (!frame || !filt_frame) {
|
||||
perror("Could not allocate frame");
|
||||
@@ -238,52 +234,54 @@ int main(int argc, char **argv)
|
||||
goto end;
|
||||
|
||||
/* read all packets */
|
||||
packet0.data = NULL;
|
||||
packet.data = NULL;
|
||||
while (1) {
|
||||
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
|
||||
break;
|
||||
if (!packet0.data) {
|
||||
if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
|
||||
break;
|
||||
packet0 = packet;
|
||||
}
|
||||
|
||||
if (packet.stream_index == audio_stream_index) {
|
||||
ret = avcodec_send_packet(dec_ctx, &packet);
|
||||
got_frame = 0;
|
||||
ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, &packet);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
|
||||
break;
|
||||
av_log(NULL, AV_LOG_ERROR, "Error decoding audio\n");
|
||||
continue;
|
||||
}
|
||||
packet.size -= ret;
|
||||
packet.data += ret;
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
if (got_frame) {
|
||||
/* push the audio data from decoded frame into the filtergraph */
|
||||
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, 0) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n");
|
||||
break;
|
||||
} else if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
/* push the audio data from decoded frame into the filtergraph */
|
||||
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n");
|
||||
/* pull filtered audio from the filtergraph */
|
||||
while (1) {
|
||||
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
}
|
||||
|
||||
/* pull filtered audio from the filtergraph */
|
||||
while (1) {
|
||||
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
print_frame(filt_frame);
|
||||
av_frame_unref(filt_frame);
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
print_frame(filt_frame);
|
||||
av_frame_unref(filt_frame);
|
||||
}
|
||||
}
|
||||
|
||||
if (packet.size <= 0)
|
||||
av_packet_unref(&packet0);
|
||||
} else {
|
||||
/* discard non-wanted packets */
|
||||
av_packet_unref(&packet0);
|
||||
}
|
||||
av_packet_unref(&packet);
|
||||
}
|
||||
end:
|
||||
avfilter_graph_free(&filter_graph);
|
||||
avcodec_free_context(&dec_ctx);
|
||||
avcodec_close(dec_ctx);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&filt_frame);
|
||||
|
||||
@@ -72,12 +72,7 @@ static int open_input_file(const char *filename)
|
||||
return ret;
|
||||
}
|
||||
video_stream_index = ret;
|
||||
|
||||
/* create decoding context */
|
||||
dec_ctx = avcodec_alloc_context3(dec);
|
||||
if (!dec_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[video_stream_index]->codecpar);
|
||||
dec_ctx = fmt_ctx->streams[video_stream_index]->codec;
|
||||
av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);
|
||||
|
||||
/* init the video decoder */
|
||||
@@ -213,6 +208,7 @@ int main(int argc, char **argv)
|
||||
AVPacket packet;
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
AVFrame *filt_frame = av_frame_alloc();
|
||||
int got_frame;
|
||||
|
||||
if (!frame || !filt_frame) {
|
||||
perror("Could not allocate frame");
|
||||
@@ -237,49 +233,40 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
if (packet.stream_index == video_stream_index) {
|
||||
ret = avcodec_send_packet(dec_ctx, &packet);
|
||||
got_frame = 0;
|
||||
ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, &packet);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
|
||||
av_log(NULL, AV_LOG_ERROR, "Error decoding video\n");
|
||||
break;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
if (got_frame) {
|
||||
frame->pts = av_frame_get_best_effort_timestamp(frame);
|
||||
|
||||
/* push the decoded frame into the filtergraph */
|
||||
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
|
||||
break;
|
||||
} else if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
frame->pts = av_frame_get_best_effort_timestamp(frame);
|
||||
|
||||
/* push the decoded frame into the filtergraph */
|
||||
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
|
||||
/* pull filtered frames from the filtergraph */
|
||||
while (1) {
|
||||
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
}
|
||||
|
||||
/* pull filtered frames from the filtergraph */
|
||||
while (1) {
|
||||
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
|
||||
av_frame_unref(filt_frame);
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
|
||||
av_frame_unref(filt_frame);
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
}
|
||||
av_packet_unref(&packet);
|
||||
}
|
||||
end:
|
||||
avfilter_graph_free(&filter_graph);
|
||||
avcodec_free_context(&dec_ctx);
|
||||
avcodec_close(dec_ctx);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&filt_frame);
|
||||
|
||||
@@ -45,7 +45,6 @@ static void process_client(AVIOContext *client, const char *in_uri)
|
||||
// may return empty string.
|
||||
if (resource && strlen(resource))
|
||||
break;
|
||||
av_freep(&resource);
|
||||
}
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
@@ -94,7 +93,6 @@ end:
|
||||
avio_close(client);
|
||||
fprintf(stderr, "Closing input\n");
|
||||
avio_close(input);
|
||||
av_freep(&resource);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
||||
@@ -335,15 +335,15 @@ static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
/* convert to destination format */
|
||||
ret = swr_convert(ost->swr_ctx,
|
||||
ost->frame->data, dst_nb_samples,
|
||||
(const uint8_t **)frame->data, frame->nb_samples);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while converting\n");
|
||||
exit(1);
|
||||
}
|
||||
frame = ost->frame;
|
||||
/* convert to destination format */
|
||||
ret = swr_convert(ost->swr_ctx,
|
||||
ost->frame->data, dst_nb_samples,
|
||||
(const uint8_t **)frame->data, frame->nb_samples);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while converting\n");
|
||||
exit(1);
|
||||
}
|
||||
frame = ost->frame;
|
||||
|
||||
frame->pts = av_rescale_q(ost->samples_count, (AVRational){1, c->sample_rate}, c->time_base);
|
||||
ost->samples_count += dst_nb_samples;
|
||||
@@ -440,7 +440,15 @@ static void open_video(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, A
|
||||
static void fill_yuv_image(AVFrame *pict, int frame_index,
|
||||
int width, int height)
|
||||
{
|
||||
int x, y, i;
|
||||
int x, y, i, ret;
|
||||
|
||||
/* when we pass a frame to the encoder, it may keep a reference to it
|
||||
* internally;
|
||||
* make sure we do not overwrite it here
|
||||
*/
|
||||
ret = av_frame_make_writable(pict);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
i = frame_index;
|
||||
|
||||
@@ -467,11 +475,6 @@ static AVFrame *get_video_frame(OutputStream *ost)
|
||||
STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
|
||||
return NULL;
|
||||
|
||||
/* when we pass a frame to the encoder, it may keep a reference to it
|
||||
* internally; make sure we do not overwrite it here */
|
||||
if (av_frame_make_writable(ost->frame) < 0)
|
||||
exit(1);
|
||||
|
||||
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
|
||||
/* as we only generate a YUV420P picture, we must convert it
|
||||
* to the codec pixel format if needed */
|
||||
|
||||
@@ -50,9 +50,6 @@ int main(int argc, char **argv)
|
||||
AVPacket pkt;
|
||||
const char *in_filename, *out_filename;
|
||||
int ret, i;
|
||||
int stream_index = 0;
|
||||
int *stream_mapping = NULL;
|
||||
int stream_mapping_size = 0;
|
||||
|
||||
if (argc < 3) {
|
||||
printf("usage: %s input output\n"
|
||||
@@ -86,42 +83,25 @@ int main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
stream_mapping_size = ifmt_ctx->nb_streams;
|
||||
stream_mapping = av_mallocz_array(stream_mapping_size, sizeof(*stream_mapping));
|
||||
if (!stream_mapping) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ofmt = ofmt_ctx->oformat;
|
||||
|
||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||
AVStream *out_stream;
|
||||
AVStream *in_stream = ifmt_ctx->streams[i];
|
||||
AVCodecParameters *in_codecpar = in_stream->codecpar;
|
||||
|
||||
if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
|
||||
in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
|
||||
in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
|
||||
stream_mapping[i] = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
stream_mapping[i] = stream_index++;
|
||||
|
||||
out_stream = avformat_new_stream(ofmt_ctx, NULL);
|
||||
AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
|
||||
if (!out_stream) {
|
||||
fprintf(stderr, "Failed allocating output stream\n");
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar);
|
||||
ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to copy codec parameters\n");
|
||||
fprintf(stderr, "Failed to copy context from input to output stream codec context\n");
|
||||
goto end;
|
||||
}
|
||||
out_stream->codecpar->codec_tag = 0;
|
||||
out_stream->codec->codec_tag = 0;
|
||||
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
}
|
||||
av_dump_format(ofmt_ctx, 0, out_filename, 1);
|
||||
|
||||
@@ -147,14 +127,8 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
in_stream = ifmt_ctx->streams[pkt.stream_index];
|
||||
if (pkt.stream_index >= stream_mapping_size ||
|
||||
stream_mapping[pkt.stream_index] < 0) {
|
||||
av_packet_unref(&pkt);
|
||||
continue;
|
||||
}
|
||||
|
||||
pkt.stream_index = stream_mapping[pkt.stream_index];
|
||||
out_stream = ofmt_ctx->streams[pkt.stream_index];
|
||||
|
||||
log_packet(ifmt_ctx, &pkt, "in");
|
||||
|
||||
/* copy packet */
|
||||
@@ -182,8 +156,6 @@ end:
|
||||
avio_closep(&ofmt_ctx->pb);
|
||||
avformat_free_context(ofmt_ctx);
|
||||
|
||||
av_freep(&stream_mapping);
|
||||
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
return 1;
|
||||
|
||||
@@ -45,6 +45,18 @@
|
||||
/** The number of output channels */
|
||||
#define OUTPUT_CHANNELS 2
|
||||
|
||||
/**
|
||||
* Convert an error code into a text message.
|
||||
* @param error Error code to be converted
|
||||
* @return Corresponding error text (not thread-safe)
|
||||
*/
|
||||
static const char *get_error_text(const int error)
|
||||
{
|
||||
static char error_buffer[255];
|
||||
av_strerror(error, error_buffer, sizeof(error_buffer));
|
||||
return error_buffer;
|
||||
}
|
||||
|
||||
/** Open an input file and the required decoder. */
|
||||
static int open_input_file(const char *filename,
|
||||
AVFormatContext **input_format_context,
|
||||
@@ -58,7 +70,7 @@ static int open_input_file(const char *filename,
|
||||
if ((error = avformat_open_input(input_format_context, filename, NULL,
|
||||
NULL)) < 0) {
|
||||
fprintf(stderr, "Could not open input file '%s' (error '%s')\n",
|
||||
filename, av_err2str(error));
|
||||
filename, get_error_text(error));
|
||||
*input_format_context = NULL;
|
||||
return error;
|
||||
}
|
||||
@@ -66,7 +78,7 @@ static int open_input_file(const char *filename,
|
||||
/** Get information on the input file (number of streams etc.). */
|
||||
if ((error = avformat_find_stream_info(*input_format_context, NULL)) < 0) {
|
||||
fprintf(stderr, "Could not open find stream info (error '%s')\n",
|
||||
av_err2str(error));
|
||||
get_error_text(error));
|
||||
avformat_close_input(input_format_context);
|
||||
return error;
|
||||
}
|
||||
@@ -105,7 +117,7 @@ static int open_input_file(const char *filename,
|
||||
/** Open the decoder for the audio stream to use it later. */
|
||||
if ((error = avcodec_open2(avctx, input_codec, NULL)) < 0) {
|
||||
fprintf(stderr, "Could not open input codec (error '%s')\n",
|
||||
av_err2str(error));
|
||||
get_error_text(error));
|
||||
avcodec_free_context(&avctx);
|
||||
avformat_close_input(input_format_context);
|
||||
return error;
|
||||
@@ -137,7 +149,7 @@ static int open_output_file(const char *filename,
|
||||
if ((error = avio_open(&output_io_context, filename,
|
||||
AVIO_FLAG_WRITE)) < 0) {
|
||||
fprintf(stderr, "Could not open output file '%s' (error '%s')\n",
|
||||
filename, av_err2str(error));
|
||||
filename, get_error_text(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -207,7 +219,7 @@ static int open_output_file(const char *filename,
|
||||
/** Open the encoder for the audio stream to use it later. */
|
||||
if ((error = avcodec_open2(avctx, output_codec, NULL)) < 0) {
|
||||
fprintf(stderr, "Could not open output codec (error '%s')\n",
|
||||
av_err2str(error));
|
||||
get_error_text(error));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -313,7 +325,7 @@ static int write_output_file_header(AVFormatContext *output_format_context)
|
||||
int error;
|
||||
if ((error = avformat_write_header(output_format_context, NULL)) < 0) {
|
||||
fprintf(stderr, "Could not write output file header (error '%s')\n",
|
||||
av_err2str(error));
|
||||
get_error_text(error));
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
@@ -337,7 +349,7 @@ static int decode_audio_frame(AVFrame *frame,
|
||||
*finished = 1;
|
||||
else {
|
||||
fprintf(stderr, "Could not read frame (error '%s')\n",
|
||||
av_err2str(error));
|
||||
get_error_text(error));
|
||||
return error;
|
||||
}
|
||||
}
|
||||
@@ -351,7 +363,7 @@ static int decode_audio_frame(AVFrame *frame,
|
||||
if ((error = avcodec_decode_audio4(input_codec_context, frame,
|
||||
data_present, &input_packet)) < 0) {
|
||||
fprintf(stderr, "Could not decode frame (error '%s')\n",
|
||||
av_err2str(error));
|
||||
get_error_text(error));
|
||||
av_packet_unref(&input_packet);
|
||||
return error;
|
||||
}
|
||||
@@ -398,7 +410,7 @@ static int init_converted_samples(uint8_t ***converted_input_samples,
|
||||
output_codec_context->sample_fmt, 0)) < 0) {
|
||||
fprintf(stderr,
|
||||
"Could not allocate converted input samples (error '%s')\n",
|
||||
av_err2str(error));
|
||||
get_error_text(error));
|
||||
av_freep(&(*converted_input_samples)[0]);
|
||||
free(*converted_input_samples);
|
||||
return error;
|
||||
@@ -422,7 +434,7 @@ static int convert_samples(const uint8_t **input_data,
|
||||
converted_data, frame_size,
|
||||
input_data , frame_size)) < 0) {
|
||||
fprintf(stderr, "Could not convert input samples (error '%s')\n",
|
||||
av_err2str(error));
|
||||
get_error_text(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -554,8 +566,8 @@ static int init_output_frame(AVFrame **frame,
|
||||
* sure that the audio frame can hold as many samples as specified.
|
||||
*/
|
||||
if ((error = av_frame_get_buffer(*frame, 0)) < 0) {
|
||||
fprintf(stderr, "Could not allocate output frame samples (error '%s')\n",
|
||||
av_err2str(error));
|
||||
fprintf(stderr, "Could allocate output frame samples (error '%s')\n",
|
||||
get_error_text(error));
|
||||
av_frame_free(frame);
|
||||
return error;
|
||||
}
|
||||
@@ -590,7 +602,7 @@ static int encode_audio_frame(AVFrame *frame,
|
||||
if ((error = avcodec_encode_audio2(output_codec_context, &output_packet,
|
||||
frame, data_present)) < 0) {
|
||||
fprintf(stderr, "Could not encode frame (error '%s')\n",
|
||||
av_err2str(error));
|
||||
get_error_text(error));
|
||||
av_packet_unref(&output_packet);
|
||||
return error;
|
||||
}
|
||||
@@ -599,7 +611,7 @@ static int encode_audio_frame(AVFrame *frame,
|
||||
if (*data_present) {
|
||||
if ((error = av_write_frame(output_format_context, &output_packet)) < 0) {
|
||||
fprintf(stderr, "Could not write frame (error '%s')\n",
|
||||
av_err2str(error));
|
||||
get_error_text(error));
|
||||
av_packet_unref(&output_packet);
|
||||
return error;
|
||||
}
|
||||
@@ -659,7 +671,7 @@ static int write_output_file_trailer(AVFormatContext *output_format_context)
|
||||
int error;
|
||||
if ((error = av_write_trailer(output_format_context)) < 0) {
|
||||
fprintf(stderr, "Could not write output file trailer (error '%s')\n",
|
||||
av_err2str(error));
|
||||
get_error_text(error));
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -45,12 +45,6 @@ typedef struct FilteringContext {
|
||||
} FilteringContext;
|
||||
static FilteringContext *filter_ctx;
|
||||
|
||||
typedef struct StreamContext {
|
||||
AVCodecContext *dec_ctx;
|
||||
AVCodecContext *enc_ctx;
|
||||
} StreamContext;
|
||||
static StreamContext *stream_ctx;
|
||||
|
||||
static int open_input_file(const char *filename)
|
||||
{
|
||||
int ret;
|
||||
@@ -67,42 +61,22 @@ static int open_input_file(const char *filename)
|
||||
return ret;
|
||||
}
|
||||
|
||||
stream_ctx = av_mallocz_array(ifmt_ctx->nb_streams, sizeof(*stream_ctx));
|
||||
if (!stream_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||
AVStream *stream = ifmt_ctx->streams[i];
|
||||
AVCodec *dec = avcodec_find_decoder(stream->codecpar->codec_id);
|
||||
AVStream *stream;
|
||||
AVCodecContext *codec_ctx;
|
||||
if (!dec) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Failed to find decoder for stream #%u\n", i);
|
||||
return AVERROR_DECODER_NOT_FOUND;
|
||||
}
|
||||
codec_ctx = avcodec_alloc_context3(dec);
|
||||
if (!codec_ctx) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Failed to allocate the decoder context for stream #%u\n", i);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
ret = avcodec_parameters_to_context(codec_ctx, stream->codecpar);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Failed to copy decoder parameters to input decoder context "
|
||||
"for stream #%u\n", i);
|
||||
return ret;
|
||||
}
|
||||
stream = ifmt_ctx->streams[i];
|
||||
codec_ctx = stream->codec;
|
||||
/* Reencode video & audio and remux subtitles etc. */
|
||||
if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
|
||||
|| codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
codec_ctx->framerate = av_guess_frame_rate(ifmt_ctx, stream, NULL);
|
||||
/* Open decoder */
|
||||
ret = avcodec_open2(codec_ctx, dec, NULL);
|
||||
ret = avcodec_open2(codec_ctx,
|
||||
avcodec_find_decoder(codec_ctx->codec_id), NULL);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
stream_ctx[i].dec_ctx = codec_ctx;
|
||||
}
|
||||
|
||||
av_dump_format(ifmt_ctx, 0, filename, 0);
|
||||
@@ -134,7 +108,8 @@ static int open_output_file(const char *filename)
|
||||
}
|
||||
|
||||
in_stream = ifmt_ctx->streams[i];
|
||||
dec_ctx = stream_ctx[i].dec_ctx;
|
||||
dec_ctx = in_stream->codec;
|
||||
enc_ctx = out_stream->codec;
|
||||
|
||||
if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
|
||||
|| dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
@@ -144,11 +119,6 @@ static int open_output_file(const char *filename)
|
||||
av_log(NULL, AV_LOG_FATAL, "Necessary encoder not found\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
enc_ctx = avcodec_alloc_context3(encoder);
|
||||
if (!enc_ctx) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Failed to allocate the encoder context\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* In this example, we transcode to same properties (picture size,
|
||||
* sample rate etc.). These properties can be changed for output
|
||||
@@ -163,7 +133,7 @@ static int open_output_file(const char *filename)
|
||||
else
|
||||
enc_ctx->pix_fmt = dec_ctx->pix_fmt;
|
||||
/* video time_base can be set to whatever is handy and supported by encoder */
|
||||
enc_ctx->time_base = av_inv_q(dec_ctx->framerate);
|
||||
enc_ctx->time_base = dec_ctx->time_base;
|
||||
} else {
|
||||
enc_ctx->sample_rate = dec_ctx->sample_rate;
|
||||
enc_ctx->channel_layout = dec_ctx->channel_layout;
|
||||
@@ -179,29 +149,22 @@ static int open_output_file(const char *filename)
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i);
|
||||
return ret;
|
||||
}
|
||||
ret = avcodec_parameters_from_context(out_stream->codecpar, enc_ctx);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Failed to copy encoder parameters to output stream #%u\n", i);
|
||||
return ret;
|
||||
}
|
||||
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
out_stream->time_base = enc_ctx->time_base;
|
||||
stream_ctx[i].enc_ctx = enc_ctx;
|
||||
} else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed\n", i);
|
||||
return AVERROR_INVALIDDATA;
|
||||
} else {
|
||||
/* if this stream must be remuxed */
|
||||
ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar);
|
||||
ret = avcodec_copy_context(ofmt_ctx->streams[i]->codec,
|
||||
ifmt_ctx->streams[i]->codec);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Copying parameters for stream #%u failed\n", i);
|
||||
av_log(NULL, AV_LOG_ERROR, "Copying stream context failed\n");
|
||||
return ret;
|
||||
}
|
||||
out_stream->time_base = in_stream->time_base;
|
||||
}
|
||||
|
||||
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
}
|
||||
av_dump_format(ofmt_ctx, 0, filename, 1);
|
||||
|
||||
@@ -385,17 +348,17 @@ static int init_filters(void)
|
||||
filter_ctx[i].buffersrc_ctx = NULL;
|
||||
filter_ctx[i].buffersink_ctx = NULL;
|
||||
filter_ctx[i].filter_graph = NULL;
|
||||
if (!(ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO
|
||||
|| ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO))
|
||||
if (!(ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO
|
||||
|| ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
|
||||
continue;
|
||||
|
||||
|
||||
if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
if (ifmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
filter_spec = "null"; /* passthrough (dummy) filter for video */
|
||||
else
|
||||
filter_spec = "anull"; /* passthrough (dummy) filter for audio */
|
||||
ret = init_filter(&filter_ctx[i], stream_ctx[i].dec_ctx,
|
||||
stream_ctx[i].enc_ctx, filter_spec);
|
||||
ret = init_filter(&filter_ctx[i], ifmt_ctx->streams[i]->codec,
|
||||
ofmt_ctx->streams[i]->codec, filter_spec);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -407,7 +370,7 @@ static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, in
|
||||
int got_frame_local;
|
||||
AVPacket enc_pkt;
|
||||
int (*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) =
|
||||
(ifmt_ctx->streams[stream_index]->codecpar->codec_type ==
|
||||
(ifmt_ctx->streams[stream_index]->codec->codec_type ==
|
||||
AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2;
|
||||
|
||||
if (!got_frame)
|
||||
@@ -418,7 +381,7 @@ static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, in
|
||||
enc_pkt.data = NULL;
|
||||
enc_pkt.size = 0;
|
||||
av_init_packet(&enc_pkt);
|
||||
ret = enc_func(stream_ctx[stream_index].enc_ctx, &enc_pkt,
|
||||
ret = enc_func(ofmt_ctx->streams[stream_index]->codec, &enc_pkt,
|
||||
filt_frame, got_frame);
|
||||
av_frame_free(&filt_frame);
|
||||
if (ret < 0)
|
||||
@@ -429,7 +392,7 @@ static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, in
|
||||
/* prepare packet for muxing */
|
||||
enc_pkt.stream_index = stream_index;
|
||||
av_packet_rescale_ts(&enc_pkt,
|
||||
stream_ctx[stream_index].enc_ctx->time_base,
|
||||
ofmt_ctx->streams[stream_index]->codec->time_base,
|
||||
ofmt_ctx->streams[stream_index]->time_base);
|
||||
|
||||
av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
|
||||
@@ -487,7 +450,7 @@ static int flush_encoder(unsigned int stream_index)
|
||||
int ret;
|
||||
int got_frame;
|
||||
|
||||
if (!(stream_ctx[stream_index].enc_ctx->codec->capabilities &
|
||||
if (!(ofmt_ctx->streams[stream_index]->codec->codec->capabilities &
|
||||
AV_CODEC_CAP_DELAY))
|
||||
return 0;
|
||||
|
||||
@@ -533,7 +496,7 @@ int main(int argc, char **argv)
|
||||
if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0)
|
||||
break;
|
||||
stream_index = packet.stream_index;
|
||||
type = ifmt_ctx->streams[packet.stream_index]->codecpar->codec_type;
|
||||
type = ifmt_ctx->streams[packet.stream_index]->codec->codec_type;
|
||||
av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n",
|
||||
stream_index);
|
||||
|
||||
@@ -546,10 +509,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
av_packet_rescale_ts(&packet,
|
||||
ifmt_ctx->streams[stream_index]->time_base,
|
||||
stream_ctx[stream_index].dec_ctx->time_base);
|
||||
ifmt_ctx->streams[stream_index]->codec->time_base);
|
||||
dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
|
||||
avcodec_decode_audio4;
|
||||
ret = dec_func(stream_ctx[stream_index].dec_ctx, frame,
|
||||
ret = dec_func(ifmt_ctx->streams[stream_index]->codec, frame,
|
||||
&got_frame, &packet);
|
||||
if (ret < 0) {
|
||||
av_frame_free(&frame);
|
||||
@@ -603,14 +566,13 @@ end:
|
||||
av_packet_unref(&packet);
|
||||
av_frame_free(&frame);
|
||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||
avcodec_free_context(&stream_ctx[i].dec_ctx);
|
||||
if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && stream_ctx[i].enc_ctx)
|
||||
avcodec_free_context(&stream_ctx[i].enc_ctx);
|
||||
avcodec_close(ifmt_ctx->streams[i]->codec);
|
||||
if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && ofmt_ctx->streams[i]->codec)
|
||||
avcodec_close(ofmt_ctx->streams[i]->codec);
|
||||
if (filter_ctx && filter_ctx[i].filter_graph)
|
||||
avfilter_graph_free(&filter_ctx[i].filter_graph);
|
||||
}
|
||||
av_free(filter_ctx);
|
||||
av_free(stream_ctx);
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
|
||||
avio_closep(&ofmt_ctx->pb);
|
||||
|
||||
@@ -197,11 +197,6 @@ through @command{ssh}.
|
||||
|
||||
@item GEN
|
||||
Set to @samp{1} to generate the missing or mismatched references.
|
||||
|
||||
@item HWACCEL
|
||||
Specify which hardware acceleration to use while running regression tests,
|
||||
by default @samp{none} is used.
|
||||
|
||||
@end table
|
||||
|
||||
@section Examples
|
||||
|
||||
@@ -357,40 +357,6 @@ To set the language of the first audio stream:
|
||||
ffmpeg -i INPUT -metadata:s:a:0 language=eng OUTPUT
|
||||
@end example
|
||||
|
||||
@item -disposition[:stream_specifier] @var{value} (@emph{output,per-stream})
|
||||
Sets the disposition for a stream.
|
||||
|
||||
This option overrides the disposition copied from the input stream. It is also
|
||||
possible to delete the disposition by setting it to 0.
|
||||
|
||||
The following dispositions are recognized:
|
||||
@table @option
|
||||
@item default
|
||||
@item dub
|
||||
@item original
|
||||
@item comment
|
||||
@item lyrics
|
||||
@item karaoke
|
||||
@item forced
|
||||
@item hearing_impaired
|
||||
@item visual_impaired
|
||||
@item clean_effects
|
||||
@item captions
|
||||
@item descriptions
|
||||
@item metadata
|
||||
@end table
|
||||
|
||||
For example, to make the second audio stream the default stream:
|
||||
@example
|
||||
ffmpeg -i in.mkv -disposition:a:1 default out.mkv
|
||||
@end example
|
||||
|
||||
To make the second subtitle stream the default stream and remove the default
|
||||
disposition from the first subtitle stream:
|
||||
@example
|
||||
ffmpeg -i INPUT -disposition:s:0 0 -disposition:s:1 default OUTPUT
|
||||
@end example
|
||||
|
||||
@item -program [title=@var{title}:][program_num=@var{program_num}:]st=@var{stream}[:st=@var{stream}...] (@emph{output})
|
||||
|
||||
Creates a program with the specified @var{title}, @var{program_num} and adds the specified
|
||||
@@ -414,8 +380,7 @@ ffmpeg -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg
|
||||
@end example
|
||||
|
||||
@item -dframes @var{number} (@emph{output})
|
||||
Set the number of data frames to output. This is an obsolete alias for
|
||||
@code{-frames:d}, which you should use instead.
|
||||
Set the number of data frames to output. This is an alias for @code{-frames:d}.
|
||||
|
||||
@item -frames[:@var{stream_specifier}] @var{framecount} (@emph{output,per-stream})
|
||||
Stop writing to the stream after @var{framecount} frames.
|
||||
@@ -450,11 +415,6 @@ This option is similar to @option{-filter}, the only difference is that its
|
||||
argument is the name of the file from which a filtergraph description is to be
|
||||
read.
|
||||
|
||||
@item -filter_threads @var{nb_threads} (@emph{global})
|
||||
Defines how many threads are used to process a filter pipeline. Each pipeline
|
||||
will produce a thread pool with this many threads available for parallel processing.
|
||||
The default is the number of available CPUs.
|
||||
|
||||
@item -pre[:@var{stream_specifier}] @var{preset_name} (@emph{output,per-stream})
|
||||
Specify the preset for matching stream(s).
|
||||
|
||||
@@ -530,8 +490,7 @@ Disable automatically rotating video based on file metadata.
|
||||
|
||||
@table @option
|
||||
@item -vframes @var{number} (@emph{output})
|
||||
Set the number of video frames to output. This is an obsolete alias for
|
||||
@code{-frames:v}, which you should use instead.
|
||||
Set the number of video frames to output. This is an alias for @code{-frames:v}.
|
||||
@item -r[:@var{stream_specifier}] @var{fps} (@emph{input/output,per-stream})
|
||||
Set frame rate (Hz value, fraction or abbreviation).
|
||||
|
||||
@@ -638,16 +597,6 @@ Calculate PSNR of compressed frames.
|
||||
Dump video coding statistics to @file{vstats_HHMMSS.log}.
|
||||
@item -vstats_file @var{file}
|
||||
Dump video coding statistics to @var{file}.
|
||||
@item -vstats_version @var{file}
|
||||
Specifies which version of the vstats format to use. Default is 2.
|
||||
|
||||
version = 1 :
|
||||
|
||||
@code{frame= %5d q= %2.1f PSNR= %6.2f f_size= %6d s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s}
|
||||
|
||||
version > 1:
|
||||
|
||||
@code{out= %2d st= %2d frame= %5d q= %2.1f PSNR= %6.2f f_size= %6d s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s}
|
||||
@item -top[:@var{stream_specifier}] @var{n} (@emph{output,per-stream})
|
||||
top=1/bottom=0/auto=-1 field first
|
||||
@item -dc @var{precision}
|
||||
@@ -794,8 +743,7 @@ List all hardware acceleration methods supported in this build of ffmpeg.
|
||||
|
||||
@table @option
|
||||
@item -aframes @var{number} (@emph{output})
|
||||
Set the number of audio frames to output. This is an obsolete alias for
|
||||
@code{-frames:a}, which you should use instead.
|
||||
Set the number of audio frames to output. This is an alias for @code{-frames:a}.
|
||||
@item -ar[:@var{stream_specifier}] @var{freq} (@emph{input/output,per-stream})
|
||||
Set the audio sampling frequency. For output streams it is set by
|
||||
default to the frequency of the corresponding input stream. For input
|
||||
@@ -874,7 +822,7 @@ Set the size of the canvas used to render subtitles.
|
||||
@section Advanced options
|
||||
|
||||
@table @option
|
||||
@item -map [-]@var{input_file_id}[:@var{stream_specifier}][?][,@var{sync_file_id}[:@var{stream_specifier}]] | @var{[linklabel]} (@emph{output})
|
||||
@item -map [-]@var{input_file_id}[:@var{stream_specifier}][,@var{sync_file_id}[:@var{stream_specifier}]] | @var{[linklabel]} (@emph{output})
|
||||
|
||||
Designate one or more input streams as a source for the output file. Each input
|
||||
stream is identified by the input file index @var{input_file_id} and
|
||||
@@ -890,11 +838,6 @@ the source for output stream 1, etc.
|
||||
A @code{-} character before the stream identifier creates a "negative" mapping.
|
||||
It disables matching streams from already created mappings.
|
||||
|
||||
A trailing @code{?} after the stream index will allow the map to be
|
||||
optional: if the map matches no streams the map will be ignored instead
|
||||
of failing. Note the map will still fail if an invalid input file index
|
||||
is used; such as if the map refers to a non-existant input.
|
||||
|
||||
An alternative @var{[linklabel]} form will map outputs from complex filter
|
||||
graphs (see the @option{-filter_complex} option) to the output file.
|
||||
@var{linklabel} must correspond to a defined output link label in the graph.
|
||||
@@ -932,13 +875,6 @@ To map all the streams except the second audio, use negative mappings
|
||||
ffmpeg -i INPUT -map 0 -map -0:a:1 OUTPUT
|
||||
@end example
|
||||
|
||||
To map the video and audio streams from the first input, and using the
|
||||
trailing @code{?}, ignore the audio mapping if no audio streams exist in
|
||||
the first input:
|
||||
@example
|
||||
ffmpeg -i INPUT -map 0:v -map 0:a? OUTPUT
|
||||
@end example
|
||||
|
||||
To pick the English audio stream:
|
||||
@example
|
||||
ffmpeg -i INPUT -map 0:m:language:eng OUTPUT
|
||||
@@ -1265,11 +1201,6 @@ To generate 5 seconds of pure red video using lavfi @code{color} source:
|
||||
ffmpeg -filter_complex 'color=c=red' -t 5 out.mkv
|
||||
@end example
|
||||
|
||||
@item -filter_complex_threads @var{nb_threads} (@emph{global})
|
||||
Defines how many threads are used to process a filter_complex graph.
|
||||
Similar to filter_threads but used for @code{-filter_complex} graphs only.
|
||||
The default is the number of available CPUs.
|
||||
|
||||
@item -lavfi @var{filtergraph} (@emph{global})
|
||||
Define a complex filtergraph, i.e. one with arbitrary number of inputs and/or
|
||||
outputs. Equivalent to @option{-filter_complex}.
|
||||
@@ -1562,7 +1493,7 @@ to enable LAME support by passing @code{--enable-libmp3lame} to configure.
|
||||
The mapping is particularly useful for DVD transcoding
|
||||
to get the desired audio language.
|
||||
|
||||
NOTE: To see the supported input formats, use @code{ffmpeg -demuxers}.
|
||||
NOTE: To see the supported input formats, use @code{ffmpeg -formats}.
|
||||
|
||||
@item
|
||||
You can extract images from a video, or create a video from many images:
|
||||
@@ -1577,8 +1508,8 @@ output them in files named @file{foo-001.jpeg}, @file{foo-002.jpeg},
|
||||
etc. Images will be rescaled to fit the new WxH values.
|
||||
|
||||
If you want to extract just a limited number of frames, you can use the
|
||||
above command in combination with the @code{-frames:v} or @code{-t} option,
|
||||
or in combination with -ss to start extracting from a certain point in time.
|
||||
above command in combination with the -vframes or -t option, or in
|
||||
combination with -ss to start extracting from a certain point in time.
|
||||
|
||||
For creating a video from many images:
|
||||
@example
|
||||
|
||||
@@ -62,12 +62,6 @@ see @ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1)
|
||||
Seek by bytes.
|
||||
@item -nodisp
|
||||
Disable graphical display.
|
||||
@item -noborder
|
||||
Borderless window.
|
||||
@item -volume
|
||||
Set the startup volume. 0 means silence, 100 means no volume reduction or
|
||||
amplification. Negative values are treated as 0, values above 100 are treated
|
||||
as 100.
|
||||
@item -f @var{fmt}
|
||||
Force format.
|
||||
@item -window_title @var{title}
|
||||
|
||||
@@ -208,13 +208,6 @@ multimedia stream.
|
||||
The information for each single frame is printed within a dedicated
|
||||
section with name "FRAME" or "SUBTITLE".
|
||||
|
||||
@item -show_log @var{loglevel}
|
||||
Show logging information from the decoder about each frame according to
|
||||
the value set in @var{loglevel}, (see @code{-loglevel}). This option requires @code{-show_frames}.
|
||||
|
||||
The information for each log message is printed within a dedicated
|
||||
section with name "LOG".
|
||||
|
||||
@item -show_streams
|
||||
Show information about each media stream contained in the input
|
||||
multimedia stream.
|
||||
|
||||
@@ -83,7 +83,6 @@
|
||||
<xsd:complexType name="frameType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xsd:element name="logs" type="ffprobe:logsType" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="side_data_list" type="ffprobe:frameSideDataListType" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
|
||||
@@ -122,20 +121,6 @@
|
||||
<xsd:attribute name="repeat_pict" type="xsd:int" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="logsType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="log" type="ffprobe:logType" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="logType">
|
||||
<xsd:attribute name="context" type="xsd:string"/>
|
||||
<xsd:attribute name="level" type="xsd:int" />
|
||||
<xsd:attribute name="category" type="xsd:int" />
|
||||
<xsd:attribute name="parent_context" type="xsd:string"/>
|
||||
<xsd:attribute name="parent_category" type="xsd:int" />
|
||||
<xsd:attribute name="message" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="frameSideDataListType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="side_data" type="ffprobe:frameSideDataType" minOccurs="1" maxOccurs="unbounded"/>
|
||||
|
||||
@@ -110,12 +110,6 @@ Show version.
|
||||
@item -formats
|
||||
Show available formats (including devices).
|
||||
|
||||
@item -demuxers
|
||||
Show available demuxers.
|
||||
|
||||
@item -muxers
|
||||
Show available muxers.
|
||||
|
||||
@item -devices
|
||||
Show available devices.
|
||||
|
||||
|
||||
484
doc/filters.texi
484
doc/filters.texi
@@ -306,8 +306,6 @@ smartblur = enable='between(t,10,3*60)',
|
||||
curves = enable='gte(t,3)' : preset=cross_process
|
||||
@end example
|
||||
|
||||
See @code{ffmpeg -filters} to view which filters have timeline support.
|
||||
|
||||
@c man end FILTERGRAPH DESCRIPTION
|
||||
|
||||
@chapter Audio Filters
|
||||
@@ -1413,9 +1411,7 @@ The filter accepts the syntax
|
||||
[@var{sample_rate}:]@var{resampler_options}, where @var{sample_rate}
|
||||
expresses a sample rate and @var{resampler_options} is a list of
|
||||
@var{key}=@var{value} pairs, separated by ":". See the
|
||||
@ref{Resampler Options,,the "Resampler Options" section in the
|
||||
ffmpeg-resampler(1) manual,ffmpeg-resampler}
|
||||
for the complete list of supported options.
|
||||
ffmpeg-resampler manual for the complete list of supported options.
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@@ -1642,6 +1638,39 @@ Number of occasions (not the number of samples) that the signal attained either
|
||||
Overall bit depth of audio. Number of bits used for each sample.
|
||||
@end table
|
||||
|
||||
@section asyncts
|
||||
|
||||
Synchronize audio data with timestamps by squeezing/stretching it and/or
|
||||
dropping samples/adding silence when needed.
|
||||
|
||||
This filter is not built by default, please use @ref{aresample} to do squeezing/stretching.
|
||||
|
||||
It accepts the following parameters:
|
||||
@table @option
|
||||
|
||||
@item compensate
|
||||
Enable stretching/squeezing the data to make it match the timestamps. Disabled
|
||||
by default. When disabled, time gaps are covered with silence.
|
||||
|
||||
@item min_delta
|
||||
The minimum difference between timestamps and audio data (in seconds) to trigger
|
||||
adding/dropping samples. The default value is 0.1. If you get an imperfect
|
||||
sync with this filter, try setting this parameter to 0.
|
||||
|
||||
@item max_comp
|
||||
The maximum compensation in samples per second. Only relevant with compensate=1.
|
||||
The default value is 500.
|
||||
|
||||
@item first_pts
|
||||
Assume that the first PTS should be this value. The time base is 1 / sample
|
||||
rate. This allows for padding/trimming at the start of the stream. By default,
|
||||
no assumption is made about the first frame's expected PTS, so no padding or
|
||||
trimming is done. For example, this could be set to 0 to pad the beginning with
|
||||
silence if an audio stream starts after the video stream or to trim any samples
|
||||
with a negative PTS due to encoder delay.
|
||||
|
||||
@end table
|
||||
|
||||
@section atempo
|
||||
|
||||
Adjust audio tempo.
|
||||
@@ -1876,6 +1905,9 @@ Remap input channels to new locations.
|
||||
|
||||
It accepts the following parameters:
|
||||
@table @option
|
||||
@item channel_layout
|
||||
The channel layout of the output stream.
|
||||
|
||||
@item map
|
||||
Map channels from input to output. The argument is a '|'-separated list of
|
||||
mappings, each in the @code{@var{in_channel}-@var{out_channel}} or
|
||||
@@ -1884,9 +1916,6 @@ channel (e.g. FL for front left) or its index in the input channel layout.
|
||||
@var{out_channel} is the name of the output channel or its index in the output
|
||||
channel layout. If @var{out_channel} is not given then it is implicitly an
|
||||
index, starting with zero and increasing by one for each mapping.
|
||||
|
||||
@item channel_layout
|
||||
The channel layout of the output stream.
|
||||
@end table
|
||||
|
||||
If no mapping is present, the filter will implicitly map input channels to
|
||||
@@ -2556,10 +2585,6 @@ Set file for dumping, suitable for gnuplot.
|
||||
@item dumpscale
|
||||
Set scale for dumpfile. Acceptable values are same with scale option.
|
||||
Default is linlog.
|
||||
|
||||
@item fft2
|
||||
Enable 2-channel convolution using complex FFT. This improves speed significantly.
|
||||
Default is disabled.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
@@ -2892,6 +2917,9 @@ EBU R128 loudness normalization. Includes both dynamic and linear normalization
|
||||
Support for both single pass (livestreams, files) and double pass (files) modes.
|
||||
This algorithm can target IL, LRA, and maximum true peak.
|
||||
|
||||
To enable compilation of this filter you need to configure FFmpeg with
|
||||
@code{--enable-libebur128}.
|
||||
|
||||
The filter accepts the following options:
|
||||
|
||||
@table @option
|
||||
@@ -2997,7 +3025,7 @@ output channel layout or number of channels
|
||||
|
||||
@item outdef
|
||||
output channel specification, of the form:
|
||||
"@var{out_name}=[@var{gain}*]@var{in_name}[(+-)[@var{gain}*]@var{in_name}...]"
|
||||
"@var{out_name}=[@var{gain}*]@var{in_name}[+[@var{gain}*]@var{in_name}...]"
|
||||
|
||||
@item out_name
|
||||
output channel to define, either a channel name (FL, FR, etc.) or a channel
|
||||
@@ -3482,10 +3510,10 @@ sofalizer=sofa=/path/to/ClubFritz12.sofa:type=freq:radius=2:rotation=5
|
||||
@end example
|
||||
|
||||
@item
|
||||
Similar as above but with custom speaker positions for front left, front right, back left and back right
|
||||
Similar as above but with custom speaker positions for front left, front right, rear left and rear right
|
||||
and also with custom gain:
|
||||
@example
|
||||
"sofalizer=sofa=/path/to/ClubFritz6.sofa:type=freq:radius=2:speakers=FL 45|FR 315|BL 135|BR 225:gain=28"
|
||||
"sofalizer=sofa=/path/to/ClubFritz6.sofa:type=freq:radius=2:speakers=FL 45|FR 315|RL 135|RR 225:gain=28"
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@@ -4510,10 +4538,6 @@ the position in the file if known or -1 and the timestamp in seconds.
|
||||
In order to display the output lines, you need to set the loglevel at
|
||||
least to the AV_LOG_INFO value.
|
||||
|
||||
This filter exports frame metadata @code{lavfi.blackframe.pblack}.
|
||||
The value represents the percentage of pixels in the picture that
|
||||
are below the threshold value.
|
||||
|
||||
It accepts the following parameters:
|
||||
|
||||
@table @option
|
||||
@@ -5227,24 +5251,15 @@ The accepted values are:
|
||||
@item bt709
|
||||
BT.709
|
||||
|
||||
@item fcc
|
||||
FCC
|
||||
|
||||
@item bt601
|
||||
BT.601
|
||||
|
||||
@item bt470
|
||||
BT.470
|
||||
|
||||
@item bt470bg
|
||||
BT.470BG
|
||||
|
||||
@item smpte170m
|
||||
SMPTE-170M
|
||||
|
||||
@item smpte240m
|
||||
SMPTE-240M
|
||||
|
||||
@item fcc
|
||||
FCC
|
||||
|
||||
@item bt2020
|
||||
BT.2020
|
||||
@end table
|
||||
@@ -5258,7 +5273,6 @@ colormatrix=bt601:smpte240m
|
||||
@section colorspace
|
||||
|
||||
Convert colorspace, transfer characteristics or color primaries.
|
||||
Input video needs to have an even size.
|
||||
|
||||
The filter accepts the following options:
|
||||
|
||||
@@ -5316,9 +5330,6 @@ SMPTE-170M or BT.601-6 525
|
||||
@item smpte240m
|
||||
SMPTE-240M
|
||||
|
||||
@item ycgco
|
||||
YCgCo
|
||||
|
||||
@item bt2020ncl
|
||||
BT.2020 with non-constant luminance
|
||||
|
||||
@@ -5333,12 +5344,6 @@ The accepted values are:
|
||||
@item bt709
|
||||
BT.709
|
||||
|
||||
@item bt470m
|
||||
BT.470M
|
||||
|
||||
@item bt470bg
|
||||
BT.470BG
|
||||
|
||||
@item gamma22
|
||||
Constant gamma of 2.2
|
||||
|
||||
@@ -5351,18 +5356,6 @@ SMPTE-170M, BT.601-6 625 or BT.601-6 525
|
||||
@item smpte240m
|
||||
SMPTE-240M
|
||||
|
||||
@item srgb
|
||||
SRGB
|
||||
|
||||
@item iec61966-2-1
|
||||
iec61966-2-1
|
||||
|
||||
@item iec61966-2-4
|
||||
iec61966-2-4
|
||||
|
||||
@item xvycc
|
||||
xvycc
|
||||
|
||||
@item bt2020-10
|
||||
BT.2020 for 10-bits content
|
||||
|
||||
@@ -5392,15 +5385,6 @@ SMPTE-170M or BT.601-6 525
|
||||
@item smpte240m
|
||||
SMPTE-240M
|
||||
|
||||
@item film
|
||||
film
|
||||
|
||||
@item smpte431
|
||||
SMPTE-431
|
||||
|
||||
@item smpte432
|
||||
SMPTE-432
|
||||
|
||||
@item bt2020
|
||||
BT.2020
|
||||
|
||||
@@ -5412,15 +5396,9 @@ Specify output color range.
|
||||
|
||||
The accepted values are:
|
||||
@table @samp
|
||||
@item tv
|
||||
TV (restricted) range
|
||||
|
||||
@item mpeg
|
||||
MPEG (restricted) range
|
||||
|
||||
@item pc
|
||||
PC (full) range
|
||||
|
||||
@item jpeg
|
||||
JPEG (full) range
|
||||
|
||||
@@ -6183,16 +6161,11 @@ absolute value will be picked. For example direction 0, -PI or -2*PI radians
|
||||
will pick only pixels on same row and -PI/2 will pick only pixels on same
|
||||
column.
|
||||
|
||||
@item blur, b
|
||||
@item blur
|
||||
If enabled, current pixel is compared with average value of all four
|
||||
surrounding pixels. The default is enabled. If disabled current pixel is
|
||||
compared with all four surrounding pixels. The pixel is considered banded
|
||||
if only all four differences with surrounding pixels are less than threshold.
|
||||
|
||||
@item coupling, c
|
||||
If enabled, current pixel is changed if and only if all pixel components are banded,
|
||||
e.g. banding detection threshold is triggered for all color components.
|
||||
The default is disabled.
|
||||
@end table
|
||||
|
||||
@anchor{decimate}
|
||||
@@ -6730,10 +6703,6 @@ option, check the "Color" section in the ffmpeg-utils manual.
|
||||
|
||||
The default value of @var{boxcolor} is "white".
|
||||
|
||||
@item line_spacing
|
||||
Set the line spacing in pixels of the border to be drawn around the box using @var{box}.
|
||||
The default value of @var{line_spacing} is 0.
|
||||
|
||||
@item borderw
|
||||
Set the width of the border to be drawn around the text using @var{bordercolor}.
|
||||
The default value of @var{borderw} is 0.
|
||||
@@ -6750,12 +6719,6 @@ Select how the @var{text} is expanded. Can be either @code{none},
|
||||
@code{normal} (default). See the @ref{drawtext_expansion, Text expansion} section
|
||||
below for details.
|
||||
|
||||
@item basetime
|
||||
Set a start time for the count. Value is in microseconds. Only applied
|
||||
in the deprecated strftime expansion mode. To emulate in normal expansion
|
||||
mode use the @code{pts} function, supplying the start time (in seconds)
|
||||
as the second argument.
|
||||
|
||||
@item fix_bounds
|
||||
If true, check and fix text coords to avoid clipping.
|
||||
|
||||
@@ -6777,6 +6740,9 @@ The font family to be used for drawing text. By default Sans.
|
||||
The font file to be used for drawing text. The path must be included.
|
||||
This parameter is mandatory if the fontconfig support is disabled.
|
||||
|
||||
@item draw
|
||||
This option does not exist, please see the timeline system
|
||||
|
||||
@item alpha
|
||||
Draw the text applying alpha blending. The value can
|
||||
be a number between 0.0 and 1.0.
|
||||
@@ -6850,10 +6816,6 @@ option must be specified.
|
||||
@item timecode_rate, rate, r
|
||||
Set the timecode frame rate (timecode only).
|
||||
|
||||
@item tc24hmax
|
||||
If set to 1, the output of the timecode option will wrap around at 24 hours.
|
||||
Default is 0 (disabled).
|
||||
|
||||
@item text
|
||||
The text string to be drawn. The text must be a sequence of UTF-8
|
||||
encoded characters.
|
||||
@@ -7131,14 +7093,6 @@ FOD=5 # fade out duration
|
||||
ffplay -f lavfi "color,drawtext=text=TEST:fontsize=50:fontfile=FreeSerif.ttf:fontcolor_expr=ff0000%@{eif\\\\: clip(255*(1*between(t\\, $DS + $FID\\, $DE - $FOD) + ((t - $DS)/$FID)*between(t\\, $DS\\, $DS + $FID) + (-(t - $DE)/$FOD)*between(t\\, $DE - $FOD\\, $DE) )\\, 0\\, 255) \\\\: x\\\\: 2 @}"
|
||||
@end example
|
||||
|
||||
@item
|
||||
Horizontally align multiple separate texts. Note that @option{max_glyph_a}
|
||||
and the @option{fontsize} value are included in the @option{y} offset.
|
||||
@example
|
||||
drawtext=fontfile=FreeSans.ttf:text=DOG:fontsize=24:x=10:y=20+24-max_glyph_a,
|
||||
drawtext=fontfile=FreeSans.ttf:text=cow:fontsize=24:x=80:y=20+24-max_glyph_a
|
||||
@end example
|
||||
|
||||
@end itemize
|
||||
|
||||
For more information about libfreetype, check:
|
||||
@@ -8263,7 +8217,7 @@ It accepts the following parameters:
|
||||
@item filter_name
|
||||
The name of the frei0r effect to load. If the environment variable
|
||||
@env{FREI0R_PATH} is defined, the frei0r effect is searched for in each of the
|
||||
directories specified by the colon-separated list in @env{FREIOR_PATH}.
|
||||
directories specified by the colon-separated list in @env{FREI0R_PATH}.
|
||||
Otherwise, the standard frei0r paths are searched, in this order:
|
||||
@file{HOME/.frei0r-1/lib/}, @file{/usr/local/lib/frei0r-1/},
|
||||
@file{/usr/lib/frei0r-1/}.
|
||||
@@ -9630,25 +9584,6 @@ Macroblock size. Default @code{16}.
|
||||
Search parameter. Default @code{7}.
|
||||
@end table
|
||||
|
||||
@section midequalizer
|
||||
|
||||
Apply Midway Image Equalization effect using two video streams.
|
||||
|
||||
Midway Image Equalization adjusts a pair of images to have the same
|
||||
histogram, while maintaining their dynamics as much as possible. It's
|
||||
useful for e.g. matching exposures from a pair of stereo cameras.
|
||||
|
||||
This filter has two inputs and one output, which must be of same pixel format, but
|
||||
may be of different sizes. The output of filter is first input adjusted with
|
||||
midway histogram of both inputs.
|
||||
|
||||
This filter accepts the following option:
|
||||
|
||||
@table @option
|
||||
@item planes
|
||||
Set which planes to process. Default is @code{15}, which is all available planes.
|
||||
@end table
|
||||
|
||||
@section minterpolate
|
||||
|
||||
Convert the video to specified frame rate using motion interpolation.
|
||||
@@ -9719,7 +9654,7 @@ Macroblock size. Default @code{16}.
|
||||
@item search_param
|
||||
Motion estimation search parameter. Default @code{32}.
|
||||
|
||||
@item vsbmc
|
||||
@item vsmbc
|
||||
Enable variable-size block motion compensation. Motion estimation is applied with smaller block sizes at object boundaries in order to make the them less blur. Default is @code{0} (disabled).
|
||||
@end table
|
||||
@end table
|
||||
@@ -10207,10 +10142,7 @@ force YUV422 output
|
||||
force YUV444 output
|
||||
|
||||
@item rgb
|
||||
force packed RGB output
|
||||
|
||||
@item gbrp
|
||||
force planar RGB output
|
||||
force RGB output
|
||||
@end table
|
||||
|
||||
Default value is @samp{yuv420}.
|
||||
@@ -10435,24 +10367,6 @@ Specify the color of the padded area. For the syntax of this option,
|
||||
check the "Color" section in the ffmpeg-utils manual.
|
||||
|
||||
The default value of @var{color} is "black".
|
||||
|
||||
@item eval
|
||||
Specify when to evaluate @var{width}, @var{height}, @var{x} and @var{y} expression.
|
||||
|
||||
It accepts the following values:
|
||||
|
||||
@table @samp
|
||||
@item init
|
||||
Only evaluate expressions once during the filter initialization or when
|
||||
a command is processed.
|
||||
|
||||
@item frame
|
||||
Evaluate expressions for each incoming frame.
|
||||
|
||||
@end table
|
||||
|
||||
Default value is @samp{init}.
|
||||
|
||||
@end table
|
||||
|
||||
The value for the @var{width}, @var{height}, @var{x}, and @var{y}
|
||||
@@ -11027,12 +10941,6 @@ Set medium thresholding (good results, default).
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@section premultiply
|
||||
Apply alpha premultiply effect to input video stream using first plane
|
||||
of second stream as alpha.
|
||||
|
||||
Both streams must have same dimensions and same pixel format.
|
||||
|
||||
@section prewitt
|
||||
Apply prewitt operator to input video stream.
|
||||
|
||||
@@ -11262,76 +11170,6 @@ less than @code{0}, the filter will try to use a good random seed on a
|
||||
best effort basis.
|
||||
@end table
|
||||
|
||||
@section readeia608
|
||||
|
||||
Read closed captioning (EIA-608) information from the top lines of a video frame.
|
||||
|
||||
This filter adds frame metadata for @code{lavfi.readeia608.X.cc} and
|
||||
@code{lavfi.readeia608.X.line}, where @code{X} is the number of the identified line
|
||||
with EIA-608 data (starting from 0). A description of each metadata value follows:
|
||||
|
||||
@table @option
|
||||
@item lavfi.readeia608.X.cc
|
||||
The two bytes stored as EIA-608 data (printed in hexadecimal).
|
||||
|
||||
@item lavfi.readeia608.X.line
|
||||
The number of the line on which the EIA-608 data was identified and read.
|
||||
@end table
|
||||
|
||||
This filter accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item scan_min
|
||||
Set the line to start scanning for EIA-608 data. Default is @code{0}.
|
||||
|
||||
@item scan_max
|
||||
Set the line to end scanning for EIA-608 data. Default is @code{29}.
|
||||
|
||||
@item mac
|
||||
Set minimal acceptable amplitude change for sync codes detection.
|
||||
Default is @code{0.2}. Allowed range is @code{[0.001 - 1]}.
|
||||
|
||||
@item spw
|
||||
Set the ratio of width reserved for sync code detection.
|
||||
Default is @code{0.27}. Allowed range is @code{[0.01 - 0.7]}.
|
||||
|
||||
@item mhd
|
||||
Set the max peaks height difference for sync code detection.
|
||||
Default is @code{0.1}. Allowed range is @code{[0.0 - 0.5]}.
|
||||
|
||||
@item mpd
|
||||
Set max peaks period difference for sync code detection.
|
||||
Default is @code{0.1}. Allowed range is @code{[0.0 - 0.5]}.
|
||||
|
||||
@item msd
|
||||
Set the first two max start code bits differences.
|
||||
Default is @code{0.02}. Allowed range is @code{[0.0 - 0.5]}.
|
||||
|
||||
@item bhd
|
||||
Set the minimum ratio of bits height compared to 3rd start code bit.
|
||||
Default is @code{0.75}. Allowed range is @code{[0.01 - 1]}.
|
||||
|
||||
@item th_w
|
||||
Set the white color threshold. Default is @code{0.35}. Allowed range is @code{[0.1 - 1]}.
|
||||
|
||||
@item th_b
|
||||
Set the black color threshold. Default is @code{0.15}. Allowed range is @code{[0.0 - 0.5]}.
|
||||
|
||||
@item chp
|
||||
Enable checking the parity bit. In the event of a parity error, the filter will output
|
||||
@code{0x00} for that character. Default is false.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Output a csv with presentation time and the first two lines of identified EIA-608 captioning data.
|
||||
@example
|
||||
ffprobe -f lavfi -i movie=captioned_video.mov,readeia608 -show_entries frame=pkt_pts_time:frame_tags=lavfi.readeia608.0.cc,lavfi.readeia608.1.cc -of csv
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section readvitc
|
||||
|
||||
Read vertical interval timecode (VITC) information from the top lines of a
|
||||
@@ -12077,7 +11915,7 @@ uses the reference video instead of the main input as basis.
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Scale a subtitle stream to match the main video in size before overlaying
|
||||
Scale a subtitle stream (b) to match the main video (a) in size before overlaying
|
||||
@example
|
||||
'scale2ref[b][a];[a][b]overlay'
|
||||
@end example
|
||||
@@ -12368,7 +12206,7 @@ Set the size of the box used to represent one palette color entry. Default is
|
||||
|
||||
@section shuffleframes
|
||||
|
||||
Reorder and/or duplicate and/or drop video frames.
|
||||
Reorder and/or duplicate video frames.
|
||||
|
||||
It accepts the following parameters:
|
||||
|
||||
@@ -12377,7 +12215,6 @@ It accepts the following parameters:
|
||||
Set the destination indexes of input frames.
|
||||
This is space or '|' separated list of indexes that maps input frames to output
|
||||
frames. Number of indexes also sets maximal value that each index may have.
|
||||
'-1' index have special meaning and that is to drop frame.
|
||||
@end table
|
||||
|
||||
The first frame has the index 0. The default is to keep the input unchanged.
|
||||
@@ -12627,95 +12464,6 @@ saturation maximum: %@{metadata:lavfi.signalstats.SATMAX@}
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@anchor{signature}
|
||||
@section signature
|
||||
|
||||
Calculates the MPEG-7 Video Signature. The filter can handle more than one
|
||||
input. In this case the matching between the inputs can be calculated additionally.
|
||||
The filter always passes through the first input. The signature of each stream can
|
||||
be written into a file.
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item detectmode
|
||||
Enable or disable the matching process.
|
||||
|
||||
Available values are:
|
||||
|
||||
@table @samp
|
||||
@item off
|
||||
Disable the calculation of a matching (default).
|
||||
@item full
|
||||
Calculate the matching for the whole video and output whether the whole video
|
||||
matches or only parts.
|
||||
@item fast
|
||||
Calculate only until a matching is found or the video ends. Should be faster in
|
||||
some cases.
|
||||
@end table
|
||||
|
||||
@item nb_inputs
|
||||
Set the number of inputs. The option value must be a non negative integer.
|
||||
Default value is 1.
|
||||
|
||||
@item filename
|
||||
Set the path to which the output is written. If there is more than one input,
|
||||
the path must be a prototype, i.e. must contain %d or %0nd (where n is a positive
|
||||
integer), that will be replaced with the input number. If no filename is
|
||||
specified, no output will be written. This is the default.
|
||||
|
||||
@item format
|
||||
Choose the output format.
|
||||
|
||||
Available values are:
|
||||
|
||||
@table @samp
|
||||
@item binary
|
||||
Use the specified binary representation (default).
|
||||
@item xml
|
||||
Use the specified xml representation.
|
||||
@end table
|
||||
|
||||
@item th_d
|
||||
Set threshold to detect one word as similar. The option value must be an integer
|
||||
greater than zero. The default value is 9000.
|
||||
|
||||
@item th_dc
|
||||
Set threshold to detect all words as similar. The option value must be an integer
|
||||
greater than zero. The default value is 60000.
|
||||
|
||||
@item th_xh
|
||||
Set threshold to detect frames as similar. The option value must be an integer
|
||||
greater than zero. The default value is 116.
|
||||
|
||||
@item th_di
|
||||
Set the minimum length of a sequence in frames to recognize it as matching
|
||||
sequence. The option value must be a non negative integer value.
|
||||
The default value is 0.
|
||||
|
||||
@item th_it
|
||||
Set the minimum relation, that matching frames to all frames must have.
|
||||
The option value must be a double value between 0 and 1. The default value is 0.5.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
To calculate the signature of an input video and store it in signature.bin:
|
||||
@example
|
||||
ffmpeg -i input.mkv -vf signature=filename=signature.bin -map 0:v -f null -
|
||||
@end example
|
||||
|
||||
@item
|
||||
To detect whether two videos match and store the signatures in XML format in
|
||||
signature0.xml and signature1.xml:
|
||||
@example
|
||||
ffmpeg -i input1.mkv -i input2.mkv -filter_complex "[0:v][1:v] signature=nb_inputs=2:detectmode=full:format=xml:filename=signature%d.xml" -map :v -f null -
|
||||
@end example
|
||||
|
||||
@end itemize
|
||||
|
||||
@anchor{smartblur}
|
||||
@section smartblur
|
||||
|
||||
@@ -12745,20 +12493,20 @@ in [-30,0] will filter edges. Default value is 0.
|
||||
@item chroma_radius, cr
|
||||
Set the chroma radius. The option value must be a float number in
|
||||
the range [0.1,5.0] that specifies the variance of the gaussian filter
|
||||
used to blur the image (slower if larger). Default value is @option{luma_radius}.
|
||||
used to blur the image (slower if larger). Default value is 1.0.
|
||||
|
||||
@item chroma_strength, cs
|
||||
Set the chroma strength. The option value must be a float number
|
||||
in the range [-1.0,1.0] that configures the blurring. A value included
|
||||
in [0.0,1.0] will blur the image whereas a value included in
|
||||
[-1.0,0.0] will sharpen the image. Default value is @option{luma_strength}.
|
||||
[-1.0,0.0] will sharpen the image. Default value is 1.0.
|
||||
|
||||
@item chroma_threshold, ct
|
||||
Set the chroma threshold used as a coefficient to determine
|
||||
whether a pixel should be blurred or not. The option value must be an
|
||||
integer in the range [-30,30]. A value of 0 will filter all the image,
|
||||
a value included in [0,30] will filter flat areas and a value included
|
||||
in [-30,0] will filter edges. Default value is @option{luma_threshold}.
|
||||
in [-30,0] will filter edges. Default value is 0.
|
||||
@end table
|
||||
|
||||
If a chroma option is not explicitly set, the corresponding luma value
|
||||
@@ -13290,63 +13038,6 @@ PAL output (25i):
|
||||
16p: 33333334
|
||||
@end example
|
||||
|
||||
@section threshold
|
||||
|
||||
Apply threshold effect to video stream.
|
||||
|
||||
This filter needs four video streams to perform thresholding.
|
||||
First stream is stream we are filtering.
|
||||
Second stream is holding threshold values, third stream is holding min values,
|
||||
and last, fourth stream is holding max values.
|
||||
|
||||
The filter accepts the following option:
|
||||
|
||||
@table @option
|
||||
@item planes
|
||||
Set which planes will be processed, unprocessed planes will be copied.
|
||||
By default value 0xf, all planes will be processed.
|
||||
@end table
|
||||
|
||||
For example if first stream pixel's component value is less then threshold value
|
||||
of pixel component from 2nd threshold stream, third stream value will picked,
|
||||
otherwise fourth stream pixel component value will be picked.
|
||||
|
||||
Using color source filter one can perform various types of thresholding:
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Binary threshold, using gray color as threshold:
|
||||
@example
|
||||
ffmpeg -i 320x240.avi -f lavfi -i color=gray -f lavfi -i color=black -f lavfi -i color=white -lavfi threshold output.avi
|
||||
@end example
|
||||
|
||||
@item
|
||||
Inverted binary threshold, using gray color as threshold:
|
||||
@example
|
||||
ffmpeg -i 320x240.avi -f lavfi -i color=gray -f lavfi -i color=white -f lavfi -i color=black -lavfi threshold output.avi
|
||||
@end example
|
||||
|
||||
@item
|
||||
Truncate binary threshold, using gray color as threshold:
|
||||
@example
|
||||
ffmpeg -i 320x240.avi -f lavfi -i color=gray -i 320x240.avi -f lavfi -i color=gray -lavfi threshold output.avi
|
||||
@end example
|
||||
|
||||
@item
|
||||
Threshold to zero, using gray color as threshold:
|
||||
@example
|
||||
ffmpeg -i 320x240.avi -f lavfi -i color=gray -f lavfi -i color=white -i 320x240.avi -lavfi threshold output.avi
|
||||
@end example
|
||||
|
||||
@item
|
||||
Inverted threshold to zero, using gray color as threshold:
|
||||
@example
|
||||
ffmpeg -i 320x240.avi -f lavfi -i color=gray -i 320x240.avi -f lavfi -i color=white -lavfi threshold output.avi
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section thumbnail
|
||||
Select the most representative frame in a given sequence of consecutive frames.
|
||||
|
||||
@@ -14928,9 +14619,6 @@ Possible values are:
|
||||
@item linear
|
||||
@item 2020_10
|
||||
@item 2020_12
|
||||
@item smpte2084
|
||||
@item iec61966-2-1
|
||||
@item arib-std-b67
|
||||
@end table
|
||||
|
||||
Default is same as input.
|
||||
@@ -15035,9 +14723,6 @@ Possible values are:
|
||||
@item bottomleft
|
||||
@item bottom
|
||||
@end table
|
||||
|
||||
@item npl
|
||||
Set the nominal peak luminance.
|
||||
@end table
|
||||
|
||||
The values of the @option{w} and @option{h} options are expressions
|
||||
@@ -15782,28 +15467,6 @@ tools.
|
||||
|
||||
Below is a description of the currently available multimedia filters.
|
||||
|
||||
@section abitscope
|
||||
|
||||
Convert input audio to a video output, displaying the audio bit scope.
|
||||
|
||||
The filter accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item rate, r
|
||||
Set frame rate, expressed as number of frames per second. Default
|
||||
value is "25".
|
||||
|
||||
@item size, s
|
||||
Specify the video size for the output. For the syntax of this option, check the
|
||||
@ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
|
||||
Default value is @code{1024x256}.
|
||||
|
||||
@item colors
|
||||
Specify list of colors separated by space or by '|' which will be used to
|
||||
draw channels. Unrecognized or missing colors will be replaced
|
||||
by white color.
|
||||
@end table
|
||||
|
||||
@section ahistogram
|
||||
|
||||
Convert input audio to a video output, displaying the volume histogram.
|
||||
@@ -15907,9 +15570,6 @@ Allowed range is @code{[0, 255]}.
|
||||
@item mpc
|
||||
Set color which will be used for drawing median phase. If color is
|
||||
@code{none} which is default, no median phase value will be drawn.
|
||||
|
||||
@item video
|
||||
Enable video output. Default is enabled.
|
||||
@end table
|
||||
|
||||
The filter also exports the frame metadata @code{lavfi.aphasemeter.phase} which
|
||||
@@ -16476,13 +16136,13 @@ Float representation of @code{value} from metadata key.
|
||||
|
||||
@item VALUE2
|
||||
Float representation of @code{value} as supplied by user in @code{value} option.
|
||||
@end table
|
||||
|
||||
@item file
|
||||
If specified in @code{print} mode, output is written to the named file. Instead of
|
||||
plain filename any writable url can be specified. Filename ``-'' is a shorthand
|
||||
for standard output. If @code{file} option is not set, output is written to the log
|
||||
with AV_LOG_INFO loglevel.
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@@ -17175,16 +16835,12 @@ Acceptable range is @code{[1, 7]}.
|
||||
Specify the bargraph gamma. Default value is @code{1}. Acceptable range is
|
||||
@code{[1, 7]}.
|
||||
|
||||
@item bar_t
|
||||
Specify the bargraph transparency level. Lower value makes the bargraph sharper.
|
||||
Default value is @code{1}. Acceptable range is @code{[0, 1]}.
|
||||
|
||||
@item timeclamp, tc
|
||||
Specify the transform timeclamp. At low frequency, there is trade-off between
|
||||
accuracy in time domain and frequency domain. If timeclamp is lower,
|
||||
event in time domain is represented more accurately (such as fast bass drum),
|
||||
otherwise event in frequency domain is represented more accurately
|
||||
(such as bass guitar). Acceptable range is @code{[0.002, 1]}. Default value is @code{0.17}.
|
||||
(such as bass guitar). Acceptable range is @code{[0.1, 1]}. Default value is @code{0.17}.
|
||||
|
||||
@item basefreq
|
||||
Specify the transform base frequency. Default value is @code{20.01523126408007475},
|
||||
@@ -17962,23 +17618,7 @@ Set if channels should be drawn separately or overlap. Default value is 0.
|
||||
Set colors separated by '|' which are going to be used for drawing of each channel.
|
||||
|
||||
@item scale
|
||||
Set amplitude scale.
|
||||
|
||||
Available values are:
|
||||
@table @samp
|
||||
@item lin
|
||||
Linear.
|
||||
|
||||
@item log
|
||||
Logarithmic.
|
||||
|
||||
@item sqrt
|
||||
Square root.
|
||||
|
||||
@item cbrt
|
||||
Cubic root.
|
||||
@end table
|
||||
|
||||
Set amplitude scale. Can be linear @code{lin} or logarithmic @code{log}.
|
||||
Default is linear.
|
||||
@end table
|
||||
|
||||
@@ -18245,7 +17885,7 @@ audio instead of video.
|
||||
|
||||
@item loop
|
||||
Specifies how many times to read the stream in sequence.
|
||||
If the value is 0, the stream will be looped infinitely.
|
||||
If the value is less than 1, the stream will be read again and again.
|
||||
Default value is "1".
|
||||
|
||||
Note that when the movie is looped the source timestamps are not
|
||||
|
||||
@@ -186,19 +186,6 @@ For Windows, supported AviSynth variants are
|
||||
For Linux and OS X, the supported AviSynth variant is
|
||||
@url{https://github.com/avxsynth/avxsynth, AvxSynth}.
|
||||
|
||||
@float NOTE
|
||||
There is currently a regression in AviSynth+'s @code{capi.h} header as of
|
||||
October 2016, which interferes with the ability for builds of Libav to use
|
||||
MSVC-built binaries of AviSynth. Until this is resolved, you can make sure
|
||||
a known good version is installed by checking out a version from before
|
||||
the regression occurred:
|
||||
|
||||
@code{git clone -b MT git://github.com/AviSynth/AviSynthPlus.git @*
|
||||
cd AviSynthPlus @*
|
||||
git checkout -b oldheader b4f292b4dbfad149697fb65c6a037bb3810813f9 @*
|
||||
make install PREFIX=/install/prefix}
|
||||
@end float
|
||||
|
||||
@float NOTE
|
||||
AviSynth and AvxSynth are loaded dynamically. Distributors can build FFmpeg
|
||||
with @code{--enable-avisynth}, and the binaries will work regardless of the
|
||||
@@ -355,7 +342,6 @@ library:
|
||||
@item iLBC @tab X @tab X
|
||||
@item Interplay MVE @tab @tab X
|
||||
@tab Format used in various Interplay computer games.
|
||||
@item Iterated Systems ClearVideo @tab @tab X
|
||||
@item IV8 @tab @tab X
|
||||
@tab A format generated by IndigoVision 8000 video server.
|
||||
@item IVF (On2) @tab X @tab X
|
||||
@@ -401,7 +387,6 @@ library:
|
||||
@tab Audio format used on the PS3.
|
||||
@item Mirillis FIC video @tab @tab X
|
||||
@tab No cursor rendering.
|
||||
@item MIDI Sample Dump Standard @tab @tab X
|
||||
@item MIME multipart JPEG @tab X @tab
|
||||
@item MSN TCP webcam @tab @tab X
|
||||
@tab Used by MSN Messenger webcam streams.
|
||||
@@ -465,8 +450,6 @@ library:
|
||||
@item raw PCM signed 24 bit little-endian @tab X @tab X
|
||||
@item raw PCM signed 32 bit big-endian @tab X @tab X
|
||||
@item raw PCM signed 32 bit little-endian @tab X @tab X
|
||||
@item raw PCM signed 64 bit big-endian @tab X @tab X
|
||||
@item raw PCM signed 64 bit little-endian @tab X @tab X
|
||||
@item raw PCM unsigned 8 bit @tab X @tab X
|
||||
@item raw PCM unsigned 16 bit big-endian @tab X @tab X
|
||||
@item raw PCM unsigned 16 bit little-endian @tab X @tab X
|
||||
@@ -474,8 +457,6 @@ library:
|
||||
@item raw PCM unsigned 24 bit little-endian @tab X @tab X
|
||||
@item raw PCM unsigned 32 bit big-endian @tab X @tab X
|
||||
@item raw PCM unsigned 32 bit little-endian @tab X @tab X
|
||||
@item raw PCM 16.8 floating point little-endian @tab @tab X
|
||||
@item raw PCM 24.0 floating point little-endian @tab @tab X
|
||||
@item raw PCM floating-point 32 bit big-endian @tab X @tab X
|
||||
@item raw PCM floating-point 32 bit little-endian @tab X @tab X
|
||||
@item raw PCM floating-point 64 bit big-endian @tab X @tab X
|
||||
@@ -497,7 +478,6 @@ library:
|
||||
@tab Output is performed by publishing stream to RTMP server
|
||||
@item RTP @tab X @tab X
|
||||
@item RTSP @tab X @tab X
|
||||
@item Sample Dump eXchange @tab @tab X
|
||||
@item SAP @tab X @tab X
|
||||
@item SBG @tab @tab X
|
||||
@item SDP @tab @tab X
|
||||
@@ -604,8 +584,6 @@ following image formats are supported:
|
||||
@item PNG @tab X @tab X
|
||||
@item PPM @tab X @tab X
|
||||
@tab Portable PixelMap image
|
||||
@item PSD @tab @tab X
|
||||
@tab Photoshop
|
||||
@item PTX @tab @tab X
|
||||
@tab V.Flash PTX format
|
||||
@item SGI @tab X @tab X
|
||||
@@ -622,8 +600,6 @@ following image formats are supported:
|
||||
@tab X BitMap image format
|
||||
@item XFace @tab X @tab X
|
||||
@tab X-Face image format
|
||||
@item XPM @tab @tab X
|
||||
@tab X PixMap image format
|
||||
@item XWD @tab X @tab X
|
||||
@tab X Window Dump image format
|
||||
@end multitable
|
||||
@@ -649,7 +625,6 @@ following image formats are supported:
|
||||
@item ANSI/ASCII art @tab @tab X
|
||||
@item Apple Intermediate Codec @tab @tab X
|
||||
@item Apple MJPEG-B @tab @tab X
|
||||
@item Apple Pixlet @tab @tab X
|
||||
@item Apple ProRes @tab X @tab X
|
||||
@item Apple QuickDraw @tab @tab X
|
||||
@tab fourcc: qdrw
|
||||
@@ -732,7 +707,6 @@ following image formats are supported:
|
||||
@item Flash Screen Video v2 @tab X @tab X
|
||||
@item Flash Video (FLV) @tab X @tab X
|
||||
@tab Sorenson H.263 used in Flash
|
||||
@item FM Screen Capture Codec @tab @tab X
|
||||
@item Forward Uncompressed @tab @tab X
|
||||
@item Fraps @tab @tab X
|
||||
@item Go2Meeting @tab @tab X
|
||||
@@ -805,7 +779,6 @@ following image formats are supported:
|
||||
@item MPEG-4 part 2 Microsoft variant version 1 @tab @tab X
|
||||
@item MPEG-4 part 2 Microsoft variant version 2 @tab X @tab X
|
||||
@item MPEG-4 part 2 Microsoft variant version 3 @tab X @tab X
|
||||
@item Newtek SpeedHQ @tab @tab X
|
||||
@item Nintendo Gamecube THP video @tab @tab X
|
||||
@item NuppelVideo/RTjpeg @tab @tab X
|
||||
@tab Video encoding used in NuppelVideo files.
|
||||
@@ -846,7 +819,6 @@ following image formats are supported:
|
||||
@tab Texture dictionaries used by the Renderware Engine.
|
||||
@item RL2 video @tab @tab X
|
||||
@tab used in some games by Entertainment Software Partners
|
||||
@item ScreenPressor @tab @tab X
|
||||
@item Screenpresso @tab @tab X
|
||||
@item Sierra VMD video @tab @tab X
|
||||
@tab Used in Sierra VMD files.
|
||||
@@ -1069,7 +1041,6 @@ following image formats are supported:
|
||||
@item PCM unsigned 32-bit little-endian @tab X @tab X
|
||||
@item PCM Zork @tab @tab X
|
||||
@item QCELP / PureVoice @tab @tab X
|
||||
@item QDesign Music Codec 1 @tab @tab X
|
||||
@item QDesign Music Codec 2 @tab @tab X
|
||||
@tab There are still some distortions.
|
||||
@item RealAudio 1.0 (14.4K) @tab X @tab X
|
||||
@@ -1166,7 +1137,6 @@ performance on systems without hardware floating point support).
|
||||
@item MMSH @tab X
|
||||
@item MMST @tab X
|
||||
@item pipe @tab X
|
||||
@item Pro-MPEG FEC @tab X
|
||||
@item RTMP @tab X
|
||||
@item RTMPE @tab X
|
||||
@item RTMPS @tab X
|
||||
|
||||
@@ -233,12 +233,6 @@ Defaults to @option{false}.
|
||||
If set to @option{true}, print a list of supported formats and exit.
|
||||
Defaults to @option{false}.
|
||||
|
||||
@item format_code <FourCC>
|
||||
This sets the input video format to the format given by the FourCC. To see
|
||||
the supported values of your device(s) use @option{list_formats}.
|
||||
Note that there is a FourCC @option{'pal '} that can also be used
|
||||
as @option{pal} (3 letters).
|
||||
|
||||
@item bm_v210
|
||||
If set to @samp{1}, video is captured in 10 bit v210 instead
|
||||
of uyvy422. Not all Blackmagic devices support this option.
|
||||
@@ -302,21 +296,21 @@ ffmpeg -f decklink -list_formats 1 -i 'Intensity Pro'
|
||||
@end example
|
||||
|
||||
@item
|
||||
Capture video clip at 1080i50:
|
||||
Capture video clip at 1080i50 (format 11):
|
||||
@example
|
||||
ffmpeg -format_code Hi50 -f decklink -i 'Intensity Pro' -acodec copy -vcodec copy output.avi
|
||||
ffmpeg -f decklink -i 'Intensity Pro@@11' -acodec copy -vcodec copy output.avi
|
||||
@end example
|
||||
|
||||
@item
|
||||
Capture video clip at 1080i50 10 bit:
|
||||
@example
|
||||
ffmpeg -bm_v210 1 -format_code Hi50 -f decklink -i 'UltraStudio Mini Recorder' -acodec copy -vcodec copy output.avi
|
||||
ffmpeg -bm_v210 1 -f decklink -i 'UltraStudio Mini Recorder@@11' -acodec copy -vcodec copy output.avi
|
||||
@end example
|
||||
|
||||
@item
|
||||
Capture video clip at 1080i50 with 16 audio channels:
|
||||
@example
|
||||
ffmpeg -channels 16 -format_code Hi50 -f decklink -i 'UltraStudio Mini Recorder' -acodec copy -vcodec copy output.avi
|
||||
ffmpeg -channels 16 -f decklink -i 'UltraStudio Mini Recorder@@11' -acodec copy -vcodec copy output.avi
|
||||
@end example
|
||||
|
||||
@end itemize
|
||||
@@ -1311,6 +1305,9 @@ To enable this input device during configuration you need libxcb
|
||||
installed on your system. It will be automatically detected during
|
||||
configuration.
|
||||
|
||||
Alternatively, the configure option @option{--enable-x11grab} exists
|
||||
for legacy Xlib users.
|
||||
|
||||
This device allows one to capture a region of an X11 display.
|
||||
|
||||
The filename passed as input has the syntax:
|
||||
@@ -1398,6 +1395,11 @@ ffmpeg -f x11grab -follow_mouse centered -show_region 1 -framerate 25 -video_siz
|
||||
@item video_size
|
||||
Set the video frame size. Default value is @code{vga}.
|
||||
|
||||
@item use_shm
|
||||
Use the MIT-SHM extension for shared memory. Default value is @code{1}.
|
||||
It may be necessary to disable it for remote displays (legacy x11grab
|
||||
only).
|
||||
|
||||
@item grab_x
|
||||
@item grab_y
|
||||
Set the grabbing region coordinates. They are expressed as offset from
|
||||
|
||||
27
doc/lexicon
27
doc/lexicon
@@ -1,27 +0,0 @@
|
||||
Common abbreviations/shorthands we use that don't need a comment
|
||||
================================================================
|
||||
|
||||
dsp: digital signal processing
|
||||
dst/adst: (asymmetric) discrete sine transform
|
||||
ec: entropy coding or error concealment
|
||||
er: error resilience
|
||||
fdct/idct: forward/inverse discrete cosine transform
|
||||
fft: fast Fourier transform
|
||||
gop: group of pictures
|
||||
hw/sw: hardware/software
|
||||
lp: lowpass
|
||||
lpf: loop filter
|
||||
lut: lookup table
|
||||
mb: macroblock
|
||||
mc: motion compensation
|
||||
me: motion estimation
|
||||
mv: motion vector
|
||||
nal: network abstraction layer
|
||||
pel/qpel/epel/hpel/fpel: pixel / quarter-pixel / eighth-pixel / half-pixel / full-pixel
|
||||
pp: post process
|
||||
qp: quantization parameter
|
||||
rc: rate control
|
||||
sei: supplemental enhancement information
|
||||
sl: slice
|
||||
vlc: variable length coding
|
||||
vq: vector quantization
|
||||
@@ -88,16 +88,7 @@ Stuff that didn't reach the codebase:
|
||||
-------------------------------------
|
||||
|
||||
- HEVC DSP and x86 MC SIMD improvements from Libav (see https://ffmpeg.org/pipermail/ffmpeg-devel/2015-December/184777.html)
|
||||
- 1f821750f hevcdsp: split the qpel functions by width instead of by the subpixel fraction
|
||||
- 818bfe7f0 hevcdsp: split the epel functions by width
|
||||
- 688417399 hevcdsp: split the pred functions by width
|
||||
- a853388d2 hevc: change the stride of the MC buffer to be in bytes instead of elements
|
||||
- 0cef06df0 checkasm: add HEVC MC tests
|
||||
- e7078e842 hevcdsp: add x86 SIMD for MC
|
||||
- VAAPI VP8 decode hwaccel (currently under review: http://ffmpeg.org/pipermail/ffmpeg-devel/2017-February/thread.html#207348)
|
||||
- Removal of the custom atomic API (5cc0057f49, see http://ffmpeg.org/pipermail/ffmpeg-devel/2017-March/209003.html)
|
||||
- Use the new bitstream filter for extracting extradata (8e2ea69135 and 096a8effa3, see https://ffmpeg.org/pipermail/ffmpeg-devel/2017-March/209068.html)
|
||||
- Read aac_adtstoasc extradata updates from packet side data on Matroska once mov and the bsf in question are fixed (See 13a211e632 and 5ef1959080)
|
||||
- QSV HWContext integration (04b17ff and 130e1f1), QSV scaling filter (62c58c5)
|
||||
|
||||
Collateral damage that needs work locally:
|
||||
------------------------------------------
|
||||
@@ -105,11 +96,3 @@ Collateral damage that needs work locally:
|
||||
- Merge proresdec2.c and proresdec_lgpl.c
|
||||
- Merge proresenc_anatoliy.c and proresenc_kostya.c
|
||||
- Remove ADVANCED_PARSER in libavcodec/hevc_parser.c
|
||||
- Fix MIPS AC3 downmix
|
||||
- hlsenc encryption support may need some adjustment (see edc43c571d)
|
||||
|
||||
Extra changes needed to be aligned with Libav:
|
||||
----------------------------------------------
|
||||
|
||||
- Switching our examples to the new encode/decode API (see 67d28f4a0f)
|
||||
- HEVC IDCT bit depth 12-bit support (Libav added 8 and 10 but doesn't have 12)
|
||||
|
||||
335
doc/muxers.texi
335
doc/muxers.texi
@@ -13,9 +13,8 @@ You can disable all the muxers with the configure option
|
||||
with the options @code{--enable-muxer=@var{MUXER}} /
|
||||
@code{--disable-muxer=@var{MUXER}}.
|
||||
|
||||
The option @code{-muxers} of the ff* tools will display the list of
|
||||
enabled muxers. Use @code{-formats} to view a combined list of
|
||||
enabled demuxers and muxers.
|
||||
The option @code{-formats} of the ff* tools will display the list of
|
||||
enabled muxers.
|
||||
|
||||
A description of some of the currently available muxers follows.
|
||||
|
||||
@@ -58,39 +57,6 @@ fragmentation or muxer overhead depending on your source. Default value is
|
||||
|
||||
@end table
|
||||
|
||||
@anchor{avi}
|
||||
@section avi
|
||||
|
||||
Audio Video Interleaved muxer.
|
||||
|
||||
@subsection Options
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item reserve_index_space
|
||||
Reserve the specified amount of bytes for the OpenDML master index of each
|
||||
stream within the file header. By default additional master indexes are
|
||||
embedded within the data packets if there is no space left in the first master
|
||||
index and are linked together as a chain of indexes. This index structure can
|
||||
cause problems for some use cases, e.g. third-party software strictly relying
|
||||
on the OpenDML index specification or when file seeking is slow. Reserving
|
||||
enough index space in the file header avoids these problems.
|
||||
|
||||
The required index space depends on the output file size and should be about 16
|
||||
bytes per gigabyte. When this option is omitted or set to zero the necessary
|
||||
index space is guessed.
|
||||
|
||||
@item write_channel_mask
|
||||
Write the channel layout mask into the audio stream header.
|
||||
|
||||
This option is enabled by default. Disabling the channel mask can be useful in
|
||||
specific scenarios, e.g. when merging multiple audio streams into one for
|
||||
compatibility with software that only supports a single audio stream in AVI
|
||||
(see @ref{amerge,,the "amerge" section in the ffmpeg-filters manual,ffmpeg-filters}).
|
||||
|
||||
@end table
|
||||
|
||||
@anchor{chromaprint}
|
||||
@section chromaprint
|
||||
|
||||
@@ -181,16 +147,6 @@ Place AAC sequence header based on audio stream data.
|
||||
|
||||
@item no_sequence_end
|
||||
Disable sequence end tag.
|
||||
|
||||
@item no_metadata
|
||||
Disable metadata tag.
|
||||
|
||||
@item no_duration_filesize
|
||||
Disable duration and filesize in metadata when they are equal to zero
|
||||
at the end of stream. (Be used to non-seekable living stream).
|
||||
|
||||
@item add_keyframe_index
|
||||
Used to facilitate seeking; particularly for HTTP pseudo streaming.
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@@ -442,41 +398,17 @@ parameters. Values containing @code{:} special characters must be
|
||||
escaped.
|
||||
|
||||
@item hls_wrap @var{wrap}
|
||||
This is a deprecated option, you can use @code{hls_list_size}
|
||||
and @code{hls_flags delete_segments} instead it
|
||||
Set the number after which the segment filename number (the number
|
||||
specified in each segment file) wraps. If set to 0 the number will be
|
||||
never wrapped. Default value is 0.
|
||||
|
||||
This option is useful to avoid to fill the disk with many segment
|
||||
files, and limits the maximum number of segment files written to disk
|
||||
to @var{wrap}.
|
||||
|
||||
|
||||
@item hls_start_number_source
|
||||
Start the playlist sequence number (@code{#EXT-X-MEDIA-SEQUENCE}) according to the specified source.
|
||||
Unless @code{hls_flags single_file} is set, it also specifies source of starting sequence numbers of
|
||||
segment and subtitle filenames. In any case, if @code{hls_flags append_list}
|
||||
is set and read playlist sequence number is greater than the specified start sequence number,
|
||||
then that value will be used as start value.
|
||||
|
||||
It accepts the following values:
|
||||
|
||||
@table @option
|
||||
|
||||
@item generic (default)
|
||||
Set the starting sequence numbers according to @var{start_number} option value.
|
||||
|
||||
@item epoch
|
||||
The start number will be the seconds since epoch (1970-01-01 00:00:00)
|
||||
|
||||
@item datetime
|
||||
The start number will be based on the current date/time as YYYYmmddHHMMSS. e.g. 20161231235759.
|
||||
|
||||
@end table
|
||||
|
||||
@item start_number @var{number}
|
||||
Start the playlist sequence number (@code{#EXT-X-MEDIA-SEQUENCE}) from the specified @var{number}
|
||||
when @var{hls_start_number_source} value is @var{generic}. (This is the default case.)
|
||||
Unless @code{hls_flags single_file} is set, it also specifies starting sequence numbers of segment and subtitle filenames.
|
||||
Default value is 0.
|
||||
Start the playlist sequence number from @var{number}. Default value is
|
||||
0.
|
||||
|
||||
@item hls_allow_cache @var{allowcache}
|
||||
Explicitly set whether the client MAY (1) or MUST NOT (0) cache media segments.
|
||||
@@ -499,46 +431,24 @@ ffmpeg -i in.nut -hls_segment_filename 'file%03d.ts' out.m3u8
|
||||
This example will produce the playlist, @file{out.m3u8}, and segment files:
|
||||
@file{file000.ts}, @file{file001.ts}, @file{file002.ts}, etc.
|
||||
|
||||
@var{filename} may contain full path or relative path specification,
|
||||
but only the file name part without any path info will be contained in the m3u8 segment list.
|
||||
Should a relative path be specified, the path of the created segment
|
||||
files will be relative to the current working directory.
|
||||
When use_localtime_mkdir is set, the whole expanded value of @var{filename} will be written into the m3u8 segment list.
|
||||
|
||||
|
||||
@item use_localtime
|
||||
Use strftime() on @var{filename} to expand the segment filename with localtime.
|
||||
The segment number is also available in this mode, but to use it, you need to specify second_level_segment_index
|
||||
hls_flag and %%d will be the specifier.
|
||||
Use strftime on @var{filename} to expand the segment filename with localtime.
|
||||
The segment number (%d) is not available in this mode.
|
||||
@example
|
||||
ffmpeg -i in.nut -use_localtime 1 -hls_segment_filename 'file-%Y%m%d-%s.ts' out.m3u8
|
||||
@end example
|
||||
This example will produce the playlist, @file{out.m3u8}, and segment files:
|
||||
@file{file-20160215-1455569023.ts}, @file{file-20160215-1455569024.ts}, etc.
|
||||
Note: On some systems/environments, the @code{%s} specifier is not available. See
|
||||
@code{strftime()} documentation.
|
||||
@example
|
||||
ffmpeg -i in.nut -use_localtime 1 -hls_flags second_level_segment_index -hls_segment_filename 'file-%Y%m%d-%%04d.ts' out.m3u8
|
||||
@end example
|
||||
This example will produce the playlist, @file{out.m3u8}, and segment files:
|
||||
@file{file-20160215-0001.ts}, @file{file-20160215-0002.ts}, etc.
|
||||
|
||||
@item use_localtime_mkdir
|
||||
Used together with -use_localtime, it will create all subdirectories which
|
||||
Used together with -use_localtime, it will create up to one subdirectory which
|
||||
is expanded in @var{filename}.
|
||||
@example
|
||||
ffmpeg -i in.nut -use_localtime 1 -use_localtime_mkdir 1 -hls_segment_filename '%Y%m%d/file-%Y%m%d-%s.ts' out.m3u8
|
||||
@end example
|
||||
This example will create a directory 201560215 (if it does not exist), and then
|
||||
produce the playlist, @file{out.m3u8}, and segment files:
|
||||
@file{20160215/file-20160215-1455569023.ts}, @file{20160215/file-20160215-1455569024.ts}, etc.
|
||||
|
||||
@example
|
||||
ffmpeg -i in.nut -use_localtime 1 -use_localtime_mkdir 1 -hls_segment_filename '%Y/%m/%d/file-%Y%m%d-%s.ts' out.m3u8
|
||||
@end example
|
||||
This example will create a directory hierarchy 2016/02/15 (if any of them do not exist), and then
|
||||
produce the playlist, @file{out.m3u8}, and segment files:
|
||||
@file{2016/02/15/file-20160215-1455569023.ts}, @file{2016/02/15/file-20160215-1455569024.ts}, etc.
|
||||
@file{201560215/file-20160215-1455569023.ts}, @file{201560215/file-20160215-1455569024.ts}, etc.
|
||||
|
||||
|
||||
@item hls_key_info_file @var{key_info_file}
|
||||
@@ -597,12 +507,7 @@ ffmpeg -f lavfi -re -i testsrc -c:v h264 -hls_flags delete_segments \
|
||||
-hls_key_info_file file.keyinfo out.m3u8
|
||||
@end example
|
||||
|
||||
|
||||
@item hls_flags @var{flags}
|
||||
Possible values:
|
||||
|
||||
@table @samp
|
||||
@item single_file
|
||||
@item hls_flags single_file
|
||||
If this flag is set, the muxer will store all segments in a single MPEG-TS
|
||||
file, and will use byte ranges in the playlist. HLS playlists generated with
|
||||
this way will have the version number 4.
|
||||
@@ -613,65 +518,34 @@ ffmpeg -i in.nut -hls_flags single_file out.m3u8
|
||||
Will produce the playlist, @file{out.m3u8}, and a single segment file,
|
||||
@file{out.ts}.
|
||||
|
||||
@item delete_segments
|
||||
@item hls_flags delete_segments
|
||||
Segment files removed from the playlist are deleted after a period of time
|
||||
equal to the duration of the segment plus the duration of the playlist.
|
||||
|
||||
@item append_list
|
||||
@item hls_flags append_list
|
||||
Append new segments into the end of old segment list,
|
||||
and remove the @code{#EXT-X-ENDLIST} from the old segment list.
|
||||
|
||||
@item round_durations
|
||||
@item hls_flags round_durations
|
||||
Round the duration info in the playlist file segment info to integer
|
||||
values, instead of using floating point.
|
||||
|
||||
@item discont_start
|
||||
@item hls_flags discont_starts
|
||||
Add the @code{#EXT-X-DISCONTINUITY} tag to the playlist, before the
|
||||
first segment's information.
|
||||
|
||||
@item omit_endlist
|
||||
@item hls_flags omit_endlist
|
||||
Do not append the @code{EXT-X-ENDLIST} tag at the end of the playlist.
|
||||
|
||||
@item split_by_time
|
||||
@item hls_flags split_by_time
|
||||
Allow segments to start on frames other than keyframes. This improves
|
||||
behavior on some players when the time between keyframes is inconsistent,
|
||||
but may make things worse on others, and can cause some oddities during
|
||||
seeking. This flag should be used with the @code{hls_time} option.
|
||||
|
||||
@item program_date_time
|
||||
@item hls_flags program_date_time
|
||||
Generate @code{EXT-X-PROGRAM-DATE-TIME} tags.
|
||||
|
||||
@item second_level_segment_index
|
||||
Makes it possible to use segment indexes as %%d in hls_segment_filename expression
|
||||
besides date/time values when use_localtime is on.
|
||||
To get fixed width numbers with trailing zeroes, %%0xd format is available where x is the required width.
|
||||
|
||||
@item second_level_segment_size
|
||||
Makes it possible to use segment sizes (counted in bytes) as %%s in hls_segment_filename
|
||||
expression besides date/time values when use_localtime is on.
|
||||
To get fixed width numbers with trailing zeroes, %%0xs format is available where x is the required width.
|
||||
|
||||
@item second_level_segment_duration
|
||||
Makes it possible to use segment duration (calculated in microseconds) as %%t in hls_segment_filename
|
||||
expression besides date/time values when use_localtime is on.
|
||||
To get fixed width numbers with trailing zeroes, %%0xt format is available where x is the required width.
|
||||
|
||||
@example
|
||||
ffmpeg -i sample.mpeg \
|
||||
-f hls -hls_time 3 -hls_list_size 5 \
|
||||
-hls_flags second_level_segment_index+second_level_segment_size+second_level_segment_duration \
|
||||
-use_localtime 1 -use_localtime_mkdir 1 -hls_segment_filename "segment_%Y%m%d%H%M%S_%%04d_%%08s_%%013t.ts" stream.m3u8
|
||||
@end example
|
||||
This will produce segments like this:
|
||||
@file{segment_20170102194334_0003_00122200_0000003000000.ts}, @file{segment_20170102194334_0004_00120072_0000003000000.ts} etc.
|
||||
|
||||
@item temp_file
|
||||
Write segment data to filename.tmp and rename to filename only once the segment is complete. A webserver
|
||||
serving up segments can be configured to reject requests to *.tmp to prevent access to in-progress segments
|
||||
before they have been added to the m3u8 playlist.
|
||||
|
||||
@end table
|
||||
|
||||
@item hls_playlist_type event
|
||||
Emit @code{#EXT-X-PLAYLIST-TYPE:EVENT} in the m3u8 header. Forces
|
||||
@option{hls_list_size} to 0; the playlist can only be appended to.
|
||||
@@ -761,7 +635,7 @@ The following example shows how to use @command{ffmpeg} for creating a
|
||||
sequence of files @file{img-001.jpeg}, @file{img-002.jpeg}, ...,
|
||||
taking one image every second from the input video:
|
||||
@example
|
||||
ffmpeg -i in.avi -vsync cfr -r 1 -f image2 'img-%03d.jpeg'
|
||||
ffmpeg -i in.avi -vsync 1 -r 1 -f image2 'img-%03d.jpeg'
|
||||
@end example
|
||||
|
||||
Note that with @command{ffmpeg}, if the format is not specified with the
|
||||
@@ -769,12 +643,12 @@ Note that with @command{ffmpeg}, if the format is not specified with the
|
||||
format, the image2 muxer is automatically selected, so the previous
|
||||
command can be written as:
|
||||
@example
|
||||
ffmpeg -i in.avi -vsync cfr -r 1 'img-%03d.jpeg'
|
||||
ffmpeg -i in.avi -vsync 1 -r 1 'img-%03d.jpeg'
|
||||
@end example
|
||||
|
||||
Note also that the pattern must not necessarily contain "%d" or
|
||||
"%0@var{N}d", for example to create a single image file
|
||||
@file{img.jpeg} from the start of the input video you can employ the command:
|
||||
@file{img.jpeg} from the input video you can employ the command:
|
||||
@example
|
||||
ffmpeg -i in.avi -f image2 -frames:v 1 img.jpeg
|
||||
@end example
|
||||
@@ -1091,35 +965,69 @@ This muxer implements ISO 13818-1 and part of ETSI EN 300 468.
|
||||
|
||||
The recognized metadata settings in mpegts muxer are @code{service_provider}
|
||||
and @code{service_name}. If they are not set the default for
|
||||
@code{service_provider} is @samp{FFmpeg} and the default for
|
||||
@code{service_name} is @samp{Service01}.
|
||||
@code{service_provider} is "FFmpeg" and the default for
|
||||
@code{service_name} is "Service01".
|
||||
|
||||
@subsection Options
|
||||
|
||||
The muxer options are:
|
||||
|
||||
@table @option
|
||||
@item mpegts_transport_stream_id @var{integer}
|
||||
Set the @samp{transport_stream_id}. This identifies a transponder in DVB.
|
||||
Default is @code{0x0001}.
|
||||
@item mpegts_original_network_id @var{number}
|
||||
Set the original_network_id (default 0x0001). This is unique identifier
|
||||
of a network in DVB. Its main use is in the unique identification of a
|
||||
service through the path Original_Network_ID, Transport_Stream_ID.
|
||||
@item mpegts_transport_stream_id @var{number}
|
||||
Set the transport_stream_id (default 0x0001). This identifies a
|
||||
transponder in DVB.
|
||||
@item mpegts_service_id @var{number}
|
||||
Set the service_id (default 0x0001) also known as program in DVB.
|
||||
@item mpegts_service_type @var{number}
|
||||
Set the program service_type (default @var{digital_tv}), see below
|
||||
a list of pre defined values.
|
||||
@item mpegts_pmt_start_pid @var{number}
|
||||
Set the first PID for PMT (default 0x1000, max 0x1f00).
|
||||
@item mpegts_start_pid @var{number}
|
||||
Set the first PID for data packets (default 0x0100, max 0x0f00).
|
||||
@item mpegts_m2ts_mode @var{number}
|
||||
Enable m2ts mode if set to 1. Default value is -1 which disables m2ts mode.
|
||||
@item muxrate @var{number}
|
||||
Set a constant muxrate (default VBR).
|
||||
@item pcr_period @var{numer}
|
||||
Override the default PCR retransmission time (default 20ms), ignored
|
||||
if variable muxrate is selected.
|
||||
@item pat_period @var{number}
|
||||
Maximal time in seconds between PAT/PMT tables.
|
||||
@item sdt_period @var{number}
|
||||
Maximal time in seconds between SDT tables.
|
||||
@item pes_payload_size @var{number}
|
||||
Set minimum PES packet payload in bytes.
|
||||
@item mpegts_flags @var{flags}
|
||||
Set flags (see below).
|
||||
@item mpegts_copyts @var{number}
|
||||
Preserve original timestamps, if value is set to 1. Default value is -1, which
|
||||
results in shifting timestamps so that they start from 0.
|
||||
@item tables_version @var{number}
|
||||
Set PAT, PMT and SDT version (default 0, valid values are from 0 to 31, inclusively).
|
||||
This option allows updating stream structure so that standard consumer may
|
||||
detect the change. To do so, reopen output AVFormatContext (in case of API
|
||||
usage) or restart ffmpeg instance, cyclically changing tables_version value:
|
||||
@example
|
||||
ffmpeg -i source1.ts -codec copy -f mpegts -tables_version 0 udp://1.1.1.1:1111
|
||||
ffmpeg -i source2.ts -codec copy -f mpegts -tables_version 1 udp://1.1.1.1:1111
|
||||
...
|
||||
ffmpeg -i source3.ts -codec copy -f mpegts -tables_version 31 udp://1.1.1.1:1111
|
||||
ffmpeg -i source1.ts -codec copy -f mpegts -tables_version 0 udp://1.1.1.1:1111
|
||||
ffmpeg -i source2.ts -codec copy -f mpegts -tables_version 1 udp://1.1.1.1:1111
|
||||
...
|
||||
@end example
|
||||
@end table
|
||||
|
||||
@item mpegts_original_network_id @var{integer}
|
||||
Set the @samp{original_network_id}. This is unique identifier of a
|
||||
network in DVB. Its main use is in the unique identification of a service
|
||||
through the path @samp{Original_Network_ID, Transport_Stream_ID}. Default
|
||||
is @code{0x0001}.
|
||||
Option @option{mpegts_service_type} accepts the following values:
|
||||
|
||||
@item mpegts_service_id @var{integer}
|
||||
Set the @samp{service_id}, also known as program in DVB. Default is
|
||||
@code{0x0001}.
|
||||
|
||||
@item mpegts_service_type @var{integer}
|
||||
Set the program @samp{service_type}. Default is @code{digital_tv}.
|
||||
Accepts the following options:
|
||||
@table @samp
|
||||
@table @option
|
||||
@item hex_value
|
||||
Any hexdecimal value between @code{0x01} to @code{0xff} as defined in
|
||||
ETSI 300 468.
|
||||
Any hexdecimal value between 0x01 to 0xff as defined in ETSI 300 468.
|
||||
@item digital_tv
|
||||
Digital TV service.
|
||||
@item digital_radio
|
||||
@@ -1136,26 +1044,9 @@ Advanced Codec Digital SDTV service.
|
||||
Advanced Codec Digital HDTV service.
|
||||
@end table
|
||||
|
||||
@item mpegts_pmt_start_pid @var{integer}
|
||||
Set the first PID for PMT. Default is @code{0x1000}. Max is @code{0x1f00}.
|
||||
Option @option{mpegts_flags} may take a set of such flags:
|
||||
|
||||
@item mpegts_start_pid @var{integer}
|
||||
Set the first PID for data packets. Default is @code{0x0100}. Max is
|
||||
@code{0x0f00}.
|
||||
|
||||
@item mpegts_m2ts_mode @var{boolean}
|
||||
Enable m2ts mode if set to @code{1}. Default value is @code{-1} which
|
||||
disables m2ts mode.
|
||||
|
||||
@item muxrate @var{integer}
|
||||
Set a constant muxrate. Default is VBR.
|
||||
|
||||
@item pes_payload_size @var{integer}
|
||||
Set minimum PES packet payload in bytes. Default is @code{2930}.
|
||||
|
||||
@item mpegts_flags @var{flags}
|
||||
Set mpegts flags. Accepts the following options:
|
||||
@table @samp
|
||||
@table @option
|
||||
@item resend_headers
|
||||
Reemit PAT/PMT before writing the next packet.
|
||||
@item latm
|
||||
@@ -1164,47 +1055,6 @@ Use LATM packetization for AAC.
|
||||
Reemit PAT and PMT at each video frame.
|
||||
@item system_b
|
||||
Conform to System B (DVB) instead of System A (ATSC).
|
||||
@item initial_discontinuity
|
||||
Mark the initial packet of each stream as discontinuity.
|
||||
@end table
|
||||
|
||||
@item resend_headers @var{integer}
|
||||
Reemit PAT/PMT before writing the next packet. This option is deprecated:
|
||||
use @option{mpegts_flags} instead.
|
||||
|
||||
@item mpegts_copyts @var{boolean}
|
||||
Preserve original timestamps, if value is set to @code{1}. Default value
|
||||
is @code{-1}, which results in shifting timestamps so that they start from 0.
|
||||
|
||||
@item omit_video_pes_length @var{boolean}
|
||||
Omit the PES packet length for video packets. Default is @code{1} (true).
|
||||
|
||||
@item pcr_period @var{integer}
|
||||
Override the default PCR retransmission time in milliseconds. Ignored if
|
||||
variable muxrate is selected. Default is @code{20}.
|
||||
|
||||
@item pat_period @var{double}
|
||||
Maximum time in seconds between PAT/PMT tables.
|
||||
|
||||
@item sdt_period @var{double}
|
||||
Maximum time in seconds between SDT tables.
|
||||
|
||||
@item tables_version @var{integer}
|
||||
Set PAT, PMT and SDT version (default @code{0}, valid values are from 0 to 31, inclusively).
|
||||
This option allows updating stream structure so that standard consumer may
|
||||
detect the change. To do so, reopen output @code{AVFormatContext} (in case of API
|
||||
usage) or restart @command{ffmpeg} instance, cyclically changing
|
||||
@option{tables_version} value:
|
||||
|
||||
@example
|
||||
ffmpeg -i source1.ts -codec copy -f mpegts -tables_version 0 udp://1.1.1.1:1111
|
||||
ffmpeg -i source2.ts -codec copy -f mpegts -tables_version 1 udp://1.1.1.1:1111
|
||||
...
|
||||
ffmpeg -i source3.ts -codec copy -f mpegts -tables_version 31 udp://1.1.1.1:1111
|
||||
ffmpeg -i source1.ts -codec copy -f mpegts -tables_version 0 udp://1.1.1.1:1111
|
||||
ffmpeg -i source2.ts -codec copy -f mpegts -tables_version 1 udp://1.1.1.1:1111
|
||||
...
|
||||
@end example
|
||||
@end table
|
||||
|
||||
@subsection Example
|
||||
@@ -1218,7 +1068,7 @@ ffmpeg -i file.mpg -c copy \
|
||||
-mpegts_start_pid 0x150 \
|
||||
-metadata service_provider="Some provider" \
|
||||
-metadata service_name="Some Channel" \
|
||||
out.ts
|
||||
-y out.ts
|
||||
@end example
|
||||
|
||||
@section mxf, mxf_d10
|
||||
@@ -1467,6 +1317,9 @@ within the specified duration after the segmenting clock time. This way you
|
||||
can make the segmenter more resilient to backward local time jumps, such as
|
||||
leap seconds or transition to standard time from daylight savings time.
|
||||
|
||||
Assuming that the delay between the packets of your source is less than 0.5
|
||||
second you can detect a leap second by specifying 0.5 as the duration.
|
||||
|
||||
Default is the maximum possible duration which means starting a new segment
|
||||
regardless of the elapsed time since the last clock time.
|
||||
|
||||
@@ -1620,7 +1473,6 @@ Specify whether to remove all fragments when finished. Default 0 (do not remove)
|
||||
|
||||
@end table
|
||||
|
||||
@anchor{fifo}
|
||||
@section fifo
|
||||
|
||||
The fifo pseudo-muxer allows the separation of encoding and muxing by using
|
||||
@@ -1728,18 +1580,6 @@ with the tee muxer; encoding can be a very expensive process. It is not
|
||||
useful when using the libavformat API directly because it is then possible
|
||||
to feed the same packets to several muxers directly.
|
||||
|
||||
@table @option
|
||||
|
||||
@item use_fifo @var{bool}
|
||||
If set to 1, slave outputs will be processed in separate thread using @ref{fifo}
|
||||
muxer. This allows to compensate for different speed/latency/reliability of
|
||||
outputs and setup transparent recovery. By default this feature is turned off.
|
||||
|
||||
@item fifo_options
|
||||
Options to pass to fifo pseudo-muxer instances. See @ref{fifo}.
|
||||
|
||||
@end table
|
||||
|
||||
The slave outputs are specified in the file name given to the muxer,
|
||||
separated by '|'. If any of the slave name contains the '|' separator,
|
||||
leading or trailing spaces or any special character, it must be
|
||||
@@ -1761,13 +1601,6 @@ output name suffix.
|
||||
Specify a list of bitstream filters to apply to the specified
|
||||
output.
|
||||
|
||||
@item use_fifo @var{bool}
|
||||
This allows to override tee muxer use_fifo option for individual slave muxer.
|
||||
|
||||
@item fifo_options
|
||||
This allows to override tee muxer fifo_options for individual slave muxer.
|
||||
See @ref{fifo}.
|
||||
|
||||
It is possible to specify to which streams a given bitstream filter
|
||||
applies, by appending a stream specifier to the option separated by
|
||||
@code{/}. @var{spec} must be a stream specifier (see @ref{Format
|
||||
@@ -1816,7 +1649,7 @@ keyframes packets, as requested by the MPEG-TS format. The select
|
||||
option is applied to @file{out.aac} in order to make it contain only
|
||||
audio packets.
|
||||
@example
|
||||
ffmpeg -i ... -map 0 -flags +global_header -c:v libx264 -c:a aac
|
||||
ffmpeg -i ... -map 0 -flags +global_header -c:v libx264 -c:a aac -strict experimental
|
||||
-f tee "[bsfs/v=dump_extra]out.ts|[movflags=+faststart]out.mp4|[select=a]out.aac"
|
||||
@end example
|
||||
|
||||
@@ -1825,7 +1658,7 @@ As below, but select only stream @code{a:1} for the audio output. Note
|
||||
that a second level escaping must be performed, as ":" is a special
|
||||
character used to separate options.
|
||||
@example
|
||||
ffmpeg -i ... -map 0 -flags +global_header -c:v libx264 -c:a aac
|
||||
ffmpeg -i ... -map 0 -flags +global_header -c:v libx264 -c:a aac -strict experimental
|
||||
-f tee "[bsfs/v=dump_extra]out.ts|[movflags=+faststart]out.mp4|[select=\'a:1\']out.aac"
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@@ -142,7 +142,7 @@ Alignment:
|
||||
Some instructions on some architectures have strict alignment restrictions,
|
||||
for example most SSE/SSE2 instructions on x86.
|
||||
The minimum guaranteed alignment is written in the .h files, for example:
|
||||
void (*put_pixels_clamped)(const int16_t *block/*align 16*/, uint8_t *pixels/*align 8*/, ptrdiff_t stride);
|
||||
void (*put_pixels_clamped)(const int16_t *block/*align 16*/, UINT8 *pixels/*align 8*/, int line_size);
|
||||
|
||||
|
||||
General Tips:
|
||||
|
||||
@@ -131,8 +131,8 @@ and @code{--extra-ldflags}.
|
||||
On Windows, you need to run the IDL files through @command{widl}.
|
||||
|
||||
DeckLink is very picky about the formats it supports. Pixel format is always
|
||||
uyvy422, framerate, field order and video size must be determined for your
|
||||
device with @command{-list_formats 1}. Audio sample rate is always 48 kHz.
|
||||
uyvy422, framerate and video size must be determined for your device with
|
||||
@command{-list_formats 1}. Audio sample rate is always 48 kHz.
|
||||
|
||||
@subsection Options
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
|
||||
@@ -31,16 +30,11 @@
|
||||
// for the target. without this build breaks on mingw
|
||||
#define AVFORMAT_OS_SUPPORT_H
|
||||
|
||||
#include "libavutil/attributes.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
/* Forcibly turn off deprecation warnings, which just add noise here. */
|
||||
#undef attribute_deprecated
|
||||
#define attribute_deprecated
|
||||
|
||||
#include "libavcodec/options_table.h"
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavformat/options_table.h"
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavcodec/options_table.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
static void print_usage(void)
|
||||
{
|
||||
|
||||
@@ -5,11 +5,6 @@ The libavformat library provides some generic global options, which
|
||||
can be set on all the protocols. In addition each protocol may support
|
||||
so-called private options, which are specific for that component.
|
||||
|
||||
Options may be set by specifying -@var{option} @var{value} in the
|
||||
FFmpeg tools, or by setting the value explicitly in the
|
||||
@code{AVFormatContext} options or using the @file{libavutil/opt.h} API
|
||||
for programmatic use.
|
||||
|
||||
The list of supported options follows:
|
||||
|
||||
@table @option
|
||||
@@ -520,41 +515,6 @@ time, which is valuable if data transmission is slow.
|
||||
Note that some formats (typically MOV), require the output protocol to
|
||||
be seekable, so they will fail with the pipe output protocol.
|
||||
|
||||
@section prompeg
|
||||
|
||||
Pro-MPEG Code of Practice #3 Release 2 FEC protocol.
|
||||
|
||||
The Pro-MPEG CoP#3 FEC is a 2D parity-check forward error correction mechanism
|
||||
for MPEG-2 Transport Streams sent over RTP.
|
||||
|
||||
This protocol must be used in conjunction with the @code{rtp_mpegts} muxer and
|
||||
the @code{rtp} protocol.
|
||||
|
||||
The required syntax is:
|
||||
@example
|
||||
-f rtp_mpegts -fec prompeg=@var{option}=@var{val}... rtp://@var{hostname}:@var{port}
|
||||
@end example
|
||||
|
||||
The destination UDP ports are @code{port + 2} for the column FEC stream
|
||||
and @code{port + 4} for the row FEC stream.
|
||||
|
||||
This protocol accepts the following options:
|
||||
@table @option
|
||||
|
||||
@item l=@var{n}
|
||||
The number of columns (4-20, LxD <= 100)
|
||||
|
||||
@item d=@var{n}
|
||||
The number of rows (4-20, LxD <= 100)
|
||||
|
||||
@end table
|
||||
|
||||
Example usage:
|
||||
|
||||
@example
|
||||
-f rtp_mpegts -fec prompeg=l=8:d=4 rtp://@var{hostname}:@var{port}
|
||||
@end example
|
||||
|
||||
@section rtmp
|
||||
|
||||
Real-Time Messaging Protocol.
|
||||
|
||||
@@ -132,13 +132,12 @@ For swr only, set resampling phase shift, default value is 10, and must be in
|
||||
the interval [0,30].
|
||||
|
||||
@item linear_interp
|
||||
Use linear interpolation when enabled (the default). Disable it if you want
|
||||
to preserve speed instead of quality when exact_rational fails.
|
||||
Use linear interpolation if set to 1, default value is 0.
|
||||
|
||||
@item exact_rational
|
||||
For swr only, when enabled, try to use exact phase_count based on input and
|
||||
output sample rate. However, if it is larger than @code{1 << phase_shift},
|
||||
the phase_count will be @code{1 << phase_shift} as fallback. Default is enabled.
|
||||
the phase_count will be @code{1 << phase_shift} as fallback. Default is disabled.
|
||||
|
||||
@item cutoff
|
||||
Set cutoff frequency (swr: 6dB point; soxr: 0dB point) ratio; must be a float
|
||||
|
||||
@@ -13,8 +13,7 @@ FFmpeg tools. For programmatic use, they can be set explicitly in the
|
||||
@anchor{sws_flags}
|
||||
@item sws_flags
|
||||
Set the scaler flags. This is also used to set the scaling
|
||||
algorithm. Only a single algorithm should be selected. Default
|
||||
value is @samp{bicubic}.
|
||||
algorithm. Only a single algorithm should be selected.
|
||||
|
||||
It accepts the following values:
|
||||
@table @samp
|
||||
|
||||
@@ -719,24 +719,19 @@ the name of a standard channel layout (e.g. @samp{mono},
|
||||
the name of a single channel (e.g. @samp{FL}, @samp{FR}, @samp{FC}, @samp{LFE}, etc.)
|
||||
|
||||
@item
|
||||
a number of channels, in decimal, followed by 'c', yielding the default channel
|
||||
layout for that number of channels (see the function
|
||||
@code{av_get_default_channel_layout}). Note that not all channel counts have a
|
||||
default layout.
|
||||
|
||||
@item
|
||||
a number of channels, in decimal, followed by 'C', yielding an unknown channel
|
||||
layout with the specified number of channels. Note that not all channel layout
|
||||
specification strings support unknown channel layouts.
|
||||
a number of channels, in decimal, optionally followed by 'c', yielding
|
||||
the default channel layout for that number of channels (see the
|
||||
function @code{av_get_default_channel_layout})
|
||||
|
||||
@item
|
||||
a channel layout mask, in hexadecimal starting with "0x" (see the
|
||||
@code{AV_CH_*} macros in @file{libavutil/channel_layout.h}.
|
||||
@end itemize
|
||||
|
||||
Before libavutil version 53 the trailing character "c" to specify a number of
|
||||
channels was optional, but now it is required, while a channel layout mask can
|
||||
also be specified as a decimal number (if and only if not followed by "c" or "C").
|
||||
Starting from libavutil version 53 the trailing character "c" to
|
||||
specify a number of channels will be required, while a channel layout
|
||||
mask could also be specified as a decimal number (if and only if not
|
||||
followed by "c").
|
||||
|
||||
See also the function @code{av_get_channel_layout} defined in
|
||||
@file{libavutil/channel_layout.h}.
|
||||
@@ -776,9 +771,6 @@ Compute arcsine of @var{x}.
|
||||
@item atan(x)
|
||||
Compute arctangent of @var{x}.
|
||||
|
||||
@item atan2(x, y)
|
||||
Compute principal value of the arc tangent of @var{y}/@var{x}.
|
||||
|
||||
@item between(x, min, max)
|
||||
Return 1 if @var{x} is greater than or equal to @var{min} and lesser than or
|
||||
equal to @var{max}, 0 otherwise.
|
||||
|
||||
65
ffmpeg.h
65
ffmpeg.h
@@ -224,8 +224,6 @@ typedef struct OptionsContext {
|
||||
int nb_disposition;
|
||||
SpecifierOpt *program;
|
||||
int nb_program;
|
||||
SpecifierOpt *time_bases;
|
||||
int nb_time_bases;
|
||||
} OptionsContext;
|
||||
|
||||
typedef struct InputFilter {
|
||||
@@ -233,23 +231,6 @@ typedef struct InputFilter {
|
||||
struct InputStream *ist;
|
||||
struct FilterGraph *graph;
|
||||
uint8_t *name;
|
||||
enum AVMediaType type; // AVMEDIA_TYPE_SUBTITLE for sub2video
|
||||
|
||||
AVFifoBuffer *frame_queue;
|
||||
|
||||
// parameters configured for this input
|
||||
int format;
|
||||
|
||||
int width, height;
|
||||
AVRational sample_aspect_ratio;
|
||||
|
||||
int sample_rate;
|
||||
int channels;
|
||||
uint64_t channel_layout;
|
||||
|
||||
AVBufferRef *hw_frames_ctx;
|
||||
|
||||
int eof;
|
||||
} InputFilter;
|
||||
|
||||
typedef struct OutputFilter {
|
||||
@@ -261,18 +242,6 @@ typedef struct OutputFilter {
|
||||
/* temporary storage until stream maps are processed */
|
||||
AVFilterInOut *out_tmp;
|
||||
enum AVMediaType type;
|
||||
|
||||
/* desired output stream properties */
|
||||
int width, height;
|
||||
AVRational frame_rate;
|
||||
int format;
|
||||
int sample_rate;
|
||||
uint64_t channel_layout;
|
||||
|
||||
// those are only set if no format is specified and the encoder gives us multiple options
|
||||
int *formats;
|
||||
uint64_t *channel_layouts;
|
||||
int *sample_rates;
|
||||
} OutputFilter;
|
||||
|
||||
typedef struct FilterGraph {
|
||||
@@ -316,11 +285,6 @@ typedef struct InputStream {
|
||||
|
||||
int64_t min_pts; /* pts with the smallest value in a current stream */
|
||||
int64_t max_pts; /* pts with the higher value in a current stream */
|
||||
|
||||
// when forcing constant input framerate through -r,
|
||||
// this contains the pts that will be given to the next decoded frame
|
||||
int64_t cfr_next_pts;
|
||||
|
||||
int64_t nb_samples; /* number of samples in the last decoded audio frame before looping */
|
||||
|
||||
double ts_scale;
|
||||
@@ -331,6 +295,14 @@ typedef struct InputStream {
|
||||
int guess_layout_max;
|
||||
|
||||
int autorotate;
|
||||
int resample_height;
|
||||
int resample_width;
|
||||
int resample_pix_fmt;
|
||||
|
||||
int resample_sample_fmt;
|
||||
int resample_sample_rate;
|
||||
int resample_channels;
|
||||
uint64_t resample_channel_layout;
|
||||
|
||||
int fix_sub_duration;
|
||||
struct { /* previous decoded subtitle and related variables */
|
||||
@@ -342,7 +314,6 @@ typedef struct InputStream {
|
||||
struct sub2video {
|
||||
int64_t last_pts;
|
||||
int64_t end_pts;
|
||||
AVFifoBuffer *sub_queue; ///< queue of AVSubtitle* before filter init
|
||||
AVFrame *frame;
|
||||
int w, h;
|
||||
} sub2video;
|
||||
@@ -382,8 +353,6 @@ typedef struct InputStream {
|
||||
|
||||
int64_t *dts_buffer;
|
||||
int nb_dts_buffer;
|
||||
|
||||
int got_output;
|
||||
} InputStream;
|
||||
|
||||
typedef struct InputFile {
|
||||
@@ -451,8 +420,6 @@ typedef struct OutputStream {
|
||||
int64_t first_pts;
|
||||
/* dts of the last packet sent to the muxer */
|
||||
int64_t last_mux_dts;
|
||||
// the timebase of the packets sent to the muxer
|
||||
AVRational mux_timebase;
|
||||
|
||||
int nb_bitstream_filters;
|
||||
uint8_t *bsf_extradata_updated;
|
||||
@@ -475,7 +442,6 @@ typedef struct OutputStream {
|
||||
int force_fps;
|
||||
int top_field_first;
|
||||
int rotate_overridden;
|
||||
double rotate_override_value;
|
||||
|
||||
AVRational frame_aspect_ratio;
|
||||
|
||||
@@ -513,8 +479,6 @@ typedef struct OutputStream {
|
||||
// parameters are set in the AVStream.
|
||||
int initialized;
|
||||
|
||||
int inputs_done;
|
||||
|
||||
const char *attachment_filename;
|
||||
int copy_initial_nonkeyframes;
|
||||
int copy_prior_start;
|
||||
@@ -605,19 +569,12 @@ extern AVIOContext *progress_avio;
|
||||
extern float max_error_rate;
|
||||
extern char *videotoolbox_pixfmt;
|
||||
|
||||
extern int filter_nbthreads;
|
||||
extern int filter_complex_nbthreads;
|
||||
extern int vstats_version;
|
||||
|
||||
extern const AVIOInterruptCB int_cb;
|
||||
|
||||
extern const OptionDef options[];
|
||||
extern const HWAccel hwaccels[];
|
||||
extern int hwaccel_lax_profile_check;
|
||||
extern AVBufferRef *hw_device_ctx;
|
||||
#if CONFIG_QSV
|
||||
extern char *qsv_device;
|
||||
#endif
|
||||
|
||||
|
||||
void term_init(void);
|
||||
@@ -643,10 +600,6 @@ int filtergraph_is_simple(FilterGraph *fg);
|
||||
int init_simple_filtergraph(InputStream *ist, OutputStream *ost);
|
||||
int init_complex_filtergraph(FilterGraph *fg);
|
||||
|
||||
void sub2video_update(InputStream *ist, AVSubtitle *sub);
|
||||
|
||||
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame);
|
||||
|
||||
int ffmpeg_parse_options(int argc, char **argv);
|
||||
|
||||
int vdpau_init(AVCodecContext *s);
|
||||
@@ -654,8 +607,10 @@ int dxva2_init(AVCodecContext *s);
|
||||
int vda_init(AVCodecContext *s);
|
||||
int videotoolbox_init(AVCodecContext *s);
|
||||
int qsv_init(AVCodecContext *s);
|
||||
int qsv_transcode_init(OutputStream *ost);
|
||||
int vaapi_decode_init(AVCodecContext *avctx);
|
||||
int vaapi_device_init(const char *device);
|
||||
int cuvid_init(AVCodecContext *s);
|
||||
int cuvid_transcode_init(OutputStream *ost);
|
||||
|
||||
#endif /* FFMPEG_H */
|
||||
|
||||
158
ffmpeg_cuvid.c
158
ffmpeg_cuvid.c
@@ -17,57 +17,139 @@
|
||||
*/
|
||||
|
||||
#include "libavutil/hwcontext.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
|
||||
#include "ffmpeg.h"
|
||||
|
||||
typedef struct CUVIDContext {
|
||||
AVBufferRef *hw_frames_ctx;
|
||||
} CUVIDContext;
|
||||
|
||||
static void cuvid_uninit(AVCodecContext *avctx)
|
||||
{
|
||||
InputStream *ist = avctx->opaque;
|
||||
InputStream *ist = avctx->opaque;
|
||||
CUVIDContext *ctx = ist->hwaccel_ctx;
|
||||
|
||||
if (ctx) {
|
||||
av_buffer_unref(&ctx->hw_frames_ctx);
|
||||
av_freep(&ctx);
|
||||
}
|
||||
|
||||
av_buffer_unref(&ist->hw_frames_ctx);
|
||||
|
||||
ist->hwaccel_ctx = 0;
|
||||
ist->hwaccel_uninit = 0;
|
||||
}
|
||||
|
||||
int cuvid_init(AVCodecContext *avctx)
|
||||
{
|
||||
InputStream *ist = avctx->opaque;
|
||||
AVHWFramesContext *frames_ctx;
|
||||
int ret;
|
||||
InputStream *ist = avctx->opaque;
|
||||
CUVIDContext *ctx = ist->hwaccel_ctx;
|
||||
|
||||
av_log(avctx, AV_LOG_VERBOSE, "Initializing cuvid hwaccel\n");
|
||||
av_log(NULL, AV_LOG_TRACE, "Initializing cuvid hwaccel\n");
|
||||
|
||||
if (!hw_device_ctx) {
|
||||
ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_CUDA,
|
||||
ist->hwaccel_device, NULL, 0);
|
||||
if (ret < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error creating a CUDA device\n");
|
||||
return ret;
|
||||
}
|
||||
if (!ctx) {
|
||||
av_log(NULL, AV_LOG_ERROR, "CUVID transcoding is not initialized. "
|
||||
"-hwaccel cuvid should only be used for one-to-one CUVID transcoding "
|
||||
"with no (software) filters.\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cuvid_transcode_init(OutputStream *ost)
|
||||
{
|
||||
InputStream *ist;
|
||||
const enum AVPixelFormat *pix_fmt;
|
||||
AVHWFramesContext *hwframe_ctx;
|
||||
AVBufferRef *device_ref = NULL;
|
||||
CUVIDContext *ctx = NULL;
|
||||
int ret = 0;
|
||||
|
||||
av_log(NULL, AV_LOG_TRACE, "Initializing cuvid transcoding\n");
|
||||
|
||||
if (ost->source_index < 0)
|
||||
return 0;
|
||||
|
||||
ist = input_streams[ost->source_index];
|
||||
|
||||
/* check if the encoder supports CUVID */
|
||||
if (!ost->enc->pix_fmts)
|
||||
goto cancel;
|
||||
for (pix_fmt = ost->enc->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++)
|
||||
if (*pix_fmt == AV_PIX_FMT_CUDA)
|
||||
break;
|
||||
if (*pix_fmt == AV_PIX_FMT_NONE)
|
||||
goto cancel;
|
||||
|
||||
/* check if the decoder supports CUVID */
|
||||
if (ist->hwaccel_id != HWACCEL_CUVID || !ist->dec || !ist->dec->pix_fmts)
|
||||
goto cancel;
|
||||
for (pix_fmt = ist->dec->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++)
|
||||
if (*pix_fmt == AV_PIX_FMT_CUDA)
|
||||
break;
|
||||
if (*pix_fmt == AV_PIX_FMT_NONE)
|
||||
goto cancel;
|
||||
|
||||
av_log(NULL, AV_LOG_VERBOSE, "Setting up CUVID transcoding\n");
|
||||
|
||||
if (ist->hwaccel_ctx) {
|
||||
ctx = ist->hwaccel_ctx;
|
||||
} else {
|
||||
ctx = av_mallocz(sizeof(*ctx));
|
||||
if (!ctx) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctx->hw_frames_ctx) {
|
||||
ret = av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_CUDA,
|
||||
ist->hwaccel_device, NULL, 0);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
ctx->hw_frames_ctx = av_hwframe_ctx_alloc(device_ref);
|
||||
if (!ctx->hw_frames_ctx) {
|
||||
av_log(NULL, AV_LOG_ERROR, "av_hwframe_ctx_alloc failed\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto error;
|
||||
}
|
||||
av_buffer_unref(&device_ref);
|
||||
|
||||
ist->hw_frames_ctx = av_buffer_ref(ctx->hw_frames_ctx);
|
||||
if (!ist->hw_frames_ctx) {
|
||||
av_log(NULL, AV_LOG_ERROR, "av_buffer_ref failed\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ist->hwaccel_ctx = ctx;
|
||||
ist->resample_pix_fmt = AV_PIX_FMT_CUDA;
|
||||
ist->hwaccel_uninit = cuvid_uninit;
|
||||
|
||||
/* This is a bit hacky, av_hwframe_ctx_init is called by the cuvid decoder
|
||||
* once it has probed the necessary format information. But as filters/nvenc
|
||||
* need to know the format/sw_format, set them here so they are happy.
|
||||
* This is fine as long as CUVID doesn't add another supported pix_fmt.
|
||||
*/
|
||||
hwframe_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data;
|
||||
hwframe_ctx->format = AV_PIX_FMT_CUDA;
|
||||
hwframe_ctx->sw_format = AV_PIX_FMT_NV12;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
av_freep(&ctx);
|
||||
av_buffer_unref(&device_ref);
|
||||
return ret;
|
||||
|
||||
cancel:
|
||||
if (ist->hwaccel_id == HWACCEL_CUVID) {
|
||||
av_log(NULL, AV_LOG_ERROR, "CUVID hwaccel requested, but impossible to achieve.\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
av_buffer_unref(&ist->hw_frames_ctx);
|
||||
ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx);
|
||||
if (!ist->hw_frames_ctx) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error creating a CUDA frames context\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
frames_ctx = (AVHWFramesContext*)ist->hw_frames_ctx->data;
|
||||
|
||||
frames_ctx->format = AV_PIX_FMT_CUDA;
|
||||
frames_ctx->sw_format = avctx->sw_pix_fmt;
|
||||
frames_ctx->width = avctx->width;
|
||||
frames_ctx->height = avctx->height;
|
||||
|
||||
av_log(avctx, AV_LOG_DEBUG, "Initializing CUDA frames context: sw_format = %s, width = %d, height = %d\n",
|
||||
av_get_pix_fmt_name(frames_ctx->sw_format), frames_ctx->width, frames_ctx->height);
|
||||
|
||||
ret = av_hwframe_ctx_init(ist->hw_frames_ctx);
|
||||
if (ret < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error initializing a CUDA frame pool\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ist->hwaccel_uninit = cuvid_uninit;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
281
ffmpeg_filter.c
281
ffmpeg_filter.c
@@ -111,16 +111,16 @@ void choose_sample_fmt(AVStream *st, AVCodec *codec)
|
||||
}
|
||||
}
|
||||
|
||||
static char *choose_pix_fmts(OutputFilter *ofilter)
|
||||
static char *choose_pix_fmts(OutputStream *ost)
|
||||
{
|
||||
OutputStream *ost = ofilter->ost;
|
||||
AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, "strict", NULL, 0);
|
||||
if (strict_dict)
|
||||
// used by choose_pixel_fmt() and below
|
||||
av_opt_set(ost->enc_ctx, "strict", strict_dict->value, 0);
|
||||
|
||||
if (ost->keep_pix_fmt) {
|
||||
avfilter_graph_set_auto_convert(ofilter->graph->graph,
|
||||
if (ost->filter)
|
||||
avfilter_graph_set_auto_convert(ost->filter->graph->graph,
|
||||
AVFILTER_AUTO_CONVERT_NONE);
|
||||
if (ost->enc_ctx->pix_fmt == AV_PIX_FMT_NONE)
|
||||
return NULL;
|
||||
@@ -155,13 +155,13 @@ static char *choose_pix_fmts(OutputFilter *ofilter)
|
||||
|
||||
/* Define a function for building a string containing a list of
|
||||
* allowed formats. */
|
||||
#define DEF_CHOOSE_FORMAT(suffix, type, var, supported_list, none, get_name) \
|
||||
static char *choose_ ## suffix (OutputFilter *ofilter) \
|
||||
#define DEF_CHOOSE_FORMAT(type, var, supported_list, none, get_name) \
|
||||
static char *choose_ ## var ## s(OutputStream *ost) \
|
||||
{ \
|
||||
if (ofilter->var != none) { \
|
||||
get_name(ofilter->var); \
|
||||
if (ost->enc_ctx->var != none) { \
|
||||
get_name(ost->enc_ctx->var); \
|
||||
return av_strdup(name); \
|
||||
} else if (ofilter->supported_list) { \
|
||||
} else if (ost->enc && ost->enc->supported_list) { \
|
||||
const type *p; \
|
||||
AVIOContext *s = NULL; \
|
||||
uint8_t *ret; \
|
||||
@@ -170,7 +170,7 @@ static char *choose_ ## suffix (OutputFilter *ofilter) \
|
||||
if (avio_open_dyn_buf(&s) < 0) \
|
||||
exit_program(1); \
|
||||
\
|
||||
for (p = ofilter->supported_list; *p != none; p++) { \
|
||||
for (p = ost->enc->supported_list; *p != none; p++) { \
|
||||
get_name(*p); \
|
||||
avio_printf(s, "%s|", name); \
|
||||
} \
|
||||
@@ -181,16 +181,16 @@ static char *choose_ ## suffix (OutputFilter *ofilter) \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
//DEF_CHOOSE_FORMAT(pix_fmts, enum AVPixelFormat, format, formats, AV_PIX_FMT_NONE,
|
||||
// GET_PIX_FMT_NAME)
|
||||
// DEF_CHOOSE_FORMAT(enum AVPixelFormat, pix_fmt, pix_fmts, AV_PIX_FMT_NONE,
|
||||
// GET_PIX_FMT_NAME)
|
||||
|
||||
DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
|
||||
DEF_CHOOSE_FORMAT(enum AVSampleFormat, sample_fmt, sample_fmts,
|
||||
AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME)
|
||||
|
||||
DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
|
||||
DEF_CHOOSE_FORMAT(int, sample_rate, supported_samplerates, 0,
|
||||
GET_SAMPLE_RATE_NAME)
|
||||
|
||||
DEF_CHOOSE_FORMAT(channel_layouts, uint64_t, channel_layout, channel_layouts, 0,
|
||||
DEF_CHOOSE_FORMAT(uint64_t, channel_layout, channel_layouts, 0,
|
||||
GET_CH_LAYOUT_NAME)
|
||||
|
||||
int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
|
||||
@@ -206,7 +206,6 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
|
||||
exit_program(1);
|
||||
fg->outputs[0]->ost = ost;
|
||||
fg->outputs[0]->graph = fg;
|
||||
fg->outputs[0]->format = -1;
|
||||
|
||||
ost->filter = fg->outputs[0];
|
||||
|
||||
@@ -215,11 +214,6 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
|
||||
exit_program(1);
|
||||
fg->inputs[0]->ist = ist;
|
||||
fg->inputs[0]->graph = fg;
|
||||
fg->inputs[0]->format = -1;
|
||||
|
||||
fg->inputs[0]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
|
||||
if (!fg->inputs[0]->frame_queue)
|
||||
exit_program(1);
|
||||
|
||||
GROW_ARRAY(ist->filters, ist->nb_filters);
|
||||
ist->filters[ist->nb_filters - 1] = fg->inputs[0];
|
||||
@@ -230,25 +224,6 @@ int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
|
||||
{
|
||||
AVFilterContext *ctx = inout->filter_ctx;
|
||||
AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads;
|
||||
int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs;
|
||||
AVIOContext *pb;
|
||||
uint8_t *res = NULL;
|
||||
|
||||
if (avio_open_dyn_buf(&pb) < 0)
|
||||
exit_program(1);
|
||||
|
||||
avio_printf(pb, "%s", ctx->filter->name);
|
||||
if (nb_pads > 1)
|
||||
avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));
|
||||
avio_w8(pb, 0);
|
||||
avio_close_dyn_buf(pb, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
|
||||
{
|
||||
InputStream *ist = NULL;
|
||||
@@ -317,13 +292,6 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
|
||||
exit_program(1);
|
||||
fg->inputs[fg->nb_inputs - 1]->ist = ist;
|
||||
fg->inputs[fg->nb_inputs - 1]->graph = fg;
|
||||
fg->inputs[fg->nb_inputs - 1]->format = -1;
|
||||
fg->inputs[fg->nb_inputs - 1]->type = ist->st->codecpar->codec_type;
|
||||
fg->inputs[fg->nb_inputs - 1]->name = describe_filter_link(fg, in, 1);
|
||||
|
||||
fg->inputs[fg->nb_inputs - 1]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
|
||||
if (!fg->inputs[fg->nb_inputs - 1]->frame_queue)
|
||||
exit_program(1);
|
||||
|
||||
GROW_ARRAY(ist->filters, ist->nb_filters);
|
||||
ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
|
||||
@@ -358,7 +326,6 @@ int init_complex_filtergraph(FilterGraph *fg)
|
||||
fg->outputs[fg->nb_outputs - 1]->out_tmp = cur;
|
||||
fg->outputs[fg->nb_outputs - 1]->type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
|
||||
cur->pad_idx);
|
||||
fg->outputs[fg->nb_outputs - 1]->name = describe_filter_link(fg, cur, 0);
|
||||
cur = cur->next;
|
||||
fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL;
|
||||
}
|
||||
@@ -447,12 +414,13 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
char *pix_fmts;
|
||||
OutputStream *ost = ofilter->ost;
|
||||
OutputFile *of = output_files[ost->file_index];
|
||||
AVCodecContext *codec = ost->enc_ctx;
|
||||
AVFilterContext *last_filter = out->filter_ctx;
|
||||
int pad_idx = out->pad_idx;
|
||||
int ret;
|
||||
char name[255];
|
||||
|
||||
snprintf(name, sizeof(name), "out_%d_%d", ost->file_index, ost->index);
|
||||
snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index);
|
||||
ret = avfilter_graph_create_filter(&ofilter->filter,
|
||||
avfilter_get_by_name("buffersink"),
|
||||
name, NULL, NULL, fg->graph);
|
||||
@@ -460,20 +428,21 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ofilter->width || ofilter->height) {
|
||||
if (!hw_device_ctx && (codec->width || codec->height)) {
|
||||
char args[255];
|
||||
AVFilterContext *filter;
|
||||
AVDictionaryEntry *e = NULL;
|
||||
|
||||
snprintf(args, sizeof(args), "%d:%d",
|
||||
ofilter->width, ofilter->height);
|
||||
codec->width,
|
||||
codec->height);
|
||||
|
||||
while ((e = av_dict_get(ost->sws_dict, "", e,
|
||||
AV_DICT_IGNORE_SUFFIX))) {
|
||||
av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "scaler_out_%d_%d",
|
||||
snprintf(name, sizeof(name), "scaler for output stream %d:%d",
|
||||
ost->file_index, ost->index);
|
||||
if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
|
||||
name, args, NULL, fg->graph)) < 0)
|
||||
@@ -485,9 +454,9 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
pad_idx = 0;
|
||||
}
|
||||
|
||||
if ((pix_fmts = choose_pix_fmts(ofilter))) {
|
||||
if ((pix_fmts = choose_pix_fmts(ost))) {
|
||||
AVFilterContext *filter;
|
||||
snprintf(name, sizeof(name), "format_out_%d_%d",
|
||||
snprintf(name, sizeof(name), "pixel format for output stream %d:%d",
|
||||
ost->file_index, ost->index);
|
||||
ret = avfilter_graph_create_filter(&filter,
|
||||
avfilter_get_by_name("format"),
|
||||
@@ -508,7 +477,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
|
||||
snprintf(args, sizeof(args), "fps=%d/%d", ost->frame_rate.num,
|
||||
ost->frame_rate.den);
|
||||
snprintf(name, sizeof(name), "fps_out_%d_%d",
|
||||
snprintf(name, sizeof(name), "fps for output stream %d:%d",
|
||||
ost->file_index, ost->index);
|
||||
ret = avfilter_graph_create_filter(&fps, avfilter_get_by_name("fps"),
|
||||
name, args, NULL, fg->graph);
|
||||
@@ -522,7 +491,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
pad_idx = 0;
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "trim_out_%d_%d",
|
||||
snprintf(name, sizeof(name), "trim for output stream %d:%d",
|
||||
ost->file_index, ost->index);
|
||||
ret = insert_trim(of->start_time, of->recording_time,
|
||||
&last_filter, &pad_idx, name);
|
||||
@@ -547,7 +516,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
char name[255];
|
||||
int ret;
|
||||
|
||||
snprintf(name, sizeof(name), "out_%d_%d", ost->file_index, ost->index);
|
||||
snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index);
|
||||
ret = avfilter_graph_create_filter(&ofilter->filter,
|
||||
avfilter_get_by_name("abuffersink"),
|
||||
name, NULL, NULL, fg->graph);
|
||||
@@ -592,9 +561,9 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
if (codec->channels && !codec->channel_layout)
|
||||
codec->channel_layout = av_get_default_channel_layout(codec->channels);
|
||||
|
||||
sample_fmts = choose_sample_fmts(ofilter);
|
||||
sample_rates = choose_sample_rates(ofilter);
|
||||
channel_layouts = choose_channel_layouts(ofilter);
|
||||
sample_fmts = choose_sample_fmts(ost);
|
||||
sample_rates = choose_sample_rates(ost);
|
||||
channel_layouts = choose_channel_layouts(ost);
|
||||
if (sample_fmts || sample_rates || channel_layouts) {
|
||||
AVFilterContext *format;
|
||||
char args[256];
|
||||
@@ -614,7 +583,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
av_freep(&sample_rates);
|
||||
av_freep(&channel_layouts);
|
||||
|
||||
snprintf(name, sizeof(name), "format_out_%d_%d",
|
||||
snprintf(name, sizeof(name), "audio format for output stream %d:%d",
|
||||
ost->file_index, ost->index);
|
||||
ret = avfilter_graph_create_filter(&format,
|
||||
avfilter_get_by_name("aformat"),
|
||||
@@ -664,8 +633,28 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DESCRIBE_FILTER_LINK(f, inout, in) \
|
||||
{ \
|
||||
AVFilterContext *ctx = inout->filter_ctx; \
|
||||
AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads; \
|
||||
int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs; \
|
||||
AVIOContext *pb; \
|
||||
\
|
||||
if (avio_open_dyn_buf(&pb) < 0) \
|
||||
exit_program(1); \
|
||||
\
|
||||
avio_printf(pb, "%s", ctx->filter->name); \
|
||||
if (nb_pads > 1) \
|
||||
avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));\
|
||||
avio_w8(pb, 0); \
|
||||
avio_close_dyn_buf(pb, &f->name); \
|
||||
}
|
||||
|
||||
int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
|
||||
{
|
||||
av_freep(&ofilter->name);
|
||||
DESCRIBE_FILTER_LINK(ofilter, out, 0);
|
||||
|
||||
if (!ofilter->ost) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Filter %s has an unconnected output\n", ofilter->name);
|
||||
exit_program(1);
|
||||
@@ -678,7 +667,7 @@ int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOu
|
||||
}
|
||||
}
|
||||
|
||||
static int sub2video_prepare(InputStream *ist, InputFilter *ifilter)
|
||||
static int sub2video_prepare(InputStream *ist)
|
||||
{
|
||||
AVFormatContext *avf = input_files[ist->file_index]->ctx;
|
||||
int i, w, h;
|
||||
@@ -686,8 +675,8 @@ static int sub2video_prepare(InputStream *ist, InputFilter *ifilter)
|
||||
/* Compute the size of the canvas for the subtitles stream.
|
||||
If the subtitles codecpar has set a size, use it. Otherwise use the
|
||||
maximum dimensions of the video streams in the same file. */
|
||||
w = ifilter->width;
|
||||
h = ifilter->height;
|
||||
w = ist->dec_ctx->width;
|
||||
h = ist->dec_ctx->height;
|
||||
if (!(w && h)) {
|
||||
for (i = 0; i < avf->nb_streams; i++) {
|
||||
if (avf->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
@@ -701,15 +690,12 @@ static int sub2video_prepare(InputStream *ist, InputFilter *ifilter)
|
||||
}
|
||||
av_log(avf, AV_LOG_INFO, "sub2video: using %dx%d canvas\n", w, h);
|
||||
}
|
||||
ist->sub2video.w = ifilter->width = w;
|
||||
ist->sub2video.h = ifilter->height = h;
|
||||
|
||||
ifilter->width = ist->dec_ctx->width ? ist->dec_ctx->width : ist->sub2video.w;
|
||||
ifilter->height = ist->dec_ctx->height ? ist->dec_ctx->height : ist->sub2video.h;
|
||||
ist->sub2video.w = ist->resample_width = w;
|
||||
ist->sub2video.h = ist->resample_height = h;
|
||||
|
||||
/* rectangles are AV_PIX_FMT_PAL8, but we have no guarantee that the
|
||||
palettes for all rectangles are identical or compatible */
|
||||
ifilter->format = AV_PIX_FMT_RGB32;
|
||||
ist->resample_pix_fmt = ist->dec_ctx->pix_fmt = AV_PIX_FMT_RGB32;
|
||||
|
||||
ist->sub2video.frame = av_frame_alloc();
|
||||
if (!ist->sub2video.frame)
|
||||
@@ -750,19 +736,22 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
fr = av_guess_frame_rate(input_files[ist->file_index]->ctx, ist->st, NULL);
|
||||
|
||||
if (ist->dec_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
||||
ret = sub2video_prepare(ist, ifilter);
|
||||
ret = sub2video_prepare(ist);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sar = ifilter->sample_aspect_ratio;
|
||||
sar = ist->st->sample_aspect_ratio.num ?
|
||||
ist->st->sample_aspect_ratio :
|
||||
ist->dec_ctx->sample_aspect_ratio;
|
||||
if(!sar.den)
|
||||
sar = (AVRational){0,1};
|
||||
av_bprint_init(&args, 0, 1);
|
||||
av_bprintf(&args,
|
||||
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:"
|
||||
"pixel_aspect=%d/%d:sws_param=flags=%d",
|
||||
ifilter->width, ifilter->height, ifilter->format,
|
||||
"pixel_aspect=%d/%d:sws_param=flags=%d", ist->resample_width,
|
||||
ist->resample_height,
|
||||
ist->hwaccel_retrieve_data ? ist->hwaccel_retrieved_pix_fmt : ist->resample_pix_fmt,
|
||||
tb.num, tb.den, sar.num, sar.den,
|
||||
SWS_BILINEAR + ((ist->dec_ctx->flags&AV_CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0));
|
||||
if (fr.num && fr.den)
|
||||
@@ -774,7 +763,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
if ((ret = avfilter_graph_create_filter(&ifilter->filter, buffer_filt, name,
|
||||
args.str, NULL, fg->graph)) < 0)
|
||||
goto fail;
|
||||
par->hw_frames_ctx = ifilter->hw_frames_ctx;
|
||||
par->hw_frames_ctx = ist->hw_frames_ctx;
|
||||
ret = av_buffersrc_parameters_set(ifilter->filter, par);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
@@ -802,10 +791,27 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ist->framerate.num) {
|
||||
AVFilterContext *setpts;
|
||||
|
||||
snprintf(name, sizeof(name), "force CFR for input from stream %d:%d",
|
||||
ist->file_index, ist->st->index);
|
||||
if ((ret = avfilter_graph_create_filter(&setpts,
|
||||
avfilter_get_by_name("setpts"),
|
||||
name, "N", NULL,
|
||||
fg->graph)) < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = avfilter_link(last_filter, 0, setpts, 0)) < 0)
|
||||
return ret;
|
||||
|
||||
last_filter = setpts;
|
||||
}
|
||||
|
||||
if (do_deinterlace) {
|
||||
AVFilterContext *yadif;
|
||||
|
||||
snprintf(name, sizeof(name), "deinterlace_in_%d_%d",
|
||||
snprintf(name, sizeof(name), "deinterlace input from stream %d:%d",
|
||||
ist->file_index, ist->st->index);
|
||||
if ((ret = avfilter_graph_create_filter(&yadif,
|
||||
avfilter_get_by_name("yadif"),
|
||||
@@ -819,7 +825,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
last_filter = yadif;
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "trim_in_%d_%d",
|
||||
snprintf(name, sizeof(name), "trim for input stream %d:%d",
|
||||
ist->file_index, ist->st->index);
|
||||
if (copy_ts) {
|
||||
tsoffset = f->start_time == AV_NOPTS_VALUE ? 0 : f->start_time;
|
||||
@@ -860,15 +866,15 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
|
||||
av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);
|
||||
av_bprintf(&args, "time_base=%d/%d:sample_rate=%d:sample_fmt=%s",
|
||||
1, ifilter->sample_rate,
|
||||
ifilter->sample_rate,
|
||||
av_get_sample_fmt_name(ifilter->format));
|
||||
if (ifilter->channel_layout)
|
||||
1, ist->dec_ctx->sample_rate,
|
||||
ist->dec_ctx->sample_rate,
|
||||
av_get_sample_fmt_name(ist->dec_ctx->sample_fmt));
|
||||
if (ist->dec_ctx->channel_layout)
|
||||
av_bprintf(&args, ":channel_layout=0x%"PRIx64,
|
||||
ifilter->channel_layout);
|
||||
ist->dec_ctx->channel_layout);
|
||||
else
|
||||
av_bprintf(&args, ":channels=%d", ifilter->channels);
|
||||
snprintf(name, sizeof(name), "graph_%d_in_%d_%d", fg->index,
|
||||
av_bprintf(&args, ":channels=%d", ist->dec_ctx->channels);
|
||||
snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
|
||||
ist->file_index, ist->st->index);
|
||||
|
||||
if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt,
|
||||
@@ -883,7 +889,7 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
av_log(NULL, AV_LOG_INFO, opt_name " is forwarded to lavfi " \
|
||||
"similarly to -af " filter_name "=%s.\n", arg); \
|
||||
\
|
||||
snprintf(name, sizeof(name), "graph_%d_%s_in_%d_%d", \
|
||||
snprintf(name, sizeof(name), "graph %d %s for input stream %d:%d", \
|
||||
fg->index, filter_name, ist->file_index, ist->st->index); \
|
||||
ret = avfilter_graph_create_filter(&filt_ctx, \
|
||||
avfilter_get_by_name(filter_name), \
|
||||
@@ -954,6 +960,9 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
AVFilterInOut *in)
|
||||
{
|
||||
av_freep(&ifilter->name);
|
||||
DESCRIBE_FILTER_LINK(ifilter, in, 1);
|
||||
|
||||
if (!ifilter->ist->dec) {
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"No decoder for stream #%d:%d, filtering impossible\n",
|
||||
@@ -967,16 +976,6 @@ static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter,
|
||||
}
|
||||
}
|
||||
|
||||
static void cleanup_filtergraph(FilterGraph *fg)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < fg->nb_outputs; i++)
|
||||
fg->outputs[i]->filter = (AVFilterContext *)NULL;
|
||||
for (i = 0; i < fg->nb_inputs; i++)
|
||||
fg->inputs[i]->filter = (AVFilterContext *)NULL;
|
||||
avfilter_graph_free(&fg->graph);
|
||||
}
|
||||
|
||||
int configure_filtergraph(FilterGraph *fg)
|
||||
{
|
||||
AVFilterInOut *inputs, *outputs, *cur;
|
||||
@@ -984,7 +983,7 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter :
|
||||
fg->graph_desc;
|
||||
|
||||
cleanup_filtergraph(fg);
|
||||
avfilter_graph_free(&fg->graph);
|
||||
if (!(fg->graph = avfilter_graph_alloc()))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
@@ -993,8 +992,6 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
char args[512];
|
||||
AVDictionaryEntry *e = NULL;
|
||||
|
||||
fg->graph->nb_threads = filter_nbthreads;
|
||||
|
||||
args[0] = 0;
|
||||
while ((e = av_dict_get(ost->sws_dict, "", e,
|
||||
AV_DICT_IGNORE_SUFFIX))) {
|
||||
@@ -1020,16 +1017,15 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
}
|
||||
if (strlen(args))
|
||||
args[strlen(args) - 1] = '\0';
|
||||
fg->graph->resample_lavr_opts = av_strdup(args);
|
||||
|
||||
e = av_dict_get(ost->encoder_opts, "threads", NULL, 0);
|
||||
if (e)
|
||||
av_opt_set(fg->graph, "threads", e->value, 0);
|
||||
} else {
|
||||
fg->graph->nb_threads = filter_complex_nbthreads;
|
||||
}
|
||||
|
||||
if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
|
||||
goto fail;
|
||||
return ret;
|
||||
|
||||
if (hw_device_ctx) {
|
||||
for (i = 0; i < fg->graph->nb_filters; i++) {
|
||||
@@ -1059,15 +1055,14 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
" However, it had %s input(s) and %s output(s)."
|
||||
" Please adjust, or use a complex filtergraph (-filter_complex) instead.\n",
|
||||
graph_desc, num_inputs, num_outputs);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
for (cur = inputs, i = 0; cur; cur = cur->next, i++)
|
||||
if ((ret = configure_input_filter(fg, fg->inputs[i], cur)) < 0) {
|
||||
avfilter_inout_free(&inputs);
|
||||
avfilter_inout_free(&outputs);
|
||||
goto fail;
|
||||
return ret;
|
||||
}
|
||||
avfilter_inout_free(&inputs);
|
||||
|
||||
@@ -1076,22 +1071,7 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
avfilter_inout_free(&outputs);
|
||||
|
||||
if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
|
||||
goto fail;
|
||||
|
||||
/* limit the lists of allowed formats to the ones selected, to
|
||||
* make sure they stay the same if the filtergraph is reconfigured later */
|
||||
for (i = 0; i < fg->nb_outputs; i++) {
|
||||
OutputFilter *ofilter = fg->outputs[i];
|
||||
AVFilterContext *sink = ofilter->filter;
|
||||
|
||||
ofilter->format = av_buffersink_get_format(sink);
|
||||
|
||||
ofilter->width = av_buffersink_get_w(sink);
|
||||
ofilter->height = av_buffersink_get_h(sink);
|
||||
|
||||
ofilter->sample_rate = av_buffersink_get_sample_rate(sink);
|
||||
ofilter->channel_layout = av_buffersink_get_channel_layout(sink);
|
||||
}
|
||||
return ret;
|
||||
|
||||
fg->reconfiguration = 1;
|
||||
|
||||
@@ -1102,8 +1082,7 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
complex filter graphs are initialized earlier */
|
||||
av_log(NULL, AV_LOG_ERROR, "Encoder (codec %s) not found for output stream #%d:%d\n",
|
||||
avcodec_get_name(ost->st->codecpar->codec_id), ost->file_index, ost->index);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
|
||||
!(ost->enc->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE))
|
||||
@@ -1111,66 +1090,6 @@ int configure_filtergraph(FilterGraph *fg)
|
||||
ost->enc_ctx->frame_size);
|
||||
}
|
||||
|
||||
for (i = 0; i < fg->nb_inputs; i++) {
|
||||
while (av_fifo_size(fg->inputs[i]->frame_queue)) {
|
||||
AVFrame *tmp;
|
||||
av_fifo_generic_read(fg->inputs[i]->frame_queue, &tmp, sizeof(tmp), NULL);
|
||||
ret = av_buffersrc_add_frame(fg->inputs[i]->filter, tmp);
|
||||
av_frame_free(&tmp);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* send the EOFs for the finished inputs */
|
||||
for (i = 0; i < fg->nb_inputs; i++) {
|
||||
if (fg->inputs[i]->eof) {
|
||||
ret = av_buffersrc_add_frame(fg->inputs[i]->filter, NULL);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* process queued up subtitle packets */
|
||||
for (i = 0; i < fg->nb_inputs; i++) {
|
||||
InputStream *ist = fg->inputs[i]->ist;
|
||||
if (ist->sub2video.sub_queue && ist->sub2video.frame) {
|
||||
while (av_fifo_size(ist->sub2video.sub_queue)) {
|
||||
AVSubtitle tmp;
|
||||
av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL);
|
||||
sub2video_update(ist, &tmp);
|
||||
avsubtitle_free(&tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
cleanup_filtergraph(fg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
|
||||
{
|
||||
av_buffer_unref(&ifilter->hw_frames_ctx);
|
||||
|
||||
ifilter->format = frame->format;
|
||||
|
||||
ifilter->width = frame->width;
|
||||
ifilter->height = frame->height;
|
||||
ifilter->sample_aspect_ratio = frame->sample_aspect_ratio;
|
||||
|
||||
ifilter->sample_rate = frame->sample_rate;
|
||||
ifilter->channels = av_frame_get_channels(frame);
|
||||
ifilter->channel_layout = frame->channel_layout;
|
||||
|
||||
if (frame->hw_frames_ctx) {
|
||||
ifilter->hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx);
|
||||
if (!ifilter->hw_frames_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
145
ffmpeg_opt.c
145
ffmpeg_opt.c
@@ -119,9 +119,6 @@ int qp_hist = 0;
|
||||
int stdin_interaction = 1;
|
||||
int frame_bits_per_raw_sample = 0;
|
||||
float max_error_rate = 2.0/3;
|
||||
int filter_nbthreads = 0;
|
||||
int filter_complex_nbthreads = 0;
|
||||
int vstats_version = 2;
|
||||
|
||||
|
||||
static int intra_only = 0;
|
||||
@@ -185,7 +182,7 @@ static int show_hwaccels(void *optctx, const char *opt, const char *arg)
|
||||
int i;
|
||||
|
||||
printf("Hardware acceleration methods:\n");
|
||||
for (i = 0; hwaccels[i].name; i++) {
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(hwaccels) - 1; i++) {
|
||||
printf("%s\n", hwaccels[i].name);
|
||||
}
|
||||
printf("\n");
|
||||
@@ -736,6 +733,10 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
|
||||
// avformat_find_stream_info() doesn't set this for us anymore.
|
||||
ist->dec_ctx->framerate = st->avg_frame_rate;
|
||||
|
||||
ist->resample_height = ist->dec_ctx->height;
|
||||
ist->resample_width = ist->dec_ctx->width;
|
||||
ist->resample_pix_fmt = ist->dec_ctx->pix_fmt;
|
||||
|
||||
MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
|
||||
if (framerate && av_parse_video_rate(&ist->framerate,
|
||||
framerate) < 0) {
|
||||
@@ -800,6 +801,12 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
|
||||
ist->guess_layout_max = INT_MAX;
|
||||
MATCH_PER_STREAM_OPT(guess_layout_max, i, ist->guess_layout_max, ic, st);
|
||||
guess_input_channel_layout(ist);
|
||||
|
||||
ist->resample_sample_fmt = ist->dec_ctx->sample_fmt;
|
||||
ist->resample_sample_rate = ist->dec_ctx->sample_rate;
|
||||
ist->resample_channels = ist->dec_ctx->channels;
|
||||
ist->resample_channel_layout = ist->dec_ctx->channel_layout;
|
||||
|
||||
break;
|
||||
case AVMEDIA_TYPE_DATA:
|
||||
case AVMEDIA_TYPE_SUBTITLE: {
|
||||
@@ -927,7 +934,6 @@ static int open_input_file(OptionsContext *o, const char *filename)
|
||||
print_error(filename, AVERROR(ENOMEM));
|
||||
exit_program(1);
|
||||
}
|
||||
ic->flags |= AVFMT_FLAG_KEEP_SIDE_DATA;
|
||||
if (o->nb_audio_sample_rate) {
|
||||
av_dict_set_int(&o->g->format_opts, "sample_rate", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i, 0);
|
||||
}
|
||||
@@ -1223,7 +1229,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
|
||||
OutputStream *ost;
|
||||
AVStream *st = avformat_new_stream(oc, NULL);
|
||||
int idx = oc->nb_streams - 1, ret = 0;
|
||||
const char *bsfs = NULL, *time_base = NULL;
|
||||
const char *bsfs = NULL;
|
||||
char *next, *codec_tag = NULL;
|
||||
double qscale = -1;
|
||||
int i;
|
||||
@@ -1300,17 +1306,6 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
|
||||
ost->encoder_opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
|
||||
}
|
||||
|
||||
MATCH_PER_STREAM_OPT(time_bases, str, time_base, oc, st);
|
||||
if (time_base) {
|
||||
AVRational q;
|
||||
if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 ||
|
||||
q.num <= 0 || q.den <= 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Invalid time base: %s\n", time_base);
|
||||
exit_program(1);
|
||||
}
|
||||
st->time_base = q;
|
||||
}
|
||||
|
||||
ost->max_frames = INT64_MAX;
|
||||
MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
|
||||
for (i = 0; i<o->nb_max_frames; i++) {
|
||||
@@ -1913,7 +1908,6 @@ static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch
|
||||
int i, err;
|
||||
AVFormatContext *ic = avformat_alloc_context();
|
||||
|
||||
ic->flags |= AVFMT_FLAG_KEEP_SIDE_DATA;
|
||||
ic->interrupt_callback = int_cb;
|
||||
err = avformat_open_input(&ic, filename, NULL, NULL);
|
||||
if (err < 0)
|
||||
@@ -1977,7 +1971,6 @@ static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
|
||||
ost->filter = ofilter;
|
||||
|
||||
ofilter->ost = ost;
|
||||
ofilter->format = -1;
|
||||
|
||||
if (ost->stream_copy) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
|
||||
@@ -2013,6 +2006,17 @@ static int init_complex_filters(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int configure_complex_filters(void)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < nb_filtergraphs; i++)
|
||||
if (!filtergraph_is_simple(filtergraphs[i]) &&
|
||||
(ret = configure_filtergraph(filtergraphs[i])) < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_output_file(OptionsContext *o, const char *filename)
|
||||
{
|
||||
AVFormatContext *oc;
|
||||
@@ -2023,7 +2027,7 @@ static int open_output_file(OptionsContext *o, const char *filename)
|
||||
InputStream *ist;
|
||||
AVDictionary *unused_opts = NULL;
|
||||
AVDictionaryEntry *e = NULL;
|
||||
int format_flags = 0;
|
||||
|
||||
|
||||
if (o->stop_time != INT64_MAX && o->recording_time != INT64_MAX) {
|
||||
o->stop_time = INT64_MAX;
|
||||
@@ -2069,12 +2073,6 @@ static int open_output_file(OptionsContext *o, const char *filename)
|
||||
file_oformat= oc->oformat;
|
||||
oc->interrupt_callback = int_cb;
|
||||
|
||||
e = av_dict_get(o->g->format_opts, "fflags", NULL, 0);
|
||||
if (e) {
|
||||
const AVOption *o = av_opt_find(oc, "fflags", NULL, 0, 0);
|
||||
av_opt_eval_flags(oc, o, e->value, &format_flags);
|
||||
}
|
||||
|
||||
/* create streams for all unlabeled output pads */
|
||||
for (i = 0; i < nb_filtergraphs; i++) {
|
||||
FilterGraph *fg = filtergraphs[i];
|
||||
@@ -2095,7 +2093,6 @@ static int open_output_file(OptionsContext *o, const char *filename)
|
||||
|
||||
/* ffserver seeking with date=... needs a date reference */
|
||||
if (!strcmp(file_oformat->name, "ffm") &&
|
||||
!(format_flags & AVFMT_FLAG_BITEXACT) &&
|
||||
av_strstart(filename, "http:", NULL)) {
|
||||
int err = parse_option(o, "metadata", "creation_time=now", options);
|
||||
if (err < 0) {
|
||||
@@ -2402,67 +2399,6 @@ loop_end:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set the filter output constraints */
|
||||
if (ost->filter) {
|
||||
OutputFilter *f = ost->filter;
|
||||
int count;
|
||||
switch (ost->enc_ctx->codec_type) {
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
f->frame_rate = ost->frame_rate;
|
||||
f->width = ost->enc_ctx->width;
|
||||
f->height = ost->enc_ctx->height;
|
||||
if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
|
||||
f->format = ost->enc_ctx->pix_fmt;
|
||||
} else if (ost->enc->pix_fmts) {
|
||||
count = 0;
|
||||
while (ost->enc->pix_fmts[count] != AV_PIX_FMT_NONE)
|
||||
count++;
|
||||
f->formats = av_mallocz_array(count + 1, sizeof(*f->formats));
|
||||
if (!f->formats)
|
||||
exit_program(1);
|
||||
memcpy(f->formats, ost->enc->pix_fmts, (count + 1) * sizeof(*f->formats));
|
||||
}
|
||||
break;
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
if (ost->enc_ctx->sample_fmt != AV_SAMPLE_FMT_NONE) {
|
||||
f->format = ost->enc_ctx->sample_fmt;
|
||||
} else if (ost->enc->sample_fmts) {
|
||||
count = 0;
|
||||
while (ost->enc->sample_fmts[count] != AV_SAMPLE_FMT_NONE)
|
||||
count++;
|
||||
f->formats = av_mallocz_array(count + 1, sizeof(*f->formats));
|
||||
if (!f->formats)
|
||||
exit_program(1);
|
||||
memcpy(f->formats, ost->enc->sample_fmts, (count + 1) * sizeof(*f->formats));
|
||||
}
|
||||
if (ost->enc_ctx->sample_rate) {
|
||||
f->sample_rate = ost->enc_ctx->sample_rate;
|
||||
} else if (ost->enc->supported_samplerates) {
|
||||
count = 0;
|
||||
while (ost->enc->supported_samplerates[count])
|
||||
count++;
|
||||
f->sample_rates = av_mallocz_array(count + 1, sizeof(*f->sample_rates));
|
||||
if (!f->sample_rates)
|
||||
exit_program(1);
|
||||
memcpy(f->sample_rates, ost->enc->supported_samplerates,
|
||||
(count + 1) * sizeof(*f->sample_rates));
|
||||
}
|
||||
if (ost->enc_ctx->channels) {
|
||||
f->channel_layout = av_get_default_channel_layout(ost->enc_ctx->channels);
|
||||
} else if (ost->enc->channel_layouts) {
|
||||
count = 0;
|
||||
while (ost->enc->channel_layouts[count])
|
||||
count++;
|
||||
f->channel_layouts = av_mallocz_array(count + 1, sizeof(*f->channel_layouts));
|
||||
if (!f->channel_layouts)
|
||||
exit_program(1);
|
||||
memcpy(f->channel_layouts, ost->enc->channel_layouts,
|
||||
(count + 1) * sizeof(*f->channel_layouts));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check filename in case of an image number is expected */
|
||||
@@ -2549,6 +2485,8 @@ loop_end:
|
||||
av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
|
||||
if (!output_streams[i]->stream_copy) {
|
||||
av_dict_set(&output_streams[i]->st->metadata, "encoder", NULL, 0);
|
||||
if (ist->autorotate)
|
||||
av_dict_set(&output_streams[i]->st->metadata, "rotate", NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2638,15 +2576,9 @@ loop_end:
|
||||
for (j = 0; j < oc->nb_streams; j++) {
|
||||
ost = output_streams[nb_output_streams - oc->nb_streams + j];
|
||||
if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
|
||||
av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
|
||||
if (!strcmp(o->metadata[i].u.str, "rotate")) {
|
||||
char *tail;
|
||||
double theta = av_strtod(val, &tail);
|
||||
if (!*tail) {
|
||||
ost->rotate_overridden = 1;
|
||||
ost->rotate_override_value = theta;
|
||||
}
|
||||
} else {
|
||||
av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
|
||||
ost->rotate_overridden = 1;
|
||||
}
|
||||
} else if (ret < 0)
|
||||
exit_program(1);
|
||||
@@ -3260,6 +3192,13 @@ int ffmpeg_parse_options(int argc, char **argv)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* configure the complex filtergraphs */
|
||||
ret = configure_complex_filters();
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Error configuring complex filters.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
uninit_parse_context(&octx);
|
||||
if (ret < 0) {
|
||||
@@ -3426,16 +3365,12 @@ const OptionDef options[] = {
|
||||
"set profile", "profile" },
|
||||
{ "filter", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filters) },
|
||||
"set stream filtergraph", "filter_graph" },
|
||||
{ "filter_threads", HAS_ARG | OPT_INT, { &filter_nbthreads },
|
||||
"number of non-complex filter threads" },
|
||||
{ "filter_script", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filter_scripts) },
|
||||
"read stream filtergraph description from a file", "filename" },
|
||||
{ "reinit_filter", HAS_ARG | OPT_INT | OPT_SPEC | OPT_INPUT, { .off = OFFSET(reinit_filters) },
|
||||
"reinit filtergraph on input parameter changes", "" },
|
||||
{ "filter_complex", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex },
|
||||
"create a complex filtergraph", "graph_description" },
|
||||
{ "filter_complex_threads", HAS_ARG | OPT_INT, { &filter_complex_nbthreads },
|
||||
"number of threads for -filter_complex" },
|
||||
{ "lavfi", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex },
|
||||
"create a complex filtergraph", "graph_description" },
|
||||
{ "filter_complex_script", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex_script },
|
||||
@@ -3510,8 +3445,6 @@ const OptionDef options[] = {
|
||||
"dump video coding statistics to file" },
|
||||
{ "vstats_file", OPT_VIDEO | HAS_ARG | OPT_EXPERT , { .func_arg = opt_vstats_file },
|
||||
"dump video coding statistics to file", "file" },
|
||||
{ "vstats_version", OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT , { &vstats_version },
|
||||
"Version of the vstats format to use."},
|
||||
{ "vf", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_filters },
|
||||
"set video filters", "filter_graph" },
|
||||
{ "intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
|
||||
@@ -3625,9 +3558,6 @@ const OptionDef options[] = {
|
||||
{ "sdp_file", HAS_ARG | OPT_EXPERT | OPT_OUTPUT, { .func_arg = opt_sdp_file },
|
||||
"specify a file in which to print sdp information", "file" },
|
||||
|
||||
{ "time_base", HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(time_bases) },
|
||||
"set the desired time base hint for output stream (1:24, 1:48000 or 0.04166, 2.0833e-5)", "ratio" },
|
||||
|
||||
{ "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(bitstream_filters) },
|
||||
"A comma-separated list of bitstream filters", "bitstream_filters" },
|
||||
{ "absf", HAS_ARG | OPT_AUDIO | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_old2new },
|
||||
@@ -3658,10 +3588,5 @@ const OptionDef options[] = {
|
||||
"set VAAPI hardware device (DRM path or X11 display name)", "device" },
|
||||
#endif
|
||||
|
||||
#if CONFIG_QSV
|
||||
{ "qsv_device", HAS_ARG | OPT_STRING | OPT_EXPERT, { &qsv_device },
|
||||
"set QSV hardware device (DirectX adapter index, DRM path or X11 display name)", "device"},
|
||||
#endif
|
||||
|
||||
{ NULL, },
|
||||
};
|
||||
|
||||
258
ffmpeg_qsv.c
258
ffmpeg_qsv.c
@@ -20,90 +20,248 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavutil/hwcontext.h"
|
||||
#include "libavutil/hwcontext_qsv.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavcodec/qsv.h"
|
||||
|
||||
#include "ffmpeg.h"
|
||||
|
||||
char *qsv_device = NULL;
|
||||
typedef struct QSVContext {
|
||||
OutputStream *ost;
|
||||
|
||||
mfxSession session;
|
||||
|
||||
mfxExtOpaqueSurfaceAlloc opaque_alloc;
|
||||
AVBufferRef *opaque_surfaces_buf;
|
||||
|
||||
uint8_t *surface_used;
|
||||
mfxFrameSurface1 **surface_ptrs;
|
||||
int nb_surfaces;
|
||||
|
||||
mfxExtBuffer *ext_buffers[1];
|
||||
} QSVContext;
|
||||
|
||||
static void buffer_release(void *opaque, uint8_t *data)
|
||||
{
|
||||
*(uint8_t*)opaque = 0;
|
||||
}
|
||||
|
||||
static int qsv_get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
QSVContext *qsv = ist->hwaccel_ctx;
|
||||
int i;
|
||||
|
||||
return av_hwframe_get_buffer(ist->hw_frames_ctx, frame, 0);
|
||||
for (i = 0; i < qsv->nb_surfaces; i++) {
|
||||
if (qsv->surface_used[i])
|
||||
continue;
|
||||
|
||||
frame->buf[0] = av_buffer_create((uint8_t*)qsv->surface_ptrs[i], sizeof(*qsv->surface_ptrs[i]),
|
||||
buffer_release, &qsv->surface_used[i], 0);
|
||||
if (!frame->buf[0])
|
||||
return AVERROR(ENOMEM);
|
||||
frame->data[3] = (uint8_t*)qsv->surface_ptrs[i];
|
||||
qsv->surface_used[i] = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
static int init_opaque_surf(QSVContext *qsv)
|
||||
{
|
||||
AVQSVContext *hwctx_enc = qsv->ost->enc_ctx->hwaccel_context;
|
||||
mfxFrameSurface1 *surfaces;
|
||||
int i;
|
||||
|
||||
qsv->nb_surfaces = hwctx_enc->nb_opaque_surfaces;
|
||||
|
||||
qsv->opaque_surfaces_buf = av_buffer_ref(hwctx_enc->opaque_surfaces);
|
||||
qsv->surface_ptrs = av_mallocz_array(qsv->nb_surfaces, sizeof(*qsv->surface_ptrs));
|
||||
qsv->surface_used = av_mallocz_array(qsv->nb_surfaces, sizeof(*qsv->surface_used));
|
||||
if (!qsv->opaque_surfaces_buf || !qsv->surface_ptrs || !qsv->surface_used)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
surfaces = (mfxFrameSurface1*)qsv->opaque_surfaces_buf->data;
|
||||
for (i = 0; i < qsv->nb_surfaces; i++)
|
||||
qsv->surface_ptrs[i] = surfaces + i;
|
||||
|
||||
qsv->opaque_alloc.Out.Surfaces = qsv->surface_ptrs;
|
||||
qsv->opaque_alloc.Out.NumSurface = qsv->nb_surfaces;
|
||||
qsv->opaque_alloc.Out.Type = hwctx_enc->opaque_alloc_type;
|
||||
|
||||
qsv->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
|
||||
qsv->opaque_alloc.Header.BufferSz = sizeof(qsv->opaque_alloc);
|
||||
qsv->ext_buffers[0] = (mfxExtBuffer*)&qsv->opaque_alloc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qsv_uninit(AVCodecContext *s)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
av_buffer_unref(&ist->hw_frames_ctx);
|
||||
}
|
||||
QSVContext *qsv = ist->hwaccel_ctx;
|
||||
|
||||
static int qsv_device_init(InputStream *ist)
|
||||
{
|
||||
int err;
|
||||
AVDictionary *dict = NULL;
|
||||
av_freep(&qsv->ost->enc_ctx->hwaccel_context);
|
||||
av_freep(&s->hwaccel_context);
|
||||
|
||||
if (qsv_device) {
|
||||
err = av_dict_set(&dict, "child_device", qsv_device, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
av_buffer_unref(&qsv->opaque_surfaces_buf);
|
||||
av_freep(&qsv->surface_used);
|
||||
av_freep(&qsv->surface_ptrs);
|
||||
|
||||
err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_QSV,
|
||||
ist->hwaccel_device, dict, 0);
|
||||
if (err < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error creating a QSV device\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
err_out:
|
||||
if (dict)
|
||||
av_dict_free(&dict);
|
||||
|
||||
return err;
|
||||
av_freep(&qsv);
|
||||
}
|
||||
|
||||
int qsv_init(AVCodecContext *s)
|
||||
{
|
||||
InputStream *ist = s->opaque;
|
||||
AVHWFramesContext *frames_ctx;
|
||||
AVQSVFramesContext *frames_hwctx;
|
||||
QSVContext *qsv = ist->hwaccel_ctx;
|
||||
AVQSVContext *hwctx_dec;
|
||||
int ret;
|
||||
|
||||
if (!hw_device_ctx) {
|
||||
ret = qsv_device_init(ist);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (!qsv) {
|
||||
av_log(NULL, AV_LOG_ERROR, "QSV transcoding is not initialized. "
|
||||
"-hwaccel qsv should only be used for one-to-one QSV transcoding "
|
||||
"with no filters.\n");
|
||||
return AVERROR_BUG;
|
||||
}
|
||||
|
||||
av_buffer_unref(&ist->hw_frames_ctx);
|
||||
ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx);
|
||||
if (!ist->hw_frames_ctx)
|
||||
ret = init_opaque_surf(qsv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
hwctx_dec = av_qsv_alloc_context();
|
||||
if (!hwctx_dec)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
frames_ctx = (AVHWFramesContext*)ist->hw_frames_ctx->data;
|
||||
frames_hwctx = frames_ctx->hwctx;
|
||||
hwctx_dec->session = qsv->session;
|
||||
hwctx_dec->iopattern = MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
|
||||
hwctx_dec->ext_buffers = qsv->ext_buffers;
|
||||
hwctx_dec->nb_ext_buffers = FF_ARRAY_ELEMS(qsv->ext_buffers);
|
||||
|
||||
frames_ctx->width = FFALIGN(s->coded_width, 32);
|
||||
frames_ctx->height = FFALIGN(s->coded_height, 32);
|
||||
frames_ctx->format = AV_PIX_FMT_QSV;
|
||||
frames_ctx->sw_format = s->sw_pix_fmt;
|
||||
frames_ctx->initial_pool_size = 64;
|
||||
frames_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
|
||||
|
||||
ret = av_hwframe_ctx_init(ist->hw_frames_ctx);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error initializing a QSV frame pool\n");
|
||||
return ret;
|
||||
}
|
||||
av_freep(&s->hwaccel_context);
|
||||
s->hwaccel_context = hwctx_dec;
|
||||
|
||||
ist->hwaccel_get_buffer = qsv_get_buffer;
|
||||
ist->hwaccel_uninit = qsv_uninit;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static mfxIMPL choose_implementation(const InputStream *ist)
|
||||
{
|
||||
static const struct {
|
||||
const char *name;
|
||||
mfxIMPL impl;
|
||||
} impl_map[] = {
|
||||
{ "auto", MFX_IMPL_AUTO },
|
||||
{ "sw", MFX_IMPL_SOFTWARE },
|
||||
{ "hw", MFX_IMPL_HARDWARE },
|
||||
{ "auto_any", MFX_IMPL_AUTO_ANY },
|
||||
{ "hw_any", MFX_IMPL_HARDWARE_ANY },
|
||||
{ "hw2", MFX_IMPL_HARDWARE2 },
|
||||
{ "hw3", MFX_IMPL_HARDWARE3 },
|
||||
{ "hw4", MFX_IMPL_HARDWARE4 },
|
||||
};
|
||||
|
||||
mfxIMPL impl = MFX_IMPL_AUTO_ANY;
|
||||
int i;
|
||||
|
||||
if (ist->hwaccel_device) {
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(impl_map); i++)
|
||||
if (!strcmp(ist->hwaccel_device, impl_map[i].name)) {
|
||||
impl = impl_map[i].impl;
|
||||
break;
|
||||
}
|
||||
if (i == FF_ARRAY_ELEMS(impl_map))
|
||||
impl = strtol(ist->hwaccel_device, NULL, 0);
|
||||
}
|
||||
|
||||
return impl;
|
||||
}
|
||||
|
||||
int qsv_transcode_init(OutputStream *ost)
|
||||
{
|
||||
InputStream *ist;
|
||||
const enum AVPixelFormat *pix_fmt;
|
||||
|
||||
AVDictionaryEntry *e;
|
||||
const AVOption *opt;
|
||||
int flags = 0;
|
||||
|
||||
int err, i;
|
||||
|
||||
QSVContext *qsv = NULL;
|
||||
AVQSVContext *hwctx = NULL;
|
||||
mfxIMPL impl;
|
||||
mfxVersion ver = { { 3, 1 } };
|
||||
|
||||
/* check if the encoder supports QSV */
|
||||
if (!ost->enc->pix_fmts)
|
||||
return 0;
|
||||
for (pix_fmt = ost->enc->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++)
|
||||
if (*pix_fmt == AV_PIX_FMT_QSV)
|
||||
break;
|
||||
if (*pix_fmt == AV_PIX_FMT_NONE)
|
||||
return 0;
|
||||
|
||||
if (strcmp(ost->avfilter, "null") || ost->source_index < 0)
|
||||
return 0;
|
||||
|
||||
/* check if the decoder supports QSV and the output only goes to this stream */
|
||||
ist = input_streams[ost->source_index];
|
||||
if (ist->hwaccel_id != HWACCEL_QSV || !ist->dec || !ist->dec->pix_fmts)
|
||||
return 0;
|
||||
for (pix_fmt = ist->dec->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++)
|
||||
if (*pix_fmt == AV_PIX_FMT_QSV)
|
||||
break;
|
||||
if (*pix_fmt == AV_PIX_FMT_NONE)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < nb_output_streams; i++)
|
||||
if (output_streams[i] != ost &&
|
||||
output_streams[i]->source_index == ost->source_index)
|
||||
return 0;
|
||||
|
||||
av_log(NULL, AV_LOG_VERBOSE, "Setting up QSV transcoding\n");
|
||||
|
||||
qsv = av_mallocz(sizeof(*qsv));
|
||||
hwctx = av_qsv_alloc_context();
|
||||
if (!qsv || !hwctx)
|
||||
goto fail;
|
||||
|
||||
impl = choose_implementation(ist);
|
||||
|
||||
err = MFXInit(impl, &ver, &qsv->session);
|
||||
if (err != MFX_ERR_NONE) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error initializing an MFX session: %d\n", err);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
e = av_dict_get(ost->encoder_opts, "flags", NULL, 0);
|
||||
opt = av_opt_find(ost->enc_ctx, "flags", NULL, 0, 0);
|
||||
if (e && opt)
|
||||
av_opt_eval_flags(ost->enc_ctx, opt, e->value, &flags);
|
||||
|
||||
qsv->ost = ost;
|
||||
|
||||
hwctx->session = qsv->session;
|
||||
hwctx->iopattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY;
|
||||
hwctx->opaque_alloc = 1;
|
||||
hwctx->nb_opaque_surfaces = 16;
|
||||
|
||||
ost->hwaccel_ctx = qsv;
|
||||
ost->enc_ctx->hwaccel_context = hwctx;
|
||||
ost->enc_ctx->pix_fmt = AV_PIX_FMT_QSV;
|
||||
|
||||
ist->hwaccel_ctx = qsv;
|
||||
ist->dec_ctx->pix_fmt = AV_PIX_FMT_QSV;
|
||||
ist->resample_pix_fmt = AV_PIX_FMT_QSV;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
av_freep(&hwctx);
|
||||
av_freep(&qsv);
|
||||
return AVERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
357
ffmpeg_vaapi.c
357
ffmpeg_vaapi.c
@@ -18,10 +18,28 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <va/va.h>
|
||||
#if HAVE_VAAPI_X11
|
||||
# include <va/va_x11.h>
|
||||
#endif
|
||||
#if HAVE_VAAPI_DRM
|
||||
# include <va/va_drm.h>
|
||||
#endif
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avconfig.h"
|
||||
#include "libavutil/buffer.h"
|
||||
#include "libavutil/frame.h"
|
||||
#include "libavutil/hwcontext.h"
|
||||
#include "libavutil/log.h"
|
||||
#include "libavutil/hwcontext_vaapi.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/pixfmt.h"
|
||||
|
||||
#include "libavcodec/vaapi.h"
|
||||
|
||||
#include "ffmpeg.h"
|
||||
|
||||
@@ -42,11 +60,23 @@ typedef struct VAAPIDecoderContext {
|
||||
AVBufferRef *frames_ref;
|
||||
AVHWFramesContext *frames;
|
||||
|
||||
VAProfile va_profile;
|
||||
VAEntrypoint va_entrypoint;
|
||||
VAConfigID va_config;
|
||||
VAContextID va_context;
|
||||
|
||||
enum AVPixelFormat decode_format;
|
||||
int decode_width;
|
||||
int decode_height;
|
||||
int decode_surfaces;
|
||||
|
||||
// The output need not have the same format, width and height as the
|
||||
// decoded frames - the copy for non-direct-mapped access is actually
|
||||
// a whole vpp instance which can do arbitrary scaling and format
|
||||
// conversion.
|
||||
enum AVPixelFormat output_format;
|
||||
|
||||
struct vaapi_context decoder_vaapi_context;
|
||||
} VAAPIDecoderContext;
|
||||
|
||||
|
||||
@@ -114,12 +144,257 @@ fail:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static const struct {
|
||||
enum AVCodecID codec_id;
|
||||
int codec_profile;
|
||||
VAProfile va_profile;
|
||||
} vaapi_profile_map[] = {
|
||||
#define MAP(c, p, v) { AV_CODEC_ID_ ## c, FF_PROFILE_ ## p, VAProfile ## v }
|
||||
MAP(MPEG2VIDEO, MPEG2_SIMPLE, MPEG2Simple ),
|
||||
MAP(MPEG2VIDEO, MPEG2_MAIN, MPEG2Main ),
|
||||
MAP(H263, UNKNOWN, H263Baseline),
|
||||
MAP(MPEG4, MPEG4_SIMPLE, MPEG4Simple ),
|
||||
MAP(MPEG4, MPEG4_ADVANCED_SIMPLE,
|
||||
MPEG4AdvancedSimple),
|
||||
MAP(MPEG4, MPEG4_MAIN, MPEG4Main ),
|
||||
MAP(H264, H264_CONSTRAINED_BASELINE,
|
||||
H264ConstrainedBaseline),
|
||||
MAP(H264, H264_BASELINE, H264Baseline),
|
||||
MAP(H264, H264_MAIN, H264Main ),
|
||||
MAP(H264, H264_HIGH, H264High ),
|
||||
#if VA_CHECK_VERSION(0, 37, 0)
|
||||
MAP(HEVC, HEVC_MAIN, HEVCMain ),
|
||||
#endif
|
||||
MAP(WMV3, VC1_SIMPLE, VC1Simple ),
|
||||
MAP(WMV3, VC1_MAIN, VC1Main ),
|
||||
MAP(WMV3, VC1_COMPLEX, VC1Advanced ),
|
||||
MAP(WMV3, VC1_ADVANCED, VC1Advanced ),
|
||||
MAP(VC1, VC1_SIMPLE, VC1Simple ),
|
||||
MAP(VC1, VC1_MAIN, VC1Main ),
|
||||
MAP(VC1, VC1_COMPLEX, VC1Advanced ),
|
||||
MAP(VC1, VC1_ADVANCED, VC1Advanced ),
|
||||
#if VA_CHECK_VERSION(0, 35, 0)
|
||||
MAP(VP8, UNKNOWN, VP8Version0_3 ),
|
||||
#endif
|
||||
#if VA_CHECK_VERSION(0, 37, 1)
|
||||
MAP(VP9, VP9_0, VP9Profile0 ),
|
||||
#endif
|
||||
#undef MAP
|
||||
};
|
||||
|
||||
static int vaapi_build_decoder_config(VAAPIDecoderContext *ctx,
|
||||
AVCodecContext *avctx,
|
||||
int fallback_allowed)
|
||||
{
|
||||
AVVAAPIDeviceContext *hwctx = ctx->device->hwctx;
|
||||
AVVAAPIHWConfig *hwconfig = NULL;
|
||||
AVHWFramesConstraints *constraints = NULL;
|
||||
VAStatus vas;
|
||||
int err, i, j;
|
||||
int loglevel = fallback_allowed ? AV_LOG_VERBOSE : AV_LOG_ERROR;
|
||||
const AVCodecDescriptor *codec_desc;
|
||||
const AVPixFmtDescriptor *pix_desc;
|
||||
enum AVPixelFormat pix_fmt;
|
||||
VAProfile profile, *profile_list = NULL;
|
||||
int profile_count, exact_match, alt_profile;
|
||||
|
||||
codec_desc = avcodec_descriptor_get(avctx->codec_id);
|
||||
if (!codec_desc) {
|
||||
err = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
profile_count = vaMaxNumProfiles(hwctx->display);
|
||||
profile_list = av_malloc(profile_count * sizeof(VAProfile));
|
||||
if (!profile_list) {
|
||||
err = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
vas = vaQueryConfigProfiles(hwctx->display,
|
||||
profile_list, &profile_count);
|
||||
if (vas != VA_STATUS_SUCCESS) {
|
||||
av_log(ctx, loglevel, "Failed to query profiles: %d (%s).\n",
|
||||
vas, vaErrorStr(vas));
|
||||
err = AVERROR(EIO);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
profile = VAProfileNone;
|
||||
exact_match = 0;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
|
||||
int profile_match = 0;
|
||||
if (avctx->codec_id != vaapi_profile_map[i].codec_id)
|
||||
continue;
|
||||
if (avctx->profile == vaapi_profile_map[i].codec_profile)
|
||||
profile_match = 1;
|
||||
profile = vaapi_profile_map[i].va_profile;
|
||||
for (j = 0; j < profile_count; j++) {
|
||||
if (profile == profile_list[j]) {
|
||||
exact_match = profile_match;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < profile_count) {
|
||||
if (exact_match)
|
||||
break;
|
||||
alt_profile = vaapi_profile_map[i].codec_profile;
|
||||
}
|
||||
}
|
||||
av_freep(&profile_list);
|
||||
|
||||
if (profile == VAProfileNone) {
|
||||
av_log(ctx, loglevel, "No VAAPI support for codec %s.\n",
|
||||
codec_desc->name);
|
||||
err = AVERROR(ENOSYS);
|
||||
goto fail;
|
||||
}
|
||||
if (!exact_match) {
|
||||
if (fallback_allowed || !hwaccel_lax_profile_check) {
|
||||
av_log(ctx, loglevel, "No VAAPI support for codec %s "
|
||||
"profile %d.\n", codec_desc->name, avctx->profile);
|
||||
if (!fallback_allowed) {
|
||||
av_log(ctx, AV_LOG_WARNING, "If you want attempt decoding "
|
||||
"anyway with a possibly-incompatible profile, add "
|
||||
"the option -hwaccel_lax_profile_check.\n");
|
||||
}
|
||||
err = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
} else {
|
||||
av_log(ctx, AV_LOG_WARNING, "No VAAPI support for codec %s "
|
||||
"profile %d: trying instead with profile %d.\n",
|
||||
codec_desc->name, avctx->profile, alt_profile);
|
||||
av_log(ctx, AV_LOG_WARNING, "This may fail or give "
|
||||
"incorrect results, depending on your hardware.\n");
|
||||
}
|
||||
}
|
||||
|
||||
ctx->va_profile = profile;
|
||||
ctx->va_entrypoint = VAEntrypointVLD;
|
||||
|
||||
vas = vaCreateConfig(hwctx->display, ctx->va_profile,
|
||||
ctx->va_entrypoint, 0, 0, &ctx->va_config);
|
||||
if (vas != VA_STATUS_SUCCESS) {
|
||||
av_log(ctx, AV_LOG_ERROR, "Failed to create decode pipeline "
|
||||
"configuration: %d (%s).\n", vas, vaErrorStr(vas));
|
||||
err = AVERROR(EIO);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
|
||||
if (!hwconfig) {
|
||||
err = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
hwconfig->config_id = ctx->va_config;
|
||||
|
||||
constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref,
|
||||
hwconfig);
|
||||
if (!constraints)
|
||||
goto fail;
|
||||
|
||||
// Decide on the decoder target format.
|
||||
// If the user specified something with -hwaccel_output_format then
|
||||
// try to use that to minimise conversions later.
|
||||
ctx->decode_format = AV_PIX_FMT_NONE;
|
||||
if (ctx->output_format != AV_PIX_FMT_NONE &&
|
||||
ctx->output_format != AV_PIX_FMT_VAAPI) {
|
||||
for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
|
||||
if (constraints->valid_sw_formats[i] == ctx->output_format) {
|
||||
ctx->decode_format = ctx->output_format;
|
||||
av_log(ctx, AV_LOG_DEBUG, "Using decode format %s (output "
|
||||
"format).\n", av_get_pix_fmt_name(ctx->decode_format));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Otherwise, we would like to try to choose something which matches the
|
||||
// decoder output, but there isn't enough information available here to
|
||||
// do so. Assume for now that we are always dealing with YUV 4:2:0, so
|
||||
// pick a format which does that.
|
||||
if (ctx->decode_format == AV_PIX_FMT_NONE) {
|
||||
for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
|
||||
pix_fmt = constraints->valid_sw_formats[i];
|
||||
pix_desc = av_pix_fmt_desc_get(pix_fmt);
|
||||
if (pix_desc->nb_components == 3 &&
|
||||
pix_desc->log2_chroma_w == 1 &&
|
||||
pix_desc->log2_chroma_h == 1) {
|
||||
ctx->decode_format = pix_fmt;
|
||||
av_log(ctx, AV_LOG_DEBUG, "Using decode format %s (format "
|
||||
"matched).\n", av_get_pix_fmt_name(ctx->decode_format));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Otherwise pick the first in the list and hope for the best.
|
||||
if (ctx->decode_format == AV_PIX_FMT_NONE) {
|
||||
ctx->decode_format = constraints->valid_sw_formats[0];
|
||||
av_log(ctx, AV_LOG_DEBUG, "Using decode format %s (first in list).\n",
|
||||
av_get_pix_fmt_name(ctx->decode_format));
|
||||
if (i > 1) {
|
||||
// There was a choice, and we picked randomly. Warn the user
|
||||
// that they might want to choose intelligently instead.
|
||||
av_log(ctx, AV_LOG_WARNING, "Using randomly chosen decode "
|
||||
"format %s.\n", av_get_pix_fmt_name(ctx->decode_format));
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the picture size is supported by the hardware.
|
||||
ctx->decode_width = avctx->coded_width;
|
||||
ctx->decode_height = avctx->coded_height;
|
||||
if (ctx->decode_width < constraints->min_width ||
|
||||
ctx->decode_height < constraints->min_height ||
|
||||
ctx->decode_width > constraints->max_width ||
|
||||
ctx->decode_height >constraints->max_height) {
|
||||
av_log(ctx, AV_LOG_ERROR, "VAAPI hardware does not support image "
|
||||
"size %dx%d (constraints: width %d-%d height %d-%d).\n",
|
||||
ctx->decode_width, ctx->decode_height,
|
||||
constraints->min_width, constraints->max_width,
|
||||
constraints->min_height, constraints->max_height);
|
||||
err = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
av_hwframe_constraints_free(&constraints);
|
||||
av_freep(&hwconfig);
|
||||
|
||||
// Decide how many reference frames we need. This might be doable more
|
||||
// nicely based on the codec and input stream?
|
||||
ctx->decode_surfaces = DEFAULT_SURFACES;
|
||||
// For frame-threaded decoding, one additional surfaces is needed for
|
||||
// each thread.
|
||||
if (avctx->active_thread_type & FF_THREAD_FRAME)
|
||||
ctx->decode_surfaces += avctx->thread_count;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
av_hwframe_constraints_free(&constraints);
|
||||
av_freep(&hwconfig);
|
||||
vaDestroyConfig(hwctx->display, ctx->va_config);
|
||||
av_freep(&profile_list);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void vaapi_decode_uninit(AVCodecContext *avctx)
|
||||
{
|
||||
InputStream *ist = avctx->opaque;
|
||||
VAAPIDecoderContext *ctx = ist->hwaccel_ctx;
|
||||
|
||||
if (ctx) {
|
||||
AVVAAPIDeviceContext *hwctx = ctx->device->hwctx;
|
||||
|
||||
if (ctx->va_context != VA_INVALID_ID) {
|
||||
vaDestroyContext(hwctx->display, ctx->va_context);
|
||||
ctx->va_context = VA_INVALID_ID;
|
||||
}
|
||||
if (ctx->va_config != VA_INVALID_ID) {
|
||||
vaDestroyConfig(hwctx->display, ctx->va_config);
|
||||
ctx->va_config = VA_INVALID_ID;
|
||||
}
|
||||
|
||||
av_buffer_unref(&ctx->frames_ref);
|
||||
av_buffer_unref(&ctx->device_ref);
|
||||
av_free(ctx);
|
||||
@@ -127,16 +402,19 @@ static void vaapi_decode_uninit(AVCodecContext *avctx)
|
||||
|
||||
av_buffer_unref(&ist->hw_frames_ctx);
|
||||
|
||||
ist->hwaccel_ctx = NULL;
|
||||
ist->hwaccel_uninit = NULL;
|
||||
ist->hwaccel_get_buffer = NULL;
|
||||
ist->hwaccel_retrieve_data = NULL;
|
||||
ist->hwaccel_ctx = 0;
|
||||
ist->hwaccel_uninit = 0;
|
||||
ist->hwaccel_get_buffer = 0;
|
||||
ist->hwaccel_retrieve_data = 0;
|
||||
}
|
||||
|
||||
int vaapi_decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
InputStream *ist = avctx->opaque;
|
||||
AVVAAPIDeviceContext *hwctx;
|
||||
AVVAAPIFramesContext *avfc;
|
||||
VAAPIDecoderContext *ctx;
|
||||
VAStatus vas;
|
||||
int err;
|
||||
int loglevel = (ist->hwaccel_id != HWACCEL_VAAPI ? AV_LOG_VERBOSE
|
||||
: AV_LOG_ERROR);
|
||||
@@ -157,12 +435,24 @@ int vaapi_decode_init(AVCodecContext *avctx)
|
||||
if (!ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
ctx->class = &vaapi_class;
|
||||
ist->hwaccel_ctx = ctx;
|
||||
|
||||
ctx->device_ref = av_buffer_ref(hw_device_ctx);
|
||||
ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
|
||||
|
||||
ctx->va_config = VA_INVALID_ID;
|
||||
ctx->va_context = VA_INVALID_ID;
|
||||
|
||||
hwctx = ctx->device->hwctx;
|
||||
|
||||
ctx->output_format = ist->hwaccel_output_format;
|
||||
|
||||
err = vaapi_build_decoder_config(ctx, avctx,
|
||||
ist->hwaccel_id != HWACCEL_VAAPI);
|
||||
if (err < 0) {
|
||||
av_log(ctx, loglevel, "No supported configuration for this codec.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
avctx->pix_fmt = ctx->output_format;
|
||||
|
||||
ctx->frames_ref = av_hwframe_ctx_alloc(ctx->device_ref);
|
||||
@@ -174,21 +464,11 @@ int vaapi_decode_init(AVCodecContext *avctx)
|
||||
|
||||
ctx->frames = (AVHWFramesContext*)ctx->frames_ref->data;
|
||||
|
||||
ctx->frames->format = AV_PIX_FMT_VAAPI;
|
||||
ctx->frames->width = avctx->coded_width;
|
||||
ctx->frames->height = avctx->coded_height;
|
||||
|
||||
// It would be nice if we could query the available formats here,
|
||||
// but unfortunately we don't have a VAConfigID to do it with.
|
||||
// For now, just assume an NV12 format (or P010 if 10-bit).
|
||||
ctx->frames->sw_format = (avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ?
|
||||
AV_PIX_FMT_P010 : AV_PIX_FMT_NV12);
|
||||
|
||||
// For frame-threaded decoding, at least one additional surface
|
||||
// is needed for each thread.
|
||||
ctx->frames->initial_pool_size = DEFAULT_SURFACES;
|
||||
if (avctx->active_thread_type & FF_THREAD_FRAME)
|
||||
ctx->frames->initial_pool_size += avctx->thread_count;
|
||||
ctx->frames->format = AV_PIX_FMT_VAAPI;
|
||||
ctx->frames->sw_format = ctx->decode_format;
|
||||
ctx->frames->width = ctx->decode_width;
|
||||
ctx->frames->height = ctx->decode_height;
|
||||
ctx->frames->initial_pool_size = ctx->decode_surfaces;
|
||||
|
||||
err = av_hwframe_ctx_init(ctx->frames_ref);
|
||||
if (err < 0) {
|
||||
@@ -197,15 +477,42 @@ int vaapi_decode_init(AVCodecContext *avctx)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
avfc = ctx->frames->hwctx;
|
||||
|
||||
vas = vaCreateContext(hwctx->display, ctx->va_config,
|
||||
ctx->decode_width, ctx->decode_height,
|
||||
VA_PROGRESSIVE,
|
||||
avfc->surface_ids, avfc->nb_surfaces,
|
||||
&ctx->va_context);
|
||||
if (vas != VA_STATUS_SUCCESS) {
|
||||
av_log(ctx, AV_LOG_ERROR, "Failed to create decode pipeline "
|
||||
"context: %d (%s).\n", vas, vaErrorStr(vas));
|
||||
err = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
av_log(ctx, AV_LOG_DEBUG, "VAAPI decoder (re)init complete.\n");
|
||||
|
||||
// We would like to set this on the AVCodecContext for use by whoever gets
|
||||
// the frames from the decoder, but unfortunately the AVCodecContext we
|
||||
// have here need not be the "real" one (H.264 makes many copies for
|
||||
// threading purposes). To avoid the problem, we instead store it in the
|
||||
// InputStream and propagate it from there.
|
||||
ist->hw_frames_ctx = av_buffer_ref(ctx->frames_ref);
|
||||
if (!ist->hw_frames_ctx) {
|
||||
err = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ist->hwaccel_uninit = &vaapi_decode_uninit;
|
||||
ist->hwaccel_get_buffer = &vaapi_get_buffer;
|
||||
ist->hwaccel_retrieve_data = &vaapi_retrieve_data;
|
||||
ist->hwaccel_ctx = ctx;
|
||||
ist->hwaccel_uninit = vaapi_decode_uninit;
|
||||
ist->hwaccel_get_buffer = vaapi_get_buffer;
|
||||
ist->hwaccel_retrieve_data = vaapi_retrieve_data;
|
||||
|
||||
ctx->decoder_vaapi_context.display = hwctx->display;
|
||||
ctx->decoder_vaapi_context.config_id = ctx->va_config;
|
||||
ctx->decoder_vaapi_context.context_id = ctx->va_context;
|
||||
avctx->hwaccel_context = &ctx->decoder_vaapi_context;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -220,8 +527,6 @@ av_cold int vaapi_device_init(const char *device)
|
||||
{
|
||||
int err;
|
||||
|
||||
av_buffer_unref(&hw_device_ctx);
|
||||
|
||||
err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI,
|
||||
device, NULL, 0);
|
||||
if (err < 0) {
|
||||
|
||||
@@ -48,6 +48,7 @@ static int videotoolbox_retrieve_data(AVCodecContext *s, AVFrame *frame)
|
||||
uint8_t *data[4] = { 0 };
|
||||
int linesize[4] = { 0 };
|
||||
int planes, ret, i;
|
||||
char codec_str[32];
|
||||
|
||||
av_frame_unref(vt->tmp_frame);
|
||||
|
||||
@@ -59,9 +60,9 @@ static int videotoolbox_retrieve_data(AVCodecContext *s, AVFrame *frame)
|
||||
case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: vt->tmp_frame->format = AV_PIX_FMT_NV12; break;
|
||||
#endif
|
||||
default:
|
||||
av_get_codec_tag_string(codec_str, sizeof(codec_str), s->codec_tag);
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"%s: Unsupported pixel format: %s\n",
|
||||
av_fourcc2str(s->codec_tag), videotoolbox_pixfmt);
|
||||
"%s: Unsupported pixel format: %s\n", codec_str, videotoolbox_pixfmt);
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
|
||||
|
||||
294
ffplay.c
294
ffplay.c
@@ -73,8 +73,8 @@ const int program_birth_year = 2003;
|
||||
/* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
|
||||
#define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
|
||||
|
||||
/* Step size for volume control in dB */
|
||||
#define SDL_VOLUME_STEP (0.75)
|
||||
/* Step size for volume control */
|
||||
#define SDL_VOLUME_STEP (SDL_MIX_MAXVOLUME / 50)
|
||||
|
||||
/* no AV sync correction is done if below the minimum AV sync threshold */
|
||||
#define AV_SYNC_THRESHOLD_MIN 0.04
|
||||
@@ -158,12 +158,13 @@ typedef struct Frame {
|
||||
double pts; /* presentation timestamp for the frame */
|
||||
double duration; /* estimated duration of the frame */
|
||||
int64_t pos; /* byte position of the frame in the input file */
|
||||
SDL_Texture *bmp;
|
||||
int allocated;
|
||||
int width;
|
||||
int height;
|
||||
int format;
|
||||
AVRational sar;
|
||||
int uploaded;
|
||||
int flip_v;
|
||||
} Frame;
|
||||
|
||||
typedef struct FrameQueue {
|
||||
@@ -272,7 +273,6 @@ typedef struct VideoState {
|
||||
double last_vis_time;
|
||||
SDL_Texture *vis_texture;
|
||||
SDL_Texture *sub_texture;
|
||||
SDL_Texture *vid_texture;
|
||||
|
||||
int subtitle_stream;
|
||||
AVStream *subtitle_st;
|
||||
@@ -321,8 +321,6 @@ static int subtitle_disable;
|
||||
static const char* wanted_stream_spec[AVMEDIA_TYPE_NB] = {0};
|
||||
static int seek_by_bytes = -1;
|
||||
static int display_disable;
|
||||
static int borderless;
|
||||
static int startup_volume = 100;
|
||||
static int show_status = 1;
|
||||
static int av_sync_type = AV_SYNC_AUDIO_MASTER;
|
||||
static int64_t start_time = AV_NOPTS_VALUE;
|
||||
@@ -357,6 +355,7 @@ static int64_t audio_callback_time;
|
||||
|
||||
static AVPacket flush_pkt;
|
||||
|
||||
#define FF_ALLOC_EVENT (SDL_USEREVENT)
|
||||
#define FF_QUIT_EVENT (SDL_USEREVENT + 2)
|
||||
|
||||
static SDL_Window *window;
|
||||
@@ -391,6 +390,8 @@ int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_picture(Frame *vp);
|
||||
|
||||
static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
|
||||
{
|
||||
MyAVPacketList *pkt1;
|
||||
@@ -674,6 +675,7 @@ static void frame_queue_destory(FrameQueue *f)
|
||||
Frame *vp = &f->queue[i];
|
||||
frame_queue_unref_item(vp);
|
||||
av_frame_free(&vp->frame);
|
||||
free_picture(vp);
|
||||
}
|
||||
SDL_DestroyMutex(f->mutex);
|
||||
SDL_DestroyCond(f->cond);
|
||||
@@ -794,6 +796,14 @@ static inline void fill_rectangle(int x, int y, int w, int h)
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
}
|
||||
|
||||
static void free_picture(Frame *vp)
|
||||
{
|
||||
if (vp->bmp) {
|
||||
SDL_DestroyTexture(vp->bmp);
|
||||
vp->bmp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
|
||||
{
|
||||
Uint32 format;
|
||||
@@ -851,20 +861,12 @@ static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **
|
||||
int ret = 0;
|
||||
switch (frame->format) {
|
||||
case AV_PIX_FMT_YUV420P:
|
||||
if (frame->linesize[0] < 0 || frame->linesize[1] < 0 || frame->linesize[2] < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Negative linesize is not supported for YUV.\n");
|
||||
return -1;
|
||||
}
|
||||
ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0],
|
||||
frame->data[1], frame->linesize[1],
|
||||
frame->data[2], frame->linesize[2]);
|
||||
break;
|
||||
case AV_PIX_FMT_BGRA:
|
||||
if (frame->linesize[0] < 0) {
|
||||
ret = SDL_UpdateTexture(tex, NULL, frame->data[0] + frame->linesize[0] * (frame->height - 1), -frame->linesize[0]);
|
||||
} else {
|
||||
ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]);
|
||||
}
|
||||
ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]);
|
||||
break;
|
||||
default:
|
||||
/* This should only happen if we are not using avfilter... */
|
||||
@@ -895,80 +897,78 @@ static void video_image_display(VideoState *is)
|
||||
SDL_Rect rect;
|
||||
|
||||
vp = frame_queue_peek_last(&is->pictq);
|
||||
if (is->subtitle_st) {
|
||||
if (frame_queue_nb_remaining(&is->subpq) > 0) {
|
||||
sp = frame_queue_peek(&is->subpq);
|
||||
if (vp->bmp) {
|
||||
if (is->subtitle_st) {
|
||||
if (frame_queue_nb_remaining(&is->subpq) > 0) {
|
||||
sp = frame_queue_peek(&is->subpq);
|
||||
|
||||
if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
|
||||
if (!sp->uploaded) {
|
||||
uint8_t* pixels[4];
|
||||
int pitch[4];
|
||||
int i;
|
||||
if (!sp->width || !sp->height) {
|
||||
sp->width = vp->width;
|
||||
sp->height = vp->height;
|
||||
}
|
||||
if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < sp->sub.num_rects; i++) {
|
||||
AVSubtitleRect *sub_rect = sp->sub.rects[i];
|
||||
|
||||
sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
|
||||
sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
|
||||
sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
|
||||
sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
|
||||
|
||||
is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
|
||||
sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
|
||||
sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
|
||||
0, NULL, NULL, NULL);
|
||||
if (!is->sub_convert_ctx) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
|
||||
if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
|
||||
if (!sp->uploaded) {
|
||||
uint8_t* pixels[4];
|
||||
int pitch[4];
|
||||
int i;
|
||||
if (!sp->width || !sp->height) {
|
||||
sp->width = vp->width;
|
||||
sp->height = vp->height;
|
||||
}
|
||||
if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < sp->sub.num_rects; i++) {
|
||||
AVSubtitleRect *sub_rect = sp->sub.rects[i];
|
||||
|
||||
sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
|
||||
sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
|
||||
sub_rect->w = av_clip(sub_rect->w, 0, sp->width - sub_rect->x);
|
||||
sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
|
||||
|
||||
is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
|
||||
sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
|
||||
sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
|
||||
0, NULL, NULL, NULL);
|
||||
if (!is->sub_convert_ctx) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
|
||||
return;
|
||||
}
|
||||
if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
|
||||
sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
|
||||
0, sub_rect->h, pixels, pitch);
|
||||
SDL_UnlockTexture(is->sub_texture);
|
||||
}
|
||||
}
|
||||
if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)pixels, pitch)) {
|
||||
sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
|
||||
0, sub_rect->h, pixels, pitch);
|
||||
SDL_UnlockTexture(is->sub_texture);
|
||||
}
|
||||
sp->uploaded = 1;
|
||||
}
|
||||
sp->uploaded = 1;
|
||||
}
|
||||
} else
|
||||
sp = NULL;
|
||||
} else
|
||||
sp = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
|
||||
calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
|
||||
|
||||
if (!vp->uploaded) {
|
||||
int sdl_pix_fmt = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_PIXELFORMAT_YV12 : SDL_PIXELFORMAT_ARGB8888;
|
||||
if (realloc_texture(&is->vid_texture, sdl_pix_fmt, vp->frame->width, vp->frame->height, SDL_BLENDMODE_NONE, 0) < 0)
|
||||
return;
|
||||
if (upload_texture(is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
|
||||
return;
|
||||
vp->uploaded = 1;
|
||||
vp->flip_v = vp->frame->linesize[0] < 0;
|
||||
}
|
||||
if (!vp->uploaded) {
|
||||
if (upload_texture(vp->bmp, vp->frame, &is->img_convert_ctx) < 0)
|
||||
return;
|
||||
vp->uploaded = 1;
|
||||
}
|
||||
|
||||
SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
|
||||
if (sp) {
|
||||
SDL_RenderCopy(renderer, vp->bmp, NULL, &rect);
|
||||
if (sp) {
|
||||
#if USE_ONEPASS_SUBTITLE_RENDER
|
||||
SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
|
||||
SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
|
||||
#else
|
||||
int i;
|
||||
double xratio = (double)rect.w / (double)sp->width;
|
||||
double yratio = (double)rect.h / (double)sp->height;
|
||||
for (i = 0; i < sp->sub.num_rects; i++) {
|
||||
SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
|
||||
SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
|
||||
.y = rect.y + sub_rect->y * yratio,
|
||||
.w = sub_rect->w * xratio,
|
||||
.h = sub_rect->h * yratio};
|
||||
SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
|
||||
}
|
||||
int i;
|
||||
double xratio = (double)rect.w / (double)sp->width;
|
||||
double yratio = (double)rect.h / (double)sp->height;
|
||||
for (i = 0; i < sp->sub.num_rects; i++) {
|
||||
SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
|
||||
SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
|
||||
.y = rect.y + sub_rect->y * yratio,
|
||||
.w = sub_rect->w * xratio,
|
||||
.h = sub_rect->h * yratio};
|
||||
SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1206,8 +1206,6 @@ static void stream_close(VideoState *is)
|
||||
av_free(is->filename);
|
||||
if (is->vis_texture)
|
||||
SDL_DestroyTexture(is->vis_texture);
|
||||
if (is->vid_texture)
|
||||
SDL_DestroyTexture(is->vid_texture);
|
||||
if (is->sub_texture)
|
||||
SDL_DestroyTexture(is->sub_texture);
|
||||
av_free(is);
|
||||
@@ -1248,10 +1246,13 @@ static void set_default_window_size(int width, int height, AVRational sar)
|
||||
default_height = rect.h;
|
||||
}
|
||||
|
||||
static int video_open(VideoState *is)
|
||||
static int video_open(VideoState *is, Frame *vp)
|
||||
{
|
||||
int w,h;
|
||||
|
||||
if (vp && vp->width)
|
||||
set_default_window_size(vp->width, vp->height, vp->sar);
|
||||
|
||||
if (screen_width) {
|
||||
w = screen_width;
|
||||
h = screen_height;
|
||||
@@ -1261,24 +1262,16 @@ static int video_open(VideoState *is)
|
||||
}
|
||||
|
||||
if (!window) {
|
||||
int flags = SDL_WINDOW_SHOWN;
|
||||
int flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
|
||||
if (!window_title)
|
||||
window_title = input_filename;
|
||||
if (is_full_screen)
|
||||
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
if (borderless)
|
||||
flags |= SDL_WINDOW_BORDERLESS;
|
||||
else
|
||||
flags |= SDL_WINDOW_RESIZABLE;
|
||||
window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
|
||||
if (window) {
|
||||
SDL_RendererInfo info;
|
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||
if (!renderer) {
|
||||
av_log(NULL, AV_LOG_WARNING, "Failed to initialize a hardware accelerated renderer: %s\n", SDL_GetError());
|
||||
renderer = SDL_CreateRenderer(window, -1, 0);
|
||||
}
|
||||
if (renderer) {
|
||||
if (!SDL_GetRendererInfo(renderer, &info))
|
||||
av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", info.name);
|
||||
@@ -1303,7 +1296,7 @@ static int video_open(VideoState *is)
|
||||
static void video_display(VideoState *is)
|
||||
{
|
||||
if (!window)
|
||||
video_open(is);
|
||||
video_open(is, NULL);
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
@@ -1450,11 +1443,9 @@ static void toggle_mute(VideoState *is)
|
||||
is->muted = !is->muted;
|
||||
}
|
||||
|
||||
static void update_volume(VideoState *is, int sign, double step)
|
||||
static void update_volume(VideoState *is, int sign, int step)
|
||||
{
|
||||
double volume_level = is->audio_volume ? (20 * log(is->audio_volume / (double)SDL_MIX_MAXVOLUME) / log(10)) : -1000.0;
|
||||
int new_volume = lrint(SDL_MIX_MAXVOLUME * pow(10.0, (volume_level + sign * step) / 20.0));
|
||||
is->audio_volume = av_clip(is->audio_volume == new_volume ? (is->audio_volume + sign) : new_volume, 0, SDL_MIX_MAXVOLUME);
|
||||
is->audio_volume = av_clip(is->audio_volume + sign * step, 0, SDL_MIX_MAXVOLUME);
|
||||
}
|
||||
|
||||
static void step_to_next_frame(VideoState *is)
|
||||
@@ -1672,6 +1663,38 @@ display:
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate a picture (needs to do that in main thread to avoid
|
||||
potential locking problems */
|
||||
static void alloc_picture(VideoState *is)
|
||||
{
|
||||
Frame *vp;
|
||||
int sdl_format;
|
||||
|
||||
vp = &is->pictq.queue[is->pictq.windex];
|
||||
|
||||
video_open(is, vp);
|
||||
|
||||
if (vp->format == AV_PIX_FMT_YUV420P)
|
||||
sdl_format = SDL_PIXELFORMAT_YV12;
|
||||
else
|
||||
sdl_format = SDL_PIXELFORMAT_ARGB8888;
|
||||
|
||||
if (realloc_texture(&vp->bmp, sdl_format, vp->width, vp->height, SDL_BLENDMODE_NONE, 0) < 0) {
|
||||
/* SDL allocates a buffer smaller than requested if the video
|
||||
* overlay hardware is unable to support the requested size. */
|
||||
av_log(NULL, AV_LOG_FATAL,
|
||||
"Error: the video system does not support an image\n"
|
||||
"size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
|
||||
"to reduce the image size.\n", vp->width, vp->height );
|
||||
do_exit(is);
|
||||
}
|
||||
|
||||
SDL_LockMutex(is->pictq.mutex);
|
||||
vp->allocated = 1;
|
||||
SDL_CondSignal(is->pictq.cond);
|
||||
SDL_UnlockMutex(is->pictq.mutex);
|
||||
}
|
||||
|
||||
static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
|
||||
{
|
||||
Frame *vp;
|
||||
@@ -1687,19 +1710,51 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double
|
||||
vp->sar = src_frame->sample_aspect_ratio;
|
||||
vp->uploaded = 0;
|
||||
|
||||
vp->width = src_frame->width;
|
||||
vp->height = src_frame->height;
|
||||
vp->format = src_frame->format;
|
||||
/* alloc or resize hardware picture buffer */
|
||||
if (!vp->bmp || !vp->allocated ||
|
||||
vp->width != src_frame->width ||
|
||||
vp->height != src_frame->height ||
|
||||
vp->format != src_frame->format) {
|
||||
SDL_Event event;
|
||||
|
||||
vp->pts = pts;
|
||||
vp->duration = duration;
|
||||
vp->pos = pos;
|
||||
vp->serial = serial;
|
||||
vp->allocated = 0;
|
||||
vp->width = src_frame->width;
|
||||
vp->height = src_frame->height;
|
||||
vp->format = src_frame->format;
|
||||
|
||||
set_default_window_size(vp->width, vp->height, vp->sar);
|
||||
/* the allocation must be done in the main thread to avoid
|
||||
locking problems. */
|
||||
event.type = FF_ALLOC_EVENT;
|
||||
event.user.data1 = is;
|
||||
SDL_PushEvent(&event);
|
||||
|
||||
av_frame_move_ref(vp->frame, src_frame);
|
||||
frame_queue_push(&is->pictq);
|
||||
/* wait until the picture is allocated */
|
||||
SDL_LockMutex(is->pictq.mutex);
|
||||
while (!vp->allocated && !is->videoq.abort_request) {
|
||||
SDL_CondWait(is->pictq.cond, is->pictq.mutex);
|
||||
}
|
||||
/* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
|
||||
if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, FF_ALLOC_EVENT, FF_ALLOC_EVENT) != 1) {
|
||||
while (!vp->allocated && !is->abort_request) {
|
||||
SDL_CondWait(is->pictq.cond, is->pictq.mutex);
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(is->pictq.mutex);
|
||||
|
||||
if (is->videoq.abort_request)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* if the frame is not skipped, then display it */
|
||||
if (vp->bmp) {
|
||||
vp->pts = pts;
|
||||
vp->duration = duration;
|
||||
vp->pos = pos;
|
||||
vp->serial = serial;
|
||||
|
||||
av_frame_move_ref(vp->frame, src_frame);
|
||||
frame_queue_push(&is->pictq);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2006,7 +2061,7 @@ static int audio_thread(void *arg)
|
||||
goto the_end;
|
||||
|
||||
while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) {
|
||||
tb = av_buffersink_get_time_base(is->out_audio_filter);
|
||||
tb = is->out_audio_filter->inputs[0]->time_base;
|
||||
#endif
|
||||
if (!(af = frame_queue_peek_writable(&is->sampq)))
|
||||
goto the_end;
|
||||
@@ -2114,7 +2169,7 @@ static int video_thread(void *arg)
|
||||
last_format = frame->format;
|
||||
last_serial = is->viddec.pkt_serial;
|
||||
last_vfilter_idx = is->vfilter_idx;
|
||||
frame_rate = av_buffersink_get_frame_rate(filt_out);
|
||||
frame_rate = filt_out->inputs[0]->frame_rate;
|
||||
}
|
||||
|
||||
ret = av_buffersrc_add_frame(filt_in, frame);
|
||||
@@ -2135,7 +2190,7 @@ static int video_thread(void *arg)
|
||||
is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
|
||||
if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
|
||||
is->frame_last_filter_delay = 0;
|
||||
tb = av_buffersink_get_time_base(filt_out);
|
||||
tb = filt_out->inputs[0]->time_base;
|
||||
#endif
|
||||
duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
|
||||
pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
|
||||
@@ -2572,7 +2627,7 @@ static int stream_component_open(VideoState *is, int stream_index)
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
#if CONFIG_AVFILTER
|
||||
{
|
||||
AVFilterContext *sink;
|
||||
AVFilterLink *link;
|
||||
|
||||
is->audio_filter_src.freq = avctx->sample_rate;
|
||||
is->audio_filter_src.channels = avctx->channels;
|
||||
@@ -2580,10 +2635,10 @@ static int stream_component_open(VideoState *is, int stream_index)
|
||||
is->audio_filter_src.fmt = avctx->sample_fmt;
|
||||
if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
|
||||
goto fail;
|
||||
sink = is->out_audio_filter;
|
||||
sample_rate = av_buffersink_get_sample_rate(sink);
|
||||
nb_channels = av_buffersink_get_channels(sink);
|
||||
channel_layout = av_buffersink_get_channel_layout(sink);
|
||||
link = is->out_audio_filter->inputs[0];
|
||||
sample_rate = link->sample_rate;
|
||||
nb_channels = avfilter_link_get_channels(link);
|
||||
channel_layout = link->channel_layout;
|
||||
}
|
||||
#else
|
||||
sample_rate = avctx->sample_rate;
|
||||
@@ -3036,13 +3091,7 @@ static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
|
||||
init_clock(&is->audclk, &is->audioq.serial);
|
||||
init_clock(&is->extclk, &is->extclk.serial);
|
||||
is->audio_clock_serial = -1;
|
||||
if (startup_volume < 0)
|
||||
av_log(NULL, AV_LOG_WARNING, "-volume=%d < 0, setting to 0\n", startup_volume);
|
||||
if (startup_volume > 100)
|
||||
av_log(NULL, AV_LOG_WARNING, "-volume=%d > 100, setting to 100\n", startup_volume);
|
||||
startup_volume = av_clip(startup_volume, 0, 100);
|
||||
startup_volume = av_clip(SDL_MIX_MAXVOLUME * startup_volume / 100, 0, SDL_MIX_MAXVOLUME);
|
||||
is->audio_volume = startup_volume;
|
||||
is->audio_volume = SDL_MIX_MAXVOLUME;
|
||||
is->muted = 0;
|
||||
is->av_sync_type = av_sync_type;
|
||||
is->read_tid = SDL_CreateThread(read_thread, "read_thread", is);
|
||||
@@ -3391,6 +3440,9 @@ static void event_loop(VideoState *cur_stream)
|
||||
case FF_QUIT_EVENT:
|
||||
do_exit(cur_stream);
|
||||
break;
|
||||
case FF_ALLOC_EVENT:
|
||||
alloc_picture(event.user.data1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -3520,8 +3572,6 @@ static const OptionDef options[] = {
|
||||
{ "t", HAS_ARG, { .func_arg = opt_duration }, "play \"duration\" seconds of audio/video", "duration" },
|
||||
{ "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
|
||||
{ "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
|
||||
{ "noborder", OPT_BOOL, { &borderless }, "borderless window" },
|
||||
{ "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
|
||||
{ "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
|
||||
{ "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
|
||||
{ "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
|
||||
|
||||
268
ffprobe.c
268
ffprobe.c
@@ -37,7 +37,6 @@
|
||||
#include "libavutil/hash.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/spherical.h"
|
||||
#include "libavutil/stereo3d.h"
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
@@ -51,19 +50,6 @@
|
||||
#include "libpostproc/postprocess.h"
|
||||
#include "cmdutils.h"
|
||||
|
||||
#include "libavutil/thread.h"
|
||||
|
||||
#if !HAVE_THREADS
|
||||
# ifdef pthread_mutex_lock
|
||||
# undef pthread_mutex_lock
|
||||
# endif
|
||||
# define pthread_mutex_lock(a)
|
||||
# ifdef pthread_mutex_unlock
|
||||
# undef pthread_mutex_unlock
|
||||
# endif
|
||||
# define pthread_mutex_unlock(a)
|
||||
#endif
|
||||
|
||||
typedef struct InputStream {
|
||||
AVStream *st;
|
||||
|
||||
@@ -99,7 +85,6 @@ static int do_show_library_versions = 0;
|
||||
static int do_show_pixel_formats = 0;
|
||||
static int do_show_pixel_format_flags = 0;
|
||||
static int do_show_pixel_format_components = 0;
|
||||
static int do_show_log = 0;
|
||||
|
||||
static int do_show_chapter_tags = 0;
|
||||
static int do_show_format_tags = 0;
|
||||
@@ -162,8 +147,6 @@ typedef enum {
|
||||
SECTION_ID_FRAME_TAGS,
|
||||
SECTION_ID_FRAME_SIDE_DATA_LIST,
|
||||
SECTION_ID_FRAME_SIDE_DATA,
|
||||
SECTION_ID_FRAME_LOG,
|
||||
SECTION_ID_FRAME_LOGS,
|
||||
SECTION_ID_LIBRARY_VERSION,
|
||||
SECTION_ID_LIBRARY_VERSIONS,
|
||||
SECTION_ID_PACKET,
|
||||
@@ -203,19 +186,17 @@ static struct section sections[] = {
|
||||
[SECTION_ID_FORMAT] = { SECTION_ID_FORMAT, "format", 0, { SECTION_ID_FORMAT_TAGS, -1 } },
|
||||
[SECTION_ID_FORMAT_TAGS] = { SECTION_ID_FORMAT_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "format_tags" },
|
||||
[SECTION_ID_FRAMES] = { SECTION_ID_FRAMES, "frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME, SECTION_ID_SUBTITLE, -1 } },
|
||||
[SECTION_ID_FRAME] = { SECTION_ID_FRAME, "frame", 0, { SECTION_ID_FRAME_TAGS, SECTION_ID_FRAME_SIDE_DATA_LIST, SECTION_ID_FRAME_LOGS, -1 } },
|
||||
[SECTION_ID_FRAME] = { SECTION_ID_FRAME, "frame", 0, { SECTION_ID_FRAME_TAGS, SECTION_ID_FRAME_SIDE_DATA_LIST, -1 } },
|
||||
[SECTION_ID_FRAME_TAGS] = { SECTION_ID_FRAME_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "frame_tags" },
|
||||
[SECTION_ID_FRAME_SIDE_DATA_LIST] ={ SECTION_ID_FRAME_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "frame_side_data_list" },
|
||||
[SECTION_ID_FRAME_SIDE_DATA_LIST] ={ SECTION_ID_FRAME_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA, -1 } },
|
||||
[SECTION_ID_FRAME_SIDE_DATA] = { SECTION_ID_FRAME_SIDE_DATA, "side_data", 0, { -1 } },
|
||||
[SECTION_ID_FRAME_LOGS] = { SECTION_ID_FRAME_LOGS, "logs", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_LOG, -1 } },
|
||||
[SECTION_ID_FRAME_LOG] = { SECTION_ID_FRAME_LOG, "log", 0, { -1 }, },
|
||||
[SECTION_ID_LIBRARY_VERSIONS] = { SECTION_ID_LIBRARY_VERSIONS, "library_versions", SECTION_FLAG_IS_ARRAY, { SECTION_ID_LIBRARY_VERSION, -1 } },
|
||||
[SECTION_ID_LIBRARY_VERSION] = { SECTION_ID_LIBRARY_VERSION, "library_version", 0, { -1 } },
|
||||
[SECTION_ID_PACKETS] = { SECTION_ID_PACKETS, "packets", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET, -1} },
|
||||
[SECTION_ID_PACKETS_AND_FRAMES] = { SECTION_ID_PACKETS_AND_FRAMES, "packets_and_frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET, -1} },
|
||||
[SECTION_ID_PACKET] = { SECTION_ID_PACKET, "packet", 0, { SECTION_ID_PACKET_TAGS, SECTION_ID_PACKET_SIDE_DATA_LIST, -1 } },
|
||||
[SECTION_ID_PACKET_TAGS] = { SECTION_ID_PACKET_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "packet_tags" },
|
||||
[SECTION_ID_PACKET_SIDE_DATA_LIST] ={ SECTION_ID_PACKET_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "packet_side_data_list" },
|
||||
[SECTION_ID_PACKET_SIDE_DATA_LIST] ={ SECTION_ID_PACKET_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET_SIDE_DATA, -1 } },
|
||||
[SECTION_ID_PACKET_SIDE_DATA] = { SECTION_ID_PACKET_SIDE_DATA, "side_data", 0, { -1 } },
|
||||
[SECTION_ID_PIXEL_FORMATS] = { SECTION_ID_PIXEL_FORMATS, "pixel_formats", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PIXEL_FORMAT, -1 } },
|
||||
[SECTION_ID_PIXEL_FORMAT] = { SECTION_ID_PIXEL_FORMAT, "pixel_format", 0, { SECTION_ID_PIXEL_FORMAT_FLAGS, SECTION_ID_PIXEL_FORMAT_COMPONENTS, -1 } },
|
||||
@@ -238,7 +219,7 @@ static struct section sections[] = {
|
||||
[SECTION_ID_STREAM] = { SECTION_ID_STREAM, "stream", 0, { SECTION_ID_STREAM_DISPOSITION, SECTION_ID_STREAM_TAGS, SECTION_ID_STREAM_SIDE_DATA_LIST, -1 } },
|
||||
[SECTION_ID_STREAM_DISPOSITION] = { SECTION_ID_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "stream_disposition" },
|
||||
[SECTION_ID_STREAM_TAGS] = { SECTION_ID_STREAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "stream_tags" },
|
||||
[SECTION_ID_STREAM_SIDE_DATA_LIST] ={ SECTION_ID_STREAM_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "stream_side_data_list" },
|
||||
[SECTION_ID_STREAM_SIDE_DATA_LIST] ={ SECTION_ID_STREAM_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_SIDE_DATA, -1 } },
|
||||
[SECTION_ID_STREAM_SIDE_DATA] = { SECTION_ID_STREAM_SIDE_DATA, "side_data", 0, { -1 } },
|
||||
[SECTION_ID_SUBTITLE] = { SECTION_ID_SUBTITLE, "subtitle", 0, { -1 } },
|
||||
};
|
||||
@@ -275,79 +256,11 @@ static uint64_t *nb_streams_packets;
|
||||
static uint64_t *nb_streams_frames;
|
||||
static int *selected_streams;
|
||||
|
||||
#if HAVE_THREADS
|
||||
pthread_mutex_t log_mutex;
|
||||
#endif
|
||||
typedef struct LogBuffer {
|
||||
char *context_name;
|
||||
int log_level;
|
||||
char *log_message;
|
||||
AVClassCategory category;
|
||||
char *parent_name;
|
||||
AVClassCategory parent_category;
|
||||
}LogBuffer;
|
||||
|
||||
static LogBuffer *log_buffer;
|
||||
static int log_buffer_size;
|
||||
|
||||
static void log_callback(void *ptr, int level, const char *fmt, va_list vl)
|
||||
{
|
||||
AVClass* avc = ptr ? *(AVClass **) ptr : NULL;
|
||||
va_list vl2;
|
||||
char line[1024];
|
||||
static int print_prefix = 1;
|
||||
void *new_log_buffer;
|
||||
|
||||
va_copy(vl2, vl);
|
||||
av_log_default_callback(ptr, level, fmt, vl);
|
||||
av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
|
||||
va_end(vl2);
|
||||
|
||||
#if HAVE_THREADS
|
||||
pthread_mutex_lock(&log_mutex);
|
||||
|
||||
new_log_buffer = av_realloc_array(log_buffer, log_buffer_size + 1, sizeof(*log_buffer));
|
||||
if (new_log_buffer) {
|
||||
char *msg;
|
||||
int i;
|
||||
|
||||
log_buffer = new_log_buffer;
|
||||
memset(&log_buffer[log_buffer_size], 0, sizeof(log_buffer[log_buffer_size]));
|
||||
log_buffer[log_buffer_size].context_name= avc ? av_strdup(avc->item_name(ptr)) : NULL;
|
||||
if (avc) {
|
||||
if (avc->get_category) log_buffer[log_buffer_size].category = avc->get_category(ptr);
|
||||
else log_buffer[log_buffer_size].category = avc->category;
|
||||
}
|
||||
log_buffer[log_buffer_size].log_level = level;
|
||||
msg = log_buffer[log_buffer_size].log_message = av_strdup(line);
|
||||
for (i=strlen(msg) - 1; i>=0 && msg[i] == '\n'; i--) {
|
||||
msg[i] = 0;
|
||||
}
|
||||
if (avc && avc->parent_log_context_offset) {
|
||||
AVClass** parent = *(AVClass ***) (((uint8_t *) ptr) +
|
||||
avc->parent_log_context_offset);
|
||||
if (parent && *parent) {
|
||||
log_buffer[log_buffer_size].parent_name = av_strdup((*parent)->item_name(parent));
|
||||
log_buffer[log_buffer_size].parent_category =
|
||||
(*parent)->get_category ? (*parent)->get_category(parent) :(*parent)->category;
|
||||
}
|
||||
}
|
||||
log_buffer_size ++;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&log_mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ffprobe_cleanup(int ret)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(sections); i++)
|
||||
av_dict_free(&(sections[i].entries_to_show));
|
||||
|
||||
#if HAVE_THREADS
|
||||
pthread_mutex_destroy(&log_mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct unit_value {
|
||||
@@ -1848,7 +1761,6 @@ static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id
|
||||
}
|
||||
|
||||
static void print_pkt_side_data(WriterContext *w,
|
||||
AVCodecParameters *par,
|
||||
const AVPacketSideData *side_data,
|
||||
int nb_side_data,
|
||||
SectionID id_data_list,
|
||||
@@ -1856,13 +1768,14 @@ static void print_pkt_side_data(WriterContext *w,
|
||||
{
|
||||
int i;
|
||||
|
||||
writer_print_section_header(w, id_data_list);
|
||||
writer_print_section_header(w, SECTION_ID_STREAM_SIDE_DATA_LIST);
|
||||
for (i = 0; i < nb_side_data; i++) {
|
||||
const AVPacketSideData *sd = &side_data[i];
|
||||
const char *name = av_packet_side_data_name(sd->type);
|
||||
|
||||
writer_print_section_header(w, id_data);
|
||||
writer_print_section_header(w, SECTION_ID_STREAM_SIDE_DATA);
|
||||
print_str("side_data_type", name ? name : "unknown");
|
||||
print_int("side_data_size", sd->size);
|
||||
if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
|
||||
writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1);
|
||||
print_int("rotation", av_display_rotation_get((int32_t *)sd->data));
|
||||
@@ -1870,84 +1783,60 @@ static void print_pkt_side_data(WriterContext *w,
|
||||
const AVStereo3D *stereo = (AVStereo3D *)sd->data;
|
||||
print_str("type", av_stereo3d_type_name(stereo->type));
|
||||
print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT));
|
||||
} else if (sd->type == AV_PKT_DATA_SPHERICAL) {
|
||||
const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
|
||||
print_str("projection", av_spherical_projection_name(spherical->projection));
|
||||
if (spherical->projection == AV_SPHERICAL_CUBEMAP) {
|
||||
print_int("padding", spherical->padding);
|
||||
} else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) {
|
||||
size_t l, t, r, b;
|
||||
av_spherical_tile_bounds(spherical, par->width, par->height,
|
||||
&l, &t, &r, &b);
|
||||
print_int("bound_left", l);
|
||||
print_int("bound_top", t);
|
||||
print_int("bound_right", r);
|
||||
print_int("bound_bottom", b);
|
||||
}
|
||||
|
||||
print_int("yaw", (double) spherical->yaw / (1 << 16));
|
||||
print_int("pitch", (double) spherical->pitch / (1 << 16));
|
||||
print_int("roll", (double) spherical->roll / (1 << 16));
|
||||
} else if (sd->type == AV_PKT_DATA_SKIP_SAMPLES && sd->size == 10) {
|
||||
print_int("skip_samples", AV_RL32(sd->data));
|
||||
print_int("discard_padding", AV_RL32(sd->data + 4));
|
||||
print_int("skip_reason", AV_RL8(sd->data + 8));
|
||||
print_int("discard_reason", AV_RL8(sd->data + 9));
|
||||
}
|
||||
writer_print_section_footer(w);
|
||||
}
|
||||
writer_print_section_footer(w);
|
||||
}
|
||||
|
||||
static void clear_log(int need_lock)
|
||||
static void print_color_range(WriterContext *w, enum AVColorRange color_range, const char *fallback)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (need_lock)
|
||||
pthread_mutex_lock(&log_mutex);
|
||||
for (i=0; i<log_buffer_size; i++) {
|
||||
av_freep(&log_buffer[i].context_name);
|
||||
av_freep(&log_buffer[i].parent_name);
|
||||
av_freep(&log_buffer[i].log_message);
|
||||
const char *val = av_color_range_name(color_range);
|
||||
if (!val || color_range == AVCOL_RANGE_UNSPECIFIED) {
|
||||
print_str_opt("color_range", fallback);
|
||||
} else {
|
||||
print_str("color_range", val);
|
||||
}
|
||||
log_buffer_size = 0;
|
||||
if(need_lock)
|
||||
pthread_mutex_unlock(&log_mutex);
|
||||
}
|
||||
|
||||
static int show_log(WriterContext *w, int section_ids, int section_id, int log_level)
|
||||
static void print_color_space(WriterContext *w, enum AVColorSpace color_space)
|
||||
{
|
||||
int i;
|
||||
pthread_mutex_lock(&log_mutex);
|
||||
if (!log_buffer_size) {
|
||||
pthread_mutex_unlock(&log_mutex);
|
||||
return 0;
|
||||
const char *val = av_color_space_name(color_space);
|
||||
if (!val || color_space == AVCOL_SPC_UNSPECIFIED) {
|
||||
print_str_opt("color_space", "unknown");
|
||||
} else {
|
||||
print_str("color_space", val);
|
||||
}
|
||||
writer_print_section_header(w, section_ids);
|
||||
}
|
||||
|
||||
for (i=0; i<log_buffer_size; i++) {
|
||||
if (log_buffer[i].log_level <= log_level) {
|
||||
writer_print_section_header(w, section_id);
|
||||
print_str("context", log_buffer[i].context_name);
|
||||
print_int("level", log_buffer[i].log_level);
|
||||
print_int("category", log_buffer[i].category);
|
||||
if (log_buffer[i].parent_name) {
|
||||
print_str("parent_context", log_buffer[i].parent_name);
|
||||
print_int("parent_category", log_buffer[i].parent_category);
|
||||
} else {
|
||||
print_str_opt("parent_context", "N/A");
|
||||
print_str_opt("parent_category", "N/A");
|
||||
}
|
||||
print_str("message", log_buffer[i].log_message);
|
||||
writer_print_section_footer(w);
|
||||
}
|
||||
static void print_primaries(WriterContext *w, enum AVColorPrimaries color_primaries)
|
||||
{
|
||||
const char *val = av_color_primaries_name(color_primaries);
|
||||
if (!val || color_primaries == AVCOL_PRI_UNSPECIFIED) {
|
||||
print_str_opt("color_primaries", "unknown");
|
||||
} else {
|
||||
print_str("color_primaries", val);
|
||||
}
|
||||
clear_log(0);
|
||||
pthread_mutex_unlock(&log_mutex);
|
||||
}
|
||||
|
||||
writer_print_section_footer(w);
|
||||
static void print_color_trc(WriterContext *w, enum AVColorTransferCharacteristic color_trc)
|
||||
{
|
||||
const char *val = av_color_transfer_name(color_trc);
|
||||
if (!val || color_trc == AVCOL_TRC_UNSPECIFIED) {
|
||||
print_str_opt("color_transfer", "unknown");
|
||||
} else {
|
||||
print_str("color_transfer", val);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
static void print_chroma_location(WriterContext *w, enum AVChromaLocation chroma_location)
|
||||
{
|
||||
const char *val = av_chroma_location_name(chroma_location);
|
||||
if (!val || chroma_location == AVCHROMA_LOC_UNSPECIFIED) {
|
||||
print_str_opt("chroma_location", "unspecified");
|
||||
} else {
|
||||
print_str("chroma_location", val);
|
||||
}
|
||||
}
|
||||
|
||||
static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int packet_idx)
|
||||
@@ -1991,7 +1880,7 @@ static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int p
|
||||
av_dict_free(&dict);
|
||||
}
|
||||
|
||||
print_pkt_side_data(w, st->codecpar, pkt->side_data, pkt->side_data_elems,
|
||||
print_pkt_side_data(w, pkt->side_data, pkt->side_data_elems,
|
||||
SECTION_ID_PACKET_SIDE_DATA_LIST,
|
||||
SECTION_ID_PACKET_SIDE_DATA);
|
||||
}
|
||||
@@ -2098,8 +1987,6 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
|
||||
}
|
||||
if (do_show_frame_tags)
|
||||
show_tags(w, av_frame_get_metadata(frame), SECTION_ID_FRAME_TAGS);
|
||||
if (do_show_log)
|
||||
show_log(w, SECTION_ID_FRAME_LOGS, SECTION_ID_FRAME_LOG, do_show_log);
|
||||
if (frame->nb_side_data) {
|
||||
writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA_LIST);
|
||||
for (i = 0; i < frame->nb_side_data; i++) {
|
||||
@@ -2109,6 +1996,7 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
|
||||
writer_print_section_header(w, SECTION_ID_FRAME_SIDE_DATA);
|
||||
name = av_frame_side_data_name(sd->type);
|
||||
print_str("side_data_type", name ? name : "unknown");
|
||||
print_int("side_data_size", sd->size);
|
||||
if (sd->type == AV_FRAME_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
|
||||
writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1);
|
||||
print_int("rotation", av_display_rotation_get((int32_t *)sd->data));
|
||||
@@ -2138,7 +2026,6 @@ static av_always_inline int process_frame(WriterContext *w,
|
||||
AVSubtitle sub;
|
||||
int ret = 0, got_frame = 0;
|
||||
|
||||
clear_log(1);
|
||||
if (dec_ctx && dec_ctx->codec) {
|
||||
switch (par->codec_type) {
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
@@ -2378,8 +2265,9 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id
|
||||
#endif
|
||||
|
||||
/* print AVI/FourCC tag */
|
||||
print_str("codec_tag_string", av_fourcc2str(par->codec_tag));
|
||||
print_fmt("codec_tag", "0x%04"PRIx32, par->codec_tag);
|
||||
av_get_codec_tag_string(val_str, sizeof(val_str), par->codec_tag);
|
||||
print_str("codec_tag_string", val_str);
|
||||
print_fmt("codec_tag", "0x%04x", par->codec_tag);
|
||||
|
||||
switch (par->codec_type) {
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
@@ -2406,29 +2294,12 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id
|
||||
if (s) print_str ("pix_fmt", s);
|
||||
else print_str_opt("pix_fmt", "unknown");
|
||||
print_int("level", par->level);
|
||||
if (par->color_range != AVCOL_RANGE_UNSPECIFIED)
|
||||
print_str ("color_range", av_color_range_name(par->color_range));
|
||||
else
|
||||
print_str_opt("color_range", "N/A");
|
||||
|
||||
s = av_get_colorspace_name(par->color_space);
|
||||
if (s) print_str ("color_space", s);
|
||||
else print_str_opt("color_space", "unknown");
|
||||
|
||||
if (par->color_trc != AVCOL_TRC_UNSPECIFIED)
|
||||
print_str("color_transfer", av_color_transfer_name(par->color_trc));
|
||||
else
|
||||
print_str_opt("color_transfer", av_color_transfer_name(par->color_trc));
|
||||
|
||||
if (par->color_primaries != AVCOL_PRI_UNSPECIFIED)
|
||||
print_str("color_primaries", av_color_primaries_name(par->color_primaries));
|
||||
else
|
||||
print_str_opt("color_primaries", av_color_primaries_name(par->color_primaries));
|
||||
|
||||
if (par->chroma_location != AVCHROMA_LOC_UNSPECIFIED)
|
||||
print_str("chroma_location", av_chroma_location_name(par->chroma_location));
|
||||
else
|
||||
print_str_opt("chroma_location", av_chroma_location_name(par->chroma_location));
|
||||
print_color_range(w, par->color_range, "N/A");
|
||||
print_color_space(w, par->color_space);
|
||||
print_color_trc(w, par->color_trc);
|
||||
print_primaries(w, par->color_primaries);
|
||||
print_chroma_location(w, par->chroma_location);
|
||||
|
||||
if (par->field_order == AV_FIELD_PROGRESSIVE)
|
||||
print_str("field_order", "progressive");
|
||||
@@ -2553,7 +2424,7 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id
|
||||
ret = show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS);
|
||||
|
||||
if (stream->nb_side_data) {
|
||||
print_pkt_side_data(w, stream->codecpar, stream->side_data, stream->nb_side_data,
|
||||
print_pkt_side_data(w, stream->side_data, stream->nb_side_data,
|
||||
SECTION_ID_STREAM_SIDE_DATA_LIST,
|
||||
SECTION_ID_STREAM_SIDE_DATA);
|
||||
}
|
||||
@@ -2713,14 +2584,6 @@ static int open_input_file(InputFile *ifile, const char *filename)
|
||||
AVDictionary **opts;
|
||||
int scan_all_pmts_set = 0;
|
||||
|
||||
fmt_ctx = avformat_alloc_context();
|
||||
if (!fmt_ctx) {
|
||||
print_error(filename, AVERROR(ENOMEM));
|
||||
exit_program(1);
|
||||
}
|
||||
|
||||
fmt_ctx->flags |= AVFMT_FLAG_KEEP_SIDE_DATA;
|
||||
|
||||
if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {
|
||||
av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);
|
||||
scan_all_pmts_set = 1;
|
||||
@@ -2795,13 +2658,6 @@ static int open_input_file(InputFile *ifile, const char *filename)
|
||||
if (err < 0)
|
||||
exit(1);
|
||||
|
||||
if (do_show_log) {
|
||||
// For loging it is needed to disable at least frame threads as otherwise
|
||||
// the log information would need to be reordered and matches up to contexts and frames
|
||||
// That is in fact possible but not trivial
|
||||
av_dict_set(&codec_opts, "threads", "1", 0);
|
||||
}
|
||||
|
||||
av_codec_set_pkt_timebase(ist->dec_ctx, stream->time_base);
|
||||
ist->dec_ctx->framerate = stream->avg_frame_rate;
|
||||
|
||||
@@ -3157,7 +3013,6 @@ void show_help_default(const char *opt, const char *arg)
|
||||
printf("\n");
|
||||
|
||||
show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
|
||||
show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3387,9 +3242,6 @@ static const OptionDef real_options[] = {
|
||||
"show a particular entry from the format/container info", "entry" },
|
||||
{ "show_entries", HAS_ARG, {.func_arg = opt_show_entries},
|
||||
"show a set of specified entries", "entry_list" },
|
||||
#if HAVE_THREADS
|
||||
{ "show_log", OPT_INT|HAS_ARG, {(void*)&do_show_log}, "show log" },
|
||||
#endif
|
||||
{ "show_packets", 0, {(void*)&opt_show_packets}, "show packets info" },
|
||||
{ "show_programs", 0, {(void*)&opt_show_programs}, "show programs info" },
|
||||
{ "show_streams", 0, {(void*)&opt_show_streams}, "show streams info" },
|
||||
@@ -3436,14 +3288,6 @@ int main(int argc, char **argv)
|
||||
|
||||
init_dynload();
|
||||
|
||||
#if HAVE_THREADS
|
||||
ret = pthread_mutex_init(&log_mutex, NULL);
|
||||
if (ret != 0) {
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
av_log_set_callback(log_callback);
|
||||
|
||||
av_log_set_flags(AV_LOG_SKIP_REPEATED);
|
||||
register_exit(ffprobe_cleanup);
|
||||
|
||||
|
||||
400
ffserver.c
400
ffserver.c
@@ -32,10 +32,16 @@
|
||||
#include <stdio.h>
|
||||
#include "libavformat/avformat.h"
|
||||
/* FIXME: those are internal headers, ffserver _really_ shouldn't use them */
|
||||
#include "libavformat/ffm.h"
|
||||
#include "libavformat/network.h"
|
||||
#include "libavformat/os_support.h"
|
||||
#include "libavformat/rtpdec.h"
|
||||
#include "libavformat/rtpproto.h"
|
||||
#include "libavformat/rtsp.h"
|
||||
#include "libavformat/rtspcodes.h"
|
||||
#include "libavformat/avio_internal.h"
|
||||
#include "libavformat/internal.h"
|
||||
#include "libavformat/url.h"
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avstring.h"
|
||||
@@ -44,7 +50,6 @@
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavutil/random_seed.h"
|
||||
#include "libavutil/rational.h"
|
||||
#include "libavutil/parseutils.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/time.h"
|
||||
@@ -156,7 +161,7 @@ typedef struct HTTPContext {
|
||||
int feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */
|
||||
int switch_feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */
|
||||
int switch_pending;
|
||||
AVFormatContext *pfmt_ctx; /* instance of FFServerStream for one user */
|
||||
AVFormatContext fmt_ctx; /* instance of FFServerStream for one user */
|
||||
int last_packet_sent; /* true if last data packet was sent */
|
||||
int suppress_log;
|
||||
DataRateData datarate;
|
||||
@@ -164,7 +169,6 @@ typedef struct HTTPContext {
|
||||
char protocol[16];
|
||||
char method[16];
|
||||
char url[128];
|
||||
char clean_url[128*7];
|
||||
int buffer_size;
|
||||
uint8_t *buffer;
|
||||
int is_packetized; /* if true, the stream is packetized */
|
||||
@@ -188,6 +192,11 @@ typedef struct HTTPContext {
|
||||
uint8_t *packet_buffer, *packet_buffer_ptr, *packet_buffer_end;
|
||||
} HTTPContext;
|
||||
|
||||
typedef struct FeedData {
|
||||
long long data_count;
|
||||
float avg_frame_size; /* frame size averaged over last frames with exponential mean */
|
||||
} FeedData;
|
||||
|
||||
static HTTPContext *first_http_ctx;
|
||||
|
||||
static FFServerConfig config = {
|
||||
@@ -236,7 +245,8 @@ static int rtp_new_av_stream(HTTPContext *c,
|
||||
/* utils */
|
||||
static size_t htmlencode (const char *src, char **dest);
|
||||
static inline void cp_html_entity (char *buffer, const char *entity);
|
||||
static inline int check_codec_match(LayeredAVStream *ccf, AVStream *ccs, int stream);
|
||||
static inline int check_codec_match(AVCodecContext *ccf, AVCodecContext *ccs,
|
||||
int stream);
|
||||
|
||||
static const char *my_program_name;
|
||||
|
||||
@@ -255,21 +265,6 @@ static AVLFG random_state;
|
||||
|
||||
static FILE *logfile = NULL;
|
||||
|
||||
static void unlayer_stream(AVStream *st, LayeredAVStream *lst)
|
||||
{
|
||||
avcodec_free_context(&st->codec);
|
||||
avcodec_parameters_free(&st->codecpar);
|
||||
#define COPY(a) st->a = lst->a;
|
||||
COPY(index)
|
||||
COPY(id)
|
||||
COPY(codec)
|
||||
COPY(codecpar)
|
||||
COPY(time_base)
|
||||
COPY(pts_wrap_bits)
|
||||
COPY(sample_aspect_ratio)
|
||||
COPY(recommended_encoder_configuration)
|
||||
}
|
||||
|
||||
static inline void cp_html_entity (char *buffer, const char *entity) {
|
||||
if (!buffer || !entity)
|
||||
return;
|
||||
@@ -495,22 +490,20 @@ static void start_children(FFServerStream *feed)
|
||||
return;
|
||||
}
|
||||
|
||||
slash = strrchr(my_program_name, '/');
|
||||
if (!slash) {
|
||||
pathname = av_mallocz(sizeof("ffmpeg"));
|
||||
} else {
|
||||
pathname = av_mallocz(slash - my_program_name + sizeof("ffmpeg"));
|
||||
if (pathname != NULL) {
|
||||
memcpy(pathname, my_program_name, slash - my_program_name);
|
||||
}
|
||||
}
|
||||
pathname = av_strdup (my_program_name);
|
||||
if (!pathname) {
|
||||
http_log("Could not allocate memory for children cmd line\n");
|
||||
return;
|
||||
}
|
||||
/* use "ffmpeg" in the path of current program. Ignore user provided path */
|
||||
/* replace "ffserver" with "ffmpeg" in the path of current
|
||||
* program. Ignore user provided path */
|
||||
|
||||
strcat(pathname, "ffmpeg");
|
||||
slash = strrchr(pathname, '/');
|
||||
if (!slash)
|
||||
slash = pathname;
|
||||
else
|
||||
slash++;
|
||||
strcpy(slash, "ffmpeg");
|
||||
|
||||
for (; feed; feed = feed->next) {
|
||||
|
||||
@@ -943,22 +936,21 @@ static void close_connection(HTTPContext *c)
|
||||
ffurl_close(c->rtp_handles[i]);
|
||||
}
|
||||
|
||||
ctx = c->pfmt_ctx;
|
||||
ctx = &c->fmt_ctx;
|
||||
|
||||
if (ctx) {
|
||||
if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) {
|
||||
/* prepare header */
|
||||
if (ctx->oformat && avio_open_dyn_buf(&ctx->pb) >= 0) {
|
||||
av_write_trailer(ctx);
|
||||
av_freep(&c->pb_buffer);
|
||||
avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
|
||||
}
|
||||
}
|
||||
for(i=0; i<ctx->nb_streams; i++)
|
||||
av_freep(&ctx->streams[i]);
|
||||
av_freep(&ctx->streams);
|
||||
av_freep(&ctx->priv_data);
|
||||
if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) {
|
||||
/* prepare header */
|
||||
if (ctx->oformat && avio_open_dyn_buf(&ctx->pb) >= 0) {
|
||||
av_write_trailer(ctx);
|
||||
av_freep(&c->pb_buffer);
|
||||
avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<ctx->nb_streams; i++)
|
||||
av_freep(&ctx->streams[i]);
|
||||
av_freep(&ctx->streams);
|
||||
av_freep(&ctx->priv_data);
|
||||
|
||||
if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
|
||||
current_bandwidth -= c->stream->bandwidth;
|
||||
@@ -1204,7 +1196,7 @@ static int extract_rates(char *rates, int ratelen, const char *request)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_stream_in_feed(FFServerStream *feed, AVCodecParameters *codec,
|
||||
static int find_stream_in_feed(FFServerStream *feed, AVCodecContext *codec,
|
||||
int bit_rate)
|
||||
{
|
||||
int i;
|
||||
@@ -1212,7 +1204,7 @@ static int find_stream_in_feed(FFServerStream *feed, AVCodecParameters *codec,
|
||||
int best = -1;
|
||||
|
||||
for (i = 0; i < feed->nb_streams; i++) {
|
||||
AVCodecParameters *feed_codec = feed->streams[i]->codecpar;
|
||||
AVCodecContext *feed_codec = feed->streams[i]->codec;
|
||||
|
||||
if (feed_codec->codec_id != codec->codec_id ||
|
||||
feed_codec->sample_rate != codec->sample_rate ||
|
||||
@@ -1253,7 +1245,7 @@ static int modify_current_stream(HTTPContext *c, char *rates)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < req->nb_streams; i++) {
|
||||
AVCodecParameters *codec = req->streams[i]->codecpar;
|
||||
AVCodecContext *codec = req->streams[i]->codec;
|
||||
|
||||
switch(rates[i]) {
|
||||
case 0:
|
||||
@@ -1287,8 +1279,6 @@ static void get_word(char *buf, int buf_size, const char **pp)
|
||||
const char *p;
|
||||
char *q;
|
||||
|
||||
#define SPACE_CHARS " \t\r\n"
|
||||
|
||||
p = *pp;
|
||||
p += strspn(p, SPACE_CHARS);
|
||||
q = buf;
|
||||
@@ -1702,7 +1692,7 @@ static int http_parse_request(HTTPContext *c)
|
||||
memcpy(q, sdp_data, sdp_data_size);
|
||||
q += sdp_data_size;
|
||||
*q = '\0';
|
||||
av_freep(&sdp_data);
|
||||
av_free(sdp_data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1882,75 +1872,47 @@ static inline void print_stream_params(AVIOContext *pb, FFServerStream *stream)
|
||||
int i, stream_no;
|
||||
const char *type = "unknown";
|
||||
char parameters[64];
|
||||
LayeredAVStream *st;
|
||||
AVStream *st;
|
||||
AVCodec *codec;
|
||||
|
||||
stream_no = stream->nb_streams;
|
||||
|
||||
avio_printf(pb, "<table><tr><th>Stream<th>"
|
||||
"type<th>kbit/s<th>codec<th>"
|
||||
avio_printf(pb, "<table cellspacing=0 cellpadding=4><tr><th>Stream<th>"
|
||||
"type<th>kbit/s<th align=left>codec<th align=left>"
|
||||
"Parameters\n");
|
||||
|
||||
for (i = 0; i < stream_no; i++) {
|
||||
st = stream->streams[i];
|
||||
codec = avcodec_find_encoder(st->codecpar->codec_id);
|
||||
codec = avcodec_find_encoder(st->codec->codec_id);
|
||||
|
||||
parameters[0] = 0;
|
||||
|
||||
switch(st->codecpar->codec_type) {
|
||||
switch(st->codec->codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
type = "audio";
|
||||
snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz",
|
||||
st->codecpar->channels, st->codecpar->sample_rate);
|
||||
st->codec->channels, st->codec->sample_rate);
|
||||
break;
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
type = "video";
|
||||
snprintf(parameters, sizeof(parameters),
|
||||
"%dx%d, q=%d-%d, fps=%d", st->codecpar->width,
|
||||
st->codecpar->height, st->codec->qmin, st->codec->qmax,
|
||||
st->time_base.den / st->time_base.num);
|
||||
"%dx%d, q=%d-%d, fps=%d", st->codec->width,
|
||||
st->codec->height, st->codec->qmin, st->codec->qmax,
|
||||
st->codec->time_base.den / st->codec->time_base.num);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
avio_printf(pb, "<tr><td>%d<td>%s<td>%"PRId64
|
||||
avio_printf(pb, "<tr><td align=right>%d<td>%s<td align=right>%"PRId64
|
||||
"<td>%s<td>%s\n",
|
||||
i, type, (int64_t)st->codecpar->bit_rate/1000,
|
||||
i, type, (int64_t)st->codec->bit_rate/1000,
|
||||
codec ? codec->name : "", parameters);
|
||||
}
|
||||
|
||||
avio_printf(pb, "</table>\n");
|
||||
}
|
||||
|
||||
static void clean_html(char *clean, int clean_len, char *dirty)
|
||||
{
|
||||
int i, o;
|
||||
|
||||
for (o = i = 0; o+10 < clean_len && dirty[i];) {
|
||||
int len = strspn(dirty+i, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$-_.+!*(),?/ :;%");
|
||||
if (len) {
|
||||
if (o + len >= clean_len)
|
||||
break;
|
||||
memcpy(clean + o, dirty + i, len);
|
||||
i += len;
|
||||
o += len;
|
||||
} else {
|
||||
int c = dirty[i++];
|
||||
switch (c) {
|
||||
case '&': av_strlcat(clean+o, "&" , clean_len - o); break;
|
||||
case '<': av_strlcat(clean+o, "<" , clean_len - o); break;
|
||||
case '>': av_strlcat(clean+o, ">" , clean_len - o); break;
|
||||
case '\'': av_strlcat(clean+o, "'" , clean_len - o); break;
|
||||
case '\"': av_strlcat(clean+o, """ , clean_len - o); break;
|
||||
default: av_strlcat(clean+o, "☹", clean_len - o); break;
|
||||
}
|
||||
o += strlen(clean+o);
|
||||
}
|
||||
}
|
||||
clean[o] = 0;
|
||||
}
|
||||
|
||||
static void compute_status(HTTPContext *c)
|
||||
{
|
||||
HTTPContext *c1;
|
||||
@@ -1981,8 +1943,8 @@ static void compute_status(HTTPContext *c)
|
||||
avio_printf(pb, "<h1>%s Status</h1>\n", program_name);
|
||||
/* format status */
|
||||
avio_printf(pb, "<h2>Available Streams</h2>\n");
|
||||
avio_printf(pb, "<table>\n");
|
||||
avio_printf(pb, "<tr><th>Path<th>Served<br>Conns<th><br>bytes<th>Format<th>Bit rate<br>kbit/s<th>Video<br>kbit/s<th><br>Codec<th>Audio<br>kbit/s<th><br>Codec<th>Feed\n");
|
||||
avio_printf(pb, "<table cellspacing=0 cellpadding=4>\n");
|
||||
avio_printf(pb, "<tr><th valign=top>Path<th align=left>Served<br>Conns<th><br>bytes<th valign=top>Format<th>Bit rate<br>kbit/s<th align=left>Video<br>kbit/s<th><br>Codec<th align=left>Audio<br>kbit/s<th><br>Codec<th align=left valign=top>Feed\n");
|
||||
stream = config.first_stream;
|
||||
while (stream) {
|
||||
char sfilename[1024];
|
||||
@@ -2016,11 +1978,9 @@ static void compute_status(HTTPContext *c)
|
||||
|
||||
avio_printf(pb, "<tr><td><a href=\"/%s\">%s</a> ",
|
||||
sfilename, stream->filename);
|
||||
avio_printf(pb, "<td> %d <td> ",
|
||||
avio_printf(pb, "<td align=right> %d <td align=right> ",
|
||||
stream->conns_served);
|
||||
// TODO: Investigate if we can make http bitexact so it always produces the same count of bytes
|
||||
if (!config.bitexact)
|
||||
fmt_bytecount(pb, stream->bytes_served);
|
||||
fmt_bytecount(pb, stream->bytes_served);
|
||||
|
||||
switch(stream->stream_type) {
|
||||
case STREAM_TYPE_LIVE: {
|
||||
@@ -2032,12 +1992,12 @@ static void compute_status(HTTPContext *c)
|
||||
const char *video_codec_name_extra = "";
|
||||
|
||||
for(i=0;i<stream->nb_streams;i++) {
|
||||
LayeredAVStream *st = stream->streams[i];
|
||||
AVCodec *codec = avcodec_find_encoder(st->codecpar->codec_id);
|
||||
AVStream *st = stream->streams[i];
|
||||
AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
|
||||
|
||||
switch(st->codecpar->codec_type) {
|
||||
switch(st->codec->codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
audio_bit_rate += st->codecpar->bit_rate;
|
||||
audio_bit_rate += st->codec->bit_rate;
|
||||
if (codec) {
|
||||
if (*audio_codec_name)
|
||||
audio_codec_name_extra = "...";
|
||||
@@ -2045,7 +2005,7 @@ static void compute_status(HTTPContext *c)
|
||||
}
|
||||
break;
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
video_bit_rate += st->codecpar->bit_rate;
|
||||
video_bit_rate += st->codec->bit_rate;
|
||||
if (codec) {
|
||||
if (*video_codec_name)
|
||||
video_codec_name_extra = "...";
|
||||
@@ -2053,14 +2013,15 @@ static void compute_status(HTTPContext *c)
|
||||
}
|
||||
break;
|
||||
case AVMEDIA_TYPE_DATA:
|
||||
video_bit_rate += st->codecpar->bit_rate;
|
||||
video_bit_rate += st->codec->bit_rate;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
avio_printf(pb, "<td> %s <td> %d <td> %d <td> %s %s <td> "
|
||||
avio_printf(pb, "<td align=center> %s <td align=right> %d "
|
||||
"<td align=right> %d <td> %s %s <td align=right> "
|
||||
"%d <td> %s %s",
|
||||
stream->fmt->name, stream->bandwidth,
|
||||
video_bit_rate / 1000, video_codec_name,
|
||||
@@ -2075,8 +2036,8 @@ static void compute_status(HTTPContext *c)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
avio_printf(pb, "<td> - <td> - "
|
||||
"<td> - <td><td> - <td>\n");
|
||||
avio_printf(pb, "<td align=center> - <td align=right> - "
|
||||
"<td align=right> - <td><td align=right> - <td>\n");
|
||||
break;
|
||||
}
|
||||
stream = stream->next;
|
||||
@@ -2137,7 +2098,7 @@ static void compute_status(HTTPContext *c)
|
||||
current_bandwidth, config.max_bandwidth);
|
||||
|
||||
avio_printf(pb, "<table>\n");
|
||||
avio_printf(pb, "<tr><th>#<th>File<th>IP<th>URL<th>Proto<th>State<th>Target "
|
||||
avio_printf(pb, "<tr><th>#<th>File<th>IP<th>Proto<th>State<th>Target "
|
||||
"bit/s<th>Actual bit/s<th>Bytes transferred\n");
|
||||
c1 = first_http_ctx;
|
||||
i = 0;
|
||||
@@ -2149,38 +2110,33 @@ static void compute_status(HTTPContext *c)
|
||||
if (c1->stream) {
|
||||
for (j = 0; j < c1->stream->nb_streams; j++) {
|
||||
if (!c1->stream->feed)
|
||||
bitrate += c1->stream->streams[j]->codecpar->bit_rate;
|
||||
bitrate += c1->stream->streams[j]->codec->bit_rate;
|
||||
else if (c1->feed_streams[j] >= 0)
|
||||
bitrate += c1->stream->feed->streams[c1->feed_streams[j]]->codecpar->bit_rate;
|
||||
bitrate += c1->stream->feed->streams[c1->feed_streams[j]]->codec->bit_rate;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
p = inet_ntoa(c1->from_addr.sin_addr);
|
||||
clean_html(c1->clean_url, sizeof(c1->clean_url), c1->url);
|
||||
avio_printf(pb, "<tr><td><b>%d</b><td>%s%s<td>%s<td>%s<td>%s<td>%s"
|
||||
"<td>",
|
||||
avio_printf(pb, "<tr><td><b>%d</b><td>%s%s<td>%s<td>%s<td>%s"
|
||||
"<td align=right>",
|
||||
i, c1->stream ? c1->stream->filename : "",
|
||||
c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "",
|
||||
p,
|
||||
c1->clean_url,
|
||||
c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "", p,
|
||||
c1->protocol, http_state[c1->state]);
|
||||
fmt_bytecount(pb, bitrate);
|
||||
avio_printf(pb, "<td>");
|
||||
avio_printf(pb, "<td align=right>");
|
||||
fmt_bytecount(pb, compute_datarate(&c1->datarate, c1->data_count) * 8);
|
||||
avio_printf(pb, "<td>");
|
||||
avio_printf(pb, "<td align=right>");
|
||||
fmt_bytecount(pb, c1->data_count);
|
||||
avio_printf(pb, "\n");
|
||||
c1 = c1->next;
|
||||
}
|
||||
avio_printf(pb, "</table>\n");
|
||||
|
||||
if (!config.bitexact) {
|
||||
/* date */
|
||||
ti = time(NULL);
|
||||
p = ctime(&ti);
|
||||
avio_printf(pb, "<hr>Generated at %s", p);
|
||||
}
|
||||
/* date */
|
||||
ti = time(NULL);
|
||||
p = ctime(&ti);
|
||||
avio_printf(pb, "<hr size=1 noshade>Generated at %s", p);
|
||||
avio_printf(pb, "</body>\n</html>\n");
|
||||
|
||||
len = avio_close_dyn_buf(pb, &c->pb_buffer);
|
||||
@@ -2306,14 +2262,17 @@ static int http_prepare_data(HTTPContext *c)
|
||||
ctx = avformat_alloc_context();
|
||||
if (!ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
c->pfmt_ctx = ctx;
|
||||
av_dict_copy(&(c->pfmt_ctx->metadata), c->stream->metadata, 0);
|
||||
c->fmt_ctx = *ctx;
|
||||
av_freep(&ctx);
|
||||
av_dict_copy(&(c->fmt_ctx.metadata), c->stream->metadata, 0);
|
||||
c->fmt_ctx.streams = av_mallocz_array(c->stream->nb_streams,
|
||||
sizeof(AVStream *));
|
||||
if (!c->fmt_ctx.streams)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
for(i=0;i<c->stream->nb_streams;i++) {
|
||||
LayeredAVStream *src;
|
||||
AVStream *st = avformat_new_stream(c->pfmt_ctx, NULL);
|
||||
if (!st)
|
||||
return AVERROR(ENOMEM);
|
||||
AVStream *src;
|
||||
c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
|
||||
|
||||
/* if file or feed, then just take streams from FFServerStream
|
||||
* struct */
|
||||
@@ -2323,40 +2282,39 @@ static int http_prepare_data(HTTPContext *c)
|
||||
else
|
||||
src = c->stream->feed->streams[c->stream->feed_streams[i]];
|
||||
|
||||
unlayer_stream(c->pfmt_ctx->streams[i], src); //TODO we no longer copy st->internal, does this matter?
|
||||
av_assert0(!c->pfmt_ctx->streams[i]->priv_data);
|
||||
|
||||
if (src->codec->flags & AV_CODEC_FLAG_BITEXACT)
|
||||
c->pfmt_ctx->flags |= AVFMT_FLAG_BITEXACT;
|
||||
*(c->fmt_ctx.streams[i]) = *src;
|
||||
c->fmt_ctx.streams[i]->priv_data = 0;
|
||||
/* XXX: should be done in AVStream, not in codec */
|
||||
c->fmt_ctx.streams[i]->codec->frame_number = 0;
|
||||
}
|
||||
/* set output format parameters */
|
||||
c->pfmt_ctx->oformat = c->stream->fmt;
|
||||
av_assert0(c->pfmt_ctx->nb_streams == c->stream->nb_streams);
|
||||
c->fmt_ctx.oformat = c->stream->fmt;
|
||||
c->fmt_ctx.nb_streams = c->stream->nb_streams;
|
||||
|
||||
c->got_key_frame = 0;
|
||||
|
||||
/* prepare header and save header data in a stream */
|
||||
if (avio_open_dyn_buf(&c->pfmt_ctx->pb) < 0) {
|
||||
if (avio_open_dyn_buf(&c->fmt_ctx.pb) < 0) {
|
||||
/* XXX: potential leak */
|
||||
return -1;
|
||||
}
|
||||
c->pfmt_ctx->pb->seekable = 0;
|
||||
c->fmt_ctx.pb->seekable = 0;
|
||||
|
||||
/*
|
||||
* HACK to avoid MPEG-PS muxer to spit many underflow errors
|
||||
* Default value from FFmpeg
|
||||
* Try to set it using configuration option
|
||||
*/
|
||||
c->pfmt_ctx->max_delay = (int)(0.7*AV_TIME_BASE);
|
||||
c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
|
||||
|
||||
if ((ret = avformat_write_header(c->pfmt_ctx, NULL)) < 0) {
|
||||
if ((ret = avformat_write_header(&c->fmt_ctx, NULL)) < 0) {
|
||||
http_log("Error writing output header for stream '%s': %s\n",
|
||||
c->stream->filename, av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
av_dict_free(&c->pfmt_ctx->metadata);
|
||||
av_dict_free(&c->fmt_ctx.metadata);
|
||||
|
||||
len = avio_close_dyn_buf(c->pfmt_ctx->pb, &c->pb_buffer);
|
||||
len = avio_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer);
|
||||
c->buffer_ptr = c->pb_buffer;
|
||||
c->buffer_end = c->pb_buffer + len;
|
||||
|
||||
@@ -2425,7 +2383,7 @@ static int http_prepare_data(HTTPContext *c)
|
||||
AVStream *st = c->fmt_in->streams[source_index];
|
||||
pkt.stream_index = i;
|
||||
if (pkt.flags & AV_PKT_FLAG_KEY &&
|
||||
(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
|
||||
(st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
|
||||
c->stream->nb_streams == 1))
|
||||
c->got_key_frame = 1;
|
||||
if (!c->stream->send_on_key || c->got_key_frame)
|
||||
@@ -2433,6 +2391,7 @@ static int http_prepare_data(HTTPContext *c)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
AVCodecContext *codec;
|
||||
AVStream *ist, *ost;
|
||||
send_it:
|
||||
ist = c->fmt_in->streams[source_index];
|
||||
@@ -2453,11 +2412,13 @@ static int http_prepare_data(HTTPContext *c)
|
||||
av_packet_unref(&pkt);
|
||||
break;
|
||||
}
|
||||
codec = ctx->streams[0]->codec;
|
||||
/* only one stream per RTP connection */
|
||||
pkt.stream_index = 0;
|
||||
} else {
|
||||
ctx = c->pfmt_ctx;
|
||||
ctx = &c->fmt_ctx;
|
||||
/* Fudge here */
|
||||
codec = ctx->streams[pkt.stream_index]->codec;
|
||||
}
|
||||
|
||||
if (c->is_packetized) {
|
||||
@@ -2499,6 +2460,7 @@ static int http_prepare_data(HTTPContext *c)
|
||||
c->buffer_ptr = c->pb_buffer;
|
||||
c->buffer_end = c->pb_buffer + len;
|
||||
|
||||
codec->frame_number++;
|
||||
if (len == 0) {
|
||||
av_packet_unref(&pkt);
|
||||
goto redo;
|
||||
@@ -2513,13 +2475,13 @@ static int http_prepare_data(HTTPContext *c)
|
||||
/* last packet test ? */
|
||||
if (c->last_packet_sent || c->is_packetized)
|
||||
return -1;
|
||||
ctx = c->pfmt_ctx;
|
||||
ctx = &c->fmt_ctx;
|
||||
/* prepare header */
|
||||
if (avio_open_dyn_buf(&ctx->pb) < 0) {
|
||||
/* XXX: potential leak */
|
||||
return -1;
|
||||
}
|
||||
c->pfmt_ctx->pb->seekable = 0;
|
||||
c->fmt_ctx.pb->seekable = 0;
|
||||
av_write_trailer(ctx);
|
||||
len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
|
||||
c->buffer_ptr = c->pb_buffer;
|
||||
@@ -2857,10 +2819,9 @@ static int http_receive_data(HTTPContext *c)
|
||||
}
|
||||
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
LayeredAVStream *fst = feed->streams[i];
|
||||
AVStream *fst = feed->streams[i];
|
||||
AVStream *st = s->streams[i];
|
||||
avcodec_parameters_to_context(fst->codec, st->codecpar);
|
||||
avcodec_parameters_from_context(fst->codecpar, fst->codec);
|
||||
avcodec_copy_context(fst->codec, st->codec);
|
||||
}
|
||||
|
||||
avformat_close_input(&s);
|
||||
@@ -3005,6 +2966,7 @@ static int prepare_sdp_description(FFServerStream *stream, uint8_t **pbuffer,
|
||||
struct in_addr my_ip)
|
||||
{
|
||||
AVFormatContext *avc;
|
||||
AVStream *avs = NULL;
|
||||
AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
|
||||
AVDictionaryEntry *entry = av_dict_get(stream->metadata, "title", NULL, 0);
|
||||
int i;
|
||||
@@ -3018,6 +2980,7 @@ static int prepare_sdp_description(FFServerStream *stream, uint8_t **pbuffer,
|
||||
avc->oformat = rtp_format;
|
||||
av_dict_set(&avc->metadata, "title",
|
||||
entry ? entry->value : "No Title", 0);
|
||||
avc->nb_streams = stream->nb_streams;
|
||||
if (stream->is_multicast) {
|
||||
snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
|
||||
inet_ntoa(stream->multicast_ip),
|
||||
@@ -3025,23 +2988,30 @@ static int prepare_sdp_description(FFServerStream *stream, uint8_t **pbuffer,
|
||||
} else
|
||||
snprintf(avc->filename, 1024, "rtp://0.0.0.0");
|
||||
|
||||
avc->streams = av_malloc_array(avc->nb_streams, sizeof(*avc->streams));
|
||||
if (!avc->streams)
|
||||
goto sdp_done;
|
||||
|
||||
avs = av_malloc_array(avc->nb_streams, sizeof(*avs));
|
||||
if (!avs)
|
||||
goto sdp_done;
|
||||
|
||||
for(i = 0; i < stream->nb_streams; i++) {
|
||||
AVStream *st = avformat_new_stream(avc, NULL);
|
||||
if (!st)
|
||||
goto sdp_done;
|
||||
avc->streams[i] = &avs[i];
|
||||
avc->streams[i]->codec = stream->streams[i]->codec;
|
||||
avcodec_parameters_from_context(stream->streams[i]->codecpar, stream->streams[i]->codec);
|
||||
unlayer_stream(st, stream->streams[i]);
|
||||
avc->streams[i]->codecpar = stream->streams[i]->codecpar;
|
||||
}
|
||||
#define PBUFFER_SIZE 2048
|
||||
*pbuffer = av_mallocz(PBUFFER_SIZE);
|
||||
*pbuffer = av_mallocz(2048);
|
||||
if (!*pbuffer)
|
||||
goto sdp_done;
|
||||
av_sdp_create(&avc, 1, *pbuffer, PBUFFER_SIZE);
|
||||
av_sdp_create(&avc, 1, *pbuffer, 2048);
|
||||
|
||||
sdp_done:
|
||||
av_freep(&avc->streams);
|
||||
av_dict_free(&avc->metadata);
|
||||
av_free(avc);
|
||||
av_free(avs);
|
||||
|
||||
return *pbuffer ? strlen(*pbuffer) : AVERROR(ENOMEM);
|
||||
}
|
||||
@@ -3465,16 +3435,19 @@ static int rtp_new_av_stream(HTTPContext *c,
|
||||
if (!st)
|
||||
goto fail;
|
||||
|
||||
av_freep(&st->codec);
|
||||
av_freep(&st->info);
|
||||
st_internal = st->internal;
|
||||
|
||||
if (!c->stream->feed ||
|
||||
c->stream->feed == c->stream)
|
||||
unlayer_stream(st, c->stream->streams[stream_index]);
|
||||
memcpy(st, c->stream->streams[stream_index], sizeof(AVStream));
|
||||
else
|
||||
unlayer_stream(st,
|
||||
c->stream->feed->streams[c->stream->feed_streams[stream_index]]);
|
||||
av_assert0(st->priv_data == NULL);
|
||||
av_assert0(st->internal == st_internal);
|
||||
memcpy(st,
|
||||
c->stream->feed->streams[c->stream->feed_streams[stream_index]],
|
||||
sizeof(AVStream));
|
||||
st->priv_data = NULL;
|
||||
st->internal = st_internal;
|
||||
|
||||
/* build destination RTP address */
|
||||
ipaddr = inet_ntoa(dest_addr->sin_addr);
|
||||
@@ -3542,15 +3515,15 @@ static int rtp_new_av_stream(HTTPContext *c,
|
||||
/* ffserver initialization */
|
||||
|
||||
/* FIXME: This code should use avformat_new_stream() */
|
||||
static LayeredAVStream *add_av_stream1(FFServerStream *stream,
|
||||
static AVStream *add_av_stream1(FFServerStream *stream,
|
||||
AVCodecContext *codec, int copy)
|
||||
{
|
||||
LayeredAVStream *fst;
|
||||
AVStream *fst;
|
||||
|
||||
if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
|
||||
return NULL;
|
||||
|
||||
fst = av_mallocz(sizeof(*fst));
|
||||
fst = av_mallocz(sizeof(AVStream));
|
||||
if (!fst)
|
||||
return NULL;
|
||||
if (copy) {
|
||||
@@ -3566,20 +3539,21 @@ static LayeredAVStream *add_av_stream1(FFServerStream *stream,
|
||||
*/
|
||||
fst->codec = codec;
|
||||
|
||||
//NOTE we previously allocated internal & internal->avctx, these seemed uneeded though
|
||||
fst->priv_data = av_mallocz(sizeof(FeedData));
|
||||
fst->internal = av_mallocz(sizeof(*fst->internal));
|
||||
fst->internal->avctx = avcodec_alloc_context3(NULL);
|
||||
fst->codecpar = avcodec_parameters_alloc();
|
||||
fst->index = stream->nb_streams;
|
||||
fst->time_base = codec->time_base;
|
||||
fst->pts_wrap_bits = 33;
|
||||
avpriv_set_pts_info(fst, 33, 1, 90000);
|
||||
fst->sample_aspect_ratio = codec->sample_aspect_ratio;
|
||||
stream->streams[stream->nb_streams++] = fst;
|
||||
return fst;
|
||||
}
|
||||
|
||||
/* return the stream number in the feed */
|
||||
static int add_av_stream(FFServerStream *feed, LayeredAVStream *st)
|
||||
static int add_av_stream(FFServerStream *feed, AVStream *st)
|
||||
{
|
||||
LayeredAVStream *fst;
|
||||
AVStream *fst;
|
||||
AVCodecContext *av, *av1;
|
||||
int i;
|
||||
|
||||
@@ -3613,9 +3587,9 @@ static int add_av_stream(FFServerStream *feed, LayeredAVStream *st)
|
||||
fst = add_av_stream1(feed, av, 0);
|
||||
if (!fst)
|
||||
return -1;
|
||||
if (st->recommended_encoder_configuration)
|
||||
fst->recommended_encoder_configuration =
|
||||
av_strdup(st->recommended_encoder_configuration);
|
||||
if (av_stream_get_recommended_encoder_configuration(st))
|
||||
av_stream_set_recommended_encoder_configuration(fst,
|
||||
av_strdup(av_stream_get_recommended_encoder_configuration(st)));
|
||||
return feed->nb_streams - 1;
|
||||
}
|
||||
|
||||
@@ -3631,6 +3605,57 @@ static void remove_stream(FFServerStream *stream)
|
||||
}
|
||||
}
|
||||
|
||||
/* specific MPEG4 handling : we extract the raw parameters */
|
||||
static void extract_mpeg4_header(AVFormatContext *infile)
|
||||
{
|
||||
int mpeg4_count, i, size;
|
||||
AVPacket pkt;
|
||||
AVStream *st;
|
||||
const uint8_t *p;
|
||||
|
||||
infile->flags |= AVFMT_FLAG_NOFILLIN | AVFMT_FLAG_NOPARSE;
|
||||
|
||||
mpeg4_count = 0;
|
||||
for(i=0;i<infile->nb_streams;i++) {
|
||||
st = infile->streams[i];
|
||||
if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
|
||||
st->codec->extradata_size == 0) {
|
||||
mpeg4_count++;
|
||||
}
|
||||
}
|
||||
if (!mpeg4_count)
|
||||
return;
|
||||
|
||||
printf("MPEG4 without extra data: trying to find header in %s\n",
|
||||
infile->filename);
|
||||
while (mpeg4_count > 0) {
|
||||
if (av_read_frame(infile, &pkt) < 0)
|
||||
break;
|
||||
st = infile->streams[pkt.stream_index];
|
||||
if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
|
||||
st->codec->extradata_size == 0) {
|
||||
av_freep(&st->codec->extradata);
|
||||
/* fill extradata with the header */
|
||||
/* XXX: we make hard suppositions here ! */
|
||||
p = pkt.data;
|
||||
while (p < pkt.data + pkt.size - 4) {
|
||||
/* stop when vop header is found */
|
||||
if (p[0] == 0x00 && p[1] == 0x00 &&
|
||||
p[2] == 0x01 && p[3] == 0xb6) {
|
||||
size = p - pkt.data;
|
||||
st->codec->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
st->codec->extradata_size = size;
|
||||
memcpy(st->codec->extradata, pkt.data, size);
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
mpeg4_count--;
|
||||
}
|
||||
av_packet_unref(&pkt);
|
||||
}
|
||||
}
|
||||
|
||||
/* compute the needed AVStream for each file */
|
||||
static void build_file_streams(void)
|
||||
{
|
||||
@@ -3681,6 +3706,7 @@ static void build_file_streams(void)
|
||||
avformat_close_input(&infile);
|
||||
goto fail;
|
||||
}
|
||||
extract_mpeg4_header(infile);
|
||||
|
||||
for(i=0;i<infile->nb_streams;i++)
|
||||
add_av_stream1(stream, infile->streams[i]->codec, 1);
|
||||
@@ -3691,25 +3717,26 @@ static void build_file_streams(void)
|
||||
}
|
||||
|
||||
static inline
|
||||
int check_codec_match(LayeredAVStream *ccf, AVStream *ccs, int stream)
|
||||
int check_codec_match(AVCodecContext *ccf, AVCodecContext *ccs, int stream)
|
||||
{
|
||||
int matches = 1;
|
||||
|
||||
/* FIXME: Missed check on AVCodecContext.flags */
|
||||
#define CHECK_CODEC(x) (ccf->codecpar->x != ccs->codecpar->x)
|
||||
#define CHECK_CODEC(x) (ccf->x != ccs->x)
|
||||
if (CHECK_CODEC(codec_id) || CHECK_CODEC(codec_type)) {
|
||||
http_log("Codecs do not match for stream %d\n", stream);
|
||||
matches = 0;
|
||||
} else if (CHECK_CODEC(bit_rate)) {
|
||||
} else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) {
|
||||
http_log("Codec bitrates do not match for stream %d\n", stream);
|
||||
matches = 0;
|
||||
} else if (ccf->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
if (av_cmp_q(ccf->time_base, ccs->time_base) ||
|
||||
CHECK_CODEC(width) || CHECK_CODEC(height)) {
|
||||
} else if (ccf->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
if (CHECK_CODEC(time_base.den) ||
|
||||
CHECK_CODEC(time_base.num) ||
|
||||
CHECK_CODEC(width) ||
|
||||
CHECK_CODEC(height)) {
|
||||
http_log("Codec width, height or framerate do not match for stream %d\n", stream);
|
||||
matches = 0;
|
||||
}
|
||||
} else if (ccf->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
} else if (ccf->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
if (CHECK_CODEC(sample_rate) ||
|
||||
CHECK_CODEC(channels) ||
|
||||
CHECK_CODEC(frame_size)) {
|
||||
@@ -3779,8 +3806,7 @@ static int build_feed_streams(void)
|
||||
|
||||
matches = 1;
|
||||
for(i=0;i<s->nb_streams;i++) {
|
||||
AVStream *ss;
|
||||
LayeredAVStream *sf;
|
||||
AVStream *sf, *ss;
|
||||
|
||||
sf = feed->streams[i];
|
||||
ss = s->streams[i];
|
||||
@@ -3792,7 +3818,7 @@ static int build_feed_streams(void)
|
||||
break;
|
||||
}
|
||||
|
||||
matches = check_codec_match (sf, ss, i);
|
||||
matches = check_codec_match (sf->codec, ss->codec, i);
|
||||
if (!matches)
|
||||
break;
|
||||
}
|
||||
@@ -3835,14 +3861,8 @@ drop:
|
||||
goto bail;
|
||||
}
|
||||
s->oformat = feed->fmt;
|
||||
for (i = 0; i<feed->nb_streams; i++) {
|
||||
AVStream *st = avformat_new_stream(s, NULL); // FIXME free this
|
||||
if (!st) {
|
||||
http_log("Failed to allocate stream\n");
|
||||
goto bail;
|
||||
}
|
||||
unlayer_stream(st, feed->streams[i]);
|
||||
}
|
||||
s->nb_streams = feed->nb_streams;
|
||||
s->streams = feed->streams;
|
||||
if (avformat_write_header(s, NULL) < 0) {
|
||||
http_log("Container doesn't support the required parameters\n");
|
||||
avio_closep(&s->pb);
|
||||
@@ -3892,7 +3912,7 @@ static void compute_bandwidth(void)
|
||||
for(stream = config.first_stream; stream; stream = stream->next) {
|
||||
bandwidth = 0;
|
||||
for(i=0;i<stream->nb_streams;i++) {
|
||||
LayeredAVStream *st = stream->streams[i];
|
||||
AVStream *st = stream->streams[i];
|
||||
switch(st->codec->codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/avassert.h"
|
||||
|
||||
// FIXME those are internal headers, ffserver _really_ shouldn't use them
|
||||
#include "libavformat/ffm.h"
|
||||
|
||||
#include "cmdutils.h"
|
||||
#include "ffserver_config.h"
|
||||
|
||||
@@ -150,11 +153,6 @@ void ffserver_parse_acl_row(FFServerStream *stream, FFServerStream* feed,
|
||||
}
|
||||
|
||||
nacl = av_mallocz(sizeof(*nacl));
|
||||
if (!nacl) {
|
||||
fprintf(stderr, "Failed to allocate FFServerIPAddressACL\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
naclp = 0;
|
||||
|
||||
acl.next = 0;
|
||||
@@ -187,7 +185,7 @@ bail:
|
||||
static void add_codec(FFServerStream *stream, AVCodecContext *av,
|
||||
FFServerConfig *config)
|
||||
{
|
||||
LayeredAVStream *st;
|
||||
AVStream *st;
|
||||
AVDictionary **opts, *recommended = NULL;
|
||||
char *enc_config;
|
||||
|
||||
@@ -318,12 +316,12 @@ static void add_codec(FFServerStream *stream, AVCodecContext *av,
|
||||
}
|
||||
|
||||
done:
|
||||
st = av_mallocz(sizeof(*st));
|
||||
st = av_mallocz(sizeof(AVStream));
|
||||
if (!st)
|
||||
return;
|
||||
av_dict_get_string(recommended, &enc_config, '=', ',');
|
||||
av_dict_free(&recommended);
|
||||
st->recommended_encoder_configuration = enc_config;
|
||||
av_stream_set_recommended_encoder_configuration(st, enc_config);
|
||||
st->codec = av;
|
||||
st->codecpar = avcodec_parameters_alloc();
|
||||
avcodec_parameters_from_context(st->codecpar, av);
|
||||
@@ -1053,7 +1051,6 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd,
|
||||
AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
|
||||
goto nomem;
|
||||
} else if (!av_strcasecmp(cmd, "BitExact")) {
|
||||
config->bitexact = 1;
|
||||
if (ffserver_save_avoption("flags", "+bitexact", AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
|
||||
goto nomem;
|
||||
} else if (!av_strcasecmp(cmd, "DctFastint")) {
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#ifndef FFSERVER_CONFIG_H
|
||||
#define FFSERVER_CONFIG_H
|
||||
|
||||
#define FFM_PACKET_SIZE 4096
|
||||
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavformat/network.h"
|
||||
@@ -49,24 +47,6 @@ typedef struct FFServerIPAddressACL {
|
||||
struct in_addr last;
|
||||
} FFServerIPAddressACL;
|
||||
|
||||
/**
|
||||
* This holds the stream parameters for an AVStream, it cannot be a AVStream
|
||||
* because AVStreams cannot be instanciated without a AVFormatContext, especially
|
||||
* not outside libavformat.
|
||||
*
|
||||
* The fields of this struct have the same semantics as the fields of an AVStream.
|
||||
*/
|
||||
typedef struct LayeredAVStream {
|
||||
int index;
|
||||
int id;
|
||||
AVCodecParameters *codecpar;
|
||||
AVCodecContext *codec;
|
||||
AVRational time_base;
|
||||
int pts_wrap_bits;
|
||||
AVRational sample_aspect_ratio;
|
||||
char *recommended_encoder_configuration;
|
||||
} LayeredAVStream;
|
||||
|
||||
/* description of each stream of the ffserver.conf file */
|
||||
typedef struct FFServerStream {
|
||||
enum FFServerStreamType stream_type;
|
||||
@@ -82,7 +62,7 @@ typedef struct FFServerStream {
|
||||
int prebuffer; /* Number of milliseconds early to start */
|
||||
int64_t max_time; /* Number of milliseconds to run */
|
||||
int send_on_key;
|
||||
LayeredAVStream *streams[FFSERVER_MAX_STREAMS];
|
||||
AVStream *streams[FFSERVER_MAX_STREAMS];
|
||||
int feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */
|
||||
char feed_filename[1024]; /* file name of the feed storage, or
|
||||
input file name for a stream */
|
||||
@@ -122,7 +102,6 @@ typedef struct FFServerConfig {
|
||||
unsigned int nb_max_connections;
|
||||
uint64_t max_bandwidth;
|
||||
int debug;
|
||||
int bitexact;
|
||||
char logfilename[1024];
|
||||
struct sockaddr_in http_addr;
|
||||
struct sockaddr_in rtsp_addr;
|
||||
|
||||
@@ -37,9 +37,7 @@ OBJS = allcodecs.o \
|
||||
jni.o \
|
||||
mathtables.o \
|
||||
mediacodec.o \
|
||||
mpeg12framerate.o \
|
||||
options.o \
|
||||
mjpegenc_huffman.o \
|
||||
parser.o \
|
||||
profiles.o \
|
||||
qsv_api.o \
|
||||
@@ -75,7 +73,6 @@ OBJS-$(CONFIG_GOLOMB) += golomb.o
|
||||
OBJS-$(CONFIG_H263DSP) += h263dsp.o
|
||||
OBJS-$(CONFIG_H264CHROMA) += h264chroma.o
|
||||
OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o
|
||||
OBJS-$(CONFIG_H264PARSE) += h264_parse.o h2645_parse.o h264_ps.o
|
||||
OBJS-$(CONFIG_H264PRED) += h264pred.o
|
||||
OBJS-$(CONFIG_H264QPEL) += h264qpel.o
|
||||
OBJS-$(CONFIG_HPELDSP) += hpeldsp.o
|
||||
@@ -84,7 +81,7 @@ OBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o
|
||||
OBJS-$(CONFIG_HUFFYUVENCDSP) += huffyuvencdsp.o
|
||||
OBJS-$(CONFIG_IDCTDSP) += idctdsp.o simple_idct.o jrevdct.o
|
||||
OBJS-$(CONFIG_IIRFILTER) += iirfilter.o
|
||||
OBJS-$(CONFIG_MDCT15) += mdct15.o
|
||||
OBJS-$(CONFIG_IMDCT15) += imdct15.o
|
||||
OBJS-$(CONFIG_INTRAX8) += intrax8.o intrax8dsp.o
|
||||
OBJS-$(CONFIG_IVIDSP) += ivi_dsp.o
|
||||
OBJS-$(CONFIG_JNI) += ffjni.o jni.o
|
||||
@@ -92,7 +89,6 @@ OBJS-$(CONFIG_JPEGTABLES) += jpegtables.o
|
||||
OBJS-$(CONFIG_LIBXVID) += libxvid_rc.o
|
||||
OBJS-$(CONFIG_LLAUDDSP) += lossless_audiodsp.o
|
||||
OBJS-$(CONFIG_LLVIDDSP) += lossless_videodsp.o
|
||||
OBJS-$(CONFIG_LLVIDENCDSP) += lossless_videoencdsp.o
|
||||
OBJS-$(CONFIG_LPC) += lpc.o
|
||||
OBJS-$(CONFIG_LSP) += lsp.o
|
||||
OBJS-$(CONFIG_LZF) += lzf.o
|
||||
@@ -177,7 +173,9 @@ OBJS-$(CONFIG_AMRWB_DECODER) += amrwbdec.o celp_filters.o \
|
||||
acelp_vectors.o \
|
||||
acelp_pitch_delay.o
|
||||
OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpegenc_common.o \
|
||||
mjpegenc_huffman.o
|
||||
mpegvideo_enc.o motion_est.o \
|
||||
ratecontrol.o mpeg12data.o \
|
||||
mpegvideo.o
|
||||
OBJS-$(CONFIG_ANM_DECODER) += anm.o
|
||||
OBJS-$(CONFIG_ANSI_DECODER) += ansi.o cga_data.o
|
||||
OBJS-$(CONFIG_APE_DECODER) += apedec.o
|
||||
@@ -193,11 +191,8 @@ OBJS-$(CONFIG_ASV2_DECODER) += asvdec.o asv.o mpeg12data.o
|
||||
OBJS-$(CONFIG_ASV2_ENCODER) += asvenc.o asv.o mpeg12data.o
|
||||
OBJS-$(CONFIG_ATRAC1_DECODER) += atrac1.o atrac.o
|
||||
OBJS-$(CONFIG_ATRAC3_DECODER) += atrac3.o atrac.o
|
||||
OBJS-$(CONFIG_ATRAC3AL_DECODER) += atrac3.o atrac.o
|
||||
OBJS-$(CONFIG_ATRAC3P_DECODER) += atrac3plusdec.o atrac3plus.o \
|
||||
atrac3plusdsp.o atrac.o
|
||||
OBJS-$(CONFIG_ATRAC3PAL_DECODER) += atrac3plusdec.o atrac3plus.o \
|
||||
atrac3plusdsp.o atrac.o
|
||||
OBJS-$(CONFIG_AURA_DECODER) += cyuv.o
|
||||
OBJS-$(CONFIG_AURA2_DECODER) += aura.o
|
||||
OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o mjpegdec.o
|
||||
@@ -221,14 +216,13 @@ OBJS-$(CONFIG_BMV_VIDEO_DECODER) += bmvvideo.o
|
||||
OBJS-$(CONFIG_BRENDER_PIX_DECODER) += brenderpix.o
|
||||
OBJS-$(CONFIG_C93_DECODER) += c93.o
|
||||
OBJS-$(CONFIG_CAVS_DECODER) += cavs.o cavsdec.o cavsdsp.o \
|
||||
cavsdata.o
|
||||
cavsdata.o mpeg12data.o
|
||||
OBJS-$(CONFIG_CCAPTION_DECODER) += ccaption_dec.o
|
||||
OBJS-$(CONFIG_CDGRAPHICS_DECODER) += cdgraphics.o
|
||||
OBJS-$(CONFIG_CDXL_DECODER) += cdxl.o
|
||||
OBJS-$(CONFIG_CFHD_DECODER) += cfhd.o cfhddata.o
|
||||
OBJS-$(CONFIG_CINEPAK_DECODER) += cinepak.o
|
||||
OBJS-$(CONFIG_CINEPAK_ENCODER) += cinepakenc.o elbg.o
|
||||
OBJS-$(CONFIG_CLEARVIDEO_DECODER) += clearvideo.o
|
||||
OBJS-$(CONFIG_CLJR_DECODER) += cljrdec.o
|
||||
OBJS-$(CONFIG_CLJR_ENCODER) += cljrenc.o
|
||||
OBJS-$(CONFIG_CLLC_DECODER) += cllc.o canopus.o
|
||||
@@ -241,10 +235,11 @@ OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o
|
||||
OBJS-$(CONFIG_DCA_DECODER) += dcadec.o dca.o dcadata.o dcahuff.o \
|
||||
dca_core.o dca_exss.o dca_xll.o dca_lbr.o \
|
||||
dcadsp.o dcadct.o synth_filter.o
|
||||
OBJS-$(CONFIG_DCA_ENCODER) += dcaenc.o dca.o dcadata.o dcahuff.o
|
||||
OBJS-$(CONFIG_DCA_ENCODER) += dcaenc.o dca.o dcadata.o
|
||||
OBJS-$(CONFIG_DDS_DECODER) += dds.o
|
||||
OBJS-$(CONFIG_DIRAC_DECODER) += diracdec.o dirac.o diracdsp.o diractab.o \
|
||||
dirac_arith.o dirac_dwt.o dirac_vlc.o
|
||||
dirac_arith.o mpeg12data.o dirac_dwt.o \
|
||||
dirac_vlc.o
|
||||
OBJS-$(CONFIG_DFA_DECODER) += dfa.o
|
||||
OBJS-$(CONFIG_DNXHD_DECODER) += dnxhddec.o dnxhddata.o
|
||||
OBJS-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.o dnxhddata.o
|
||||
@@ -294,7 +289,6 @@ OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o
|
||||
OBJS-$(CONFIG_FLASHSV2_ENCODER) += flashsv2enc.o
|
||||
OBJS-$(CONFIG_FLASHSV2_DECODER) += flashsv.o
|
||||
OBJS-$(CONFIG_FLIC_DECODER) += flicvideo.o
|
||||
OBJS-$(CONFIG_FMVC_DECODER) += fmvc.o
|
||||
OBJS-$(CONFIG_FOURXM_DECODER) += 4xm.o
|
||||
OBJS-$(CONFIG_FRAPS_DECODER) += fraps.o
|
||||
OBJS-$(CONFIG_FRWU_DECODER) += frwu.o
|
||||
@@ -317,9 +311,10 @@ OBJS-$(CONFIG_H263_ENCODER) += mpeg4videoenc.o mpeg4video.o \
|
||||
h263.o ituh263enc.o flvenc.o h263data.o
|
||||
OBJS-$(CONFIG_H264_DECODER) += h264dec.o h264_cabac.o h264_cavlc.o \
|
||||
h264_direct.o h264_loopfilter.o \
|
||||
h264_mb.o h264_picture.o \
|
||||
h264_mb.o h264_picture.o h264_ps.o \
|
||||
h264_refs.o h264_sei.o \
|
||||
h264_slice.o h264data.o
|
||||
h264_slice.o h264data.o h264_parse.o \
|
||||
h2645_parse.o
|
||||
OBJS-$(CONFIG_H264_CUVID_DECODER) += cuvid.o
|
||||
OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_H264_MMAL_DECODER) += mmaldec.o
|
||||
@@ -334,7 +329,7 @@ OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o vaapi_encode_h26x.
|
||||
OBJS-$(CONFIG_H264_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
|
||||
OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o
|
||||
OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o
|
||||
OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o hevc_ps.o hevc_sei.o \
|
||||
OBJS-$(CONFIG_HEVC_DECODER) += hevc.o hevc_mvs.o hevc_ps.o hevc_sei.o \
|
||||
hevc_cabac.o hevc_refs.o hevcpred.o \
|
||||
hevcdsp.o hevc_filter.o h2645_parse.o hevc_data.o
|
||||
OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuvid.o
|
||||
@@ -384,8 +379,7 @@ OBJS-$(CONFIG_METASOUND_DECODER) += metasound.o metasound_data.o \
|
||||
OBJS-$(CONFIG_MICRODVD_DECODER) += microdvddec.o ass.o
|
||||
OBJS-$(CONFIG_MIMIC_DECODER) += mimic.o
|
||||
OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o
|
||||
OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpegenc_common.o \
|
||||
mjpegenc_huffman.o
|
||||
OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpegenc_common.o
|
||||
OBJS-$(CONFIG_MJPEGB_DECODER) += mjpegbdec.o
|
||||
OBJS-$(CONFIG_MJPEG_VAAPI_ENCODER) += vaapi_encode_mjpeg.o
|
||||
OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o
|
||||
@@ -414,11 +408,10 @@ OBJS-$(CONFIG_MPEGVIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o
|
||||
OBJS-$(CONFIG_MPEG1VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o
|
||||
OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpeg12.o
|
||||
OBJS-$(CONFIG_MPEG2_MMAL_DECODER) += mmaldec.o
|
||||
OBJS-$(CONFIG_MPEG2_QSV_DECODER) += qsvdec_other.o
|
||||
OBJS-$(CONFIG_MPEG2_QSV_DECODER) += qsvdec_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2_QSV_ENCODER) += qsvenc_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12dec.o mpeg12.o mpeg12data.o
|
||||
OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12.o
|
||||
OBJS-$(CONFIG_MPEG2_VAAPI_ENCODER) += vaapi_encode_mpeg2.o
|
||||
OBJS-$(CONFIG_MPEG4_DECODER) += xvididct.o
|
||||
OBJS-$(CONFIG_MPEG4_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_MPEG4_OMX_ENCODER) += omx.o
|
||||
@@ -443,9 +436,8 @@ OBJS-$(CONFIG_NELLYMOSER_DECODER) += nellymoserdec.o nellymoser.o
|
||||
OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o
|
||||
OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o
|
||||
OBJS-$(CONFIG_ON2AVC_DECODER) += on2avc.o on2avcdata.o
|
||||
OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opus.o opus_celt.o opus_rc.o \
|
||||
opus_pvq.o opus_silk.o opustab.o vorbis_data.o
|
||||
OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opus_rc.o opustab.o opus_pvq.o
|
||||
OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opus.o opus_celt.o \
|
||||
opus_silk.o vorbis_data.o
|
||||
OBJS-$(CONFIG_PAF_AUDIO_DECODER) += pafaudio.o
|
||||
OBJS-$(CONFIG_PAF_VIDEO_DECODER) += pafvideo.o
|
||||
OBJS-$(CONFIG_PAM_DECODER) += pnmdec.o pnm.o
|
||||
@@ -460,7 +452,6 @@ OBJS-$(CONFIG_PGMYUV_DECODER) += pnmdec.o pnm.o
|
||||
OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o
|
||||
OBJS-$(CONFIG_PGSSUB_DECODER) += pgssubdec.o
|
||||
OBJS-$(CONFIG_PICTOR_DECODER) += pictordec.o cga_data.o
|
||||
OBJS-$(CONFIG_PIXLET_DECODER) += pixlet.o
|
||||
OBJS-$(CONFIG_PJS_DECODER) += textdec.o ass.o
|
||||
OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o pngdsp.o
|
||||
OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o
|
||||
@@ -471,13 +462,11 @@ OBJS-$(CONFIG_PRORES_LGPL_DECODER) += proresdec_lgpl.o proresdsp.o proresdat
|
||||
OBJS-$(CONFIG_PRORES_ENCODER) += proresenc_anatoliy.o
|
||||
OBJS-$(CONFIG_PRORES_AW_ENCODER) += proresenc_anatoliy.o
|
||||
OBJS-$(CONFIG_PRORES_KS_ENCODER) += proresenc_kostya.o proresdata.o
|
||||
OBJS-$(CONFIG_PSD_DECODER) += psd.o
|
||||
OBJS-$(CONFIG_PTX_DECODER) += ptx.o
|
||||
OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o \
|
||||
celp_filters.o acelp_vectors.o \
|
||||
acelp_filters.o
|
||||
OBJS-$(CONFIG_QDM2_DECODER) += qdm2.o
|
||||
OBJS-$(CONFIG_QDMC_DECODER) += qdmc.o
|
||||
OBJS-$(CONFIG_QDRAW_DECODER) += qdrw.o
|
||||
OBJS-$(CONFIG_QPEG_DECODER) += qpeg.o
|
||||
OBJS-$(CONFIG_QTRLE_DECODER) += qtrle.o
|
||||
@@ -510,7 +499,6 @@ OBJS-$(CONFIG_SAMI_DECODER) += samidec.o ass.o htmlsubtitles.o
|
||||
OBJS-$(CONFIG_S302M_DECODER) += s302m.o
|
||||
OBJS-$(CONFIG_S302M_ENCODER) += s302menc.o
|
||||
OBJS-$(CONFIG_SANM_DECODER) += sanm.o
|
||||
OBJS-$(CONFIG_SCPR_DECODER) += scpr.o
|
||||
OBJS-$(CONFIG_SCREENPRESSO_DECODER) += screenpresso.o
|
||||
OBJS-$(CONFIG_SDX2_DPCM_DECODER) += dpcm.o
|
||||
OBJS-$(CONFIG_SGI_DECODER) += sgidec.o
|
||||
@@ -533,7 +521,6 @@ OBJS-$(CONFIG_SOL_DPCM_DECODER) += dpcm.o
|
||||
OBJS-$(CONFIG_SONIC_DECODER) += sonic.o
|
||||
OBJS-$(CONFIG_SONIC_ENCODER) += sonic.o
|
||||
OBJS-$(CONFIG_SONIC_LS_ENCODER) += sonic.o
|
||||
OBJS-$(CONFIG_SPEEDHQ_DECODER) += speedhq.o simple_idct.o
|
||||
OBJS-$(CONFIG_SP5X_DECODER) += sp5xdec.o
|
||||
OBJS-$(CONFIG_SRT_DECODER) += srtdec.o ass.o htmlsubtitles.o
|
||||
OBJS-$(CONFIG_SRT_ENCODER) += srtenc.o ass_split.o
|
||||
@@ -547,7 +534,8 @@ OBJS-$(CONFIG_SUNRAST_ENCODER) += sunrastenc.o
|
||||
OBJS-$(CONFIG_SVQ1_DECODER) += svq1dec.o svq1.o svq13.o h263data.o
|
||||
OBJS-$(CONFIG_SVQ1_ENCODER) += svq1enc.o svq1.o h263data.o \
|
||||
h263.o ituh263enc.o
|
||||
OBJS-$(CONFIG_SVQ3_DECODER) += svq3.o svq13.o mpegutils.o h264data.o
|
||||
OBJS-$(CONFIG_SVQ3_DECODER) += svq3.o svq13.o mpegutils.o \
|
||||
h264_parse.o h264data.o h264_ps.o h2645_parse.o
|
||||
OBJS-$(CONFIG_TEXT_DECODER) += textdec.o ass.o
|
||||
OBJS-$(CONFIG_TEXT_ENCODER) += srtenc.o ass_split.o
|
||||
OBJS-$(CONFIG_TAK_DECODER) += takdec.o tak.o takdsp.o
|
||||
@@ -591,7 +579,7 @@ OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1_block.o vc1_loopfilter.o
|
||||
wmv2dsp.o wmv2data.o
|
||||
OBJS-$(CONFIG_VC1_CUVID_DECODER) += cuvid.o
|
||||
OBJS-$(CONFIG_VC1_MMAL_DECODER) += mmaldec.o
|
||||
OBJS-$(CONFIG_VC1_QSV_DECODER) += qsvdec_other.o
|
||||
OBJS-$(CONFIG_VC1_QSV_DECODER) += qsvdec_vc1.o
|
||||
OBJS-$(CONFIG_VC2_ENCODER) += vc2enc.o vc2enc_dwt.o diractab.o
|
||||
OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o
|
||||
OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdaudio.o
|
||||
@@ -609,11 +597,8 @@ OBJS-$(CONFIG_VP7_DECODER) += vp8.o vp56rac.o
|
||||
OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp56rac.o
|
||||
OBJS-$(CONFIG_VP8_CUVID_DECODER) += cuvid.o
|
||||
OBJS-$(CONFIG_VP8_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_VP8_QSV_DECODER) += qsvdec_other.o
|
||||
OBJS-$(CONFIG_VP8_VAAPI_ENCODER) += vaapi_encode_vp8.o
|
||||
OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o vp9lpf.o vp9recon.o \
|
||||
vp9block.o vp9prob.o vp9mvs.o vp56rac.o \
|
||||
vp9dsp_8bpp.o vp9dsp_10bpp.o vp9dsp_12bpp.o
|
||||
OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9dsp.o vp56rac.o vp9dsp_8bpp.o \
|
||||
vp9dsp_10bpp.o vp9dsp_12bpp.o
|
||||
OBJS-$(CONFIG_VP9_CUVID_DECODER) += cuvid.o
|
||||
OBJS-$(CONFIG_VP9_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o
|
||||
@@ -652,7 +637,6 @@ OBJS-$(CONFIG_XFACE_ENCODER) += xfaceenc.o xface.o
|
||||
OBJS-$(CONFIG_XL_DECODER) += xl.o
|
||||
OBJS-$(CONFIG_XMA1_DECODER) += wmaprodec.o wma.o wma_common.o
|
||||
OBJS-$(CONFIG_XMA2_DECODER) += wmaprodec.o wma.o wma_common.o
|
||||
OBJS-$(CONFIG_XPM_DECODER) += xpmdec.o
|
||||
OBJS-$(CONFIG_XSUB_DECODER) += xsubdec.o
|
||||
OBJS-$(CONFIG_XSUB_ENCODER) += xsubenc.o
|
||||
OBJS-$(CONFIG_XWD_DECODER) += xwddec.o
|
||||
@@ -674,8 +658,6 @@ OBJS-$(CONFIG_PCM_ALAW_DECODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_ALAW_ENCODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_BLURAY_DECODER) += pcm-bluray.o
|
||||
OBJS-$(CONFIG_PCM_DVD_DECODER) += pcm-dvd.o
|
||||
OBJS-$(CONFIG_PCM_F16LE_DECODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_F24LE_DECODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_F32BE_DECODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_F32BE_ENCODER) += pcm.o
|
||||
OBJS-$(CONFIG_PCM_F32LE_DECODER) += pcm.o
|
||||
@@ -786,7 +768,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o
|
||||
# hardware accelerators
|
||||
OBJS-$(CONFIG_D3D11VA) += dxva2.o
|
||||
OBJS-$(CONFIG_DXVA2) += dxva2.o
|
||||
OBJS-$(CONFIG_VAAPI) += vaapi_decode.o
|
||||
OBJS-$(CONFIG_VAAPI) += vaapi.o
|
||||
OBJS-$(CONFIG_VDA) += vda.o videotoolbox.o
|
||||
OBJS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.o
|
||||
OBJS-$(CONFIG_VDPAU) += vdpau.o
|
||||
@@ -829,20 +811,34 @@ OBJS-$(CONFIG_ISO_MEDIA) += mpeg4audio.o mpegaudiodata.o
|
||||
OBJS-$(CONFIG_ADTS_MUXER) += mpeg4audio.o
|
||||
OBJS-$(CONFIG_CAF_DEMUXER) += ac3tab.o
|
||||
OBJS-$(CONFIG_DNXHD_DEMUXER) += dnxhddata.o
|
||||
OBJS-$(CONFIG_FLAC_DEMUXER) += flac.o flacdata.o vorbis_data.o
|
||||
OBJS-$(CONFIG_FLAC_MUXER) += flac.o flacdata.o vorbis_data.o
|
||||
OBJS-$(CONFIG_FLV_DEMUXER) += mpeg4audio.o
|
||||
OBJS-$(CONFIG_GXF_DEMUXER) += mpeg12data.o
|
||||
OBJS-$(CONFIG_IFF_DEMUXER) += iff.o
|
||||
OBJS-$(CONFIG_LATM_MUXER) += mpeg4audio.o
|
||||
OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += mpeg4audio.o
|
||||
OBJS-$(CONFIG_MATROSKA_MUXER) += mpeg4audio.o
|
||||
OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += mpeg4audio.o vorbis_data.o \
|
||||
flac.o flacdata.o
|
||||
OBJS-$(CONFIG_MATROSKA_MUXER) += flac.o flacdata.o vorbis_data.o
|
||||
OBJS-$(CONFIG_MOV_DEMUXER) += ac3tab.o
|
||||
OBJS-$(CONFIG_MP2_MUXER) += mpegaudiodata.o mpegaudiodecheader.o
|
||||
OBJS-$(CONFIG_MP3_MUXER) += mpegaudiodata.o mpegaudiodecheader.o
|
||||
OBJS-$(CONFIG_MPEGTS_MUXER) += mpeg4audio.o
|
||||
OBJS-$(CONFIG_MXF_MUXER) += dnxhddata.o
|
||||
OBJS-$(CONFIG_NUT_MUXER) += mpegaudiodata.o
|
||||
OBJS-$(CONFIG_NUT_DEMUXER) += mpegaudiodata.o mpeg4audio.o
|
||||
OBJS-$(CONFIG_OGA_MUXER) += flac.o flacdata.o
|
||||
OBJS-$(CONFIG_OGG_DEMUXER) += mpeg12data.o \
|
||||
dirac.o vorbis_data.o
|
||||
OBJS-$(CONFIG_OGG_MUXER) += flac.o flacdata.o \
|
||||
vorbis_data.o
|
||||
OBJS-$(CONFIG_RTP_MUXER) += mpeg4audio.o
|
||||
OBJS-$(CONFIG_SPDIF_DEMUXER) += aacadtsdec.o mpeg4audio.o
|
||||
OBJS-$(CONFIG_SPDIF_MUXER) += dca.o
|
||||
OBJS-$(CONFIG_TAK_DEMUXER) += tak.o
|
||||
OBJS-$(CONFIG_WEBM_MUXER) += mpeg4audio.o
|
||||
OBJS-$(CONFIG_WEBM_MUXER) += mpeg4audio.o mpegaudiodata.o \
|
||||
flac.o flacdata.o \
|
||||
vorbis_data.o
|
||||
|
||||
# libavfilter dependencies
|
||||
OBJS-$(CONFIG_ELBG_FILTER) += elbg.o
|
||||
@@ -941,7 +937,8 @@ OBJS-$(CONFIG_G729_PARSER) += g729_parser.o
|
||||
OBJS-$(CONFIG_GSM_PARSER) += gsm_parser.o
|
||||
OBJS-$(CONFIG_H261_PARSER) += h261_parser.o
|
||||
OBJS-$(CONFIG_H263_PARSER) += h263_parser.o
|
||||
OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264_sei.o h264data.o
|
||||
OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264_parse.o h2645_parse.o \
|
||||
h264_ps.o h264_sei.o h264data.o
|
||||
OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o h2645_parse.o hevc_ps.o hevc_data.o
|
||||
OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o
|
||||
OBJS-$(CONFIG_MLP_PARSER) += mlp_parser.o mlp.o
|
||||
@@ -958,14 +955,12 @@ OBJS-$(CONFIG_PNG_PARSER) += png_parser.o
|
||||
OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o
|
||||
OBJS-$(CONFIG_RV30_PARSER) += rv34_parser.o
|
||||
OBJS-$(CONFIG_RV40_PARSER) += rv34_parser.o
|
||||
OBJS-$(CONFIG_SIPR_PARSER) += sipr_parser.o
|
||||
OBJS-$(CONFIG_TAK_PARSER) += tak_parser.o tak.o
|
||||
OBJS-$(CONFIG_VC1_PARSER) += vc1_parser.o vc1.o vc1data.o \
|
||||
simple_idct.o wmv2data.o
|
||||
OBJS-$(CONFIG_VP3_PARSER) += vp3_parser.o
|
||||
OBJS-$(CONFIG_VP8_PARSER) += vp8_parser.o
|
||||
OBJS-$(CONFIG_VP9_PARSER) += vp9_parser.o
|
||||
OBJS-$(CONFIG_XMA_PARSER) += xma_parser.o
|
||||
|
||||
# bitstream filters
|
||||
OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o aacadtsdec.o \
|
||||
@@ -973,7 +968,6 @@ OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o aacadtsdec.o \
|
||||
OBJS-$(CONFIG_CHOMP_BSF) += chomp_bsf.o
|
||||
OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o
|
||||
OBJS-$(CONFIG_DCA_CORE_BSF) += dca_core_bsf.o
|
||||
OBJS-$(CONFIG_EXTRACT_EXTRADATA_BSF) += extract_extradata_bsf.o
|
||||
OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o
|
||||
OBJS-$(CONFIG_HEVC_MP4TOANNEXB_BSF) += hevc_mp4toannexb_bsf.o
|
||||
OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o
|
||||
@@ -1020,18 +1014,15 @@ SKIPHEADERS-$(CONFIG_QSV) += qsv.h qsv_internal.h
|
||||
SKIPHEADERS-$(CONFIG_QSVDEC) += qsvdec.h
|
||||
SKIPHEADERS-$(CONFIG_QSVENC) += qsvenc.h
|
||||
SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h
|
||||
SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_decode.h vaapi_encode.h
|
||||
SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_encode.h vaapi_internal.h
|
||||
SKIPHEADERS-$(CONFIG_VDA) += vda.h vda_vt_internal.h
|
||||
SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h
|
||||
SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.h vda_vt_internal.h
|
||||
|
||||
TESTPROGS = avpacket \
|
||||
celp_math \
|
||||
imgconvert \
|
||||
TESTPROGS = imgconvert \
|
||||
jpeg2000dwt \
|
||||
mathops \
|
||||
options \
|
||||
mjpegenc_huffman \
|
||||
utils \
|
||||
|
||||
TESTPROGS-$(CONFIG_CABAC) += cabac
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "libavutil/fixed_dsp.h"
|
||||
#include "avcodec.h"
|
||||
#if !USE_FIXED
|
||||
#include "mdct15.h"
|
||||
#include "imdct15.h"
|
||||
#endif
|
||||
#include "fft.h"
|
||||
#include "mpeg4audio.h"
|
||||
@@ -327,7 +327,7 @@ struct AACContext {
|
||||
#if USE_FIXED
|
||||
AVFixedDSPContext *fdsp;
|
||||
#else
|
||||
MDCT15Context *mdct480;
|
||||
IMDCT15Context *mdct480;
|
||||
AVFloatDSPContext *fdsp;
|
||||
#endif /* USE_FIXED */
|
||||
int random_state;
|
||||
|
||||
@@ -49,14 +49,14 @@ static int aac_adtstoasc_filter(AVBSFContext *bsfc, AVPacket *out)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (bsfc->par_in->extradata && in->size >= 2 && (AV_RB16(in->data) >> 4) != 0xfff)
|
||||
goto finish;
|
||||
|
||||
if (in->size < AAC_ADTS_HEADER_SIZE)
|
||||
goto packet_too_small;
|
||||
|
||||
init_get_bits(&gb, in->data, AAC_ADTS_HEADER_SIZE * 8);
|
||||
|
||||
if (bsfc->par_in->extradata && show_bits(&gb, 12) != 0xfff)
|
||||
goto finish;
|
||||
|
||||
if (avpriv_aac_parse_header(&gb, &hdr) < 0) {
|
||||
av_log(bsfc, AV_LOG_ERROR, "Error parsing ADTS frame header!\n");
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#define AAC_RENAME(x) x ## _fixed
|
||||
#define AAC_RENAME_32(x) x ## _fixed_32
|
||||
typedef int INTFLOAT;
|
||||
typedef unsigned UINTFLOAT; ///< Equivalent to INTFLOAT, Used as temporal cast to avoid undefined sign overflow operations.
|
||||
typedef int64_t INT64FLOAT;
|
||||
typedef int16_t SHORTFLOAT;
|
||||
typedef SoftFloat AAC_FLOAT;
|
||||
@@ -45,7 +46,7 @@ typedef int AAC_SIGNE;
|
||||
#define Q30(x) (int)((x)*1073741824.0 + 0.5)
|
||||
#define Q31(x) (int)((x)*2147483648.0 + 0.5)
|
||||
#define RANGE15(x) x
|
||||
#define GET_GAIN(x, y) (-(y) << (x)) + 1024
|
||||
#define GET_GAIN(x, y) (-(y) * (1 << (x))) + 1024
|
||||
#define AAC_MUL16(x, y) (int)(((int64_t)(x) * (y) + 0x8000) >> 16)
|
||||
#define AAC_MUL26(x, y) (int)(((int64_t)(x) * (y) + 0x2000000) >> 26)
|
||||
#define AAC_MUL30(x, y) (int)(((int64_t)(x) * (y) + 0x20000000) >> 30)
|
||||
@@ -72,7 +73,7 @@ typedef int AAC_SIGNE;
|
||||
#define AAC_MSUB31_V3(x, y, z) (int)((((int64_t)(x) * (z)) - \
|
||||
((int64_t)(y) * (z)) + \
|
||||
0x40000000) >> 31)
|
||||
#define AAC_HALF_SUM(x, y) (x) >> 1 + (y) >> 1
|
||||
#define AAC_HALF_SUM(x, y) (((x) >> 1) + ((y) >> 1))
|
||||
#define AAC_SRA_R(x, y) (int)(((x) + (1 << ((y) - 1))) >> (y))
|
||||
|
||||
#else
|
||||
@@ -83,6 +84,7 @@ typedef int AAC_SIGNE;
|
||||
#define AAC_RENAME(x) x
|
||||
#define AAC_RENAME_32(x) x
|
||||
typedef float INTFLOAT;
|
||||
typedef float UINTFLOAT;
|
||||
typedef float INT64FLOAT;
|
||||
typedef float SHORTFLOAT;
|
||||
typedef float AAC_FLOAT;
|
||||
|
||||
@@ -557,13 +557,13 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne
|
||||
const float pns_transient_energy_r = FFMIN(0.7f, lambda / 140.f);
|
||||
|
||||
int refbits = avctx->bit_rate * 1024.0 / avctx->sample_rate
|
||||
/ ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels)
|
||||
/ ((avctx->flags & CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels)
|
||||
* (lambda / 120.f);
|
||||
|
||||
/** Keep this in sync with twoloop's cutoff selection */
|
||||
float rate_bandwidth_multiplier = 1.5f;
|
||||
int prev = -1000, prev_sf = -1;
|
||||
int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE)
|
||||
int frame_bit_rate = (avctx->flags & CODEC_FLAG_QSCALE)
|
||||
? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024)
|
||||
: (avctx->bit_rate / avctx->channels);
|
||||
|
||||
@@ -694,12 +694,12 @@ static void mark_pns(AACEncContext *s, AVCodecContext *avctx, SingleChannelEleme
|
||||
const float pns_transient_energy_r = FFMIN(0.7f, lambda / 140.f);
|
||||
|
||||
int refbits = avctx->bit_rate * 1024.0 / avctx->sample_rate
|
||||
/ ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels)
|
||||
/ ((avctx->flags & CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels)
|
||||
* (lambda / 120.f);
|
||||
|
||||
/** Keep this in sync with twoloop's cutoff selection */
|
||||
float rate_bandwidth_multiplier = 1.5f;
|
||||
int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE)
|
||||
int frame_bit_rate = (avctx->flags & CODEC_FLAG_QSCALE)
|
||||
? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024)
|
||||
: (avctx->bit_rate / avctx->channels);
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
{
|
||||
int start = 0, i, w, w2, g, recomprd;
|
||||
int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate
|
||||
/ ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels)
|
||||
/ ((avctx->flags & CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels)
|
||||
* (lambda / 120.f);
|
||||
int refbits = destbits;
|
||||
int toomanybits, toofewbits;
|
||||
@@ -136,7 +136,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
* (lambda / (avctx->global_quality ? avctx->global_quality : 120));
|
||||
}
|
||||
|
||||
if (avctx->flags & AV_CODEC_FLAG_QSCALE) {
|
||||
if (avctx->flags & CODEC_FLAG_QSCALE) {
|
||||
/**
|
||||
* Constant Q-scale doesn't compensate MS coding on its own
|
||||
* No need to be overly precise, this only controls RD
|
||||
@@ -184,7 +184,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
* AAC_CUTOFF_FROM_BITRATE is calibrated for effective bitrate.
|
||||
*/
|
||||
float rate_bandwidth_multiplier = 1.5f;
|
||||
int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE)
|
||||
int frame_bit_rate = (avctx->flags & CODEC_FLAG_QSCALE)
|
||||
? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024)
|
||||
: (avctx->bit_rate / avctx->channels);
|
||||
|
||||
@@ -332,7 +332,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
sce->coeffs + start,
|
||||
nzslope * cleanup_factor);
|
||||
energy2uplim *= de_psy_factor;
|
||||
if (!(avctx->flags & AV_CODEC_FLAG_QSCALE)) {
|
||||
if (!(avctx->flags & CODEC_FLAG_QSCALE)) {
|
||||
/** In ABR, we need to priorize less and let rate control do its thing */
|
||||
energy2uplim = sqrtf(energy2uplim);
|
||||
}
|
||||
@@ -346,7 +346,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
sce->coeffs + start,
|
||||
2.0f);
|
||||
energy2uplim *= de_psy_factor;
|
||||
if (!(avctx->flags & AV_CODEC_FLAG_QSCALE)) {
|
||||
if (!(avctx->flags & CODEC_FLAG_QSCALE)) {
|
||||
/** In ABR, we need to priorize less and let rate control do its thing */
|
||||
energy2uplim = sqrtf(energy2uplim);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#include "internal.h"
|
||||
#include "get_bits.h"
|
||||
#include "fft.h"
|
||||
#include "mdct15.h"
|
||||
#include "imdct15.h"
|
||||
#include "lpc.h"
|
||||
#include "kbdwin.h"
|
||||
#include "sinewin.h"
|
||||
@@ -284,35 +284,29 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
|
||||
AACContext *ac = &latmctx->aac_ctx;
|
||||
AVCodecContext *avctx = ac->avctx;
|
||||
MPEG4AudioConfig m4ac = { 0 };
|
||||
GetBitContext gbc;
|
||||
int config_start_bit = get_bits_count(gb);
|
||||
int sync_extension = 0;
|
||||
int bits_consumed, esize, i;
|
||||
int bits_consumed, esize;
|
||||
|
||||
if (asclen > 0) {
|
||||
if (asclen) {
|
||||
sync_extension = 1;
|
||||
asclen = FFMIN(asclen, get_bits_left(gb));
|
||||
init_get_bits(&gbc, gb->buffer, config_start_bit + asclen);
|
||||
skip_bits_long(&gbc, config_start_bit);
|
||||
} else if (asclen == 0) {
|
||||
gbc = *gb;
|
||||
} else {
|
||||
return AVERROR_INVALIDDATA;
|
||||
} else
|
||||
asclen = get_bits_left(gb);
|
||||
|
||||
if (config_start_bit % 8) {
|
||||
avpriv_request_sample(latmctx->aac_ctx.avctx,
|
||||
"Non-byte-aligned audio-specific config");
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
|
||||
if (get_bits_left(gb) <= 0)
|
||||
if (asclen <= 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
bits_consumed = decode_audio_specific_config(NULL, avctx, &m4ac,
|
||||
gb->buffer + (config_start_bit / 8),
|
||||
asclen, sync_extension);
|
||||
|
||||
bits_consumed = decode_audio_specific_config_gb(NULL, avctx, &m4ac,
|
||||
&gbc, config_start_bit,
|
||||
sync_extension);
|
||||
|
||||
if (bits_consumed < config_start_bit)
|
||||
if (bits_consumed < 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
bits_consumed -= config_start_bit;
|
||||
|
||||
if (asclen == 0)
|
||||
asclen = bits_consumed;
|
||||
|
||||
if (!latmctx->initialized ||
|
||||
ac->oc[1].m4ac.sample_rate != m4ac.sample_rate ||
|
||||
@@ -325,7 +319,7 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
|
||||
}
|
||||
latmctx->initialized = 0;
|
||||
|
||||
esize = (asclen + 7) / 8;
|
||||
esize = (bits_consumed+7) / 8;
|
||||
|
||||
if (avctx->extradata_size < esize) {
|
||||
av_free(avctx->extradata);
|
||||
@@ -335,15 +329,12 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
|
||||
}
|
||||
|
||||
avctx->extradata_size = esize;
|
||||
gbc = *gb;
|
||||
for (i = 0; i < esize; i++) {
|
||||
avctx->extradata[i] = get_bits(&gbc, 8);
|
||||
}
|
||||
memcpy(avctx->extradata, gb->buffer + (config_start_bit/8), esize);
|
||||
memset(avctx->extradata+esize, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
}
|
||||
skip_bits_long(gb, asclen);
|
||||
skip_bits_long(gb, bits_consumed);
|
||||
|
||||
return 0;
|
||||
return bits_consumed;
|
||||
}
|
||||
|
||||
static int read_stream_mux_config(struct LATMContext *latmctx,
|
||||
@@ -384,6 +375,8 @@ static int read_stream_mux_config(struct LATMContext *latmctx,
|
||||
int ascLen = latm_get_value(gb);
|
||||
if ((ret = latm_decode_audio_specific_config(latmctx, gb, ascLen)) < 0)
|
||||
return ret;
|
||||
ascLen -= ret;
|
||||
skip_bits_long(gb, ascLen);
|
||||
}
|
||||
|
||||
latmctx->frame_length_type = get_bits(gb, 3);
|
||||
@@ -431,6 +424,8 @@ static int read_payload_length_info(struct LATMContext *ctx, GetBitContext *gb)
|
||||
if (ctx->frame_length_type == 0) {
|
||||
int mux_slot_length = 0;
|
||||
do {
|
||||
if (get_bits_left(gb) < 8)
|
||||
return AVERROR_INVALIDDATA;
|
||||
tmp = get_bits(gb, 8);
|
||||
mux_slot_length += tmp;
|
||||
} while (tmp == 255);
|
||||
@@ -460,7 +455,7 @@ static int read_audio_mux_element(struct LATMContext *latmctx,
|
||||
}
|
||||
if (latmctx->audio_mux_version_A == 0) {
|
||||
int mux_slot_length_bytes = read_payload_length_info(latmctx, gb);
|
||||
if (mux_slot_length_bytes * 8 > get_bits_left(gb)) {
|
||||
if (mux_slot_length_bytes < 0 || mux_slot_length_bytes * 8LL > get_bits_left(gb)) {
|
||||
av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, "incomplete frame\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
} else if (mux_slot_length_bytes * 8 + 256 < get_bits_left(gb)) {
|
||||
|
||||
@@ -125,7 +125,7 @@ static inline int *DEC_SQUAD(int *dst, unsigned idx)
|
||||
static inline int *DEC_UPAIR(int *dst, unsigned idx, unsigned sign)
|
||||
{
|
||||
dst[0] = (idx & 15) * (1 - (sign & 0xFFFFFFFE));
|
||||
dst[1] = (idx >> 4 & 15) * (1 - ((sign & 1) << 1));
|
||||
dst[1] = (idx >> 4 & 15) * (1 - ((sign & 1) * 2));
|
||||
|
||||
return dst + 2;
|
||||
}
|
||||
@@ -134,16 +134,16 @@ static inline int *DEC_UQUAD(int *dst, unsigned idx, unsigned sign)
|
||||
{
|
||||
unsigned nz = idx >> 12;
|
||||
|
||||
dst[0] = (idx & 3) * (1 + (((int)sign >> 31) << 1));
|
||||
dst[0] = (idx & 3) * (1 + (((int)sign >> 31) * 2));
|
||||
sign <<= nz & 1;
|
||||
nz >>= 1;
|
||||
dst[1] = (idx >> 2 & 3) * (1 + (((int)sign >> 31) << 1));
|
||||
dst[1] = (idx >> 2 & 3) * (1 + (((int)sign >> 31) * 2));
|
||||
sign <<= nz & 1;
|
||||
nz >>= 1;
|
||||
dst[2] = (idx >> 4 & 3) * (1 + (((int)sign >> 31) << 1));
|
||||
dst[2] = (idx >> 4 & 3) * (1 + (((int)sign >> 31) * 2));
|
||||
sign <<= nz & 1;
|
||||
nz >>= 1;
|
||||
dst[3] = (idx >> 6 & 3) * (1 + (((int)sign >> 31) << 1));
|
||||
dst[3] = (idx >> 6 & 3) * (1 + (((int)sign >> 31) * 2));
|
||||
|
||||
return dst + 4;
|
||||
}
|
||||
@@ -171,20 +171,25 @@ static void subband_scale(int *dst, int *src, int scale, int offset, int len)
|
||||
|
||||
s = offset - (s >> 2);
|
||||
|
||||
if (s > 0) {
|
||||
if (s > 31) {
|
||||
for (i=0; i<len; i++) {
|
||||
dst[i] = 0;
|
||||
}
|
||||
} else if (s > 0) {
|
||||
round = 1 << (s-1);
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)(((int64_t)src[i] * c) >> 32);
|
||||
dst[i] = ((int)(out+round) >> s) * ssign;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else if (s > -32) {
|
||||
s = s + 32;
|
||||
round = 1 << (s-1);
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)((int64_t)((int64_t)src[i] * c + round) >> s);
|
||||
dst[i] = out * ssign;
|
||||
dst[i] = out * (unsigned)ssign;
|
||||
}
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_ERROR, "Overflow in subband_scale()\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,8 +208,12 @@ static void noise_scale(int *coefs, int scale, int band_energy, int len)
|
||||
c /= band_energy;
|
||||
s = 21 + nlz - (s >> 2);
|
||||
|
||||
if (s > 0) {
|
||||
round = 1 << (s-1);
|
||||
if (s > 31) {
|
||||
for (i=0; i<len; i++) {
|
||||
coefs[i] = 0;
|
||||
}
|
||||
} else if (s >= 0) {
|
||||
round = s ? 1 << (s-1) : 0;
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)(((int64_t)coefs[i] * c) >> 32);
|
||||
coefs[i] = ((int)(out+round) >> s) * ssign;
|
||||
@@ -296,8 +305,12 @@ static av_always_inline void predict(PredictorState *ps, int *coef,
|
||||
if (output_enable) {
|
||||
int shift = 28 - pv.exp;
|
||||
|
||||
if (shift < 31)
|
||||
*coef += (pv.mant + (1 << (shift - 1))) >> shift;
|
||||
if (shift < 31) {
|
||||
if (shift > 0) {
|
||||
*coef += (pv.mant + (1 << (shift - 1))) >> shift;
|
||||
} else
|
||||
*coef += pv.mant << -shift;
|
||||
}
|
||||
}
|
||||
|
||||
e0 = av_int2sf(*coef, 2);
|
||||
@@ -362,7 +375,9 @@ static void apply_dependent_coupling_fixed(AACContext *ac,
|
||||
shift = (gain-1024) >> 3;
|
||||
}
|
||||
|
||||
if (shift < 0) {
|
||||
if (shift < -31) {
|
||||
// Nothing to do
|
||||
} else if (shift < 0) {
|
||||
shift = -shift;
|
||||
round = 1 << (shift - 1);
|
||||
|
||||
@@ -379,7 +394,7 @@ static void apply_dependent_coupling_fixed(AACContext *ac,
|
||||
for (k = offsets[i]; k < offsets[i + 1]; k++) {
|
||||
tmp = (int)(((int64_t)src[group * 128 + k] * c + \
|
||||
(int64_t)0x1000000000) >> 37);
|
||||
dest[group * 128 + k] += tmp << shift;
|
||||
dest[group * 128 + k] += tmp * (1 << shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -419,7 +434,7 @@ static void apply_independent_coupling_fixed(AACContext *ac,
|
||||
else {
|
||||
for (i = 0; i < len; i++) {
|
||||
tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
|
||||
dest[i] += tmp << shift;
|
||||
dest[i] += tmp * (1 << shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ static av_cold int che_configure(AACContext *ac,
|
||||
if (!ac->che[type][id]) {
|
||||
if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
|
||||
return AVERROR(ENOMEM);
|
||||
AAC_RENAME(ff_aac_sbr_ctx_init)(ac, &ac->che[type][id]->sbr, type);
|
||||
AAC_RENAME(ff_aac_sbr_ctx_init)(ac, &ac->che[type][id]->sbr);
|
||||
}
|
||||
if (type != TYPE_CCE) {
|
||||
if (*channels >= MAX_CHANNELS - (type == TYPE_CPE || (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1))) {
|
||||
@@ -406,11 +406,15 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags)
|
||||
/**
|
||||
* Save current output configuration if and only if it has been locked.
|
||||
*/
|
||||
static void push_output_configuration(AACContext *ac) {
|
||||
static int push_output_configuration(AACContext *ac) {
|
||||
int pushed = 0;
|
||||
|
||||
if (ac->oc[1].status == OC_LOCKED || ac->oc[0].status == OC_NONE) {
|
||||
ac->oc[0] = ac->oc[1];
|
||||
pushed = 1;
|
||||
}
|
||||
ac->oc[1].status = OC_NONE;
|
||||
return pushed;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -452,7 +456,7 @@ static int output_configure(AACContext *ac,
|
||||
int id = layout_map[i][1];
|
||||
id_map[type][id] = type_counts[type]++;
|
||||
if (id_map[type][id] >= MAX_ELEM_ID) {
|
||||
avpriv_request_sample(ac->avctx, "Too large remapped id");
|
||||
avpriv_request_sample(ac->avctx, "Remapped id too large\n");
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
}
|
||||
@@ -715,13 +719,6 @@ static void decode_channel_map(uint8_t layout_map[][3],
|
||||
}
|
||||
}
|
||||
|
||||
static inline void relative_align_get_bits(GetBitContext *gb,
|
||||
int reference_position) {
|
||||
int n = (reference_position - get_bits_count(gb) & 7);
|
||||
if (n)
|
||||
skip_bits(gb, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode program configuration element; reference: table 4.2.
|
||||
*
|
||||
@@ -729,7 +726,7 @@ static inline void relative_align_get_bits(GetBitContext *gb,
|
||||
*/
|
||||
static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac,
|
||||
uint8_t (*layout_map)[3],
|
||||
GetBitContext *gb, int byte_align_ref)
|
||||
GetBitContext *gb)
|
||||
{
|
||||
int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc;
|
||||
int sampling_index;
|
||||
@@ -777,7 +774,7 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac,
|
||||
decode_channel_map(layout_map + tags, AAC_CHANNEL_CC, gb, num_cc);
|
||||
tags += num_cc;
|
||||
|
||||
relative_align_get_bits(gb, byte_align_ref);
|
||||
align_get_bits(gb);
|
||||
|
||||
/* comment field, first byte is length */
|
||||
comment_len = get_bits(gb, 8) * 8;
|
||||
@@ -799,7 +796,6 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac,
|
||||
*/
|
||||
static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx,
|
||||
GetBitContext *gb,
|
||||
int get_bit_alignment,
|
||||
MPEG4AudioConfig *m4ac,
|
||||
int channel_config)
|
||||
{
|
||||
@@ -823,7 +819,7 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx,
|
||||
|
||||
if (channel_config == 0) {
|
||||
skip_bits(gb, 4); // element_instance_tag
|
||||
tags = decode_pce(avctx, m4ac, layout_map, gb, get_bit_alignment);
|
||||
tags = decode_pce(avctx, m4ac, layout_map, gb);
|
||||
if (tags < 0)
|
||||
return tags;
|
||||
} else {
|
||||
@@ -945,25 +941,37 @@ static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx,
|
||||
* @param ac pointer to AACContext, may be null
|
||||
* @param avctx pointer to AVCCodecContext, used for logging
|
||||
* @param m4ac pointer to MPEG4AudioConfig, used for parsing
|
||||
* @param gb buffer holding an audio specific config
|
||||
* @param get_bit_alignment relative alignment for byte align operations
|
||||
* @param data pointer to buffer holding an audio specific config
|
||||
* @param bit_size size of audio specific config or data in bits
|
||||
* @param sync_extension look for an appended sync extension
|
||||
*
|
||||
* @return Returns error status or number of consumed bits. <0 - error
|
||||
*/
|
||||
static int decode_audio_specific_config_gb(AACContext *ac,
|
||||
AVCodecContext *avctx,
|
||||
MPEG4AudioConfig *m4ac,
|
||||
GetBitContext *gb,
|
||||
int get_bit_alignment,
|
||||
int sync_extension)
|
||||
static int decode_audio_specific_config(AACContext *ac,
|
||||
AVCodecContext *avctx,
|
||||
MPEG4AudioConfig *m4ac,
|
||||
const uint8_t *data, int64_t bit_size,
|
||||
int sync_extension)
|
||||
{
|
||||
GetBitContext gb;
|
||||
int i, ret;
|
||||
GetBitContext gbc = *gb;
|
||||
|
||||
if ((i = ff_mpeg4audio_get_config_gb(m4ac, &gbc, sync_extension)) < 0)
|
||||
if (bit_size < 0 || bit_size > INT_MAX) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Audio specific config size is invalid\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
ff_dlog(avctx, "audio specific config size %d\n", (int)bit_size >> 3);
|
||||
for (i = 0; i < bit_size >> 3; i++)
|
||||
ff_dlog(avctx, "%02x ", data[i]);
|
||||
ff_dlog(avctx, "\n");
|
||||
|
||||
if ((ret = init_get_bits(&gb, data, bit_size)) < 0)
|
||||
return ret;
|
||||
|
||||
if ((i = avpriv_mpeg4audio_get_config(m4ac, data, bit_size,
|
||||
sync_extension)) < 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
if (m4ac->sampling_index > 12) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"invalid sampling rate index %d\n",
|
||||
@@ -978,7 +986,7 @@ static int decode_audio_specific_config_gb(AACContext *ac,
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
skip_bits_long(gb, i);
|
||||
skip_bits_long(&gb, i);
|
||||
|
||||
switch (m4ac->object_type) {
|
||||
case AOT_AAC_MAIN:
|
||||
@@ -986,12 +994,12 @@ static int decode_audio_specific_config_gb(AACContext *ac,
|
||||
case AOT_AAC_LTP:
|
||||
case AOT_ER_AAC_LC:
|
||||
case AOT_ER_AAC_LD:
|
||||
if ((ret = decode_ga_specific_config(ac, avctx, gb, get_bit_alignment,
|
||||
if ((ret = decode_ga_specific_config(ac, avctx, &gb,
|
||||
m4ac, m4ac->chan_config)) < 0)
|
||||
return ret;
|
||||
break;
|
||||
case AOT_ER_AAC_ELD:
|
||||
if ((ret = decode_eld_specific_config(ac, avctx, gb,
|
||||
if ((ret = decode_eld_specific_config(ac, avctx, &gb,
|
||||
m4ac, m4ac->chan_config)) < 0)
|
||||
return ret;
|
||||
break;
|
||||
@@ -1009,33 +1017,7 @@ static int decode_audio_specific_config_gb(AACContext *ac,
|
||||
m4ac->sample_rate, m4ac->sbr,
|
||||
m4ac->ps);
|
||||
|
||||
return get_bits_count(gb);
|
||||
}
|
||||
|
||||
static int decode_audio_specific_config(AACContext *ac,
|
||||
AVCodecContext *avctx,
|
||||
MPEG4AudioConfig *m4ac,
|
||||
const uint8_t *data, int64_t bit_size,
|
||||
int sync_extension)
|
||||
{
|
||||
int i, ret;
|
||||
GetBitContext gb;
|
||||
|
||||
if (bit_size < 0 || bit_size > INT_MAX) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Audio specific config size is invalid\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
ff_dlog(avctx, "audio specific config size %d\n", (int)bit_size >> 3);
|
||||
for (i = 0; i < bit_size >> 3; i++)
|
||||
ff_dlog(avctx, "%02x ", data[i]);
|
||||
ff_dlog(avctx, "\n");
|
||||
|
||||
if ((ret = init_get_bits(&gb, data, bit_size)) < 0)
|
||||
return ret;
|
||||
|
||||
return decode_audio_specific_config_gb(ac, avctx, m4ac, &gb, 0,
|
||||
sync_extension);
|
||||
return get_bits_count(&gb);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1207,7 +1189,7 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
|
||||
AAC_RENAME_32(ff_mdct_init)(&ac->mdct_small, 8, 1, 1.0 / RANGE15(128.0));
|
||||
AAC_RENAME_32(ff_mdct_init)(&ac->mdct_ltp, 11, 0, RANGE15(-2.0));
|
||||
#if !USE_FIXED
|
||||
ret = ff_mdct15_init(&ac->mdct480, 1, 5, -1.0f);
|
||||
ret = ff_imdct15_init(&ac->mdct480, 5);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#endif
|
||||
@@ -1277,6 +1259,8 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
|
||||
const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac;
|
||||
const int aot = m4ac->object_type;
|
||||
const int sampling_index = m4ac->sampling_index;
|
||||
int ret_fail = AVERROR_INVALIDDATA;
|
||||
|
||||
if (aot != AOT_ER_AAC_ELD) {
|
||||
if (get_bits1(gb)) {
|
||||
av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n");
|
||||
@@ -1327,8 +1311,10 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
|
||||
ics->num_swb = ff_aac_num_swb_512[sampling_index];
|
||||
ics->tns_max_bands = ff_tns_max_bands_512[sampling_index];
|
||||
}
|
||||
if (!ics->num_swb || !ics->swb_offset)
|
||||
return AVERROR_BUG;
|
||||
if (!ics->num_swb || !ics->swb_offset) {
|
||||
ret_fail = AVERROR_BUG;
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
ics->swb_offset = ff_swb_offset_1024[sampling_index];
|
||||
ics->num_swb = ff_aac_num_swb_1024[sampling_index];
|
||||
@@ -1352,7 +1338,8 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
|
||||
if (aot == AOT_ER_AAC_LD) {
|
||||
av_log(ac->avctx, AV_LOG_ERROR,
|
||||
"LTP in ER AAC LD not yet implemented.\n");
|
||||
return AVERROR_PATCHWELCOME;
|
||||
ret_fail = AVERROR_PATCHWELCOME;
|
||||
goto fail;
|
||||
}
|
||||
if ((ics->ltp.present = get_bits(gb, 1)))
|
||||
decode_ltp(&ics->ltp, gb, ics->max_sfb);
|
||||
@@ -1371,7 +1358,7 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
|
||||
return 0;
|
||||
fail:
|
||||
ics->max_sfb = 0;
|
||||
return AVERROR_INVALIDDATA;
|
||||
return ret_fail;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2177,7 +2164,11 @@ static int decode_cce(AACContext *ac, GetBitContext *gb, ChannelElement *che)
|
||||
coup->coupling_point += get_bits1(gb) || (coup->coupling_point >> 1);
|
||||
|
||||
sign = get_bits(gb, 1);
|
||||
scale = AAC_RENAME(cce_scale)[get_bits(gb, 2)];
|
||||
#if USE_FIXED
|
||||
scale = get_bits(gb, 2);
|
||||
#else
|
||||
scale = cce_scale[get_bits(gb, 2)];
|
||||
#endif
|
||||
|
||||
if ((ret = decode_ics(ac, sce, gb, 0, 0)))
|
||||
return ret;
|
||||
@@ -2191,6 +2182,10 @@ static int decode_cce(AACContext *ac, GetBitContext *gb, ChannelElement *che)
|
||||
cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb);
|
||||
gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0;
|
||||
gain_cache = GET_GAIN(scale, gain);
|
||||
#if USE_FIXED
|
||||
if ((abs(gain_cache)-1024) >> 3 > 30)
|
||||
return AVERROR(ERANGE);
|
||||
#endif
|
||||
}
|
||||
if (coup->coupling_point == AFTER_IMDCT) {
|
||||
coup->gain[c][0] = gain_cache;
|
||||
@@ -2208,6 +2203,10 @@ static int decode_cce(AACContext *ac, GetBitContext *gb, ChannelElement *che)
|
||||
t >>= 1;
|
||||
}
|
||||
gain_cache = GET_GAIN(scale, t) * s;
|
||||
#if USE_FIXED
|
||||
if ((abs(gain_cache)-1024) >> 3 > 30)
|
||||
return AVERROR(ERANGE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
coup->gain[c][idx] = gain_cache;
|
||||
@@ -2381,7 +2380,7 @@ static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt,
|
||||
* @param decode 1 if tool is used normally, 0 if tool is used in LTP.
|
||||
* @param coef spectral coefficients
|
||||
*/
|
||||
static void apply_tns(INTFLOAT coef[1024], TemporalNoiseShaping *tns,
|
||||
static void apply_tns(INTFLOAT coef_param[1024], TemporalNoiseShaping *tns,
|
||||
IndividualChannelStream *ics, int decode)
|
||||
{
|
||||
const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
|
||||
@@ -2389,6 +2388,7 @@ static void apply_tns(INTFLOAT coef[1024], TemporalNoiseShaping *tns,
|
||||
int bottom, top, order, start, end, size, inc;
|
||||
INTFLOAT lpc[TNS_MAX_ORDER];
|
||||
INTFLOAT tmp[TNS_MAX_ORDER+1];
|
||||
UINTFLOAT *coef = coef_param;
|
||||
|
||||
for (w = 0; w < ics->num_windows; w++) {
|
||||
bottom = ics->num_swb;
|
||||
@@ -2418,7 +2418,7 @@ static void apply_tns(INTFLOAT coef[1024], TemporalNoiseShaping *tns,
|
||||
// ar filter
|
||||
for (m = 0; m < size; m++, start += inc)
|
||||
for (i = 1; i <= FFMIN(m, order); i++)
|
||||
coef[start] -= AAC_MUL26(coef[start - i * inc], lpc[i - 1]);
|
||||
coef[start] -= AAC_MUL26((INTFLOAT)coef[start - i * inc], lpc[i - 1]);
|
||||
} else {
|
||||
// ma filter
|
||||
for (m = 0; m < size; m++, start += inc) {
|
||||
@@ -2945,11 +2945,10 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
|
||||
{
|
||||
AACContext *ac = avctx->priv_data;
|
||||
ChannelElement *che = NULL, *che_prev = NULL;
|
||||
enum RawDataBlockType elem_type, che_prev_type = TYPE_END;
|
||||
enum RawDataBlockType elem_type, elem_type_prev = TYPE_END;
|
||||
int err, elem_id;
|
||||
int samples = 0, multiplier, audio_found = 0, pce_found = 0;
|
||||
int is_dmono, sce_count = 0;
|
||||
int payload_alignment;
|
||||
|
||||
ac->frame = data;
|
||||
|
||||
@@ -2972,7 +2971,6 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
|
||||
// This may lead to an undefined profile being signaled
|
||||
ac->avctx->profile = ac->oc[1].m4ac.object_type - 1;
|
||||
|
||||
payload_alignment = get_bits_count(gb);
|
||||
ac->tags_mapped = 0;
|
||||
// parse
|
||||
while ((elem_type = get_bits(gb, 3)) != TYPE_END) {
|
||||
@@ -3026,9 +3024,14 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
|
||||
case TYPE_PCE: {
|
||||
uint8_t layout_map[MAX_ELEM_ID*4][3];
|
||||
int tags;
|
||||
push_output_configuration(ac);
|
||||
tags = decode_pce(avctx, &ac->oc[1].m4ac, layout_map, gb,
|
||||
payload_alignment);
|
||||
|
||||
int pushed = push_output_configuration(ac);
|
||||
if (pce_found && !pushed) {
|
||||
err = AVERROR_INVALIDDATA;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
tags = decode_pce(avctx, &ac->oc[1].m4ac, layout_map, gb);
|
||||
if (tags < 0) {
|
||||
err = tags;
|
||||
break;
|
||||
@@ -3036,7 +3039,6 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
|
||||
if (pce_found) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"Not evaluating a further program_config_element as this construct is dubious at best.\n");
|
||||
pop_output_configuration(ac);
|
||||
} else {
|
||||
err = output_configure(ac, layout_map, tags, OC_TRIAL_PCE, 1);
|
||||
if (!err)
|
||||
@@ -3055,7 +3057,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
|
||||
goto fail;
|
||||
}
|
||||
while (elem_id > 0)
|
||||
elem_id -= decode_extension_payload(ac, gb, elem_id, che_prev, che_prev_type);
|
||||
elem_id -= decode_extension_payload(ac, gb, elem_id, che_prev, elem_type_prev);
|
||||
err = 0; /* FIXME */
|
||||
break;
|
||||
|
||||
@@ -3064,10 +3066,8 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
|
||||
break;
|
||||
}
|
||||
|
||||
if (elem_type < TYPE_DSE) {
|
||||
che_prev = che;
|
||||
che_prev_type = elem_type;
|
||||
}
|
||||
che_prev = che;
|
||||
elem_type_prev = elem_type;
|
||||
|
||||
if (err)
|
||||
goto fail;
|
||||
@@ -3095,8 +3095,12 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
|
||||
ac->oc[1].status = OC_LOCKED;
|
||||
}
|
||||
|
||||
if (multiplier)
|
||||
avctx->internal->skip_samples_multiplier = 2;
|
||||
if (multiplier) {
|
||||
int side_size;
|
||||
const uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
|
||||
if (side && side_size>=4)
|
||||
AV_WL32(side, 2*AV_RL32(side));
|
||||
}
|
||||
|
||||
if (!ac->frame->data[0] && samples) {
|
||||
av_log(avctx, AV_LOG_ERROR, "no frame data found\n");
|
||||
@@ -3214,7 +3218,7 @@ static av_cold int aac_decode_close(AVCodecContext *avctx)
|
||||
ff_mdct_end(&ac->mdct_ld);
|
||||
ff_mdct_end(&ac->mdct_ltp);
|
||||
#if !USE_FIXED
|
||||
ff_mdct15_uninit(&ac->mdct480);
|
||||
ff_imdct15_uninit(&ac->mdct480);
|
||||
#endif
|
||||
av_freep(&ac->fdsp);
|
||||
return 0;
|
||||
|
||||
@@ -520,13 +520,13 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
||||
int chan_el_counter[4];
|
||||
FFPsyWindowInfo windows[AAC_MAX_CHANNELS];
|
||||
|
||||
if (s->last_frame == 2)
|
||||
return 0;
|
||||
|
||||
/* add current frame to queue */
|
||||
if (frame) {
|
||||
if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
|
||||
return ret;
|
||||
} else {
|
||||
if (!s->afq.remaining_samples || (!s->afq.frame_alloc && !s->afq.frame_count))
|
||||
return 0;
|
||||
}
|
||||
|
||||
copy_input_samples(s, frame);
|
||||
@@ -769,7 +769,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
||||
start_ch += chans;
|
||||
}
|
||||
|
||||
if (avctx->flags & AV_CODEC_FLAG_QSCALE) {
|
||||
if (avctx->flags & CODEC_FLAG_QSCALE) {
|
||||
/* When using a constant Q-scale, don't mess with lambda */
|
||||
break;
|
||||
}
|
||||
@@ -841,6 +841,9 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
||||
s->lambda_sum += s->lambda;
|
||||
s->lambda_count++;
|
||||
|
||||
if (!frame)
|
||||
s->last_frame++;
|
||||
|
||||
ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts,
|
||||
&avpkt->duration);
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@ typedef struct AACEncContext {
|
||||
struct FFPsyPreprocessContext* psypp;
|
||||
AACCoefficientsEncoder *coder;
|
||||
int cur_channel; ///< current channel for coder context
|
||||
int last_frame;
|
||||
int random_state;
|
||||
float lambda;
|
||||
int last_frame_pb_count; ///< number of bits for the previous frame
|
||||
|
||||
@@ -499,13 +499,13 @@ static void map_idx_34_to_20(int8_t *par_mapped, const int8_t *par, int full)
|
||||
static void map_val_34_to_20(INTFLOAT par[PS_MAX_NR_IIDICC])
|
||||
{
|
||||
#if USE_FIXED
|
||||
par[ 0] = (int)(((int64_t)(par[ 0] + (par[ 1]>>1)) * 1431655765 + \
|
||||
par[ 0] = (int)(((int64_t)(par[ 0] + (unsigned)(par[ 1]>>1)) * 1431655765 + \
|
||||
0x40000000) >> 31);
|
||||
par[ 1] = (int)(((int64_t)((par[ 1]>>1) + par[ 2]) * 1431655765 + \
|
||||
par[ 1] = (int)(((int64_t)((par[ 1]>>1) + (unsigned)par[ 2]) * 1431655765 + \
|
||||
0x40000000) >> 31);
|
||||
par[ 2] = (int)(((int64_t)(par[ 3] + (par[ 4]>>1)) * 1431655765 + \
|
||||
par[ 2] = (int)(((int64_t)(par[ 3] + (unsigned)(par[ 4]>>1)) * 1431655765 + \
|
||||
0x40000000) >> 31);
|
||||
par[ 3] = (int)(((int64_t)((par[ 4]>>1) + par[ 5]) * 1431655765 + \
|
||||
par[ 3] = (int)(((int64_t)((par[ 4]>>1) + (unsigned)par[ 5]) * 1431655765 + \
|
||||
0x40000000) >> 31);
|
||||
#else
|
||||
par[ 0] = (2*par[ 0] + par[ 1]) * 0.33333333f;
|
||||
@@ -692,26 +692,17 @@ static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT
|
||||
for (i = 0; i < NR_PAR_BANDS[is34]; i++) {
|
||||
for (n = n0; n < nL; n++) {
|
||||
int decayed_peak;
|
||||
int denom;
|
||||
|
||||
decayed_peak = (int)(((int64_t)peak_decay_factor * \
|
||||
peak_decay_nrg[i] + 0x40000000) >> 31);
|
||||
peak_decay_nrg[i] = FFMAX(decayed_peak, power[i][n]);
|
||||
power_smooth[i] += (power[i][n] - power_smooth[i] + 2) >> 2;
|
||||
peak_decay_diff_smooth[i] += (peak_decay_nrg[i] - power[i][n] - \
|
||||
peak_decay_diff_smooth[i] + 2) >> 2;
|
||||
denom = peak_decay_diff_smooth[i] + (peak_decay_diff_smooth[i] >> 1);
|
||||
if (denom > power_smooth[i]) {
|
||||
int p = power_smooth[i];
|
||||
while (denom < 0x40000000) {
|
||||
denom <<= 1;
|
||||
p <<= 1;
|
||||
}
|
||||
transient_gain[i][n] = p / (denom >> 16);
|
||||
}
|
||||
else {
|
||||
transient_gain[i][n] = 1 << 16;
|
||||
}
|
||||
power_smooth[i] += (power[i][n] + 2LL - power_smooth[i]) >> 2;
|
||||
peak_decay_diff_smooth[i] += (peak_decay_nrg[i] + 2LL - power[i][n] - \
|
||||
peak_decay_diff_smooth[i]) >> 2;
|
||||
|
||||
if (peak_decay_diff_smooth[i]) {
|
||||
transient_gain[i][n] = FFMIN(power_smooth[i]*43691LL / peak_decay_diff_smooth[i], 1<<16);
|
||||
} else
|
||||
transient_gain[i][n] = 1 << 16;
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -942,7 +933,7 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)
|
||||
int stop = ps->border_position[e+1];
|
||||
INTFLOAT width = Q30(1.f) / ((stop - start) ? (stop - start) : 1);
|
||||
#if USE_FIXED
|
||||
width <<= 1;
|
||||
width = FFMIN(2U*width, INT_MAX);
|
||||
#endif
|
||||
b = k_to_i[k];
|
||||
h[0][0] = H11[0][e][b];
|
||||
@@ -975,7 +966,7 @@ static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)
|
||||
h_step[1][3] = AAC_MSUB31_V3(H22[1][e+1][b], h[1][3], width);
|
||||
}
|
||||
ps->dsp.stereo_interpolate[!PS_BASELINE && ps->enable_ipdopd](
|
||||
l[k] + start + 1, r[k] + start + 1,
|
||||
l[k] + 1 + start, r[k] + 1 + start,
|
||||
h, h_step, stop - start);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ static av_cold int psy_3gpp_init(FFPsyContext *ctx) {
|
||||
float bark;
|
||||
int i, j, g, start;
|
||||
float prev, minscale, minath, minsnr, pe_min;
|
||||
int chan_bitrate = ctx->avctx->bit_rate / ((ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : ctx->avctx->channels);
|
||||
int chan_bitrate = ctx->avctx->bit_rate / ((ctx->avctx->flags & CODEC_FLAG_QSCALE) ? 2.0f : ctx->avctx->channels);
|
||||
|
||||
const int bandwidth = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx);
|
||||
const float num_bark = calc_bark((float)bandwidth);
|
||||
@@ -311,10 +311,10 @@ static av_cold int psy_3gpp_init(FFPsyContext *ctx) {
|
||||
ctx->model_priv_data = av_mallocz(sizeof(AacPsyContext));
|
||||
if (!ctx->model_priv_data)
|
||||
return AVERROR(ENOMEM);
|
||||
pctx = ctx->model_priv_data;
|
||||
pctx = (AacPsyContext*) ctx->model_priv_data;
|
||||
pctx->global_quality = (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120) * 0.01f;
|
||||
|
||||
if (ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) {
|
||||
if (ctx->avctx->flags & CODEC_FLAG_QSCALE) {
|
||||
/* Use the target average bitrate to compute spread parameters */
|
||||
chan_bitrate = (int)(chan_bitrate / 120.0 * (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120));
|
||||
}
|
||||
@@ -704,7 +704,7 @@ static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel,
|
||||
|
||||
/* 5.6.1.3.2 "Calculation of the desired perceptual entropy" */
|
||||
ctx->ch[channel].entropy = pe;
|
||||
if (ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) {
|
||||
if (ctx->avctx->flags & CODEC_FLAG_QSCALE) {
|
||||
/* (2.5 * 120) achieves almost transparent rate, and we want to give
|
||||
* ample room downwards, so we make that equivalent to QSCALE=2.4
|
||||
*/
|
||||
|
||||
@@ -81,7 +81,7 @@ static const int8_t vlc_sbr_lav[10] =
|
||||
/** Initialize SBR. */
|
||||
void AAC_RENAME(ff_aac_sbr_init)(void);
|
||||
/** Initialize one SBR context. */
|
||||
void AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr, int id_aac);
|
||||
void AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr);
|
||||
/** Close one SBR context. */
|
||||
void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr);
|
||||
/** Decode one SBR element. */
|
||||
|
||||
@@ -288,6 +288,8 @@ static void sbr_hf_inverse_filter(SBRDSPContext *dsp,
|
||||
shift = a00.exp;
|
||||
if (shift >= 3)
|
||||
alpha0[k][0] = 0x7fffffff;
|
||||
else if (shift <= -30)
|
||||
alpha0[k][0] = 0;
|
||||
else {
|
||||
a00.mant <<= 1;
|
||||
shift = 2-shift;
|
||||
@@ -302,6 +304,8 @@ static void sbr_hf_inverse_filter(SBRDSPContext *dsp,
|
||||
shift = a01.exp;
|
||||
if (shift >= 3)
|
||||
alpha0[k][1] = 0x7fffffff;
|
||||
else if (shift <= -30)
|
||||
alpha0[k][1] = 0;
|
||||
else {
|
||||
a01.mant <<= 1;
|
||||
shift = 2-shift;
|
||||
@@ -315,6 +319,8 @@ static void sbr_hf_inverse_filter(SBRDSPContext *dsp,
|
||||
shift = a10.exp;
|
||||
if (shift >= 3)
|
||||
alpha1[k][0] = 0x7fffffff;
|
||||
else if (shift <= -30)
|
||||
alpha1[k][0] = 0;
|
||||
else {
|
||||
a10.mant <<= 1;
|
||||
shift = 2-shift;
|
||||
@@ -329,6 +335,8 @@ static void sbr_hf_inverse_filter(SBRDSPContext *dsp,
|
||||
shift = a11.exp;
|
||||
if (shift >= 3)
|
||||
alpha1[k][1] = 0x7fffffff;
|
||||
else if (shift <= -30)
|
||||
alpha1[k][1] = 0;
|
||||
else {
|
||||
a11.mant <<= 1;
|
||||
shift = 2-shift;
|
||||
@@ -567,20 +575,33 @@ static void sbr_hf_assemble(int Y1[38][64][2],
|
||||
|
||||
SoftFloat *in = sbr->s_m[e];
|
||||
for (m = 0; m+1 < m_max; m+=2) {
|
||||
shift = 22 - in[m ].exp;
|
||||
round = 1 << (shift-1);
|
||||
out[2*m ] += (in[m ].mant * A + round) >> shift;
|
||||
int shift2;
|
||||
shift = 22 - in[m ].exp;
|
||||
shift2= 22 - in[m+1].exp;
|
||||
if (shift < 1 || shift2 < 1) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Overflow in sbr_hf_assemble, shift=%d,%d\n", shift, shift2);
|
||||
return;
|
||||
}
|
||||
if (shift < 32) {
|
||||
round = 1 << (shift-1);
|
||||
out[2*m ] += (in[m ].mant * A + round) >> shift;
|
||||
}
|
||||
|
||||
shift = 22 - in[m+1].exp;
|
||||
round = 1 << (shift-1);
|
||||
out[2*m+2] += (in[m+1].mant * B + round) >> shift;
|
||||
if (shift2 < 32) {
|
||||
round = 1 << (shift2-1);
|
||||
out[2*m+2] += (in[m+1].mant * B + round) >> shift2;
|
||||
}
|
||||
}
|
||||
if(m_max&1)
|
||||
{
|
||||
shift = 22 - in[m ].exp;
|
||||
round = 1 << (shift-1);
|
||||
|
||||
out[2*m ] += (in[m ].mant * A + round) >> shift;
|
||||
shift = 22 - in[m ].exp;
|
||||
if (shift < 1) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Overflow in sbr_hf_assemble, shift=%d\n", shift);
|
||||
return;
|
||||
} else if (shift < 32) {
|
||||
round = 1 << (shift-1);
|
||||
out[2*m ] += (in[m ].mant * A + round) >> shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
indexnoise = (indexnoise + m_max) & 0x1ff;
|
||||
|
||||
@@ -81,12 +81,11 @@ static void sbr_turnoff(SpectralBandReplication *sbr) {
|
||||
memset(&sbr->spectrum_params, -1, sizeof(SpectrumParameters));
|
||||
}
|
||||
|
||||
av_cold void AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr, int id_aac)
|
||||
av_cold void AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr)
|
||||
{
|
||||
if(sbr->mdct.mdct_bits)
|
||||
return;
|
||||
sbr->kx[0] = sbr->kx[1];
|
||||
sbr->id_aac = id_aac;
|
||||
sbr_turnoff(sbr);
|
||||
sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128);
|
||||
sbr->data[1].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128);
|
||||
@@ -624,24 +623,26 @@ static int read_sbr_grid(AACContext *ac, SpectralBandReplication *sbr,
|
||||
int abs_bord_trail = 16;
|
||||
int num_rel_lead, num_rel_trail;
|
||||
unsigned bs_num_env_old = ch_data->bs_num_env;
|
||||
int bs_frame_class, bs_num_env;
|
||||
|
||||
ch_data->bs_freq_res[0] = ch_data->bs_freq_res[ch_data->bs_num_env];
|
||||
ch_data->bs_amp_res = sbr->bs_amp_res_header;
|
||||
ch_data->t_env_num_env_old = ch_data->t_env[bs_num_env_old];
|
||||
|
||||
switch (ch_data->bs_frame_class = get_bits(gb, 2)) {
|
||||
switch (bs_frame_class = get_bits(gb, 2)) {
|
||||
case FIXFIX:
|
||||
ch_data->bs_num_env = 1 << get_bits(gb, 2);
|
||||
bs_num_env = 1 << get_bits(gb, 2);
|
||||
if (bs_num_env > 4) {
|
||||
av_log(ac->avctx, AV_LOG_ERROR,
|
||||
"Invalid bitstream, too many SBR envelopes in FIXFIX type SBR frame: %d\n",
|
||||
bs_num_env);
|
||||
return -1;
|
||||
}
|
||||
ch_data->bs_num_env = bs_num_env;
|
||||
num_rel_lead = ch_data->bs_num_env - 1;
|
||||
if (ch_data->bs_num_env == 1)
|
||||
ch_data->bs_amp_res = 0;
|
||||
|
||||
if (ch_data->bs_num_env > 4) {
|
||||
av_log(ac->avctx, AV_LOG_ERROR,
|
||||
"Invalid bitstream, too many SBR envelopes in FIXFIX type SBR frame: %d\n",
|
||||
ch_data->bs_num_env);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ch_data->t_env[0] = 0;
|
||||
ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
|
||||
@@ -689,14 +690,15 @@ static int read_sbr_grid(AACContext *ac, SpectralBandReplication *sbr,
|
||||
abs_bord_trail += get_bits(gb, 2);
|
||||
num_rel_lead = get_bits(gb, 2);
|
||||
num_rel_trail = get_bits(gb, 2);
|
||||
ch_data->bs_num_env = num_rel_lead + num_rel_trail + 1;
|
||||
bs_num_env = num_rel_lead + num_rel_trail + 1;
|
||||
|
||||
if (ch_data->bs_num_env > 5) {
|
||||
if (bs_num_env > 5) {
|
||||
av_log(ac->avctx, AV_LOG_ERROR,
|
||||
"Invalid bitstream, too many SBR envelopes in VARVAR type SBR frame: %d\n",
|
||||
ch_data->bs_num_env);
|
||||
bs_num_env);
|
||||
return -1;
|
||||
}
|
||||
ch_data->bs_num_env = bs_num_env;
|
||||
|
||||
ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
|
||||
|
||||
@@ -711,6 +713,7 @@ static int read_sbr_grid(AACContext *ac, SpectralBandReplication *sbr,
|
||||
get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env);
|
||||
break;
|
||||
}
|
||||
ch_data->bs_frame_class = bs_frame_class;
|
||||
|
||||
av_assert0(bs_pointer >= 0);
|
||||
if (bs_pointer > ch_data->bs_num_env + 1) {
|
||||
@@ -941,8 +944,14 @@ static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
|
||||
skip_bits_long(gb, *num_bits_left); // bs_fill_bits
|
||||
*num_bits_left = 0;
|
||||
} else {
|
||||
#if 1
|
||||
*num_bits_left -= AAC_RENAME(ff_ps_read_data)(ac->avctx, gb, &sbr->ps, *num_bits_left);
|
||||
ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
|
||||
#else
|
||||
avpriv_report_missing_feature(ac->avctx, "Parametric Stereo");
|
||||
skip_bits_long(gb, *num_bits_left); // bs_fill_bits
|
||||
*num_bits_left = 0;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1137,7 +1146,6 @@ int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac, SpectralBandReplication
|
||||
if (bytes_read > cnt) {
|
||||
av_log(ac->avctx, AV_LOG_ERROR,
|
||||
"Expected to read %d SBR bytes actually read %d.\n", cnt, bytes_read);
|
||||
sbr_turnoff(sbr);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@@ -139,10 +139,10 @@ DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_128)[128];
|
||||
DECLARE_ALIGNED(32, extern int, ff_aac_kbd_long_1024_fixed)[1024];
|
||||
DECLARE_ALIGNED(32, extern int, ff_aac_kbd_long_512_fixed)[512];
|
||||
DECLARE_ALIGNED(32, extern int, ff_aac_kbd_short_128_fixed)[128];
|
||||
DECLARE_ALIGNED(32, extern const float, ff_aac_eld_window_512)[1920];
|
||||
DECLARE_ALIGNED(32, extern const int, ff_aac_eld_window_512_fixed)[1920];
|
||||
DECLARE_ALIGNED(32, extern const float, ff_aac_eld_window_480)[1800];
|
||||
DECLARE_ALIGNED(32, extern const int, ff_aac_eld_window_480_fixed)[1800];
|
||||
const DECLARE_ALIGNED(32, extern float, ff_aac_eld_window_512)[1920];
|
||||
const DECLARE_ALIGNED(32, extern int, ff_aac_eld_window_512_fixed)[1920];
|
||||
const DECLARE_ALIGNED(32, extern float, ff_aac_eld_window_480)[1800];
|
||||
const DECLARE_ALIGNED(32, extern int, ff_aac_eld_window_480_fixed)[1800];
|
||||
// @}
|
||||
|
||||
/* @name number of scalefactor window bands for long and short transform windows respectively
|
||||
|
||||
@@ -6,6 +6,7 @@ OBJS-$(CONFIG_H264DSP) += aarch64/h264dsp_init_aarch64.o
|
||||
OBJS-$(CONFIG_H264PRED) += aarch64/h264pred_init.o
|
||||
OBJS-$(CONFIG_H264QPEL) += aarch64/h264qpel_init_aarch64.o
|
||||
OBJS-$(CONFIG_HPELDSP) += aarch64/hpeldsp_init_aarch64.o
|
||||
OBJS-$(CONFIG_IMDCT15) += aarch64/imdct15_init.o
|
||||
OBJS-$(CONFIG_MPEGAUDIODSP) += aarch64/mpegaudiodsp_init.o
|
||||
OBJS-$(CONFIG_NEON_CLOBBER_TEST) += aarch64/neontest.o
|
||||
OBJS-$(CONFIG_VIDEODSP) += aarch64/videodsp_init.o
|
||||
@@ -15,9 +16,6 @@ OBJS-$(CONFIG_DCA_DECODER) += aarch64/synth_filter_init.o
|
||||
OBJS-$(CONFIG_RV40_DECODER) += aarch64/rv40dsp_init_aarch64.o
|
||||
OBJS-$(CONFIG_VC1DSP) += aarch64/vc1dsp_init_aarch64.o
|
||||
OBJS-$(CONFIG_VORBIS_DECODER) += aarch64/vorbisdsp_init.o
|
||||
OBJS-$(CONFIG_VP9_DECODER) += aarch64/vp9dsp_init_10bpp_aarch64.o \
|
||||
aarch64/vp9dsp_init_12bpp_aarch64.o \
|
||||
aarch64/vp9dsp_init_aarch64.o
|
||||
|
||||
# ARMv8 optimizations
|
||||
|
||||
@@ -36,17 +34,10 @@ NEON-OBJS-$(CONFIG_H264PRED) += aarch64/h264pred_neon.o
|
||||
NEON-OBJS-$(CONFIG_H264QPEL) += aarch64/h264qpel_neon.o \
|
||||
aarch64/hpeldsp_neon.o
|
||||
NEON-OBJS-$(CONFIG_HPELDSP) += aarch64/hpeldsp_neon.o
|
||||
NEON-OBJS-$(CONFIG_IDCTDSP) += aarch64/idctdsp_init_aarch64.o \
|
||||
aarch64/simple_idct_neon.o
|
||||
NEON-OBJS-$(CONFIG_IMDCT15) += aarch64/imdct15_neon.o
|
||||
NEON-OBJS-$(CONFIG_MDCT) += aarch64/mdct_neon.o
|
||||
NEON-OBJS-$(CONFIG_MPEGAUDIODSP) += aarch64/mpegaudiodsp_neon.o
|
||||
|
||||
# decoders/encoders
|
||||
NEON-OBJS-$(CONFIG_DCA_DECODER) += aarch64/synth_filter_neon.o
|
||||
NEON-OBJS-$(CONFIG_VORBIS_DECODER) += aarch64/vorbisdsp_neon.o
|
||||
NEON-OBJS-$(CONFIG_VP9_DECODER) += aarch64/vp9itxfm_16bpp_neon.o \
|
||||
aarch64/vp9itxfm_neon.o \
|
||||
aarch64/vp9lpf_16bpp_neon.o \
|
||||
aarch64/vp9lpf_neon.o \
|
||||
aarch64/vp9mc_16bpp_neon.o \
|
||||
aarch64/vp9mc_neon.o
|
||||
|
||||
@@ -28,18 +28,18 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
void ff_put_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
|
||||
void ff_put_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, int stride,
|
||||
int h, int x, int y);
|
||||
void ff_put_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
|
||||
void ff_put_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, int stride,
|
||||
int h, int x, int y);
|
||||
void ff_put_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
|
||||
void ff_put_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, int stride,
|
||||
int h, int x, int y);
|
||||
|
||||
void ff_avg_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
|
||||
void ff_avg_h264_chroma_mc8_neon(uint8_t *dst, uint8_t *src, int stride,
|
||||
int h, int x, int y);
|
||||
void ff_avg_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
|
||||
void ff_avg_h264_chroma_mc4_neon(uint8_t *dst, uint8_t *src, int stride,
|
||||
int h, int x, int y);
|
||||
void ff_avg_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
|
||||
void ff_avg_h264_chroma_mc2_neon(uint8_t *dst, uint8_t *src, int stride,
|
||||
int h, int x, int y);
|
||||
|
||||
av_cold void ff_h264chroma_init_aarch64(H264ChromaContext *c, int bit_depth)
|
||||
|
||||
@@ -21,9 +21,10 @@
|
||||
|
||||
#include "libavutil/aarch64/asm.S"
|
||||
|
||||
/* chroma_mc8(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y) */
|
||||
/* chroma_mc8(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y) */
|
||||
.macro h264_chroma_mc8 type, codec=h264
|
||||
function ff_\type\()_\codec\()_chroma_mc8_neon, export=1
|
||||
sxtw x2, w2
|
||||
.ifc \type,avg
|
||||
mov x8, x0
|
||||
.endif
|
||||
@@ -191,9 +192,10 @@ function ff_\type\()_\codec\()_chroma_mc8_neon, export=1
|
||||
endfunc
|
||||
.endm
|
||||
|
||||
/* chroma_mc4(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y) */
|
||||
/* chroma_mc4(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y) */
|
||||
.macro h264_chroma_mc4 type, codec=h264
|
||||
function ff_\type\()_\codec\()_chroma_mc4_neon, export=1
|
||||
sxtw x2, w2
|
||||
.ifc \type,avg
|
||||
mov x8, x0
|
||||
.endif
|
||||
@@ -357,6 +359,7 @@ endfunc
|
||||
|
||||
.macro h264_chroma_mc2 type
|
||||
function ff_\type\()_h264_chroma_mc2_neon, export=1
|
||||
sxtw x2, w2
|
||||
prfm pldl1strm, [x1]
|
||||
prfm pldl1strm, [x1, x2]
|
||||
orr w7, w4, w5
|
||||
|
||||
@@ -162,7 +162,7 @@ function ff_h264_idct_add8_neon, export=1
|
||||
mov w19, w3 // stride
|
||||
movrel x13, X(ff_h264_idct_dc_add_neon)
|
||||
movrel x14, X(ff_h264_idct_add_neon)
|
||||
movrel x7, scan8, 16
|
||||
movrel x7, scan8+16
|
||||
mov x10, #0
|
||||
mov x11, #16
|
||||
1: mov w2, w19
|
||||
@@ -264,7 +264,6 @@ endfunc
|
||||
|
||||
function ff_h264_idct8_add_neon, export=1
|
||||
movi v19.8H, #0
|
||||
sxtw x2, w2
|
||||
ld1 {v24.8H, v25.8H}, [x1]
|
||||
st1 {v19.8H}, [x1], #16
|
||||
st1 {v19.8H}, [x1], #16
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user